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 std::unique_ptr
<int []>lineStarts
;
53 /// Drawing is only performed for @a maxLineLength characters on each line.
56 enum { wrapWidthInfinite
= 0x7ffffff };
60 int numCharsBeforeEOL
;
61 enum class ValidLevel
{ invalid
, checkTextAndStyle
, positions
, lines
} validity
;
66 std::unique_ptr
<char[]> chars
;
67 std::unique_ptr
<unsigned char[]> styles
;
68 std::unique_ptr
<XYPOSITION
[]> positions
;
69 char bracePreviousStyles
[2];
71 std::unique_ptr
<BidiData
> bidiData
;
73 // Wrapped line support
76 XYPOSITION wrapIndent
; // In pixels
78 LineLayout(Sci::Line lineNumber_
, int maxLineLength_
);
79 // Deleted so LineLayout objects can not be copied.
80 LineLayout(const LineLayout
&) = delete;
81 LineLayout(LineLayout
&&) = delete;
82 void operator=(const LineLayout
&) = delete;
83 void operator=(LineLayout
&&) = delete;
84 virtual ~LineLayout();
85 void Resize(int maxLineLength_
);
86 void ReSet(Sci::Line lineNumber_
, Sci::Position maxLineLength_
);
87 void EnsureBidiData();
89 void ClearPositions();
90 void Invalidate(ValidLevel validity_
) noexcept
;
91 Sci::Line
LineNumber() const noexcept
;
92 bool CanHold(Sci::Line lineDoc
, int lineLength_
) const noexcept
;
93 int LineStart(int line
) const noexcept
;
94 int LineLength(int line
) const noexcept
;
95 enum class Scope
{ visibleOnly
, includeEnd
};
96 int LineLastVisible(int line
, Scope scope
) const noexcept
;
97 Range
SubLineRange(int subLine
, Scope scope
) const noexcept
;
98 bool InLine(int offset
, int line
) const noexcept
;
99 int SubLineFromPosition(int posInLine
, PointEnd pe
) const noexcept
;
100 void AddLineStart(Sci::Position start
);
101 void SetBracesHighlight(Range rangeLine
, const Sci::Position braces
[],
102 char bracesMatchStyle
, int xHighlight
, bool ignoreStyle
);
103 void RestoreBracesHighlight(Range rangeLine
, const Sci::Position braces
[], bool ignoreStyle
);
104 int FindBefore(XYPOSITION x
, Range range
) const noexcept
;
105 int FindPositionFromX(XYPOSITION x
, Range range
, bool charPosition
) const noexcept
;
106 Point
PointFromPosition(int posInLine
, int lineHeight
, PointEnd pe
) const noexcept
;
107 XYPOSITION
XInLine(Sci::Position index
) const noexcept
;
108 Interval
Span(int start
, int end
) const noexcept
;
109 Interval
SpanByte(int index
) const noexcept
;
110 int EndLineStyle() const noexcept
;
111 void WrapLine(const Document
*pdoc
, Sci::Position posLineStart
, Wrap wrapState
, XYPOSITION wrapWidth
);
114 struct ScreenLine
: public IScreenLine
{
115 const LineLayout
*ll
;
122 int tabWidthMinimumPixels
;
124 ScreenLine(const LineLayout
*ll_
, int subLine
, const ViewStyle
&vs
, XYPOSITION width_
, int tabWidthMinimumPixels_
);
125 // Deleted so ScreenLine objects can not be copied.
126 ScreenLine(const ScreenLine
&) = delete;
127 ScreenLine(ScreenLine
&&) = delete;
128 void operator=(const ScreenLine
&) = delete;
129 void operator=(ScreenLine
&&) = delete;
130 virtual ~ScreenLine();
132 std::string_view
Text() const override
;
133 size_t Length() const override
;
134 size_t RepresentationCount() const override
;
135 XYPOSITION
Width() const override
;
136 XYPOSITION
Height() const override
;
137 XYPOSITION
TabWidth() const override
;
138 XYPOSITION
TabWidthMinimumPixels() const override
;
139 const Font
*FontOfPosition(size_t position
) const override
;
140 XYPOSITION
RepresentationWidth(size_t position
) const override
;
141 XYPOSITION
TabPositionAfter(XYPOSITION xPosition
) const override
;
144 struct SignificantLines
{
147 Sci::Line linesOnScreen
;
148 Scintilla::LineCache level
;
149 bool LineMayCache(Sci::Line line
) const noexcept
;
154 class LineLayoutCache
{
157 Scintilla::LineCache level
;
158 std::vector
<std::shared_ptr
<LineLayout
>>cache
;
161 size_t EntryForLine(Sci::Line line
) const noexcept
;
162 void AllocateForLevel(Sci::Line linesOnScreen
, Sci::Line linesInDoc
);
165 // Deleted so LineLayoutCache objects can not be copied.
166 LineLayoutCache(const LineLayoutCache
&) = delete;
167 LineLayoutCache(LineLayoutCache
&&) = delete;
168 void operator=(const LineLayoutCache
&) = delete;
169 void operator=(LineLayoutCache
&&) = delete;
170 virtual ~LineLayoutCache();
171 void Deallocate() noexcept
;
172 void Invalidate(LineLayout::ValidLevel validity_
) noexcept
;
173 void SetLevel(Scintilla::LineCache level_
) noexcept
;
174 Scintilla::LineCache
GetLevel() const noexcept
{ return level
; }
175 std::shared_ptr
<LineLayout
> Retrieve(Sci::Line lineNumber
, Sci::Line lineCaret
, int maxChars
, int styleClock_
,
176 Sci::Line linesOnScreen
, Sci::Line linesInDoc
);
179 class Representation
{
181 static constexpr size_t maxLength
= 200;
182 std::string stringRep
;
183 RepresentationAppearance appearance
;
185 explicit Representation(std::string_view value
="", RepresentationAppearance appearance_
= RepresentationAppearance::Blob
) :
186 stringRep(value
), appearance(appearance_
) {
190 typedef std::map
<unsigned int, Representation
> MapRepresentation
;
192 const char *ControlCharacterString(unsigned char ch
) noexcept
;
193 void Hexits(char *hexits
, int ch
) noexcept
;
195 class SpecialRepresentations
{
196 MapRepresentation mapReprs
;
197 unsigned short startByteHasReprs
[0x100] {};
198 unsigned int maxKey
= 0;
201 void SetRepresentation(std::string_view charBytes
, std::string_view value
);
202 void SetRepresentationAppearance(std::string_view charBytes
, RepresentationAppearance appearance
);
203 void SetRepresentationColour(std::string_view charBytes
, ColourRGBA colour
);
204 void ClearRepresentation(std::string_view charBytes
);
205 const Representation
*GetRepresentation(std::string_view charBytes
) const;
206 const Representation
*RepresentationFromCharacter(std::string_view charBytes
) const;
207 bool ContainsCrLf() const noexcept
{
210 bool MayContain(unsigned char ch
) const noexcept
{
211 return startByteHasReprs
[ch
] != 0;
214 void SetDefaultRepresentations(int dbcsCodePage
);
220 const Representation
*representation
;
221 TextSegment(int start_
=0, int length_
=0, const Representation
*representation_
=nullptr) noexcept
:
222 start(start_
), length(length_
), representation(representation_
) {
224 int end() const noexcept
{
225 return start
+ length
;
229 // Class to break a line of text into shorter runs at sensible places.
231 const LineLayout
*ll
;
232 const Range lineRange
;
234 std::vector
<int> selAndEdge
;
235 unsigned int saeCurrentPos
;
238 const Document
*pdoc
;
239 const EncodingFamily encodingFamily
;
240 const SpecialRepresentations
*preprs
;
241 void Insert(Sci::Position val
);
243 // If a whole run is longer than lengthStartSubdivision then subdivide
244 // into smaller runs at spaces or punctuation.
245 enum { lengthStartSubdivision
= 300 };
246 // Try to make each subdivided run lengthEachSubdivision or shorter.
247 enum { lengthEachSubdivision
= 100 };
248 enum class BreakFor
{
252 ForegroundAndSelection
= 3,
254 BreakFinder(const LineLayout
*ll_
, const Selection
*psel
, Range lineRange_
, Sci::Position posLineStart
,
255 XYPOSITION xStart
, BreakFor breakFor
, const Document
*pdoc_
, const SpecialRepresentations
*preprs_
, const ViewStyle
*pvsDraw
);
256 // Deleted so BreakFinder objects can not be copied.
257 BreakFinder(const BreakFinder
&) = delete;
258 BreakFinder(BreakFinder
&&) = delete;
259 void operator=(const BreakFinder
&) = delete;
260 void operator=(BreakFinder
&&) = delete;
261 ~BreakFinder() noexcept
;
263 bool More() const noexcept
;
266 class IPositionCache
{
268 virtual ~IPositionCache() = default;
269 virtual void Clear() noexcept
= 0;
270 virtual void SetSize(size_t size_
) = 0;
271 virtual size_t GetSize() const noexcept
= 0;
272 virtual void MeasureWidths(Surface
*surface
, const ViewStyle
&vstyle
, unsigned int styleNumber
,
273 bool unicode
, std::string_view sv
, XYPOSITION
*positions
, bool needsLocking
) = 0;
276 std::unique_ptr
<IPositionCache
> CreatePositionCache();