diff --git a/src/buffer/out/TextAttribute.cpp b/src/buffer/out/TextAttribute.cpp index c44724846..b99c3121d 100644 --- a/src/buffer/out/TextAttribute.cpp +++ b/src/buffer/out/TextAttribute.cpp @@ -12,8 +12,30 @@ static_assert(alignof(TextAttribute) == 2); // Ensure that we can memcpy() and memmove() the struct for performance. static_assert(std::is_trivially_copyable_v); -BYTE TextAttribute::s_legacyDefaultForeground = 7; -BYTE TextAttribute::s_legacyDefaultBackground = 0; +namespace +{ + constexpr std::array s_initLegacyColorMap(const BYTE defaultIndex) + { + std::array legacyColorMap; + for (auto i = 0u; i < legacyColorMap.size(); i++) + { + const auto legacyIndex = TextColor::TransposeLegacyIndex(i); + gsl::at(legacyColorMap, i) = i == defaultIndex ? TextColor{} : TextColor{ legacyIndex, true }; + } + return legacyColorMap; + } + + BYTE s_legacyDefaultForeground = 7; + BYTE s_legacyDefaultBackground = 0; + BYTE s_ansiDefaultForeground = 7; + BYTE s_ansiDefaultBackground = 0; +} + +// These maps allow for an efficient conversion from a legacy attribute index +// to a TextColor with the corresponding ANSI index, also taking into account +// the legacy index values that need to be converted to a default TextColor. +std::array TextAttribute::s_legacyForegroundColorMap = s_initLegacyColorMap(7); +std::array TextAttribute::s_legacyBackgroundColorMap = s_initLegacyColorMap(0); // Routine Description: // - Sets the legacy attributes which map to and from the default colors. @@ -23,8 +45,22 @@ BYTE TextAttribute::s_legacyDefaultBackground = 0; // - None void TextAttribute::SetLegacyDefaultAttributes(const WORD defaultAttributes) noexcept { + // First we reset the current default color map entries to what they should + // be for a regular translation from a legacy index to an ANSI TextColor. + gsl::at(s_legacyForegroundColorMap, s_legacyDefaultForeground) = TextColor{ s_ansiDefaultForeground, true }; + gsl::at(s_legacyBackgroundColorMap, s_legacyDefaultBackground) = TextColor{ s_ansiDefaultBackground, true }; + + // Then we save the new default attribute values and their corresponding + // ANSI translations. We use the latter values to more efficiently handle + // the "VT Quirk" conversion below. s_legacyDefaultForeground = defaultAttributes & FG_ATTRS; s_legacyDefaultBackground = (defaultAttributes & BG_ATTRS) >> 4; + s_ansiDefaultForeground = TextColor::TransposeLegacyIndex(s_legacyDefaultForeground); + s_ansiDefaultBackground = TextColor::TransposeLegacyIndex(s_legacyDefaultBackground); + + // Finally we set the new default color map entries. + gsl::at(s_legacyForegroundColorMap, s_legacyDefaultForeground) = TextColor{}; + gsl::at(s_legacyBackgroundColorMap, s_legacyDefaultBackground) = TextColor{}; } // Routine Description: @@ -55,13 +91,13 @@ TextAttribute TextAttribute::StripErroneousVT16VersionsOfLegacyDefaults(const Te const auto bg{ attribute.GetBackground() }; auto copy{ attribute }; if (fg.IsIndex16() && - attribute.IsBold() == WI_IsFlagSet(s_legacyDefaultForeground, FOREGROUND_INTENSITY) && - fg.GetIndex() == (s_legacyDefaultForeground & ~FOREGROUND_INTENSITY)) + attribute.IsBold() == WI_IsFlagSet(s_ansiDefaultForeground, FOREGROUND_INTENSITY) && + fg.GetIndex() == (s_ansiDefaultForeground & ~FOREGROUND_INTENSITY)) { // We don't want to turn 1;37m into 39m (or even 1;39m), as this was meant to mimic a legacy color. copy.SetDefaultForeground(); } - if (bg.IsIndex16() && bg.GetIndex() == s_legacyDefaultBackground) + if (bg.IsIndex16() && bg.GetIndex() == s_ansiDefaultBackground) { copy.SetDefaultBackground(); } diff --git a/src/buffer/out/TextAttribute.hpp b/src/buffer/out/TextAttribute.hpp index 00f8a2266..e973a9cd3 100644 --- a/src/buffer/out/TextAttribute.hpp +++ b/src/buffer/out/TextAttribute.hpp @@ -41,8 +41,8 @@ public: explicit constexpr TextAttribute(const WORD wLegacyAttr) noexcept : _wAttrLegacy{ gsl::narrow_cast(wLegacyAttr & META_ATTRS) }, - _foreground{ s_LegacyIndexOrDefault(wLegacyAttr & FG_ATTRS, s_legacyDefaultForeground) }, - _background{ s_LegacyIndexOrDefault((wLegacyAttr & BG_ATTRS) >> 4, s_legacyDefaultBackground) }, + _foreground{ gsl::at(s_legacyForegroundColorMap, wLegacyAttr & FG_ATTRS) }, + _background{ gsl::at(s_legacyBackgroundColorMap, (wLegacyAttr & BG_ATTRS) >> 4) }, _extendedAttrs{ ExtendedAttributes::Normal }, _hyperlinkId{ 0 } { @@ -167,13 +167,8 @@ public: } private: - static constexpr TextColor s_LegacyIndexOrDefault(const BYTE requestedIndex, const BYTE defaultIndex) - { - return requestedIndex == defaultIndex ? TextColor{} : TextColor{ requestedIndex, true }; - } - - static BYTE s_legacyDefaultForeground; - static BYTE s_legacyDefaultBackground; + static std::array s_legacyForegroundColorMap; + static std::array s_legacyBackgroundColorMap; uint16_t _wAttrLegacy; // sizeof: 2, alignof: 2 uint16_t _hyperlinkId; // sizeof: 2, alignof: 2 diff --git a/src/buffer/out/TextColor.cpp b/src/buffer/out/TextColor.cpp index 7c05dd200..88bc8657f 100644 --- a/src/buffer/out/TextColor.cpp +++ b/src/buffer/out/TextColor.cpp @@ -32,7 +32,7 @@ constexpr std::array CompressedRgbToIndex16 = { // A table mapping indexed colors from the 256-color palette, // down to one of the 16 colors in the legacy palette. constexpr std::array Index256ToIndex16 = { - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 0, 4, 2, 6, 1, 5, 3, 7, 8, 12, 10, 14, 9, 13, 11, 15, 0, 1, 1, 1, 9, 9, 2, 1, 1, 1, 1, 1, 2, 2, 3, 3, 3, 3, 2, 2, 11, 11, 3, 3, 10, 10, 11, 11, 11, 11, 10, 10, 10, 10, 11, 11, 5, 5, 5, 5, 1, 1, 8, 8, 1, 1, 9, 9, @@ -252,11 +252,7 @@ BYTE TextColor::GetLegacyIndex(const BYTE defaultIndex) const noexcept { return defaultIndex; } - else if (IsIndex16()) - { - return GetIndex(); - } - else if (IsIndex256()) + else if (IsIndex16() || IsIndex256()) { return til::at(Index256ToIndex16, GetIndex()); } diff --git a/src/buffer/out/TextColor.h b/src/buffer/out/TextColor.h index ad984702f..35b62ff65 100644 --- a/src/buffer/out/TextColor.h +++ b/src/buffer/out/TextColor.h @@ -48,6 +48,23 @@ enum class ColorType : BYTE struct TextColor { public: + static constexpr BYTE DARK_BLACK = 0; + static constexpr BYTE DARK_RED = 1; + static constexpr BYTE DARK_GREEN = 2; + static constexpr BYTE DARK_YELLOW = 3; + static constexpr BYTE DARK_BLUE = 4; + static constexpr BYTE DARK_MAGENTA = 5; + static constexpr BYTE DARK_CYAN = 6; + static constexpr BYTE DARK_WHITE = 7; + static constexpr BYTE BRIGHT_BLACK = 8; + static constexpr BYTE BRIGHT_RED = 9; + static constexpr BYTE BRIGHT_GREEN = 10; + static constexpr BYTE BRIGHT_YELLOW = 11; + static constexpr BYTE BRIGHT_BLUE = 12; + static constexpr BYTE BRIGHT_MAGENTA = 13; + static constexpr BYTE BRIGHT_CYAN = 14; + static constexpr BYTE BRIGHT_WHITE = 15; + constexpr TextColor() noexcept : _meta{ ColorType::IsDefault }, _red{ 0 }, @@ -96,6 +113,16 @@ public: COLORREF GetRGB() const noexcept; + static constexpr BYTE TransposeLegacyIndex(const size_t index) + { + // When converting a 16-color index in the legacy Windows order to or + // from an ANSI-compatible order, we need to swap the bits in positions + // 0 and 2. We do this by XORing the index with 00000101, but only if + // one (but not both) of those bit positions is set. + const auto oneBitSet = (index ^ (index >> 2)) & 1; + return gsl::narrow_cast(index ^ oneBitSet ^ (oneBitSet << 2)); + } + private: union { diff --git a/src/buffer/out/ut_textbuffer/TextAttributeTests.cpp b/src/buffer/out/ut_textbuffer/TextAttributeTests.cpp index 65aba47f7..1b61955bb 100644 --- a/src/buffer/out/ut_textbuffer/TextAttributeTests.cpp +++ b/src/buffer/out/ut_textbuffer/TextAttributeTests.cpp @@ -237,7 +237,7 @@ void TextAttributeTests::TestRoundtripDefaultColors() Log::Comment(L"Foreground legacy default index should map to default text color."); legacyAttribute = fgLegacyDefault | BACKGROUND_GREEN; textAttribute.SetDefaultForeground(); - textAttribute.SetIndexedBackground256(BACKGROUND_GREEN >> 4); + textAttribute.SetIndexedBackground256(TextColor::DARK_GREEN); VERIFY_ARE_EQUAL(textAttribute, TextAttribute{ legacyAttribute }); Log::Comment(L"Default foreground text color should map back to legacy default index."); @@ -245,7 +245,7 @@ void TextAttributeTests::TestRoundtripDefaultColors() Log::Comment(L"Background legacy default index should map to default text color."); legacyAttribute = FOREGROUND_GREEN | bgLegacyDefault; - textAttribute.SetIndexedForeground256(FOREGROUND_GREEN); + textAttribute.SetIndexedForeground256(TextColor::DARK_GREEN); textAttribute.SetDefaultBackground(); VERIFY_ARE_EQUAL(textAttribute, TextAttribute{ legacyAttribute }); @@ -288,7 +288,7 @@ void TextAttributeTests::TestBoldAsBright() VERIFY_ARE_EQUAL(std::make_pair(_defaultFg, _defaultBg), attr.CalculateRgbColors(_colorTable, _defaultFg, _defaultBg, false, false, true)); VERIFY_ARE_EQUAL(std::make_pair(_defaultFg, _defaultBg), attr.CalculateRgbColors(_colorTable, _defaultFg, _defaultBg, false, false, false)); - attr.SetIndexedForeground(0); + attr.SetIndexedForeground(TextColor::DARK_BLACK); VERIFY_IS_TRUE(attr.IsBold()); Log::Comment(L"Foreground should be bright black when bold is bright is enabled"); @@ -297,7 +297,7 @@ void TextAttributeTests::TestBoldAsBright() Log::Comment(L"Foreground should be dark black when bold is bright is disabled"); VERIFY_ARE_EQUAL(std::make_pair(darkBlack, _defaultBg), attr.CalculateRgbColors(_colorTable, _defaultFg, _defaultBg, false, false, false)); - attr.SetIndexedBackground(2); + attr.SetIndexedBackground(TextColor::DARK_GREEN); VERIFY_IS_TRUE(attr.IsBold()); Log::Comment(L"background should be unaffected by 'bold is bright'"); @@ -312,7 +312,7 @@ void TextAttributeTests::TestBoldAsBright() Log::Comment(L"When set to a bright color, and bold, 'bold is bright' changes nothing"); attr.SetBold(true); - attr.SetIndexedForeground(8); + attr.SetIndexedForeground(TextColor::BRIGHT_BLACK); VERIFY_IS_TRUE(attr.IsBold()); VERIFY_ARE_EQUAL(std::make_pair(brightBlack, darkGreen), attr.CalculateRgbColors(_colorTable, _defaultFg, _defaultBg, false, false, true)); VERIFY_ARE_EQUAL(std::make_pair(brightBlack, darkGreen), attr.CalculateRgbColors(_colorTable, _defaultFg, _defaultBg, false, false, false)); diff --git a/src/cascadia/LocalTests_SettingsModel/ColorSchemeTests.cpp b/src/cascadia/LocalTests_SettingsModel/ColorSchemeTests.cpp index 85a9dd34a..682bee5f2 100644 --- a/src/cascadia/LocalTests_SettingsModel/ColorSchemeTests.cpp +++ b/src/cascadia/LocalTests_SettingsModel/ColorSchemeTests.cpp @@ -80,7 +80,7 @@ namespace SettingsModelLocalTests std::array expectedCampbellTable; const auto campbellSpan = gsl::make_span(expectedCampbellTable); - Utils::InitializeCampbellColorTable(campbellSpan); + Utils::InitializeColorTable(campbellSpan); Utils::SetColorTableAlpha(campbellSpan, 0); for (size_t i = 0; i < expectedCampbellTable.size(); i++) diff --git a/src/cascadia/TerminalCore/Terminal.cpp b/src/cascadia/TerminalCore/Terminal.cpp index 3433b60d9..c12a02f6d 100644 --- a/src/cascadia/TerminalCore/Terminal.cpp +++ b/src/cascadia/TerminalCore/Terminal.cpp @@ -1210,9 +1210,7 @@ try { const gsl::span tableView = { _colorTable.data(), _colorTable.size() }; // First set up the basic 256 colors - Utils::Initialize256ColorTable(tableView); - // Then use fill the first 16 values with the Campbell scheme - Utils::InitializeCampbellColorTable(tableView); + Utils::InitializeColorTable(tableView); // Then make sure all the values have an alpha of 255 Utils::SetColorTableAlpha(tableView, 0xff); } diff --git a/src/cascadia/TerminalCore/TerminalDispatchGraphics.cpp b/src/cascadia/TerminalCore/TerminalDispatchGraphics.cpp index c70d61b05..3f34e768c 100644 --- a/src/cascadia/TerminalCore/TerminalDispatchGraphics.cpp +++ b/src/cascadia/TerminalCore/TerminalDispatchGraphics.cpp @@ -7,29 +7,6 @@ using namespace Microsoft::Console::VirtualTerminal; using namespace Microsoft::Console::VirtualTerminal::DispatchTypes; -// clang-format off -const BYTE RED_ATTR = 0x01; -const BYTE GREEN_ATTR = 0x02; -const BYTE BLUE_ATTR = 0x04; -const BYTE BRIGHT_ATTR = 0x08; -const BYTE DARK_BLACK = 0; -const BYTE DARK_RED = RED_ATTR; -const BYTE DARK_GREEN = GREEN_ATTR; -const BYTE DARK_YELLOW = RED_ATTR | GREEN_ATTR; -const BYTE DARK_BLUE = BLUE_ATTR; -const BYTE DARK_MAGENTA = RED_ATTR | BLUE_ATTR; -const BYTE DARK_CYAN = GREEN_ATTR | BLUE_ATTR; -const BYTE DARK_WHITE = RED_ATTR | GREEN_ATTR | BLUE_ATTR; -const BYTE BRIGHT_BLACK = BRIGHT_ATTR; -const BYTE BRIGHT_RED = BRIGHT_ATTR | RED_ATTR; -const BYTE BRIGHT_GREEN = BRIGHT_ATTR | GREEN_ATTR; -const BYTE BRIGHT_YELLOW = BRIGHT_ATTR | RED_ATTR | GREEN_ATTR; -const BYTE BRIGHT_BLUE = BRIGHT_ATTR | BLUE_ATTR; -const BYTE BRIGHT_MAGENTA = BRIGHT_ATTR | RED_ATTR | BLUE_ATTR; -const BYTE BRIGHT_CYAN = BRIGHT_ATTR | GREEN_ATTR | BLUE_ATTR; -const BYTE BRIGHT_WHITE = BRIGHT_ATTR | RED_ATTR | GREEN_ATTR | BLUE_ATTR; -// clang-format on - // Routine Description: // - Helper to parse extended graphics options, which start with 38 (FG) or 48 (BG) // These options are followed by either a 2 (RGB) or 5 (xterm index) @@ -169,100 +146,100 @@ bool TerminalDispatch::SetGraphicsRendition(const VTParameters options) noexcept attr.SetOverlined(false); break; case ForegroundBlack: - attr.SetIndexedForeground(DARK_BLACK); + attr.SetIndexedForeground(TextColor::DARK_BLACK); break; case ForegroundBlue: - attr.SetIndexedForeground(DARK_BLUE); + attr.SetIndexedForeground(TextColor::DARK_BLUE); break; case ForegroundGreen: - attr.SetIndexedForeground(DARK_GREEN); + attr.SetIndexedForeground(TextColor::DARK_GREEN); break; case ForegroundCyan: - attr.SetIndexedForeground(DARK_CYAN); + attr.SetIndexedForeground(TextColor::DARK_CYAN); break; case ForegroundRed: - attr.SetIndexedForeground(DARK_RED); + attr.SetIndexedForeground(TextColor::DARK_RED); break; case ForegroundMagenta: - attr.SetIndexedForeground(DARK_MAGENTA); + attr.SetIndexedForeground(TextColor::DARK_MAGENTA); break; case ForegroundYellow: - attr.SetIndexedForeground(DARK_YELLOW); + attr.SetIndexedForeground(TextColor::DARK_YELLOW); break; case ForegroundWhite: - attr.SetIndexedForeground(DARK_WHITE); + attr.SetIndexedForeground(TextColor::DARK_WHITE); break; case BackgroundBlack: - attr.SetIndexedBackground(DARK_BLACK); + attr.SetIndexedBackground(TextColor::DARK_BLACK); break; case BackgroundBlue: - attr.SetIndexedBackground(DARK_BLUE); + attr.SetIndexedBackground(TextColor::DARK_BLUE); break; case BackgroundGreen: - attr.SetIndexedBackground(DARK_GREEN); + attr.SetIndexedBackground(TextColor::DARK_GREEN); break; case BackgroundCyan: - attr.SetIndexedBackground(DARK_CYAN); + attr.SetIndexedBackground(TextColor::DARK_CYAN); break; case BackgroundRed: - attr.SetIndexedBackground(DARK_RED); + attr.SetIndexedBackground(TextColor::DARK_RED); break; case BackgroundMagenta: - attr.SetIndexedBackground(DARK_MAGENTA); + attr.SetIndexedBackground(TextColor::DARK_MAGENTA); break; case BackgroundYellow: - attr.SetIndexedBackground(DARK_YELLOW); + attr.SetIndexedBackground(TextColor::DARK_YELLOW); break; case BackgroundWhite: - attr.SetIndexedBackground(DARK_WHITE); + attr.SetIndexedBackground(TextColor::DARK_WHITE); break; case BrightForegroundBlack: - attr.SetIndexedForeground(BRIGHT_BLACK); + attr.SetIndexedForeground(TextColor::BRIGHT_BLACK); break; case BrightForegroundBlue: - attr.SetIndexedForeground(BRIGHT_BLUE); + attr.SetIndexedForeground(TextColor::BRIGHT_BLUE); break; case BrightForegroundGreen: - attr.SetIndexedForeground(BRIGHT_GREEN); + attr.SetIndexedForeground(TextColor::BRIGHT_GREEN); break; case BrightForegroundCyan: - attr.SetIndexedForeground(BRIGHT_CYAN); + attr.SetIndexedForeground(TextColor::BRIGHT_CYAN); break; case BrightForegroundRed: - attr.SetIndexedForeground(BRIGHT_RED); + attr.SetIndexedForeground(TextColor::BRIGHT_RED); break; case BrightForegroundMagenta: - attr.SetIndexedForeground(BRIGHT_MAGENTA); + attr.SetIndexedForeground(TextColor::BRIGHT_MAGENTA); break; case BrightForegroundYellow: - attr.SetIndexedForeground(BRIGHT_YELLOW); + attr.SetIndexedForeground(TextColor::BRIGHT_YELLOW); break; case BrightForegroundWhite: - attr.SetIndexedForeground(BRIGHT_WHITE); + attr.SetIndexedForeground(TextColor::BRIGHT_WHITE); break; case BrightBackgroundBlack: - attr.SetIndexedBackground(BRIGHT_BLACK); + attr.SetIndexedBackground(TextColor::BRIGHT_BLACK); break; case BrightBackgroundBlue: - attr.SetIndexedBackground(BRIGHT_BLUE); + attr.SetIndexedBackground(TextColor::BRIGHT_BLUE); break; case BrightBackgroundGreen: - attr.SetIndexedBackground(BRIGHT_GREEN); + attr.SetIndexedBackground(TextColor::BRIGHT_GREEN); break; case BrightBackgroundCyan: - attr.SetIndexedBackground(BRIGHT_CYAN); + attr.SetIndexedBackground(TextColor::BRIGHT_CYAN); break; case BrightBackgroundRed: - attr.SetIndexedBackground(BRIGHT_RED); + attr.SetIndexedBackground(TextColor::BRIGHT_RED); break; case BrightBackgroundMagenta: - attr.SetIndexedBackground(BRIGHT_MAGENTA); + attr.SetIndexedBackground(TextColor::BRIGHT_MAGENTA); break; case BrightBackgroundYellow: - attr.SetIndexedBackground(BRIGHT_YELLOW); + attr.SetIndexedBackground(TextColor::BRIGHT_YELLOW); break; case BrightBackgroundWhite: - attr.SetIndexedBackground(BRIGHT_WHITE); + attr.SetIndexedBackground(TextColor::BRIGHT_WHITE); break; case ForegroundExtended: i += _SetRgbColorsHelper(options.subspan(i + 1), attr, true); diff --git a/src/cascadia/UnitTests_TerminalCore/ConptyRoundtripTests.cpp b/src/cascadia/UnitTests_TerminalCore/ConptyRoundtripTests.cpp index fe671a65a..2145032fd 100644 --- a/src/cascadia/UnitTests_TerminalCore/ConptyRoundtripTests.cpp +++ b/src/cascadia/UnitTests_TerminalCore/ConptyRoundtripTests.cpp @@ -2901,15 +2901,9 @@ void ConptyRoundtripTests::ResizeInitializeBufferWithDefaultAttrs() auto defaultAttrs = si.GetAttributes(); auto conhostGreenAttrs = TextAttribute(); - - // Conhost and Terminal store attributes in different bits. - // conhostGreenAttrs.SetIndexedAttributes(std::nullopt, - // { static_cast(FOREGROUND_GREEN) }); - conhostGreenAttrs.SetIndexedBackground(FOREGROUND_GREEN); + conhostGreenAttrs.SetIndexedBackground(TextColor::DARK_GREEN); auto terminalGreenAttrs = TextAttribute(); - // terminalGreenAttrs.SetIndexedAttributes(std::nullopt, - // { static_cast(XTERM_GREEN_ATTR) }); - terminalGreenAttrs.SetIndexedBackground(XTERM_GREEN_ATTR); + terminalGreenAttrs.SetIndexedBackground(TextColor::DARK_GREEN); // Use an initial ^[[m to start printing with default-on-default sm.ProcessString(L"\x1b[m"); @@ -2942,7 +2936,7 @@ void ConptyRoundtripTests::ResizeInitializeBufferWithDefaultAttrs() auto verifyBuffer = [&](const TextBuffer& tb, const til::rectangle viewport, const bool isTerminal, const bool afterResize) { const auto width = viewport.width(); - // Conhost and Terminal store attributes in different bits. + // Conhost and Terminal attributes are potentially different. const auto greenAttrs = isTerminal ? terminalGreenAttrs : conhostGreenAttrs; for (short row = 0; row < tb.GetSize().Height(); row++) @@ -3034,13 +3028,11 @@ void ConptyRoundtripTests::NewLinesAtBottomWithBackground() auto defaultAttrs = si.GetAttributes(); auto conhostBlueAttrs = defaultAttrs; - - // Conhost and Terminal store attributes in different bits. - conhostBlueAttrs.SetIndexedForeground(FOREGROUND_GREEN); - conhostBlueAttrs.SetIndexedBackground(FOREGROUND_BLUE); + conhostBlueAttrs.SetIndexedForeground(TextColor::DARK_GREEN); + conhostBlueAttrs.SetIndexedBackground(TextColor::DARK_BLUE); auto terminalBlueAttrs = TextAttribute(); - terminalBlueAttrs.SetIndexedForeground(XTERM_GREEN_ATTR); - terminalBlueAttrs.SetIndexedBackground(XTERM_BLUE_ATTR); + terminalBlueAttrs.SetIndexedForeground(TextColor::DARK_GREEN); + terminalBlueAttrs.SetIndexedBackground(TextColor::DARK_BLUE); // We're going to print 4 more rows than the entire height of the viewport, // causing the buffer to circle 4 times. This is 2 extra iterations of the @@ -3083,7 +3075,7 @@ void ConptyRoundtripTests::NewLinesAtBottomWithBackground() const auto width = viewport.width(); const auto isTerminal = viewport.top() != 0; - // Conhost and Terminal store attributes in different bits. + // Conhost and Terminal attributes are potentially different. const auto blueAttrs = isTerminal ? terminalBlueAttrs : conhostBlueAttrs; for (short row = 0; row < viewport.bottom() - 2; row++) diff --git a/src/host/conattrs.cpp b/src/host/conattrs.cpp deleted file mode 100644 index 07d1f21f2..000000000 --- a/src/host/conattrs.cpp +++ /dev/null @@ -1,52 +0,0 @@ -/*++ -Copyright (c) Microsoft Corporation -Licensed under the MIT license. - -Module Name: -- conattrs.cpp - -Abstract: -- Defines common operations on console attributes, especially in regards to - finding the nearest color from a color table. - -Author(s): -- Mike Griese (migrie) 01-Sept-2017 ---*/ - -#include "precomp.h" -#include "../inc/conattrs.hpp" -#include - -// Function Description: -// - Converts the value of a xterm color table index to the windows color table equivalent. -// Arguments: -// - xtermTableEntry: the xterm color table index -// Return Value: -// - The windows color table equivalent. -WORD XtermToWindowsIndex(const size_t xtermTableEntry) noexcept -{ - const bool fRed = WI_IsFlagSet(xtermTableEntry, XTERM_RED_ATTR); - const bool fGreen = WI_IsFlagSet(xtermTableEntry, XTERM_GREEN_ATTR); - const bool fBlue = WI_IsFlagSet(xtermTableEntry, XTERM_BLUE_ATTR); - const bool fBright = WI_IsFlagSet(xtermTableEntry, XTERM_BRIGHT_ATTR); - - return (fRed ? WINDOWS_RED_ATTR : 0x0) + - (fGreen ? WINDOWS_GREEN_ATTR : 0x0) + - (fBlue ? WINDOWS_BLUE_ATTR : 0x0) + - (fBright ? WINDOWS_BRIGHT_ATTR : 0x0); -} - -// Function Description: -// - Converts the value of a xterm color table index to the windows color table -// equivalent. The range of values is [0, 255], where the lowest 16 are -// mapped to the equivalent Windows index, and the rest of the values are -// passed through. -// Arguments: -// - xtermTableEntry: the xterm color table index -// Return Value: -// - The windows color table equivalent. -WORD Xterm256ToWindowsIndex(const size_t xtermTableEntry) noexcept -{ - return xtermTableEntry < 16 ? XtermToWindowsIndex(xtermTableEntry) : - static_cast(xtermTableEntry); -} diff --git a/src/host/consoleInformation.cpp b/src/host/consoleInformation.cpp index 112905921..51ed7de9b 100644 --- a/src/host/consoleInformation.cpp +++ b/src/host/consoleInformation.cpp @@ -231,7 +231,7 @@ InputBuffer* const CONSOLE_INFORMATION::GetActiveInputBuffer() const COLORREF CONSOLE_INFORMATION::GetDefaultForeground() const noexcept { const auto fg = GetDefaultForegroundColor(); - return fg != INVALID_COLOR ? fg : GetColorTableEntry(LOBYTE(GetFillAttribute()) & FG_ATTRS); + return fg != INVALID_COLOR ? fg : GetLegacyColorTableEntry(LOBYTE(GetFillAttribute()) & FG_ATTRS); } // Method Description: @@ -246,23 +246,37 @@ COLORREF CONSOLE_INFORMATION::GetDefaultForeground() const noexcept COLORREF CONSOLE_INFORMATION::GetDefaultBackground() const noexcept { const auto bg = GetDefaultBackgroundColor(); - return bg != INVALID_COLOR ? bg : GetColorTableEntry((LOBYTE(GetFillAttribute()) & BG_ATTRS) >> 4); + return bg != INVALID_COLOR ? bg : GetLegacyColorTableEntry((LOBYTE(GetFillAttribute()) & BG_ATTRS) >> 4); } // Method Description: // - Get the colors of a particular text attribute, using our color table, // and our configured default attributes. // Arguments: -// - attr: the TextAttribute to retrieve the foreground color of. +// - attr: the TextAttribute to retrieve the foreground and background color of. // Return Value: // - The color values of the attribute's foreground and background. std::pair CONSOLE_INFORMATION::LookupAttributeColors(const TextAttribute& attr) const noexcept +{ + return LookupAttributeColors(attr, GetDefaultForeground(), GetDefaultBackground()); +} + +// Method Description: +// - Get the colors of a particular text attribute, using our color table, +// and the given default color values. +// Arguments: +// - attr: the TextAttribute to retrieve the foreground and background color of. +// - defaultFg: the COLORREF to use for a default foreground color. +// - defaultBg: the COLORREF to use for a default background color. +// Return Value: +// - The color values of the attribute's foreground and background. +std::pair CONSOLE_INFORMATION::LookupAttributeColors(const TextAttribute& attr, const COLORREF defaultFg, const COLORREF defaultBg) const noexcept { _blinkingState.RecordBlinkingUsage(attr); return attr.CalculateRgbColors( GetColorTable(), - GetDefaultForeground(), - GetDefaultBackground(), + defaultFg, + defaultBg, IsScreenReversed(), _blinkingState.IsBlinkingFaint()); } diff --git a/src/host/getset.cpp b/src/host/getset.cpp index 6203aef0e..4f85d4a5b 100644 --- a/src/host/getset.cpp +++ b/src/host/getset.cpp @@ -605,7 +605,7 @@ void ApiRoutines::GetLargestConsoleWindowSizeImpl(const SCREEN_INFORMATION& cont for (size_t i = 0; i < std::size(data.ColorTable); i++) { - gci.SetColorTableEntry(i, data.ColorTable[i]); + gci.SetLegacyColorTableEntry(i, data.ColorTable[i]); } context.SetDefaultAttributes(TextAttribute{ data.wAttributes }, TextAttribute{ data.wPopupAttributes }); @@ -1978,7 +1978,7 @@ void DoSrvPrivateMoveToBottom(SCREEN_INFORMATION& screenInfo) Globals& g = ServiceLocator::LocateGlobals(); CONSOLE_INFORMATION& gci = g.getConsoleInformation(); - value = gci.GetColorTableEntry(::Xterm256ToWindowsIndex(index)); + value = gci.GetColorTableEntry(index); return S_OK; } @@ -2004,7 +2004,7 @@ void DoSrvPrivateMoveToBottom(SCREEN_INFORMATION& screenInfo) Globals& g = ServiceLocator::LocateGlobals(); CONSOLE_INFORMATION& gci = g.getConsoleInformation(); - gci.SetColorTableEntry(::Xterm256ToWindowsIndex(index), value); + gci.SetColorTableEntry(index, value); // Update the screen colors if we're not a pty // No need to force a redraw in pty mode. diff --git a/src/host/host-common.vcxitems b/src/host/host-common.vcxitems index 190eef792..7645ced09 100644 --- a/src/host/host-common.vcxitems +++ b/src/host/host-common.vcxitems @@ -7,7 +7,6 @@ - diff --git a/src/host/lib/hostlib.vcxproj.filters b/src/host/lib/hostlib.vcxproj.filters index e8877f96c..11256b620 100644 --- a/src/host/lib/hostlib.vcxproj.filters +++ b/src/host/lib/hostlib.vcxproj.filters @@ -138,9 +138,6 @@ Source Files - - Source Files - Source Files diff --git a/src/host/registry.cpp b/src/host/registry.cpp index 9b022d983..49bd06423 100644 --- a/src/host/registry.cpp +++ b/src/host/registry.cpp @@ -310,7 +310,7 @@ void Registry::LoadFromRegistry(_In_ PCWSTR const pwszConsoleTitle) nullptr); if (NT_SUCCESS(Status)) { - _pSettings->SetColorTableEntry(i, dwValue); + _pSettings->SetLegacyColorTableEntry(i, dwValue); } } diff --git a/src/host/renderData.cpp b/src/host/renderData.cpp index c860b3da3..1eb6090d7 100644 --- a/src/host/renderData.cpp +++ b/src/host/renderData.cpp @@ -110,6 +110,8 @@ void RenderData::UnlockConsole() noexcept const TextAttribute RenderData::GetDefaultBrushColors() noexcept { const CONSOLE_INFORMATION& gci = ServiceLocator::LocateGlobals().getConsoleInformation(); + _defaultForeground = gci.GetDefaultForeground(); + _defaultBackground = gci.GetDefaultBackground(); return gci.GetActiveOutputBuffer().GetAttributes(); } @@ -362,7 +364,7 @@ const std::vector RenderData::GetPatternId(const COORD /*location*/) con std::pair RenderData::GetAttributeColors(const TextAttribute& attr) const noexcept { const CONSOLE_INFORMATION& gci = ServiceLocator::LocateGlobals().getConsoleInformation(); - return gci.LookupAttributeColors(attr); + return gci.LookupAttributeColors(attr, _defaultForeground, _defaultBackground); } #pragma endregion diff --git a/src/host/renderData.hpp b/src/host/renderData.hpp index b1699531d..9b5ab7f6d 100644 --- a/src/host/renderData.hpp +++ b/src/host/renderData.hpp @@ -15,6 +15,7 @@ Author(s): #pragma once #include "../renderer/inc/IRenderData.hpp" +#include "../types/inc/colorTable.hpp" #include "../types/IUiaData.h" class RenderData final : @@ -71,4 +72,8 @@ public: void ColorSelection(const COORD coordSelectionStart, const COORD coordSelectionEnd, const TextAttribute attr); const bool IsUiaDataInitialized() const noexcept override { return true; } #pragma endregion + +private: + COLORREF _defaultForeground = gsl::at(Microsoft::Console::Utils::CampbellColorTable(), 7); + COLORREF _defaultBackground = gsl::at(Microsoft::Console::Utils::CampbellColorTable(), 0); }; diff --git a/src/host/screenInfo.cpp b/src/host/screenInfo.cpp index 320e1148d..cc06df4ca 100644 --- a/src/host/screenInfo.cpp +++ b/src/host/screenInfo.cpp @@ -364,7 +364,7 @@ void SCREEN_INFORMATION::GetScreenBufferInformation(_Out_ PCOORD pcoordSize, // the copy length must be constant for now to keep OACR happy with buffer overruns. for (size_t i = 0; i < COLOR_TABLE_SIZE; i++) { - lpColorTable[i] = gci.GetColorTableEntry(i); + lpColorTable[i] = gci.GetLegacyColorTableEntry(i); } *pcoordMaximumWindowSize = GetMaxWindowSizeInCharacters(); diff --git a/src/host/selectionInput.cpp b/src/host/selectionInput.cpp index 70b4d4f38..cab5aa88b 100644 --- a/src/host/selectionInput.cpp +++ b/src/host/selectionInput.cpp @@ -661,13 +661,15 @@ bool Selection::_HandleColorSelection(const INPUT_KEY_INFO* const pInputKeyInfo) if (fAltPressed || fCtrlPressed) { TextAttribute selectionAttr; - const BYTE colorIndex = gsl::narrow_cast(wVirtualKeyCode - '0' + 6); + // The key number corresponds to the Windows color table order, so the value + // need to be transposed to obtain the index in an ANSI-compatible order. + const auto colorIndex = TextColor::TransposeLegacyIndex(wVirtualKeyCode - '0' + 6); if (fCtrlPressed) { // Setting background color. Set fg color to black. selectionAttr.SetIndexedBackground256(colorIndex); - selectionAttr.SetIndexedForeground256(0); + selectionAttr.SetIndexedForeground256(TextColor::DARK_BLACK); } else { diff --git a/src/host/server.h b/src/host/server.h index 91ea54537..2d8fa0d15 100644 --- a/src/host/server.h +++ b/src/host/server.h @@ -127,6 +127,7 @@ public: COLORREF GetDefaultForeground() const noexcept; COLORREF GetDefaultBackground() const noexcept; std::pair LookupAttributeColors(const TextAttribute& attr) const noexcept; + std::pair LookupAttributeColors(const TextAttribute& attr, const COLORREF defaultFg, const COLORREF defaultBg) const noexcept; void SetTitle(const std::wstring_view newTitle); void SetTitlePrefix(const std::wstring_view newTitlePrefix); diff --git a/src/host/settings.cpp b/src/host/settings.cpp index a9fb5d093..d1443cb32 100644 --- a/src/host/settings.cpp +++ b/src/host/settings.cpp @@ -82,8 +82,7 @@ Settings::Settings() : _CursorType = CursorType::Legacy; gsl::span tableView = { _colorTable.data(), _colorTable.size() }; - ::Microsoft::Console::Utils::Initialize256ColorTable(tableView); - ::Microsoft::Console::Utils::InitializeCampbellColorTableForConhost(tableView); + ::Microsoft::Console::Utils::InitializeColorTable(tableView); } // Routine Description: @@ -122,8 +121,8 @@ void Settings::ApplyDesktopSpecificDefaults() _uNumberOfHistoryBuffers = 4; _bHistoryNoDup = FALSE; - gsl::span tableView = { _colorTable.data(), _colorTable.size() }; - ::Microsoft::Console::Utils::InitializeCampbellColorTableForConhost(tableView); + gsl::span tableView = { _colorTable.data(), 16 }; + ::Microsoft::Console::Utils::InitializeColorTable(tableView); _fTrimLeadingZeros = false; _fEnableColorSelection = false; @@ -222,7 +221,7 @@ void Settings::InitFromStateInfo(_In_ PCONSOLE_STATE_INFO pStateInfo) _uNumberOfHistoryBuffers = pStateInfo->NumberOfHistoryBuffers; for (size_t i = 0; i < std::size(pStateInfo->ColorTable); i++) { - SetColorTableEntry(i, pStateInfo->ColorTable[i]); + SetLegacyColorTableEntry(i, pStateInfo->ColorTable[i]); } _uCodePage = pStateInfo->CodePage; _bWrapText = !!pStateInfo->fWrapText; @@ -267,7 +266,7 @@ CONSOLE_STATE_INFO Settings::CreateConsoleStateInfo() const csi.NumberOfHistoryBuffers = _uNumberOfHistoryBuffers; for (size_t i = 0; i < std::size(csi.ColorTable); i++) { - csi.ColorTable[i] = GetColorTableEntry(i); + csi.ColorTable[i] = GetLegacyColorTableEntry(i); } csi.CodePage = _uCodePage; csi.fWrapText = !!_bWrapText; @@ -726,11 +725,6 @@ void Settings::SetHistoryNoDup(const bool bHistoryNoDup) _bHistoryNoDup = bHistoryNoDup; } -void Settings::SetColorTableEntry(const size_t index, const COLORREF ColorValue) -{ - _colorTable.at(index) = ColorValue; -} - bool Settings::IsStartupTitleIsLinkNameSet() const { return WI_IsFlagSet(_dwStartupFlags, STARTF_TITLEISLINKNAME); @@ -746,11 +740,26 @@ void Settings::UnsetStartupFlag(const DWORD dwFlagToUnset) _dwStartupFlags &= ~dwFlagToUnset; } +void Settings::SetColorTableEntry(const size_t index, const COLORREF ColorValue) +{ + _colorTable.at(index) = ColorValue; +} + COLORREF Settings::GetColorTableEntry(const size_t index) const { return _colorTable.at(index); } +void Settings::SetLegacyColorTableEntry(const size_t index, const COLORREF ColorValue) +{ + _colorTable.at(TextColor::TransposeLegacyIndex(index)) = ColorValue; +} + +COLORREF Settings::GetLegacyColorTableEntry(const size_t index) const +{ + return _colorTable.at(TextColor::TransposeLegacyIndex(index)); +} + COLORREF Settings::GetCursorColor() const noexcept { return _CursorColor; diff --git a/src/host/settings.hpp b/src/host/settings.hpp index e8468da6b..896de0e20 100644 --- a/src/host/settings.hpp +++ b/src/host/settings.hpp @@ -167,6 +167,8 @@ public: void SetColorTableEntry(const size_t index, const COLORREF ColorValue); COLORREF GetColorTableEntry(const size_t index) const; + void SetLegacyColorTableEntry(const size_t index, const COLORREF ColorValue); + COLORREF GetLegacyColorTableEntry(const size_t index) const; COLORREF GetCursorColor() const noexcept; CursorType GetCursorType() const noexcept; diff --git a/src/host/sources.inc b/src/host/sources.inc index 3ee3b70c3..700fda72a 100644 --- a/src/host/sources.inc +++ b/src/host/sources.inc @@ -89,7 +89,6 @@ SOURCES = \ ..\utf8ToWideCharParser.cpp \ ..\conareainfo.cpp \ ..\conimeinfo.cpp \ - ..\conattrs.cpp \ ..\ConsoleArguments.cpp \ ..\CommandNumberPopup.cpp \ ..\CommandListPopup.cpp \ diff --git a/src/host/ut_host/ScreenBufferTests.cpp b/src/host/ut_host/ScreenBufferTests.cpp index 0e31c2b32..83ba0c502 100644 --- a/src/host/ut_host/ScreenBufferTests.cpp +++ b/src/host/ut_host/ScreenBufferTests.cpp @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Corporation. +// Copyright (c) Microsoft Corporation. // Licensed under the MIT license. #include "precomp.h" @@ -1634,74 +1634,74 @@ void ScreenBufferTests::VtSetColorTable() L"Process some valid sequences for setting the table")); stateMachine.ProcessString(L"\x1b]4;0;rgb:1/1/1\x7"); - VERIFY_ARE_EQUAL(RGB(0x11, 0x11, 0x11), gci.GetColorTableEntry(::XtermToWindowsIndex(0))); + VERIFY_ARE_EQUAL(RGB(0x11, 0x11, 0x11), gci.GetColorTableEntry(0)); stateMachine.ProcessString(L"\x1b]4;1;rgb:1/23/1\x7"); - VERIFY_ARE_EQUAL(RGB(0x11, 0x23, 0x11), gci.GetColorTableEntry(::XtermToWindowsIndex(1))); + VERIFY_ARE_EQUAL(RGB(0x11, 0x23, 0x11), gci.GetColorTableEntry(1)); stateMachine.ProcessString(L"\x1b]4;2;rgb:1/23/12\x7"); - VERIFY_ARE_EQUAL(RGB(0x11, 0x23, 0x12), gci.GetColorTableEntry(::XtermToWindowsIndex(2))); + VERIFY_ARE_EQUAL(RGB(0x11, 0x23, 0x12), gci.GetColorTableEntry(2)); stateMachine.ProcessString(L"\x1b]4;3;rgb:12/23/12\x7"); - VERIFY_ARE_EQUAL(RGB(0x12, 0x23, 0x12), gci.GetColorTableEntry(::XtermToWindowsIndex(3))); + VERIFY_ARE_EQUAL(RGB(0x12, 0x23, 0x12), gci.GetColorTableEntry(3)); stateMachine.ProcessString(L"\x1b]4;4;rgb:ff/a1/1b\x7"); - VERIFY_ARE_EQUAL(RGB(0xff, 0xa1, 0x1b), gci.GetColorTableEntry(::XtermToWindowsIndex(4))); + VERIFY_ARE_EQUAL(RGB(0xff, 0xa1, 0x1b), gci.GetColorTableEntry(4)); stateMachine.ProcessString(L"\x1b]4;5;rgb:ff/a1/1b\x1b\\"); - VERIFY_ARE_EQUAL(RGB(0xff, 0xa1, 0x1b), gci.GetColorTableEntry(::XtermToWindowsIndex(5))); + VERIFY_ARE_EQUAL(RGB(0xff, 0xa1, 0x1b), gci.GetColorTableEntry(5)); Log::Comment(NoThrowString().Format( L"Try a bunch of invalid sequences.")); Log::Comment(NoThrowString().Format( L"First start by setting an entry to a known value to compare to.")); stateMachine.ProcessString(L"\x1b]4;5;rgb:09/09/09\x1b\\"); - VERIFY_ARE_EQUAL(RGB(9, 9, 9), gci.GetColorTableEntry(::XtermToWindowsIndex(5))); + VERIFY_ARE_EQUAL(RGB(9, 9, 9), gci.GetColorTableEntry(5)); Log::Comment(NoThrowString().Format( L"invalid: Missing the first component")); stateMachine.ProcessString(L"\x1b]4;5;rgb:/1/1\x1b\\"); - VERIFY_ARE_EQUAL(RGB(9, 9, 9), gci.GetColorTableEntry(::XtermToWindowsIndex(5))); + VERIFY_ARE_EQUAL(RGB(9, 9, 9), gci.GetColorTableEntry(5)); Log::Comment(NoThrowString().Format( L"invalid: too many components")); stateMachine.ProcessString(L"\x1b]4;5;rgb:1/1/1/1\x1b\\"); - VERIFY_ARE_EQUAL(RGB(9, 9, 9), gci.GetColorTableEntry(::XtermToWindowsIndex(5))); + VERIFY_ARE_EQUAL(RGB(9, 9, 9), gci.GetColorTableEntry(5)); Log::Comment(NoThrowString().Format( L"invalid: no second component")); stateMachine.ProcessString(L"\x1b]4;5;rgb:1//1\x1b\\"); - VERIFY_ARE_EQUAL(RGB(9, 9, 9), gci.GetColorTableEntry(::XtermToWindowsIndex(5))); + VERIFY_ARE_EQUAL(RGB(9, 9, 9), gci.GetColorTableEntry(5)); Log::Comment(NoThrowString().Format( L"invalid: no components")); stateMachine.ProcessString(L"\x1b]4;5;rgb://\x1b\\"); - VERIFY_ARE_EQUAL(RGB(9, 9, 9), gci.GetColorTableEntry(::XtermToWindowsIndex(5))); + VERIFY_ARE_EQUAL(RGB(9, 9, 9), gci.GetColorTableEntry(5)); Log::Comment(NoThrowString().Format( L"invalid: no third component")); stateMachine.ProcessString(L"\x1b]4;5;rgb:1/11/\x1b\\"); - VERIFY_ARE_EQUAL(RGB(9, 9, 9), gci.GetColorTableEntry(::XtermToWindowsIndex(5))); + VERIFY_ARE_EQUAL(RGB(9, 9, 9), gci.GetColorTableEntry(5)); Log::Comment(NoThrowString().Format( L"invalid: rgbi is not a supported color space")); stateMachine.ProcessString(L"\x1b]4;5;rgbi:1/1/1\x1b\\"); - VERIFY_ARE_EQUAL(RGB(9, 9, 9), gci.GetColorTableEntry(::XtermToWindowsIndex(5))); + VERIFY_ARE_EQUAL(RGB(9, 9, 9), gci.GetColorTableEntry(5)); Log::Comment(NoThrowString().Format( L"invalid: cmyk is not a supported color space")); stateMachine.ProcessString(L"\x1b]4;5;cmyk:1/1/1\x1b\\"); - VERIFY_ARE_EQUAL(RGB(9, 9, 9), gci.GetColorTableEntry(::XtermToWindowsIndex(5))); + VERIFY_ARE_EQUAL(RGB(9, 9, 9), gci.GetColorTableEntry(5)); Log::Comment(NoThrowString().Format( L"invalid: no table index should do nothing")); stateMachine.ProcessString(L"\x1b]4;;rgb:1/1/1\x1b\\"); - VERIFY_ARE_EQUAL(RGB(9, 9, 9), gci.GetColorTableEntry(::XtermToWindowsIndex(5))); + VERIFY_ARE_EQUAL(RGB(9, 9, 9), gci.GetColorTableEntry(5)); Log::Comment(NoThrowString().Format( L"invalid: need to specify a color space")); stateMachine.ProcessString(L"\x1b]4;5;1/1/1\x1b\\"); - VERIFY_ARE_EQUAL(RGB(9, 9, 9), gci.GetColorTableEntry(::XtermToWindowsIndex(5))); + VERIFY_ARE_EQUAL(RGB(9, 9, 9), gci.GetColorTableEntry(5)); } void ScreenBufferTests::ResizeTraditionalDoesNotDoubleFreeAttrRows() @@ -1912,8 +1912,8 @@ void ScreenBufferTests::VtEraseAllPersistCursorFillColor() L"The viewport should be full of dark_red on bright_blue")); auto expectedAttr = TextAttribute{}; - expectedAttr.SetIndexedForeground((BYTE)XtermToWindowsIndex(1)); - expectedAttr.SetIndexedBackground((BYTE)XtermToWindowsIndex(12)); + expectedAttr.SetIndexedForeground(TextColor::DARK_RED); + expectedAttr.SetIndexedBackground(TextColor::BRIGHT_BLUE); stateMachine.ProcessString(L"\x1b[31;104m"); VERIFY_ARE_EQUAL(expectedAttr, si.GetAttributes()); @@ -2256,8 +2256,8 @@ void ScreenBufferTests::SetDefaultsIndividuallyBothDefault() COLORREF magenta = RGB(255, 0, 255); COLORREF yellow = RGB(255, 255, 0); - COLORREF brightGreen = gci.GetColorTableEntry(::XtermToWindowsIndex(10)); - COLORREF darkBlue = gci.GetColorTableEntry(::XtermToWindowsIndex(4)); + COLORREF brightGreen = gci.GetColorTableEntry(TextColor::BRIGHT_GREEN); + COLORREF darkBlue = gci.GetColorTableEntry(TextColor::DARK_BLUE); gci.SetDefaultForegroundColor(yellow); gci.SetDefaultBackgroundColor(magenta); @@ -2292,8 +2292,8 @@ void ScreenBufferTests::SetDefaultsIndividuallyBothDefault() // See the log comment above for description of these values. TextAttribute expectedDefaults{}; TextAttribute expectedTwo; - expectedTwo.SetIndexedForeground((BYTE)XtermToWindowsIndex(10)); - expectedTwo.SetIndexedBackground((BYTE)XtermToWindowsIndex(4)); + expectedTwo.SetIndexedForeground(TextColor::BRIGHT_GREEN); + expectedTwo.SetIndexedBackground(TextColor::DARK_BLUE); TextAttribute expectedThree = expectedTwo; expectedThree.SetDefaultForeground(); // Four is the same as Defaults @@ -2705,7 +2705,7 @@ void ScreenBufferTests::SetGlobalColorTable() VERIFY_SUCCEEDED(mainBuffer.SetViewportOrigin(true, COORD({ 0, 0 }), true)); mainCursor.SetPosition({ 0, 0 }); - const COLORREF originalRed = gci.GetColorTableEntry(4); + const COLORREF originalRed = gci.GetColorTableEntry(TextColor::DARK_RED); const COLORREF testColor = RGB(0x11, 0x22, 0x33); VERIFY_ARE_NOT_EQUAL(originalRed, testColor); @@ -3209,10 +3209,10 @@ void ScreenBufferTests::DontResetColorsAboveVirtualBottom() L"cursor=%s", VerifyOutputTraits::ToString(cursor.GetPosition()).GetBuffer())); Log::Comment(NoThrowString().Format( L"viewport=%s", VerifyOutputTraits::ToString(si.GetViewport().ToInclusive()).GetBuffer())); - const auto darkRed = gci.GetColorTableEntry(::XtermToWindowsIndex(1)); - const auto darkBlue = gci.GetColorTableEntry(::XtermToWindowsIndex(4)); - const auto darkBlack = gci.GetColorTableEntry(::XtermToWindowsIndex(0)); - const auto darkWhite = gci.GetColorTableEntry(::XtermToWindowsIndex(7)); + const auto darkRed = gci.GetColorTableEntry(TextColor::DARK_RED); + const auto darkBlue = gci.GetColorTableEntry(TextColor::DARK_BLUE); + const auto darkBlack = gci.GetColorTableEntry(TextColor::DARK_BLACK); + const auto darkWhite = gci.GetColorTableEntry(TextColor::DARK_WHITE); stateMachine.ProcessString(L"\x1b[31;44m"); stateMachine.ProcessString(L"X"); stateMachine.ProcessString(L"\x1b[m"); @@ -6168,8 +6168,8 @@ void ScreenBufferTests::TestWriteConsoleVTQuirkMode() /* Write red on blue, verify that it comes through */ { TextAttribute vtRedOnBlueAttribute{}; - vtRedOnBlueAttribute.SetForeground(TextColor{ gsl::narrow_cast(XtermToWindowsIndex(1)), false }); - vtRedOnBlueAttribute.SetBackground(TextColor{ gsl::narrow_cast(XtermToWindowsIndex(4)), false }); + vtRedOnBlueAttribute.SetForeground(TextColor{ TextColor::DARK_RED, false }); + vtRedOnBlueAttribute.SetBackground(TextColor{ TextColor::DARK_BLUE, false }); seq = L"\x1b[31;44m"; seqCb = 2 * seq.size(); @@ -6187,8 +6187,8 @@ void ScreenBufferTests::TestWriteConsoleVTQuirkMode() /* Write white on black, verify that it acts as expected for the quirk mode */ { TextAttribute vtWhiteOnBlackAttribute{}; - vtWhiteOnBlackAttribute.SetForeground(TextColor{ gsl::narrow_cast(XtermToWindowsIndex(7)), false }); - vtWhiteOnBlackAttribute.SetBackground(TextColor{ gsl::narrow_cast(XtermToWindowsIndex(0)), false }); + vtWhiteOnBlackAttribute.SetForeground(TextColor{ TextColor::DARK_WHITE, false }); + vtWhiteOnBlackAttribute.SetBackground(TextColor{ TextColor::DARK_BLACK, false }); const TextAttribute quirkExpectedAttribute{ useQuirk ? defaultAttribute : vtWhiteOnBlackAttribute }; @@ -6208,8 +6208,8 @@ void ScreenBufferTests::TestWriteConsoleVTQuirkMode() /* Write bright white on black, verify that it acts as expected for the quirk mode */ { TextAttribute vtBrightWhiteOnBlackAttribute{}; - vtBrightWhiteOnBlackAttribute.SetForeground(TextColor{ gsl::narrow_cast(XtermToWindowsIndex(7)), false }); - vtBrightWhiteOnBlackAttribute.SetBackground(TextColor{ gsl::narrow_cast(XtermToWindowsIndex(0)), false }); + vtBrightWhiteOnBlackAttribute.SetForeground(TextColor{ TextColor::DARK_WHITE, false }); + vtBrightWhiteOnBlackAttribute.SetBackground(TextColor{ TextColor::DARK_BLACK, false }); vtBrightWhiteOnBlackAttribute.SetBold(true); TextAttribute vtBrightWhiteOnDefaultAttribute{ vtBrightWhiteOnBlackAttribute }; // copy the above attribute @@ -6233,8 +6233,8 @@ void ScreenBufferTests::TestWriteConsoleVTQuirkMode() /* Write a 256-color white on a 256-color black, make sure the quirk does not suppress it */ { TextAttribute vtWhiteOnBlack256Attribute{}; - vtWhiteOnBlack256Attribute.SetForeground(TextColor{ gsl::narrow_cast(XtermToWindowsIndex(7)), true }); - vtWhiteOnBlack256Attribute.SetBackground(TextColor{ gsl::narrow_cast(XtermToWindowsIndex(0)), true }); + vtWhiteOnBlack256Attribute.SetForeground(TextColor{ TextColor::DARK_WHITE, true }); + vtWhiteOnBlack256Attribute.SetBackground(TextColor{ TextColor::DARK_BLACK, true }); // reset (disable bold from the last test) before setting both colors seq = L"\x1b[m\x1b[38;5;7;48;5;0m"; // the quirk should *not* suppress this (!) diff --git a/src/host/ut_host/TextBufferTests.cpp b/src/host/ut_host/TextBufferTests.cpp index c8dd06793..2872c9421 100644 --- a/src/host/ut_host/TextBufferTests.cpp +++ b/src/host/ut_host/TextBufferTests.cpp @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Corporation. +// Copyright (c) Microsoft Corporation. // Licensed under the MIT license. #include "precomp.h" @@ -779,8 +779,8 @@ void TextBufferTests::TestMixedRgbAndLegacyBrightness() // '\E[m\E[32mX\E[1mX' // Make sure that the second X is a BRIGHT green, not white. Log::Comment(L"Case 4 ;\"\\E[m\\E[32mX\\E[1mX\""); - const auto dark_green = gci.GetColorTableEntry(2); - const auto bright_green = gci.GetColorTableEntry(10); + const auto dark_green = gci.GetColorTableEntry(TextColor::DARK_GREEN); + const auto bright_green = gci.GetColorTableEntry(TextColor::BRIGHT_GREEN); VERIFY_ARE_NOT_EQUAL(dark_green, bright_green); wchar_t* sequence = L"\x1b[m\x1b[32mX\x1b[1mX"; @@ -887,8 +887,8 @@ void TextBufferTests::TestUnBold() const auto x = cursor.GetPosition().X; const auto y = cursor.GetPosition().Y; - const auto dark_green = gci.GetColorTableEntry(2); - const auto bright_green = gci.GetColorTableEntry(10); + const auto dark_green = gci.GetColorTableEntry(TextColor::DARK_GREEN); + const auto bright_green = gci.GetColorTableEntry(TextColor::BRIGHT_GREEN); Log::Comment(NoThrowString().Format( L"cursor={X:%d,Y:%d}", @@ -938,8 +938,8 @@ void TextBufferTests::TestUnBoldRgb() const auto x = cursor.GetPosition().X; const auto y = cursor.GetPosition().Y; - const auto dark_green = gci.GetColorTableEntry(2); - const auto bright_green = gci.GetColorTableEntry(10); + const auto dark_green = gci.GetColorTableEntry(TextColor::DARK_GREEN); + const auto bright_green = gci.GetColorTableEntry(TextColor::BRIGHT_GREEN); Log::Comment(NoThrowString().Format( L"cursor={X:%d,Y:%d}", @@ -997,8 +997,8 @@ void TextBufferTests::TestComplexUnBold() const auto x = cursor.GetPosition().X; const auto y = cursor.GetPosition().Y; - const auto dark_green = gci.GetColorTableEntry(2); - const auto bright_green = gci.GetColorTableEntry(10); + const auto dark_green = gci.GetColorTableEntry(TextColor::DARK_GREEN); + const auto bright_green = gci.GetColorTableEntry(TextColor::BRIGHT_GREEN); Log::Comment(NoThrowString().Format( L"cursor={X:%d,Y:%d}", @@ -1079,8 +1079,8 @@ void TextBufferTests::CopyAttrs() const auto x = cursor.GetPosition().X; const auto y = cursor.GetPosition().Y; - const auto dark_blue = gci.GetColorTableEntry(1); - const auto dark_magenta = gci.GetColorTableEntry(5); + const auto dark_blue = gci.GetColorTableEntry(TextColor::DARK_BLUE); + const auto dark_magenta = gci.GetColorTableEntry(TextColor::DARK_MAGENTA); Log::Comment(NoThrowString().Format( L"cursor={X:%d,Y:%d}", @@ -1133,7 +1133,7 @@ void TextBufferTests::EmptySgrTest() const auto x = cursor.GetPosition().X; const auto y = cursor.GetPosition().Y; - const COLORREF darkRed = gci.GetColorTableEntry(4); + const COLORREF darkRed = gci.GetColorTableEntry(TextColor::DARK_RED); Log::Comment(NoThrowString().Format( L"cursor={X:%d,Y:%d}", x, @@ -1192,7 +1192,7 @@ void TextBufferTests::TestReverseReset() const auto x = cursor.GetPosition().X; const auto y = cursor.GetPosition().Y; - const auto dark_green = gci.GetColorTableEntry(2); + const auto dark_green = gci.GetColorTableEntry(TextColor::DARK_GREEN); const COLORREF rgbColor = RGB(128, 5, 255); Log::Comment(NoThrowString().Format( @@ -1258,9 +1258,9 @@ void TextBufferTests::CopyLastAttr() const COLORREF defaultBrightYellow = RGB(249, 241, 165); const COLORREF defaultBrightCyan = RGB(97, 214, 214); - gci.SetColorTableEntry(8, defaultBrightBlack); - gci.SetColorTableEntry(14, defaultBrightYellow); - gci.SetColorTableEntry(11, defaultBrightCyan); + gci.SetColorTableEntry(TextColor::BRIGHT_BLACK, defaultBrightBlack); + gci.SetColorTableEntry(TextColor::BRIGHT_YELLOW, defaultBrightYellow); + gci.SetColorTableEntry(TextColor::BRIGHT_CYAN, defaultBrightCyan); // Write (solFg, solBG) X \n // (solFg, solBG) X (solCyan, solBG) X \n @@ -1405,8 +1405,8 @@ void TextBufferTests::TestResetClearsBoldness() si.SetAttributes(defaultAttribute); const auto [defaultFg, defaultBg] = gci.LookupAttributeColors(si.GetAttributes()); - const auto dark_green = gci.GetColorTableEntry(2); - const auto bright_green = gci.GetColorTableEntry(10); + const auto dark_green = gci.GetColorTableEntry(TextColor::DARK_GREEN); + const auto bright_green = gci.GetColorTableEntry(TextColor::BRIGHT_GREEN); wchar_t* sequence = L"\x1b[32mA\x1b[1mB\x1b[0mC\x1b[32mD"; Log::Comment(NoThrowString().Format(sequence)); diff --git a/src/host/ut_host/VtRendererTests.cpp b/src/host/ut_host/VtRendererTests.cpp index a12dd8673..3d9a5b8aa 100644 --- a/src/host/ut_host/VtRendererTests.cpp +++ b/src/host/ut_host/VtRendererTests.cpp @@ -470,7 +470,7 @@ void VtRendererTest::Xterm256TestColors() Log::Comment(NoThrowString().Format( L"----Change only the BG----")); - textAttributes.SetIndexedBackground(FOREGROUND_RED); + textAttributes.SetIndexedBackground(TextColor::DARK_RED); qExpectedInput.push_back("\x1b[41m"); // Background DARK_RED VERIFY_SUCCEEDED(engine->UpdateDrawingBrushes(textAttributes, &renderData, @@ -479,7 +479,7 @@ void VtRendererTest::Xterm256TestColors() Log::Comment(NoThrowString().Format( L"----Change only the FG----")); - textAttributes.SetIndexedForeground(FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE); + textAttributes.SetIndexedForeground(TextColor::DARK_WHITE); qExpectedInput.push_back("\x1b[37m"); // Foreground DARK_WHITE VERIFY_SUCCEEDED(engine->UpdateDrawingBrushes(textAttributes, &renderData, @@ -515,7 +515,7 @@ void VtRendererTest::Xterm256TestColors() Log::Comment(NoThrowString().Format( L"----Change only the FG to a 256-color index----")); - textAttributes.SetIndexedForeground256(FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE); + textAttributes.SetIndexedForeground256(TextColor::DARK_WHITE); qExpectedInput.push_back("\x1b[38;5;7m"); // Foreground DARK_WHITE (256-Color Index) VERIFY_SUCCEEDED(engine->UpdateDrawingBrushes(textAttributes, &renderData, @@ -524,7 +524,7 @@ void VtRendererTest::Xterm256TestColors() Log::Comment(NoThrowString().Format( L"----Change only the BG to a 256-color index----")); - textAttributes.SetIndexedBackground256(FOREGROUND_RED); + textAttributes.SetIndexedBackground256(TextColor::DARK_RED); qExpectedInput.push_back("\x1b[48;5;1m"); // Background DARK_RED (256-Color Index) VERIFY_SUCCEEDED(engine->UpdateDrawingBrushes(textAttributes, &renderData, @@ -859,7 +859,7 @@ void VtRendererTest::Xterm256TestAttributesAcrossReset() VERIFY_SUCCEEDED(engine->UpdateDrawingBrushes(textAttributes, &renderData, false, false)); Log::Comment(L"----Set Green Foreground----"); - textAttributes.SetIndexedForeground(FOREGROUND_GREEN); + textAttributes.SetIndexedForeground(TextColor::DARK_GREEN); qExpectedInput.push_back("\x1b[32m"); VERIFY_SUCCEEDED(engine->UpdateDrawingBrushes(textAttributes, &renderData, false, false)); @@ -870,7 +870,7 @@ void VtRendererTest::Xterm256TestAttributesAcrossReset() VERIFY_SUCCEEDED(engine->UpdateDrawingBrushes(textAttributes, &renderData, false, false)); Log::Comment(L"----Set Green Background----"); - textAttributes.SetIndexedBackground(FOREGROUND_GREEN); + textAttributes.SetIndexedBackground(TextColor::DARK_GREEN); qExpectedInput.push_back("\x1b[42m"); VERIFY_SUCCEEDED(engine->UpdateDrawingBrushes(textAttributes, &renderData, false, false)); @@ -1104,7 +1104,7 @@ void VtRendererTest::XtermTestColors() Log::Comment(NoThrowString().Format( L"----Change only the BG----")); - textAttributes.SetIndexedBackground(FOREGROUND_RED); + textAttributes.SetIndexedBackground(TextColor::DARK_RED); qExpectedInput.push_back("\x1b[41m"); // Background DARK_RED VERIFY_SUCCEEDED(engine->UpdateDrawingBrushes(textAttributes, &renderData, @@ -1113,7 +1113,7 @@ void VtRendererTest::XtermTestColors() Log::Comment(NoThrowString().Format( L"----Change only the FG----")); - textAttributes.SetIndexedForeground(FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE); + textAttributes.SetIndexedForeground(TextColor::DARK_WHITE); qExpectedInput.push_back("\x1b[37m"); // Foreground DARK_WHITE VERIFY_SUCCEEDED(engine->UpdateDrawingBrushes(textAttributes, &renderData, @@ -1150,7 +1150,7 @@ void VtRendererTest::XtermTestColors() Log::Comment(NoThrowString().Format( L"----Change only the FG to a 256-color index----")); - textAttributes.SetIndexedForeground256(FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE); + textAttributes.SetIndexedForeground256(TextColor::DARK_WHITE); qExpectedInput.push_back("\x1b[37m"); // Foreground DARK_WHITE VERIFY_SUCCEEDED(engine->UpdateDrawingBrushes(textAttributes, &renderData, @@ -1159,7 +1159,7 @@ void VtRendererTest::XtermTestColors() Log::Comment(NoThrowString().Format( L"----Change only the BG to a 256-color index----")); - textAttributes.SetIndexedBackground256(FOREGROUND_RED); + textAttributes.SetIndexedBackground256(TextColor::DARK_RED); qExpectedInput.push_back("\x1b[41m"); // Background DARK_RED VERIFY_SUCCEEDED(engine->UpdateDrawingBrushes(textAttributes, &renderData, @@ -1351,7 +1351,7 @@ void VtRendererTest::XtermTestAttributesAcrossReset() VERIFY_SUCCEEDED(engine->UpdateDrawingBrushes(textAttributes, &renderData, false, false)); Log::Comment(L"----Set Green Foreground----"); - textAttributes.SetIndexedForeground(FOREGROUND_GREEN); + textAttributes.SetIndexedForeground(TextColor::DARK_GREEN); qExpectedInput.push_back("\x1b[32m"); VERIFY_SUCCEEDED(engine->UpdateDrawingBrushes(textAttributes, &renderData, false, false)); @@ -1362,7 +1362,7 @@ void VtRendererTest::XtermTestAttributesAcrossReset() VERIFY_SUCCEEDED(engine->UpdateDrawingBrushes(textAttributes, &renderData, false, false)); Log::Comment(L"----Set Green Background----"); - textAttributes.SetIndexedBackground(FOREGROUND_GREEN); + textAttributes.SetIndexedBackground(TextColor::DARK_GREEN); qExpectedInput.push_back("\x1b[42m"); VERIFY_SUCCEEDED(engine->UpdateDrawingBrushes(textAttributes, &renderData, false, false)); diff --git a/src/inc/conattrs.hpp b/src/inc/conattrs.hpp index cb9110064..8589590d4 100644 --- a/src/inc/conattrs.hpp +++ b/src/inc/conattrs.hpp @@ -22,20 +22,6 @@ enum class ExtendedAttributes : BYTE }; DEFINE_ENUM_FLAG_OPERATORS(ExtendedAttributes); -WORD XtermToWindowsIndex(const size_t index) noexcept; -WORD Xterm256ToWindowsIndex(const size_t index) noexcept; -WORD XtermToLegacy(const size_t xtermForeground, const size_t xtermBackground); - -constexpr WORD WINDOWS_RED_ATTR = FOREGROUND_RED; -constexpr WORD WINDOWS_GREEN_ATTR = FOREGROUND_GREEN; -constexpr WORD WINDOWS_BLUE_ATTR = FOREGROUND_BLUE; -constexpr WORD WINDOWS_BRIGHT_ATTR = FOREGROUND_INTENSITY; - -constexpr WORD XTERM_RED_ATTR = 0x01; -constexpr WORD XTERM_GREEN_ATTR = 0x02; -constexpr WORD XTERM_BLUE_ATTR = 0x04; -constexpr WORD XTERM_BRIGHT_ATTR = 0x08; - enum class CursorType : unsigned int { Legacy = 0x0, // uses the cursor's height value to range from underscore-like to full box diff --git a/src/interactivity/win32/Clipboard.cpp b/src/interactivity/win32/Clipboard.cpp index b12161ccf..8e05e7827 100644 --- a/src/interactivity/win32/Clipboard.cpp +++ b/src/interactivity/win32/Clipboard.cpp @@ -208,7 +208,11 @@ void Clipboard::StoreSelectionToClipboard(bool const copyFormatting) const auto& gci = ServiceLocator::LocateGlobals().getConsoleInformation(); const auto& buffer = gci.GetActiveOutputBuffer().GetTextBuffer(); - const auto GetAttributeColors = std::bind(&CONSOLE_INFORMATION::LookupAttributeColors, &gci, std::placeholders::_1); + const auto defaultForeground = gci.GetDefaultForeground(); + const auto defaultBackground = gci.GetDefaultBackground(); + const auto GetAttributeColors = [=, &gci](const auto& attr) { + return gci.LookupAttributeColors(attr, defaultForeground, defaultBackground); + }; bool includeCRLF, trimTrailingWhitespace; if (WI_IsFlagSet(GetKeyState(VK_SHIFT), KEY_PRESSED)) diff --git a/src/interactivity/win32/menu.cpp b/src/interactivity/win32/menu.cpp index 3229f5663..9364e6364 100644 --- a/src/interactivity/win32/menu.cpp +++ b/src/interactivity/win32/menu.cpp @@ -337,7 +337,7 @@ void Menu::s_ShowPropertiesDialog(HWND const hwnd, BOOL const Defaults) for (size_t i = 0; i < std::size(pStateInfo->ColorTable); i++) { - pStateInfo->ColorTable[i] = gci.GetColorTableEntry(i); + pStateInfo->ColorTable[i] = gci.GetLegacyColorTableEntry(i); } // Create mutable copies of the titles so the propsheet can do something with them. @@ -566,7 +566,7 @@ void Menu::s_PropertiesUpdate(PCONSOLE_STATE_INFO pStateInfo) for (size_t i = 0; i < std::size(pStateInfo->ColorTable); i++) { - gci.SetColorTableEntry(i, pStateInfo->ColorTable[i]); + gci.SetLegacyColorTableEntry(i, pStateInfo->ColorTable[i]); } // Ensure that attributes only contain color specification. diff --git a/src/renderer/vt/VtSequences.cpp b/src/renderer/vt/VtSequences.cpp index efd16e2cb..c11e8cc4d 100644 --- a/src/renderer/vt/VtSequences.cpp +++ b/src/renderer/vt/VtSequences.cpp @@ -199,13 +199,14 @@ using namespace Microsoft::Console::Render; } // Method Description: -// - Formats and writes a sequence to change the current text attributes. +// - Formats and writes a sequence to change the current text attributes to an +// indexed color from the 16-color table. // Arguments: -// - wAttr: Windows color table index to emit as a VT sequence +// - index: color table index to emit as a VT sequence // - fIsForeground: true if we should emit the foreground sequence, false for background // Return Value: // - S_OK if we succeeded, else an appropriate HRESULT for failing to allocate or write. -[[nodiscard]] HRESULT VtEngine::_SetGraphicsRendition16Color(const WORD wAttr, +[[nodiscard]] HRESULT VtEngine::_SetGraphicsRendition16Color(const BYTE index, const bool fIsForeground) noexcept { // Always check using the foreground flags, because the bg flags constants @@ -220,28 +221,22 @@ using namespace Microsoft::Console::Render; // terminals display the bright color when displaying bolded text. // By specifying the boldness and brightness separately, we'll make sure the // terminal has an accurate representation of our buffer. - const int vtIndex = 30 + - (fIsForeground ? 0 : 10) + - ((WI_IsFlagSet(wAttr, FOREGROUND_INTENSITY)) ? 60 : 0) + - (WI_IsFlagSet(wAttr, FOREGROUND_RED) ? 1 : 0) + - (WI_IsFlagSet(wAttr, FOREGROUND_GREEN) ? 2 : 0) + - (WI_IsFlagSet(wAttr, FOREGROUND_BLUE) ? 4 : 0); - - return _WriteFormatted(FMT_COMPILE("\x1b[{}m"), vtIndex); + const auto prefix = WI_IsFlagSet(index, FOREGROUND_INTENSITY) ? (fIsForeground ? 90 : 100) : (fIsForeground ? 30 : 40); + return _WriteFormatted(FMT_COMPILE("\x1b[{}m"), prefix + (index & 7)); } // Method Description: // - Formats and writes a sequence to change the current text attributes to an // indexed color from the 256-color table. // Arguments: -// - wAttr: Windows color table index to emit as a VT sequence +// - index: color table index to emit as a VT sequence // - fIsForeground: true if we should emit the foreground sequence, false for background // Return Value: // - S_OK if we succeeded, else an appropriate HRESULT for failing to allocate or write. -[[nodiscard]] HRESULT VtEngine::_SetGraphicsRendition256Color(const WORD index, +[[nodiscard]] HRESULT VtEngine::_SetGraphicsRendition256Color(const BYTE index, const bool fIsForeground) noexcept { - return _WriteFormatted(FMT_COMPILE("\x1b[{}8;5;{}m"), fIsForeground ? '3' : '4', ::Xterm256ToWindowsIndex(index)); + return _WriteFormatted(FMT_COMPILE("\x1b[{}8;5;{}m"), fIsForeground ? '3' : '4', index); } // Method Description: diff --git a/src/renderer/vt/paint.cpp b/src/renderer/vt/paint.cpp index 1b9efb35e..adb0c90d1 100644 --- a/src/renderer/vt/paint.cpp +++ b/src/renderer/vt/paint.cpp @@ -287,9 +287,10 @@ using namespace Microsoft::Console::Types; } // We use the legacy color calculations to generate an approximation of the - // colors in the 16-color table. - auto fgIndex = fg.GetLegacyIndex(0); - auto bgIndex = bg.GetLegacyIndex(0); + // colors in the Windows 16-color table, but we need to transpose those + // values to obtain an index in an ANSI-compatible order. + auto fgIndex = TextColor::TransposeLegacyIndex(fg.GetLegacyIndex(0)); + auto bgIndex = TextColor::TransposeLegacyIndex(bg.GetLegacyIndex(0)); // If the bold attribute is set, and the foreground can be brightened, then do so. const bool brighten = textAttributes.IsBold() && fg.CanBeBrightened(); diff --git a/src/renderer/vt/vtrenderer.hpp b/src/renderer/vt/vtrenderer.hpp index 1965034db..f78adf647 100644 --- a/src/renderer/vt/vtrenderer.hpp +++ b/src/renderer/vt/vtrenderer.hpp @@ -185,9 +185,9 @@ namespace Microsoft::Console::Render [[nodiscard]] HRESULT _ClearScreen() noexcept; [[nodiscard]] HRESULT _ClearScrollback() noexcept; [[nodiscard]] HRESULT _ChangeTitle(const std::string& title) noexcept; - [[nodiscard]] HRESULT _SetGraphicsRendition16Color(const WORD wAttr, + [[nodiscard]] HRESULT _SetGraphicsRendition16Color(const BYTE index, const bool fIsForeground) noexcept; - [[nodiscard]] HRESULT _SetGraphicsRendition256Color(const WORD index, + [[nodiscard]] HRESULT _SetGraphicsRendition256Color(const BYTE index, const bool fIsForeground) noexcept; [[nodiscard]] HRESULT _SetGraphicsRenditionRGBColor(const COLORREF color, const bool fIsForeground) noexcept; diff --git a/src/terminal/adapter/adaptDispatch.cpp b/src/terminal/adapter/adaptDispatch.cpp index 49a3f71a9..8ffe4c202 100644 --- a/src/terminal/adapter/adaptDispatch.cpp +++ b/src/terminal/adapter/adaptDispatch.cpp @@ -2541,13 +2541,13 @@ void AdaptDispatch::_ReportSGRSetting() const const auto iterator = std::back_insert_iterator(response); if (color.IsIndex16()) { - const auto index = XtermToWindowsIndex(color.GetIndex()); + const auto index = color.GetIndex(); const auto colorParameter = base + (index >= 8 ? 60 : 0) + (index % 8); fmt::format_to(iterator, FMT_STRING(L";{}"), colorParameter); } else if (color.IsIndex256()) { - const auto index = Xterm256ToWindowsIndex(color.GetIndex()); + const auto index = color.GetIndex(); fmt::format_to(iterator, FMT_STRING(L";{};5;{}"), base + 8, index); } else if (color.IsRgb()) diff --git a/src/terminal/adapter/adaptDispatchGraphics.cpp b/src/terminal/adapter/adaptDispatchGraphics.cpp index c258c2c44..6d586cce6 100644 --- a/src/terminal/adapter/adaptDispatchGraphics.cpp +++ b/src/terminal/adapter/adaptDispatchGraphics.cpp @@ -13,29 +13,6 @@ using namespace Microsoft::Console::VirtualTerminal; using namespace Microsoft::Console::VirtualTerminal::DispatchTypes; -// clang-format off -constexpr BYTE BLUE_ATTR = 0x01; -constexpr BYTE GREEN_ATTR = 0x02; -constexpr BYTE RED_ATTR = 0x04; -constexpr BYTE BRIGHT_ATTR = 0x08; -constexpr BYTE DARK_BLACK = 0; -constexpr BYTE DARK_RED = RED_ATTR; -constexpr BYTE DARK_GREEN = GREEN_ATTR; -constexpr BYTE DARK_YELLOW = RED_ATTR | GREEN_ATTR; -constexpr BYTE DARK_BLUE = BLUE_ATTR; -constexpr BYTE DARK_MAGENTA = RED_ATTR | BLUE_ATTR; -constexpr BYTE DARK_CYAN = GREEN_ATTR | BLUE_ATTR; -constexpr BYTE DARK_WHITE = RED_ATTR | GREEN_ATTR | BLUE_ATTR; -constexpr BYTE BRIGHT_BLACK = BRIGHT_ATTR; -constexpr BYTE BRIGHT_RED = BRIGHT_ATTR | RED_ATTR; -constexpr BYTE BRIGHT_GREEN = BRIGHT_ATTR | GREEN_ATTR; -constexpr BYTE BRIGHT_YELLOW = BRIGHT_ATTR | RED_ATTR | GREEN_ATTR; -constexpr BYTE BRIGHT_BLUE = BRIGHT_ATTR | BLUE_ATTR; -constexpr BYTE BRIGHT_MAGENTA = BRIGHT_ATTR | RED_ATTR | BLUE_ATTR; -constexpr BYTE BRIGHT_CYAN = BRIGHT_ATTR | GREEN_ATTR | BLUE_ATTR; -constexpr BYTE BRIGHT_WHITE = BRIGHT_ATTR | RED_ATTR | GREEN_ATTR | BLUE_ATTR; -// clang-format on - // Routine Description: // - Helper to parse extended graphics options, which start with 38 (FG) or 48 (BG) // These options are followed by either a 2 (RGB) or 5 (xterm index) @@ -72,7 +49,7 @@ size_t AdaptDispatch::_SetRgbColorsHelper(const VTParameters options, const size_t tableIndex = options.at(1).value_or(0); if (tableIndex <= 255) { - const auto adjustedIndex = gsl::narrow_cast(::Xterm256ToWindowsIndex(tableIndex)); + const auto adjustedIndex = gsl::narrow_cast(tableIndex); if (isForeground) { attr.SetIndexedForeground256(adjustedIndex); @@ -178,100 +155,100 @@ bool AdaptDispatch::SetGraphicsRendition(const VTParameters options) attr.SetOverlined(false); break; case ForegroundBlack: - attr.SetIndexedForeground(DARK_BLACK); + attr.SetIndexedForeground(TextColor::DARK_BLACK); break; case ForegroundBlue: - attr.SetIndexedForeground(DARK_BLUE); + attr.SetIndexedForeground(TextColor::DARK_BLUE); break; case ForegroundGreen: - attr.SetIndexedForeground(DARK_GREEN); + attr.SetIndexedForeground(TextColor::DARK_GREEN); break; case ForegroundCyan: - attr.SetIndexedForeground(DARK_CYAN); + attr.SetIndexedForeground(TextColor::DARK_CYAN); break; case ForegroundRed: - attr.SetIndexedForeground(DARK_RED); + attr.SetIndexedForeground(TextColor::DARK_RED); break; case ForegroundMagenta: - attr.SetIndexedForeground(DARK_MAGENTA); + attr.SetIndexedForeground(TextColor::DARK_MAGENTA); break; case ForegroundYellow: - attr.SetIndexedForeground(DARK_YELLOW); + attr.SetIndexedForeground(TextColor::DARK_YELLOW); break; case ForegroundWhite: - attr.SetIndexedForeground(DARK_WHITE); + attr.SetIndexedForeground(TextColor::DARK_WHITE); break; case BackgroundBlack: - attr.SetIndexedBackground(DARK_BLACK); + attr.SetIndexedBackground(TextColor::DARK_BLACK); break; case BackgroundBlue: - attr.SetIndexedBackground(DARK_BLUE); + attr.SetIndexedBackground(TextColor::DARK_BLUE); break; case BackgroundGreen: - attr.SetIndexedBackground(DARK_GREEN); + attr.SetIndexedBackground(TextColor::DARK_GREEN); break; case BackgroundCyan: - attr.SetIndexedBackground(DARK_CYAN); + attr.SetIndexedBackground(TextColor::DARK_CYAN); break; case BackgroundRed: - attr.SetIndexedBackground(DARK_RED); + attr.SetIndexedBackground(TextColor::DARK_RED); break; case BackgroundMagenta: - attr.SetIndexedBackground(DARK_MAGENTA); + attr.SetIndexedBackground(TextColor::DARK_MAGENTA); break; case BackgroundYellow: - attr.SetIndexedBackground(DARK_YELLOW); + attr.SetIndexedBackground(TextColor::DARK_YELLOW); break; case BackgroundWhite: - attr.SetIndexedBackground(DARK_WHITE); + attr.SetIndexedBackground(TextColor::DARK_WHITE); break; case BrightForegroundBlack: - attr.SetIndexedForeground(BRIGHT_BLACK); + attr.SetIndexedForeground(TextColor::BRIGHT_BLACK); break; case BrightForegroundBlue: - attr.SetIndexedForeground(BRIGHT_BLUE); + attr.SetIndexedForeground(TextColor::BRIGHT_BLUE); break; case BrightForegroundGreen: - attr.SetIndexedForeground(BRIGHT_GREEN); + attr.SetIndexedForeground(TextColor::BRIGHT_GREEN); break; case BrightForegroundCyan: - attr.SetIndexedForeground(BRIGHT_CYAN); + attr.SetIndexedForeground(TextColor::BRIGHT_CYAN); break; case BrightForegroundRed: - attr.SetIndexedForeground(BRIGHT_RED); + attr.SetIndexedForeground(TextColor::BRIGHT_RED); break; case BrightForegroundMagenta: - attr.SetIndexedForeground(BRIGHT_MAGENTA); + attr.SetIndexedForeground(TextColor::BRIGHT_MAGENTA); break; case BrightForegroundYellow: - attr.SetIndexedForeground(BRIGHT_YELLOW); + attr.SetIndexedForeground(TextColor::BRIGHT_YELLOW); break; case BrightForegroundWhite: - attr.SetIndexedForeground(BRIGHT_WHITE); + attr.SetIndexedForeground(TextColor::BRIGHT_WHITE); break; case BrightBackgroundBlack: - attr.SetIndexedBackground(BRIGHT_BLACK); + attr.SetIndexedBackground(TextColor::BRIGHT_BLACK); break; case BrightBackgroundBlue: - attr.SetIndexedBackground(BRIGHT_BLUE); + attr.SetIndexedBackground(TextColor::BRIGHT_BLUE); break; case BrightBackgroundGreen: - attr.SetIndexedBackground(BRIGHT_GREEN); + attr.SetIndexedBackground(TextColor::BRIGHT_GREEN); break; case BrightBackgroundCyan: - attr.SetIndexedBackground(BRIGHT_CYAN); + attr.SetIndexedBackground(TextColor::BRIGHT_CYAN); break; case BrightBackgroundRed: - attr.SetIndexedBackground(BRIGHT_RED); + attr.SetIndexedBackground(TextColor::BRIGHT_RED); break; case BrightBackgroundMagenta: - attr.SetIndexedBackground(BRIGHT_MAGENTA); + attr.SetIndexedBackground(TextColor::BRIGHT_MAGENTA); break; case BrightBackgroundYellow: - attr.SetIndexedBackground(BRIGHT_YELLOW); + attr.SetIndexedBackground(TextColor::BRIGHT_YELLOW); break; case BrightBackgroundWhite: - attr.SetIndexedBackground(BRIGHT_WHITE); + attr.SetIndexedBackground(TextColor::BRIGHT_WHITE); break; case ForegroundExtended: i += _SetRgbColorsHelper(options.subspan(i + 1), attr, true); diff --git a/src/terminal/adapter/ut_adapter/adapterTest.cpp b/src/terminal/adapter/ut_adapter/adapterTest.cpp index b775f4c7a..d494b2deb 100644 --- a/src/terminal/adapter/ut_adapter/adapterTest.cpp +++ b/src/terminal/adapter/ut_adapter/adapterTest.cpp @@ -1307,49 +1307,49 @@ public: Log::Comment(L"Testing graphics 'Foreground Color Black'"); _testGetSet->_attribute = TextAttribute{ FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY }; _testGetSet->_expectedAttribute = _testGetSet->_attribute; - _testGetSet->_expectedAttribute.SetIndexedForeground(0); + _testGetSet->_expectedAttribute.SetIndexedForeground(TextColor::DARK_BLACK); break; case DispatchTypes::GraphicsOptions::ForegroundBlue: Log::Comment(L"Testing graphics 'Foreground Color Blue'"); _testGetSet->_attribute = TextAttribute{ FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_INTENSITY }; _testGetSet->_expectedAttribute = _testGetSet->_attribute; - _testGetSet->_expectedAttribute.SetIndexedForeground(FOREGROUND_BLUE); + _testGetSet->_expectedAttribute.SetIndexedForeground(TextColor::DARK_BLUE); break; case DispatchTypes::GraphicsOptions::ForegroundGreen: Log::Comment(L"Testing graphics 'Foreground Color Green'"); _testGetSet->_attribute = TextAttribute{ FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_INTENSITY }; _testGetSet->_expectedAttribute = _testGetSet->_attribute; - _testGetSet->_expectedAttribute.SetIndexedForeground(FOREGROUND_GREEN); + _testGetSet->_expectedAttribute.SetIndexedForeground(TextColor::DARK_GREEN); break; case DispatchTypes::GraphicsOptions::ForegroundCyan: Log::Comment(L"Testing graphics 'Foreground Color Cyan'"); _testGetSet->_attribute = TextAttribute{ FOREGROUND_RED | FOREGROUND_INTENSITY }; _testGetSet->_expectedAttribute = _testGetSet->_attribute; - _testGetSet->_expectedAttribute.SetIndexedForeground(FOREGROUND_BLUE | FOREGROUND_GREEN); + _testGetSet->_expectedAttribute.SetIndexedForeground(TextColor::DARK_CYAN); break; case DispatchTypes::GraphicsOptions::ForegroundRed: Log::Comment(L"Testing graphics 'Foreground Color Red'"); _testGetSet->_attribute = TextAttribute{ FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_INTENSITY }; _testGetSet->_expectedAttribute = _testGetSet->_attribute; - _testGetSet->_expectedAttribute.SetIndexedForeground(FOREGROUND_RED); + _testGetSet->_expectedAttribute.SetIndexedForeground(TextColor::DARK_RED); break; case DispatchTypes::GraphicsOptions::ForegroundMagenta: Log::Comment(L"Testing graphics 'Foreground Color Magenta'"); _testGetSet->_attribute = TextAttribute{ FOREGROUND_GREEN | FOREGROUND_INTENSITY }; _testGetSet->_expectedAttribute = _testGetSet->_attribute; - _testGetSet->_expectedAttribute.SetIndexedForeground(FOREGROUND_BLUE | FOREGROUND_RED); + _testGetSet->_expectedAttribute.SetIndexedForeground(TextColor::DARK_MAGENTA); break; case DispatchTypes::GraphicsOptions::ForegroundYellow: Log::Comment(L"Testing graphics 'Foreground Color Yellow'"); _testGetSet->_attribute = TextAttribute{ FOREGROUND_BLUE | FOREGROUND_INTENSITY }; _testGetSet->_expectedAttribute = _testGetSet->_attribute; - _testGetSet->_expectedAttribute.SetIndexedForeground(FOREGROUND_GREEN | FOREGROUND_RED); + _testGetSet->_expectedAttribute.SetIndexedForeground(TextColor::DARK_YELLOW); break; case DispatchTypes::GraphicsOptions::ForegroundWhite: Log::Comment(L"Testing graphics 'Foreground Color White'"); _testGetSet->_attribute = TextAttribute{ FOREGROUND_INTENSITY }; _testGetSet->_expectedAttribute = _testGetSet->_attribute; - _testGetSet->_expectedAttribute.SetIndexedForeground(FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED); + _testGetSet->_expectedAttribute.SetIndexedForeground(TextColor::DARK_WHITE); break; case DispatchTypes::GraphicsOptions::ForegroundDefault: Log::Comment(L"Testing graphics 'Foreground Color Default'"); @@ -1362,49 +1362,49 @@ public: Log::Comment(L"Testing graphics 'Background Color Black'"); _testGetSet->_attribute = TextAttribute{ BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE | BACKGROUND_INTENSITY }; _testGetSet->_expectedAttribute = _testGetSet->_attribute; - _testGetSet->_expectedAttribute.SetIndexedBackground(0); + _testGetSet->_expectedAttribute.SetIndexedBackground(TextColor::DARK_BLACK); break; case DispatchTypes::GraphicsOptions::BackgroundBlue: Log::Comment(L"Testing graphics 'Background Color Blue'"); _testGetSet->_attribute = TextAttribute{ BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_INTENSITY }; _testGetSet->_expectedAttribute = _testGetSet->_attribute; - _testGetSet->_expectedAttribute.SetIndexedBackground(BACKGROUND_BLUE >> 4); + _testGetSet->_expectedAttribute.SetIndexedBackground(TextColor::DARK_BLUE); break; case DispatchTypes::GraphicsOptions::BackgroundGreen: Log::Comment(L"Testing graphics 'Background Color Green'"); _testGetSet->_attribute = TextAttribute{ BACKGROUND_RED | BACKGROUND_BLUE | BACKGROUND_INTENSITY }; _testGetSet->_expectedAttribute = _testGetSet->_attribute; - _testGetSet->_expectedAttribute.SetIndexedBackground(BACKGROUND_GREEN >> 4); + _testGetSet->_expectedAttribute.SetIndexedBackground(TextColor::DARK_GREEN); break; case DispatchTypes::GraphicsOptions::BackgroundCyan: Log::Comment(L"Testing graphics 'Background Color Cyan'"); _testGetSet->_attribute = TextAttribute{ BACKGROUND_RED | BACKGROUND_INTENSITY }; _testGetSet->_expectedAttribute = _testGetSet->_attribute; - _testGetSet->_expectedAttribute.SetIndexedBackground((BACKGROUND_BLUE | BACKGROUND_GREEN) >> 4); + _testGetSet->_expectedAttribute.SetIndexedBackground(TextColor::DARK_CYAN); break; case DispatchTypes::GraphicsOptions::BackgroundRed: Log::Comment(L"Testing graphics 'Background Color Red'"); _testGetSet->_attribute = TextAttribute{ BACKGROUND_BLUE | BACKGROUND_GREEN | BACKGROUND_INTENSITY }; _testGetSet->_expectedAttribute = _testGetSet->_attribute; - _testGetSet->_expectedAttribute.SetIndexedBackground(BACKGROUND_RED >> 4); + _testGetSet->_expectedAttribute.SetIndexedBackground(TextColor::DARK_RED); break; case DispatchTypes::GraphicsOptions::BackgroundMagenta: Log::Comment(L"Testing graphics 'Background Color Magenta'"); _testGetSet->_attribute = TextAttribute{ BACKGROUND_GREEN | BACKGROUND_INTENSITY }; _testGetSet->_expectedAttribute = _testGetSet->_attribute; - _testGetSet->_expectedAttribute.SetIndexedBackground((BACKGROUND_BLUE | BACKGROUND_RED) >> 4); + _testGetSet->_expectedAttribute.SetIndexedBackground(TextColor::DARK_MAGENTA); break; case DispatchTypes::GraphicsOptions::BackgroundYellow: Log::Comment(L"Testing graphics 'Background Color Yellow'"); _testGetSet->_attribute = TextAttribute{ BACKGROUND_BLUE | BACKGROUND_INTENSITY }; _testGetSet->_expectedAttribute = _testGetSet->_attribute; - _testGetSet->_expectedAttribute.SetIndexedBackground((BACKGROUND_GREEN | BACKGROUND_RED) >> 4); + _testGetSet->_expectedAttribute.SetIndexedBackground(TextColor::DARK_YELLOW); break; case DispatchTypes::GraphicsOptions::BackgroundWhite: Log::Comment(L"Testing graphics 'Background Color White'"); _testGetSet->_attribute = TextAttribute{ BACKGROUND_INTENSITY }; _testGetSet->_expectedAttribute = _testGetSet->_attribute; - _testGetSet->_expectedAttribute.SetIndexedBackground((BACKGROUND_BLUE | BACKGROUND_GREEN | BACKGROUND_RED) >> 4); + _testGetSet->_expectedAttribute.SetIndexedBackground(TextColor::DARK_WHITE); break; case DispatchTypes::GraphicsOptions::BackgroundDefault: Log::Comment(L"Testing graphics 'Background Color Default'"); @@ -1417,97 +1417,97 @@ public: Log::Comment(L"Testing graphics 'Bright Foreground Color Black'"); _testGetSet->_attribute = TextAttribute{ FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE }; _testGetSet->_expectedAttribute = _testGetSet->_attribute; - _testGetSet->_expectedAttribute.SetIndexedForeground(FOREGROUND_INTENSITY); + _testGetSet->_expectedAttribute.SetIndexedForeground(TextColor::BRIGHT_BLACK); break; case DispatchTypes::GraphicsOptions::BrightForegroundBlue: Log::Comment(L"Testing graphics 'Bright Foreground Color Blue'"); _testGetSet->_attribute = TextAttribute{ FOREGROUND_RED | FOREGROUND_GREEN }; _testGetSet->_expectedAttribute = _testGetSet->_attribute; - _testGetSet->_expectedAttribute.SetIndexedForeground(FOREGROUND_INTENSITY | FOREGROUND_BLUE); + _testGetSet->_expectedAttribute.SetIndexedForeground(TextColor::BRIGHT_BLUE); break; case DispatchTypes::GraphicsOptions::BrightForegroundGreen: Log::Comment(L"Testing graphics 'Bright Foreground Color Green'"); _testGetSet->_attribute = TextAttribute{ FOREGROUND_RED | FOREGROUND_BLUE }; _testGetSet->_expectedAttribute = _testGetSet->_attribute; - _testGetSet->_expectedAttribute.SetIndexedForeground(FOREGROUND_INTENSITY | FOREGROUND_GREEN); + _testGetSet->_expectedAttribute.SetIndexedForeground(TextColor::BRIGHT_GREEN); break; case DispatchTypes::GraphicsOptions::BrightForegroundCyan: Log::Comment(L"Testing graphics 'Bright Foreground Color Cyan'"); _testGetSet->_attribute = TextAttribute{ FOREGROUND_RED }; _testGetSet->_expectedAttribute = _testGetSet->_attribute; - _testGetSet->_expectedAttribute.SetIndexedForeground(FOREGROUND_INTENSITY | FOREGROUND_BLUE | FOREGROUND_GREEN); + _testGetSet->_expectedAttribute.SetIndexedForeground(TextColor::BRIGHT_CYAN); break; case DispatchTypes::GraphicsOptions::BrightForegroundRed: Log::Comment(L"Testing graphics 'Bright Foreground Color Red'"); _testGetSet->_attribute = TextAttribute{ FOREGROUND_BLUE | FOREGROUND_GREEN }; _testGetSet->_expectedAttribute = _testGetSet->_attribute; - _testGetSet->_expectedAttribute.SetIndexedForeground(FOREGROUND_INTENSITY | FOREGROUND_RED); + _testGetSet->_expectedAttribute.SetIndexedForeground(TextColor::BRIGHT_RED); break; case DispatchTypes::GraphicsOptions::BrightForegroundMagenta: Log::Comment(L"Testing graphics 'Bright Foreground Color Magenta'"); _testGetSet->_attribute = TextAttribute{ FOREGROUND_GREEN }; _testGetSet->_expectedAttribute = _testGetSet->_attribute; - _testGetSet->_expectedAttribute.SetIndexedForeground(FOREGROUND_INTENSITY | FOREGROUND_BLUE | FOREGROUND_RED); + _testGetSet->_expectedAttribute.SetIndexedForeground(TextColor::BRIGHT_MAGENTA); break; case DispatchTypes::GraphicsOptions::BrightForegroundYellow: Log::Comment(L"Testing graphics 'Bright Foreground Color Yellow'"); _testGetSet->_attribute = TextAttribute{ FOREGROUND_BLUE }; _testGetSet->_expectedAttribute = _testGetSet->_attribute; - _testGetSet->_expectedAttribute.SetIndexedForeground(FOREGROUND_INTENSITY | FOREGROUND_GREEN | FOREGROUND_RED); + _testGetSet->_expectedAttribute.SetIndexedForeground(TextColor::BRIGHT_YELLOW); break; case DispatchTypes::GraphicsOptions::BrightForegroundWhite: Log::Comment(L"Testing graphics 'Bright Foreground Color White'"); _testGetSet->_attribute = TextAttribute{ 0 }; _testGetSet->_expectedAttribute = _testGetSet->_attribute; - _testGetSet->_expectedAttribute.SetIndexedForeground(FOREGROUND_INTENSITY | FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED); + _testGetSet->_expectedAttribute.SetIndexedForeground(TextColor::BRIGHT_WHITE); break; case DispatchTypes::GraphicsOptions::BrightBackgroundBlack: Log::Comment(L"Testing graphics 'Bright Background Color Black'"); _testGetSet->_attribute = TextAttribute{ BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE }; _testGetSet->_expectedAttribute = _testGetSet->_attribute; - _testGetSet->_expectedAttribute.SetIndexedBackground(BACKGROUND_INTENSITY >> 4); + _testGetSet->_expectedAttribute.SetIndexedBackground(TextColor::BRIGHT_BLACK); break; case DispatchTypes::GraphicsOptions::BrightBackgroundBlue: Log::Comment(L"Testing graphics 'Bright Background Color Blue'"); _testGetSet->_attribute = TextAttribute{ BACKGROUND_RED | BACKGROUND_GREEN }; _testGetSet->_expectedAttribute = _testGetSet->_attribute; - _testGetSet->_expectedAttribute.SetIndexedBackground((BACKGROUND_INTENSITY | BACKGROUND_BLUE) >> 4); + _testGetSet->_expectedAttribute.SetIndexedBackground(TextColor::BRIGHT_BLUE); break; case DispatchTypes::GraphicsOptions::BrightBackgroundGreen: Log::Comment(L"Testing graphics 'Bright Background Color Green'"); _testGetSet->_attribute = TextAttribute{ BACKGROUND_RED | BACKGROUND_BLUE }; _testGetSet->_expectedAttribute = _testGetSet->_attribute; - _testGetSet->_expectedAttribute.SetIndexedBackground((BACKGROUND_INTENSITY | BACKGROUND_GREEN) >> 4); + _testGetSet->_expectedAttribute.SetIndexedBackground(TextColor::BRIGHT_GREEN); break; case DispatchTypes::GraphicsOptions::BrightBackgroundCyan: Log::Comment(L"Testing graphics 'Bright Background Color Cyan'"); _testGetSet->_attribute = TextAttribute{ BACKGROUND_RED }; _testGetSet->_expectedAttribute = _testGetSet->_attribute; - _testGetSet->_expectedAttribute.SetIndexedBackground((BACKGROUND_INTENSITY | BACKGROUND_BLUE | BACKGROUND_GREEN) >> 4); + _testGetSet->_expectedAttribute.SetIndexedBackground(TextColor::BRIGHT_CYAN); break; case DispatchTypes::GraphicsOptions::BrightBackgroundRed: Log::Comment(L"Testing graphics 'Bright Background Color Red'"); _testGetSet->_attribute = TextAttribute{ BACKGROUND_BLUE | BACKGROUND_GREEN }; _testGetSet->_expectedAttribute = _testGetSet->_attribute; - _testGetSet->_expectedAttribute.SetIndexedBackground((BACKGROUND_INTENSITY | BACKGROUND_RED) >> 4); + _testGetSet->_expectedAttribute.SetIndexedBackground(TextColor::BRIGHT_RED); break; case DispatchTypes::GraphicsOptions::BrightBackgroundMagenta: Log::Comment(L"Testing graphics 'Bright Background Color Magenta'"); _testGetSet->_attribute = TextAttribute{ BACKGROUND_GREEN }; _testGetSet->_expectedAttribute = _testGetSet->_attribute; - _testGetSet->_expectedAttribute.SetIndexedBackground((BACKGROUND_INTENSITY | BACKGROUND_BLUE | BACKGROUND_RED) >> 4); + _testGetSet->_expectedAttribute.SetIndexedBackground(TextColor::BRIGHT_MAGENTA); break; case DispatchTypes::GraphicsOptions::BrightBackgroundYellow: Log::Comment(L"Testing graphics 'Bright Background Color Yellow'"); _testGetSet->_attribute = TextAttribute{ BACKGROUND_BLUE }; _testGetSet->_expectedAttribute = _testGetSet->_attribute; - _testGetSet->_expectedAttribute.SetIndexedBackground((BACKGROUND_INTENSITY | BACKGROUND_GREEN | BACKGROUND_RED) >> 4); + _testGetSet->_expectedAttribute.SetIndexedBackground(TextColor::BRIGHT_YELLOW); break; case DispatchTypes::GraphicsOptions::BrightBackgroundWhite: Log::Comment(L"Testing graphics 'Bright Background Color White'"); _testGetSet->_attribute = TextAttribute{ 0 }; _testGetSet->_expectedAttribute = _testGetSet->_attribute; - _testGetSet->_expectedAttribute.SetIndexedBackground((BACKGROUND_INTENSITY | BACKGROUND_BLUE | BACKGROUND_GREEN | BACKGROUND_RED) >> 4); + _testGetSet->_expectedAttribute.SetIndexedBackground(TextColor::BRIGHT_WHITE); break; default: VERIFY_FAIL(L"Test not implemented yet!"); @@ -1545,7 +1545,7 @@ public: cOptions = 1; rgOptions[0] = DispatchTypes::GraphicsOptions::ForegroundCyan; _testGetSet->_expectedAttribute = {}; - _testGetSet->_expectedAttribute.SetIndexedForeground(3); + _testGetSet->_expectedAttribute.SetIndexedForeground(TextColor::DARK_CYAN); _testGetSet->_expectedAttribute.SetDefaultBackground(); VERIFY_IS_TRUE(_pDispatch->SetGraphicsRendition({ rgOptions, cOptions })); @@ -1561,7 +1561,7 @@ public: cOptions = 1; rgOptions[0] = DispatchTypes::GraphicsOptions::ForegroundRed; _testGetSet->_expectedAttribute = {}; - _testGetSet->_expectedAttribute.SetIndexedForeground(FOREGROUND_RED); + _testGetSet->_expectedAttribute.SetIndexedForeground(TextColor::DARK_RED); _testGetSet->_expectedAttribute.SetDefaultBackground(); VERIFY_IS_TRUE(_pDispatch->SetGraphicsRendition({ rgOptions, cOptions })); @@ -1572,14 +1572,14 @@ public: cOptions = 1; rgOptions[0] = DispatchTypes::GraphicsOptions::ForegroundGreen; _testGetSet->_expectedAttribute = {}; - _testGetSet->_expectedAttribute.SetIndexedForeground(FOREGROUND_GREEN); + _testGetSet->_expectedAttribute.SetIndexedForeground(TextColor::DARK_GREEN); _testGetSet->_expectedAttribute.SetDefaultBackground(); VERIFY_IS_TRUE(_pDispatch->SetGraphicsRendition({ rgOptions, cOptions })); // First pop: cOptions = 0; _testGetSet->_expectedAttribute = {}; - _testGetSet->_expectedAttribute.SetIndexedForeground(FOREGROUND_RED); + _testGetSet->_expectedAttribute.SetIndexedForeground(TextColor::DARK_RED); _testGetSet->_expectedAttribute.SetDefaultBackground(); VERIFY_IS_TRUE(_pDispatch->PopGraphicsRendition()); @@ -1593,22 +1593,22 @@ public: cOptions = 1; rgOptions[0] = DispatchTypes::GraphicsOptions::ForegroundGreen; _testGetSet->_expectedAttribute = {}; - _testGetSet->_expectedAttribute.SetIndexedForeground(FOREGROUND_GREEN); + _testGetSet->_expectedAttribute.SetIndexedForeground(TextColor::DARK_GREEN); _testGetSet->_expectedAttribute.SetDefaultBackground(); VERIFY_IS_TRUE(_pDispatch->SetGraphicsRendition({ rgOptions, cOptions })); cOptions = 1; rgOptions[0] = DispatchTypes::GraphicsOptions::BoldBright; _testGetSet->_expectedAttribute = {}; - _testGetSet->_expectedAttribute.SetIndexedForeground(FOREGROUND_GREEN); + _testGetSet->_expectedAttribute.SetIndexedForeground(TextColor::DARK_GREEN); _testGetSet->_expectedAttribute.SetBold(true); _testGetSet->_expectedAttribute.SetDefaultBackground(); VERIFY_IS_TRUE(_pDispatch->SetGraphicsRendition({ rgOptions, cOptions })); rgOptions[0] = DispatchTypes::GraphicsOptions::BackgroundBlue; _testGetSet->_expectedAttribute = {}; - _testGetSet->_expectedAttribute.SetIndexedForeground(FOREGROUND_GREEN); - _testGetSet->_expectedAttribute.SetIndexedBackground(BACKGROUND_BLUE >> 4); + _testGetSet->_expectedAttribute.SetIndexedForeground(TextColor::DARK_GREEN); + _testGetSet->_expectedAttribute.SetIndexedBackground(TextColor::DARK_BLUE); _testGetSet->_expectedAttribute.SetBold(true); VERIFY_IS_TRUE(_pDispatch->SetGraphicsRendition({ rgOptions, cOptions })); @@ -1624,8 +1624,8 @@ public: rgOptions[0] = DispatchTypes::GraphicsOptions::BackgroundGreen; rgOptions[1] = DispatchTypes::GraphicsOptions::DoublyUnderlined; _testGetSet->_expectedAttribute = {}; - _testGetSet->_expectedAttribute.SetIndexedForeground(FOREGROUND_GREEN); - _testGetSet->_expectedAttribute.SetIndexedBackground(BACKGROUND_GREEN >> 4); + _testGetSet->_expectedAttribute.SetIndexedForeground(TextColor::DARK_GREEN); + _testGetSet->_expectedAttribute.SetIndexedBackground(TextColor::DARK_GREEN); _testGetSet->_expectedAttribute.SetBold(true); _testGetSet->_expectedAttribute.SetDoublyUnderlined(true); VERIFY_IS_TRUE(_pDispatch->SetGraphicsRendition({ rgOptions, cOptions })); @@ -1633,24 +1633,24 @@ public: cOptions = 1; rgOptions[0] = DispatchTypes::GraphicsOptions::ForegroundRed; _testGetSet->_expectedAttribute = {}; - _testGetSet->_expectedAttribute.SetIndexedForeground(FOREGROUND_RED); - _testGetSet->_expectedAttribute.SetIndexedBackground(BACKGROUND_GREEN >> 4); + _testGetSet->_expectedAttribute.SetIndexedForeground(TextColor::DARK_RED); + _testGetSet->_expectedAttribute.SetIndexedBackground(TextColor::DARK_GREEN); _testGetSet->_expectedAttribute.SetBold(true); _testGetSet->_expectedAttribute.SetDoublyUnderlined(true); VERIFY_IS_TRUE(_pDispatch->SetGraphicsRendition({ rgOptions, cOptions })); rgOptions[0] = DispatchTypes::GraphicsOptions::NotBoldOrFaint; _testGetSet->_expectedAttribute = {}; - _testGetSet->_expectedAttribute.SetIndexedForeground(FOREGROUND_RED); - _testGetSet->_expectedAttribute.SetIndexedBackground(BACKGROUND_GREEN >> 4); + _testGetSet->_expectedAttribute.SetIndexedForeground(TextColor::DARK_RED); + _testGetSet->_expectedAttribute.SetIndexedBackground(TextColor::DARK_GREEN); _testGetSet->_expectedAttribute.SetDoublyUnderlined(true); VERIFY_IS_TRUE(_pDispatch->SetGraphicsRendition({ rgOptions, cOptions })); // And then restore... cOptions = 0; _testGetSet->_expectedAttribute = {}; - _testGetSet->_expectedAttribute.SetIndexedForeground(FOREGROUND_RED); - _testGetSet->_expectedAttribute.SetIndexedBackground(BACKGROUND_BLUE >> 4); + _testGetSet->_expectedAttribute.SetIndexedForeground(TextColor::DARK_RED); + _testGetSet->_expectedAttribute.SetIndexedBackground(TextColor::DARK_BLUE); _testGetSet->_expectedAttribute.SetBold(true); VERIFY_IS_TRUE(_pDispatch->PopGraphicsRendition()); } @@ -1672,7 +1672,7 @@ public: Log::Comment(L"Testing graphics 'Foreground Color Blue'"); rgOptions[0] = DispatchTypes::GraphicsOptions::ForegroundBlue; - _testGetSet->_expectedAttribute.SetIndexedForeground(FOREGROUND_BLUE); + _testGetSet->_expectedAttribute.SetIndexedForeground(TextColor::DARK_BLUE); VERIFY_IS_TRUE(_pDispatch.get()->SetGraphicsRendition({ rgOptions, cOptions })); Log::Comment(L"Enabling brightness"); @@ -1683,7 +1683,7 @@ public: Log::Comment(L"Testing graphics 'Foreground Color Green, with brightness'"); rgOptions[0] = DispatchTypes::GraphicsOptions::ForegroundGreen; - _testGetSet->_expectedAttribute.SetIndexedForeground(FOREGROUND_GREEN); + _testGetSet->_expectedAttribute.SetIndexedForeground(TextColor::DARK_GREEN); VERIFY_IS_TRUE(_pDispatch.get()->SetGraphicsRendition({ rgOptions, cOptions })); VERIFY_IS_TRUE(WI_IsFlagSet(_testGetSet->_attribute.GetLegacyAttributes(), FOREGROUND_GREEN)); VERIFY_IS_TRUE(_testGetSet->_attribute.IsBold()); @@ -1698,13 +1698,13 @@ public: Log::Comment(L"Testing graphics 'Foreground Color Bright Blue'"); rgOptions[0] = DispatchTypes::GraphicsOptions::BrightForegroundBlue; - _testGetSet->_expectedAttribute.SetIndexedForeground(FOREGROUND_BLUE | FOREGROUND_INTENSITY); + _testGetSet->_expectedAttribute.SetIndexedForeground(TextColor::BRIGHT_BLUE); VERIFY_IS_TRUE(_pDispatch.get()->SetGraphicsRendition({ rgOptions, cOptions })); VERIFY_IS_FALSE(_testGetSet->_attribute.IsBold()); Log::Comment(L"Testing graphics 'Foreground Color Blue', brightness of 9x series doesn't persist"); rgOptions[0] = DispatchTypes::GraphicsOptions::ForegroundBlue; - _testGetSet->_expectedAttribute.SetIndexedForeground(FOREGROUND_BLUE); + _testGetSet->_expectedAttribute.SetIndexedForeground(TextColor::DARK_BLUE); VERIFY_IS_TRUE(_pDispatch.get()->SetGraphicsRendition({ rgOptions, cOptions })); VERIFY_IS_FALSE(_testGetSet->_attribute.IsBold()); @@ -1717,7 +1717,7 @@ public: Log::Comment(L"Testing graphics 'Foreground Color Blue'"); rgOptions[0] = DispatchTypes::GraphicsOptions::ForegroundBlue; - _testGetSet->_expectedAttribute.SetIndexedForeground(FOREGROUND_BLUE); + _testGetSet->_expectedAttribute.SetIndexedForeground(TextColor::DARK_BLUE); VERIFY_IS_TRUE(_pDispatch.get()->SetGraphicsRendition({ rgOptions, cOptions })); VERIFY_IS_FALSE(_testGetSet->_attribute.IsBold()); @@ -1729,19 +1729,19 @@ public: Log::Comment(L"Testing graphics 'Foreground Color Bright Blue'"); rgOptions[0] = DispatchTypes::GraphicsOptions::BrightForegroundBlue; - _testGetSet->_expectedAttribute.SetIndexedForeground(FOREGROUND_BLUE | FOREGROUND_INTENSITY); + _testGetSet->_expectedAttribute.SetIndexedForeground(TextColor::BRIGHT_BLUE); VERIFY_IS_TRUE(_pDispatch.get()->SetGraphicsRendition({ rgOptions, cOptions })); VERIFY_IS_TRUE(_testGetSet->_attribute.IsBold()); Log::Comment(L"Testing graphics 'Foreground Color Blue, with brightness', brightness of 9x series doesn't affect brightness"); rgOptions[0] = DispatchTypes::GraphicsOptions::ForegroundBlue; - _testGetSet->_expectedAttribute.SetIndexedForeground(FOREGROUND_BLUE); + _testGetSet->_expectedAttribute.SetIndexedForeground(TextColor::DARK_BLUE); VERIFY_IS_TRUE(_pDispatch.get()->SetGraphicsRendition({ rgOptions, cOptions })); VERIFY_IS_TRUE(_testGetSet->_attribute.IsBold()); Log::Comment(L"Testing graphics 'Foreground Color Green, with brightness'"); rgOptions[0] = DispatchTypes::GraphicsOptions::ForegroundGreen; - _testGetSet->_expectedAttribute.SetIndexedForeground(FOREGROUND_GREEN); + _testGetSet->_expectedAttribute.SetIndexedForeground(TextColor::DARK_GREEN); VERIFY_IS_TRUE(_pDispatch.get()->SetGraphicsRendition({ rgOptions, cOptions })); VERIFY_IS_TRUE(_testGetSet->_attribute.IsBold()); } @@ -1971,16 +1971,16 @@ public: Log::Comment(L"Requesting SGR attributes (standard colors)."); _testGetSet->PrepData(); _testGetSet->_attribute = {}; - _testGetSet->_attribute.SetIndexedForeground((BYTE)::XtermToWindowsIndex(3)); - _testGetSet->_attribute.SetIndexedBackground((BYTE)::XtermToWindowsIndex(6)); + _testGetSet->_attribute.SetIndexedForeground(TextColor::DARK_YELLOW); + _testGetSet->_attribute.SetIndexedBackground(TextColor::DARK_CYAN); requestSetting(L"m"); _testGetSet->ValidateInputEvent(L"\033P1$r0;33;46m\033\\"); Log::Comment(L"Requesting SGR attributes (AIX colors)."); _testGetSet->PrepData(); _testGetSet->_attribute = {}; - _testGetSet->_attribute.SetIndexedForeground((BYTE)::XtermToWindowsIndex(14)); - _testGetSet->_attribute.SetIndexedBackground((BYTE)::XtermToWindowsIndex(11)); + _testGetSet->_attribute.SetIndexedForeground(TextColor::BRIGHT_CYAN); + _testGetSet->_attribute.SetIndexedBackground(TextColor::BRIGHT_YELLOW); requestSetting(L"m"); _testGetSet->ValidateInputEvent(L"\033P1$r0;96;103m\033\\"); @@ -2297,14 +2297,14 @@ public: rgOptions[0] = DispatchTypes::GraphicsOptions::ForegroundExtended; rgOptions[1] = DispatchTypes::GraphicsOptions::BlinkOrXterm256Index; rgOptions[2] = (DispatchTypes::GraphicsOptions)2; // Green - _testGetSet->_expectedAttribute.SetIndexedForeground256((BYTE)::XtermToWindowsIndex(2)); + _testGetSet->_expectedAttribute.SetIndexedForeground256(TextColor::DARK_GREEN); 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.SetIndexedBackground256((BYTE)::XtermToWindowsIndex(9)); + _testGetSet->_expectedAttribute.SetIndexedBackground256(TextColor::BRIGHT_RED); VERIFY_IS_TRUE(_pDispatch.get()->SetGraphicsRendition({ rgOptions, cOptions })); Log::Comment(L"Test 3: Change Foreground to RGB color"); @@ -2328,7 +2328,7 @@ public: rgOptions[0] = DispatchTypes::GraphicsOptions::ForegroundExtended; rgOptions[1] = DispatchTypes::GraphicsOptions::BlinkOrXterm256Index; rgOptions[2] = (DispatchTypes::GraphicsOptions)9; // Bright Red - _testGetSet->_expectedAttribute.SetIndexedForeground256((BYTE)::XtermToWindowsIndex(9)); + _testGetSet->_expectedAttribute.SetIndexedForeground256(TextColor::BRIGHT_RED); VERIFY_IS_TRUE(_pDispatch.get()->SetGraphicsRendition({ rgOptions, cOptions })); } @@ -2346,14 +2346,14 @@ public: Log::Comment(L"Test 1: Change Indexed Foreground with missing index parameter"); rgOptions[0] = DispatchTypes::GraphicsOptions::ForegroundExtended; rgOptions[1] = DispatchTypes::GraphicsOptions::BlinkOrXterm256Index; - _testGetSet->_expectedAttribute.SetIndexedForeground256(0); + _testGetSet->_expectedAttribute.SetIndexedForeground256(TextColor::DARK_BLACK); VERIFY_IS_TRUE(_pDispatch.get()->SetGraphicsRendition({ rgOptions, 2 })); Log::Comment(L"Test 2: Change Indexed Background with default index parameter"); rgOptions[0] = DispatchTypes::GraphicsOptions::BackgroundExtended; rgOptions[1] = DispatchTypes::GraphicsOptions::BlinkOrXterm256Index; rgOptions[2] = {}; - _testGetSet->_expectedAttribute.SetIndexedBackground256(0); + _testGetSet->_expectedAttribute.SetIndexedBackground256(TextColor::DARK_BLACK); VERIFY_IS_TRUE(_pDispatch.get()->SetGraphicsRendition({ rgOptions, 3 })); Log::Comment(L"Test 3: Change RGB Foreground with all RGB parameters missing"); diff --git a/src/types/colorTable.cpp b/src/types/colorTable.cpp index 630674549..0fa05ae3c 100644 --- a/src/types/colorTable.cpp +++ b/src/types/colorTable.cpp @@ -8,7 +8,7 @@ using namespace Microsoft::Console; using namespace std::string_view_literals; -static constexpr std::array campbellColorTable{ +static constexpr std::array standard256ColorTable{ til::color{ 0x0C, 0x0C, 0x0C }, til::color{ 0xC5, 0x0F, 0x1F }, til::color{ 0x13, 0xA1, 0x0E }, @@ -25,25 +25,6 @@ static constexpr std::array campbellColorTable{ til::color{ 0xB4, 0x00, 0x9E }, til::color{ 0x61, 0xD6, 0xD6 }, til::color{ 0xF2, 0xF2, 0xF2 }, -}; - -static constexpr std::array standardXterm256ColorTable{ - til::color{ 0x00, 0x00, 0x00 }, - til::color{ 0x80, 0x00, 0x00 }, - til::color{ 0x00, 0x80, 0x00 }, - til::color{ 0x80, 0x80, 0x00 }, - til::color{ 0x00, 0x00, 0x80 }, - til::color{ 0x80, 0x00, 0x80 }, - til::color{ 0x00, 0x80, 0x80 }, - til::color{ 0xC0, 0xC0, 0xC0 }, - til::color{ 0x80, 0x80, 0x80 }, - til::color{ 0xFF, 0x00, 0x00 }, - til::color{ 0x00, 0xFF, 0x00 }, - til::color{ 0xFF, 0xFF, 0x00 }, - til::color{ 0x00, 0x00, 0xFF }, - til::color{ 0xFF, 0x00, 0xFF }, - til::color{ 0x00, 0xFF, 0xFF }, - til::color{ 0xFF, 0xFF, 0xFF }, til::color{ 0x00, 0x00, 0x00 }, til::color{ 0x00, 0x00, 0x5F }, til::color{ 0x00, 0x00, 0x87 }, @@ -454,73 +435,21 @@ static constexpr til::presorted_static_map xorgAppColorTable{ std::pair{ "yellowgreen"sv, til::color{ 154, 205, 50 } } }; -// Function Description: -// - Fill the first 16 entries of a given color table with the Campbell color -// scheme, in the ANSI/VT RGB order. -// Arguments: -// - table: a color table with at least 16 entries -// Return Value: -// - , throws if the table has less that 16 entries -void Utils::InitializeCampbellColorTable(const gsl::span table) -{ - THROW_HR_IF(E_INVALIDARG, table.size() < 16); - - std::copy(campbellColorTable.begin(), campbellColorTable.end(), table.begin()); -} - -void Utils::InitializeCampbellColorTable(const gsl::span table) -{ - THROW_HR_IF(E_INVALIDARG, table.size() < 16); - - std::copy(campbellColorTable.begin(), campbellColorTable.end(), table.begin()); -} - gsl::span Utils::CampbellColorTable() { - return gsl::make_span(campbellColorTable); + return gsl::make_span(standard256ColorTable).first(16); } // Function Description: -// - Fill the first 16 entries of a given color table with the Campbell color -// scheme, in the Windows BGR order. +// - Fill up to 256 entries of a given color table with the default values // Arguments: -// - table: a color table with at least 16 entries +// - table: a color table to be filled // Return Value: -// - , throws if the table has less that 16 entries -void Utils::InitializeCampbellColorTableForConhost(const gsl::span table) +// - +void Utils::InitializeColorTable(const gsl::span table) { - THROW_HR_IF(E_INVALIDARG, table.size() < 16); - InitializeCampbellColorTable(table); - SwapANSIColorOrderForConhost(table); -} - -// Function Description: -// - modifies in-place the given color table from ANSI (RGB) order to Console order (BRG). -// Arguments: -// - table: a color table with at least 16 entries -// Return Value: -// - , throws if the table has less that 16 entries -void Utils::SwapANSIColorOrderForConhost(const gsl::span table) -{ - THROW_HR_IF(E_INVALIDARG, table.size() < 16); - std::swap(til::at(table, 1), til::at(table, 4)); - std::swap(til::at(table, 3), til::at(table, 6)); - std::swap(til::at(table, 9), til::at(table, 12)); - std::swap(til::at(table, 11), til::at(table, 14)); -} - -// Function Description: -// - Fill the first 255 entries of a given color table with the default values -// of a full 256-color table -// Arguments: -// - table: a color table with at least 256 entries -// Return Value: -// - , throws if the table has less that 256 entries -void Utils::Initialize256ColorTable(const gsl::span table) -{ - THROW_HR_IF(E_INVALIDARG, table.size() < 256); - - std::copy(standardXterm256ColorTable.begin(), standardXterm256ColorTable.end(), table.begin()); + const auto tableSize = std::min(table.size(), standard256ColorTable.size()); + std::copy_n(standard256ColorTable.begin(), tableSize, table.begin()); } #pragma warning(push) diff --git a/src/types/inc/colorTable.hpp b/src/types/inc/colorTable.hpp index 9754fc362..9999c3768 100644 --- a/src/types/inc/colorTable.hpp +++ b/src/types/inc/colorTable.hpp @@ -12,11 +12,7 @@ Abstract: namespace Microsoft::Console::Utils { - void InitializeCampbellColorTable(const gsl::span table); - void InitializeCampbellColorTable(const gsl::span table); - void InitializeCampbellColorTableForConhost(const gsl::span table); - void SwapANSIColorOrderForConhost(const gsl::span table); - void Initialize256ColorTable(const gsl::span table); + void InitializeColorTable(const gsl::span table); gsl::span CampbellColorTable(); std::optional ColorFromXOrgAppColorName(const std::wstring_view wstr) noexcept; diff --git a/src/types/ut_types/UtilsTests.cpp b/src/types/ut_types/UtilsTests.cpp index 88b8926f6..ac8b5e974 100644 --- a/src/types/ut_types/UtilsTests.cpp +++ b/src/types/ut_types/UtilsTests.cpp @@ -20,7 +20,6 @@ class UtilsTests TEST_CLASS(UtilsTests); TEST_METHOD(TestClampToShortMax); - TEST_METHOD(TestSwapColorPalette); TEST_METHOD(TestGuidToString); TEST_METHOD(TestSplitString); TEST_METHOD(TestFilterStringForPaste); @@ -55,35 +54,6 @@ void UtilsTests::TestClampToShortMax() auto withinRangeActual = ClampToShortMax(withinRangeExpected, min); VERIFY_ARE_EQUAL(withinRangeExpected, withinRangeActual); } -void UtilsTests::TestSwapColorPalette() -{ - std::array terminalTable; - std::array consoleTable; - - gsl::span terminalTableView = { &terminalTable[0], terminalTable.size() }; - gsl::span consoleTableView = { &consoleTable[0], consoleTable.size() }; - - // First set up the colors - InitializeCampbellColorTable(terminalTableView); - InitializeCampbellColorTableForConhost(consoleTableView); - - VERIFY_ARE_EQUAL(terminalTable[0], consoleTable[0]); - VERIFY_ARE_EQUAL(terminalTable[1], consoleTable[4]); - VERIFY_ARE_EQUAL(terminalTable[2], consoleTable[2]); - VERIFY_ARE_EQUAL(terminalTable[3], consoleTable[6]); - VERIFY_ARE_EQUAL(terminalTable[4], consoleTable[1]); - VERIFY_ARE_EQUAL(terminalTable[5], consoleTable[5]); - VERIFY_ARE_EQUAL(terminalTable[6], consoleTable[3]); - VERIFY_ARE_EQUAL(terminalTable[7], consoleTable[7]); - VERIFY_ARE_EQUAL(terminalTable[8], consoleTable[8]); - VERIFY_ARE_EQUAL(terminalTable[9], consoleTable[12]); - VERIFY_ARE_EQUAL(terminalTable[10], consoleTable[10]); - VERIFY_ARE_EQUAL(terminalTable[11], consoleTable[14]); - VERIFY_ARE_EQUAL(terminalTable[12], consoleTable[9]); - VERIFY_ARE_EQUAL(terminalTable[13], consoleTable[13]); - VERIFY_ARE_EQUAL(terminalTable[14], consoleTable[11]); - VERIFY_ARE_EQUAL(terminalTable[15], consoleTable[15]); -} void UtilsTests::TestGuidToString() {