diff options
author | Neil <nyamatongwe@gmail.com> | 2023-01-25 16:48:16 +1100 |
---|---|---|
committer | Neil <nyamatongwe@gmail.com> | 2023-01-25 16:48:16 +1100 |
commit | cc899ffb690aa53cfaff02fafb5297515f292164 (patch) | |
tree | 4e88e9d470d53fd9b0dd4c266949d94b43f77df8 /src/PositionCache.cxx | |
parent | 1a9af9dcdfcc8b6c1124278f3c1d9d64075ae82b (diff) | |
download | scintilla-mirror-cc899ffb690aa53cfaff02fafb5297515f292164.tar.gz |
Hoist line wrapping code into LineLayout::WrapLine as it has few dependencies.
Diffstat (limited to 'src/PositionCache.cxx')
-rw-r--r-- | src/PositionCache.cxx | 58 |
1 files changed, 58 insertions, 0 deletions
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, |