1 // Scintilla source code edit control
2 /** @file PositionCache.h
3 ** Classes for caching layout information.
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.
8 #ifndef POSITIONCACHE_H
9 #define POSITIONCACHE_H
15 static inline bool IsEOLChar(char ch
) {
16 return (ch
== '\r') || (ch
== '\n');
20 * A point in document space.
21 * Uses double for sufficient resolution in large (>20,000,000 line) documents.
28 explicit PointDocument(double x_
= 0, double y_
= 0) : x(x_
), y(y_
) {
31 // Conversion from Point.
32 explicit PointDocument(Point pt
) : x(pt
.x
), y(pt
.y
) {
36 // There are two points for some positions and this enumeration
37 // can choose between the end of the first line or subline
38 // and the start of the next line or subline.
49 friend class LineLayoutCache
;
50 std::unique_ptr
<int []>lineStarts
;
52 /// Drawing is only performed for @a maxLineLength characters on each line.
56 enum { wrapWidthInfinite
= 0x7ffffff };
60 int numCharsBeforeEOL
;
61 enum validLevel
{ llInvalid
, llCheckTextAndStyle
, llPositions
, llLines
} validity
;
66 std::unique_ptr
<char[]> chars
;
67 std::unique_ptr
<unsigned char[]> styles
;
68 std::unique_ptr
<XYPOSITION
[]> positions
;
69 char bracePreviousStyles
[2];
74 // Wrapped line support
77 XYPOSITION wrapIndent
; // In pixels
79 explicit LineLayout(int maxLineLength_
);
80 // Deleted so LineLayout objects can not be copied.
81 LineLayout(const LineLayout
&) = delete;
82 void operator=(const LineLayout
&) = delete;
83 virtual ~LineLayout();
84 void Resize(int maxLineLength_
);
86 void Invalidate(validLevel validity_
);
87 int LineStart(int line
) const;
88 int LineLastVisible(int line
) const;
89 Range
SubLineRange(int subLine
) const;
90 bool InLine(int offset
, int line
) const;
91 void SetLineStart(int line
, int start
);
92 void SetBracesHighlight(Range rangeLine
, const Sci::Position braces
[],
93 char bracesMatchStyle
, int xHighlight
, bool ignoreStyle
);
94 void RestoreBracesHighlight(Range rangeLine
, const Sci::Position braces
[], bool ignoreStyle
);
95 int FindBefore(XYPOSITION x
, int lower
, int upper
) const;
96 int FindPositionFromX(XYPOSITION x
, Range range
, bool charPosition
) const;
97 Point
PointFromPosition(int posInLine
, int lineHeight
, PointEnd pe
) const;
98 int EndLineStyle() const;
103 class LineLayoutCache
{
105 std::vector
<std::unique_ptr
<LineLayout
>>cache
;
109 void Allocate(size_t length_
);
110 void AllocateForLevel(Sci::Line linesOnScreen
, Sci::Line linesInDoc
);
113 // Deleted so LineLayoutCache objects can not be copied.
114 LineLayoutCache(const LineLayoutCache
&) = delete;
115 void operator=(const LineLayoutCache
&) = delete;
116 virtual ~LineLayoutCache();
119 llcNone
=SC_CACHE_NONE
,
120 llcCaret
=SC_CACHE_CARET
,
121 llcPage
=SC_CACHE_PAGE
,
122 llcDocument
=SC_CACHE_DOCUMENT
124 void Invalidate(LineLayout::validLevel validity_
);
125 void SetLevel(int level_
);
126 int GetLevel() const { return level
; }
127 LineLayout
*Retrieve(Sci::Line lineNumber
, Sci::Line lineCaret
, int maxChars
, int styleClock_
,
128 Sci::Line linesOnScreen
, Sci::Line linesInDoc
);
129 void Dispose(LineLayout
*ll
);
132 class PositionCacheEntry
{
133 unsigned int styleNumber
:8;
135 unsigned int clock
:16;
136 std::unique_ptr
<XYPOSITION
[]> positions
;
138 PositionCacheEntry();
139 // Copy constructor not currently used, but needed for being element in std::vector.
140 PositionCacheEntry(const PositionCacheEntry
&);
141 // Deleted so PositionCacheEntry objects can not be assigned.
142 void operator=(const PositionCacheEntry
&) = delete;
143 ~PositionCacheEntry();
144 void Set(unsigned int styleNumber_
, const char *s_
, unsigned int len_
, XYPOSITION
*positions_
, unsigned int clock_
);
146 bool Retrieve(unsigned int styleNumber_
, const char *s_
, unsigned int len_
, XYPOSITION
*positions_
) const;
147 static unsigned int Hash(unsigned int styleNumber_
, const char *s
, unsigned int len_
);
148 bool NewerThan(const PositionCacheEntry
&other
) const;
152 class Representation
{
154 std::string stringRep
;
155 explicit Representation(const char *value
="") : stringRep(value
) {
159 typedef std::map
<int, Representation
> MapRepresentation
;
161 class SpecialRepresentations
{
162 MapRepresentation mapReprs
;
163 short startByteHasReprs
[0x100];
165 SpecialRepresentations();
166 void SetRepresentation(const char *charBytes
, const char *value
);
167 void ClearRepresentation(const char *charBytes
);
168 const Representation
*RepresentationFromCharacter(const char *charBytes
, size_t len
) const;
169 bool Contains(const char *charBytes
, size_t len
) const;
176 const Representation
*representation
;
177 TextSegment(int start_
=0, int length_
=0, const Representation
*representation_
=0) :
178 start(start_
), length(length_
), representation(representation_
) {
181 return start
+ length
;
185 // Class to break a line of text into shorter runs at sensible places.
187 const LineLayout
*ll
;
189 Sci::Position posLineStart
;
191 std::vector
<int> selAndEdge
;
192 unsigned int saeCurrentPos
;
195 const Document
*pdoc
;
196 EncodingFamily encodingFamily
;
197 const SpecialRepresentations
*preprs
;
198 void Insert(int val
);
200 // If a whole run is longer than lengthStartSubdivision then subdivide
201 // into smaller runs at spaces or punctuation.
202 enum { lengthStartSubdivision
= 300 };
203 // Try to make each subdivided run lengthEachSubdivision or shorter.
204 enum { lengthEachSubdivision
= 100 };
205 BreakFinder(const LineLayout
*ll_
, const Selection
*psel
, Range lineRange_
, Sci::Position posLineStart_
,
206 int xStart
, bool breakForSelection
, const Document
*pdoc_
, const SpecialRepresentations
*preprs_
, const ViewStyle
*pvsDraw
);
207 // Deleted so BreakFinder objects can not be copied.
208 BreakFinder(const BreakFinder
&) = delete;
209 void operator=(const BreakFinder
&) = delete;
215 class PositionCache
{
216 std::vector
<PositionCacheEntry
> pces
;
221 // Deleted so PositionCache objects can not be copied.
222 PositionCache(const PositionCache
&) = delete;
223 void operator=(const PositionCache
&) = delete;
226 void SetSize(size_t size_
);
227 size_t GetSize() const { return pces
.size(); }
228 void MeasureWidths(Surface
*surface
, const ViewStyle
&vstyle
, unsigned int styleNumber
,
229 const char *s
, unsigned int len
, XYPOSITION
*positions
, const Document
*pdoc
);
232 inline bool IsSpaceOrTab(int ch
) {
233 return ch
== ' ' || ch
== '\t';