Repository: microsoft/terminal
File: src/host/screenInfo.cpp (C++)

Code before:
                                                     _textBuffer->GetRenderer());
    }
    catch (...)
    {
        return NTSTATUS_FROM_HRESULT(wil::ResultFromCaughtException());
    }

    // Save cursor's relative height versus the viewport
    const auto sCursorHeightInViewportBefore = _textBuffer->GetCursor().GetPosition().Y - _viewport.Top();

    // skip any drawing updates that might occur until we swap _textBuffer with the new buffer or we exit early.
    newTextBuffer->GetCursor().StartDeferDrawing();
    _textBuffer->GetCursor().StartDeferDrawing();
    // we're capturing _textBuffer by reference here because when we exit, we want to EndDefer on the current active buffer.
    auto endDefer = wil::scope_exit([&]() noexcept { _textBuffer->GetCursor().EndDeferDrawing(); });

    auto hr = TextBuffer::Reflow(*_textBuffer.get(), *newTextBuffer.get(), std::nullopt, std::nullopt);

    if (SUCCEEDED(hr))
    {
        auto& newCursor = newTextBuffer->GetCursor();
        // Adjust the viewport so the cursor doesn't wildly fly off up or down.
        const auto sCursorHeightInViewportAfter = newCursor.GetPosition().Y - _viewport.Top();
        COORD coordCursorHeightDiff = { 0 };
        coordCursorHeightDiff.Y = gsl::narrow_cast<short>(sCursorHeightInViewportAfter - sCursorHeightInViewportBefore);
        LOG_IF_FAILED(SetViewportOrigin(false, coordCursorHeightDiff, true));

        newTextBuffer->SetCurrentAttributes(oldPrimaryAttributes);

        _textBuffer.swap(newTextBuffer);
    }

    return NTSTATUS_FROM_HRESULT(hr);
}

//
// Routine Description:
// - This is the legacy screen resize with minimal changes
// Arguments:
// - coordNewScreenSize - new size of screen.
// Return Value:
// - Success if successful. Invalid parameter if screen buffer size is unexpected. No memory if allocation failed.
[[nodiscard]] NTSTATUS SCREEN_INFORMATION::ResizeTraditional(const COORD coordNewScreenSize)
{
    _textBuffer->GetCursor().StartDeferDrawing();
    auto endDefer = wil::scope_exit([&]() noexcept { _textBuffer->GetCursor().EndDeferDrawing(); });
    return NTSTATUS_FROM_HRESULT(_textBuffer->ResizeTraditional(coordNewScreenSize));
}

//
// Routine Description:

Review comment (performance):
`GetLastNonSpaceCharacter` is very very slow if the text buffer is mostly empty.
Will this be a problem? Is there some other way we can extract this information?

Code after:
                                                     0, // temporarily set size to 0 so it won't render.
                                                     _textBuffer->IsActiveBuffer(),
                                                     _textBuffer->GetRenderer());
    }
    catch (...)
    {
        return NTSTATUS_FROM_HRESULT(wil::ResultFromCaughtException());
    }

    // Save cursor's relative height versus the viewport
    const auto sCursorHeightInViewportBefore = _textBuffer->GetCursor().GetPosition().Y - _viewport.Top();

    // skip any drawing updates that might occur until we swap _textBuffer with the new buffer or we exit early.
    newTextBuffer->GetCursor().StartDeferDrawing();
    _textBuffer->GetCursor().StartDeferDrawing();
    // we're capturing _textBuffer by reference here because when we exit, we want to EndDefer on the current active buffer.
    auto endDefer = wil::scope_exit([&]() noexcept { _textBuffer->GetCursor().EndDeferDrawing(); });

    auto hr = TextBuffer::Reflow(*_textBuffer.get(), *newTextBuffer.get(), std::nullopt, std::nullopt);

    if (SUCCEEDED(hr))
    {
        // Make sure the new virtual bottom is far enough down to include both
        // the cursor row and the last non-space row.
        const auto cursorRow = newTextBuffer->GetCursor().GetPosition().Y;
        const auto lastNonSpaceRow = newTextBuffer->GetLastNonSpaceCharacter().Y;
        _virtualBottom = std::max({ cursorRow, lastNonSpaceRow });

        // Adjust the viewport so the cursor doesn't wildly fly off up or down.
        const auto sCursorHeightInViewportAfter = cursorRow - _viewport.Top();
        COORD coordCursorHeightDiff = { 0 };
        coordCursorHeightDiff.Y = gsl::narrow_cast<short>(sCursorHeightInViewportAfter - sCursorHeightInViewportBefore);
        LOG_IF_FAILED(SetViewportOrigin(false, coordCursorHeightDiff, false));

        newTextBuffer->SetCurrentAttributes(oldPrimaryAttributes);

        _textBuffer.swap(newTextBuffer);
    }

    return NTSTATUS_FROM_HRESULT(hr);
}

//
// Routine Description:
// - This is the legacy screen resize with minimal changes
// Arguments:
// - coordNewScreenSize - new size of screen.
// Return Value:
// - Success if successful. Invalid parameter if screen buffer size is unexpected. No memory if allocation failed.
[[nodiscard]] NTSTATUS SCREEN_INFORMATION::ResizeTraditional(const COORD coordNewScreenSize)
{