From b604117421f92ac01c8a7119fb1985fee383b8d1 Mon Sep 17 00:00:00 2001 From: James Holderness Date: Thu, 4 Nov 2021 22:13:22 +0000 Subject: [PATCH] Standardize the color table order (#11602) ## Summary of the Pull Request In the original implementation, we used two different orderings for the color tables. The WT color table used ANSI order, while the conhost color table used a Windows-specific order. This PR standardizes on the ANSI color order everywhere, so the usage of indexed colors is consistent across both parts of the code base, which will hopefully allow more of the code to be shared one day. ## References This is another small step towards de-duplicating `AdaptDispatch` and `TerminalDispatch` for issue #3849, and is essentially a followup to the SGR dispatch refactoring in PR #6728. ## PR Checklist * [x] Closes #11461 * [x] CLA signed. * [x] Tests added/passed * [ ] Documentation updated. * [ ] Schema updated. * [x] I've discussed this with core contributors already. Issue number where discussion took place: #11461 ## Detailed Description of the Pull Request / Additional comments Conhost still needs to deal with legacy attributes using Windows color order, so those values now need to be transposed to ANSI colors order when creating a `TextAttribute` object. This is done with a simple mapping table, which also handles the translation of the default color entries, so it's actually slightly faster than the original code. And when converting `TextAttribute` values back to legacy console attributes, we were already using a mapping table to handle the narrowing of 256-color values down to 16 colors, so we just needed to adjust that table to account for the translation from ANSI to Windows, and then could make use of the same table for both 256-color and 16-color values. There are also a few places in conhost that read from or write to the color tables, and those now need to transpose the index values. I've addressed this by creating separate `SetLegacyColorTableEntry` and `GetLegacyColorTableEntry` methods in the `Settings` class which take care of the mapping, so it's now clearer in which cases the code is dealing with legacy values, and which are ANSI values. These methods are used in the `SetConsoleScreenBufferInfoEx` and `GetConsoleScreenBufferInfoEx` APIs, as well as a few place where color preferences are handled (the registry, shortcut links, and the properties dialog), none of which are particularly sensitive to performance. However, we also use the legacy table when looking up the default colors for rendering (which happens a lot), so I've refactored that code so the default color calculations now only occur once per frame. The plus side of all of this is that the VT code doesn't need to do the index translation anymore, so we can finally get rid of all the calls to `XTermToWindowsIndex`, and we no longer need a separate color table initialization method for conhost, so I was able to merge a number of color initialization methods into one. We also no longer need to translate from legacy values to ANSI when generating VT sequences for conpty. The one exception to that is the 16-color VT renderer, which uses the `TextColor::GetLegacyIndex` method to approximate 16-color equivalents for RGB and 256-color values. Since that method returns a legacy index, it still needs to be translated to ANSI before it can be used in a VT sequence. But this should be no worse than it was before. One more special case is conhost's secret _Color Selection_ feature. That uses `Ctrl`+Number and `Alt`+Number key sequences to highlight parts of the buffer, and the mapping from number to color is based on the Windows color order. So that mapping now needs to be transposed, but that's also not performance sensitive. The only thing that I haven't bothered to update is the trace logging code in the `Telemetry` class, which logs the first 16 entries in the color table. Those entries are now going to be in a different order, but I didn't think that would be of great concern to anyone. ## Validation Steps Performed A lot of unit tests needed to be updated to use ANSI color constants when setting indexed colors, where before they might have been expecting values in Windows order. But this replaced a wild mix of different constants, sometimes having to use bit shifting, as well as values mapped with `XTermToWindowsIndex`, so I think the tests are a whole lot clearer now. Only a few cases have been left with literal numbers where that seemed more appropriate. In addition to getting the unit tests working, I've also manually tested the behaviour of all the console APIs which I thought could be affected by these changes, and confirmed that they produced the same results in the new code as they did in the original implementation. This includes: - `WriteConsoleOutput` - `ReadConsoleOutput` - `SetConsoleTextAttribute` with `WriteConsoleOutputCharacter` - `FillConsoleOutputAttribute` and `FillConsoleOutputCharacter` - `ScrollConsoleScreenBuffer` - `GetConsoleScreenBufferInfo` - `GetConsoleScreenBufferInfoEx` - `SetConsoleScreenBufferInfoEx` I've also manually tested changing colors via the console properties menu, the registry, and shortcut links, including setting default colors and popup colors. And I've tested that the "Quirks Mode" is still working as expected in PowerShell. In terms of performance, I wrote a little test app that filled a 80x9999 buffer with random color combinations using `WriteConsoleOutput`, which I figured was likely to be the most performance sensitive call, and I think it now actually performs slightly better than the original implementation. I've also tested similar code - just filling the visible window - with SGR VT sequences of various types, and the performance seems about the same as it was before. --- src/buffer/out/TextAttribute.cpp | 46 ++++++- src/buffer/out/TextAttribute.hpp | 13 +- src/buffer/out/TextColor.cpp | 8 +- src/buffer/out/TextColor.h | 27 ++++ .../out/ut_textbuffer/TextAttributeTests.cpp | 10 +- .../ColorSchemeTests.cpp | 2 +- src/cascadia/TerminalCore/Terminal.cpp | 4 +- .../TerminalCore/TerminalDispatchGraphics.cpp | 87 +++++------- .../ConptyRoundtripTests.cpp | 24 ++-- src/host/conattrs.cpp | 52 ------- src/host/consoleInformation.cpp | 24 +++- src/host/getset.cpp | 6 +- src/host/host-common.vcxitems | 1 - src/host/lib/hostlib.vcxproj.filters | 3 - src/host/registry.cpp | 2 +- src/host/renderData.cpp | 4 +- src/host/renderData.hpp | 5 + src/host/screenInfo.cpp | 2 +- src/host/selectionInput.cpp | 6 +- src/host/server.h | 1 + src/host/settings.cpp | 31 +++-- src/host/settings.hpp | 2 + src/host/sources.inc | 1 - src/host/ut_host/ScreenBufferTests.cpp | 72 +++++----- src/host/ut_host/TextBufferTests.cpp | 36 ++--- src/host/ut_host/VtRendererTests.cpp | 24 ++-- src/inc/conattrs.hpp | 14 -- src/interactivity/win32/Clipboard.cpp | 6 +- src/interactivity/win32/menu.cpp | 4 +- src/renderer/vt/VtSequences.cpp | 23 ++-- src/renderer/vt/paint.cpp | 7 +- src/renderer/vt/vtrenderer.hpp | 4 +- src/terminal/adapter/adaptDispatch.cpp | 4 +- .../adapter/adaptDispatchGraphics.cpp | 89 +++++------- .../adapter/ut_adapter/adapterTest.cpp | 130 +++++++++--------- src/types/colorTable.cpp | 87 ++---------- src/types/inc/colorTable.hpp | 6 +- src/types/ut_types/UtilsTests.cpp | 30 ---- 38 files changed, 377 insertions(+), 520 deletions(-) delete mode 100644 src/host/conattrs.cpp 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() {