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

Code before:
                if (*it != color)
                {
                    _p.colorBitmapGenerations[i].bump();
                    std::fill(it, end, color);
                    break;
                }
            }

            beg += _p.colorBitmapDepthStride;
            end += _p.colorBitmapDepthStride;
        }
    }

    _api.lastPaintBufferLineCoord = { x, y };
    return S_OK;
}
CATCH_RETURN()

[[nodiscard]] HRESULT AtlasEngine::PaintBufferGridLines(const GridLineSet lines, const COLORREF color, const size_t cchLine, const til::point coordTarget) noexcept
try
{
    const auto shift = gsl::narrow_cast<u8>(_api.lineRendition != LineRendition::SingleWidth);
    const auto y = gsl::narrow_cast<u16>(clamp<til::CoordType>(coordTarget.y, 0, _p.s->cellCount.y));
    const auto from = gsl::narrow_cast<u16>(clamp<til::CoordType>(coordTarget.x << shift, 0, _p.s->cellCount.x - 1));
    const auto to = gsl::narrow_cast<u16>(clamp<size_t>((coordTarget.x + cchLine) << shift, from, _p.s->cellCount.x));
    const auto fg = gsl::narrow_cast<u32>(color) | 0xff000000;
    _p.rows[y]->gridLineRanges.emplace_back(lines, fg, from, to);
    return S_OK;
}
CATCH_RETURN()

[[nodiscard]] HRESULT AtlasEngine::PaintSelection(const til::rect& rect) 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 auto y = gsl::narrow_cast<u16>(clamp<til::CoordType>(rect.top, 0, _p.s->cellCount.y));
    const auto from = gsl::narrow_cast<u16>(clamp<til::CoordType>(rect.left, 0, _p.s->cellCount.x - 1));
    const auto to = gsl::narrow_cast<u16>(clamp<til::CoordType>(rect.right, from, _p.s->cellCount.x));

    auto& row = *_p.rows[y];
    row.selectionFrom = from;
    row.selectionTo = to;

    _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);

Review comment (suggestion):
Here, the only change is that `coordTarget.x` is replaced with `x`.
`coordTarget.x` is in textbuffer-relative coordinates (so when you scroll horizontally, the left edge of the viewport might be something non-0), but we need viewport relative coordinates where the left edge is always 0.
To do so we first need to horizontal scroll-offset `viewportOffset.x` from the `coordTarget.x`, but this breaks with line renditions, because the caller already divides `coordTarget.x` by 2, whereas `viewportOffset.x` is not being divided by 2.

And so we first shift `viewportOffset.x` to the right, then subtract and then finally shift it to the left again to get viewport-relative, unshifted coordinates.

Code after:
                if (*it != color)
                {
                    _p.colorBitmapGenerations[i].bump();
                    std::fill(it, end, color);
                    break;
                }
            }

            beg += _p.colorBitmapDepthStride;
            end += _p.colorBitmapDepthStride;
        }
    }

    _api.lastPaintBufferLineCoord = { x, y };
    return S_OK;
}
CATCH_RETURN()

[[nodiscard]] HRESULT AtlasEngine::PaintBufferGridLines(const GridLineSet lines, const COLORREF color, const size_t cchLine, const til::point coordTarget) noexcept
try
{
    const auto shift = gsl::narrow_cast<u8>(_api.lineRendition != LineRendition::SingleWidth);
    const auto x = std::max(0, coordTarget.x - (_p.s->viewportOffset.x >> shift));
    const auto y = gsl::narrow_cast<u16>(clamp<til::CoordType>(coordTarget.y, 0, _p.s->viewportCellCount.y));
    const auto from = gsl::narrow_cast<u16>(clamp<til::CoordType>(x << shift, 0, _p.s->viewportCellCount.x - 1));
    const auto to = gsl::narrow_cast<u16>(clamp<size_t>((x + cchLine) << shift, from, _p.s->viewportCellCount.x));
    const auto fg = gsl::narrow_cast<u32>(color) | 0xff000000;
    _p.rows[y]->gridLineRanges.emplace_back(lines, fg, from, to);
    return S_OK;
}
CATCH_RETURN()

[[nodiscard]] HRESULT AtlasEngine::PaintSelection(const til::rect& rect) 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 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));

    auto& row = *_p.rows[y];
    row.selectionFrom = from;
    row.selectionTo = to;

    _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);