aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/PositionCache.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'src/PositionCache.cxx')
-rw-r--r--src/PositionCache.cxx103
1 files changed, 103 insertions, 0 deletions
diff --git a/src/PositionCache.cxx b/src/PositionCache.cxx
index 31a8601f5..b218c39e0 100644
--- a/src/PositionCache.cxx
+++ b/src/PositionCache.cxx
@@ -46,6 +46,11 @@
using namespace Scintilla;
+void BidiData::Resize(size_t maxLineLength_) {
+ stylesFonts.resize(maxLineLength_ + 1);
+ widthReprs.resize(maxLineLength_ + 1);
+}
+
LineLayout::LineLayout(int maxLineLength_) :
lenLineStarts(0),
lineNumber(-1),
@@ -79,15 +84,27 @@ void LineLayout::Resize(int maxLineLength_) {
// Extra position allocated as sometimes the Windows
// GetTextExtentExPoint API writes an extra element.
positions = std::make_unique<XYPOSITION []>(maxLineLength_ + 1 + 1);
+ if (bidiData) {
+ bidiData->Resize(maxLineLength_);
+ }
+
maxLineLength = maxLineLength_;
}
}
+void LineLayout::EnsureBidiData() {
+ if (!bidiData) {
+ bidiData = std::make_unique<BidiData>();
+ bidiData->Resize(maxLineLength);
+ }
+}
+
void LineLayout::Free() {
chars.reset();
styles.reset();
positions.reset();
lineStarts.reset();
+ bidiData.reset();
}
void LineLayout::Invalidate(validLevel validity_) {
@@ -105,6 +122,16 @@ int LineLayout::LineStart(int line) const {
}
}
+int Scintilla::LineLayout::LineLength(int line) const {
+ if (!lineStarts) {
+ return numCharsInLine;
+ } if (line >= lines - 1) {
+ return numCharsInLine - lineStarts[line];
+ } else {
+ return lineStarts[line + 1] - lineStarts[line];
+ }
+}
+
int LineLayout::LineLastVisible(int line, Scope scope) const {
if (line < 0) {
return 0;
@@ -124,6 +151,25 @@ bool LineLayout::InLine(int offset, int line) const {
((offset == numCharsInLine) && (line == (lines-1)));
}
+int LineLayout::SubLineFromPosition(int posInLine, PointEnd pe) const {
+ if (!lineStarts || (posInLine > maxLineLength)) {
+ return lines - 1;
+ }
+
+ for (int line = 0; line < lines; line++) {
+ if (pe & peSubLineEnd) {
+ // Return subline not start of next
+ if (lineStarts[line + 1] <= posInLine + 1)
+ return line;
+ } else {
+ if (lineStarts[line + 1] <= posInLine)
+ return line;
+ }
+ }
+
+ return lines - 1;
+}
+
void LineLayout::SetLineStart(int line, int start) {
if ((line >= lenLineStarts) && (line != 0)) {
const int newMaxLines = line + 20;
@@ -244,6 +290,63 @@ int LineLayout::EndLineStyle() const {
return styles[numCharsBeforeEOL > 0 ? numCharsBeforeEOL-1 : 0];
}
+ScreenLine::ScreenLine(
+ const LineLayout *ll_,
+ int subLine,
+ const ViewStyle &vs,
+ XYPOSITION width_,
+ int tabWidthMinimumPixels_) :
+ ll(ll_),
+ start(ll->LineStart(subLine)),
+ len(ll->LineLength(subLine)),
+ width(width_),
+ height(static_cast<float>(vs.lineHeight)),
+ ctrlCharPadding(vs.ctrlCharPadding),
+ tabWidth(vs.tabWidth),
+ tabWidthMinimumPixels(tabWidthMinimumPixels_) {
+}
+
+ScreenLine::~ScreenLine() {
+}
+
+std::string_view ScreenLine::Text() const {
+ return std::string_view(&ll->chars[start], len);
+}
+
+size_t ScreenLine::Length() const {
+ return len;
+}
+
+size_t ScreenLine::RepresentationCount() const {
+ return std::count_if(&ll->bidiData->widthReprs[start],
+ &ll->bidiData->widthReprs[start + len],
+ [](XYPOSITION w) {return w > 0.0f; });
+}
+
+XYPOSITION ScreenLine::Width() const {
+ return width;
+}
+
+XYPOSITION ScreenLine::Height() const {
+ return height;
+}
+
+XYPOSITION ScreenLine::TabWidth() const {
+ return tabWidth;
+}
+
+XYPOSITION ScreenLine::TabWidthMinimumPixels() const {
+ return static_cast<XYPOSITION>(tabWidthMinimumPixels);
+}
+
+const Font *ScreenLine::FontOfPosition(size_t position) const {
+ return &ll->bidiData->stylesFonts[start + position];
+}
+
+XYPOSITION ScreenLine::RepresentationWidth(size_t position) const {
+ return ll->bidiData->widthReprs[start + position];
+}
+
LineLayoutCache::LineLayoutCache() :
level(0),
allInvalidated(false), styleClock(-1), useCount(0) {