Repository: microsoft/terminal
File: src/buffer/out/LineRendition.hpp (C++)

Code before:
{
    // Use shift right to quickly divide the Left and Right by 2 for double width lines.
    const auto scale = lineRendition == LineRendition::SingleWidth ? 0 : 1;
    return { line.left >> scale, line.top, line.right >> scale, line.bottom };
}

constexpr til::inclusive_rect ScreenToBufferLine(const til::inclusive_rect& line, const LineRendition lineRendition)
{
    // Use shift right to quickly divide the Left and Right by 2 for double width lines.
    const auto scale = lineRendition == LineRendition::SingleWidth ? 0 : 1;
    return { line.left >> scale, line.top, line.right >> scale, line.bottom };
}

constexpr til::point ScreenToBufferLine(const til::point& line, const LineRendition lineRendition)
{
    // Use shift right to quickly divide the Left and Right by 2 for double width lines.
    const auto scale = lineRendition == LineRendition::SingleWidth ? 0 : 1;
    return { line.x >> scale, line.y };
}

constexpr til::rect BufferToScreenLine(const til::rect& line, const LineRendition lineRendition)
{
    // Use shift left to quickly multiply the Left and Right by 2 for double width lines.
    const auto scale = lineRendition == LineRendition::SingleWidth ? 0 : 1;
    return { line.left << scale, line.top, (line.right << scale) + scale, line.bottom };
}

constexpr til::inclusive_rect BufferToScreenLine(const til::inclusive_rect& line, const LineRendition lineRendition)
{
    // Use shift left to quickly multiply the Left and Right by 2 for double width lines.
    const auto scale = lineRendition == LineRendition::SingleWidth ? 0 : 1;
    return { line.left << scale, line.top, (line.right << scale) + scale, line.bottom };
}


Review comment (suggestion):
I think this may also be off by one when dealing with exclusive coordinates. For example, if the right buffer coordinate is 4 exclusive (3 inclusive), then the right screen coordinate should be 8 exclusive (7 inclusive). The current formula works for inclusive coordinates (`(3 << 1) + 1 = 7`), but not exclusive coordinates (`(4 << 1) + 1 = 9`, but we want 8).

Code after:
/*++
Copyright (c) Microsoft Corporation
Licensed under the MIT license.

Module Name:
- LineRendition.hpp

Abstract:
- Enumerated type for the VT line rendition attribute. This determines the
  width and height scaling with which each line is rendered.

--*/

#pragma once

enum class LineRendition : uint8_t
{
    SingleWidth,
    DoubleWidth,
    DoubleHeightTop,
    DoubleHeightBottom
};

constexpr til::inclusive_rect ScreenToBufferLine(const til::inclusive_rect& line, const LineRendition lineRendition)
{
    const auto scale = lineRendition == LineRendition::SingleWidth ? 0 : 1;
    return { line.left >> scale, line.top, line.right >> scale, line.bottom };
}

constexpr til::point ScreenToBufferLineInclusive(const til::point& line, const LineRendition lineRendition)
{
    const auto scale = lineRendition == LineRendition::SingleWidth ? 0 : 1;
    return { line.x >> scale, line.y };
}

constexpr til::rect BufferToScreenLine(const til::rect& line, const LineRendition lineRendition)
{
    const auto scale = lineRendition == LineRendition::SingleWidth ? 0 : 1;
    return { line.left << scale, line.top, line.right << scale, line.bottom };
}

constexpr til::inclusive_rect BufferToScreenLine(const til::inclusive_rect& line, const LineRendition lineRendition)
{
    const auto scale = lineRendition == LineRendition::SingleWidth ? 0 : 1;
    return { line.left << scale, line.top, (line.right << scale) + scale, line.bottom };
}