diff --git a/src/buffer/out/TextAttribute.cpp b/src/buffer/out/TextAttribute.cpp index aa66a3ed419..ee779402202 100644 --- a/src/buffer/out/TextAttribute.cpp +++ b/src/buffer/out/TextAttribute.cpp @@ -10,6 +10,11 @@ bool TextAttribute::IsLegacy() const noexcept return _foreground.IsLegacy() && _background.IsLegacy(); } +bool TextAttribute::IsHighColor() const noexcept +{ + return _foreground.IsHighColor() || _background.IsHighColor(); +} + // Arguments: // - None // Return Value: @@ -72,12 +77,22 @@ void TextAttribute::SetBackground(const COLORREF rgbBackground) noexcept void TextAttribute::SetIndexedForeground(const BYTE fgIndex) noexcept { - _foreground = TextColor(fgIndex); + _foreground = TextColor(fgIndex, false); } void TextAttribute::SetIndexedBackground(const BYTE bgIndex) noexcept { - _background = TextColor(bgIndex); + _background = TextColor(bgIndex, false); +} + +void TextAttribute::SetIndexedForeground256(const BYTE fgIndex) noexcept +{ + _foreground = TextColor(fgIndex, true); +} + +void TextAttribute::SetIndexedBackground256(const BYTE bgIndex) noexcept +{ + _background = TextColor(bgIndex, true); } void TextAttribute::SetColor(const COLORREF rgbColor, const bool fIsForeground) noexcept diff --git a/src/buffer/out/TextAttribute.hpp b/src/buffer/out/TextAttribute.hpp index edabdc45661..df6278e3f0b 100644 --- a/src/buffer/out/TextAttribute.hpp +++ b/src/buffer/out/TextAttribute.hpp @@ -42,8 +42,8 @@ class TextAttribute final constexpr TextAttribute(const WORD wLegacyAttr) noexcept : _wAttrLegacy{ gsl::narrow_cast(wLegacyAttr & META_ATTRS) }, - _foreground{ gsl::narrow_cast(wLegacyAttr & FG_ATTRS) }, - _background{ gsl::narrow_cast((wLegacyAttr & BG_ATTRS) >> 4) }, + _foreground{ gsl::narrow_cast(wLegacyAttr & FG_ATTRS), true }, + _background{ gsl::narrow_cast((wLegacyAttr & BG_ATTRS) >> 4), true }, _extendedAttrs{ ExtendedAttributes::Normal } { // If we're given lead/trailing byte information with the legacy color, strip it. @@ -59,12 +59,13 @@ class TextAttribute final { } - constexpr WORD GetLegacyAttributes() const noexcept + WORD GetLegacyAttributes() const noexcept { const BYTE fg = (_foreground.GetIndex() & FG_ATTRS); const BYTE bg = (_background.GetIndex() << 4) & BG_ATTRS; const WORD meta = (_wAttrLegacy & META_ATTRS); - return (fg | bg | meta) | (IsBold() ? FOREGROUND_INTENSITY : 0); + const bool brighten = _foreground.IsIndex16() && IsBold(); + return (fg | bg | meta) | (brighten ? FOREGROUND_INTENSITY : 0); } // Method Description: @@ -79,15 +80,16 @@ class TextAttribute final // the background not be a legacy style attribute. // Return Value: // - a WORD with legacy-style attributes for this textattribute. - constexpr WORD GetLegacyAttributes(const BYTE defaultFgIndex, - const BYTE defaultBgIndex) const noexcept + WORD GetLegacyAttributes(const BYTE defaultFgIndex, + const BYTE defaultBgIndex) const noexcept { const BYTE fgIndex = _foreground.IsLegacy() ? _foreground.GetIndex() : defaultFgIndex; const BYTE bgIndex = _background.IsLegacy() ? _background.GetIndex() : defaultBgIndex; const BYTE fg = (fgIndex & FG_ATTRS); const BYTE bg = (bgIndex << 4) & BG_ATTRS; const WORD meta = (_wAttrLegacy & META_ATTRS); - return (fg | bg | meta) | (IsBold() ? FOREGROUND_INTENSITY : 0); + const bool brighten = _foreground.IsIndex16() && IsBold(); + return (fg | bg | meta) | (brighten ? FOREGROUND_INTENSITY : 0); } COLORREF CalculateRgbForeground(std::basic_string_view colorTable, @@ -117,6 +119,7 @@ class TextAttribute final friend constexpr bool operator!=(const WORD& legacyAttr, const TextAttribute& attr) noexcept; bool IsLegacy() const noexcept; + bool IsHighColor() const noexcept; bool IsBold() const noexcept; bool IsItalic() const noexcept; bool IsBlinking() const noexcept; @@ -139,6 +142,8 @@ class TextAttribute final void SetBackground(const COLORREF rgbBackground) 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 SetDefaultForeground() noexcept; @@ -149,11 +154,6 @@ class TextAttribute final void SetStandardErase() noexcept; - constexpr bool IsRgb() const noexcept - { - return _foreground.IsRgb() || _background.IsRgb(); - } - // This returns whether this attribute, if printed directly next to another attribute, for the space // character, would look identical to the other one. bool HasIdenticalVisualRepresentationForBlankSpace(const TextAttribute& other, const bool inverted = false) const noexcept @@ -224,26 +224,6 @@ constexpr bool operator!=(const TextAttribute& a, const TextAttribute& b) noexce return !(a == b); } -constexpr bool operator==(const TextAttribute& attr, const WORD& legacyAttr) noexcept -{ - return attr.GetLegacyAttributes() == legacyAttr; -} - -constexpr bool operator!=(const TextAttribute& attr, const WORD& legacyAttr) noexcept -{ - return !(attr == legacyAttr); -} - -constexpr bool operator==(const WORD& legacyAttr, const TextAttribute& attr) noexcept -{ - return attr == legacyAttr; -} - -constexpr bool operator!=(const WORD& legacyAttr, const TextAttribute& attr) noexcept -{ - return !(attr == legacyAttr); -} - #ifdef UNIT_TESTING #define LOG_ATTR(attr) (Log::Comment(NoThrowString().Format( \ diff --git a/src/buffer/out/TextColor.cpp b/src/buffer/out/TextColor.cpp index 05fcded149a..11c054fe805 100644 --- a/src/buffer/out/TextColor.cpp +++ b/src/buffer/out/TextColor.cpp @@ -4,6 +4,36 @@ #include "precomp.h" #include "TextColor.h" +bool TextColor::IsLegacy() const noexcept +{ + return IsIndex16() || (IsIndex256() && _index < 16); +} + +bool TextColor::IsHighColor() const noexcept +{ + return IsRgb() || (IsIndex256() && _index >= 16); +} + +bool TextColor::IsIndex16() const noexcept +{ + return _meta == ColorType::IsIndex16; +} + +bool TextColor::IsIndex256() const noexcept +{ + return _meta == ColorType::IsIndex256; +} + +bool TextColor::IsDefault() const noexcept +{ + return _meta == ColorType::IsDefault; +} + +bool TextColor::IsRgb() const noexcept +{ + return _meta == ColorType::IsRgb; +} + // Method Description: // - Sets the color value of this attribute, and sets this color to be an RGB // attribute. @@ -23,11 +53,12 @@ void TextColor::SetColor(const COLORREF rgbColor) noexcept // - Sets this TextColor to be a legacy-style index into the color table. // 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). // Return Value: // - -void TextColor::SetIndex(const BYTE index) noexcept +void TextColor::SetIndex(const BYTE index, const bool isIndex256) noexcept { - _meta = ColorType::IsIndex; + _meta = isIndex256 ? ColorType::IsIndex256 : ColorType::IsIndex16; _index = index; } @@ -48,15 +79,15 @@ void TextColor::SetDefault() noexcept // * If we're an RGB color, we'll use that value. // * If we're an indexed color table value, we'll use that index to look up // our value in the provided color table. -// - If brighten is true, and the index is in the "dark" portion of the -// color table (indices [0,7]), then we'll look up the bright version of -// this color (from indices [8,15]). This should be true for -// TextAttributes that are "Bold" and we're treating bold as bright -// (which is the default behavior of most terminals.) +// - If brighten is true, and we've got a 16 color index in the "dark" +// portion of the color table (indices [0,7]), then we'll look up the +// bright version of this color (from indices [8,15]). This should be +// true for TextAttributes that are "Bold" and we're treating bold as +// bright (which is the default behavior of most terminals.) // * If we're a default color, we'll return the default color provided. // Arguments: -// - colorTable: The table of colors we should use to look up the value of a -// legacy attribute from +// - colorTable: The table of colors we should use to look up the value of +// an indexed attribute from. // - defaultColor: The color value to use if we're a default attribute. // - brighten: if true, we'll brighten a dark color table index. // Return Value: @@ -94,21 +125,13 @@ COLORREF TextColor::GetColor(std::basic_string_view colorTable, { return _GetRGB(); } + else if (IsIndex16() && brighten) + { + return colorTable.at(_index | 8); + } else { - FAIL_FAST_IF(colorTable.size() < _index); - // If the color is already bright (it's in index [8,15] or it's a - // 256color value [16,255], then boldness does nothing. - if (brighten && _index < 8) - { - FAIL_FAST_IF(colorTable.size() < 16); - FAIL_FAST_IF(gsl::narrow_cast(_index) + 8 > colorTable.size()); - return colorTable.at(gsl::narrow_cast(_index) + 8); - } - else - { - return colorTable.at(_index); - } + return colorTable.at(_index); } } diff --git a/src/buffer/out/TextColor.h b/src/buffer/out/TextColor.h index 21896ca0413..08db63b831b 100644 --- a/src/buffer/out/TextColor.h +++ b/src/buffer/out/TextColor.h @@ -41,9 +41,10 @@ Revision History: enum class ColorType : BYTE { - IsIndex = 0x0, - IsDefault = 0x1, - IsRgb = 0x2 + IsIndex256 = 0x0, + IsIndex16 = 0x1, + IsDefault = 0x2, + IsRgb = 0x3 }; struct TextColor @@ -57,9 +58,9 @@ struct TextColor { } - constexpr TextColor(const BYTE wLegacyAttr) noexcept : - _meta{ ColorType::IsIndex }, - _index{ wLegacyAttr }, + constexpr TextColor(const BYTE index, const bool isIndex256) noexcept : + _meta{ isIndex256 ? ColorType::IsIndex256 : ColorType::IsIndex16 }, + _index{ index }, _green{ 0 }, _blue{ 0 } { @@ -76,23 +77,15 @@ struct TextColor friend constexpr bool operator==(const TextColor& a, const TextColor& b) noexcept; friend constexpr bool operator!=(const TextColor& a, const TextColor& b) noexcept; - constexpr bool IsLegacy() const noexcept - { - return !(IsDefault() || IsRgb()); - } - - constexpr bool IsDefault() const noexcept - { - return _meta == ColorType::IsDefault; - } - - constexpr bool IsRgb() const noexcept - { - return _meta == ColorType::IsRgb; - } + bool IsLegacy() const noexcept; + bool IsHighColor() const noexcept; + bool IsIndex16() const noexcept; + bool IsIndex256() const noexcept; + bool IsDefault() const noexcept; + bool IsRgb() const noexcept; void SetColor(const COLORREF rgbColor) noexcept; - void SetIndex(const BYTE index) noexcept; + void SetIndex(const BYTE index, const bool isIndex256) noexcept; void SetDefault() noexcept; COLORREF GetColor(std::basic_string_view colorTable, diff --git a/src/buffer/out/ut_textbuffer/TextColorTests.cpp b/src/buffer/out/ut_textbuffer/TextColorTests.cpp index 3497bdcae41..794331fee3d 100644 --- a/src/buffer/out/ut_textbuffer/TextColorTests.cpp +++ b/src/buffer/out/ut_textbuffer/TextColorTests.cpp @@ -81,7 +81,7 @@ void TextColorTests::TestDefaultColor() void TextColorTests::TestDarkIndexColor() { - TextColor indexColor((BYTE)(7)); + TextColor indexColor((BYTE)(7), false); VERIFY_IS_FALSE(indexColor.IsDefault()); VERIFY_IS_TRUE(indexColor.IsLegacy()); @@ -104,7 +104,7 @@ void TextColorTests::TestDarkIndexColor() void TextColorTests::TestBrightIndexColor() { - TextColor indexColor((BYTE)(15)); + TextColor indexColor((BYTE)(15), false); VERIFY_IS_FALSE(indexColor.IsDefault()); VERIFY_IS_TRUE(indexColor.IsLegacy()); @@ -186,7 +186,7 @@ void TextColorTests::TestChangeColor() color = rgbColor.GetColor(view, _defaultBg, true); VERIFY_ARE_EQUAL(_defaultBg, color); - rgbColor.SetIndex(7); + rgbColor.SetIndex(7, false); color = rgbColor.GetColor(view, _defaultFg, false); VERIFY_ARE_EQUAL(_colorTable[7], color); @@ -199,7 +199,7 @@ void TextColorTests::TestChangeColor() color = rgbColor.GetColor(view, _defaultBg, true); VERIFY_ARE_EQUAL(_colorTable[15], color); - rgbColor.SetIndex(15); + rgbColor.SetIndex(15, false); color = rgbColor.GetColor(view, _defaultFg, false); VERIFY_ARE_EQUAL(_colorTable[15], color); diff --git a/src/cascadia/TerminalCore/ITerminalApi.hpp b/src/cascadia/TerminalCore/ITerminalApi.hpp index b521f4ecea2..5b1f3d0ec5d 100644 --- a/src/cascadia/TerminalCore/ITerminalApi.hpp +++ b/src/cascadia/TerminalCore/ITerminalApi.hpp @@ -21,6 +21,8 @@ namespace Microsoft::Terminal::Core virtual bool SetTextToDefaults(bool foreground, bool background) noexcept = 0; virtual bool SetTextForegroundIndex(BYTE colorIndex) noexcept = 0; virtual bool SetTextBackgroundIndex(BYTE colorIndex) noexcept = 0; + virtual bool SetTextForegroundIndex256(BYTE colorIndex) noexcept = 0; + virtual bool SetTextBackgroundIndex256(BYTE colorIndex) noexcept = 0; virtual bool SetTextRgbColor(COLORREF color, bool foreground) noexcept = 0; virtual bool BoldText(bool boldOn) noexcept = 0; virtual bool UnderlineText(bool underlineOn) noexcept = 0; diff --git a/src/cascadia/TerminalCore/Terminal.hpp b/src/cascadia/TerminalCore/Terminal.hpp index 8655987ae33..a145ce40ae8 100644 --- a/src/cascadia/TerminalCore/Terminal.hpp +++ b/src/cascadia/TerminalCore/Terminal.hpp @@ -81,6 +81,8 @@ class Microsoft::Terminal::Core::Terminal final : bool SetTextToDefaults(bool foreground, bool background) noexcept override; bool SetTextForegroundIndex(BYTE colorIndex) noexcept override; bool SetTextBackgroundIndex(BYTE colorIndex) noexcept override; + bool SetTextForegroundIndex256(BYTE colorIndex) noexcept override; + bool SetTextBackgroundIndex256(BYTE colorIndex) noexcept override; bool SetTextRgbColor(COLORREF color, bool foreground) noexcept override; bool BoldText(bool boldOn) noexcept override; bool UnderlineText(bool underlineOn) noexcept override; diff --git a/src/cascadia/TerminalCore/TerminalApi.cpp b/src/cascadia/TerminalCore/TerminalApi.cpp index 4189e07b1d0..72abe4e618b 100644 --- a/src/cascadia/TerminalCore/TerminalApi.cpp +++ b/src/cascadia/TerminalCore/TerminalApi.cpp @@ -57,6 +57,22 @@ bool Terminal::SetTextBackgroundIndex(BYTE colorIndex) noexcept return true; } +bool Terminal::SetTextForegroundIndex256(BYTE colorIndex) noexcept +{ + TextAttribute attrs = _buffer->GetCurrentAttributes(); + attrs.SetIndexedForeground256(colorIndex); + _buffer->SetCurrentAttributes(attrs); + return true; +} + +bool Terminal::SetTextBackgroundIndex256(BYTE colorIndex) noexcept +{ + TextAttribute attrs = _buffer->GetCurrentAttributes(); + attrs.SetIndexedBackground256(colorIndex); + _buffer->SetCurrentAttributes(attrs); + return true; +} + bool Terminal::SetTextRgbColor(COLORREF color, bool foreground) noexcept { TextAttribute attrs = _buffer->GetCurrentAttributes(); diff --git a/src/cascadia/TerminalCore/TerminalDispatchGraphics.cpp b/src/cascadia/TerminalCore/TerminalDispatchGraphics.cpp index 0a37cebed4e..4403de582ac 100644 --- a/src/cascadia/TerminalCore/TerminalDispatchGraphics.cpp +++ b/src/cascadia/TerminalCore/TerminalDispatchGraphics.cpp @@ -121,8 +121,8 @@ bool TerminalDispatch::_SetRgbColorsHelper(const std::basic_string_view(tableIndex)) : - _terminalApi.SetTextBackgroundIndex(gsl::narrow_cast(tableIndex)); + _terminalApi.SetTextForegroundIndex256(gsl::narrow_cast(tableIndex)) : + _terminalApi.SetTextBackgroundIndex256(gsl::narrow_cast(tableIndex)); } } } diff --git a/src/cascadia/UnitTests_TerminalCore/ConptyRoundtripTests.cpp b/src/cascadia/UnitTests_TerminalCore/ConptyRoundtripTests.cpp index bb208b6980c..aa1eb5f4fe2 100644 --- a/src/cascadia/UnitTests_TerminalCore/ConptyRoundtripTests.cpp +++ b/src/cascadia/UnitTests_TerminalCore/ConptyRoundtripTests.cpp @@ -119,8 +119,7 @@ class TerminalCoreUnitTests::ConptyRoundtripTests final auto vtRenderEngine = std::make_unique(std::move(hFile), gci, initialViewport, - gci.GetColorTable(), - static_cast(gci.GetColorTableSize())); + gci.Get16ColorTable()); auto pfn = std::bind(&ConptyRoundtripTests::_writeCallback, this, std::placeholders::_1, std::placeholders::_2); vtRenderEngine->SetTestCallback(pfn); diff --git a/src/host/VtIo.cpp b/src/host/VtIo.cpp index 09b3af630bd..3fea6aa60ca 100644 --- a/src/host/VtIo.cpp +++ b/src/host/VtIo.cpp @@ -161,31 +161,27 @@ VtIo::VtIo() : _pVtRenderEngine = std::make_unique(std::move(_hOutput), gci, initialViewport, - gci.GetColorTable(), - static_cast(gci.GetColorTableSize())); + gci.Get16ColorTable()); break; case VtIoMode::XTERM: _pVtRenderEngine = std::make_unique(std::move(_hOutput), gci, initialViewport, - gci.GetColorTable(), - static_cast(gci.GetColorTableSize()), + gci.Get16ColorTable(), false); break; case VtIoMode::XTERM_ASCII: _pVtRenderEngine = std::make_unique(std::move(_hOutput), gci, initialViewport, - gci.GetColorTable(), - static_cast(gci.GetColorTableSize()), + gci.Get16ColorTable(), true); break; case VtIoMode::WIN_TELNET: _pVtRenderEngine = std::make_unique(std::move(_hOutput), gci, initialViewport, - gci.GetColorTable(), - static_cast(gci.GetColorTableSize())); + gci.Get16ColorTable()); break; default: return E_FAIL; diff --git a/src/host/conattrs.cpp b/src/host/conattrs.cpp index c33864d8aa2..b64ff757fea 100644 --- a/src/host/conattrs.cpp +++ b/src/host/conattrs.cpp @@ -81,13 +81,12 @@ static double _FindDifference(const _HSL* const phslColorA, const COLORREF rgbCo //Arguments: // - Color - The RGB color to fine the nearest color to. // - ColorTable - The array of colors to find a nearest color from. -// - cColorTable - The number of elements in ColorTable // Return value: // The index in ColorTable of the nearest match to Color. -WORD FindNearestTableIndex(const COLORREF Color, _In_reads_(cColorTable) const COLORREF* const ColorTable, const WORD cColorTable) +WORD FindNearestTableIndex(const COLORREF Color, const std::basic_string_view ColorTable) { // Quick check for an exact match in the color table: - for (WORD i = 0; i < cColorTable; i++) + for (WORD i = 0; i < ColorTable.size(); i++) { if (Color == ColorTable[i]) { @@ -100,7 +99,7 @@ WORD FindNearestTableIndex(const COLORREF Color, _In_reads_(cColorTable) const C const _HSL hslColor = _HSL(Color); WORD closest = 0; double minDiff = _FindDifference(&hslColor, ColorTable[0]); - for (WORD i = 1; i < cColorTable; i++) + for (WORD i = 1; i < ColorTable.size(); i++) { double diff = _FindDifference(&hslColor, ColorTable[i]); if (diff < minDiff) @@ -146,36 +145,19 @@ WORD Xterm256ToWindowsIndex(const size_t xtermTableEntry) noexcept static_cast(xtermTableEntry); } -// Function Description: -// - Converts the value of a pair of xterm color table indices to the legacy attr equivalent. -// Arguments: -// - xtermForeground: the xterm color table foreground index -// - xtermBackground: the xterm color table background index -// Return Value: -// - The legacy windows attribute equivalent. -WORD XtermToLegacy(const size_t xtermForeground, const size_t xtermBackground) -{ - const WORD fgAttr = XtermToWindowsIndex(xtermForeground); - const WORD bgAttr = XtermToWindowsIndex(xtermBackground); - - return (bgAttr << 4) | fgAttr; -} - //Routine Description: // Returns the exact entry from the color table, if it's in there. //Arguments: // - Color - The RGB color to fine the nearest color to. // - ColorTable - The array of colors to find a nearest color from. -// - cColorTable - The number of elements in ColorTable // Return value: // The index in ColorTable of the nearest match to Color. bool FindTableIndex(const COLORREF Color, - _In_reads_(cColorTable) const COLORREF* const ColorTable, - const WORD cColorTable, + const std::basic_string_view ColorTable, _Out_ WORD* const pFoundIndex) { *pFoundIndex = 0; - for (WORD i = 0; i < cColorTable; i++) + for (WORD i = 0; i < ColorTable.size(); i++) { if (ColorTable[i] == Color) { @@ -185,41 +167,3 @@ bool FindTableIndex(const COLORREF Color, } return false; } - -// Method Description: -// - Get a COLORREF for the foreground component of the given legacy attributes. -// Arguments: -// - wLegacyAttrs - The legacy attributes to get the foreground color from. -// - ColorTable - The array of colors to get the color from. -// - cColorTable - The number of elements in ColorTable -// Return Value: -// - the COLORREF for the foreground component -COLORREF ForegroundColor(const WORD wLegacyAttrs, - _In_reads_(cColorTable) const COLORREF* const ColorTable, - const size_t cColorTable) -{ - const byte iColorTableIndex = LOBYTE(wLegacyAttrs) & FG_ATTRS; - - return (iColorTableIndex < cColorTable && iColorTableIndex >= 0) ? - ColorTable[iColorTableIndex] : - INVALID_COLOR; -} - -// Method Description: -// - Get a COLORREF for the background component of the given legacy attributes. -// Arguments: -// - wLegacyAttrs - The legacy attributes to get the background color from. -// - ColorTable - The array of colors to get the color from. -// - cColorTable - The number of elements in ColorTable -// Return Value: -// - the COLORREF for the background component -COLORREF BackgroundColor(const WORD wLegacyAttrs, - _In_reads_(cColorTable) const COLORREF* const ColorTable, - const size_t cColorTable) -{ - const byte iColorTableIndex = (LOBYTE(wLegacyAttrs) & BG_ATTRS) >> 4; - - return (iColorTableIndex < cColorTable && iColorTableIndex >= 0) ? - ColorTable[iColorTableIndex] : - INVALID_COLOR; -} diff --git a/src/host/getset.cpp b/src/host/getset.cpp index b7af4741e99..0699e72ab74 100644 --- a/src/host/getset.cpp +++ b/src/host/getset.cpp @@ -572,7 +572,10 @@ void ApiRoutines::GetLargestConsoleWindowSizeImpl(const SCREEN_INFORMATION& cont } const COORD newBufferSize = context.GetBufferSize().Dimensions(); - gci.SetColorTable(data.ColorTable, ARRAYSIZE(data.ColorTable)); + for (size_t i = 0; i < std::size(data.ColorTable); i++) + { + gci.SetColorTableEntry(i, data.ColorTable[i]); + } context.SetDefaultAttributes({ data.wAttributes }, { data.wPopupAttributes }); diff --git a/src/host/screenInfo.cpp b/src/host/screenInfo.cpp index ecd49d0c5a7..2aa6a3b51db 100644 --- a/src/host/screenInfo.cpp +++ b/src/host/screenInfo.cpp @@ -360,7 +360,10 @@ void SCREEN_INFORMATION::GetScreenBufferInformation(_Out_ PCOORD pcoordSize, *pwPopupAttributes = gci.GenerateLegacyAttributes(_PopupAttributes); // the copy length must be constant for now to keep OACR happy with buffer overruns. - memmove(lpColorTable, gci.GetColorTable(), COLOR_TABLE_SIZE * sizeof(COLORREF)); + for (size_t i = 0; i < COLOR_TABLE_SIZE; i++) + { + lpColorTable[i] = gci.GetColorTableEntry(i); + } *pcoordMaximumWindowSize = GetMaxWindowSizeInCharacters(); } diff --git a/src/host/settings.cpp b/src/host/settings.cpp index 154d3b921c9..58f14cc7db8 100644 --- a/src/host/settings.cpp +++ b/src/host/settings.cpp @@ -81,9 +81,8 @@ Settings::Settings() : _CursorColor = Cursor::s_InvertCursorColor; _CursorType = CursorType::Legacy; - gsl::span tableView = { _ColorTable, gsl::narrow(COLOR_TABLE_SIZE) }; - gsl::span xtermTableView = { _XtermColorTable, gsl::narrow(XTERM_COLOR_TABLE_SIZE) }; - ::Microsoft::Console::Utils::Initialize256ColorTable(xtermTableView); + gsl::span tableView = { _colorTable.data(), gsl::narrow(_colorTable.size()) }; + ::Microsoft::Console::Utils::Initialize256ColorTable(tableView); ::Microsoft::Console::Utils::InitializeCampbellColorTableForConhost(tableView); } @@ -123,7 +122,7 @@ void Settings::ApplyDesktopSpecificDefaults() _uNumberOfHistoryBuffers = 4; _bHistoryNoDup = FALSE; - gsl::span tableView = { _ColorTable, gsl::narrow(COLOR_TABLE_SIZE) }; + gsl::span tableView = { _colorTable.data(), gsl::narrow(_colorTable.size()) }; ::Microsoft::Console::Utils::InitializeCampbellColorTableForConhost(tableView); _fTrimLeadingZeros = false; @@ -221,7 +220,10 @@ void Settings::InitFromStateInfo(_In_ PCONSOLE_STATE_INFO pStateInfo) _bHistoryNoDup = pStateInfo->HistoryNoDup; _uHistoryBufferSize = pStateInfo->HistoryBufferSize; _uNumberOfHistoryBuffers = pStateInfo->NumberOfHistoryBuffers; - memmove(_ColorTable, pStateInfo->ColorTable, sizeof(_ColorTable)); + for (size_t i = 0; i < std::size(pStateInfo->ColorTable); i++) + { + SetColorTableEntry(i, pStateInfo->ColorTable[i]); + } _uCodePage = pStateInfo->CodePage; _bWrapText = !!pStateInfo->fWrapText; _fFilterOnPaste = pStateInfo->fFilterOnPaste; @@ -263,7 +265,10 @@ CONSOLE_STATE_INFO Settings::CreateConsoleStateInfo() const csi.HistoryNoDup = _bHistoryNoDup; csi.HistoryBufferSize = _uHistoryBufferSize; csi.NumberOfHistoryBuffers = _uNumberOfHistoryBuffers; - memmove(csi.ColorTable, _ColorTable, sizeof(_ColorTable)); + for (size_t i = 0; i < std::size(csi.ColorTable); i++) + { + csi.ColorTable[i] = GetColorTableEntry(i); + } csi.CodePage = _uCodePage; csi.fWrapText = !!_bWrapText; csi.fFilterOnPaste = _fFilterOnPaste; @@ -717,26 +722,19 @@ void Settings::SetHistoryNoDup(const bool bHistoryNoDup) _bHistoryNoDup = bHistoryNoDup; } -const COLORREF* const Settings::GetColorTable() const +std::basic_string_view Settings::Get16ColorTable() const { - return _ColorTable; + return Get256ColorTable().substr(0, 16); } -void Settings::SetColorTable(_In_reads_(cSize) const COLORREF* const pColorTable, const size_t cSize) -{ - size_t cSizeWritten = std::min(cSize, static_cast(COLOR_TABLE_SIZE)); - memmove(_ColorTable, pColorTable, cSizeWritten * sizeof(COLORREF)); +std::basic_string_view Settings::Get256ColorTable() const +{ + return { _colorTable.data(), _colorTable.size() }; } + void Settings::SetColorTableEntry(const size_t index, const COLORREF ColorValue) { - if (index < ARRAYSIZE(_ColorTable)) - { - _ColorTable[index] = ColorValue; - } - else - { - _XtermColorTable[index] = ColorValue; - } + _colorTable.at(index) = ColorValue; } bool Settings::IsStartupTitleIsLinkNameSet() const @@ -754,21 +752,9 @@ void Settings::UnsetStartupFlag(const DWORD dwFlagToUnset) _dwStartupFlags &= ~dwFlagToUnset; } -const size_t Settings::GetColorTableSize() const -{ - return ARRAYSIZE(_ColorTable); -} - COLORREF Settings::GetColorTableEntry(const size_t index) const { - if (index < ARRAYSIZE(_ColorTable)) - { - return _ColorTable[index]; - } - else - { - return _XtermColorTable[index]; - } + return _colorTable.at(index); } // Routine Description: @@ -792,19 +778,21 @@ WORD Settings::GenerateLegacyAttributes(const TextAttribute attributes) const BYTE bgIndex = static_cast((_wFillAttribute & BG_ATTRS) >> 4); // If the attributes have any RGB components, we need to match that RGB // color to a color table value. - if (attributes.IsRgb()) + if (attributes.IsHighColor()) { // If the attribute doesn't have a "default" colored *ground, look up // the nearest color table value for its *ground. - const COLORREF rgbForeground = LookupForegroundColor(attributes); - fgIndex = attributes.ForegroundIsDefault() ? - fgIndex : - static_cast(FindNearestTableIndex(rgbForeground)); - - const COLORREF rgbBackground = LookupBackgroundColor(attributes); - bgIndex = attributes.BackgroundIsDefault() ? - bgIndex : - static_cast(FindNearestTableIndex(rgbBackground)); + if (!attributes.ForegroundIsDefault()) + { + const COLORREF rgbForeground = LookupForegroundColor(attributes); + fgIndex = static_cast(::FindNearestTableIndex(rgbForeground, Get16ColorTable())); + } + + if (!attributes.BackgroundIsDefault()) + { + const COLORREF rgbBackground = LookupBackgroundColor(attributes); + bgIndex = static_cast(::FindNearestTableIndex(rgbBackground, Get16ColorTable())); + } } // TextAttribute::GetLegacyAttributes(BYTE, BYTE) will use the legacy value @@ -815,19 +803,6 @@ WORD Settings::GenerateLegacyAttributes(const TextAttribute attributes) const return wCompleteAttr; } -//Routine Description: -// For a given RGB color Color, finds the nearest color from the array ColorTable, and returns the index of that match. -//Arguments: -// - Color - The RGB color to fine the nearest color to. -// - ColorTable - The array of colors to find a nearest color from. -// - cColorTable - The number of elements in ColorTable -// Return value: -// The index in ColorTable of the nearest match to Color. -WORD Settings::FindNearestTableIndex(const COLORREF Color) const -{ - return ::FindNearestTableIndex(Color, _ColorTable, ARRAYSIZE(_ColorTable)); -} - COLORREF Settings::GetCursorColor() const noexcept { return _CursorColor; @@ -924,7 +899,7 @@ bool Settings::GetUseDx() const noexcept COLORREF Settings::CalculateDefaultForeground() const noexcept { const auto fg = GetDefaultForegroundColor(); - return fg != INVALID_COLOR ? fg : ForegroundColor(GetFillAttribute(), GetColorTable(), GetColorTableSize()); + return fg != INVALID_COLOR ? fg : GetColorTableEntry(LOBYTE(_wFillAttribute) & FG_ATTRS); } // Method Description: @@ -939,7 +914,7 @@ COLORREF Settings::CalculateDefaultForeground() const noexcept COLORREF Settings::CalculateDefaultBackground() const noexcept { const auto bg = GetDefaultBackgroundColor(); - return bg != INVALID_COLOR ? bg : BackgroundColor(GetFillAttribute(), GetColorTable(), GetColorTableSize()); + return bg != INVALID_COLOR ? bg : GetColorTableEntry((LOBYTE(_wFillAttribute) & BG_ATTRS) >> 4); } // Method Description: @@ -951,7 +926,7 @@ COLORREF Settings::CalculateDefaultBackground() const noexcept // - The color value of the attribute's foreground TextColor. COLORREF Settings::LookupForegroundColor(const TextAttribute& attr) const noexcept { - const auto tableView = std::basic_string_view(&GetColorTable()[0], GetColorTableSize()); + const auto tableView = Get256ColorTable(); if (_fScreenReversed) { return attr.CalculateRgbBackground(tableView, CalculateDefaultForeground(), CalculateDefaultBackground()); @@ -971,7 +946,7 @@ COLORREF Settings::LookupForegroundColor(const TextAttribute& attr) const noexce // - The color value of the attribute's background TextColor. COLORREF Settings::LookupBackgroundColor(const TextAttribute& attr) const noexcept { - const auto tableView = std::basic_string_view(&GetColorTable()[0], GetColorTableSize()); + const auto tableView = Get256ColorTable(); if (_fScreenReversed) { return attr.CalculateRgbForeground(tableView, CalculateDefaultForeground(), CalculateDefaultBackground()); diff --git a/src/host/settings.hpp b/src/host/settings.hpp index 05503cf979c..2163204c9a4 100644 --- a/src/host/settings.hpp +++ b/src/host/settings.hpp @@ -159,9 +159,8 @@ class Settings bool GetHistoryNoDup() const; void SetHistoryNoDup(const bool fHistoryNoDup); - const COLORREF* const GetColorTable() const; - const size_t GetColorTableSize() const; - void SetColorTable(_In_reads_(cSize) const COLORREF* const pColorTable, const size_t cSize); + std::basic_string_view Get16ColorTable() const; + std::basic_string_view Get256ColorTable() const; void SetColorTableEntry(const size_t index, const COLORREF ColorValue); COLORREF GetColorTableEntry(const size_t index) const; @@ -217,7 +216,6 @@ class Settings UINT _uHistoryBufferSize; UINT _uNumberOfHistoryBuffers; BOOL _bHistoryNoDup; - COLORREF _ColorTable[COLOR_TABLE_SIZE]; // END - memcpy UINT _uCodePage; UINT _uScrollScale; @@ -238,7 +236,7 @@ class Settings bool _fUseDx; bool _fCopyColor; - COLORREF _XtermColorTable[XTERM_COLOR_TABLE_SIZE]; + std::array _colorTable; // this is used for the special STARTF_USESIZE mode. bool _fUseWindowSizePixels; @@ -257,5 +255,4 @@ class Settings public: WORD GenerateLegacyAttributes(const TextAttribute attributes) const; - WORD FindNearestTableIndex(const COLORREF Color) const; }; diff --git a/src/host/telemetry.cpp b/src/host/telemetry.cpp index 7a0d916011f..4f4d1bb10b0 100644 --- a/src/host/telemetry.cpp +++ b/src/host/telemetry.cpp @@ -419,7 +419,7 @@ void Telemetry::WriteFinalTraceLog() TraceLoggingBool(gci.GetQuickEdit(), "QuickEdit"), TraceLoggingValue(gci.GetWindowAlpha(), "WindowAlpha"), TraceLoggingBool(gci.GetWrapText(), "WrapText"), - TraceLoggingUInt32Array((UINT32 const*)gci.GetColorTable(), (UINT16)gci.GetColorTableSize(), "ColorTable"), + TraceLoggingUInt32Array((UINT32 const*)gci.Get16ColorTable().data(), (UINT16)gci.Get16ColorTable().size(), "ColorTable"), TraceLoggingValue(gci.CP, "CodePageInput"), TraceLoggingValue(gci.OutputCP, "CodePageOutput"), TraceLoggingValue(gci.GetFontSize().X, "FontSizeX"), @@ -453,7 +453,7 @@ void Telemetry::WriteFinalTraceLog() TraceLoggingValue(gci.GetShowWindow(), "ShowWindow"), TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES), TelemetryPrivacyDataTag(PDT_ProductAndServiceUsage)); - static_assert(sizeof(UINT32) == sizeof(*gci.GetColorTable()), "gci.GetColorTable()"); + static_assert(sizeof(UINT32) == sizeof(gci.Get16ColorTable()[0]), "gci.Get16ColorTable()"); // I could use the TraceLoggingUIntArray, but then we would have to know the order of the enums on the backend. // So just log each enum count separately with its string representation which makes it more human readable. diff --git a/src/host/ut_host/ConptyOutputTests.cpp b/src/host/ut_host/ConptyOutputTests.cpp index 071e7dd218f..6c76aae19a1 100644 --- a/src/host/ut_host/ConptyOutputTests.cpp +++ b/src/host/ut_host/ConptyOutputTests.cpp @@ -88,8 +88,7 @@ class ConptyOutputTests auto vtRenderEngine = std::make_unique(std::move(hFile), gci, initialViewport, - gci.GetColorTable(), - static_cast(gci.GetColorTableSize())); + gci.Get16ColorTable()); auto pfn = std::bind(&ConptyOutputTests::_writeCallback, this, std::placeholders::_1, std::placeholders::_2); vtRenderEngine->SetTestCallback(pfn); diff --git a/src/host/ut_host/ScreenBufferTests.cpp b/src/host/ut_host/ScreenBufferTests.cpp index 2ca2f63e018..ebda0167a8a 100644 --- a/src/host/ut_host/ScreenBufferTests.cpp +++ b/src/host/ut_host/ScreenBufferTests.cpp @@ -1844,7 +1844,9 @@ void ScreenBufferTests::VtEraseAllPersistCursorFillColor() L"Change the colors to dark_red on bright_blue, then execute a Erase All.\n" L"The viewport should be full of dark_red on bright_blue")); - auto expectedAttr = TextAttribute(XtermToLegacy(1, 12)); + auto expectedAttr = TextAttribute{}; + expectedAttr.SetIndexedForeground((BYTE)XtermToWindowsIndex(1)); + expectedAttr.SetIndexedBackground((BYTE)XtermToWindowsIndex(12)); stateMachine.ProcessString(L"\x1b[31;104m"); VERIFY_ARE_EQUAL(expectedAttr, si.GetAttributes()); @@ -2222,12 +2224,14 @@ void ScreenBufferTests::SetDefaultsIndividuallyBothDefault() // See the log comment above for description of these values. TextAttribute expectedDefaults{}; - TextAttribute expectedTwo{ FOREGROUND_GREEN | FOREGROUND_INTENSITY | BACKGROUND_BLUE }; - TextAttribute expectedThree{ FOREGROUND_GREEN | FOREGROUND_INTENSITY | BACKGROUND_BLUE }; + TextAttribute expectedTwo; + expectedTwo.SetIndexedForeground((BYTE)XtermToWindowsIndex(10)); + expectedTwo.SetIndexedBackground((BYTE)XtermToWindowsIndex(4)); + TextAttribute expectedThree = expectedTwo; expectedThree.SetDefaultForeground(); // Four is the same as Defaults // Five is the same as two - TextAttribute expectedSix{ FOREGROUND_GREEN | FOREGROUND_INTENSITY | BACKGROUND_BLUE }; + TextAttribute expectedSix = expectedTwo; expectedSix.SetDefaultBackground(); COORD expectedCursor{ 6, 0 }; @@ -2324,7 +2328,7 @@ void ScreenBufferTests::SetDefaultsTogether() // See the log comment above for description of these values. TextAttribute expectedDefaults{}; TextAttribute expectedTwo{}; - expectedTwo.SetBackground(color250); + expectedTwo.SetIndexedBackground256(250); COORD expectedCursor{ 3, 0 }; VERIFY_ARE_EQUAL(expectedCursor, cursor.GetPosition()); @@ -4503,14 +4507,14 @@ void ScreenBufferTests::ScrollLines256Colors() auto& cursor = si.GetTextBuffer().GetCursor(); TextAttribute expectedAttr{ si.GetAttributes() }; - std::wstring_view sgrSeq = L"\x1b[48;5;2m"; + std::wstring_view sgrSeq = L"\x1b[42m"; if (colorStyle == Use16Color) { - expectedAttr.SetBackground(gci.GetColorTableEntry(2)); + expectedAttr.SetIndexedBackground(2); } else if (colorStyle == Use256Color) { - expectedAttr.SetBackground(gci.GetColorTableEntry(20)); + expectedAttr.SetIndexedBackground256(20); sgrSeq = L"\x1b[48;5;20m"; } else if (colorStyle == UseRGBColor) @@ -5237,7 +5241,7 @@ void ScreenBufferTests::TestExtendedTextAttributesWithColors() } else if (setForegroundType == Use256Color) { - expectedAttr.SetForeground(gci.GetColorTableEntry(20)); + expectedAttr.SetIndexedForeground256(20); vtSeq += L"\x1b[38;5;20m"; } else if (setForegroundType == UseRGBColor) @@ -5259,7 +5263,7 @@ void ScreenBufferTests::TestExtendedTextAttributesWithColors() } else if (setBackgroundType == Use256Color) { - expectedAttr.SetBackground(gci.GetColorTableEntry(20)); + expectedAttr.SetIndexedBackground256(20); vtSeq += L"\x1b[48;5;20m"; } else if (setBackgroundType == UseRGBColor) diff --git a/src/host/ut_host/TextBufferIteratorTests.cpp b/src/host/ut_host/TextBufferIteratorTests.cpp index 13630a51a4c..55f0ae328a5 100644 --- a/src/host/ut_host/TextBufferIteratorTests.cpp +++ b/src/host/ut_host/TextBufferIteratorTests.cpp @@ -498,7 +498,7 @@ void TextBufferIteratorTests::DereferenceOperatorCell() const auto textExpected = (std::wstring_view)row.GetCharRow().GlyphAt(it._pos.X); const auto dbcsExpected = row.GetCharRow().DbcsAttrAt(it._pos.X); - const auto attrExpected = row.GetAttrRow().GetAttrByColumn(it._pos.X).GetLegacyAttributes(); + const auto attrExpected = row.GetAttrRow().GetAttrByColumn(it._pos.X); const auto cellActual = *it; const auto textActual = cellActual.Chars(); diff --git a/src/host/ut_host/VtIoTests.cpp b/src/host/ut_host/VtIoTests.cpp index f9f60946449..01124b083b8 100644 --- a/src/host/ut_host/VtIoTests.cpp +++ b/src/host/ut_host/VtIoTests.cpp @@ -124,28 +124,28 @@ void VtIoTests::DtorTestJustEngine() wil::unique_hfile hOutputFile; hOutputFile.reset(INVALID_HANDLE_VALUE); - auto pRenderer256 = new Xterm256Engine(std::move(hOutputFile), p, SetUpViewport(), colorTable, colorTableSize); + auto pRenderer256 = new Xterm256Engine(std::move(hOutputFile), p, SetUpViewport(), colorTable); Log::Comment(NoThrowString().Format(L"Made Xterm256Engine")); delete pRenderer256; Log::Comment(NoThrowString().Format(L"Deleted.")); hOutputFile.reset(INVALID_HANDLE_VALUE); - auto pRenderEngineXterm = new XtermEngine(std::move(hOutputFile), p, SetUpViewport(), colorTable, colorTableSize, false); + auto pRenderEngineXterm = new XtermEngine(std::move(hOutputFile), p, SetUpViewport(), colorTable, false); Log::Comment(NoThrowString().Format(L"Made XtermEngine")); delete pRenderEngineXterm; Log::Comment(NoThrowString().Format(L"Deleted.")); hOutputFile.reset(INVALID_HANDLE_VALUE); - auto pRenderEngineXtermAscii = new XtermEngine(std::move(hOutputFile), p, SetUpViewport(), colorTable, colorTableSize, true); + auto pRenderEngineXtermAscii = new XtermEngine(std::move(hOutputFile), p, SetUpViewport(), colorTable, true); Log::Comment(NoThrowString().Format(L"Made XtermEngine")); delete pRenderEngineXtermAscii; Log::Comment(NoThrowString().Format(L"Deleted.")); hOutputFile.reset(INVALID_HANDLE_VALUE); - auto pRenderEngineWinTelnet = new WinTelnetEngine(std::move(hOutputFile), p, SetUpViewport(), colorTable, colorTableSize); + auto pRenderEngineWinTelnet = new WinTelnetEngine(std::move(hOutputFile), p, SetUpViewport(), colorTable); Log::Comment(NoThrowString().Format(L"Made WinTelnetEngine")); delete pRenderEngineWinTelnet; Log::Comment(NoThrowString().Format(L"Deleted.")); @@ -180,8 +180,7 @@ void VtIoTests::DtorTestDeleteVtio() vtio->_pVtRenderEngine = std::make_unique(std::move(hOutputFile), p, SetUpViewport(), - colorTable, - colorTableSize); + colorTable); Log::Comment(NoThrowString().Format(L"Made Xterm256Engine")); delete vtio; Log::Comment(NoThrowString().Format(L"Deleted.")); @@ -193,7 +192,6 @@ void VtIoTests::DtorTestDeleteVtio() p, SetUpViewport(), colorTable, - colorTableSize, false); Log::Comment(NoThrowString().Format(L"Made XtermEngine")); delete vtio; @@ -206,7 +204,6 @@ void VtIoTests::DtorTestDeleteVtio() p, SetUpViewport(), colorTable, - colorTableSize, true); Log::Comment(NoThrowString().Format(L"Made XtermEngine")); delete vtio; @@ -218,8 +215,7 @@ void VtIoTests::DtorTestDeleteVtio() vtio->_pVtRenderEngine = std::make_unique(std::move(hOutputFile), p, SetUpViewport(), - colorTable, - colorTableSize); + colorTable); Log::Comment(NoThrowString().Format(L"Made WinTelnetEngine")); delete vtio; Log::Comment(NoThrowString().Format(L"Deleted.")); @@ -253,8 +249,7 @@ void VtIoTests::DtorTestStackAlloc() vtio._pVtRenderEngine = std::make_unique(std::move(hOutputFile), p, SetUpViewport(), - colorTable, - colorTableSize); + colorTable); } hOutputFile.reset(INVALID_HANDLE_VALUE); @@ -264,7 +259,6 @@ void VtIoTests::DtorTestStackAlloc() p, SetUpViewport(), colorTable, - colorTableSize, false); } @@ -275,7 +269,6 @@ void VtIoTests::DtorTestStackAlloc() p, SetUpViewport(), colorTable, - colorTableSize, true); } @@ -285,8 +278,7 @@ void VtIoTests::DtorTestStackAlloc() vtio._pVtRenderEngine = std::make_unique(std::move(hOutputFile), p, SetUpViewport(), - colorTable, - colorTableSize); + colorTable); } } } @@ -317,8 +309,7 @@ void VtIoTests::DtorTestStackAllocMany() vtio1._pVtRenderEngine = std::make_unique(std::move(hOutputFile), p, SetUpViewport(), - colorTable, - colorTableSize); + colorTable); hOutputFile.reset(INVALID_HANDLE_VALUE); VtIo vtio2; @@ -326,7 +317,6 @@ void VtIoTests::DtorTestStackAllocMany() p, SetUpViewport(), colorTable, - colorTableSize, false); hOutputFile.reset(INVALID_HANDLE_VALUE); @@ -335,7 +325,6 @@ void VtIoTests::DtorTestStackAllocMany() p, SetUpViewport(), colorTable, - colorTableSize, true); hOutputFile.reset(INVALID_HANDLE_VALUE); @@ -343,8 +332,7 @@ void VtIoTests::DtorTestStackAllocMany() vtio4._pVtRenderEngine = std::make_unique(std::move(hOutputFile), p, SetUpViewport(), - colorTable, - colorTableSize); + colorTable); } } } diff --git a/src/host/ut_host/VtRendererTests.cpp b/src/host/ut_host/VtRendererTests.cpp index 4be9db4b85a..7e5bfdd2104 100644 --- a/src/host/ut_host/VtRendererTests.cpp +++ b/src/host/ut_host/VtRendererTests.cpp @@ -189,7 +189,7 @@ void VtRendererTest::TestPaint(VtEngine& engine, std::function pfn) void VtRendererTest::VtSequenceHelperTests() { wil::unique_hfile hFile = wil::unique_hfile(INVALID_HANDLE_VALUE); - std::unique_ptr engine = std::make_unique(std::move(hFile), p, SetUpViewport(), g_ColorTable, static_cast(COLOR_TABLE_SIZE)); + std::unique_ptr engine = std::make_unique(std::move(hFile), p, SetUpViewport(), g_ColorTable); auto pfn = std::bind(&VtRendererTest::WriteCallback, this, std::placeholders::_1, std::placeholders::_2); engine->SetTestCallback(pfn); @@ -246,7 +246,7 @@ void VtRendererTest::VtSequenceHelperTests() void VtRendererTest::Xterm256TestInvalidate() { wil::unique_hfile hFile = wil::unique_hfile(INVALID_HANDLE_VALUE); - std::unique_ptr engine = std::make_unique(std::move(hFile), p, SetUpViewport(), g_ColorTable, static_cast(COLOR_TABLE_SIZE)); + std::unique_ptr engine = std::make_unique(std::move(hFile), p, SetUpViewport(), g_ColorTable); auto pfn = std::bind(&VtRendererTest::WriteCallback, this, std::placeholders::_1, std::placeholders::_2); engine->SetTestCallback(pfn); @@ -434,7 +434,7 @@ void VtRendererTest::Xterm256TestInvalidate() void VtRendererTest::Xterm256TestColors() { wil::unique_hfile hFile = wil::unique_hfile(INVALID_HANDLE_VALUE); - std::unique_ptr engine = std::make_unique(std::move(hFile), p, SetUpViewport(), g_ColorTable, static_cast(COLOR_TABLE_SIZE)); + std::unique_ptr engine = std::make_unique(std::move(hFile), p, SetUpViewport(), g_ColorTable); auto pfn = std::bind(&VtRendererTest::WriteCallback, this, std::placeholders::_1, std::placeholders::_2); engine->SetTestCallback(pfn); @@ -571,7 +571,7 @@ void VtRendererTest::Xterm256TestColors() void VtRendererTest::Xterm256TestCursor() { wil::unique_hfile hFile = wil::unique_hfile(INVALID_HANDLE_VALUE); - std::unique_ptr engine = std::make_unique(std::move(hFile), p, SetUpViewport(), g_ColorTable, static_cast(COLOR_TABLE_SIZE)); + std::unique_ptr engine = std::make_unique(std::move(hFile), p, SetUpViewport(), g_ColorTable); auto pfn = std::bind(&VtRendererTest::WriteCallback, this, std::placeholders::_1, std::placeholders::_2); engine->SetTestCallback(pfn); @@ -723,7 +723,7 @@ void VtRendererTest::Xterm256TestExtendedAttributes() } wil::unique_hfile hFile = wil::unique_hfile(INVALID_HANDLE_VALUE); - std::unique_ptr engine = std::make_unique(std::move(hFile), p, SetUpViewport(), g_ColorTable, static_cast(COLOR_TABLE_SIZE)); + std::unique_ptr engine = std::make_unique(std::move(hFile), p, SetUpViewport(), g_ColorTable); auto pfn = std::bind(&VtRendererTest::WriteCallback, this, std::placeholders::_1, std::placeholders::_2); engine->SetTestCallback(pfn); @@ -767,7 +767,7 @@ void VtRendererTest::Xterm256TestExtendedAttributes() void VtRendererTest::XtermTestInvalidate() { wil::unique_hfile hFile = wil::unique_hfile(INVALID_HANDLE_VALUE); - std::unique_ptr engine = std::make_unique(std::move(hFile), p, SetUpViewport(), g_ColorTable, static_cast(COLOR_TABLE_SIZE), false); + std::unique_ptr engine = std::make_unique(std::move(hFile), p, SetUpViewport(), g_ColorTable, false); auto pfn = std::bind(&VtRendererTest::WriteCallback, this, std::placeholders::_1, std::placeholders::_2); engine->SetTestCallback(pfn); @@ -954,7 +954,7 @@ void VtRendererTest::XtermTestInvalidate() void VtRendererTest::XtermTestColors() { wil::unique_hfile hFile = wil::unique_hfile(INVALID_HANDLE_VALUE); - std::unique_ptr engine = std::make_unique(std::move(hFile), p, SetUpViewport(), g_ColorTable, static_cast(COLOR_TABLE_SIZE), false); + std::unique_ptr engine = std::make_unique(std::move(hFile), p, SetUpViewport(), g_ColorTable, false); auto pfn = std::bind(&VtRendererTest::WriteCallback, this, std::placeholders::_1, std::placeholders::_2); engine->SetTestCallback(pfn); @@ -1040,7 +1040,7 @@ void VtRendererTest::XtermTestColors() void VtRendererTest::XtermTestCursor() { wil::unique_hfile hFile = wil::unique_hfile(INVALID_HANDLE_VALUE); - std::unique_ptr engine = std::make_unique(std::move(hFile), p, SetUpViewport(), g_ColorTable, static_cast(COLOR_TABLE_SIZE), false); + std::unique_ptr engine = std::make_unique(std::move(hFile), p, SetUpViewport(), g_ColorTable, false); auto pfn = std::bind(&VtRendererTest::WriteCallback, this, std::placeholders::_1, std::placeholders::_2); engine->SetTestCallback(pfn); @@ -1149,7 +1149,7 @@ void VtRendererTest::XtermTestCursor() void VtRendererTest::WinTelnetTestInvalidate() { wil::unique_hfile hFile = wil::unique_hfile(INVALID_HANDLE_VALUE); - std::unique_ptr engine = std::make_unique(std::move(hFile), p, SetUpViewport(), g_ColorTable, static_cast(COLOR_TABLE_SIZE)); + std::unique_ptr engine = std::make_unique(std::move(hFile), p, SetUpViewport(), g_ColorTable); auto pfn = std::bind(&VtRendererTest::WriteCallback, this, std::placeholders::_1, std::placeholders::_2); engine->SetTestCallback(pfn); @@ -1221,7 +1221,7 @@ void VtRendererTest::WinTelnetTestInvalidate() void VtRendererTest::WinTelnetTestColors() { wil::unique_hfile hFile = wil::unique_hfile(INVALID_HANDLE_VALUE); - std::unique_ptr engine = std::make_unique(std::move(hFile), p, SetUpViewport(), g_ColorTable, static_cast(COLOR_TABLE_SIZE)); + std::unique_ptr engine = std::make_unique(std::move(hFile), p, SetUpViewport(), g_ColorTable); auto pfn = std::bind(&VtRendererTest::WriteCallback, this, std::placeholders::_1, std::placeholders::_2); engine->SetTestCallback(pfn); @@ -1299,7 +1299,7 @@ void VtRendererTest::WinTelnetTestColors() void VtRendererTest::WinTelnetTestCursor() { wil::unique_hfile hFile = wil::unique_hfile(INVALID_HANDLE_VALUE); - std::unique_ptr engine = std::make_unique(std::move(hFile), p, SetUpViewport(), g_ColorTable, static_cast(COLOR_TABLE_SIZE)); + std::unique_ptr engine = std::make_unique(std::move(hFile), p, SetUpViewport(), g_ColorTable); auto pfn = std::bind(&VtRendererTest::WriteCallback, this, std::placeholders::_1, std::placeholders::_2); engine->SetTestCallback(pfn); @@ -1379,7 +1379,7 @@ void VtRendererTest::WinTelnetTestCursor() void VtRendererTest::TestWrapping() { wil::unique_hfile hFile = wil::unique_hfile(INVALID_HANDLE_VALUE); - std::unique_ptr engine = std::make_unique(std::move(hFile), p, SetUpViewport(), g_ColorTable, static_cast(COLOR_TABLE_SIZE)); + std::unique_ptr engine = std::make_unique(std::move(hFile), p, SetUpViewport(), g_ColorTable); auto pfn = std::bind(&VtRendererTest::WriteCallback, this, std::placeholders::_1, std::placeholders::_2); engine->SetTestCallback(pfn); @@ -1432,7 +1432,7 @@ void VtRendererTest::TestResize() { Viewport view = SetUpViewport(); wil::unique_hfile hFile = wil::unique_hfile(INVALID_HANDLE_VALUE); - auto engine = std::make_unique(std::move(hFile), p, view, g_ColorTable, static_cast(COLOR_TABLE_SIZE)); + auto engine = std::make_unique(std::move(hFile), p, view, g_ColorTable); auto pfn = std::bind(&VtRendererTest::WriteCallback, this, std::placeholders::_1, std::placeholders::_2); engine->SetTestCallback(pfn); @@ -1469,7 +1469,7 @@ void VtRendererTest::TestCursorVisibility() { Viewport view = SetUpViewport(); wil::unique_hfile hFile = wil::unique_hfile(INVALID_HANDLE_VALUE); - auto engine = std::make_unique(std::move(hFile), p, view, g_ColorTable, static_cast(COLOR_TABLE_SIZE)); + auto engine = std::make_unique(std::move(hFile), p, view, g_ColorTable); auto pfn = std::bind(&VtRendererTest::WriteCallback, this, std::placeholders::_1, std::placeholders::_2); engine->SetTestCallback(pfn); @@ -1594,7 +1594,7 @@ void VtRendererTest::FormattedString() Viewport view = SetUpViewport(); wil::unique_hfile hFile = wil::unique_hfile(INVALID_HANDLE_VALUE); - auto engine = std::make_unique(std::move(hFile), p, view, g_ColorTable, static_cast(COLOR_TABLE_SIZE)); + auto engine = std::make_unique(std::move(hFile), p, view, g_ColorTable); auto pfn = std::bind(&VtRendererTest::WriteCallback, this, std::placeholders::_1, std::placeholders::_2); engine->SetTestCallback(pfn); diff --git a/src/inc/conattrs.hpp b/src/inc/conattrs.hpp index a168b173cb9..a33deaf49ff 100644 --- a/src/inc/conattrs.hpp +++ b/src/inc/conattrs.hpp @@ -24,26 +24,16 @@ enum class ExtendedAttributes : BYTE DEFINE_ENUM_FLAG_OPERATORS(ExtendedAttributes); WORD FindNearestTableIndex(const COLORREF Color, - _In_reads_(cColorTable) const COLORREF* const ColorTable, - const WORD cColorTable); + const std::basic_string_view ColorTable); bool FindTableIndex(const COLORREF Color, - _In_reads_(cColorTable) const COLORREF* const ColorTable, - const WORD cColorTable, + const std::basic_string_view ColorTable, _Out_ WORD* const pFoundIndex); WORD XtermToWindowsIndex(const size_t index) noexcept; WORD Xterm256ToWindowsIndex(const size_t index) noexcept; WORD XtermToLegacy(const size_t xtermForeground, const size_t xtermBackground); -COLORREF ForegroundColor(const WORD wLegacyAttrs, - _In_reads_(cColorTable) const COLORREF* const ColorTable, - const size_t cColorTable); - -COLORREF BackgroundColor(const WORD wLegacyAttrs, - _In_reads_(cColorTable) const COLORREF* const ColorTable, - const size_t cColorTable); - const WORD WINDOWS_RED_ATTR = FOREGROUND_RED; const WORD WINDOWS_GREEN_ATTR = FOREGROUND_GREEN; const WORD WINDOWS_BLUE_ATTR = FOREGROUND_BLUE; diff --git a/src/interactivity/win32/menu.cpp b/src/interactivity/win32/menu.cpp index b9e09b32f9f..0555a315dee 100644 --- a/src/interactivity/win32/menu.cpp +++ b/src/interactivity/win32/menu.cpp @@ -335,7 +335,10 @@ void Menu::s_ShowPropertiesDialog(HWND const hwnd, BOOL const Defaults) pStateInfo->NumberOfHistoryBuffers = gci.GetNumberOfHistoryBuffers(); pStateInfo->HistoryNoDup = !!(gci.Flags & CONSOLE_HISTORY_NODUP); - memmove(pStateInfo->ColorTable, gci.GetColorTable(), gci.GetColorTableSize() * sizeof(COLORREF)); + for (size_t i = 0; i < std::size(pStateInfo->ColorTable); i++) + { + pStateInfo->ColorTable[i] = gci.GetColorTableEntry(i); + } // Create mutable copies of the titles so the propsheet can do something with them. if (gci.GetOriginalTitle().length() > 0) @@ -562,7 +565,10 @@ void Menu::s_PropertiesUpdate(PCONSOLE_STATE_INFO pStateInfo) } } - gci.SetColorTable(pStateInfo->ColorTable, gci.GetColorTableSize()); + for (size_t i = 0; i < std::size(pStateInfo->ColorTable); i++) + { + gci.SetColorTableEntry(i, pStateInfo->ColorTable[i]); + } // Ensure that attributes only contain color specification. WI_ClearAllFlags(pStateInfo->ScreenAttributes, ~(FG_ATTRS | BG_ATTRS)); diff --git a/src/renderer/vt/WinTelnetEngine.cpp b/src/renderer/vt/WinTelnetEngine.cpp index f08a186c32f..c8081cf613b 100644 --- a/src/renderer/vt/WinTelnetEngine.cpp +++ b/src/renderer/vt/WinTelnetEngine.cpp @@ -12,11 +12,9 @@ using namespace Microsoft::Console::Types; WinTelnetEngine::WinTelnetEngine(_In_ wil::unique_hfile hPipe, const IDefaultColorProvider& colorProvider, const Viewport initialViewport, - _In_reads_(cColorTable) const COLORREF* const ColorTable, - const WORD cColorTable) : + const std::basic_string_view colorTable) : VtEngine(std::move(hPipe), colorProvider, initialViewport), - _ColorTable(ColorTable), - _cColorTable(cColorTable) + _colorTable(colorTable) { } @@ -42,8 +40,7 @@ WinTelnetEngine::WinTelnetEngine(_In_ wil::unique_hfile hPipe, return VtEngine::_16ColorUpdateDrawingBrushes(colorForeground, colorBackground, WI_IsFlagSet(extendedAttrs, ExtendedAttributes::Bold), - _ColorTable, - _cColorTable); + _colorTable); } // Routine Description: diff --git a/src/renderer/vt/WinTelnetEngine.hpp b/src/renderer/vt/WinTelnetEngine.hpp index 179697a5ab9..4d40c232d0a 100644 --- a/src/renderer/vt/WinTelnetEngine.hpp +++ b/src/renderer/vt/WinTelnetEngine.hpp @@ -26,8 +26,7 @@ namespace Microsoft::Console::Render WinTelnetEngine(_In_ wil::unique_hfile hPipe, const Microsoft::Console::IDefaultColorProvider& colorProvider, const Microsoft::Console::Types::Viewport initialViewport, - _In_reads_(cColorTable) const COLORREF* const ColorTable, - const WORD cColorTable); + const std::basic_string_view colorTable); virtual ~WinTelnetEngine() override = default; [[nodiscard]] HRESULT UpdateDrawingBrushes(const COLORREF colorForeground, @@ -45,8 +44,7 @@ namespace Microsoft::Console::Render [[nodiscard]] HRESULT _MoveCursor(const COORD coord) noexcept; private: - const COLORREF* const _ColorTable; - const WORD _cColorTable; + const std::basic_string_view _colorTable; #ifdef UNIT_TESTING friend class VtRendererTest; diff --git a/src/renderer/vt/Xterm256Engine.cpp b/src/renderer/vt/Xterm256Engine.cpp index ba440db0386..2fed81c2ab8 100644 --- a/src/renderer/vt/Xterm256Engine.cpp +++ b/src/renderer/vt/Xterm256Engine.cpp @@ -11,9 +11,8 @@ using namespace Microsoft::Console::Types; Xterm256Engine::Xterm256Engine(_In_ wil::unique_hfile hPipe, const IDefaultColorProvider& colorProvider, const Viewport initialViewport, - _In_reads_(cColorTable) const COLORREF* const ColorTable, - const WORD cColorTable) : - XtermEngine(std::move(hPipe), colorProvider, initialViewport, ColorTable, cColorTable, false), + const std::basic_string_view colorTable) : + XtermEngine(std::move(hPipe), colorProvider, initialViewport, colorTable, false), _lastExtendedAttrsState{ ExtendedAttributes::Normal } { } @@ -52,8 +51,7 @@ Xterm256Engine::Xterm256Engine(_In_ wil::unique_hfile hPipe, return VtEngine::_RgbUpdateDrawingBrushes(colorForeground, colorBackground, WI_IsFlagSet(extendedAttrs, ExtendedAttributes::Bold), - _ColorTable, - _cColorTable); + _colorTable); } // Routine Description: diff --git a/src/renderer/vt/Xterm256Engine.hpp b/src/renderer/vt/Xterm256Engine.hpp index 3addb195e17..e4e5562f6c4 100644 --- a/src/renderer/vt/Xterm256Engine.hpp +++ b/src/renderer/vt/Xterm256Engine.hpp @@ -26,8 +26,7 @@ namespace Microsoft::Console::Render Xterm256Engine(_In_ wil::unique_hfile hPipe, const Microsoft::Console::IDefaultColorProvider& colorProvider, const Microsoft::Console::Types::Viewport initialViewport, - _In_reads_(cColorTable) const COLORREF* const ColorTable, - const WORD cColorTable); + const std::basic_string_view colorTable); virtual ~Xterm256Engine() override = default; diff --git a/src/renderer/vt/XtermEngine.cpp b/src/renderer/vt/XtermEngine.cpp index f212c1eeb72..6073b0358f6 100644 --- a/src/renderer/vt/XtermEngine.cpp +++ b/src/renderer/vt/XtermEngine.cpp @@ -12,12 +12,10 @@ using namespace Microsoft::Console::Types; XtermEngine::XtermEngine(_In_ wil::unique_hfile hPipe, const IDefaultColorProvider& colorProvider, const Viewport initialViewport, - _In_reads_(cColorTable) const COLORREF* const ColorTable, - const WORD cColorTable, + const std::basic_string_view colorTable, const bool fUseAsciiOnly) : VtEngine(std::move(hPipe), colorProvider, initialViewport), - _ColorTable(ColorTable), - _cColorTable(cColorTable), + _colorTable(colorTable), _fUseAsciiOnly(fUseAsciiOnly), _usingUnderLine(false), _needToDisableCursor(false), @@ -192,8 +190,7 @@ XtermEngine::XtermEngine(_In_ wil::unique_hfile hPipe, return VtEngine::_16ColorUpdateDrawingBrushes(colorForeground, colorBackground, WI_IsFlagSet(extendedAttrs, ExtendedAttributes::Bold), - _ColorTable, - _cColorTable); + _colorTable); } // Routine Description: diff --git a/src/renderer/vt/XtermEngine.hpp b/src/renderer/vt/XtermEngine.hpp index e6a0a868c18..cf5249ab6ac 100644 --- a/src/renderer/vt/XtermEngine.hpp +++ b/src/renderer/vt/XtermEngine.hpp @@ -30,8 +30,7 @@ namespace Microsoft::Console::Render XtermEngine(_In_ wil::unique_hfile hPipe, const Microsoft::Console::IDefaultColorProvider& colorProvider, const Microsoft::Console::Types::Viewport initialViewport, - _In_reads_(cColorTable) const COLORREF* const ColorTable, - const WORD cColorTable, + const std::basic_string_view colorTable, const bool fUseAsciiOnly); virtual ~XtermEngine() override = default; @@ -57,8 +56,7 @@ namespace Microsoft::Console::Render [[nodiscard]] HRESULT WriteTerminalW(const std::wstring_view str) noexcept override; protected: - const COLORREF* const _ColorTable; - const WORD _cColorTable; + const std::basic_string_view _colorTable; const bool _fUseAsciiOnly; bool _usingUnderLine; bool _needToDisableCursor; diff --git a/src/renderer/vt/paint.cpp b/src/renderer/vt/paint.cpp index b539950efb4..2a3635befa9 100644 --- a/src/renderer/vt/paint.cpp +++ b/src/renderer/vt/paint.cpp @@ -192,8 +192,7 @@ using namespace Microsoft::Console::Types; [[nodiscard]] HRESULT VtEngine::_RgbUpdateDrawingBrushes(const COLORREF colorForeground, const COLORREF colorBackground, const bool isBold, - _In_reads_(cColorTable) const COLORREF* const ColorTable, - const WORD cColorTable) noexcept + const std::basic_string_view colorTable) noexcept { const bool fgChanged = colorForeground != _LastFG; const bool bgChanged = colorBackground != _LastBG; @@ -232,7 +231,7 @@ using namespace Microsoft::Console::Types; { RETURN_IF_FAILED(_SetGraphicsRenditionDefaultColor(true)); } - else if (::FindTableIndex(colorForeground, ColorTable, cColorTable, &wFoundColor)) + else if (::FindTableIndex(colorForeground, colorTable, &wFoundColor)) { RETURN_IF_FAILED(_SetGraphicsRendition16Color(wFoundColor, true)); } @@ -249,7 +248,7 @@ using namespace Microsoft::Console::Types; { RETURN_IF_FAILED(_SetGraphicsRenditionDefaultColor(false)); } - else if (::FindTableIndex(colorBackground, ColorTable, cColorTable, &wFoundColor)) + else if (::FindTableIndex(colorBackground, colorTable, &wFoundColor)) { RETURN_IF_FAILED(_SetGraphicsRendition16Color(wFoundColor, false)); } @@ -278,8 +277,7 @@ using namespace Microsoft::Console::Types; [[nodiscard]] HRESULT VtEngine::_16ColorUpdateDrawingBrushes(const COLORREF colorForeground, const COLORREF colorBackground, const bool isBold, - _In_reads_(cColorTable) const COLORREF* const ColorTable, - const WORD cColorTable) noexcept + const std::basic_string_view colorTable) noexcept { const bool fgChanged = colorForeground != _LastFG; const bool bgChanged = colorBackground != _LastBG; @@ -312,7 +310,7 @@ using namespace Microsoft::Console::Types; if (fgChanged) { - const WORD wNearestFg = ::FindNearestTableIndex(colorForeground, ColorTable, cColorTable); + const WORD wNearestFg = ::FindNearestTableIndex(colorForeground, colorTable); RETURN_IF_FAILED(_SetGraphicsRendition16Color(wNearestFg, true)); _LastFG = colorForeground; @@ -320,7 +318,7 @@ using namespace Microsoft::Console::Types; if (bgChanged) { - const WORD wNearestBg = ::FindNearestTableIndex(colorBackground, ColorTable, cColorTable); + const WORD wNearestBg = ::FindNearestTableIndex(colorBackground, colorTable); RETURN_IF_FAILED(_SetGraphicsRendition16Color(wNearestBg, false)); _LastBG = colorBackground; diff --git a/src/renderer/vt/vtrenderer.hpp b/src/renderer/vt/vtrenderer.hpp index 5f683bc9b15..715cd9ce7f3 100644 --- a/src/renderer/vt/vtrenderer.hpp +++ b/src/renderer/vt/vtrenderer.hpp @@ -212,13 +212,11 @@ namespace Microsoft::Console::Render [[nodiscard]] HRESULT _RgbUpdateDrawingBrushes(const COLORREF colorForeground, const COLORREF colorBackground, const bool isBold, - _In_reads_(cColorTable) const COLORREF* const ColorTable, - const WORD cColorTable) noexcept; + const std::basic_string_view colorTable) noexcept; [[nodiscard]] HRESULT _16ColorUpdateDrawingBrushes(const COLORREF colorForeground, const COLORREF colorBackground, const bool isBold, - _In_reads_(cColorTable) const COLORREF* const ColorTable, - const WORD cColorTable) noexcept; + const std::basic_string_view colorTable) noexcept; bool _WillWriteSingleChar() const; diff --git a/src/terminal/adapter/adaptDispatch.hpp b/src/terminal/adapter/adaptDispatch.hpp index 8bdd40b72ee..a5319d9126b 100644 --- a/src/terminal/adapter/adaptDispatch.hpp +++ b/src/terminal/adapter/adaptDispatch.hpp @@ -178,6 +178,6 @@ namespace Microsoft::Console::VirtualTerminal size_t _SetRgbColorsHelper(const std::basic_string_view options, TextAttribute& attr, - const bool isForeground); + const bool isForeground) noexcept; }; } diff --git a/src/terminal/adapter/adaptDispatchGraphics.cpp b/src/terminal/adapter/adaptDispatchGraphics.cpp index 9e565ecf3e0..7cb0d161f65 100644 --- a/src/terminal/adapter/adaptDispatchGraphics.cpp +++ b/src/terminal/adapter/adaptDispatchGraphics.cpp @@ -49,7 +49,7 @@ const BYTE BRIGHT_WHITE = BRIGHT_ATTR | RED_ATTR | GREEN_ATTR | BLUE_ATTR; // - The number of options consumed, not including the initial 38/48. size_t AdaptDispatch::_SetRgbColorsHelper(const std::basic_string_view options, TextAttribute& attr, - const bool isForeground) + const bool isForeground) noexcept { size_t optionsConsumed = 0; if (options.size() >= 1) @@ -73,11 +73,17 @@ size_t AdaptDispatch::_SetRgbColorsHelper(const std::basic_string_viewPrivateGetColorTableEntry(tableIndex, rgbColor)) + if (tableIndex <= 255) { - // TODO GH#1223: Decouple xterm-256color indexed storage from RGB storage - attr.SetColor(rgbColor, isForeground); + const auto adjustedIndex = gsl::narrow_cast(::Xterm256ToWindowsIndex(tableIndex)); + if (isForeground) + { + attr.SetIndexedForeground256(adjustedIndex); + } + else + { + attr.SetIndexedBackground256(adjustedIndex); + } } } } diff --git a/src/terminal/adapter/ut_adapter/adapterTest.cpp b/src/terminal/adapter/ut_adapter/adapterTest.cpp index fbcbe3e6e47..7b16c3d690d 100644 --- a/src/terminal/adapter/ut_adapter/adapterTest.cpp +++ b/src/terminal/adapter/ut_adapter/adapterTest.cpp @@ -1286,42 +1286,50 @@ class AdapterTest case DispatchTypes::GraphicsOptions::ForegroundBlack: Log::Comment(L"Testing graphics 'Foreground Color Black'"); _testGetSet->_attribute = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY; - _testGetSet->_expectedAttribute = 0; + _testGetSet->_expectedAttribute = _testGetSet->_attribute; + _testGetSet->_expectedAttribute.SetIndexedForeground(0); break; case DispatchTypes::GraphicsOptions::ForegroundBlue: Log::Comment(L"Testing graphics 'Foreground Color Blue'"); _testGetSet->_attribute = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_INTENSITY; - _testGetSet->_expectedAttribute = FOREGROUND_BLUE; + _testGetSet->_expectedAttribute = _testGetSet->_attribute; + _testGetSet->_expectedAttribute.SetIndexedForeground(FOREGROUND_BLUE); break; case DispatchTypes::GraphicsOptions::ForegroundGreen: Log::Comment(L"Testing graphics 'Foreground Color Green'"); _testGetSet->_attribute = FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_INTENSITY; - _testGetSet->_expectedAttribute = FOREGROUND_GREEN; + _testGetSet->_expectedAttribute = _testGetSet->_attribute; + _testGetSet->_expectedAttribute.SetIndexedForeground(FOREGROUND_GREEN); break; case DispatchTypes::GraphicsOptions::ForegroundCyan: Log::Comment(L"Testing graphics 'Foreground Color Cyan'"); _testGetSet->_attribute = FOREGROUND_RED | FOREGROUND_INTENSITY; - _testGetSet->_expectedAttribute = FOREGROUND_BLUE | FOREGROUND_GREEN; + _testGetSet->_expectedAttribute = _testGetSet->_attribute; + _testGetSet->_expectedAttribute.SetIndexedForeground(FOREGROUND_BLUE | FOREGROUND_GREEN); break; case DispatchTypes::GraphicsOptions::ForegroundRed: Log::Comment(L"Testing graphics 'Foreground Color Red'"); _testGetSet->_attribute = FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_INTENSITY; - _testGetSet->_expectedAttribute = FOREGROUND_RED; + _testGetSet->_expectedAttribute = _testGetSet->_attribute; + _testGetSet->_expectedAttribute.SetIndexedForeground(FOREGROUND_RED); break; case DispatchTypes::GraphicsOptions::ForegroundMagenta: Log::Comment(L"Testing graphics 'Foreground Color Magenta'"); _testGetSet->_attribute = FOREGROUND_GREEN | FOREGROUND_INTENSITY; - _testGetSet->_expectedAttribute = FOREGROUND_BLUE | FOREGROUND_RED; + _testGetSet->_expectedAttribute = _testGetSet->_attribute; + _testGetSet->_expectedAttribute.SetIndexedForeground(FOREGROUND_BLUE | FOREGROUND_RED); break; case DispatchTypes::GraphicsOptions::ForegroundYellow: Log::Comment(L"Testing graphics 'Foreground Color Yellow'"); _testGetSet->_attribute = FOREGROUND_BLUE | FOREGROUND_INTENSITY; - _testGetSet->_expectedAttribute = FOREGROUND_GREEN | FOREGROUND_RED; + _testGetSet->_expectedAttribute = _testGetSet->_attribute; + _testGetSet->_expectedAttribute.SetIndexedForeground(FOREGROUND_GREEN | FOREGROUND_RED); break; case DispatchTypes::GraphicsOptions::ForegroundWhite: Log::Comment(L"Testing graphics 'Foreground Color White'"); _testGetSet->_attribute = FOREGROUND_INTENSITY; - _testGetSet->_expectedAttribute = FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED; + _testGetSet->_expectedAttribute = _testGetSet->_attribute; + _testGetSet->_expectedAttribute.SetIndexedForeground(FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED); break; case DispatchTypes::GraphicsOptions::ForegroundDefault: Log::Comment(L"Testing graphics 'Foreground Color Default'"); @@ -1333,42 +1341,50 @@ class AdapterTest case DispatchTypes::GraphicsOptions::BackgroundBlack: Log::Comment(L"Testing graphics 'Background Color Black'"); _testGetSet->_attribute = BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE | BACKGROUND_INTENSITY; - _testGetSet->_expectedAttribute = 0; + _testGetSet->_expectedAttribute = _testGetSet->_attribute; + _testGetSet->_expectedAttribute.SetIndexedBackground(0); break; case DispatchTypes::GraphicsOptions::BackgroundBlue: Log::Comment(L"Testing graphics 'Background Color Blue'"); _testGetSet->_attribute = BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_INTENSITY; - _testGetSet->_expectedAttribute = BACKGROUND_BLUE; + _testGetSet->_expectedAttribute = _testGetSet->_attribute; + _testGetSet->_expectedAttribute.SetIndexedBackground(BACKGROUND_BLUE >> 4); break; case DispatchTypes::GraphicsOptions::BackgroundGreen: Log::Comment(L"Testing graphics 'Background Color Green'"); _testGetSet->_attribute = BACKGROUND_RED | BACKGROUND_BLUE | BACKGROUND_INTENSITY; - _testGetSet->_expectedAttribute = BACKGROUND_GREEN; + _testGetSet->_expectedAttribute = _testGetSet->_attribute; + _testGetSet->_expectedAttribute.SetIndexedBackground(BACKGROUND_GREEN >> 4); break; case DispatchTypes::GraphicsOptions::BackgroundCyan: Log::Comment(L"Testing graphics 'Background Color Cyan'"); _testGetSet->_attribute = BACKGROUND_RED | BACKGROUND_INTENSITY; - _testGetSet->_expectedAttribute = BACKGROUND_BLUE | BACKGROUND_GREEN; + _testGetSet->_expectedAttribute = _testGetSet->_attribute; + _testGetSet->_expectedAttribute.SetIndexedBackground((BACKGROUND_BLUE | BACKGROUND_GREEN) >> 4); break; case DispatchTypes::GraphicsOptions::BackgroundRed: Log::Comment(L"Testing graphics 'Background Color Red'"); _testGetSet->_attribute = BACKGROUND_BLUE | BACKGROUND_GREEN | BACKGROUND_INTENSITY; - _testGetSet->_expectedAttribute = BACKGROUND_RED; + _testGetSet->_expectedAttribute = _testGetSet->_attribute; + _testGetSet->_expectedAttribute.SetIndexedBackground(BACKGROUND_RED >> 4); break; case DispatchTypes::GraphicsOptions::BackgroundMagenta: Log::Comment(L"Testing graphics 'Background Color Magenta'"); _testGetSet->_attribute = BACKGROUND_GREEN | BACKGROUND_INTENSITY; - _testGetSet->_expectedAttribute = BACKGROUND_BLUE | BACKGROUND_RED; + _testGetSet->_expectedAttribute = _testGetSet->_attribute; + _testGetSet->_expectedAttribute.SetIndexedBackground((BACKGROUND_BLUE | BACKGROUND_RED) >> 4); break; case DispatchTypes::GraphicsOptions::BackgroundYellow: Log::Comment(L"Testing graphics 'Background Color Yellow'"); _testGetSet->_attribute = BACKGROUND_BLUE | BACKGROUND_INTENSITY; - _testGetSet->_expectedAttribute = BACKGROUND_GREEN | BACKGROUND_RED; + _testGetSet->_expectedAttribute = _testGetSet->_attribute; + _testGetSet->_expectedAttribute.SetIndexedBackground((BACKGROUND_GREEN | BACKGROUND_RED) >> 4); break; case DispatchTypes::GraphicsOptions::BackgroundWhite: Log::Comment(L"Testing graphics 'Background Color White'"); _testGetSet->_attribute = BACKGROUND_INTENSITY; - _testGetSet->_expectedAttribute = BACKGROUND_BLUE | BACKGROUND_GREEN | BACKGROUND_RED; + _testGetSet->_expectedAttribute = _testGetSet->_attribute; + _testGetSet->_expectedAttribute.SetIndexedBackground((BACKGROUND_BLUE | BACKGROUND_GREEN | BACKGROUND_RED) >> 4); break; case DispatchTypes::GraphicsOptions::BackgroundDefault: Log::Comment(L"Testing graphics 'Background Color Default'"); @@ -1380,82 +1396,98 @@ class AdapterTest case DispatchTypes::GraphicsOptions::BrightForegroundBlack: Log::Comment(L"Testing graphics 'Bright Foreground Color Black'"); _testGetSet->_attribute = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE; - _testGetSet->_expectedAttribute = FOREGROUND_INTENSITY; + _testGetSet->_expectedAttribute = _testGetSet->_attribute; + _testGetSet->_expectedAttribute.SetIndexedForeground(FOREGROUND_INTENSITY); break; case DispatchTypes::GraphicsOptions::BrightForegroundBlue: Log::Comment(L"Testing graphics 'Bright Foreground Color Blue'"); _testGetSet->_attribute = FOREGROUND_RED | FOREGROUND_GREEN; - _testGetSet->_expectedAttribute = FOREGROUND_INTENSITY | FOREGROUND_BLUE; + _testGetSet->_expectedAttribute = _testGetSet->_attribute; + _testGetSet->_expectedAttribute.SetIndexedForeground(FOREGROUND_INTENSITY | FOREGROUND_BLUE); break; case DispatchTypes::GraphicsOptions::BrightForegroundGreen: Log::Comment(L"Testing graphics 'Bright Foreground Color Green'"); _testGetSet->_attribute = FOREGROUND_RED | FOREGROUND_BLUE; - _testGetSet->_expectedAttribute = FOREGROUND_INTENSITY | FOREGROUND_GREEN; + _testGetSet->_expectedAttribute = _testGetSet->_attribute; + _testGetSet->_expectedAttribute.SetIndexedForeground(FOREGROUND_INTENSITY | FOREGROUND_GREEN); break; case DispatchTypes::GraphicsOptions::BrightForegroundCyan: Log::Comment(L"Testing graphics 'Bright Foreground Color Cyan'"); _testGetSet->_attribute = FOREGROUND_RED; - _testGetSet->_expectedAttribute = FOREGROUND_INTENSITY | FOREGROUND_BLUE | FOREGROUND_GREEN; + _testGetSet->_expectedAttribute = _testGetSet->_attribute; + _testGetSet->_expectedAttribute.SetIndexedForeground(FOREGROUND_INTENSITY | FOREGROUND_BLUE | FOREGROUND_GREEN); break; case DispatchTypes::GraphicsOptions::BrightForegroundRed: Log::Comment(L"Testing graphics 'Bright Foreground Color Red'"); _testGetSet->_attribute = FOREGROUND_BLUE | FOREGROUND_GREEN; - _testGetSet->_expectedAttribute = FOREGROUND_INTENSITY | FOREGROUND_RED; + _testGetSet->_expectedAttribute = _testGetSet->_attribute; + _testGetSet->_expectedAttribute.SetIndexedForeground(FOREGROUND_INTENSITY | FOREGROUND_RED); break; case DispatchTypes::GraphicsOptions::BrightForegroundMagenta: Log::Comment(L"Testing graphics 'Bright Foreground Color Magenta'"); _testGetSet->_attribute = FOREGROUND_GREEN; - _testGetSet->_expectedAttribute = FOREGROUND_INTENSITY | FOREGROUND_BLUE | FOREGROUND_RED; + _testGetSet->_expectedAttribute = _testGetSet->_attribute; + _testGetSet->_expectedAttribute.SetIndexedForeground(FOREGROUND_INTENSITY | FOREGROUND_BLUE | FOREGROUND_RED); break; case DispatchTypes::GraphicsOptions::BrightForegroundYellow: Log::Comment(L"Testing graphics 'Bright Foreground Color Yellow'"); _testGetSet->_attribute = FOREGROUND_BLUE; - _testGetSet->_expectedAttribute = FOREGROUND_INTENSITY | FOREGROUND_GREEN | FOREGROUND_RED; + _testGetSet->_expectedAttribute = _testGetSet->_attribute; + _testGetSet->_expectedAttribute.SetIndexedForeground(FOREGROUND_INTENSITY | FOREGROUND_GREEN | FOREGROUND_RED); break; case DispatchTypes::GraphicsOptions::BrightForegroundWhite: Log::Comment(L"Testing graphics 'Bright Foreground Color White'"); _testGetSet->_attribute = 0; - _testGetSet->_expectedAttribute = FOREGROUND_INTENSITY | FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED; + _testGetSet->_expectedAttribute = _testGetSet->_attribute; + _testGetSet->_expectedAttribute.SetIndexedForeground(FOREGROUND_INTENSITY | FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED); break; case DispatchTypes::GraphicsOptions::BrightBackgroundBlack: Log::Comment(L"Testing graphics 'Bright Background Color Black'"); _testGetSet->_attribute = BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE; - _testGetSet->_expectedAttribute = BACKGROUND_INTENSITY; + _testGetSet->_expectedAttribute = _testGetSet->_attribute; + _testGetSet->_expectedAttribute.SetIndexedBackground(BACKGROUND_INTENSITY >> 4); break; case DispatchTypes::GraphicsOptions::BrightBackgroundBlue: Log::Comment(L"Testing graphics 'Bright Background Color Blue'"); _testGetSet->_attribute = BACKGROUND_RED | BACKGROUND_GREEN; - _testGetSet->_expectedAttribute = BACKGROUND_INTENSITY | BACKGROUND_BLUE; + _testGetSet->_expectedAttribute = _testGetSet->_attribute; + _testGetSet->_expectedAttribute.SetIndexedBackground((BACKGROUND_INTENSITY | BACKGROUND_BLUE) >> 4); break; case DispatchTypes::GraphicsOptions::BrightBackgroundGreen: Log::Comment(L"Testing graphics 'Bright Background Color Green'"); _testGetSet->_attribute = BACKGROUND_RED | BACKGROUND_BLUE; - _testGetSet->_expectedAttribute = BACKGROUND_INTENSITY | BACKGROUND_GREEN; + _testGetSet->_expectedAttribute = _testGetSet->_attribute; + _testGetSet->_expectedAttribute.SetIndexedBackground((BACKGROUND_INTENSITY | BACKGROUND_GREEN) >> 4); break; case DispatchTypes::GraphicsOptions::BrightBackgroundCyan: Log::Comment(L"Testing graphics 'Bright Background Color Cyan'"); _testGetSet->_attribute = BACKGROUND_RED; - _testGetSet->_expectedAttribute = BACKGROUND_INTENSITY | BACKGROUND_BLUE | BACKGROUND_GREEN; + _testGetSet->_expectedAttribute = _testGetSet->_attribute; + _testGetSet->_expectedAttribute.SetIndexedBackground((BACKGROUND_INTENSITY | BACKGROUND_BLUE | BACKGROUND_GREEN) >> 4); break; case DispatchTypes::GraphicsOptions::BrightBackgroundRed: Log::Comment(L"Testing graphics 'Bright Background Color Red'"); _testGetSet->_attribute = BACKGROUND_BLUE | BACKGROUND_GREEN; - _testGetSet->_expectedAttribute = BACKGROUND_INTENSITY | BACKGROUND_RED; + _testGetSet->_expectedAttribute = _testGetSet->_attribute; + _testGetSet->_expectedAttribute.SetIndexedBackground((BACKGROUND_INTENSITY | BACKGROUND_RED) >> 4); break; case DispatchTypes::GraphicsOptions::BrightBackgroundMagenta: Log::Comment(L"Testing graphics 'Bright Background Color Magenta'"); _testGetSet->_attribute = BACKGROUND_GREEN; - _testGetSet->_expectedAttribute = BACKGROUND_INTENSITY | BACKGROUND_BLUE | BACKGROUND_RED; + _testGetSet->_expectedAttribute = _testGetSet->_attribute; + _testGetSet->_expectedAttribute.SetIndexedBackground((BACKGROUND_INTENSITY | BACKGROUND_BLUE | BACKGROUND_RED) >> 4); break; case DispatchTypes::GraphicsOptions::BrightBackgroundYellow: Log::Comment(L"Testing graphics 'Bright Background Color Yellow'"); _testGetSet->_attribute = BACKGROUND_BLUE; - _testGetSet->_expectedAttribute = BACKGROUND_INTENSITY | BACKGROUND_GREEN | BACKGROUND_RED; + _testGetSet->_expectedAttribute = _testGetSet->_attribute; + _testGetSet->_expectedAttribute.SetIndexedBackground((BACKGROUND_INTENSITY | BACKGROUND_GREEN | BACKGROUND_RED) >> 4); break; case DispatchTypes::GraphicsOptions::BrightBackgroundWhite: Log::Comment(L"Testing graphics 'Bright Background Color White'"); _testGetSet->_attribute = 0; - _testGetSet->_expectedAttribute = BACKGROUND_INTENSITY | BACKGROUND_BLUE | BACKGROUND_GREEN | BACKGROUND_RED; + _testGetSet->_expectedAttribute = _testGetSet->_attribute; + _testGetSet->_expectedAttribute.SetIndexedBackground((BACKGROUND_INTENSITY | BACKGROUND_BLUE | BACKGROUND_GREEN | BACKGROUND_RED) >> 4); break; default: VERIFY_FAIL(L"Test not implemented yet!"); @@ -1880,32 +1912,28 @@ class AdapterTest rgOptions[0] = DispatchTypes::GraphicsOptions::ForegroundExtended; rgOptions[1] = DispatchTypes::GraphicsOptions::BlinkOrXterm256Index; rgOptions[2] = (DispatchTypes::GraphicsOptions)2; // Green - _testGetSet->_expectedAttribute.SetForeground(2); - _testGetSet->_expectedColorTableIndex = 2; + _testGetSet->_expectedAttribute.SetIndexedForeground256((BYTE)::XtermToWindowsIndex(2)); VERIFY_IS_TRUE(_pDispatch.get()->SetGraphicsRendition({ rgOptions, cOptions })); Log::Comment(L"Test 2: Change Background"); rgOptions[0] = DispatchTypes::GraphicsOptions::BackgroundExtended; rgOptions[1] = DispatchTypes::GraphicsOptions::BlinkOrXterm256Index; rgOptions[2] = (DispatchTypes::GraphicsOptions)9; // Bright Red - _testGetSet->_expectedAttribute.SetBackground(9); - _testGetSet->_expectedColorTableIndex = 9; + _testGetSet->_expectedAttribute.SetIndexedBackground256((BYTE)::XtermToWindowsIndex(9)); VERIFY_IS_TRUE(_pDispatch.get()->SetGraphicsRendition({ rgOptions, cOptions })); Log::Comment(L"Test 3: Change Foreground to RGB color"); rgOptions[0] = DispatchTypes::GraphicsOptions::ForegroundExtended; rgOptions[1] = DispatchTypes::GraphicsOptions::BlinkOrXterm256Index; rgOptions[2] = (DispatchTypes::GraphicsOptions)42; // Arbitrary Color - _testGetSet->_expectedColorTableIndex = 42; - _testGetSet->_expectedAttribute.SetForeground(42); + _testGetSet->_expectedAttribute.SetIndexedForeground256(42); VERIFY_IS_TRUE(_pDispatch.get()->SetGraphicsRendition({ rgOptions, cOptions })); Log::Comment(L"Test 4: Change Background to RGB color"); rgOptions[0] = DispatchTypes::GraphicsOptions::BackgroundExtended; rgOptions[1] = DispatchTypes::GraphicsOptions::BlinkOrXterm256Index; rgOptions[2] = (DispatchTypes::GraphicsOptions)142; // Arbitrary Color - _testGetSet->_expectedColorTableIndex = 142; - _testGetSet->_expectedAttribute.SetBackground(142); + _testGetSet->_expectedAttribute.SetIndexedBackground256(142); VERIFY_IS_TRUE(_pDispatch.get()->SetGraphicsRendition({ rgOptions, cOptions })); Log::Comment(L"Test 5: Change Foreground to Legacy Attr while BG is RGB color"); @@ -1915,8 +1943,7 @@ class AdapterTest rgOptions[0] = DispatchTypes::GraphicsOptions::ForegroundExtended; rgOptions[1] = DispatchTypes::GraphicsOptions::BlinkOrXterm256Index; rgOptions[2] = (DispatchTypes::GraphicsOptions)9; // Bright Red - _testGetSet->_expectedAttribute.SetForeground(9); - _testGetSet->_expectedColorTableIndex = 9; + _testGetSet->_expectedAttribute.SetIndexedForeground256((BYTE)::XtermToWindowsIndex(9)); VERIFY_IS_TRUE(_pDispatch.get()->SetGraphicsRendition({ rgOptions, cOptions })); } diff --git a/tools/ConsoleTypes.natvis b/tools/ConsoleTypes.natvis index 27b29d1545b..224afd9bd36 100644 --- a/tools/ConsoleTypes.natvis +++ b/tools/ConsoleTypes.natvis @@ -2,7 +2,8 @@ - {{Index:{_index}}} + {{Index256:{_index}}} + {{Index16:{_index}}} {{Default}} {{RGB:{_red},{_green},{_blue}}}