@@ -80,19 +80,20 @@ constexpr OutIt copy_n_small(InIt first, Diff count, OutIt dest)
8080 return dest;
8181}
8282
83- CharToColumnMapper::CharToColumnMapper (const wchar_t * chars, const uint16_t * charOffsets, ptrdiff_t lastCharOffset , til::CoordType currentColumn) noexcept :
83+ CharToColumnMapper::CharToColumnMapper (const wchar_t * chars, const uint16_t * charOffsets, ptrdiff_t charsLength , til::CoordType currentColumn, til::CoordType columnCount ) noexcept :
8484 _chars{ chars },
8585 _charOffsets{ charOffsets },
86- _lastCharOffset{ lastCharOffset },
87- _currentColumn{ currentColumn }
86+ _charsLength{ charsLength },
87+ _currentColumn{ currentColumn },
88+ _columnCount{ columnCount }
8889{
8990}
9091
9192// If given a position (`offset`) inside the ROW's text, this function will return the corresponding column.
9293// This function in particular returns the glyph's first column.
9394til::CoordType CharToColumnMapper::GetLeadingColumnAt (ptrdiff_t targetOffset) noexcept
9495{
95- targetOffset = clamp (targetOffset, 0 , _lastCharOffset );
96+ targetOffset = clamp (targetOffset, 0 , _charsLength );
9697
9798 // This code needs to fulfill two conditions on top of the obvious (a forward/backward search):
9899 // A: We never want to stop on a column that is marked with CharOffsetsTrailer (= "GetLeadingColumn").
@@ -130,10 +131,14 @@ til::CoordType CharToColumnMapper::GetLeadingColumnAt(ptrdiff_t targetOffset) no
130131til::CoordType CharToColumnMapper::GetTrailingColumnAt (ptrdiff_t offset) noexcept
131132{
132133 auto col = GetLeadingColumnAt (offset);
133- // This loop is a little redundant with the forward search loop in GetLeadingColumnAt()
134- // but it's realistically not worth caring about this. This code is not a bottleneck.
135- for (; WI_IsFlagSet (_charOffsets[col + 1 ], CharOffsetsTrailer); ++col)
134+
135+ if (col < _columnCount)
136136 {
137+ // This loop is a little redundant with the forward search loop in GetLeadingColumnAt()
138+ // but it's realistically not worth caring about this. This code is not a bottleneck.
139+ for (; WI_IsFlagSet (_charOffsets[col + 1 ], CharOffsetsTrailer); ++col)
140+ {
141+ }
137142 }
138143 return col;
139144}
@@ -1114,6 +1119,9 @@ std::wstring_view ROW::GetText() const noexcept
11141119 return { _chars.data (), width };
11151120}
11161121
1122+ // Arguments:
1123+ // - columnBegin: inclusive
1124+ // - columnEnd: exclusive
11171125std::wstring_view ROW::GetText (til::CoordType columnBegin, til::CoordType columnEnd) const noexcept
11181126{
11191127 const auto columns = GetReadableColumnCount ();
@@ -1219,15 +1227,15 @@ T ROW::_adjustForward(T column) const noexcept
12191227}
12201228
12211229// Creates a CharToColumnMapper given an offset into _chars.data().
1222- // In other words, for a 120 column ROW with just ASCII text, the offset should be [0,120) .
1230+ // In other words, for a 120 column ROW with just ASCII text, the offset should be [0,120] .
12231231CharToColumnMapper ROW::_createCharToColumnMapper (ptrdiff_t offset) const noexcept
12241232{
12251233 const auto charsSize = _charSize ();
1226- const auto lastChar = gsl::narrow_cast<ptrdiff_t >(charsSize - 1 );
1234+ const auto lastChar = gsl::narrow_cast<ptrdiff_t >(charsSize);
12271235 // We can sort of guess what column belongs to what offset because BMP glyphs are very common and
12281236 // UTF-16 stores them in 1 char. In other words, usually a ROW will have N chars for N columns.
12291237 const auto guessedColumn = gsl::narrow_cast<til::CoordType>(clamp (offset, 0 , _columnCount));
1230- return CharToColumnMapper{ _chars.data (), _charOffsets.data (), lastChar, guessedColumn };
1238+ return CharToColumnMapper{ _chars.data (), _charOffsets.data (), lastChar, guessedColumn, _columnCount };
12311239}
12321240
12331241const std::optional<ScrollbarData>& ROW::GetScrollbarData () const noexcept
0 commit comments