Repository: microsoft/terminal
File: src/renderer/atlas/AtlasEngine.cpp (C++)

Code before:
    for (auto rect : rects)
    {
        const auto y = gsl::narrow_cast<u16>(clamp<til::CoordType>(rect.top, 0, _p.s->viewportCellCount.y));
        const auto from = gsl::narrow_cast<u16>(clamp<til::CoordType>(rect.left, 0, _p.s->viewportCellCount.x - 1));
        const auto to = gsl::narrow_cast<u16>(clamp<til::CoordType>(rect.right, from, _p.s->viewportCellCount.x));

        if (y < _p.rows.size() && rect.top >= 0)
        {
            auto& row = *_p.rows[y];

            auto it = std::find_if(row.searchSelections.begin(), row.searchSelections.end(), [&from](const SearchSelection& selection) {
                return selection.from == from;
            });

            if (it != row.searchSelections.end())
            {
                if (to > it->to)
                {
                    it->to = to;
                }
            }
            else
            {
                auto s = SearchSelection{ from, to };
                row.searchSelections.emplace_back(s);
            }

            _p.dirtyRectInPx.left = std::min(_p.dirtyRectInPx.left, from * _p.s->font->cellSize.x);
            _p.dirtyRectInPx.top = std::min(_p.dirtyRectInPx.top, y * _p.s->font->cellSize.y);
            _p.dirtyRectInPx.right = std::max(_p.dirtyRectInPx.right, to * _p.s->font->cellSize.x);
            _p.dirtyRectInPx.bottom = std::max(_p.dirtyRectInPx.bottom, _p.dirtyRectInPx.top + _p.s->font->cellSize.y);
        }
    }
    return S_OK;
}
CATCH_RETURN()

[[nodiscard]] HRESULT AtlasEngine::PaintCursor(const CursorOptions& options) noexcept
try
{
    // Unfortunately there's no step after Renderer::_PaintBufferOutput that
    // would inform us that it's done with the last AtlasEngine::PaintBufferLine.
    // As such we got to call _flushBufferLine() here just to be sure.
    _flushBufferLine();

    {
        const CursorSettings cachedOptions{
            .cursorColor = gsl::narrow_cast<u32>(options.fUseColor ? options.cursorColor | 0xff000000 : INVALID_COLOR),
            .cursorType = gsl::narrow_cast<u16>(options.cursorType),
            .heightPercentage = gsl::narrow_cast<u16>(options.ulCursorHeightPercent),
        };

Review comment (performance):
This code rejoins neighboring search results, but is that really such a common scenario that it outweighs the cost of turning this O(n) outer loop into O(n^2)?

Previously we only had a 1 selection overlay per row at most (the regular, manual selection by a user). Now, with an arbitrary number of disjoint selections per row, the technically best approach is to resize `RenderingPayload::colorBitmap` to contain 3 textures and not just 2. Right now the bitmap contains the background and foreground bitmaps back to back, but it could also contain a bitmap for the selection. Then, in `BackendD3D` we simply overlay this bitmap on top of the previously drawn text, similar to how we draw the background as the first step.
But making this change is fairly challenging and I don't expect you to make it.

Code after:

    for (const auto& rect : rects)
    {
        const auto y = gsl::narrow_cast<u16>(clamp<til::CoordType>(rect.top, 0, _p.s->viewportCellCount.y));
        const auto from = gsl::narrow_cast<u16>(clamp<til::CoordType>(rect.left, 0, _p.s->viewportCellCount.x - 1));
        const auto to = gsl::narrow_cast<u16>(clamp<til::CoordType>(rect.right, from, _p.s->viewportCellCount.x));

        if (rect.bottom <= 0 || rect.top >= _p.s->viewportCellCount.y)
        {
            continue;
        }

        const auto bg = &_p.backgroundBitmap[_p.colorBitmapRowStride * y];
        const auto fg = &_p.foregroundBitmap[_p.colorBitmapRowStride * y];
        std::fill(bg + from, bg + to, 0xff3296ff);
        std::fill(fg + from, fg + to, 0xff000000);
    }

    for (int i = 0; i < 2; ++i)
    {
        _p.colorBitmapGenerations[i].bump();
    }

    return S_OK;
}
CATCH_RETURN()

[[nodiscard]] HRESULT AtlasEngine::PaintCursor(const CursorOptions& options) noexcept
try
{
    // Unfortunately there's no step after Renderer::_PaintBufferOutput that
    // would inform us that it's done with the last AtlasEngine::PaintBufferLine.
    // As such we got to call _flushBufferLine() here just to be sure.
    _flushBufferLine();

    {
        const CursorSettings cachedOptions{
            .cursorColor = gsl::narrow_cast<u32>(options.fUseColor ? options.cursorColor | 0xff000000 : INVALID_COLOR),
            .cursorType = gsl::narrow_cast<u16>(options.cursorType),
            .heightPercentage = gsl::narrow_cast<u16>(options.ulCursorHeightPercent),
        };
        if (*_api.s->cursor != cachedOptions)
        {
            *_api.s.write()->cursor.write() = cachedOptions;
            *_p.s.write()->cursor.write() = cachedOptions;
        }
    }

    if (options.isOn)
    {
        const auto cursorWidth = 1 + (options.fIsDoubleWidth & (options.cursorType != CursorType::VerticalBar));