1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
|
// Scintilla source code edit control
/** @file PositionCache.h
** Classes for caching layout information.
**/
// Copyright 1998-2009 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
#ifndef POSITIONCACHE_H
#define POSITIONCACHE_H
namespace Scintilla::Internal {
/**
* A point in document space.
* Uses double for sufficient resolution in large (>20,000,000 line) documents.
*/
class PointDocument {
public:
double x;
double y;
explicit PointDocument(double x_ = 0, double y_ = 0) noexcept : x(x_), y(y_) {
}
// Conversion from Point.
explicit PointDocument(Point pt) noexcept : x(pt.x), y(pt.y) {
}
};
// There are two points for some positions and this enumeration
// can choose between the end of the first line or subline
// and the start of the next line or subline.
enum class PointEnd {
start = 0x0,
lineEnd = 0x1,
subLineEnd = 0x2,
endEither = lineEnd | subLineEnd,
};
class BidiData {
public:
std::vector<std::shared_ptr<Font>> stylesFonts;
std::vector<XYPOSITION> widthReprs;
void Resize(size_t maxLineLength_);
};
/**
*/
class LineLayout {
private:
std::unique_ptr<int []>lineStarts;
int lenLineStarts;
/// Drawing is only performed for @a maxLineLength characters on each line.
Sci::Line lineNumber;
public:
enum { wrapWidthInfinite = 0x7ffffff };
int maxLineLength;
int numCharsInLine;
int numCharsBeforeEOL;
enum class ValidLevel { invalid, checkTextAndStyle, positions, lines } validity;
int xHighlightGuide;
bool highlightColumn;
bool containsCaret;
int edgeColumn;
std::unique_ptr<char[]> chars;
std::unique_ptr<unsigned char[]> styles;
std::unique_ptr<XYPOSITION[]> positions;
unsigned char bracePreviousStyles[2];
std::unique_ptr<BidiData> bidiData;
// Wrapped line support
int widthLine;
int lines;
XYPOSITION wrapIndent; // In pixels
LineLayout(Sci::Line lineNumber_, int maxLineLength_);
// Deleted so LineLayout objects can not be copied.
LineLayout(const LineLayout &) = delete;
LineLayout(LineLayout &&) = delete;
void operator=(const LineLayout &) = delete;
void operator=(LineLayout &&) = delete;
virtual ~LineLayout();
void Resize(int maxLineLength_);
void ReSet(Sci::Line lineNumber_, Sci::Position maxLineLength_);
void EnsureBidiData();
void Free() noexcept;
void ClearPositions();
void Invalidate(ValidLevel validity_) noexcept;
Sci::Line LineNumber() const noexcept;
bool CanHold(Sci::Line lineDoc, int lineLength_) const noexcept;
int LineStart(int line) const noexcept;
int LineLength(int line) const noexcept;
enum class Scope { visibleOnly, includeEnd };
int LineLastVisible(int line, Scope scope) const noexcept;
Range SubLineRange(int subLine, Scope scope) const noexcept;
bool InLine(int offset, int line) const noexcept;
int SubLineFromPosition(int posInLine, PointEnd pe) const noexcept;
void AddLineStart(Sci::Position start);
void SetBracesHighlight(Range rangeLine, const Sci::Position braces[],
char bracesMatchStyle, int xHighlight, bool ignoreStyle);
void RestoreBracesHighlight(Range rangeLine, const Sci::Position braces[], bool ignoreStyle);
int FindBefore(XYPOSITION x, Range range) const noexcept;
int FindPositionFromX(XYPOSITION x, Range range, bool charPosition) const noexcept;
Point PointFromPosition(int posInLine, int lineHeight, PointEnd pe) const noexcept;
XYPOSITION XInLine(Sci::Position index) const noexcept;
Interval Span(int start, int end) const noexcept;
Interval SpanByte(int index) const noexcept;
int EndLineStyle() const noexcept;
void WrapLine(const Document *pdoc, Sci::Position posLineStart, Wrap wrapState, XYPOSITION wrapWidth);
};
struct ScreenLine : public IScreenLine {
const LineLayout *ll;
size_t start;
size_t len;
XYPOSITION width;
XYPOSITION height;
int ctrlCharPadding;
XYPOSITION tabWidth;
int tabWidthMinimumPixels;
ScreenLine(const LineLayout *ll_, int subLine, const ViewStyle &vs, XYPOSITION width_, int tabWidthMinimumPixels_);
// Deleted so ScreenLine objects can not be copied.
ScreenLine(const ScreenLine &) = delete;
ScreenLine(ScreenLine &&) = delete;
void operator=(const ScreenLine &) = delete;
void operator=(ScreenLine &&) = delete;
virtual ~ScreenLine();
std::string_view Text() const override;
size_t Length() const override;
size_t RepresentationCount() const override;
XYPOSITION Width() const override;
XYPOSITION Height() const override;
XYPOSITION TabWidth() const override;
XYPOSITION TabWidthMinimumPixels() const override;
const Font *FontOfPosition(size_t position) const override;
XYPOSITION RepresentationWidth(size_t position) const override;
XYPOSITION TabPositionAfter(XYPOSITION xPosition) const override;
};
struct SignificantLines {
Sci::Line lineCaret;
Sci::Line lineTop;
Sci::Line linesOnScreen;
Scintilla::LineCache level;
bool LineMayCache(Sci::Line line) const noexcept;
};
/**
*/
class LineLayoutCache {
public:
private:
Scintilla::LineCache level;
std::vector<std::shared_ptr<LineLayout>>cache;
LineLayout::ValidLevel maxValidity;
int styleClock;
size_t EntryForLine(Sci::Line line) const noexcept;
void AllocateForLevel(Sci::Line linesOnScreen, Sci::Line linesInDoc);
public:
LineLayoutCache();
// Deleted so LineLayoutCache objects can not be copied.
LineLayoutCache(const LineLayoutCache &) = delete;
LineLayoutCache(LineLayoutCache &&) = delete;
void operator=(const LineLayoutCache &) = delete;
void operator=(LineLayoutCache &&) = delete;
virtual ~LineLayoutCache();
void Deallocate() noexcept;
void Invalidate(LineLayout::ValidLevel validity_) noexcept;
void SetLevel(Scintilla::LineCache level_) noexcept;
Scintilla::LineCache GetLevel() const noexcept { return level; }
std::shared_ptr<LineLayout> Retrieve(Sci::Line lineNumber, Sci::Line lineCaret, int maxChars, int styleClock_,
Sci::Line linesOnScreen, Sci::Line linesInDoc);
};
class Representation {
public:
static constexpr size_t maxLength = 200;
std::string stringRep;
RepresentationAppearance appearance;
ColourRGBA colour;
explicit Representation(std::string_view value="", RepresentationAppearance appearance_= RepresentationAppearance::Blob) :
stringRep(value), appearance(appearance_) {
}
};
typedef std::map<unsigned int, Representation> MapRepresentation;
const char *ControlCharacterString(unsigned char ch) noexcept;
void Hexits(char *hexits, int ch) noexcept;
class SpecialRepresentations {
MapRepresentation mapReprs;
unsigned short startByteHasReprs[0x100] {};
unsigned int maxKey = 0;
bool crlf = false;
public:
void SetRepresentation(std::string_view charBytes, std::string_view value);
void SetRepresentationAppearance(std::string_view charBytes, RepresentationAppearance appearance);
void SetRepresentationColour(std::string_view charBytes, ColourRGBA colour);
void ClearRepresentation(std::string_view charBytes);
const Representation *GetRepresentation(std::string_view charBytes) const;
const Representation *RepresentationFromCharacter(std::string_view charBytes) const;
bool ContainsCrLf() const noexcept {
return crlf;
}
bool MayContain(unsigned char ch) const noexcept {
return startByteHasReprs[ch] != 0;
}
void Clear();
void SetDefaultRepresentations(int dbcsCodePage);
};
struct TextSegment {
int start;
int length;
const Representation *representation;
TextSegment(int start_=0, int length_=0, const Representation *representation_=nullptr) noexcept :
start(start_), length(length_), representation(representation_) {
}
int end() const noexcept {
return start + length;
}
};
// Class to break a line of text into shorter runs at sensible places.
class BreakFinder {
const LineLayout *ll;
const Range lineRange;
int nextBreak;
std::vector<int> selAndEdge;
unsigned int saeCurrentPos;
int saeNext;
int subBreak;
const Document *pdoc;
const EncodingFamily encodingFamily;
const SpecialRepresentations *preprs;
void Insert(Sci::Position val);
public:
// If a whole run is longer than lengthStartSubdivision then subdivide
// into smaller runs at spaces or punctuation.
enum { lengthStartSubdivision = 300 };
// Try to make each subdivided run lengthEachSubdivision or shorter.
enum { lengthEachSubdivision = 100 };
enum class BreakFor {
Text = 0,
Selection = 1,
Foreground = 2,
ForegroundAndSelection = 3,
};
BreakFinder(const LineLayout *ll_, const Selection *psel, Range lineRange_, Sci::Position posLineStart,
XYPOSITION xStart, BreakFor breakFor, const Document *pdoc_, const SpecialRepresentations *preprs_, const ViewStyle *pvsDraw);
// Deleted so BreakFinder objects can not be copied.
BreakFinder(const BreakFinder &) = delete;
BreakFinder(BreakFinder &&) = delete;
void operator=(const BreakFinder &) = delete;
void operator=(BreakFinder &&) = delete;
~BreakFinder() noexcept;
TextSegment Next();
bool More() const noexcept;
};
class IPositionCache {
public:
virtual ~IPositionCache() = default;
virtual void Clear() noexcept = 0;
virtual void SetSize(size_t size_) = 0;
virtual size_t GetSize() const noexcept = 0;
virtual void MeasureWidths(Surface *surface, const ViewStyle &vstyle, unsigned int styleNumber,
bool unicode, std::string_view sv, XYPOSITION *positions, bool needsLocking) = 0;
};
std::unique_ptr<IPositionCache> CreatePositionCache();
}
#endif
|