]>
git.saurik.com Git - wxWidgets.git/blob - src/stc/scintilla/src/RunStyles.cxx
ae32c7380de8de8d4711eaea61c9ee32677508fc
1 /** @file RunStyles.cxx
2 ** Data structure used to store sparse styles.
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.
14 #include "Scintilla.h"
15 #include "SplitVector.h"
16 #include "Partitioning.h"
17 #include "RunStyles.h"
20 using namespace Scintilla
;
23 // Find the first run at a position
24 int RunStyles::RunFromPosition(int position
) {
25 int run
= starts
->PartitionFromPosition(position
);
26 // Go to first element with this position
27 while ((run
> 0) && (position
== starts
->PositionFromPartition(run
-1))) {
33 // If there is no run boundary at position, insert one continuing style.
34 int RunStyles::SplitRun(int position
) {
35 int run
= RunFromPosition(position
);
36 int posRun
= starts
->PositionFromPartition(run
);
37 if (posRun
< position
) {
38 int runStyle
= ValueAt(position
);
40 starts
->InsertPartition(run
, position
);
41 styles
->InsertValue(run
, 1, runStyle
);
46 void RunStyles::RemoveRun(int run
) {
47 starts
->RemovePartition(run
);
48 styles
->DeleteRange(run
, 1);
51 void RunStyles::RemoveRunIfEmpty(int run
) {
52 if ((run
< starts
->Partitions()) && (starts
->Partitions() > 1)) {
53 if (starts
->PositionFromPartition(run
) == starts
->PositionFromPartition(run
+1)) {
59 void RunStyles::RemoveRunIfSameAsPrevious(int run
) {
60 if ((run
> 0) && (run
< starts
->Partitions())) {
61 if (styles
->ValueAt(run
-1) == styles
->ValueAt(run
)) {
67 RunStyles::RunStyles() {
68 starts
= new Partitioning(8);
69 styles
= new SplitVector
<int>();
70 styles
->InsertValue(0, 2, 0);
73 RunStyles::~RunStyles() {
80 int RunStyles::Length() const {
81 return starts
->PositionFromPartition(starts
->Partitions());
84 int RunStyles::ValueAt(int position
) const {
85 return styles
->ValueAt(starts
->PartitionFromPosition(position
));
88 int RunStyles::FindNextChange(int position
, int end
) {
89 int run
= starts
->PartitionFromPosition(position
);
90 if (run
< starts
->Partitions()) {
91 int runChange
= starts
->PositionFromPartition(run
);
92 if (runChange
> position
)
94 int nextChange
= starts
->PositionFromPartition(run
+ 1);
95 if (nextChange
> position
) {
97 } else if (position
< end
) {
107 int RunStyles::StartRun(int position
) {
108 return starts
->PositionFromPartition(starts
->PartitionFromPosition(position
));
111 int RunStyles::EndRun(int position
) {
112 return starts
->PositionFromPartition(starts
->PartitionFromPosition(position
) + 1);
115 bool RunStyles::FillRange(int &position
, int value
, int &fillLength
) {
116 int end
= position
+ fillLength
;
117 int runEnd
= RunFromPosition(end
);
118 if (styles
->ValueAt(runEnd
) == value
) {
119 // End already has value so trim range.
120 end
= starts
->PositionFromPartition(runEnd
);
121 if (position
>= end
) {
122 // Whole range is already same as value so no action
125 fillLength
= end
- position
;
127 runEnd
= SplitRun(end
);
129 int runStart
= RunFromPosition(position
);
130 if (styles
->ValueAt(runStart
) == value
) {
131 // Start is in expected value so trim range.
133 position
= starts
->PositionFromPartition(runStart
);
134 fillLength
= end
- position
;
136 if (starts
->PositionFromPartition(runStart
) < position
) {
137 runStart
= SplitRun(position
);
141 if (runStart
< runEnd
) {
142 styles
->SetValueAt(runStart
, value
);
143 // Remove each old run over the range
144 for (int run
=runStart
+1; run
<runEnd
; run
++) {
145 RemoveRun(runStart
+1);
147 runEnd
= RunFromPosition(end
);
148 RemoveRunIfSameAsPrevious(runEnd
);
149 RemoveRunIfSameAsPrevious(runStart
);
154 void RunStyles::SetValueAt(int position
, int value
) {
156 FillRange(position
, value
, len
);
159 void RunStyles::InsertSpace(int position
, int insertLength
) {
160 int runStart
= RunFromPosition(position
);
161 if (starts
->PositionFromPartition(runStart
) == position
) {
162 int runStyle
= ValueAt(position
);
163 // Inserting at start of run so make previous longer
165 // Inserting at start of document so ensure 0
167 styles
->SetValueAt(0, 0);
168 starts
->InsertPartition(1, 0);
169 styles
->InsertValue(1, 1, runStyle
);
170 starts
->InsertText(0, insertLength
);
172 starts
->InsertText(runStart
, insertLength
);
176 starts
->InsertText(runStart
-1, insertLength
);
178 // Insert at end of run so do not extend style
179 starts
->InsertText(runStart
, insertLength
);
183 starts
->InsertText(runStart
, insertLength
);
187 void RunStyles::DeleteAll() {
192 starts
= new Partitioning(8);
193 styles
= new SplitVector
<int>();
194 styles
->InsertValue(0, 2, 0);
197 void RunStyles::DeleteRange(int position
, int deleteLength
) {
198 int end
= position
+ deleteLength
;
199 int runStart
= RunFromPosition(position
);
200 int runEnd
= RunFromPosition(end
);
201 if (runStart
== runEnd
) {
202 // Deleting from inside one run
203 starts
->InsertText(runStart
, -deleteLength
);
205 runStart
= SplitRun(position
);
206 runEnd
= SplitRun(end
);
207 starts
->InsertText(runStart
, -deleteLength
);
208 // Remove each old run over the range
209 for (int run
=runStart
; run
<runEnd
; run
++) {
212 RemoveRunIfEmpty(runStart
);
213 RemoveRunIfSameAsPrevious(runStart
);