]> git.saurik.com Git - wxWidgets.git/blob - src/stc/scintilla/src/Decoration.cxx
Initial copy of Scintilla 3.21 code
[wxWidgets.git] / src / stc / scintilla / src / Decoration.cxx
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.
6
7 #include <stdio.h>
8 #include <string.h>
9 #include <stdlib.h>
10 #include <stdarg.h>
11
12 #include "Platform.h"
13
14 #include "Scintilla.h"
15 #include "SplitVector.h"
16 #include "Partitioning.h"
17 #include "RunStyles.h"
18 #include "Decoration.h"
19
20 #ifdef SCI_NAMESPACE
21 using namespace Scintilla;
22 #endif
23
24 Decoration::Decoration(int indicator_) : next(0), indicator(indicator_) {
25 }
26
27 Decoration::~Decoration() {
28 }
29
30 bool Decoration::Empty() {
31 return (rs.Runs() == 1) && (rs.AllSameAs(0));
32 }
33
34 DecorationList::DecorationList() : currentIndicator(0), currentValue(1), current(0),
35 lengthDocument(0), root(0), clickNotified(false) {
36 }
37
38 DecorationList::~DecorationList() {
39 Decoration *deco = root;
40 while (deco) {
41 Decoration *decoNext = deco->next;
42 delete deco;
43 deco = decoNext;
44 }
45 root = 0;
46 current = 0;
47 }
48
49 Decoration *DecorationList::DecorationFromIndicator(int indicator) {
50 for (Decoration *deco=root; deco; deco = deco->next) {
51 if (deco->indicator == indicator) {
52 return deco;
53 }
54 }
55 return 0;
56 }
57
58 Decoration *DecorationList::Create(int indicator, int length) {
59 currentIndicator = indicator;
60 Decoration *decoNew = new Decoration(indicator);
61 decoNew->rs.InsertSpace(0, length);
62
63 Decoration *decoPrev = 0;
64 Decoration *deco = root;
65
66 while (deco && (deco->indicator < indicator)) {
67 decoPrev = deco;
68 deco = deco->next;
69 }
70 if (decoPrev == 0) {
71 decoNew->next = root;
72 root = decoNew;
73 } else {
74 decoNew->next = deco;
75 decoPrev->next = decoNew;
76 }
77 return decoNew;
78 }
79
80 void DecorationList::Delete(int indicator) {
81 Decoration *decoToDelete = 0;
82 if (root) {
83 if (root->indicator == indicator) {
84 decoToDelete = root;
85 root = root->next;
86 } else {
87 Decoration *deco=root;
88 while (deco->next && !decoToDelete) {
89 if (deco->next && deco->next->indicator == indicator) {
90 decoToDelete = deco->next;
91 deco->next = decoToDelete->next;
92 } else {
93 deco = deco->next;
94 }
95 }
96 }
97 }
98 if (decoToDelete) {
99 delete decoToDelete;
100 current = 0;
101 }
102 }
103
104 void DecorationList::SetCurrentIndicator(int indicator) {
105 currentIndicator = indicator;
106 current = DecorationFromIndicator(indicator);
107 currentValue = 1;
108 }
109
110 void DecorationList::SetCurrentValue(int value) {
111 currentValue = value ? value : 1;
112 }
113
114 bool DecorationList::FillRange(int &position, int value, int &fillLength) {
115 if (!current) {
116 current = DecorationFromIndicator(currentIndicator);
117 if (!current) {
118 current = Create(currentIndicator, lengthDocument);
119 }
120 }
121 bool changed = current->rs.FillRange(position, value, fillLength);
122 if (current->Empty()) {
123 Delete(currentIndicator);
124 }
125 return changed;
126 }
127
128 void DecorationList::InsertSpace(int position, int insertLength) {
129 const bool atEnd = position == lengthDocument;
130 lengthDocument += insertLength;
131 for (Decoration *deco=root; deco; deco = deco->next) {
132 deco->rs.InsertSpace(position, insertLength);
133 if (atEnd) {
134 deco->rs.FillRange(position, 0, insertLength);
135 }
136 }
137 }
138
139 void DecorationList::DeleteRange(int position, int deleteLength) {
140 lengthDocument -= deleteLength;
141 Decoration *deco;
142 for (deco=root; deco; deco = deco->next) {
143 deco->rs.DeleteRange(position, deleteLength);
144 }
145 DeleteAnyEmpty();
146 }
147
148 void DecorationList::DeleteAnyEmpty() {
149 Decoration *deco = root;
150 while (deco) {
151 if ((lengthDocument == 0) || deco->Empty()) {
152 Delete(deco->indicator);
153 deco = root;
154 } else {
155 deco = deco->next;
156 }
157 }
158 }
159
160 int DecorationList::AllOnFor(int position) {
161 int mask = 0;
162 for (Decoration *deco=root; deco; deco = deco->next) {
163 if (deco->rs.ValueAt(position)) {
164 mask |= 1 << deco->indicator;
165 }
166 }
167 return mask;
168 }
169
170 int DecorationList::ValueAt(int indicator, int position) {
171 Decoration *deco = DecorationFromIndicator(indicator);
172 if (deco) {
173 return deco->rs.ValueAt(position);
174 }
175 return 0;
176 }
177
178 int DecorationList::Start(int indicator, int position) {
179 Decoration *deco = DecorationFromIndicator(indicator);
180 if (deco) {
181 return deco->rs.StartRun(position);
182 }
183 return 0;
184 }
185
186 int DecorationList::End(int indicator, int position) {
187 Decoration *deco = DecorationFromIndicator(indicator);
188 if (deco) {
189 return deco->rs.EndRun(position);
190 }
191 return 0;
192 }