diff options
-rw-r--r-- | src/EditView.cxx | 53 | ||||
-rw-r--r-- | src/PositionCache.cxx | 58 | ||||
-rw-r--r-- | src/PositionCache.h | 1 |
3 files changed, 60 insertions, 52 deletions
diff --git a/src/EditView.cxx b/src/EditView.cxx index 79c4206b2..cc7b5dcf5 100644 --- a/src/EditView.cxx +++ b/src/EditView.cxx @@ -599,58 +599,7 @@ void EditView::LayoutLine(const EditModel &model, Surface *surface, const ViewSt // Check for wrapIndent minimum if ((FlagSet(vstyle.wrap.visualFlags, WrapVisualFlag::Start)) && (ll->wrapIndent < vstyle.aveCharWidth)) ll->wrapIndent = vstyle.aveCharWidth; // Indent to show start visual - ll->lines = 0; - // Calculate line start positions based upon width. - Sci::Position lastLineStart = 0; - XYPOSITION startOffset = width; - Sci::Position p = 0; - const Wrap wrapState = vstyle.wrap.state; - const Sci::Position numCharsInLine = ll->numCharsInLine; - while (p < numCharsInLine) { - while (p < numCharsInLine && ll->positions[p + 1] < startOffset) { - p++; - } - if (p < numCharsInLine) { - // backtrack to find lastGoodBreak - Sci::Position lastGoodBreak = p; - if (p > 0) { - lastGoodBreak = model.pdoc->MovePositionOutsideChar(p + posLineStart, -1) - posLineStart; - } - if (wrapState != Wrap::Char) { - Sci::Position pos = lastGoodBreak; - while (pos > lastLineStart) { - // style boundary and space - if (wrapState != Wrap::WhiteSpace && (ll->styles[pos - 1] != ll->styles[pos])) { - break; - } - if (IsBreakSpace(ll->chars[pos - 1]) && !IsBreakSpace(ll->chars[pos])) { - break; - } - pos = model.pdoc->MovePositionOutsideChar(pos + posLineStart - 1, -1) - posLineStart; - } - if (pos > lastLineStart) { - lastGoodBreak = pos; - } - } - if (lastGoodBreak == lastLineStart) { - // Try moving to start of last character - if (p > 0) { - lastGoodBreak = model.pdoc->MovePositionOutsideChar(p + posLineStart, -1) - posLineStart; - } - if (lastGoodBreak == lastLineStart) { - // Ensure at least one character on line. - lastGoodBreak = model.pdoc->MovePositionOutsideChar(lastGoodBreak + posLineStart + 1, 1) - posLineStart; - } - } - lastLineStart = lastGoodBreak; - ll->AddLineStart(lastLineStart); - startOffset = ll->positions[lastLineStart]; - // take into account the space for start wrap mark and indent - startOffset += width - ll->wrapIndent; - p = lastLineStart + 1; - } - } - ll->lines++; + ll->WrapLine(model.pdoc, posLineStart, vstyle.wrap.state); } ll->validity = LineLayout::ValidLevel::lines; } diff --git a/src/PositionCache.cxx b/src/PositionCache.cxx index ce932521a..f8b735bc0 100644 --- a/src/PositionCache.cxx +++ b/src/PositionCache.cxx @@ -326,6 +326,64 @@ int LineLayout::EndLineStyle() const noexcept { return styles[numCharsBeforeEOL > 0 ? numCharsBeforeEOL-1 : 0]; } +void LineLayout::WrapLine(const Document *pdoc, Sci::Position posLineStart, Wrap wrapState) { + // Document wants document positions but simpler to work in line positions + // so take care of adding and subtracting line start in a lambda. + auto CharacterBoundary = [=](Sci::Position i, Sci::Position moveDir) noexcept -> Sci::Position { + return pdoc->MovePositionOutsideChar(i + posLineStart, moveDir) - posLineStart; + }; + lines = 0; + // Calculate line start positions based upon width. + Sci::Position lastLineStart = 0; + XYPOSITION startOffset = widthLine; + Sci::Position p = 0; + while (p < numCharsInLine) { + while (p < numCharsInLine && positions[p + 1] < startOffset) { + p++; + } + if (p < numCharsInLine) { + // backtrack to find lastGoodBreak + Sci::Position lastGoodBreak = p; + if (p > 0) { + lastGoodBreak = CharacterBoundary(p, -1); + } + if (wrapState != Wrap::Char) { + Sci::Position pos = lastGoodBreak; + while (pos > lastLineStart) { + // style boundary and space + if (wrapState != Wrap::WhiteSpace && (styles[pos - 1] != styles[pos])) { + break; + } + if (IsBreakSpace(chars[pos - 1]) && !IsBreakSpace(chars[pos])) { + break; + } + pos = CharacterBoundary(pos - 1, -1); + } + if (pos > lastLineStart) { + lastGoodBreak = pos; + } + } + if (lastGoodBreak == lastLineStart) { + // Try moving to start of last character + if (p > 0) { + lastGoodBreak = CharacterBoundary(p, -1); + } + if (lastGoodBreak == lastLineStart) { + // Ensure at least one character on line. + lastGoodBreak = CharacterBoundary(lastGoodBreak + 1, 1); + } + } + lastLineStart = lastGoodBreak; + AddLineStart(lastLineStart); + startOffset = positions[lastLineStart]; + // take into account the space for start wrap mark and indent + startOffset += widthLine - wrapIndent; + p = lastLineStart + 1; + } + } + lines++; +} + ScreenLine::ScreenLine( const LineLayout *ll_, int subLine, diff --git a/src/PositionCache.h b/src/PositionCache.h index 9a4babae7..0a3434929 100644 --- a/src/PositionCache.h +++ b/src/PositionCache.h @@ -108,6 +108,7 @@ public: 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); }; struct ScreenLine : public IScreenLine { |