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

Code before:
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::rect ScreenToBufferLine(const til::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::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;

Review comment (suggestion):
I think the right hand side may be off by one when you're dealing with exclusive coordinates with an odd value. For example, if the right screen coordinate is 7 exclusive (6 inclusive), that should map to a buffer coordinate of 4 exclusive (3 inclusive). A simple right shift works for inclusive coordinates (`6 >> 1 = 3`), but not for exclusive coordinates (`7 >> 1 = 3`, but we want 4).

Code after:
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 };
}