From b798b3cd87f48583ec37dabe4712ceffb43d3ab9 Mon Sep 17 00:00:00 2001 From: zufuliu Date: Wed, 4 Dec 2024 18:48:45 +0800 Subject: [PATCH] Avoid change underline character and style buffers when wrap lines. --- scintilla/src/CellBuffer.cxx | 8 ++++++-- scintilla/src/CellBuffer.h | 2 +- scintilla/src/Document.h | 6 +++--- scintilla/src/EditView.cxx | 10 +--------- scintilla/src/SplitVector.h | 28 ++++++++++++++++++++++++---- 5 files changed, 35 insertions(+), 19 deletions(-) diff --git a/scintilla/src/CellBuffer.cxx b/scintilla/src/CellBuffer.cxx index a9fb6c7c5f..7c1f171379 100644 --- a/scintilla/src/CellBuffer.cxx +++ b/scintilla/src/CellBuffer.cxx @@ -412,8 +412,12 @@ const char *CellBuffer::RangePointer(Sci::Position position, Sci::Position range return substance.RangePointer(position, rangeLength); } -const char *CellBuffer::StyleRangePointer(Sci::Position position, Sci::Position rangeLength) noexcept { - return hasStyles ? style.RangePointer(position, rangeLength) : nullptr; +int CellBuffer::CheckRange(const char *chars, const char *styles, Sci::Position position, Sci::Position rangeLength) const noexcept { + int result = substance.CheckRange(chars, position, rangeLength); + if (hasStyles) { + result |= style.CheckRange(styles, position, rangeLength); + } + return result; } Sci::Position CellBuffer::GapPosition() const noexcept { diff --git a/scintilla/src/CellBuffer.h b/scintilla/src/CellBuffer.h index 178e3159c2..4e0257e3a2 100644 --- a/scintilla/src/CellBuffer.h +++ b/scintilla/src/CellBuffer.h @@ -116,7 +116,7 @@ class CellBuffer { void GetStyleRange(unsigned char *buffer, Sci::Position position, Sci::Position lengthRetrieve) const noexcept; const char *BufferPointer(); const char *RangePointer(Sci::Position position, Sci::Position rangeLength) noexcept; - const char *StyleRangePointer(Sci::Position position, Sci::Position rangeLength) noexcept; + int CheckRange(const char *chars, const char *styles, Sci::Position position, Sci::Position rangeLength) const noexcept; Sci::Position GapPosition() const noexcept; SplitView AllView() const noexcept; diff --git a/scintilla/src/Document.h b/scintilla/src/Document.h index 6542a3c82c..3d8318bef7 100644 --- a/scintilla/src/Document.h +++ b/scintilla/src/Document.h @@ -494,9 +494,6 @@ class Document : PerLine, public Scintilla::IDocument, public Scintilla::ILoader const char *RangePointer(Sci::Position position, Sci::Position rangeLength) noexcept { return cb.RangePointer(position, rangeLength); } - const char *StyleRangePointer(Sci::Position position, Sci::Position rangeLength) noexcept { - return cb.StyleRangePointer(position, rangeLength); - } Sci::Position GapPosition() const noexcept { return cb.GapPosition(); } @@ -545,6 +542,9 @@ class Document : PerLine, public Scintilla::IDocument, public Scintilla::ILoader void GetStyleRange(unsigned char *buffer, Sci::Position position, Sci::Position lengthRetrieve) const noexcept { cb.GetStyleRange(buffer, position, lengthRetrieve); } + int CheckRange(const char *chars, const char *styles, Sci::Position position, Sci::Position rangeLength) const noexcept { + return cb.CheckRange(chars, styles, position, rangeLength); + } MarkerMask GetMark(Sci::Line line, bool includeChangeHistory) const noexcept; Sci::Line MarkerNext(Sci::Line lineStart, MarkerMask mask) const noexcept; int AddMark(Sci::Line line, int markerNum); diff --git a/scintilla/src/EditView.cxx b/scintilla/src/EditView.cxx index 8793cd01fa..58a521c1c3 100644 --- a/scintilla/src/EditView.cxx +++ b/scintilla/src/EditView.cxx @@ -599,15 +599,7 @@ uint64_t EditView::LayoutLine(const EditModel &model, Surface *surface, const Vi const uint8_t *styles = ll->styles.get(); if (lineLength != 0) { - const char *docStyles = model.pdoc->StyleRangePointer(posLineStart, lineLength); - if (docStyles) { // HasStyles - allSame = memcmp(docStyles, styles, lineLength); - } - - const char *docChars = model.pdoc->RangePointer(posLineStart, lineLength); - const char *chars = ll->chars.get(); - // NOLINTNEXTLINE(bugprone-suspicious-string-compare) - allSame |= memcmp(docChars, chars, lineLength); + allSame = model.pdoc->CheckRange(ll->chars.get(), reinterpret_cast(styles), posLineStart, lineLength); } const int styleByteLast = (posLineEnd == posLineStart) ? 0 : model.pdoc->StyleIndexAt(posLineEnd - 1); diff --git a/scintilla/src/SplitVector.h b/scintilla/src/SplitVector.h index 93555581d1..6862836ae4 100644 --- a/scintilla/src/SplitVector.h +++ b/scintilla/src/SplitVector.h @@ -322,14 +322,34 @@ class SplitVector { void GetRange(T *buffer, ptrdiff_t position, ptrdiff_t retrieveLength) const noexcept { // Split into up to 2 ranges, before and after the split then use memcpy on each. ptrdiff_t range1Length = 0; + const T* data = body.data() + position; if (position < part1Length) { range1Length = std::min(retrieveLength, part1Length - position); + memcpy(buffer, data, range1Length*sizeof(T)); + } + if (range1Length < retrieveLength) { + data += range1Length + gapLength; + const ptrdiff_t range2Length = retrieveLength - range1Length; + memcpy(buffer + range1Length, data, range2Length*sizeof(T)); } + } + + int CheckRange(const T *buffer, ptrdiff_t position, ptrdiff_t rangeLength) const noexcept { + // Split into up to 2 ranges, before and after the split then use memcmp on each. + ptrdiff_t range1Length = 0; + int result = 0; const T* data = body.data() + position; - std::copy_n(data, range1Length, buffer); - data += range1Length + gapLength; - const ptrdiff_t range2Length = retrieveLength - range1Length; - std::copy_n(data, range2Length, buffer + range1Length); + if (position < part1Length) { + range1Length = std::min(rangeLength, part1Length - position); + result = memcmp(data, buffer, range1Length*sizeof(T)); + } + if (range1Length < rangeLength) { + data += range1Length + gapLength; + const ptrdiff_t range2Length = rangeLength - range1Length; + // NOLINTNEXTLINE(bugprone-suspicious-string-compare) + result |= memcmp(data, buffer + range1Length, range2Length*sizeof(T)); + } + return result; } /// Compact the buffer and return a pointer to the first element.