Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for ITU's T.416 - ODA SGR (38/48) sequence #15729

Merged
merged 13 commits into from Jul 21, 2023
22 changes: 11 additions & 11 deletions src/buffer/out/TextAttribute.cpp
Expand Up @@ -166,14 +166,14 @@ void TextAttribute::SetBackground(const TextColor background) noexcept
_background = background;
}

void TextAttribute::SetForeground(const COLORREF rgbForeground) noexcept
void TextAttribute::SetForeground(const COLORREF rgbForeground, const bool isColon) noexcept
{
_foreground = TextColor(rgbForeground);
_foreground = TextColor(rgbForeground, isColon);
}

void TextAttribute::SetBackground(const COLORREF rgbBackground) noexcept
void TextAttribute::SetBackground(const COLORREF rgbBackground, const bool isColon) noexcept
{
_background = TextColor(rgbBackground);
_background = TextColor(rgbBackground, isColon);
}

void TextAttribute::SetIndexedForeground(const BYTE fgIndex) noexcept
Expand All @@ -186,25 +186,25 @@ void TextAttribute::SetIndexedBackground(const BYTE bgIndex) noexcept
_background = TextColor(bgIndex, false);
}

void TextAttribute::SetIndexedForeground256(const BYTE fgIndex) noexcept
void TextAttribute::SetIndexedForeground256(const BYTE fgIndex, const bool isColon) noexcept
{
_foreground = TextColor(fgIndex, true);
_foreground = TextColor(fgIndex, true, isColon);
}

void TextAttribute::SetIndexedBackground256(const BYTE bgIndex) noexcept
void TextAttribute::SetIndexedBackground256(const BYTE bgIndex, const bool isColon) noexcept
{
_background = TextColor(bgIndex, true);
_background = TextColor(bgIndex, true, isColon);
}

void TextAttribute::SetColor(const COLORREF rgbColor, const bool fIsForeground) noexcept
void TextAttribute::SetColor(const COLORREF rgbColor, const bool fIsForeground, const bool isColon) noexcept
{
if (fIsForeground)
{
SetForeground(rgbColor);
SetForeground(rgbColor, isColon);
}
else
{
SetBackground(rgbColor);
SetBackground(rgbColor, isColon);
}
}

Expand Down
10 changes: 5 additions & 5 deletions src/buffer/out/TextAttribute.hpp
Expand Up @@ -120,13 +120,13 @@ class TextAttribute final
uint16_t GetHyperlinkId() const noexcept;
void SetForeground(const TextColor foreground) noexcept;
void SetBackground(const TextColor background) noexcept;
void SetForeground(const COLORREF rgbForeground) noexcept;
void SetBackground(const COLORREF rgbBackground) noexcept;
void SetForeground(const COLORREF rgbForeground, const bool isColon = false) noexcept;
void SetBackground(const COLORREF rgbBackground, const bool isColon = false) noexcept;
void SetIndexedForeground(const BYTE fgIndex) noexcept;
void SetIndexedBackground(const BYTE bgIndex) noexcept;
void SetIndexedForeground256(const BYTE fgIndex) noexcept;
void SetIndexedBackground256(const BYTE bgIndex) noexcept;
void SetColor(const COLORREF rgbColor, const bool fIsForeground) noexcept;
void SetIndexedForeground256(const BYTE fgIndex, const bool isColon = false) noexcept;
void SetIndexedBackground256(const BYTE bgIndex, const bool isColon = false) noexcept;
void SetColor(const COLORREF rgbColor, const bool fIsForeground, const bool isColon = false) noexcept;
void SetHyperlinkId(uint16_t id) noexcept;

void SetDefaultForeground() noexcept;
Expand Down
39 changes: 32 additions & 7 deletions src/buffer/out/TextColor.cpp
Expand Up @@ -74,7 +74,7 @@ bool TextColor::IsIndex16() const noexcept

bool TextColor::IsIndex256() const noexcept
{
return _meta == ColorType::IsIndex256;
return _meta == ColorType::IsIndex256 || _meta == ColorType::IsIndex256Colon;
}

bool TextColor::IsDefault() const noexcept
Expand All @@ -84,24 +84,30 @@ bool TextColor::IsDefault() const noexcept

bool TextColor::IsDefaultOrLegacy() const noexcept
{
return _meta != ColorType::IsRgb && _index < 16;
return !IsRgb() && _index < 16;
}

bool TextColor::IsRgb() const noexcept
{
return _meta == ColorType::IsRgb;
return _meta == ColorType::IsRgb || _meta == ColorType::IsRgbColon;
}

bool TextColor::IsColon() const noexcept
{
return _meta == ColorType::IsRgbColon || _meta == ColorType::IsIndex256Colon;
}

// Method Description:
// - Sets the color value of this attribute, and sets this color to be an RGB
// attribute.
// Arguments:
// - rgbColor: the COLORREF containing the color information for this TextColor
// - isColon: whether or not this TextColor should be a colon variant.
// Return Value:
// - <none>
void TextColor::SetColor(const COLORREF rgbColor) noexcept
void TextColor::SetColor(const COLORREF rgbColor, const bool isColon) noexcept
{
_meta = ColorType::IsRgb;
_meta = isColon ? ColorType::IsRgbColon : ColorType::IsRgb;
_red = GetRValue(rgbColor);
_green = GetGValue(rgbColor);
_blue = GetBValue(rgbColor);
Expand All @@ -112,11 +118,12 @@ void TextColor::SetColor(const COLORREF rgbColor) noexcept
// Arguments:
// - index: the index of the colortable we should use for this TextColor.
// - isIndex256: is this a 256 color index (true) or a 16 color index (false).
// - isColon: whether or not this TextColor should be a colon variant.
// Return Value:
// - <none>
void TextColor::SetIndex(const BYTE index, const bool isIndex256) noexcept
void TextColor::SetIndex(const BYTE index, const bool isIndex256, const bool isColon) noexcept
{
_meta = isIndex256 ? ColorType::IsIndex256 : ColorType::IsIndex16;
_meta = isIndex256 ? (isColon ? ColorType::IsIndex256Colon : ColorType::IsIndex256) : ColorType::IsIndex16;
_index = index;
_green = 0;
_blue = 0;
Expand All @@ -137,6 +144,24 @@ void TextColor::SetDefault() noexcept
_blue = 0;
}

// Method Description:
// - Sets this TextColor to be a colon variant of the current ColorType.
// Arguments:
// - isColon: whether or not this TextColor should be a colon variant.
// Return Value:
// - <none>
void TextColor::SetColon(const bool isColon) noexcept
{
if (IsIndex256())
{
_meta = isColon ? ColorType::IsIndex256Colon : ColorType::IsIndex256;
}
else if (IsRgb())
{
_meta = isColon ? ColorType::IsRgbColon : ColorType::IsRgb;
}
}

// Method Description:
// - Retrieve the real color value for this TextColor.
// * If we're an RGB color, we'll use that value.
Expand Down
23 changes: 14 additions & 9 deletions src/buffer/out/TextColor.h
Expand Up @@ -44,7 +44,9 @@ enum class ColorType : BYTE
IsDefault,
IsIndex16,
IsIndex256,
IsRgb
IsIndex256Colon,
IsRgb,
IsRgbColon
tusharsnx marked this conversation as resolved.
Show resolved Hide resolved
};

enum class ColorAlias : size_t
Expand Down Expand Up @@ -92,16 +94,17 @@ struct TextColor
{
}

constexpr TextColor(const BYTE index, const bool isIndex256) noexcept :
_meta{ isIndex256 ? ColorType::IsIndex256 : ColorType::IsIndex16 },
constexpr TextColor(const BYTE index, const bool isIndex256, const bool isColon = false) noexcept :
// isColon is only used with IsIndex256.
_meta{ isIndex256 ? (isColon ? ColorType::IsIndex256Colon : ColorType::IsIndex256) : ColorType::IsIndex16 },
_index{ index },
_green{ 0 },
_blue{ 0 }
{
}

constexpr TextColor(const COLORREF rgb) noexcept :
_meta{ ColorType::IsRgb },
constexpr TextColor(const COLORREF rgb, const bool isColon = false) noexcept :
_meta{ isColon ? ColorType::IsRgbColon : ColorType::IsRgb },
_red{ GetRValue(rgb) },
_green{ GetGValue(rgb) },
_blue{ GetBValue(rgb) }
Expand All @@ -125,10 +128,12 @@ struct TextColor
bool IsDefault() const noexcept;
bool IsDefaultOrLegacy() const noexcept;
bool IsRgb() const noexcept;
bool IsColon() const noexcept;

void SetColor(const COLORREF rgbColor) noexcept;
void SetIndex(const BYTE index, const bool isIndex256) noexcept;
void SetColor(const COLORREF rgbColor, const bool isColon = false) noexcept;
void SetIndex(const BYTE index, const bool isIndex256, const bool isColon = false) noexcept;
void SetDefault() noexcept;
void SetColon(const bool isColon) noexcept;

COLORREF GetColor(const std::array<COLORREF, TABLE_SIZE>& colorTable, const size_t defaultIndex, bool brighten = false) const noexcept;
BYTE GetLegacyIndex(const BYTE defaultIndex) const noexcept;
Expand Down Expand Up @@ -184,11 +189,11 @@ namespace WEX
}
else if (color.IsRgb())
{
return WEX::Common::NoThrowString().Format(L"{RGB:0x%06x}", color.GetRGB());
return WEX::Common::NoThrowString().Format((color.IsColon() ? L"{RGB:0x%06x} (Colon)" : L"{RGB:0x%06x}"), color.GetRGB());
}
else
{
return WEX::Common::NoThrowString().Format(L"{index:0x%04x}", color._red);
return WEX::Common::NoThrowString().Format((color.IsColon() ? L"{index:0x%04x} (Colon)" : L"{index:0x%04x}"), color._red);
}
}
};
Expand Down
6 changes: 5 additions & 1 deletion src/terminal/adapter/DispatchTypes.hpp
Expand Up @@ -166,7 +166,8 @@ namespace Microsoft::Console::VirtualTerminal

constexpr VTParameter at(const size_t index) const noexcept
{
return til::at(_subParams, index);
// If the index is out of range, we return a sub parameter with no value.
return index < _subParams.size() ? til::at(_subParams, index) : defaultParameter;
}

VTSubParameters subspan(const size_t offset, const size_t count) const noexcept
Expand All @@ -191,6 +192,9 @@ namespace Microsoft::Console::VirtualTerminal
}

private:
static constexpr VTParameter defaultParameter{};
static constexpr std::span defaultParameters{ &defaultParameter, 1 };
tusharsnx marked this conversation as resolved.
Show resolved Hide resolved

std::span<const VTParameter> _subParams;
};

Expand Down
18 changes: 16 additions & 2 deletions src/terminal/adapter/adaptDispatch.cpp
Expand Up @@ -4117,14 +4117,28 @@ void AdaptDispatch::_ReportSGRSetting() const
else if (color.IsIndex256())
{
const auto index = color.GetIndex();
fmt::format_to(std::back_inserter(response), FMT_COMPILE(L";{};5;{}"), base + 8, index);
if (color.IsColon())
{
fmt::format_to(std::back_inserter(response), FMT_COMPILE(L";{}:5:{}"), base + 8, index);
}
else
{
fmt::format_to(std::back_inserter(response), FMT_COMPILE(L";{};5;{}"), base + 8, index);
}
}
else if (color.IsRgb())
{
const auto r = GetRValue(color.GetRGB());
const auto g = GetGValue(color.GetRGB());
const auto b = GetBValue(color.GetRGB());
fmt::format_to(std::back_inserter(response), FMT_COMPILE(L";{};2;{};{};{}"), base + 8, r, g, b);
if (color.IsColon())
{
fmt::format_to(std::back_inserter(response), FMT_COMPILE(";{}:2::{}:{}:{}"), base + 8, r, g, b);
}
else
{
fmt::format_to(std::back_inserter(response), FMT_COMPILE(";{};2;{};{};{}"), base + 8, r, g, b);
}
}
};
addColor(30, attr.GetForeground());
Expand Down
9 changes: 6 additions & 3 deletions src/terminal/adapter/adaptDispatch.hpp
Expand Up @@ -297,12 +297,15 @@ namespace Microsoft::Console::VirtualTerminal
size_t _SetRgbColorsHelper(const VTParameters options,
TextAttribute& attr,
const bool isForeground) noexcept;
void _SetRgbColorsHelperAlt(const VTParameter colorItem,
const VTSubParameters options,
TextAttribute& attr) noexcept;
size_t _ApplyGraphicsOption(const VTParameters options,
const size_t optionIndex,
TextAttribute& attr) noexcept;
void _ApplyGraphicsOptionSubParam(const VTParameter option,
const VTSubParameters subParams,
TextAttribute& attr) noexcept;
void _ApplyGraphicsOptionAlt(const VTParameter option,
const VTSubParameters subParams,
TextAttribute& attr) noexcept;
void _ApplyGraphicsOptions(const VTParameters options,
TextAttribute& attr) noexcept;

Expand Down