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
13 inline constexpr bool IsEOLChar(int ch
) noexcept
{
14 return (ch
== '\r') || (ch
== '\n');
17 inline constexpr bool IsSpaceOrTab(int ch
) noexcept
{
18 return ch
== ' ' || ch
== '\t';
22 * A point in document space.
23 * Uses double for sufficient resolution in large (>20,000,000 line) documents.
30 explicit PointDocument(double x_
= 0, double y_
= 0) noexcept
: x(x_
), y(y_
) {
33 // Conversion from Point.
34 explicit PointDocument(Point pt
) noexcept
: x(pt
.x
), y(pt
.y
) {
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.
51 friend class LineLayoutCache
;
52 std::unique_ptr
<int []>lineStarts
;
54 /// Drawing is only performed for @a maxLineLength characters on each line.
58 enum { wrapWidthInfinite
= 0x7ffffff };
62 int numCharsBeforeEOL
;
63 enum validLevel
{ llInvalid
, llCheckTextAndStyle
, llPositions
, llLines
} validity
;
68 std::unique_ptr
<char[]> chars
;
69 std::unique_ptr
<unsigned char[]> styles
;
70 std::unique_ptr
<XYPOSITION
[]> positions
;
71 char bracePreviousStyles
[2];
76 // Wrapped line support
79 XYPOSITION wrapIndent
; // In pixels
81 explicit LineLayout(int maxLineLength_
);
82 // Deleted so LineLayout objects can not be copied.
83 LineLayout(const LineLayout
&) = delete;
84 LineLayout(LineLayout
&&) = delete;
85 void operator=(const LineLayout
&) = delete;
86 void operator=(LineLayout
&&) = delete;
87 virtual ~LineLayout();
88 void Resize(int maxLineLength_
);
90 void Invalidate(validLevel validity_
);
91 int LineStart(int line
) const;
92 enum class Scope
{ visibleOnly
, includeEnd
};
93 int LineLastVisible(int line
, Scope scope
) const;
94 Range
SubLineRange(int subLine
, Scope scope
) const;
95 bool InLine(int offset
, int line
) const;
96 void SetLineStart(int line
, int start
);
97 void SetBracesHighlight(Range rangeLine
, const Sci::Position braces
[],
98 char bracesMatchStyle
, int xHighlight
, bool ignoreStyle
);
99 void RestoreBracesHighlight(Range rangeLine
, const Sci::Position braces
[], bool ignoreStyle
);
100 int FindBefore(XYPOSITION x
, Range range
) const;
101 int FindPositionFromX(XYPOSITION x
, Range range
, bool charPosition
) const;
102 Point
PointFromPosition(int posInLine
, int lineHeight
, PointEnd pe
) const;
103 int EndLineStyle() const;
108 class LineLayoutCache
{
110 std::vector
<std::unique_ptr
<LineLayout
>>cache
;
114 void Allocate(size_t length_
);
115 void AllocateForLevel(Sci::Line linesOnScreen
, Sci::Line linesInDoc
);
118 // Deleted so LineLayoutCache objects can not be copied.
119 LineLayoutCache(const LineLayoutCache
&) = delete;
120 LineLayoutCache(LineLayoutCache
&&) = delete;
121 void operator=(const LineLayoutCache
&) = delete;
122 void operator=(LineLayoutCache
&&) = delete;
123 virtual ~LineLayoutCache();
124 void Deallocate() noexcept
;
126 llcNone
=SC_CACHE_NONE
,
127 llcCaret
=SC_CACHE_CARET
,
128 llcPage
=SC_CACHE_PAGE
,
129 llcDocument
=SC_CACHE_DOCUMENT
131 void Invalidate(LineLayout::validLevel validity_
);
132 void SetLevel(int level_
) noexcept
;
133 int GetLevel() const noexcept
{ return level
; }
134 LineLayout
*Retrieve(Sci::Line lineNumber
, Sci::Line lineCaret
, int maxChars
, int styleClock_
,
135 Sci::Line linesOnScreen
, Sci::Line linesInDoc
);
136 void Dispose(LineLayout
*ll
) noexcept
;
139 class PositionCacheEntry
{
140 unsigned int styleNumber
:8;
142 unsigned int clock
:16;
143 std::unique_ptr
<XYPOSITION
[]> positions
;
145 PositionCacheEntry() noexcept
;
146 // Copy constructor not currently used, but needed for being element in std::vector.
147 PositionCacheEntry(const PositionCacheEntry
&);
148 // PositionCacheEntry objects should not be moved but MSVC 2015 requires this.
149 PositionCacheEntry(PositionCacheEntry
&&) = default;
150 void operator=(const PositionCacheEntry
&) = delete;
151 void operator=(PositionCacheEntry
&&) = delete;
152 ~PositionCacheEntry();
153 void Set(unsigned int styleNumber_
, const char *s_
, unsigned int len_
, const XYPOSITION
*positions_
, unsigned int clock_
);
154 void Clear() noexcept
;
155 bool Retrieve(unsigned int styleNumber_
, const char *s_
, unsigned int len_
, XYPOSITION
*positions_
) const;
156 static unsigned int Hash(unsigned int styleNumber_
, const char *s
, unsigned int len_
) noexcept
;
157 bool NewerThan(const PositionCacheEntry
&other
) const noexcept
;
158 void ResetClock() noexcept
;
161 class Representation
{
163 std::string stringRep
;
164 explicit Representation(const char *value
="") : stringRep(value
) {
168 typedef std::map
<unsigned int, Representation
> MapRepresentation
;
170 class SpecialRepresentations
{
171 MapRepresentation mapReprs
;
172 short startByteHasReprs
[0x100];
174 SpecialRepresentations() noexcept
;
175 void SetRepresentation(const char *charBytes
, const char *value
);
176 void ClearRepresentation(const char *charBytes
);
177 const Representation
*RepresentationFromCharacter(const char *charBytes
, size_t len
) const;
178 bool Contains(const char *charBytes
, size_t len
) const;
185 const Representation
*representation
;
186 TextSegment(int start_
=0, int length_
=0, const Representation
*representation_
=nullptr) noexcept
:
187 start(start_
), length(length_
), representation(representation_
) {
189 int end() const noexcept
{
190 return start
+ length
;
194 // Class to break a line of text into shorter runs at sensible places.
196 const LineLayout
*ll
;
198 Sci::Position posLineStart
;
200 std::vector
<int> selAndEdge
;
201 unsigned int saeCurrentPos
;
204 const Document
*pdoc
;
205 EncodingFamily encodingFamily
;
206 const SpecialRepresentations
*preprs
;
207 void Insert(Sci::Position val
);
209 // If a whole run is longer than lengthStartSubdivision then subdivide
210 // into smaller runs at spaces or punctuation.
211 enum { lengthStartSubdivision
= 300 };
212 // Try to make each subdivided run lengthEachSubdivision or shorter.
213 enum { lengthEachSubdivision
= 100 };
214 BreakFinder(const LineLayout
*ll_
, const Selection
*psel
, Range lineRange_
, Sci::Position posLineStart_
,
215 int xStart
, bool breakForSelection
, const Document
*pdoc_
, const SpecialRepresentations
*preprs_
, const ViewStyle
*pvsDraw
);
216 // Deleted so BreakFinder objects can not be copied.
217 BreakFinder(const BreakFinder
&) = delete;
218 BreakFinder(BreakFinder
&&) = delete;
219 void operator=(const BreakFinder
&) = delete;
220 void operator=(BreakFinder
&&) = delete;
223 bool More() const noexcept
;
226 class PositionCache
{
227 std::vector
<PositionCacheEntry
> pces
;
232 // Deleted so PositionCache objects can not be copied.
233 PositionCache(const PositionCache
&) = delete;
234 PositionCache(PositionCache
&&) = delete;
235 void operator=(const PositionCache
&) = delete;
236 void operator=(PositionCache
&&) = delete;
238 void Clear() noexcept
;
239 void SetSize(size_t size_
);
240 size_t GetSize() const noexcept
{ return pces
.size(); }
241 void MeasureWidths(Surface
*surface
, const ViewStyle
&vstyle
, unsigned int styleNumber
,
242 const char *s
, unsigned int len
, XYPOSITION
*positions
, const Document
*pdoc
);