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