Update Scintilla to version 3.5.2
[TortoiseGit.git] / ext / scintilla / src / Decoration.cxx
blob4ffbcffd5b6c70e3b6da065ec2e025da3ff0711c
1 /** @file Decoration.cxx
2 ** Visual elements added over text.
3 **/
4 // Copyright 1998-2007 by Neil Hodgson <neilh@scintilla.org>
5 // The License.txt file describes the conditions under which this software may be distributed.
7 #include <stdlib.h>
8 #include <string.h>
9 #include <stdio.h>
10 #include <stdarg.h>
12 #include <algorithm>
14 #include "Platform.h"
16 #include "Scintilla.h"
17 #include "SplitVector.h"
18 #include "Partitioning.h"
19 #include "RunStyles.h"
20 #include "Decoration.h"
22 #ifdef SCI_NAMESPACE
23 using namespace Scintilla;
24 #endif
26 Decoration::Decoration(int indicator_) : next(0), indicator(indicator_) {
29 Decoration::~Decoration() {
32 bool Decoration::Empty() const {
33 return (rs.Runs() == 1) && (rs.AllSameAs(0));
36 DecorationList::DecorationList() : currentIndicator(0), currentValue(1), current(0),
37 lengthDocument(0), root(0), clickNotified(false) {
40 DecorationList::~DecorationList() {
41 Decoration *deco = root;
42 while (deco) {
43 Decoration *decoNext = deco->next;
44 delete deco;
45 deco = decoNext;
47 root = 0;
48 current = 0;
51 Decoration *DecorationList::DecorationFromIndicator(int indicator) {
52 for (Decoration *deco=root; deco; deco = deco->next) {
53 if (deco->indicator == indicator) {
54 return deco;
57 return 0;
60 Decoration *DecorationList::Create(int indicator, int length) {
61 currentIndicator = indicator;
62 Decoration *decoNew = new Decoration(indicator);
63 decoNew->rs.InsertSpace(0, length);
65 Decoration *decoPrev = 0;
66 Decoration *deco = root;
68 while (deco && (deco->indicator < indicator)) {
69 decoPrev = deco;
70 deco = deco->next;
72 if (decoPrev == 0) {
73 decoNew->next = root;
74 root = decoNew;
75 } else {
76 decoNew->next = deco;
77 decoPrev->next = decoNew;
79 return decoNew;
82 void DecorationList::Delete(int indicator) {
83 Decoration *decoToDelete = 0;
84 if (root) {
85 if (root->indicator == indicator) {
86 decoToDelete = root;
87 root = root->next;
88 } else {
89 Decoration *deco=root;
90 while (deco->next && !decoToDelete) {
91 if (deco->next && deco->next->indicator == indicator) {
92 decoToDelete = deco->next;
93 deco->next = decoToDelete->next;
94 } else {
95 deco = deco->next;
100 if (decoToDelete) {
101 delete decoToDelete;
102 current = 0;
106 void DecorationList::SetCurrentIndicator(int indicator) {
107 currentIndicator = indicator;
108 current = DecorationFromIndicator(indicator);
109 currentValue = 1;
112 void DecorationList::SetCurrentValue(int value) {
113 currentValue = value ? value : 1;
116 bool DecorationList::FillRange(int &position, int value, int &fillLength) {
117 if (!current) {
118 current = DecorationFromIndicator(currentIndicator);
119 if (!current) {
120 current = Create(currentIndicator, lengthDocument);
123 bool changed = current->rs.FillRange(position, value, fillLength);
124 if (current->Empty()) {
125 Delete(currentIndicator);
127 return changed;
130 void DecorationList::InsertSpace(int position, int insertLength) {
131 const bool atEnd = position == lengthDocument;
132 lengthDocument += insertLength;
133 for (Decoration *deco=root; deco; deco = deco->next) {
134 deco->rs.InsertSpace(position, insertLength);
135 if (atEnd) {
136 deco->rs.FillRange(position, 0, insertLength);
141 void DecorationList::DeleteRange(int position, int deleteLength) {
142 lengthDocument -= deleteLength;
143 Decoration *deco;
144 for (deco=root; deco; deco = deco->next) {
145 deco->rs.DeleteRange(position, deleteLength);
147 DeleteAnyEmpty();
150 void DecorationList::DeleteAnyEmpty() {
151 Decoration *deco = root;
152 while (deco) {
153 if ((lengthDocument == 0) || deco->Empty()) {
154 Delete(deco->indicator);
155 deco = root;
156 } else {
157 deco = deco->next;
162 int DecorationList::AllOnFor(int position) const {
163 int mask = 0;
164 for (Decoration *deco=root; deco; deco = deco->next) {
165 if (deco->rs.ValueAt(position)) {
166 if (deco->indicator < INDIC_IME) {
167 mask |= 1 << deco->indicator;
171 return mask;
174 int DecorationList::ValueAt(int indicator, int position) {
175 Decoration *deco = DecorationFromIndicator(indicator);
176 if (deco) {
177 return deco->rs.ValueAt(position);
179 return 0;
182 int DecorationList::Start(int indicator, int position) {
183 Decoration *deco = DecorationFromIndicator(indicator);
184 if (deco) {
185 return deco->rs.StartRun(position);
187 return 0;
190 int DecorationList::End(int indicator, int position) {
191 Decoration *deco = DecorationFromIndicator(indicator);
192 if (deco) {
193 return deco->rs.EndRun(position);
195 return 0;