notepad-plus-plus/scintilla/src/PositionCache.h
Christian Grasser feb454ad6f Update scintilla 5.3.4 and lexilla 5.2.4 with:
https://www.scintilla.org/scintilla534.zip

    Released 8 March 2023.
    Add multithreaded wrap to significantly improve performance of wrapping large files.
    More typesafe bindings of *Full APIs in ScintillaCall. Feature #1477.
    Fix overlapping of text with line end wrap marker. Bug #2378.
    Fix clipping of line end wrap symbol for SC_WRAPVISUALFLAGLOC_END_BY_TEXT.
    Where a multi-byte character contains multiple styles, display each byte as a representation. This makes it easier to see and fix lexers that change styles mid-character, commonly because they use fixed size buffers.
    Fix a potential crash with autocompletion list fill-ups where a SCN_CHARADDED handler retriggered an autocompletion list, but with no items that match the typed character.

lexilla523

    Released 8 March 2023.
    Add scripts/PromoteNew.bat script to promote .new files after checking.
    Makefile: Remove 1024-byte line length limit..
    Ruby: Add new lexical classes for % literals SCE_RB_STRING_W (%w non-interpolable string array), SCE_RB_STRING_I (%i non-interpolable symbol array), SCE_RB_STRING_QI (%I interpolable symbol array), and SCE_RB_STRING_QS (%s symbol). Issue #124.
    Ruby: Disambiguate %= which may be a quote or modulo assignment. Issue #124, Bug #1255, Bug #2182.
    Ruby: Fix additional fold level for single character in SCE_RB_STRING_QW. Issue #132.
    Ruby: Set SCE_RB_HERE_QQ for unquoted and double-quoted heredocs and SCE_RB_HERE_QX for backticks-quoted heredocs. Issue #134.
    Ruby: Recognise #{} inside SCE_RB_HERE_QQ and SCE_RB_HERE_QX. Issue #134.
    Ruby: Improve regex and heredoc recognition. Issue #136.
    Ruby: Highlight #@, #@@ and #$ style interpolation. Issue #140.
    Ruby: Fix folding for multiple heredocs started on one line. Fix folding when there is a space after heredoc opening delimiter. Issue #135.
    YAML: Remove 1024-byte line length limit.

https://www.scintilla.org/lexilla524.zip

    Released 13 March 2023.
    C++: Fix failure to recognize keywords containing upper case. Issue #149.
    GDScript: Support % and $ node paths. Issue #145, Pull request #146.

Close #13338
2023-03-13 21:06:09 +01:00

281 lines
9.3 KiB
C++

// Scintilla source code edit control
/** @file PositionCache.h
** Classes for caching layout information.
**/
// Copyright 1998-2009 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
#ifndef POSITIONCACHE_H
#define POSITIONCACHE_H
namespace Scintilla::Internal {
/**
* A point in document space.
* Uses double for sufficient resolution in large (>20,000,000 line) documents.
*/
class PointDocument {
public:
double x;
double y;
explicit PointDocument(double x_ = 0, double y_ = 0) noexcept : x(x_), y(y_) {
}
// Conversion from Point.
explicit PointDocument(Point pt) noexcept : x(pt.x), y(pt.y) {
}
};
// There are two points for some positions and this enumeration
// can choose between the end of the first line or subline
// and the start of the next line or subline.
enum class PointEnd {
start = 0x0,
lineEnd = 0x1,
subLineEnd = 0x2,
endEither = lineEnd | subLineEnd,
};
class BidiData {
public:
std::vector<std::shared_ptr<Font>> stylesFonts;
std::vector<XYPOSITION> widthReprs;
void Resize(size_t maxLineLength_);
};
/**
*/
class LineLayout {
private:
std::unique_ptr<int []>lineStarts;
int lenLineStarts;
/// Drawing is only performed for @a maxLineLength characters on each line.
Sci::Line lineNumber;
public:
enum { wrapWidthInfinite = 0x7ffffff };
int maxLineLength;
int numCharsInLine;
int numCharsBeforeEOL;
enum class ValidLevel { invalid, checkTextAndStyle, positions, lines } validity;
int xHighlightGuide;
bool highlightColumn;
bool containsCaret;
int edgeColumn;
std::unique_ptr<char[]> chars;
std::unique_ptr<unsigned char[]> styles;
std::unique_ptr<XYPOSITION[]> positions;
char bracePreviousStyles[2];
std::unique_ptr<BidiData> bidiData;
// Wrapped line support
int widthLine;
int lines;
XYPOSITION wrapIndent; // In pixels
LineLayout(Sci::Line lineNumber_, int maxLineLength_);
// Deleted so LineLayout objects can not be copied.
LineLayout(const LineLayout &) = delete;
LineLayout(LineLayout &&) = delete;
void operator=(const LineLayout &) = delete;
void operator=(LineLayout &&) = delete;
virtual ~LineLayout();
void Resize(int maxLineLength_);
void ReSet(Sci::Line lineNumber_, Sci::Position maxLineLength_);
void EnsureBidiData();
void Free() noexcept;
void ClearPositions();
void Invalidate(ValidLevel validity_) noexcept;
Sci::Line LineNumber() const noexcept;
bool CanHold(Sci::Line lineDoc, int lineLength_) const noexcept;
int LineStart(int line) const noexcept;
int LineLength(int line) const noexcept;
enum class Scope { visibleOnly, includeEnd };
int LineLastVisible(int line, Scope scope) const noexcept;
Range SubLineRange(int subLine, Scope scope) const noexcept;
bool InLine(int offset, int line) const noexcept;
int SubLineFromPosition(int posInLine, PointEnd pe) const noexcept;
void AddLineStart(Sci::Position start);
void SetBracesHighlight(Range rangeLine, const Sci::Position braces[],
char bracesMatchStyle, int xHighlight, bool ignoreStyle);
void RestoreBracesHighlight(Range rangeLine, const Sci::Position braces[], bool ignoreStyle);
int FindBefore(XYPOSITION x, Range range) const noexcept;
int FindPositionFromX(XYPOSITION x, Range range, bool charPosition) const noexcept;
Point PointFromPosition(int posInLine, int lineHeight, PointEnd pe) const noexcept;
XYPOSITION XInLine(Sci::Position index) const noexcept;
Interval Span(int start, int end) const noexcept;
Interval SpanByte(int index) const noexcept;
int EndLineStyle() const noexcept;
void WrapLine(const Document *pdoc, Sci::Position posLineStart, Wrap wrapState, XYPOSITION wrapWidth);
};
struct ScreenLine : public IScreenLine {
const LineLayout *ll;
size_t start;
size_t len;
XYPOSITION width;
XYPOSITION height;
int ctrlCharPadding;
XYPOSITION tabWidth;
int tabWidthMinimumPixels;
ScreenLine(const LineLayout *ll_, int subLine, const ViewStyle &vs, XYPOSITION width_, int tabWidthMinimumPixels_);
// Deleted so ScreenLine objects can not be copied.
ScreenLine(const ScreenLine &) = delete;
ScreenLine(ScreenLine &&) = delete;
void operator=(const ScreenLine &) = delete;
void operator=(ScreenLine &&) = delete;
virtual ~ScreenLine();
std::string_view Text() const override;
size_t Length() const override;
size_t RepresentationCount() const override;
XYPOSITION Width() const override;
XYPOSITION Height() const override;
XYPOSITION TabWidth() const override;
XYPOSITION TabWidthMinimumPixels() const override;
const Font *FontOfPosition(size_t position) const override;
XYPOSITION RepresentationWidth(size_t position) const override;
XYPOSITION TabPositionAfter(XYPOSITION xPosition) const override;
};
struct SignificantLines {
Sci::Line lineCaret;
Sci::Line lineTop;
Sci::Line linesOnScreen;
Scintilla::LineCache level;
bool LineMayCache(Sci::Line line) const noexcept;
};
/**
*/
class LineLayoutCache {
public:
private:
Scintilla::LineCache level;
std::vector<std::shared_ptr<LineLayout>>cache;
bool allInvalidated;
int styleClock;
size_t EntryForLine(Sci::Line line) const noexcept;
void AllocateForLevel(Sci::Line linesOnScreen, Sci::Line linesInDoc);
public:
LineLayoutCache();
// Deleted so LineLayoutCache objects can not be copied.
LineLayoutCache(const LineLayoutCache &) = delete;
LineLayoutCache(LineLayoutCache &&) = delete;
void operator=(const LineLayoutCache &) = delete;
void operator=(LineLayoutCache &&) = delete;
virtual ~LineLayoutCache();
void Deallocate() noexcept;
void Invalidate(LineLayout::ValidLevel validity_) noexcept;
void SetLevel(Scintilla::LineCache level_) noexcept;
Scintilla::LineCache GetLevel() const noexcept { return level; }
std::shared_ptr<LineLayout> Retrieve(Sci::Line lineNumber, Sci::Line lineCaret, int maxChars, int styleClock_,
Sci::Line linesOnScreen, Sci::Line linesInDoc);
};
class Representation {
public:
static constexpr size_t maxLength = 200;
std::string stringRep;
RepresentationAppearance appearance;
ColourRGBA colour;
explicit Representation(std::string_view value="", RepresentationAppearance appearance_= RepresentationAppearance::Blob) :
stringRep(value), appearance(appearance_) {
}
};
typedef std::map<unsigned int, Representation> MapRepresentation;
const char *ControlCharacterString(unsigned char ch) noexcept;
void Hexits(char *hexits, int ch) noexcept;
class SpecialRepresentations {
MapRepresentation mapReprs;
unsigned short startByteHasReprs[0x100] {};
unsigned int maxKey = 0;
bool crlf = false;
public:
void SetRepresentation(std::string_view charBytes, std::string_view value);
void SetRepresentationAppearance(std::string_view charBytes, RepresentationAppearance appearance);
void SetRepresentationColour(std::string_view charBytes, ColourRGBA colour);
void ClearRepresentation(std::string_view charBytes);
const Representation *GetRepresentation(std::string_view charBytes) const;
const Representation *RepresentationFromCharacter(std::string_view charBytes) const;
bool ContainsCrLf() const noexcept {
return crlf;
}
bool MayContain(unsigned char ch) const noexcept {
return startByteHasReprs[ch] != 0;
}
void Clear();
void SetDefaultRepresentations(int dbcsCodePage);
};
struct TextSegment {
int start;
int length;
const Representation *representation;
TextSegment(int start_=0, int length_=0, const Representation *representation_=nullptr) noexcept :
start(start_), length(length_), representation(representation_) {
}
int end() const noexcept {
return start + length;
}
};
// Class to break a line of text into shorter runs at sensible places.
class BreakFinder {
const LineLayout *ll;
const Range lineRange;
int nextBreak;
std::vector<int> selAndEdge;
unsigned int saeCurrentPos;
int saeNext;
int subBreak;
const Document *pdoc;
const EncodingFamily encodingFamily;
const SpecialRepresentations *preprs;
void Insert(Sci::Position val);
public:
// If a whole run is longer than lengthStartSubdivision then subdivide
// into smaller runs at spaces or punctuation.
enum { lengthStartSubdivision = 300 };
// Try to make each subdivided run lengthEachSubdivision or shorter.
enum { lengthEachSubdivision = 100 };
enum class BreakFor {
Text = 0,
Selection = 1,
Foreground = 2,
ForegroundAndSelection = 3,
};
BreakFinder(const LineLayout *ll_, const Selection *psel, Range lineRange_, Sci::Position posLineStart,
XYPOSITION xStart, BreakFor breakFor, const Document *pdoc_, const SpecialRepresentations *preprs_, const ViewStyle *pvsDraw);
// Deleted so BreakFinder objects can not be copied.
BreakFinder(const BreakFinder &) = delete;
BreakFinder(BreakFinder &&) = delete;
void operator=(const BreakFinder &) = delete;
void operator=(BreakFinder &&) = delete;
~BreakFinder() noexcept;
TextSegment Next();
bool More() const noexcept;
};
class IPositionCache {
public:
virtual ~IPositionCache() = default;
virtual void Clear() noexcept = 0;
virtual void SetSize(size_t size_) = 0;
virtual size_t GetSize() const noexcept = 0;
virtual void MeasureWidths(Surface *surface, const ViewStyle &vstyle, unsigned int styleNumber,
bool unicode, std::string_view sv, XYPOSITION *positions, bool needsLocking) = 0;
};
std::unique_ptr<IPositionCache> CreatePositionCache();
}
#endif