Skip to content

Commit ae0f682

Browse files
committed
wip
1 parent 934a06d commit ae0f682

File tree

7 files changed

+238
-466
lines changed

7 files changed

+238
-466
lines changed

src/buffer/out/Row.cpp

+43-86
Original file line numberDiff line numberDiff line change
@@ -141,25 +141,13 @@ ROW::ROW(wchar_t* charsBuffer, uint16_t* charOffsetsBuffer, uint16_t rowWidth, c
141141
_attr{ rowWidth, fillAttribute },
142142
_columnCount{ rowWidth }
143143
{
144-
if (_chars.data())
144+
SetBuffers(charsBuffer, charOffsetsBuffer, rowWidth, fillAttribute);
145+
if (charsBuffer)
145146
{
146147
_init();
147148
}
148149
}
149150

150-
void swap(ROW& lhs, ROW& rhs) noexcept
151-
{
152-
std::swap(lhs._charsBuffer, rhs._charsBuffer);
153-
std::swap(lhs._charsHeap, rhs._charsHeap);
154-
std::swap(lhs._chars, rhs._chars);
155-
std::swap(lhs._charOffsets, rhs._charOffsets);
156-
std::swap(lhs._attr, rhs._attr);
157-
std::swap(lhs._columnCount, rhs._columnCount);
158-
std::swap(lhs._lineRendition, rhs._lineRendition);
159-
std::swap(lhs._wrapForced, rhs._wrapForced);
160-
std::swap(lhs._doubleBytePadded, rhs._doubleBytePadded);
161-
}
162-
163151
void ROW::SetWrapForced(const bool wrap) noexcept
164152
{
165153
_wrapForced = wrap;
@@ -200,6 +188,19 @@ RowTextIterator ROW::End() const noexcept
200188
return { _chars, _charOffsets, _columnCount };
201189
}
202190

191+
void ROW::SetBuffers(wchar_t* charsBuffer, uint16_t* charOffsetsBuffer, uint16_t rowWidth, const TextAttribute& fillAttribute) noexcept
192+
{
193+
_charsBuffer = charsBuffer;
194+
_charsHeap.reset();
195+
_chars = { charsBuffer, rowWidth };
196+
_charOffsets = { charOffsetsBuffer, ::base::strict_cast<size_t>(rowWidth) + 1u };
197+
_attr = { rowWidth, fillAttribute };
198+
_columnCount = rowWidth;
199+
_lineRendition = LineRendition::SingleWidth;
200+
_wrapForced = false;
201+
_doubleBytePadded = false;
202+
}
203+
203204
// Routine Description:
204205
// - Sets all properties of the ROW to default values
205206
// Arguments:
@@ -223,78 +224,6 @@ void ROW::_init() noexcept
223224
std::iota(_charOffsets.begin(), _charOffsets.end(), uint16_t{ 0 });
224225
}
225226

226-
// Routine Description:
227-
// - resizes ROW to new width
228-
// Arguments:
229-
// - charsBuffer - a new backing buffer to use for _charsBuffer
230-
// - charOffsetsBuffer - a new backing buffer to use for _charOffsets
231-
// - rowWidth - the new width, in cells
232-
// - fillAttribute - the attribute to use for any newly added, trailing cells
233-
void ROW::Resize(wchar_t* charsBuffer, uint16_t* charOffsetsBuffer, uint16_t rowWidth, const TextAttribute& fillAttribute)
234-
{
235-
// A default-constructed ROW has no cols/chars to copy.
236-
// It can be detected by the lack of a _charsBuffer (among others).
237-
//
238-
// Otherwise, this block figures out how much we can copy into the new `rowWidth`.
239-
uint16_t colsToCopy = 0;
240-
uint16_t charsToCopy = 0;
241-
if (_charsBuffer)
242-
{
243-
colsToCopy = std::min(rowWidth, _columnCount);
244-
// Safety: colsToCopy is [0, _columnCount].
245-
charsToCopy = _uncheckedCharOffset(colsToCopy);
246-
// Safety: colsToCopy is [0, _columnCount] due to colsToCopy != 0.
247-
for (; colsToCopy != 0 && _uncheckedIsTrailer(colsToCopy); --colsToCopy)
248-
{
249-
}
250-
}
251-
252-
// If we grow the row width, we have to append a bunch of whitespace.
253-
// `trailingWhitespace` stores that amount.
254-
// Safety: The preceding block left colsToCopy in the range [0, rowWidth].
255-
const uint16_t trailingWhitespace = rowWidth - colsToCopy;
256-
257-
// Allocate memory for the new `_chars` array.
258-
// Use the provided charsBuffer if possible, otherwise allocate a `_charsHeap`.
259-
std::unique_ptr<wchar_t[]> charsHeap;
260-
std::span chars{ charsBuffer, rowWidth };
261-
const std::span charOffsets{ charOffsetsBuffer, ::base::strict_cast<size_t>(rowWidth) + 1u };
262-
if (const uint16_t charsCapacity = charsToCopy + trailingWhitespace; charsCapacity > rowWidth)
263-
{
264-
charsHeap = std::make_unique_for_overwrite<wchar_t[]>(charsCapacity);
265-
chars = { charsHeap.get(), charsCapacity };
266-
}
267-
268-
// Copy chars and charOffsets over.
269-
{
270-
const auto it = std::copy_n(_chars.begin(), charsToCopy, chars.begin());
271-
std::fill_n(it, trailingWhitespace, L' ');
272-
}
273-
{
274-
const auto it = std::copy_n(_charOffsets.begin(), colsToCopy, charOffsets.begin());
275-
// The _charOffsets array is 1 wider than newWidth indicates.
276-
// This is because the extra column contains the past-the-end index into _chars.
277-
iota_n(it, trailingWhitespace + 1u, charsToCopy);
278-
}
279-
280-
_charsBuffer = charsBuffer;
281-
_charsHeap = std::move(charsHeap);
282-
_chars = chars;
283-
_charOffsets = charOffsets;
284-
_columnCount = rowWidth;
285-
286-
// .resize_trailing_extent() doesn't work if the vector is empty,
287-
// since there's no trailing item that could be extended.
288-
if (_attr.empty())
289-
{
290-
_attr = { rowWidth, fillAttribute };
291-
}
292-
else
293-
{
294-
_attr.resize_trailing_extent(rowWidth);
295-
}
296-
}
297-
298227
void ROW::TransferAttributes(const til::small_rle<TextAttribute, uint16_t, 1>& attr, til::CoordType newWidth)
299228
{
300229
_attr = attr;
@@ -711,6 +640,34 @@ catch (...)
711640
{
712641
row.SetDoubleBytePadded(colEnd < row._columnCount);
713642
}
643+
644+
if constexpr (false)
645+
{
646+
auto it = row._charOffsets.begin();
647+
uint16_t expected = 0;
648+
649+
for (const auto& s : til::utf16_iterator{ row.GetText() })
650+
{
651+
const auto wide = til::at(s, 0) < 0x80 ? false : IsGlyphFullWidth(s);
652+
653+
if (*it != expected)
654+
{
655+
__debugbreak();
656+
}
657+
++it;
658+
659+
if (wide)
660+
{
661+
if (*it != (expected | CharOffsetsTrailer))
662+
{
663+
__debugbreak();
664+
}
665+
++it;
666+
}
667+
668+
expected = gsl::narrow_cast<uint16_t>(expected + s.size());
669+
}
670+
}
714671
}
715672

716673
// This function represents the slow path of ReplaceCharacters(),

src/buffer/out/Row.hpp

+3-5
Original file line numberDiff line numberDiff line change
@@ -91,11 +91,9 @@ class ROW final
9191
ROW(const ROW& other) = delete;
9292
ROW& operator=(const ROW& other) = delete;
9393

94-
explicit ROW(ROW&& other) = default;
94+
ROW(ROW&& other) = default;
9595
ROW& operator=(ROW&& other) = default;
96-
97-
friend void swap(ROW& lhs, ROW& rhs) noexcept;
98-
96+
9997
void SetWrapForced(const bool wrap) noexcept;
10098
bool WasWrapForced() const noexcept;
10199
void SetDoubleBytePadded(const bool doubleBytePadded) noexcept;
@@ -105,8 +103,8 @@ class ROW final
105103
RowTextIterator Begin() const noexcept;
106104
RowTextIterator End() const noexcept;
107105

106+
void SetBuffers(wchar_t* charsBuffer, uint16_t* charOffsetsBuffer, uint16_t rowWidth, const TextAttribute& fillAttribute) noexcept;
108107
void Reset(const TextAttribute& attr);
109-
void Resize(wchar_t* charsBuffer, uint16_t* charOffsetsBuffer, uint16_t rowWidth, const TextAttribute& fillAttribute);
110108
void TransferAttributes(const til::small_rle<TextAttribute, uint16_t, 1>& attr, til::CoordType newWidth);
111109

112110
til::CoordType NavigateToPrevious(til::CoordType column) const noexcept;

0 commit comments

Comments
 (0)