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.
16 #include "Scintilla.h"
17 #include "SplitVector.h"
18 #include "Partitioning.h"
19 #include "RunStyles.h"
20 #include "Decoration.h"
23 using namespace Scintilla
;
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
;
43 Decoration
*decoNext
= deco
->next
;
51 Decoration
*DecorationList::DecorationFromIndicator(int indicator
) {
52 for (Decoration
*deco
=root
; deco
; deco
= deco
->next
) {
53 if (deco
->indicator
== indicator
) {
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
)) {
77 decoPrev
->next
= decoNew
;
82 void DecorationList::Delete(int indicator
) {
83 Decoration
*decoToDelete
= 0;
85 if (root
->indicator
== indicator
) {
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
;
106 void DecorationList::SetCurrentIndicator(int indicator
) {
107 currentIndicator
= indicator
;
108 current
= DecorationFromIndicator(indicator
);
112 void DecorationList::SetCurrentValue(int value
) {
113 currentValue
= value
? value
: 1;
116 bool DecorationList::FillRange(int &position
, int value
, int &fillLength
) {
118 current
= DecorationFromIndicator(currentIndicator
);
120 current
= Create(currentIndicator
, lengthDocument
);
123 bool changed
= current
->rs
.FillRange(position
, value
, fillLength
);
124 if (current
->Empty()) {
125 Delete(currentIndicator
);
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
);
136 deco
->rs
.FillRange(position
, 0, insertLength
);
141 void DecorationList::DeleteRange(int position
, int deleteLength
) {
142 lengthDocument
-= deleteLength
;
144 for (deco
=root
; deco
; deco
= deco
->next
) {
145 deco
->rs
.DeleteRange(position
, deleteLength
);
150 void DecorationList::DeleteAnyEmpty() {
151 Decoration
*deco
= root
;
153 if ((lengthDocument
== 0) || deco
->Empty()) {
154 Delete(deco
->indicator
);
162 int DecorationList::AllOnFor(int position
) const {
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
;
174 int DecorationList::ValueAt(int indicator
, int position
) {
175 Decoration
*deco
= DecorationFromIndicator(indicator
);
177 return deco
->rs
.ValueAt(position
);
182 int DecorationList::Start(int indicator
, int position
) {
183 Decoration
*deco
= DecorationFromIndicator(indicator
);
185 return deco
->rs
.StartRun(position
);
190 int DecorationList::End(int indicator
, int position
) {
191 Decoration
*deco
= DecorationFromIndicator(indicator
);
193 return deco
->rs
.EndRun(position
);