Repository: microsoft/terminal
File: src/buffer/out/textBuffer.cpp (C++)

Code before:
    if (height <= 0)
    {
        _decommit();
        return;
    }

    // Our goal is to move the viewport to the absolute start of the underlying memory buffer so that we can
    // MEM_DECOMMIT the remaining memory. _firstRow is used to make the TextBuffer behave like a circular buffer.
    // The start parameter is relative to the _firstRow. The trick to get the content to the absolute start
    // is to simply add _firstRow ourselves and then reset it to 0. This causes ScrollRows() to write into
    // the absolute start while reading from relative coordinates. This works because GetRowByOffset()
    // operates modulo the buffer height and so the possibly-too-large startAbsolute won't be an issue.
    const auto startAbsolute = _firstRow + start;
    _firstRow = 0;
    ScrollRows(startAbsolute, height, -startAbsolute);

    const auto end = _estimateOffsetOfLastCommittedRow();
    for (auto y = height; y < end; ++y)
    {
        GetMutableRowByOffset(y).Reset(_initialAttributes);
    }

    // Clear all the marks below the new viewport position.
    ClearMarksInRange(til::point{ 0, height }, til::point{ _width, _height });
    // Then scroll all the remaining marks up. This will trim ones that are now "outside" the buffer
    ScrollMarks(-start);
}

// Routine Description:
// - This is the legacy screen resize with minimal changes
// Arguments:
// - newSize - new size of screen.
// Return Value:
// - Success if successful. Invalid parameter if screen buffer size is unexpected. No memory if allocation failed.
void TextBuffer::ResizeTraditional(til::size newSize)
{
    // Guard against resizing the text buffer to 0 columns/rows, which would break being able to insert text.
    newSize.width = std::max(newSize.width, 1);
    newSize.height = std::max(newSize.height, 1);

    TextBuffer newBuffer{ newSize, _currentAttributes, 0, false, _renderer };
    const auto cursorRow = GetCursor().GetPosition().y;
    const auto copyableRows = std::min<til::CoordType>(_height, newSize.height);
    til::CoordType srcRow = 0;
    til::CoordType dstRow = 0;

    if (cursorRow >= newSize.height)
    {
        srcRow = cursorRow - newSize.height + 1;
    }


Review comment (bug):
Should this not be `-startAbsolute` now that we're moving to absolute 0?

Also, the order of these two operations seems wrong to me. I know that's how it's currently implemented, but surely that can't have been correct? If you're clearing from the `height` offset, that would assume the positions have already been moved to the top of the buffer.

Code after:
    if (height <= 0)
    {
        _decommit();
        return;
    }

    // Our goal is to move the viewport to the absolute start of the underlying memory buffer so that we can
    // MEM_DECOMMIT the remaining memory. _firstRow is used to make the TextBuffer behave like a circular buffer.
    // The start parameter is relative to the _firstRow. The trick to get the content to the absolute start
    // is to simply add _firstRow ourselves and then reset it to 0. This causes ScrollRows() to write into
    // the absolute start while reading from relative coordinates. This works because GetRowByOffset()
    // operates modulo the buffer height and so the possibly-too-large startAbsolute won't be an issue.
    const auto startAbsolute = _firstRow + start;
    _firstRow = 0;
    ScrollRows(startAbsolute, height, -startAbsolute);

    const auto end = _estimateOffsetOfLastCommittedRow();
    for (auto y = height; y <= end; ++y)
    {
        GetMutableRowByOffset(y).Reset(_initialAttributes);
    }

    ScrollMarks(-start);
    ClearMarksInRange(til::point{ 0, height }, til::point{ _width, _height });
}

// Routine Description:
// - This is the legacy screen resize with minimal changes
// Arguments:
// - newSize - new size of screen.
// Return Value:
// - Success if successful. Invalid parameter if screen buffer size is unexpected. No memory if allocation failed.
void TextBuffer::ResizeTraditional(til::size newSize)
{
    // Guard against resizing the text buffer to 0 columns/rows, which would break being able to insert text.
    newSize.width = std::max(newSize.width, 1);
    newSize.height = std::max(newSize.height, 1);

    TextBuffer newBuffer{ newSize, _currentAttributes, 0, false, _renderer };
    const auto cursorRow = GetCursor().GetPosition().y;
    const auto copyableRows = std::min<til::CoordType>(_height, newSize.height);
    til::CoordType srcRow = 0;
    til::CoordType dstRow = 0;

    if (cursorRow >= newSize.height)
    {
        srcRow = cursorRow - newSize.height + 1;
    }

    for (; dstRow < copyableRows; ++dstRow, ++srcRow)
    {