1 // Scintilla source code edit control
2 /** @file PositionCache.h
3  ** Classes for caching layout information.
4  **/
5 // Copyright 1998-2009 by Neil Hodgson <neilh@scintilla.org>
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 #ifdef SCI_NAMESPACE
12 namespace Scintilla {
13 #endif
14 
IsEOLChar(char ch)15 static inline bool IsEOLChar(char ch) {
16 	return (ch == '\r') || (ch == '\n');
17 }
18 
19 /**
20  */
21 class LineLayout {
22 private:
23 	friend class LineLayoutCache;
24 	int *lineStarts;
25 	int lenLineStarts;
26 	/// Drawing is only performed for @a maxLineLength characters on each line.
27 	int lineNumber;
28 	bool inCache;
29 public:
30 	enum { wrapWidthInfinite = 0x7ffffff };
31 	int maxLineLength;
32 	int numCharsInLine;
33 	int numCharsBeforeEOL;
34 	enum validLevel { llInvalid, llCheckTextAndStyle, llPositions, llLines } validity;
35 	int xHighlightGuide;
36 	bool highlightColumn;
37 	Selection *psel;
38 	bool containsCaret;
39 	int edgeColumn;
40 	char *chars;
41 	unsigned char *styles;
42 	int styleBitsSet;
43 	char *indicators;
44 	XYPOSITION *positions;
45 	char bracePreviousStyles[2];
46 
47 	// Hotspot support
48 	int hsStart;
49 	int hsEnd;
50 
51 	// Wrapped line support
52 	int widthLine;
53 	int lines;
54 	XYPOSITION wrapIndent; // In pixels
55 
56 	LineLayout(int maxLineLength_);
57 	virtual ~LineLayout();
58 	void Resize(int maxLineLength_);
59 	void Free();
60 	void Invalidate(validLevel validity_);
61 	int LineStart(int line) const;
62 	int LineLastVisible(int line) const;
63 	bool InLine(int offset, int line) const;
64 	void SetLineStart(int line, int start);
65 	void SetBracesHighlight(Range rangeLine, Position braces[],
66 		char bracesMatchStyle, int xHighlight, bool ignoreStyle);
67 	void RestoreBracesHighlight(Range rangeLine, Position braces[], bool ignoreStyle);
68 	int FindBefore(XYPOSITION x, int lower, int upper) const;
69 	int EndLineStyle() const;
70 };
71 
72 /**
73  */
74 class LineLayoutCache {
75 	int level;
76 	int length;
77 	int size;
78 	LineLayout **cache;
79 	bool allInvalidated;
80 	int styleClock;
81 	int useCount;
82 	void Allocate(int length_);
83 	void AllocateForLevel(int linesOnScreen, int linesInDoc);
84 public:
85 	LineLayoutCache();
86 	virtual ~LineLayoutCache();
87 	void Deallocate();
88 	enum {
89 		llcNone=SC_CACHE_NONE,
90 		llcCaret=SC_CACHE_CARET,
91 		llcPage=SC_CACHE_PAGE,
92 		llcDocument=SC_CACHE_DOCUMENT
93 	};
94 	void Invalidate(LineLayout::validLevel validity_);
95 	void SetLevel(int level_);
GetLevel()96 	int GetLevel() const { return level; }
97 	LineLayout *Retrieve(int lineNumber, int lineCaret, int maxChars, int styleClock_,
98 		int linesOnScreen, int linesInDoc);
99 	void Dispose(LineLayout *ll);
100 };
101 
102 class PositionCacheEntry {
103 	unsigned int styleNumber:8;
104 	unsigned int len:8;
105 	unsigned int clock:16;
106 	XYPOSITION *positions;
107 public:
108 	PositionCacheEntry();
109 	~PositionCacheEntry();
110 	void Set(unsigned int styleNumber_, const char *s_, unsigned int len_, XYPOSITION *positions_, unsigned int clock);
111 	void Clear();
112 	bool Retrieve(unsigned int styleNumber_, const char *s_, unsigned int len_, XYPOSITION *positions_) const;
113 	static int Hash(unsigned int styleNumber_, const char *s, unsigned int len);
114 	bool NewerThan(const PositionCacheEntry &other) const;
115 	void ResetClock();
116 };
117 
118 // Class to break a line of text into shorter runs at sensible places.
119 class BreakFinder {
120 	LineLayout *ll;
121 	int lineStart;
122 	int lineEnd;
123 	int posLineStart;
124 	int nextBreak;
125 	int *selAndEdge;
126 	unsigned int saeSize;
127 	unsigned int saeLen;
128 	unsigned int saeCurrentPos;
129 	int saeNext;
130 	int subBreak;
131 	Document *pdoc;
132 	void Insert(int val);
133 public:
134 	// If a whole run is longer than lengthStartSubdivision then subdivide
135 	// into smaller runs at spaces or punctuation.
136 	enum { lengthStartSubdivision = 300 };
137 	// Try to make each subdivided run lengthEachSubdivision or shorter.
138 	enum { lengthEachSubdivision = 100 };
139 	BreakFinder(LineLayout *ll_, int lineStart_, int lineEnd_, int posLineStart_,
140 		int xStart, bool breakForSelection, Document *pdoc_);
141 	~BreakFinder();
142 	int First() const;
143 	int Next();
144 };
145 
146 class PositionCache {
147 	PositionCacheEntry *pces;
148 	size_t size;
149 	unsigned int clock;
150 	bool allClear;
151 public:
152 	PositionCache();
153 	~PositionCache();
154 	void Clear();
155 	void SetSize(size_t size_);
GetSize()156 	size_t GetSize() const { return size; }
157 	void MeasureWidths(Surface *surface, ViewStyle &vstyle, unsigned int styleNumber,
158 		const char *s, unsigned int len, XYPOSITION *positions, Document *pdoc);
159 };
160 
IsSpaceOrTab(int ch)161 inline bool IsSpaceOrTab(int ch) {
162 	return ch == ' ' || ch == '\t';
163 }
164 
165 #ifdef SCI_NAMESPACE
166 }
167 #endif
168 
169 #endif
170