Add utils_get_real_path() and use it
[geany-mirror.git] / scintilla / src / Decoration.cxx
blobf5f82832f432849674df02d6577fe401a3006987
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 <cstddef>
8 #include <cstdlib>
9 #include <cstring>
10 #include <cstdio>
11 #include <cstdarg>
13 #include <stdexcept>
14 #include <vector>
15 #include <algorithm>
16 #include <memory>
18 #include "Platform.h"
20 #include "Scintilla.h"
21 #include "Position.h"
22 #include "SplitVector.h"
23 #include "Partitioning.h"
24 #include "RunStyles.h"
25 #include "Decoration.h"
27 #ifdef SCI_NAMESPACE
28 using namespace Scintilla;
29 #endif
31 Decoration::Decoration(int indicator_) : indicator(indicator_) {
34 Decoration::~Decoration() {
37 bool Decoration::Empty() const {
38 return (rs.Runs() == 1) && (rs.AllSameAs(0));
41 DecorationList::DecorationList() : currentIndicator(0), currentValue(1), current(nullptr),
42 lengthDocument(0), clickNotified(false) {
45 DecorationList::~DecorationList() {
46 current = nullptr;
49 Decoration *DecorationList::DecorationFromIndicator(int indicator) {
50 for (const std::unique_ptr<Decoration> &deco : decorationList) {
51 if (deco->Indicator() == indicator) {
52 return deco.get();
55 return nullptr;
58 Decoration *DecorationList::Create(int indicator, int length) {
59 currentIndicator = indicator;
60 std::unique_ptr<Decoration> decoNew(new Decoration(indicator));
61 decoNew->rs.InsertSpace(0, length);
63 std::vector<std::unique_ptr<Decoration>>::iterator it = std::lower_bound(
64 decorationList.begin(), decorationList.end(), decoNew,
65 [](const std::unique_ptr<Decoration> &a, const std::unique_ptr<Decoration> &b) {
66 return a->Indicator() < b->Indicator();
67 });
68 std::vector<std::unique_ptr<Decoration>>::iterator itAdded =
69 decorationList.insert(it, std::move(decoNew));
71 SetView();
73 return itAdded->get();
76 void DecorationList::Delete(int indicator) {
77 decorationList.erase(std::remove_if(decorationList.begin(), decorationList.end(),
78 [=](const std::unique_ptr<Decoration> &deco) {
79 return deco->Indicator() == indicator;
80 }), decorationList.end());
81 current = nullptr;
82 SetView();
85 void DecorationList::SetCurrentIndicator(int indicator) {
86 currentIndicator = indicator;
87 current = DecorationFromIndicator(indicator);
88 currentValue = 1;
91 void DecorationList::SetCurrentValue(int value) {
92 currentValue = value ? value : 1;
95 bool DecorationList::FillRange(int &position, int value, int &fillLength) {
96 if (!current) {
97 current = DecorationFromIndicator(currentIndicator);
98 if (!current) {
99 current = Create(currentIndicator, lengthDocument);
102 const bool changed = current->rs.FillRange(position, value, fillLength);
103 if (current->Empty()) {
104 Delete(currentIndicator);
106 return changed;
109 void DecorationList::InsertSpace(int position, int insertLength) {
110 const bool atEnd = position == lengthDocument;
111 lengthDocument += insertLength;
112 for (const std::unique_ptr<Decoration> &deco : decorationList) {
113 deco->rs.InsertSpace(position, insertLength);
114 if (atEnd) {
115 deco->rs.FillRange(position, 0, insertLength);
120 void DecorationList::DeleteRange(int position, int deleteLength) {
121 lengthDocument -= deleteLength;
122 for (const std::unique_ptr<Decoration> &deco : decorationList) {
123 deco->rs.DeleteRange(position, deleteLength);
125 DeleteAnyEmpty();
126 if (decorationList.size() != decorationView.size()) {
127 // One or more empty decorations deleted so update view.
128 current = nullptr;
129 SetView();
133 void DecorationList::DeleteLexerDecorations() {
134 decorationList.erase(std::remove_if(decorationList.begin(), decorationList.end(),
135 [=](const std::unique_ptr<Decoration> &deco) {
136 return deco->Indicator() < INDIC_CONTAINER;
137 }), decorationList.end());
138 current = nullptr;
139 SetView();
142 void DecorationList::DeleteAnyEmpty() {
143 if (lengthDocument == 0) {
144 decorationList.clear();
145 } else {
146 decorationList.erase(std::remove_if(decorationList.begin(), decorationList.end(),
147 [=](const std::unique_ptr<Decoration> &deco) {
148 return deco->Empty();
149 }), decorationList.end());
153 void DecorationList::SetView() {
154 decorationView.clear();
155 for (const std::unique_ptr<Decoration> &deco : decorationList) {
156 decorationView.push_back(deco.get());
160 int DecorationList::AllOnFor(int position) const {
161 int mask = 0;
162 for (const std::unique_ptr<Decoration> &deco : decorationList) {
163 if (deco->rs.ValueAt(position)) {
164 if (deco->Indicator() < INDIC_IME) {
165 mask |= 1 << deco->Indicator();
169 return mask;
172 int DecorationList::ValueAt(int indicator, int position) {
173 const Decoration *deco = DecorationFromIndicator(indicator);
174 if (deco) {
175 return deco->rs.ValueAt(position);
177 return 0;
180 int DecorationList::Start(int indicator, int position) {
181 const Decoration *deco = DecorationFromIndicator(indicator);
182 if (deco) {
183 return deco->rs.StartRun(position);
185 return 0;
188 int DecorationList::End(int indicator, int position) {
189 const Decoration *deco = DecorationFromIndicator(indicator);
190 if (deco) {
191 return deco->rs.EndRun(position);
193 return 0;