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
11 namespace Scintilla::Internal
{
14 * A point in document space.
15 * Uses double for sufficient resolution in large (>20,000,000 line) documents.
22 explicit PointDocument(double x_
= 0, double y_
= 0) noexcept
: x(x_
), y(y_
) {
25 // Conversion from Point.
26 explicit PointDocument(Point pt
) noexcept
: x(pt
.x
), y(pt
.y
) {
30 // There are two points for some positions and this enumeration
31 // can choose between the end of the first line or subline
32 // and the start of the next line or subline.
37 endEither
= lineEnd
| subLineEnd
,
42 std::vector
<std::shared_ptr
<Font
>> stylesFonts
;
43 std::vector
<XYPOSITION
> widthReprs
;
44 void Resize(size_t maxLineLength_
);
51 friend class LineLayoutCache
;
52 std::unique_ptr
<int []>lineStarts
;
54 /// Drawing is only performed for @a maxLineLength characters on each line.
57 enum { wrapWidthInfinite
= 0x7ffffff };
61 int numCharsBeforeEOL
;
62 enum class ValidLevel
{ invalid
, checkTextAndStyle
, positions
, lines
} validity
;
67 std::unique_ptr
<char[]> chars
;
68 std::unique_ptr
<unsigned char[]> styles
;
69 std::unique_ptr
<XYPOSITION
[]> positions
;
70 char bracePreviousStyles
[2];
72 std::unique_ptr
<BidiData
> bidiData
;
74 // Wrapped line support
77 XYPOSITION wrapIndent
; // In pixels
79 LineLayout(Sci::Line lineNumber_
, int maxLineLength_
);
80 // Deleted so LineLayout objects can not be copied.
81 LineLayout(const LineLayout
&) = delete;
82 LineLayout(LineLayout
&&) = delete;
83 void operator=(const LineLayout
&) = delete;
84 void operator=(LineLayout
&&) = delete;
85 virtual ~LineLayout();
86 void Resize(int maxLineLength_
);
87 void EnsureBidiData();
89 void Invalidate(ValidLevel validity_
) noexcept
;
90 Sci::Line
LineNumber() const noexcept
;
91 bool CanHold(Sci::Line lineDoc
, int lineLength_
) const noexcept
;
92 int LineStart(int line
) const noexcept
;
93 int LineLength(int line
) const noexcept
;
94 enum class Scope
{ visibleOnly
, includeEnd
};
95 int LineLastVisible(int line
, Scope scope
) const noexcept
;
96 Range
SubLineRange(int subLine
, Scope scope
) const noexcept
;
97 bool InLine(int offset
, int line
) const noexcept
;
98 int SubLineFromPosition(int posInLine
, PointEnd pe
) const noexcept
;
99 void SetLineStart(int line
, int start
);
100 void SetBracesHighlight(Range rangeLine
, const Sci::Position braces
[],
101 char bracesMatchStyle
, int xHighlight
, bool ignoreStyle
);
102 void RestoreBracesHighlight(Range rangeLine
, const Sci::Position braces
[], bool ignoreStyle
);
103 int FindBefore(XYPOSITION x
, Range range
) const noexcept
;
104 int FindPositionFromX(XYPOSITION x
, Range range
, bool charPosition
) const noexcept
;
105 Point
PointFromPosition(int posInLine
, int lineHeight
, PointEnd pe
) const noexcept
;
106 int EndLineStyle() const noexcept
;
109 struct ScreenLine
: public IScreenLine
{
110 const LineLayout
*ll
;
117 int tabWidthMinimumPixels
;
119 ScreenLine(const LineLayout
*ll_
, int subLine
, const ViewStyle
&vs
, XYPOSITION width_
, int tabWidthMinimumPixels_
);
120 // Deleted so ScreenLine objects can not be copied.
121 ScreenLine(const ScreenLine
&) = delete;
122 ScreenLine(ScreenLine
&&) = delete;
123 void operator=(const ScreenLine
&) = delete;
124 void operator=(ScreenLine
&&) = delete;
125 virtual ~ScreenLine();
127 std::string_view
Text() const override
;
128 size_t Length() const override
;
129 size_t RepresentationCount() const override
;
130 XYPOSITION
Width() const override
;
131 XYPOSITION
Height() const override
;
132 XYPOSITION
TabWidth() const override
;
133 XYPOSITION
TabWidthMinimumPixels() const override
;
134 const Font
*FontOfPosition(size_t position
) const override
;
135 XYPOSITION
RepresentationWidth(size_t position
) const override
;
136 XYPOSITION
TabPositionAfter(XYPOSITION xPosition
) const override
;
141 class LineLayoutCache
{
144 Scintilla::LineCache level
;
145 std::vector
<std::shared_ptr
<LineLayout
>>cache
;
148 size_t EntryForLine(Sci::Line line
) const noexcept
;
149 void AllocateForLevel(Sci::Line linesOnScreen
, Sci::Line linesInDoc
);
152 // Deleted so LineLayoutCache objects can not be copied.
153 LineLayoutCache(const LineLayoutCache
&) = delete;
154 LineLayoutCache(LineLayoutCache
&&) = delete;
155 void operator=(const LineLayoutCache
&) = delete;
156 void operator=(LineLayoutCache
&&) = delete;
157 virtual ~LineLayoutCache();
158 void Deallocate() noexcept
;
159 void Invalidate(LineLayout::ValidLevel validity_
) noexcept
;
160 void SetLevel(Scintilla::LineCache level_
) noexcept
;
161 Scintilla::LineCache
GetLevel() const noexcept
{ return level
; }
162 std::shared_ptr
<LineLayout
> Retrieve(Sci::Line lineNumber
, Sci::Line lineCaret
, int maxChars
, int styleClock_
,
163 Sci::Line linesOnScreen
, Sci::Line linesInDoc
);
166 class PositionCacheEntry
{
167 uint16_t styleNumber
;
170 std::unique_ptr
<XYPOSITION
[]> positions
;
172 PositionCacheEntry() noexcept
;
173 // Copy constructor not currently used, but needed for being element in std::vector.
174 PositionCacheEntry(const PositionCacheEntry
&);
175 PositionCacheEntry(PositionCacheEntry
&&) noexcept
= default;
176 // Deleted so PositionCacheEntry objects can not be assigned.
177 void operator=(const PositionCacheEntry
&) = delete;
178 void operator=(PositionCacheEntry
&&) = delete;
179 ~PositionCacheEntry();
180 void Set(unsigned int styleNumber_
, std::string_view sv
, const XYPOSITION
*positions_
, uint16_t clock_
);
181 void Clear() noexcept
;
182 bool Retrieve(unsigned int styleNumber_
, std::string_view sv
, XYPOSITION
*positions_
) const noexcept
;
183 static size_t Hash(unsigned int styleNumber_
, std::string_view sv
) noexcept
;
184 bool NewerThan(const PositionCacheEntry
&other
) const noexcept
;
185 void ResetClock() noexcept
;
188 class Representation
{
190 static constexpr size_t maxLength
= 200;
191 std::string stringRep
;
192 RepresentationAppearance appearance
;
194 explicit Representation(std::string_view value
="", RepresentationAppearance appearance_
= RepresentationAppearance::Blob
) :
195 stringRep(value
), appearance(appearance_
) {
199 typedef std::map
<unsigned int, Representation
> MapRepresentation
;
201 class SpecialRepresentations
{
202 MapRepresentation mapReprs
;
203 unsigned short startByteHasReprs
[0x100] {};
204 unsigned int maxKey
= 0;
207 void SetRepresentation(std::string_view charBytes
, std::string_view value
);
208 void SetRepresentationAppearance(std::string_view charBytes
, RepresentationAppearance appearance
);
209 void SetRepresentationColour(std::string_view charBytes
, ColourRGBA colour
);
210 void ClearRepresentation(std::string_view charBytes
);
211 const Representation
*GetRepresentation(std::string_view charBytes
) const;
212 const Representation
*RepresentationFromCharacter(std::string_view charBytes
) const;
213 bool ContainsCrLf() const noexcept
{
216 bool MayContain(unsigned char ch
) const noexcept
{
217 return startByteHasReprs
[ch
] != 0;
225 const Representation
*representation
;
226 TextSegment(int start_
=0, int length_
=0, const Representation
*representation_
=nullptr) noexcept
:
227 start(start_
), length(length_
), representation(representation_
) {
229 int end() const noexcept
{
230 return start
+ length
;
234 // Class to break a line of text into shorter runs at sensible places.
236 const LineLayout
*ll
;
238 Sci::Position posLineStart
;
240 std::vector
<int> selAndEdge
;
241 unsigned int saeCurrentPos
;
244 const Document
*pdoc
;
245 const EncodingFamily encodingFamily
;
246 const SpecialRepresentations
*preprs
;
247 void Insert(Sci::Position val
);
249 // If a whole run is longer than lengthStartSubdivision then subdivide
250 // into smaller runs at spaces or punctuation.
251 enum { lengthStartSubdivision
= 300 };
252 // Try to make each subdivided run lengthEachSubdivision or shorter.
253 enum { lengthEachSubdivision
= 100 };
254 enum class BreakFor
{
258 ForegroundAndSelection
= 3,
260 BreakFinder(const LineLayout
*ll_
, const Selection
*psel
, Range lineRange_
, Sci::Position posLineStart_
,
261 XYPOSITION xStart
, BreakFor breakFor
, const Document
*pdoc_
, const SpecialRepresentations
*preprs_
, const ViewStyle
*pvsDraw
);
262 // Deleted so BreakFinder objects can not be copied.
263 BreakFinder(const BreakFinder
&) = delete;
264 BreakFinder(BreakFinder
&&) = delete;
265 void operator=(const BreakFinder
&) = delete;
266 void operator=(BreakFinder
&&) = delete;
267 ~BreakFinder() noexcept
;
269 bool More() const noexcept
;
272 class PositionCache
{
273 std::vector
<PositionCacheEntry
> pces
;
278 void Clear() noexcept
;
279 void SetSize(size_t size_
);
280 size_t GetSize() const noexcept
;
281 void MeasureWidths(Surface
*surface
, const ViewStyle
&vstyle
, unsigned int styleNumber
,
282 std::string_view sv
, XYPOSITION
*positions
);