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