File: PositionCache.h

package info (click to toggle)
scite 4.4.5-2
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 12,928 kB
  • sloc: cpp: 145,539; ansic: 19,277; python: 6,120; makefile: 806; perl: 200; sh: 184; sql: 160; objc: 18; ruby: 6; tcl: 6; php: 4
file content (289 lines) | stat: -rw-r--r-- 9,332 bytes parent folder | download
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
281
282
283
284
285
286
287
288
289
// 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 {

inline constexpr bool IsEOLChar(int ch) noexcept {
	return (ch == '\r') || (ch == '\n');
}

inline constexpr bool IsSpaceOrTab(int ch) noexcept {
	return ch == ' ' || ch == '\t';
}

/**
* 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 PointEnd {
	peDefault = 0x0,
	peLineEnd = 0x1,
	peSubLineEnd = 0x2
};

class BidiData {
public:
	std::vector<FontAlias> stylesFonts;
	std::vector<XYPOSITION> widthReprs;
	void Resize(size_t maxLineLength_);
};

/**
 */
class LineLayout {
private:
	friend class LineLayoutCache;
	std::unique_ptr<int []>lineStarts;
	int lenLineStarts;
	/// Drawing is only performed for @a maxLineLength characters on each line.
	Sci::Line lineNumber;
	bool inCache;
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;
	char bracePreviousStyles[2];

	std::unique_ptr<BidiData> bidiData;

	// Hotspot support
	Range hotspot;

	// Wrapped line support
	int widthLine;
	int lines;
	XYPOSITION wrapIndent; // In pixels

	explicit LineLayout(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 EnsureBidiData();
	void Free() noexcept;
	void Invalidate(ValidLevel validity_) 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 SetLineStart(int line, int 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;
	int EndLineStyle() const noexcept;
};

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;
};

/**
 */
class LineLayoutCache {
	int level;
	std::vector<std::unique_ptr<LineLayout>>cache;
	bool allInvalidated;
	int styleClock;
	int useCount;
	void Allocate(size_t length_);
	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;
	enum {
		llcNone=SC_CACHE_NONE,
		llcCaret=SC_CACHE_CARET,
		llcPage=SC_CACHE_PAGE,
		llcDocument=SC_CACHE_DOCUMENT
	};
	void Invalidate(LineLayout::ValidLevel validity_) noexcept;
	void SetLevel(int level_) noexcept;
	int GetLevel() const noexcept { return level; }
	LineLayout *Retrieve(Sci::Line lineNumber, Sci::Line lineCaret, int maxChars, int styleClock_,
		Sci::Line linesOnScreen, Sci::Line linesInDoc);
	void Dispose(LineLayout *ll) noexcept;
};

class PositionCacheEntry {
	unsigned int styleNumber:8;
	unsigned int len:8;
	unsigned int clock:16;
	std::unique_ptr<XYPOSITION []> positions;
public:
	PositionCacheEntry() noexcept;
	// Copy constructor not currently used, but needed for being element in std::vector.
	PositionCacheEntry(const PositionCacheEntry &);
	// Deleted so PositionCacheEntry objects can not be assigned.
	PositionCacheEntry(PositionCacheEntry &&) = delete;
	void operator=(const PositionCacheEntry &) = delete;
	void operator=(PositionCacheEntry &&) = delete;
	~PositionCacheEntry();
	void Set(unsigned int styleNumber_, const char *s_, unsigned int len_, const XYPOSITION *positions_, unsigned int clock_);
	void Clear() noexcept;
	bool Retrieve(unsigned int styleNumber_, const char *s_, unsigned int len_, XYPOSITION *positions_) const noexcept;
	static unsigned int Hash(unsigned int styleNumber_, const char *s, unsigned int len_) noexcept;
	bool NewerThan(const PositionCacheEntry &other) const noexcept;
	void ResetClock() noexcept;
};

class Representation {
public:
	std::string stringRep;
	explicit Representation(const char *value="") : stringRep(value) {
	}
};

typedef std::map<unsigned int, Representation> MapRepresentation;

class SpecialRepresentations {
	MapRepresentation mapReprs;
	short startByteHasReprs[0x100];
public:
	SpecialRepresentations();
	void SetRepresentation(const char *charBytes, const char *value);
	void ClearRepresentation(const char *charBytes);
	const Representation *RepresentationFromCharacter(const char *charBytes, size_t len) const;
	bool Contains(const char *charBytes, size_t len) const;
	void Clear();
};

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;
	Range lineRange;
	Sci::Position posLineStart;
	int nextBreak;
	std::vector<int> selAndEdge;
	unsigned int saeCurrentPos;
	int saeNext;
	int subBreak;
	const Document *pdoc;
	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 };
	BreakFinder(const LineLayout *ll_, const Selection *psel, Range lineRange_, Sci::Position posLineStart_,
		int xStart, bool breakForSelection, 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();
	TextSegment Next();
	bool More() const noexcept;
};

class PositionCache {
	std::vector<PositionCacheEntry> pces;
	unsigned int clock;
	bool allClear;
public:
	PositionCache();
	// Deleted so PositionCache objects can not be copied.
	PositionCache(const PositionCache &) = delete;
	PositionCache(PositionCache &&) = delete;
	void operator=(const PositionCache &) = delete;
	void operator=(PositionCache &&) = delete;
	~PositionCache();
	void Clear() noexcept;
	void SetSize(size_t size_);
	size_t GetSize() const noexcept { return pces.size(); }
	void MeasureWidths(Surface *surface, const ViewStyle &vstyle, unsigned int styleNumber,
		const char *s, unsigned int len, XYPOSITION *positions, const Document *pdoc);
};

}

#endif