1 /** @file Decoration.cxx
2 ** Visual elements added over text.
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.
17 #include "Scintilla.h"
19 #include "SplitVector.h"
20 #include "Partitioning.h"
21 #include "RunStyles.h"
22 #include "Decoration.h"
25 using namespace Scintilla
;
28 Decoration::Decoration(int indicator_
) : next(0), indicator(indicator_
) {
31 Decoration::~Decoration() {
34 bool Decoration::Empty() const {
35 return (rs
.Runs() == 1) && (rs
.AllSameAs(0));
38 DecorationList::DecorationList() : currentIndicator(0), currentValue(1), current(0),
39 lengthDocument(0), root(0), clickNotified(false) {
42 DecorationList::~DecorationList() {
43 Decoration
*deco
= root
;
45 Decoration
*decoNext
= deco
->next
;
53 Decoration
*DecorationList::DecorationFromIndicator(int indicator
) {
54 for (Decoration
*deco
=root
; deco
; deco
= deco
->next
) {
55 if (deco
->indicator
== indicator
) {
62 Decoration
*DecorationList::Create(int indicator
, int length
) {
63 currentIndicator
= indicator
;
64 Decoration
*decoNew
= new Decoration(indicator
);
65 decoNew
->rs
.InsertSpace(0, length
);
67 Decoration
*decoPrev
= 0;
68 Decoration
*deco
= root
;
70 while (deco
&& (deco
->indicator
< indicator
)) {
79 decoPrev
->next
= decoNew
;
84 void DecorationList::Delete(int indicator
) {
85 Decoration
*decoToDelete
= 0;
87 if (root
->indicator
== indicator
) {
91 Decoration
*deco
=root
;
92 while (deco
->next
&& !decoToDelete
) {
93 if (deco
->next
&& deco
->next
->indicator
== indicator
) {
94 decoToDelete
= deco
->next
;
95 deco
->next
= decoToDelete
->next
;
108 void DecorationList::SetCurrentIndicator(int indicator
) {
109 currentIndicator
= indicator
;
110 current
= DecorationFromIndicator(indicator
);
114 void DecorationList::SetCurrentValue(int value
) {
115 currentValue
= value
? value
: 1;
118 bool DecorationList::FillRange(int &position
, int value
, int &fillLength
) {
120 current
= DecorationFromIndicator(currentIndicator
);
122 current
= Create(currentIndicator
, lengthDocument
);
125 bool changed
= current
->rs
.FillRange(position
, value
, fillLength
);
126 if (current
->Empty()) {
127 Delete(currentIndicator
);
132 void DecorationList::InsertSpace(int position
, int insertLength
) {
133 const bool atEnd
= position
== lengthDocument
;
134 lengthDocument
+= insertLength
;
135 for (Decoration
*deco
=root
; deco
; deco
= deco
->next
) {
136 deco
->rs
.InsertSpace(position
, insertLength
);
138 deco
->rs
.FillRange(position
, 0, insertLength
);
143 void DecorationList::DeleteRange(int position
, int deleteLength
) {
144 lengthDocument
-= deleteLength
;
146 for (deco
=root
; deco
; deco
= deco
->next
) {
147 deco
->rs
.DeleteRange(position
, deleteLength
);
152 void DecorationList::DeleteAnyEmpty() {
153 Decoration
*deco
= root
;
155 if ((lengthDocument
== 0) || deco
->Empty()) {
156 Delete(deco
->indicator
);
164 int DecorationList::AllOnFor(int position
) const {
166 for (Decoration
*deco
=root
; deco
; deco
= deco
->next
) {
167 if (deco
->rs
.ValueAt(position
)) {
168 if (deco
->indicator
< INDIC_IME
) {
169 mask
|= 1 << deco
->indicator
;
176 int DecorationList::ValueAt(int indicator
, int position
) {
177 Decoration
*deco
= DecorationFromIndicator(indicator
);
179 return deco
->rs
.ValueAt(position
);
184 int DecorationList::Start(int indicator
, int position
) {
185 Decoration
*deco
= DecorationFromIndicator(indicator
);
187 return deco
->rs
.StartRun(position
);
192 int DecorationList::End(int indicator
, int position
) {
193 Decoration
*deco
= DecorationFromIndicator(indicator
);
195 return deco
->rs
.EndRun(position
);