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.
This commit is contained in:
James Holderness 2021-11-04 22:13:22 +00:00 committed by GitHub
parent 761203d95e
commit b604117421
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
38 changed files with 377 additions and 520 deletions

View file

@ -12,8 +12,30 @@ static_assert(alignof(TextAttribute) == 2);
// Ensure that we can memcpy() and memmove() the struct for performance. // Ensure that we can memcpy() and memmove() the struct for performance.
static_assert(std::is_trivially_copyable_v<TextAttribute>); static_assert(std::is_trivially_copyable_v<TextAttribute>);
BYTE TextAttribute::s_legacyDefaultForeground = 7; namespace
BYTE TextAttribute::s_legacyDefaultBackground = 0; {
constexpr std::array<TextColor, 16> s_initLegacyColorMap(const BYTE defaultIndex)
{
std::array<TextColor, 16> 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<TextColor, 16> TextAttribute::s_legacyForegroundColorMap = s_initLegacyColorMap(7);
std::array<TextColor, 16> TextAttribute::s_legacyBackgroundColorMap = s_initLegacyColorMap(0);
// Routine Description: // Routine Description:
// - Sets the legacy attributes which map to and from the default colors. // - Sets the legacy attributes which map to and from the default colors.
@ -23,8 +45,22 @@ BYTE TextAttribute::s_legacyDefaultBackground = 0;
// - None // - None
void TextAttribute::SetLegacyDefaultAttributes(const WORD defaultAttributes) noexcept 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_legacyDefaultForeground = defaultAttributes & FG_ATTRS;
s_legacyDefaultBackground = (defaultAttributes & BG_ATTRS) >> 4; 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: // Routine Description:
@ -55,13 +91,13 @@ TextAttribute TextAttribute::StripErroneousVT16VersionsOfLegacyDefaults(const Te
const auto bg{ attribute.GetBackground() }; const auto bg{ attribute.GetBackground() };
auto copy{ attribute }; auto copy{ attribute };
if (fg.IsIndex16() && if (fg.IsIndex16() &&
attribute.IsBold() == WI_IsFlagSet(s_legacyDefaultForeground, FOREGROUND_INTENSITY) && attribute.IsBold() == WI_IsFlagSet(s_ansiDefaultForeground, FOREGROUND_INTENSITY) &&
fg.GetIndex() == (s_legacyDefaultForeground & ~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. // 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(); copy.SetDefaultForeground();
} }
if (bg.IsIndex16() && bg.GetIndex() == s_legacyDefaultBackground) if (bg.IsIndex16() && bg.GetIndex() == s_ansiDefaultBackground)
{ {
copy.SetDefaultBackground(); copy.SetDefaultBackground();
} }

View file

@ -41,8 +41,8 @@ public:
explicit constexpr TextAttribute(const WORD wLegacyAttr) noexcept : explicit constexpr TextAttribute(const WORD wLegacyAttr) noexcept :
_wAttrLegacy{ gsl::narrow_cast<WORD>(wLegacyAttr & META_ATTRS) }, _wAttrLegacy{ gsl::narrow_cast<WORD>(wLegacyAttr & META_ATTRS) },
_foreground{ s_LegacyIndexOrDefault(wLegacyAttr & FG_ATTRS, s_legacyDefaultForeground) }, _foreground{ gsl::at(s_legacyForegroundColorMap, wLegacyAttr & FG_ATTRS) },
_background{ s_LegacyIndexOrDefault((wLegacyAttr & BG_ATTRS) >> 4, s_legacyDefaultBackground) }, _background{ gsl::at(s_legacyBackgroundColorMap, (wLegacyAttr & BG_ATTRS) >> 4) },
_extendedAttrs{ ExtendedAttributes::Normal }, _extendedAttrs{ ExtendedAttributes::Normal },
_hyperlinkId{ 0 } _hyperlinkId{ 0 }
{ {
@ -167,13 +167,8 @@ public:
} }
private: private:
static constexpr TextColor s_LegacyIndexOrDefault(const BYTE requestedIndex, const BYTE defaultIndex) static std::array<TextColor, 16> s_legacyForegroundColorMap;
{ static std::array<TextColor, 16> s_legacyBackgroundColorMap;
return requestedIndex == defaultIndex ? TextColor{} : TextColor{ requestedIndex, true };
}
static BYTE s_legacyDefaultForeground;
static BYTE s_legacyDefaultBackground;
uint16_t _wAttrLegacy; // sizeof: 2, alignof: 2 uint16_t _wAttrLegacy; // sizeof: 2, alignof: 2
uint16_t _hyperlinkId; // sizeof: 2, alignof: 2 uint16_t _hyperlinkId; // sizeof: 2, alignof: 2

View file

@ -32,7 +32,7 @@ constexpr std::array<BYTE, 256> CompressedRgbToIndex16 = {
// A table mapping indexed colors from the 256-color palette, // A table mapping indexed colors from the 256-color palette,
// down to one of the 16 colors in the legacy palette. // down to one of the 16 colors in the legacy palette.
constexpr std::array<BYTE, 256> Index256ToIndex16 = { constexpr std::array<BYTE, 256> 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, 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, 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, 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; return defaultIndex;
} }
else if (IsIndex16()) else if (IsIndex16() || IsIndex256())
{
return GetIndex();
}
else if (IsIndex256())
{ {
return til::at(Index256ToIndex16, GetIndex()); return til::at(Index256ToIndex16, GetIndex());
} }

View file

@ -48,6 +48,23 @@ enum class ColorType : BYTE
struct TextColor struct TextColor
{ {
public: 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 : constexpr TextColor() noexcept :
_meta{ ColorType::IsDefault }, _meta{ ColorType::IsDefault },
_red{ 0 }, _red{ 0 },
@ -96,6 +113,16 @@ public:
COLORREF GetRGB() const noexcept; 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<BYTE>(index ^ oneBitSet ^ (oneBitSet << 2));
}
private: private:
union union
{ {

View file

@ -237,7 +237,7 @@ void TextAttributeTests::TestRoundtripDefaultColors()
Log::Comment(L"Foreground legacy default index should map to default text color."); Log::Comment(L"Foreground legacy default index should map to default text color.");
legacyAttribute = fgLegacyDefault | BACKGROUND_GREEN; legacyAttribute = fgLegacyDefault | BACKGROUND_GREEN;
textAttribute.SetDefaultForeground(); textAttribute.SetDefaultForeground();
textAttribute.SetIndexedBackground256(BACKGROUND_GREEN >> 4); textAttribute.SetIndexedBackground256(TextColor::DARK_GREEN);
VERIFY_ARE_EQUAL(textAttribute, TextAttribute{ legacyAttribute }); VERIFY_ARE_EQUAL(textAttribute, TextAttribute{ legacyAttribute });
Log::Comment(L"Default foreground text color should map back to legacy default index."); 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."); Log::Comment(L"Background legacy default index should map to default text color.");
legacyAttribute = FOREGROUND_GREEN | bgLegacyDefault; legacyAttribute = FOREGROUND_GREEN | bgLegacyDefault;
textAttribute.SetIndexedForeground256(FOREGROUND_GREEN); textAttribute.SetIndexedForeground256(TextColor::DARK_GREEN);
textAttribute.SetDefaultBackground(); textAttribute.SetDefaultBackground();
VERIFY_ARE_EQUAL(textAttribute, TextAttribute{ legacyAttribute }); 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, true));
VERIFY_ARE_EQUAL(std::make_pair(_defaultFg, _defaultBg), attr.CalculateRgbColors(_colorTable, _defaultFg, _defaultBg, false, false, false)); 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()); VERIFY_IS_TRUE(attr.IsBold());
Log::Comment(L"Foreground should be bright black when bold is bright is enabled"); 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"); 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)); 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()); VERIFY_IS_TRUE(attr.IsBold());
Log::Comment(L"background should be unaffected by 'bold is bright'"); 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"); Log::Comment(L"When set to a bright color, and bold, 'bold is bright' changes nothing");
attr.SetBold(true); attr.SetBold(true);
attr.SetIndexedForeground(8); attr.SetIndexedForeground(TextColor::BRIGHT_BLACK);
VERIFY_IS_TRUE(attr.IsBold()); 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, true));
VERIFY_ARE_EQUAL(std::make_pair(brightBlack, darkGreen), attr.CalculateRgbColors(_colorTable, _defaultFg, _defaultBg, false, false, false)); VERIFY_ARE_EQUAL(std::make_pair(brightBlack, darkGreen), attr.CalculateRgbColors(_colorTable, _defaultFg, _defaultBg, false, false, false));

View file

@ -80,7 +80,7 @@ namespace SettingsModelLocalTests
std::array<COLORREF, COLOR_TABLE_SIZE> expectedCampbellTable; std::array<COLORREF, COLOR_TABLE_SIZE> expectedCampbellTable;
const auto campbellSpan = gsl::make_span(expectedCampbellTable); const auto campbellSpan = gsl::make_span(expectedCampbellTable);
Utils::InitializeCampbellColorTable(campbellSpan); Utils::InitializeColorTable(campbellSpan);
Utils::SetColorTableAlpha(campbellSpan, 0); Utils::SetColorTableAlpha(campbellSpan, 0);
for (size_t i = 0; i < expectedCampbellTable.size(); i++) for (size_t i = 0; i < expectedCampbellTable.size(); i++)

View file

@ -1210,9 +1210,7 @@ try
{ {
const gsl::span<COLORREF> tableView = { _colorTable.data(), _colorTable.size() }; const gsl::span<COLORREF> tableView = { _colorTable.data(), _colorTable.size() };
// First set up the basic 256 colors // First set up the basic 256 colors
Utils::Initialize256ColorTable(tableView); Utils::InitializeColorTable(tableView);
// Then use fill the first 16 values with the Campbell scheme
Utils::InitializeCampbellColorTable(tableView);
// Then make sure all the values have an alpha of 255 // Then make sure all the values have an alpha of 255
Utils::SetColorTableAlpha(tableView, 0xff); Utils::SetColorTableAlpha(tableView, 0xff);
} }

View file

@ -7,29 +7,6 @@
using namespace Microsoft::Console::VirtualTerminal; using namespace Microsoft::Console::VirtualTerminal;
using namespace Microsoft::Console::VirtualTerminal::DispatchTypes; 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: // Routine Description:
// - Helper to parse extended graphics options, which start with 38 (FG) or 48 (BG) // - 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) // 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); attr.SetOverlined(false);
break; break;
case ForegroundBlack: case ForegroundBlack:
attr.SetIndexedForeground(DARK_BLACK); attr.SetIndexedForeground(TextColor::DARK_BLACK);
break; break;
case ForegroundBlue: case ForegroundBlue:
attr.SetIndexedForeground(DARK_BLUE); attr.SetIndexedForeground(TextColor::DARK_BLUE);
break; break;
case ForegroundGreen: case ForegroundGreen:
attr.SetIndexedForeground(DARK_GREEN); attr.SetIndexedForeground(TextColor::DARK_GREEN);
break; break;
case ForegroundCyan: case ForegroundCyan:
attr.SetIndexedForeground(DARK_CYAN); attr.SetIndexedForeground(TextColor::DARK_CYAN);
break; break;
case ForegroundRed: case ForegroundRed:
attr.SetIndexedForeground(DARK_RED); attr.SetIndexedForeground(TextColor::DARK_RED);
break; break;
case ForegroundMagenta: case ForegroundMagenta:
attr.SetIndexedForeground(DARK_MAGENTA); attr.SetIndexedForeground(TextColor::DARK_MAGENTA);
break; break;
case ForegroundYellow: case ForegroundYellow:
attr.SetIndexedForeground(DARK_YELLOW); attr.SetIndexedForeground(TextColor::DARK_YELLOW);
break; break;
case ForegroundWhite: case ForegroundWhite:
attr.SetIndexedForeground(DARK_WHITE); attr.SetIndexedForeground(TextColor::DARK_WHITE);
break; break;
case BackgroundBlack: case BackgroundBlack:
attr.SetIndexedBackground(DARK_BLACK); attr.SetIndexedBackground(TextColor::DARK_BLACK);
break; break;
case BackgroundBlue: case BackgroundBlue:
attr.SetIndexedBackground(DARK_BLUE); attr.SetIndexedBackground(TextColor::DARK_BLUE);
break; break;
case BackgroundGreen: case BackgroundGreen:
attr.SetIndexedBackground(DARK_GREEN); attr.SetIndexedBackground(TextColor::DARK_GREEN);
break; break;
case BackgroundCyan: case BackgroundCyan:
attr.SetIndexedBackground(DARK_CYAN); attr.SetIndexedBackground(TextColor::DARK_CYAN);
break; break;
case BackgroundRed: case BackgroundRed:
attr.SetIndexedBackground(DARK_RED); attr.SetIndexedBackground(TextColor::DARK_RED);
break; break;
case BackgroundMagenta: case BackgroundMagenta:
attr.SetIndexedBackground(DARK_MAGENTA); attr.SetIndexedBackground(TextColor::DARK_MAGENTA);
break; break;
case BackgroundYellow: case BackgroundYellow:
attr.SetIndexedBackground(DARK_YELLOW); attr.SetIndexedBackground(TextColor::DARK_YELLOW);
break; break;
case BackgroundWhite: case BackgroundWhite:
attr.SetIndexedBackground(DARK_WHITE); attr.SetIndexedBackground(TextColor::DARK_WHITE);
break; break;
case BrightForegroundBlack: case BrightForegroundBlack:
attr.SetIndexedForeground(BRIGHT_BLACK); attr.SetIndexedForeground(TextColor::BRIGHT_BLACK);
break; break;
case BrightForegroundBlue: case BrightForegroundBlue:
attr.SetIndexedForeground(BRIGHT_BLUE); attr.SetIndexedForeground(TextColor::BRIGHT_BLUE);
break; break;
case BrightForegroundGreen: case BrightForegroundGreen:
attr.SetIndexedForeground(BRIGHT_GREEN); attr.SetIndexedForeground(TextColor::BRIGHT_GREEN);
break; break;
case BrightForegroundCyan: case BrightForegroundCyan:
attr.SetIndexedForeground(BRIGHT_CYAN); attr.SetIndexedForeground(TextColor::BRIGHT_CYAN);
break; break;
case BrightForegroundRed: case BrightForegroundRed:
attr.SetIndexedForeground(BRIGHT_RED); attr.SetIndexedForeground(TextColor::BRIGHT_RED);
break; break;
case BrightForegroundMagenta: case BrightForegroundMagenta:
attr.SetIndexedForeground(BRIGHT_MAGENTA); attr.SetIndexedForeground(TextColor::BRIGHT_MAGENTA);
break; break;
case BrightForegroundYellow: case BrightForegroundYellow:
attr.SetIndexedForeground(BRIGHT_YELLOW); attr.SetIndexedForeground(TextColor::BRIGHT_YELLOW);
break; break;
case BrightForegroundWhite: case BrightForegroundWhite:
attr.SetIndexedForeground(BRIGHT_WHITE); attr.SetIndexedForeground(TextColor::BRIGHT_WHITE);
break; break;
case BrightBackgroundBlack: case BrightBackgroundBlack:
attr.SetIndexedBackground(BRIGHT_BLACK); attr.SetIndexedBackground(TextColor::BRIGHT_BLACK);
break; break;
case BrightBackgroundBlue: case BrightBackgroundBlue:
attr.SetIndexedBackground(BRIGHT_BLUE); attr.SetIndexedBackground(TextColor::BRIGHT_BLUE);
break; break;
case BrightBackgroundGreen: case BrightBackgroundGreen:
attr.SetIndexedBackground(BRIGHT_GREEN); attr.SetIndexedBackground(TextColor::BRIGHT_GREEN);
break; break;
case BrightBackgroundCyan: case BrightBackgroundCyan:
attr.SetIndexedBackground(BRIGHT_CYAN); attr.SetIndexedBackground(TextColor::BRIGHT_CYAN);
break; break;
case BrightBackgroundRed: case BrightBackgroundRed:
attr.SetIndexedBackground(BRIGHT_RED); attr.SetIndexedBackground(TextColor::BRIGHT_RED);
break; break;
case BrightBackgroundMagenta: case BrightBackgroundMagenta:
attr.SetIndexedBackground(BRIGHT_MAGENTA); attr.SetIndexedBackground(TextColor::BRIGHT_MAGENTA);
break; break;
case BrightBackgroundYellow: case BrightBackgroundYellow:
attr.SetIndexedBackground(BRIGHT_YELLOW); attr.SetIndexedBackground(TextColor::BRIGHT_YELLOW);
break; break;
case BrightBackgroundWhite: case BrightBackgroundWhite:
attr.SetIndexedBackground(BRIGHT_WHITE); attr.SetIndexedBackground(TextColor::BRIGHT_WHITE);
break; break;
case ForegroundExtended: case ForegroundExtended:
i += _SetRgbColorsHelper(options.subspan(i + 1), attr, true); i += _SetRgbColorsHelper(options.subspan(i + 1), attr, true);

View file

@ -2901,15 +2901,9 @@ void ConptyRoundtripTests::ResizeInitializeBufferWithDefaultAttrs()
auto defaultAttrs = si.GetAttributes(); auto defaultAttrs = si.GetAttributes();
auto conhostGreenAttrs = TextAttribute(); auto conhostGreenAttrs = TextAttribute();
conhostGreenAttrs.SetIndexedBackground(TextColor::DARK_GREEN);
// Conhost and Terminal store attributes in different bits.
// conhostGreenAttrs.SetIndexedAttributes(std::nullopt,
// { static_cast<BYTE>(FOREGROUND_GREEN) });
conhostGreenAttrs.SetIndexedBackground(FOREGROUND_GREEN);
auto terminalGreenAttrs = TextAttribute(); auto terminalGreenAttrs = TextAttribute();
// terminalGreenAttrs.SetIndexedAttributes(std::nullopt, terminalGreenAttrs.SetIndexedBackground(TextColor::DARK_GREEN);
// { static_cast<BYTE>(XTERM_GREEN_ATTR) });
terminalGreenAttrs.SetIndexedBackground(XTERM_GREEN_ATTR);
// Use an initial ^[[m to start printing with default-on-default // Use an initial ^[[m to start printing with default-on-default
sm.ProcessString(L"\x1b[m"); 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) { auto verifyBuffer = [&](const TextBuffer& tb, const til::rectangle viewport, const bool isTerminal, const bool afterResize) {
const auto width = viewport.width<short>(); const auto width = viewport.width<short>();
// Conhost and Terminal store attributes in different bits. // Conhost and Terminal attributes are potentially different.
const auto greenAttrs = isTerminal ? terminalGreenAttrs : conhostGreenAttrs; const auto greenAttrs = isTerminal ? terminalGreenAttrs : conhostGreenAttrs;
for (short row = 0; row < tb.GetSize().Height(); row++) for (short row = 0; row < tb.GetSize().Height(); row++)
@ -3034,13 +3028,11 @@ void ConptyRoundtripTests::NewLinesAtBottomWithBackground()
auto defaultAttrs = si.GetAttributes(); auto defaultAttrs = si.GetAttributes();
auto conhostBlueAttrs = defaultAttrs; auto conhostBlueAttrs = defaultAttrs;
conhostBlueAttrs.SetIndexedForeground(TextColor::DARK_GREEN);
// Conhost and Terminal store attributes in different bits. conhostBlueAttrs.SetIndexedBackground(TextColor::DARK_BLUE);
conhostBlueAttrs.SetIndexedForeground(FOREGROUND_GREEN);
conhostBlueAttrs.SetIndexedBackground(FOREGROUND_BLUE);
auto terminalBlueAttrs = TextAttribute(); auto terminalBlueAttrs = TextAttribute();
terminalBlueAttrs.SetIndexedForeground(XTERM_GREEN_ATTR); terminalBlueAttrs.SetIndexedForeground(TextColor::DARK_GREEN);
terminalBlueAttrs.SetIndexedBackground(XTERM_BLUE_ATTR); terminalBlueAttrs.SetIndexedBackground(TextColor::DARK_BLUE);
// We're going to print 4 more rows than the entire height of the viewport, // 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 // 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<short>(); const auto width = viewport.width<short>();
const auto isTerminal = viewport.top() != 0; 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; const auto blueAttrs = isTerminal ? terminalBlueAttrs : conhostBlueAttrs;
for (short row = 0; row < viewport.bottom<short>() - 2; row++) for (short row = 0; row < viewport.bottom<short>() - 2; row++)

View file

@ -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 <cmath>
// 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<WORD>(xtermTableEntry);
}

View file

@ -231,7 +231,7 @@ InputBuffer* const CONSOLE_INFORMATION::GetActiveInputBuffer() const
COLORREF CONSOLE_INFORMATION::GetDefaultForeground() const noexcept COLORREF CONSOLE_INFORMATION::GetDefaultForeground() const noexcept
{ {
const auto fg = GetDefaultForegroundColor(); 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: // Method Description:
@ -246,23 +246,37 @@ COLORREF CONSOLE_INFORMATION::GetDefaultForeground() const noexcept
COLORREF CONSOLE_INFORMATION::GetDefaultBackground() const noexcept COLORREF CONSOLE_INFORMATION::GetDefaultBackground() const noexcept
{ {
const auto bg = GetDefaultBackgroundColor(); 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: // Method Description:
// - Get the colors of a particular text attribute, using our color table, // - Get the colors of a particular text attribute, using our color table,
// and our configured default attributes. // and our configured default attributes.
// Arguments: // Arguments:
// - attr: the TextAttribute to retrieve the foreground color of. // - attr: the TextAttribute to retrieve the foreground and background color of.
// Return Value: // Return Value:
// - The color values of the attribute's foreground and background. // - The color values of the attribute's foreground and background.
std::pair<COLORREF, COLORREF> CONSOLE_INFORMATION::LookupAttributeColors(const TextAttribute& attr) const noexcept std::pair<COLORREF, COLORREF> 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<COLORREF, COLORREF> CONSOLE_INFORMATION::LookupAttributeColors(const TextAttribute& attr, const COLORREF defaultFg, const COLORREF defaultBg) const noexcept
{ {
_blinkingState.RecordBlinkingUsage(attr); _blinkingState.RecordBlinkingUsage(attr);
return attr.CalculateRgbColors( return attr.CalculateRgbColors(
GetColorTable(), GetColorTable(),
GetDefaultForeground(), defaultFg,
GetDefaultBackground(), defaultBg,
IsScreenReversed(), IsScreenReversed(),
_blinkingState.IsBlinkingFaint()); _blinkingState.IsBlinkingFaint());
} }

View file

@ -605,7 +605,7 @@ void ApiRoutines::GetLargestConsoleWindowSizeImpl(const SCREEN_INFORMATION& cont
for (size_t i = 0; i < std::size(data.ColorTable); i++) 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 }); context.SetDefaultAttributes(TextAttribute{ data.wAttributes }, TextAttribute{ data.wPopupAttributes });
@ -1978,7 +1978,7 @@ void DoSrvPrivateMoveToBottom(SCREEN_INFORMATION& screenInfo)
Globals& g = ServiceLocator::LocateGlobals(); Globals& g = ServiceLocator::LocateGlobals();
CONSOLE_INFORMATION& gci = g.getConsoleInformation(); CONSOLE_INFORMATION& gci = g.getConsoleInformation();
value = gci.GetColorTableEntry(::Xterm256ToWindowsIndex(index)); value = gci.GetColorTableEntry(index);
return S_OK; return S_OK;
} }
@ -2004,7 +2004,7 @@ void DoSrvPrivateMoveToBottom(SCREEN_INFORMATION& screenInfo)
Globals& g = ServiceLocator::LocateGlobals(); Globals& g = ServiceLocator::LocateGlobals();
CONSOLE_INFORMATION& gci = g.getConsoleInformation(); CONSOLE_INFORMATION& gci = g.getConsoleInformation();
gci.SetColorTableEntry(::Xterm256ToWindowsIndex(index), value); gci.SetColorTableEntry(index, value);
// Update the screen colors if we're not a pty // Update the screen colors if we're not a pty
// No need to force a redraw in pty mode. // No need to force a redraw in pty mode.

View file

@ -7,7 +7,6 @@
<ClCompile Include="..\CommandListPopup.cpp" /> <ClCompile Include="..\CommandListPopup.cpp" />
<ClCompile Include="..\CopyFromCharPopup.cpp" /> <ClCompile Include="..\CopyFromCharPopup.cpp" />
<ClCompile Include="..\CopyToCharPopup.cpp" /> <ClCompile Include="..\CopyToCharPopup.cpp" />
<ClCompile Include="..\conattrs.cpp" />
<ClCompile Include="..\ConsoleArguments.cpp" /> <ClCompile Include="..\ConsoleArguments.cpp" />
<ClCompile Include="..\CursorBlinker.cpp" /> <ClCompile Include="..\CursorBlinker.cpp" />
<ClCompile Include="..\readDataCooked.cpp" /> <ClCompile Include="..\readDataCooked.cpp" />

View file

@ -138,9 +138,6 @@
<ClCompile Include="..\writeData.cpp"> <ClCompile Include="..\writeData.cpp">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\conattrs.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\VtInputThread.cpp"> <ClCompile Include="..\VtInputThread.cpp">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>

View file

@ -310,7 +310,7 @@ void Registry::LoadFromRegistry(_In_ PCWSTR const pwszConsoleTitle)
nullptr); nullptr);
if (NT_SUCCESS(Status)) if (NT_SUCCESS(Status))
{ {
_pSettings->SetColorTableEntry(i, dwValue); _pSettings->SetLegacyColorTableEntry(i, dwValue);
} }
} }

View file

@ -110,6 +110,8 @@ void RenderData::UnlockConsole() noexcept
const TextAttribute RenderData::GetDefaultBrushColors() noexcept const TextAttribute RenderData::GetDefaultBrushColors() noexcept
{ {
const CONSOLE_INFORMATION& gci = ServiceLocator::LocateGlobals().getConsoleInformation(); const CONSOLE_INFORMATION& gci = ServiceLocator::LocateGlobals().getConsoleInformation();
_defaultForeground = gci.GetDefaultForeground();
_defaultBackground = gci.GetDefaultBackground();
return gci.GetActiveOutputBuffer().GetAttributes(); return gci.GetActiveOutputBuffer().GetAttributes();
} }
@ -362,7 +364,7 @@ const std::vector<size_t> RenderData::GetPatternId(const COORD /*location*/) con
std::pair<COLORREF, COLORREF> RenderData::GetAttributeColors(const TextAttribute& attr) const noexcept std::pair<COLORREF, COLORREF> RenderData::GetAttributeColors(const TextAttribute& attr) const noexcept
{ {
const CONSOLE_INFORMATION& gci = ServiceLocator::LocateGlobals().getConsoleInformation(); const CONSOLE_INFORMATION& gci = ServiceLocator::LocateGlobals().getConsoleInformation();
return gci.LookupAttributeColors(attr); return gci.LookupAttributeColors(attr, _defaultForeground, _defaultBackground);
} }
#pragma endregion #pragma endregion

View file

@ -15,6 +15,7 @@ Author(s):
#pragma once #pragma once
#include "../renderer/inc/IRenderData.hpp" #include "../renderer/inc/IRenderData.hpp"
#include "../types/inc/colorTable.hpp"
#include "../types/IUiaData.h" #include "../types/IUiaData.h"
class RenderData final : class RenderData final :
@ -71,4 +72,8 @@ public:
void ColorSelection(const COORD coordSelectionStart, const COORD coordSelectionEnd, const TextAttribute attr); void ColorSelection(const COORD coordSelectionStart, const COORD coordSelectionEnd, const TextAttribute attr);
const bool IsUiaDataInitialized() const noexcept override { return true; } const bool IsUiaDataInitialized() const noexcept override { return true; }
#pragma endregion #pragma endregion
private:
COLORREF _defaultForeground = gsl::at(Microsoft::Console::Utils::CampbellColorTable(), 7);
COLORREF _defaultBackground = gsl::at(Microsoft::Console::Utils::CampbellColorTable(), 0);
}; };

View file

@ -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. // 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++) for (size_t i = 0; i < COLOR_TABLE_SIZE; i++)
{ {
lpColorTable[i] = gci.GetColorTableEntry(i); lpColorTable[i] = gci.GetLegacyColorTableEntry(i);
} }
*pcoordMaximumWindowSize = GetMaxWindowSizeInCharacters(); *pcoordMaximumWindowSize = GetMaxWindowSizeInCharacters();

View file

@ -661,13 +661,15 @@ bool Selection::_HandleColorSelection(const INPUT_KEY_INFO* const pInputKeyInfo)
if (fAltPressed || fCtrlPressed) if (fAltPressed || fCtrlPressed)
{ {
TextAttribute selectionAttr; TextAttribute selectionAttr;
const BYTE colorIndex = gsl::narrow_cast<BYTE>(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) if (fCtrlPressed)
{ {
// Setting background color. Set fg color to black. // Setting background color. Set fg color to black.
selectionAttr.SetIndexedBackground256(colorIndex); selectionAttr.SetIndexedBackground256(colorIndex);
selectionAttr.SetIndexedForeground256(0); selectionAttr.SetIndexedForeground256(TextColor::DARK_BLACK);
} }
else else
{ {

View file

@ -127,6 +127,7 @@ public:
COLORREF GetDefaultForeground() const noexcept; COLORREF GetDefaultForeground() const noexcept;
COLORREF GetDefaultBackground() const noexcept; COLORREF GetDefaultBackground() const noexcept;
std::pair<COLORREF, COLORREF> LookupAttributeColors(const TextAttribute& attr) const noexcept; std::pair<COLORREF, COLORREF> LookupAttributeColors(const TextAttribute& attr) const noexcept;
std::pair<COLORREF, COLORREF> LookupAttributeColors(const TextAttribute& attr, const COLORREF defaultFg, const COLORREF defaultBg) const noexcept;
void SetTitle(const std::wstring_view newTitle); void SetTitle(const std::wstring_view newTitle);
void SetTitlePrefix(const std::wstring_view newTitlePrefix); void SetTitlePrefix(const std::wstring_view newTitlePrefix);

View file

@ -82,8 +82,7 @@ Settings::Settings() :
_CursorType = CursorType::Legacy; _CursorType = CursorType::Legacy;
gsl::span<COLORREF> tableView = { _colorTable.data(), _colorTable.size() }; gsl::span<COLORREF> tableView = { _colorTable.data(), _colorTable.size() };
::Microsoft::Console::Utils::Initialize256ColorTable(tableView); ::Microsoft::Console::Utils::InitializeColorTable(tableView);
::Microsoft::Console::Utils::InitializeCampbellColorTableForConhost(tableView);
} }
// Routine Description: // Routine Description:
@ -122,8 +121,8 @@ void Settings::ApplyDesktopSpecificDefaults()
_uNumberOfHistoryBuffers = 4; _uNumberOfHistoryBuffers = 4;
_bHistoryNoDup = FALSE; _bHistoryNoDup = FALSE;
gsl::span<COLORREF> tableView = { _colorTable.data(), _colorTable.size() }; gsl::span<COLORREF> tableView = { _colorTable.data(), 16 };
::Microsoft::Console::Utils::InitializeCampbellColorTableForConhost(tableView); ::Microsoft::Console::Utils::InitializeColorTable(tableView);
_fTrimLeadingZeros = false; _fTrimLeadingZeros = false;
_fEnableColorSelection = false; _fEnableColorSelection = false;
@ -222,7 +221,7 @@ void Settings::InitFromStateInfo(_In_ PCONSOLE_STATE_INFO pStateInfo)
_uNumberOfHistoryBuffers = pStateInfo->NumberOfHistoryBuffers; _uNumberOfHistoryBuffers = pStateInfo->NumberOfHistoryBuffers;
for (size_t i = 0; i < std::size(pStateInfo->ColorTable); i++) for (size_t i = 0; i < std::size(pStateInfo->ColorTable); i++)
{ {
SetColorTableEntry(i, pStateInfo->ColorTable[i]); SetLegacyColorTableEntry(i, pStateInfo->ColorTable[i]);
} }
_uCodePage = pStateInfo->CodePage; _uCodePage = pStateInfo->CodePage;
_bWrapText = !!pStateInfo->fWrapText; _bWrapText = !!pStateInfo->fWrapText;
@ -267,7 +266,7 @@ CONSOLE_STATE_INFO Settings::CreateConsoleStateInfo() const
csi.NumberOfHistoryBuffers = _uNumberOfHistoryBuffers; csi.NumberOfHistoryBuffers = _uNumberOfHistoryBuffers;
for (size_t i = 0; i < std::size(csi.ColorTable); i++) 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.CodePage = _uCodePage;
csi.fWrapText = !!_bWrapText; csi.fWrapText = !!_bWrapText;
@ -726,11 +725,6 @@ void Settings::SetHistoryNoDup(const bool bHistoryNoDup)
_bHistoryNoDup = bHistoryNoDup; _bHistoryNoDup = bHistoryNoDup;
} }
void Settings::SetColorTableEntry(const size_t index, const COLORREF ColorValue)
{
_colorTable.at(index) = ColorValue;
}
bool Settings::IsStartupTitleIsLinkNameSet() const bool Settings::IsStartupTitleIsLinkNameSet() const
{ {
return WI_IsFlagSet(_dwStartupFlags, STARTF_TITLEISLINKNAME); return WI_IsFlagSet(_dwStartupFlags, STARTF_TITLEISLINKNAME);
@ -746,11 +740,26 @@ void Settings::UnsetStartupFlag(const DWORD dwFlagToUnset)
_dwStartupFlags &= ~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 COLORREF Settings::GetColorTableEntry(const size_t index) const
{ {
return _colorTable.at(index); 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 COLORREF Settings::GetCursorColor() const noexcept
{ {
return _CursorColor; return _CursorColor;

View file

@ -167,6 +167,8 @@ public:
void SetColorTableEntry(const size_t index, const COLORREF ColorValue); void SetColorTableEntry(const size_t index, const COLORREF ColorValue);
COLORREF GetColorTableEntry(const size_t index) const; 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; COLORREF GetCursorColor() const noexcept;
CursorType GetCursorType() const noexcept; CursorType GetCursorType() const noexcept;

View file

@ -89,7 +89,6 @@ SOURCES = \
..\utf8ToWideCharParser.cpp \ ..\utf8ToWideCharParser.cpp \
..\conareainfo.cpp \ ..\conareainfo.cpp \
..\conimeinfo.cpp \ ..\conimeinfo.cpp \
..\conattrs.cpp \
..\ConsoleArguments.cpp \ ..\ConsoleArguments.cpp \
..\CommandNumberPopup.cpp \ ..\CommandNumberPopup.cpp \
..\CommandListPopup.cpp \ ..\CommandListPopup.cpp \

View file

@ -1,4 +1,4 @@
// Copyright (c) Microsoft Corporation. // Copyright (c) Microsoft Corporation.
// Licensed under the MIT license. // Licensed under the MIT license.
#include "precomp.h" #include "precomp.h"
@ -1634,74 +1634,74 @@ void ScreenBufferTests::VtSetColorTable()
L"Process some valid sequences for setting the table")); L"Process some valid sequences for setting the table"));
stateMachine.ProcessString(L"\x1b]4;0;rgb:1/1/1\x7"); 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"); 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"); 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"); 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"); 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\\"); 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( Log::Comment(NoThrowString().Format(
L"Try a bunch of invalid sequences.")); L"Try a bunch of invalid sequences."));
Log::Comment(NoThrowString().Format( Log::Comment(NoThrowString().Format(
L"First start by setting an entry to a known value to compare to.")); 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\\"); 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( Log::Comment(NoThrowString().Format(
L"invalid: Missing the first component")); L"invalid: Missing the first component"));
stateMachine.ProcessString(L"\x1b]4;5;rgb:/1/1\x1b\\"); 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( Log::Comment(NoThrowString().Format(
L"invalid: too many components")); L"invalid: too many components"));
stateMachine.ProcessString(L"\x1b]4;5;rgb:1/1/1/1\x1b\\"); 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( Log::Comment(NoThrowString().Format(
L"invalid: no second component")); L"invalid: no second component"));
stateMachine.ProcessString(L"\x1b]4;5;rgb:1//1\x1b\\"); 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( Log::Comment(NoThrowString().Format(
L"invalid: no components")); L"invalid: no components"));
stateMachine.ProcessString(L"\x1b]4;5;rgb://\x1b\\"); 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( Log::Comment(NoThrowString().Format(
L"invalid: no third component")); L"invalid: no third component"));
stateMachine.ProcessString(L"\x1b]4;5;rgb:1/11/\x1b\\"); 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( Log::Comment(NoThrowString().Format(
L"invalid: rgbi is not a supported color space")); L"invalid: rgbi is not a supported color space"));
stateMachine.ProcessString(L"\x1b]4;5;rgbi:1/1/1\x1b\\"); 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( Log::Comment(NoThrowString().Format(
L"invalid: cmyk is not a supported color space")); L"invalid: cmyk is not a supported color space"));
stateMachine.ProcessString(L"\x1b]4;5;cmyk:1/1/1\x1b\\"); 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( Log::Comment(NoThrowString().Format(
L"invalid: no table index should do nothing")); L"invalid: no table index should do nothing"));
stateMachine.ProcessString(L"\x1b]4;;rgb:1/1/1\x1b\\"); 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( Log::Comment(NoThrowString().Format(
L"invalid: need to specify a color space")); L"invalid: need to specify a color space"));
stateMachine.ProcessString(L"\x1b]4;5;1/1/1\x1b\\"); 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() void ScreenBufferTests::ResizeTraditionalDoesNotDoubleFreeAttrRows()
@ -1912,8 +1912,8 @@ void ScreenBufferTests::VtEraseAllPersistCursorFillColor()
L"The viewport should be full of dark_red on bright_blue")); L"The viewport should be full of dark_red on bright_blue"));
auto expectedAttr = TextAttribute{}; auto expectedAttr = TextAttribute{};
expectedAttr.SetIndexedForeground((BYTE)XtermToWindowsIndex(1)); expectedAttr.SetIndexedForeground(TextColor::DARK_RED);
expectedAttr.SetIndexedBackground((BYTE)XtermToWindowsIndex(12)); expectedAttr.SetIndexedBackground(TextColor::BRIGHT_BLUE);
stateMachine.ProcessString(L"\x1b[31;104m"); stateMachine.ProcessString(L"\x1b[31;104m");
VERIFY_ARE_EQUAL(expectedAttr, si.GetAttributes()); VERIFY_ARE_EQUAL(expectedAttr, si.GetAttributes());
@ -2256,8 +2256,8 @@ void ScreenBufferTests::SetDefaultsIndividuallyBothDefault()
COLORREF magenta = RGB(255, 0, 255); COLORREF magenta = RGB(255, 0, 255);
COLORREF yellow = RGB(255, 255, 0); COLORREF yellow = RGB(255, 255, 0);
COLORREF brightGreen = gci.GetColorTableEntry(::XtermToWindowsIndex(10)); COLORREF brightGreen = gci.GetColorTableEntry(TextColor::BRIGHT_GREEN);
COLORREF darkBlue = gci.GetColorTableEntry(::XtermToWindowsIndex(4)); COLORREF darkBlue = gci.GetColorTableEntry(TextColor::DARK_BLUE);
gci.SetDefaultForegroundColor(yellow); gci.SetDefaultForegroundColor(yellow);
gci.SetDefaultBackgroundColor(magenta); gci.SetDefaultBackgroundColor(magenta);
@ -2292,8 +2292,8 @@ void ScreenBufferTests::SetDefaultsIndividuallyBothDefault()
// See the log comment above for description of these values. // See the log comment above for description of these values.
TextAttribute expectedDefaults{}; TextAttribute expectedDefaults{};
TextAttribute expectedTwo; TextAttribute expectedTwo;
expectedTwo.SetIndexedForeground((BYTE)XtermToWindowsIndex(10)); expectedTwo.SetIndexedForeground(TextColor::BRIGHT_GREEN);
expectedTwo.SetIndexedBackground((BYTE)XtermToWindowsIndex(4)); expectedTwo.SetIndexedBackground(TextColor::DARK_BLUE);
TextAttribute expectedThree = expectedTwo; TextAttribute expectedThree = expectedTwo;
expectedThree.SetDefaultForeground(); expectedThree.SetDefaultForeground();
// Four is the same as Defaults // Four is the same as Defaults
@ -2705,7 +2705,7 @@ void ScreenBufferTests::SetGlobalColorTable()
VERIFY_SUCCEEDED(mainBuffer.SetViewportOrigin(true, COORD({ 0, 0 }), true)); VERIFY_SUCCEEDED(mainBuffer.SetViewportOrigin(true, COORD({ 0, 0 }), true));
mainCursor.SetPosition({ 0, 0 }); 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); const COLORREF testColor = RGB(0x11, 0x22, 0x33);
VERIFY_ARE_NOT_EQUAL(originalRed, testColor); VERIFY_ARE_NOT_EQUAL(originalRed, testColor);
@ -3209,10 +3209,10 @@ void ScreenBufferTests::DontResetColorsAboveVirtualBottom()
L"cursor=%s", VerifyOutputTraits<COORD>::ToString(cursor.GetPosition()).GetBuffer())); L"cursor=%s", VerifyOutputTraits<COORD>::ToString(cursor.GetPosition()).GetBuffer()));
Log::Comment(NoThrowString().Format( Log::Comment(NoThrowString().Format(
L"viewport=%s", VerifyOutputTraits<SMALL_RECT>::ToString(si.GetViewport().ToInclusive()).GetBuffer())); L"viewport=%s", VerifyOutputTraits<SMALL_RECT>::ToString(si.GetViewport().ToInclusive()).GetBuffer()));
const auto darkRed = gci.GetColorTableEntry(::XtermToWindowsIndex(1)); const auto darkRed = gci.GetColorTableEntry(TextColor::DARK_RED);
const auto darkBlue = gci.GetColorTableEntry(::XtermToWindowsIndex(4)); const auto darkBlue = gci.GetColorTableEntry(TextColor::DARK_BLUE);
const auto darkBlack = gci.GetColorTableEntry(::XtermToWindowsIndex(0)); const auto darkBlack = gci.GetColorTableEntry(TextColor::DARK_BLACK);
const auto darkWhite = gci.GetColorTableEntry(::XtermToWindowsIndex(7)); const auto darkWhite = gci.GetColorTableEntry(TextColor::DARK_WHITE);
stateMachine.ProcessString(L"\x1b[31;44m"); stateMachine.ProcessString(L"\x1b[31;44m");
stateMachine.ProcessString(L"X"); stateMachine.ProcessString(L"X");
stateMachine.ProcessString(L"\x1b[m"); stateMachine.ProcessString(L"\x1b[m");
@ -6168,8 +6168,8 @@ void ScreenBufferTests::TestWriteConsoleVTQuirkMode()
/* Write red on blue, verify that it comes through */ /* Write red on blue, verify that it comes through */
{ {
TextAttribute vtRedOnBlueAttribute{}; TextAttribute vtRedOnBlueAttribute{};
vtRedOnBlueAttribute.SetForeground(TextColor{ gsl::narrow_cast<BYTE>(XtermToWindowsIndex(1)), false }); vtRedOnBlueAttribute.SetForeground(TextColor{ TextColor::DARK_RED, false });
vtRedOnBlueAttribute.SetBackground(TextColor{ gsl::narrow_cast<BYTE>(XtermToWindowsIndex(4)), false }); vtRedOnBlueAttribute.SetBackground(TextColor{ TextColor::DARK_BLUE, false });
seq = L"\x1b[31;44m"; seq = L"\x1b[31;44m";
seqCb = 2 * seq.size(); 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 */ /* Write white on black, verify that it acts as expected for the quirk mode */
{ {
TextAttribute vtWhiteOnBlackAttribute{}; TextAttribute vtWhiteOnBlackAttribute{};
vtWhiteOnBlackAttribute.SetForeground(TextColor{ gsl::narrow_cast<BYTE>(XtermToWindowsIndex(7)), false }); vtWhiteOnBlackAttribute.SetForeground(TextColor{ TextColor::DARK_WHITE, false });
vtWhiteOnBlackAttribute.SetBackground(TextColor{ gsl::narrow_cast<BYTE>(XtermToWindowsIndex(0)), false }); vtWhiteOnBlackAttribute.SetBackground(TextColor{ TextColor::DARK_BLACK, false });
const TextAttribute quirkExpectedAttribute{ useQuirk ? defaultAttribute : vtWhiteOnBlackAttribute }; 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 */ /* Write bright white on black, verify that it acts as expected for the quirk mode */
{ {
TextAttribute vtBrightWhiteOnBlackAttribute{}; TextAttribute vtBrightWhiteOnBlackAttribute{};
vtBrightWhiteOnBlackAttribute.SetForeground(TextColor{ gsl::narrow_cast<BYTE>(XtermToWindowsIndex(7)), false }); vtBrightWhiteOnBlackAttribute.SetForeground(TextColor{ TextColor::DARK_WHITE, false });
vtBrightWhiteOnBlackAttribute.SetBackground(TextColor{ gsl::narrow_cast<BYTE>(XtermToWindowsIndex(0)), false }); vtBrightWhiteOnBlackAttribute.SetBackground(TextColor{ TextColor::DARK_BLACK, false });
vtBrightWhiteOnBlackAttribute.SetBold(true); vtBrightWhiteOnBlackAttribute.SetBold(true);
TextAttribute vtBrightWhiteOnDefaultAttribute{ vtBrightWhiteOnBlackAttribute }; // copy the above attribute 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 */ /* Write a 256-color white on a 256-color black, make sure the quirk does not suppress it */
{ {
TextAttribute vtWhiteOnBlack256Attribute{}; TextAttribute vtWhiteOnBlack256Attribute{};
vtWhiteOnBlack256Attribute.SetForeground(TextColor{ gsl::narrow_cast<BYTE>(XtermToWindowsIndex(7)), true }); vtWhiteOnBlack256Attribute.SetForeground(TextColor{ TextColor::DARK_WHITE, true });
vtWhiteOnBlack256Attribute.SetBackground(TextColor{ gsl::narrow_cast<BYTE>(XtermToWindowsIndex(0)), true }); vtWhiteOnBlack256Attribute.SetBackground(TextColor{ TextColor::DARK_BLACK, true });
// reset (disable bold from the last test) before setting both colors // 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 (!) seq = L"\x1b[m\x1b[38;5;7;48;5;0m"; // the quirk should *not* suppress this (!)

View file

@ -1,4 +1,4 @@
// Copyright (c) Microsoft Corporation. // Copyright (c) Microsoft Corporation.
// Licensed under the MIT license. // Licensed under the MIT license.
#include "precomp.h" #include "precomp.h"
@ -779,8 +779,8 @@ void TextBufferTests::TestMixedRgbAndLegacyBrightness()
// '\E[m\E[32mX\E[1mX' // '\E[m\E[32mX\E[1mX'
// Make sure that the second X is a BRIGHT green, not white. // Make sure that the second X is a BRIGHT green, not white.
Log::Comment(L"Case 4 ;\"\\E[m\\E[32mX\\E[1mX\""); Log::Comment(L"Case 4 ;\"\\E[m\\E[32mX\\E[1mX\"");
const auto dark_green = gci.GetColorTableEntry(2); const auto dark_green = gci.GetColorTableEntry(TextColor::DARK_GREEN);
const auto bright_green = gci.GetColorTableEntry(10); const auto bright_green = gci.GetColorTableEntry(TextColor::BRIGHT_GREEN);
VERIFY_ARE_NOT_EQUAL(dark_green, bright_green); VERIFY_ARE_NOT_EQUAL(dark_green, bright_green);
wchar_t* sequence = L"\x1b[m\x1b[32mX\x1b[1mX"; 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 x = cursor.GetPosition().X;
const auto y = cursor.GetPosition().Y; const auto y = cursor.GetPosition().Y;
const auto dark_green = gci.GetColorTableEntry(2); const auto dark_green = gci.GetColorTableEntry(TextColor::DARK_GREEN);
const auto bright_green = gci.GetColorTableEntry(10); const auto bright_green = gci.GetColorTableEntry(TextColor::BRIGHT_GREEN);
Log::Comment(NoThrowString().Format( Log::Comment(NoThrowString().Format(
L"cursor={X:%d,Y:%d}", L"cursor={X:%d,Y:%d}",
@ -938,8 +938,8 @@ void TextBufferTests::TestUnBoldRgb()
const auto x = cursor.GetPosition().X; const auto x = cursor.GetPosition().X;
const auto y = cursor.GetPosition().Y; const auto y = cursor.GetPosition().Y;
const auto dark_green = gci.GetColorTableEntry(2); const auto dark_green = gci.GetColorTableEntry(TextColor::DARK_GREEN);
const auto bright_green = gci.GetColorTableEntry(10); const auto bright_green = gci.GetColorTableEntry(TextColor::BRIGHT_GREEN);
Log::Comment(NoThrowString().Format( Log::Comment(NoThrowString().Format(
L"cursor={X:%d,Y:%d}", L"cursor={X:%d,Y:%d}",
@ -997,8 +997,8 @@ void TextBufferTests::TestComplexUnBold()
const auto x = cursor.GetPosition().X; const auto x = cursor.GetPosition().X;
const auto y = cursor.GetPosition().Y; const auto y = cursor.GetPosition().Y;
const auto dark_green = gci.GetColorTableEntry(2); const auto dark_green = gci.GetColorTableEntry(TextColor::DARK_GREEN);
const auto bright_green = gci.GetColorTableEntry(10); const auto bright_green = gci.GetColorTableEntry(TextColor::BRIGHT_GREEN);
Log::Comment(NoThrowString().Format( Log::Comment(NoThrowString().Format(
L"cursor={X:%d,Y:%d}", L"cursor={X:%d,Y:%d}",
@ -1079,8 +1079,8 @@ void TextBufferTests::CopyAttrs()
const auto x = cursor.GetPosition().X; const auto x = cursor.GetPosition().X;
const auto y = cursor.GetPosition().Y; const auto y = cursor.GetPosition().Y;
const auto dark_blue = gci.GetColorTableEntry(1); const auto dark_blue = gci.GetColorTableEntry(TextColor::DARK_BLUE);
const auto dark_magenta = gci.GetColorTableEntry(5); const auto dark_magenta = gci.GetColorTableEntry(TextColor::DARK_MAGENTA);
Log::Comment(NoThrowString().Format( Log::Comment(NoThrowString().Format(
L"cursor={X:%d,Y:%d}", L"cursor={X:%d,Y:%d}",
@ -1133,7 +1133,7 @@ void TextBufferTests::EmptySgrTest()
const auto x = cursor.GetPosition().X; const auto x = cursor.GetPosition().X;
const auto y = cursor.GetPosition().Y; const auto y = cursor.GetPosition().Y;
const COLORREF darkRed = gci.GetColorTableEntry(4); const COLORREF darkRed = gci.GetColorTableEntry(TextColor::DARK_RED);
Log::Comment(NoThrowString().Format( Log::Comment(NoThrowString().Format(
L"cursor={X:%d,Y:%d}", L"cursor={X:%d,Y:%d}",
x, x,
@ -1192,7 +1192,7 @@ void TextBufferTests::TestReverseReset()
const auto x = cursor.GetPosition().X; const auto x = cursor.GetPosition().X;
const auto y = cursor.GetPosition().Y; 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); const COLORREF rgbColor = RGB(128, 5, 255);
Log::Comment(NoThrowString().Format( Log::Comment(NoThrowString().Format(
@ -1258,9 +1258,9 @@ void TextBufferTests::CopyLastAttr()
const COLORREF defaultBrightYellow = RGB(249, 241, 165); const COLORREF defaultBrightYellow = RGB(249, 241, 165);
const COLORREF defaultBrightCyan = RGB(97, 214, 214); const COLORREF defaultBrightCyan = RGB(97, 214, 214);
gci.SetColorTableEntry(8, defaultBrightBlack); gci.SetColorTableEntry(TextColor::BRIGHT_BLACK, defaultBrightBlack);
gci.SetColorTableEntry(14, defaultBrightYellow); gci.SetColorTableEntry(TextColor::BRIGHT_YELLOW, defaultBrightYellow);
gci.SetColorTableEntry(11, defaultBrightCyan); gci.SetColorTableEntry(TextColor::BRIGHT_CYAN, defaultBrightCyan);
// Write (solFg, solBG) X \n // Write (solFg, solBG) X \n
// (solFg, solBG) X (solCyan, solBG) X \n // (solFg, solBG) X (solCyan, solBG) X \n
@ -1405,8 +1405,8 @@ void TextBufferTests::TestResetClearsBoldness()
si.SetAttributes(defaultAttribute); si.SetAttributes(defaultAttribute);
const auto [defaultFg, defaultBg] = gci.LookupAttributeColors(si.GetAttributes()); const auto [defaultFg, defaultBg] = gci.LookupAttributeColors(si.GetAttributes());
const auto dark_green = gci.GetColorTableEntry(2); const auto dark_green = gci.GetColorTableEntry(TextColor::DARK_GREEN);
const auto bright_green = gci.GetColorTableEntry(10); const auto bright_green = gci.GetColorTableEntry(TextColor::BRIGHT_GREEN);
wchar_t* sequence = L"\x1b[32mA\x1b[1mB\x1b[0mC\x1b[32mD"; wchar_t* sequence = L"\x1b[32mA\x1b[1mB\x1b[0mC\x1b[32mD";
Log::Comment(NoThrowString().Format(sequence)); Log::Comment(NoThrowString().Format(sequence));

View file

@ -470,7 +470,7 @@ void VtRendererTest::Xterm256TestColors()
Log::Comment(NoThrowString().Format( Log::Comment(NoThrowString().Format(
L"----Change only the BG----")); L"----Change only the BG----"));
textAttributes.SetIndexedBackground(FOREGROUND_RED); textAttributes.SetIndexedBackground(TextColor::DARK_RED);
qExpectedInput.push_back("\x1b[41m"); // Background DARK_RED qExpectedInput.push_back("\x1b[41m"); // Background DARK_RED
VERIFY_SUCCEEDED(engine->UpdateDrawingBrushes(textAttributes, VERIFY_SUCCEEDED(engine->UpdateDrawingBrushes(textAttributes,
&renderData, &renderData,
@ -479,7 +479,7 @@ void VtRendererTest::Xterm256TestColors()
Log::Comment(NoThrowString().Format( Log::Comment(NoThrowString().Format(
L"----Change only the FG----")); 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 qExpectedInput.push_back("\x1b[37m"); // Foreground DARK_WHITE
VERIFY_SUCCEEDED(engine->UpdateDrawingBrushes(textAttributes, VERIFY_SUCCEEDED(engine->UpdateDrawingBrushes(textAttributes,
&renderData, &renderData,
@ -515,7 +515,7 @@ void VtRendererTest::Xterm256TestColors()
Log::Comment(NoThrowString().Format( Log::Comment(NoThrowString().Format(
L"----Change only the FG to a 256-color index----")); 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) qExpectedInput.push_back("\x1b[38;5;7m"); // Foreground DARK_WHITE (256-Color Index)
VERIFY_SUCCEEDED(engine->UpdateDrawingBrushes(textAttributes, VERIFY_SUCCEEDED(engine->UpdateDrawingBrushes(textAttributes,
&renderData, &renderData,
@ -524,7 +524,7 @@ void VtRendererTest::Xterm256TestColors()
Log::Comment(NoThrowString().Format( Log::Comment(NoThrowString().Format(
L"----Change only the BG to a 256-color index----")); 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) qExpectedInput.push_back("\x1b[48;5;1m"); // Background DARK_RED (256-Color Index)
VERIFY_SUCCEEDED(engine->UpdateDrawingBrushes(textAttributes, VERIFY_SUCCEEDED(engine->UpdateDrawingBrushes(textAttributes,
&renderData, &renderData,
@ -859,7 +859,7 @@ void VtRendererTest::Xterm256TestAttributesAcrossReset()
VERIFY_SUCCEEDED(engine->UpdateDrawingBrushes(textAttributes, &renderData, false, false)); VERIFY_SUCCEEDED(engine->UpdateDrawingBrushes(textAttributes, &renderData, false, false));
Log::Comment(L"----Set Green Foreground----"); Log::Comment(L"----Set Green Foreground----");
textAttributes.SetIndexedForeground(FOREGROUND_GREEN); textAttributes.SetIndexedForeground(TextColor::DARK_GREEN);
qExpectedInput.push_back("\x1b[32m"); qExpectedInput.push_back("\x1b[32m");
VERIFY_SUCCEEDED(engine->UpdateDrawingBrushes(textAttributes, &renderData, false, false)); VERIFY_SUCCEEDED(engine->UpdateDrawingBrushes(textAttributes, &renderData, false, false));
@ -870,7 +870,7 @@ void VtRendererTest::Xterm256TestAttributesAcrossReset()
VERIFY_SUCCEEDED(engine->UpdateDrawingBrushes(textAttributes, &renderData, false, false)); VERIFY_SUCCEEDED(engine->UpdateDrawingBrushes(textAttributes, &renderData, false, false));
Log::Comment(L"----Set Green Background----"); Log::Comment(L"----Set Green Background----");
textAttributes.SetIndexedBackground(FOREGROUND_GREEN); textAttributes.SetIndexedBackground(TextColor::DARK_GREEN);
qExpectedInput.push_back("\x1b[42m"); qExpectedInput.push_back("\x1b[42m");
VERIFY_SUCCEEDED(engine->UpdateDrawingBrushes(textAttributes, &renderData, false, false)); VERIFY_SUCCEEDED(engine->UpdateDrawingBrushes(textAttributes, &renderData, false, false));
@ -1104,7 +1104,7 @@ void VtRendererTest::XtermTestColors()
Log::Comment(NoThrowString().Format( Log::Comment(NoThrowString().Format(
L"----Change only the BG----")); L"----Change only the BG----"));
textAttributes.SetIndexedBackground(FOREGROUND_RED); textAttributes.SetIndexedBackground(TextColor::DARK_RED);
qExpectedInput.push_back("\x1b[41m"); // Background DARK_RED qExpectedInput.push_back("\x1b[41m"); // Background DARK_RED
VERIFY_SUCCEEDED(engine->UpdateDrawingBrushes(textAttributes, VERIFY_SUCCEEDED(engine->UpdateDrawingBrushes(textAttributes,
&renderData, &renderData,
@ -1113,7 +1113,7 @@ void VtRendererTest::XtermTestColors()
Log::Comment(NoThrowString().Format( Log::Comment(NoThrowString().Format(
L"----Change only the FG----")); 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 qExpectedInput.push_back("\x1b[37m"); // Foreground DARK_WHITE
VERIFY_SUCCEEDED(engine->UpdateDrawingBrushes(textAttributes, VERIFY_SUCCEEDED(engine->UpdateDrawingBrushes(textAttributes,
&renderData, &renderData,
@ -1150,7 +1150,7 @@ void VtRendererTest::XtermTestColors()
Log::Comment(NoThrowString().Format( Log::Comment(NoThrowString().Format(
L"----Change only the FG to a 256-color index----")); 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 qExpectedInput.push_back("\x1b[37m"); // Foreground DARK_WHITE
VERIFY_SUCCEEDED(engine->UpdateDrawingBrushes(textAttributes, VERIFY_SUCCEEDED(engine->UpdateDrawingBrushes(textAttributes,
&renderData, &renderData,
@ -1159,7 +1159,7 @@ void VtRendererTest::XtermTestColors()
Log::Comment(NoThrowString().Format( Log::Comment(NoThrowString().Format(
L"----Change only the BG to a 256-color index----")); 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 qExpectedInput.push_back("\x1b[41m"); // Background DARK_RED
VERIFY_SUCCEEDED(engine->UpdateDrawingBrushes(textAttributes, VERIFY_SUCCEEDED(engine->UpdateDrawingBrushes(textAttributes,
&renderData, &renderData,
@ -1351,7 +1351,7 @@ void VtRendererTest::XtermTestAttributesAcrossReset()
VERIFY_SUCCEEDED(engine->UpdateDrawingBrushes(textAttributes, &renderData, false, false)); VERIFY_SUCCEEDED(engine->UpdateDrawingBrushes(textAttributes, &renderData, false, false));
Log::Comment(L"----Set Green Foreground----"); Log::Comment(L"----Set Green Foreground----");
textAttributes.SetIndexedForeground(FOREGROUND_GREEN); textAttributes.SetIndexedForeground(TextColor::DARK_GREEN);
qExpectedInput.push_back("\x1b[32m"); qExpectedInput.push_back("\x1b[32m");
VERIFY_SUCCEEDED(engine->UpdateDrawingBrushes(textAttributes, &renderData, false, false)); VERIFY_SUCCEEDED(engine->UpdateDrawingBrushes(textAttributes, &renderData, false, false));
@ -1362,7 +1362,7 @@ void VtRendererTest::XtermTestAttributesAcrossReset()
VERIFY_SUCCEEDED(engine->UpdateDrawingBrushes(textAttributes, &renderData, false, false)); VERIFY_SUCCEEDED(engine->UpdateDrawingBrushes(textAttributes, &renderData, false, false));
Log::Comment(L"----Set Green Background----"); Log::Comment(L"----Set Green Background----");
textAttributes.SetIndexedBackground(FOREGROUND_GREEN); textAttributes.SetIndexedBackground(TextColor::DARK_GREEN);
qExpectedInput.push_back("\x1b[42m"); qExpectedInput.push_back("\x1b[42m");
VERIFY_SUCCEEDED(engine->UpdateDrawingBrushes(textAttributes, &renderData, false, false)); VERIFY_SUCCEEDED(engine->UpdateDrawingBrushes(textAttributes, &renderData, false, false));

View file

@ -22,20 +22,6 @@ enum class ExtendedAttributes : BYTE
}; };
DEFINE_ENUM_FLAG_OPERATORS(ExtendedAttributes); 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 enum class CursorType : unsigned int
{ {
Legacy = 0x0, // uses the cursor's height value to range from underscore-like to full box Legacy = 0x0, // uses the cursor's height value to range from underscore-like to full box

View file

@ -208,7 +208,11 @@ void Clipboard::StoreSelectionToClipboard(bool const copyFormatting)
const auto& gci = ServiceLocator::LocateGlobals().getConsoleInformation(); const auto& gci = ServiceLocator::LocateGlobals().getConsoleInformation();
const auto& buffer = gci.GetActiveOutputBuffer().GetTextBuffer(); 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; bool includeCRLF, trimTrailingWhitespace;
if (WI_IsFlagSet(GetKeyState(VK_SHIFT), KEY_PRESSED)) if (WI_IsFlagSet(GetKeyState(VK_SHIFT), KEY_PRESSED))

View file

@ -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++) 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. // 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++) 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. // Ensure that attributes only contain color specification.

View file

@ -199,13 +199,14 @@ using namespace Microsoft::Console::Render;
} }
// Method Description: // 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: // 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 // - fIsForeground: true if we should emit the foreground sequence, false for background
// Return Value: // Return Value:
// - S_OK if we succeeded, else an appropriate HRESULT for failing to allocate or write. // - 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 const bool fIsForeground) noexcept
{ {
// Always check using the foreground flags, because the bg flags constants // 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. // terminals display the bright color when displaying bolded text.
// By specifying the boldness and brightness separately, we'll make sure the // By specifying the boldness and brightness separately, we'll make sure the
// terminal has an accurate representation of our buffer. // terminal has an accurate representation of our buffer.
const int vtIndex = 30 + const auto prefix = WI_IsFlagSet(index, FOREGROUND_INTENSITY) ? (fIsForeground ? 90 : 100) : (fIsForeground ? 30 : 40);
(fIsForeground ? 0 : 10) + return _WriteFormatted(FMT_COMPILE("\x1b[{}m"), prefix + (index & 7));
((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);
} }
// Method Description: // Method Description:
// - Formats and writes a sequence to change the current text attributes to an // - Formats and writes a sequence to change the current text attributes to an
// indexed color from the 256-color table. // indexed color from the 256-color table.
// Arguments: // 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 // - fIsForeground: true if we should emit the foreground sequence, false for background
// Return Value: // Return Value:
// - S_OK if we succeeded, else an appropriate HRESULT for failing to allocate or write. // - 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 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: // Method Description:

View file

@ -287,9 +287,10 @@ using namespace Microsoft::Console::Types;
} }
// We use the legacy color calculations to generate an approximation of the // We use the legacy color calculations to generate an approximation of the
// colors in the 16-color table. // colors in the Windows 16-color table, but we need to transpose those
auto fgIndex = fg.GetLegacyIndex(0); // values to obtain an index in an ANSI-compatible order.
auto bgIndex = bg.GetLegacyIndex(0); 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. // If the bold attribute is set, and the foreground can be brightened, then do so.
const bool brighten = textAttributes.IsBold() && fg.CanBeBrightened(); const bool brighten = textAttributes.IsBold() && fg.CanBeBrightened();

View file

@ -185,9 +185,9 @@ namespace Microsoft::Console::Render
[[nodiscard]] HRESULT _ClearScreen() noexcept; [[nodiscard]] HRESULT _ClearScreen() noexcept;
[[nodiscard]] HRESULT _ClearScrollback() noexcept; [[nodiscard]] HRESULT _ClearScrollback() noexcept;
[[nodiscard]] HRESULT _ChangeTitle(const std::string& title) 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; const bool fIsForeground) noexcept;
[[nodiscard]] HRESULT _SetGraphicsRendition256Color(const WORD index, [[nodiscard]] HRESULT _SetGraphicsRendition256Color(const BYTE index,
const bool fIsForeground) noexcept; const bool fIsForeground) noexcept;
[[nodiscard]] HRESULT _SetGraphicsRenditionRGBColor(const COLORREF color, [[nodiscard]] HRESULT _SetGraphicsRenditionRGBColor(const COLORREF color,
const bool fIsForeground) noexcept; const bool fIsForeground) noexcept;

View file

@ -2541,13 +2541,13 @@ void AdaptDispatch::_ReportSGRSetting() const
const auto iterator = std::back_insert_iterator(response); const auto iterator = std::back_insert_iterator(response);
if (color.IsIndex16()) if (color.IsIndex16())
{ {
const auto index = XtermToWindowsIndex(color.GetIndex()); const auto index = color.GetIndex();
const auto colorParameter = base + (index >= 8 ? 60 : 0) + (index % 8); const auto colorParameter = base + (index >= 8 ? 60 : 0) + (index % 8);
fmt::format_to(iterator, FMT_STRING(L";{}"), colorParameter); fmt::format_to(iterator, FMT_STRING(L";{}"), colorParameter);
} }
else if (color.IsIndex256()) 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); fmt::format_to(iterator, FMT_STRING(L";{};5;{}"), base + 8, index);
} }
else if (color.IsRgb()) else if (color.IsRgb())

View file

@ -13,29 +13,6 @@
using namespace Microsoft::Console::VirtualTerminal; using namespace Microsoft::Console::VirtualTerminal;
using namespace Microsoft::Console::VirtualTerminal::DispatchTypes; 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: // Routine Description:
// - Helper to parse extended graphics options, which start with 38 (FG) or 48 (BG) // - 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) // 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); const size_t tableIndex = options.at(1).value_or(0);
if (tableIndex <= 255) if (tableIndex <= 255)
{ {
const auto adjustedIndex = gsl::narrow_cast<BYTE>(::Xterm256ToWindowsIndex(tableIndex)); const auto adjustedIndex = gsl::narrow_cast<BYTE>(tableIndex);
if (isForeground) if (isForeground)
{ {
attr.SetIndexedForeground256(adjustedIndex); attr.SetIndexedForeground256(adjustedIndex);
@ -178,100 +155,100 @@ bool AdaptDispatch::SetGraphicsRendition(const VTParameters options)
attr.SetOverlined(false); attr.SetOverlined(false);
break; break;
case ForegroundBlack: case ForegroundBlack:
attr.SetIndexedForeground(DARK_BLACK); attr.SetIndexedForeground(TextColor::DARK_BLACK);
break; break;
case ForegroundBlue: case ForegroundBlue:
attr.SetIndexedForeground(DARK_BLUE); attr.SetIndexedForeground(TextColor::DARK_BLUE);
break; break;
case ForegroundGreen: case ForegroundGreen:
attr.SetIndexedForeground(DARK_GREEN); attr.SetIndexedForeground(TextColor::DARK_GREEN);
break; break;
case ForegroundCyan: case ForegroundCyan:
attr.SetIndexedForeground(DARK_CYAN); attr.SetIndexedForeground(TextColor::DARK_CYAN);
break; break;
case ForegroundRed: case ForegroundRed:
attr.SetIndexedForeground(DARK_RED); attr.SetIndexedForeground(TextColor::DARK_RED);
break; break;
case ForegroundMagenta: case ForegroundMagenta:
attr.SetIndexedForeground(DARK_MAGENTA); attr.SetIndexedForeground(TextColor::DARK_MAGENTA);
break; break;
case ForegroundYellow: case ForegroundYellow:
attr.SetIndexedForeground(DARK_YELLOW); attr.SetIndexedForeground(TextColor::DARK_YELLOW);
break; break;
case ForegroundWhite: case ForegroundWhite:
attr.SetIndexedForeground(DARK_WHITE); attr.SetIndexedForeground(TextColor::DARK_WHITE);
break; break;
case BackgroundBlack: case BackgroundBlack:
attr.SetIndexedBackground(DARK_BLACK); attr.SetIndexedBackground(TextColor::DARK_BLACK);
break; break;
case BackgroundBlue: case BackgroundBlue:
attr.SetIndexedBackground(DARK_BLUE); attr.SetIndexedBackground(TextColor::DARK_BLUE);
break; break;
case BackgroundGreen: case BackgroundGreen:
attr.SetIndexedBackground(DARK_GREEN); attr.SetIndexedBackground(TextColor::DARK_GREEN);
break; break;
case BackgroundCyan: case BackgroundCyan:
attr.SetIndexedBackground(DARK_CYAN); attr.SetIndexedBackground(TextColor::DARK_CYAN);
break; break;
case BackgroundRed: case BackgroundRed:
attr.SetIndexedBackground(DARK_RED); attr.SetIndexedBackground(TextColor::DARK_RED);
break; break;
case BackgroundMagenta: case BackgroundMagenta:
attr.SetIndexedBackground(DARK_MAGENTA); attr.SetIndexedBackground(TextColor::DARK_MAGENTA);
break; break;
case BackgroundYellow: case BackgroundYellow:
attr.SetIndexedBackground(DARK_YELLOW); attr.SetIndexedBackground(TextColor::DARK_YELLOW);
break; break;
case BackgroundWhite: case BackgroundWhite:
attr.SetIndexedBackground(DARK_WHITE); attr.SetIndexedBackground(TextColor::DARK_WHITE);
break; break;
case BrightForegroundBlack: case BrightForegroundBlack:
attr.SetIndexedForeground(BRIGHT_BLACK); attr.SetIndexedForeground(TextColor::BRIGHT_BLACK);
break; break;
case BrightForegroundBlue: case BrightForegroundBlue:
attr.SetIndexedForeground(BRIGHT_BLUE); attr.SetIndexedForeground(TextColor::BRIGHT_BLUE);
break; break;
case BrightForegroundGreen: case BrightForegroundGreen:
attr.SetIndexedForeground(BRIGHT_GREEN); attr.SetIndexedForeground(TextColor::BRIGHT_GREEN);
break; break;
case BrightForegroundCyan: case BrightForegroundCyan:
attr.SetIndexedForeground(BRIGHT_CYAN); attr.SetIndexedForeground(TextColor::BRIGHT_CYAN);
break; break;
case BrightForegroundRed: case BrightForegroundRed:
attr.SetIndexedForeground(BRIGHT_RED); attr.SetIndexedForeground(TextColor::BRIGHT_RED);
break; break;
case BrightForegroundMagenta: case BrightForegroundMagenta:
attr.SetIndexedForeground(BRIGHT_MAGENTA); attr.SetIndexedForeground(TextColor::BRIGHT_MAGENTA);
break; break;
case BrightForegroundYellow: case BrightForegroundYellow:
attr.SetIndexedForeground(BRIGHT_YELLOW); attr.SetIndexedForeground(TextColor::BRIGHT_YELLOW);
break; break;
case BrightForegroundWhite: case BrightForegroundWhite:
attr.SetIndexedForeground(BRIGHT_WHITE); attr.SetIndexedForeground(TextColor::BRIGHT_WHITE);
break; break;
case BrightBackgroundBlack: case BrightBackgroundBlack:
attr.SetIndexedBackground(BRIGHT_BLACK); attr.SetIndexedBackground(TextColor::BRIGHT_BLACK);
break; break;
case BrightBackgroundBlue: case BrightBackgroundBlue:
attr.SetIndexedBackground(BRIGHT_BLUE); attr.SetIndexedBackground(TextColor::BRIGHT_BLUE);
break; break;
case BrightBackgroundGreen: case BrightBackgroundGreen:
attr.SetIndexedBackground(BRIGHT_GREEN); attr.SetIndexedBackground(TextColor::BRIGHT_GREEN);
break; break;
case BrightBackgroundCyan: case BrightBackgroundCyan:
attr.SetIndexedBackground(BRIGHT_CYAN); attr.SetIndexedBackground(TextColor::BRIGHT_CYAN);
break; break;
case BrightBackgroundRed: case BrightBackgroundRed:
attr.SetIndexedBackground(BRIGHT_RED); attr.SetIndexedBackground(TextColor::BRIGHT_RED);
break; break;
case BrightBackgroundMagenta: case BrightBackgroundMagenta:
attr.SetIndexedBackground(BRIGHT_MAGENTA); attr.SetIndexedBackground(TextColor::BRIGHT_MAGENTA);
break; break;
case BrightBackgroundYellow: case BrightBackgroundYellow:
attr.SetIndexedBackground(BRIGHT_YELLOW); attr.SetIndexedBackground(TextColor::BRIGHT_YELLOW);
break; break;
case BrightBackgroundWhite: case BrightBackgroundWhite:
attr.SetIndexedBackground(BRIGHT_WHITE); attr.SetIndexedBackground(TextColor::BRIGHT_WHITE);
break; break;
case ForegroundExtended: case ForegroundExtended:
i += _SetRgbColorsHelper(options.subspan(i + 1), attr, true); i += _SetRgbColorsHelper(options.subspan(i + 1), attr, true);

View file

@ -1307,49 +1307,49 @@ public:
Log::Comment(L"Testing graphics 'Foreground Color Black'"); Log::Comment(L"Testing graphics 'Foreground Color Black'");
_testGetSet->_attribute = TextAttribute{ FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY }; _testGetSet->_attribute = TextAttribute{ FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY };
_testGetSet->_expectedAttribute = _testGetSet->_attribute; _testGetSet->_expectedAttribute = _testGetSet->_attribute;
_testGetSet->_expectedAttribute.SetIndexedForeground(0); _testGetSet->_expectedAttribute.SetIndexedForeground(TextColor::DARK_BLACK);
break; break;
case DispatchTypes::GraphicsOptions::ForegroundBlue: case DispatchTypes::GraphicsOptions::ForegroundBlue:
Log::Comment(L"Testing graphics 'Foreground Color Blue'"); Log::Comment(L"Testing graphics 'Foreground Color Blue'");
_testGetSet->_attribute = TextAttribute{ FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_INTENSITY }; _testGetSet->_attribute = TextAttribute{ FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_INTENSITY };
_testGetSet->_expectedAttribute = _testGetSet->_attribute; _testGetSet->_expectedAttribute = _testGetSet->_attribute;
_testGetSet->_expectedAttribute.SetIndexedForeground(FOREGROUND_BLUE); _testGetSet->_expectedAttribute.SetIndexedForeground(TextColor::DARK_BLUE);
break; break;
case DispatchTypes::GraphicsOptions::ForegroundGreen: case DispatchTypes::GraphicsOptions::ForegroundGreen:
Log::Comment(L"Testing graphics 'Foreground Color Green'"); Log::Comment(L"Testing graphics 'Foreground Color Green'");
_testGetSet->_attribute = TextAttribute{ FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_INTENSITY }; _testGetSet->_attribute = TextAttribute{ FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_INTENSITY };
_testGetSet->_expectedAttribute = _testGetSet->_attribute; _testGetSet->_expectedAttribute = _testGetSet->_attribute;
_testGetSet->_expectedAttribute.SetIndexedForeground(FOREGROUND_GREEN); _testGetSet->_expectedAttribute.SetIndexedForeground(TextColor::DARK_GREEN);
break; break;
case DispatchTypes::GraphicsOptions::ForegroundCyan: case DispatchTypes::GraphicsOptions::ForegroundCyan:
Log::Comment(L"Testing graphics 'Foreground Color Cyan'"); Log::Comment(L"Testing graphics 'Foreground Color Cyan'");
_testGetSet->_attribute = TextAttribute{ FOREGROUND_RED | FOREGROUND_INTENSITY }; _testGetSet->_attribute = TextAttribute{ FOREGROUND_RED | FOREGROUND_INTENSITY };
_testGetSet->_expectedAttribute = _testGetSet->_attribute; _testGetSet->_expectedAttribute = _testGetSet->_attribute;
_testGetSet->_expectedAttribute.SetIndexedForeground(FOREGROUND_BLUE | FOREGROUND_GREEN); _testGetSet->_expectedAttribute.SetIndexedForeground(TextColor::DARK_CYAN);
break; break;
case DispatchTypes::GraphicsOptions::ForegroundRed: case DispatchTypes::GraphicsOptions::ForegroundRed:
Log::Comment(L"Testing graphics 'Foreground Color Red'"); Log::Comment(L"Testing graphics 'Foreground Color Red'");
_testGetSet->_attribute = TextAttribute{ FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_INTENSITY }; _testGetSet->_attribute = TextAttribute{ FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_INTENSITY };
_testGetSet->_expectedAttribute = _testGetSet->_attribute; _testGetSet->_expectedAttribute = _testGetSet->_attribute;
_testGetSet->_expectedAttribute.SetIndexedForeground(FOREGROUND_RED); _testGetSet->_expectedAttribute.SetIndexedForeground(TextColor::DARK_RED);
break; break;
case DispatchTypes::GraphicsOptions::ForegroundMagenta: case DispatchTypes::GraphicsOptions::ForegroundMagenta:
Log::Comment(L"Testing graphics 'Foreground Color Magenta'"); Log::Comment(L"Testing graphics 'Foreground Color Magenta'");
_testGetSet->_attribute = TextAttribute{ FOREGROUND_GREEN | FOREGROUND_INTENSITY }; _testGetSet->_attribute = TextAttribute{ FOREGROUND_GREEN | FOREGROUND_INTENSITY };
_testGetSet->_expectedAttribute = _testGetSet->_attribute; _testGetSet->_expectedAttribute = _testGetSet->_attribute;
_testGetSet->_expectedAttribute.SetIndexedForeground(FOREGROUND_BLUE | FOREGROUND_RED); _testGetSet->_expectedAttribute.SetIndexedForeground(TextColor::DARK_MAGENTA);
break; break;
case DispatchTypes::GraphicsOptions::ForegroundYellow: case DispatchTypes::GraphicsOptions::ForegroundYellow:
Log::Comment(L"Testing graphics 'Foreground Color Yellow'"); Log::Comment(L"Testing graphics 'Foreground Color Yellow'");
_testGetSet->_attribute = TextAttribute{ FOREGROUND_BLUE | FOREGROUND_INTENSITY }; _testGetSet->_attribute = TextAttribute{ FOREGROUND_BLUE | FOREGROUND_INTENSITY };
_testGetSet->_expectedAttribute = _testGetSet->_attribute; _testGetSet->_expectedAttribute = _testGetSet->_attribute;
_testGetSet->_expectedAttribute.SetIndexedForeground(FOREGROUND_GREEN | FOREGROUND_RED); _testGetSet->_expectedAttribute.SetIndexedForeground(TextColor::DARK_YELLOW);
break; break;
case DispatchTypes::GraphicsOptions::ForegroundWhite: case DispatchTypes::GraphicsOptions::ForegroundWhite:
Log::Comment(L"Testing graphics 'Foreground Color White'"); Log::Comment(L"Testing graphics 'Foreground Color White'");
_testGetSet->_attribute = TextAttribute{ FOREGROUND_INTENSITY }; _testGetSet->_attribute = TextAttribute{ FOREGROUND_INTENSITY };
_testGetSet->_expectedAttribute = _testGetSet->_attribute; _testGetSet->_expectedAttribute = _testGetSet->_attribute;
_testGetSet->_expectedAttribute.SetIndexedForeground(FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED); _testGetSet->_expectedAttribute.SetIndexedForeground(TextColor::DARK_WHITE);
break; break;
case DispatchTypes::GraphicsOptions::ForegroundDefault: case DispatchTypes::GraphicsOptions::ForegroundDefault:
Log::Comment(L"Testing graphics 'Foreground Color Default'"); Log::Comment(L"Testing graphics 'Foreground Color Default'");
@ -1362,49 +1362,49 @@ public:
Log::Comment(L"Testing graphics 'Background Color Black'"); Log::Comment(L"Testing graphics 'Background Color Black'");
_testGetSet->_attribute = TextAttribute{ BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE | BACKGROUND_INTENSITY }; _testGetSet->_attribute = TextAttribute{ BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE | BACKGROUND_INTENSITY };
_testGetSet->_expectedAttribute = _testGetSet->_attribute; _testGetSet->_expectedAttribute = _testGetSet->_attribute;
_testGetSet->_expectedAttribute.SetIndexedBackground(0); _testGetSet->_expectedAttribute.SetIndexedBackground(TextColor::DARK_BLACK);
break; break;
case DispatchTypes::GraphicsOptions::BackgroundBlue: case DispatchTypes::GraphicsOptions::BackgroundBlue:
Log::Comment(L"Testing graphics 'Background Color Blue'"); Log::Comment(L"Testing graphics 'Background Color Blue'");
_testGetSet->_attribute = TextAttribute{ BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_INTENSITY }; _testGetSet->_attribute = TextAttribute{ BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_INTENSITY };
_testGetSet->_expectedAttribute = _testGetSet->_attribute; _testGetSet->_expectedAttribute = _testGetSet->_attribute;
_testGetSet->_expectedAttribute.SetIndexedBackground(BACKGROUND_BLUE >> 4); _testGetSet->_expectedAttribute.SetIndexedBackground(TextColor::DARK_BLUE);
break; break;
case DispatchTypes::GraphicsOptions::BackgroundGreen: case DispatchTypes::GraphicsOptions::BackgroundGreen:
Log::Comment(L"Testing graphics 'Background Color Green'"); Log::Comment(L"Testing graphics 'Background Color Green'");
_testGetSet->_attribute = TextAttribute{ BACKGROUND_RED | BACKGROUND_BLUE | BACKGROUND_INTENSITY }; _testGetSet->_attribute = TextAttribute{ BACKGROUND_RED | BACKGROUND_BLUE | BACKGROUND_INTENSITY };
_testGetSet->_expectedAttribute = _testGetSet->_attribute; _testGetSet->_expectedAttribute = _testGetSet->_attribute;
_testGetSet->_expectedAttribute.SetIndexedBackground(BACKGROUND_GREEN >> 4); _testGetSet->_expectedAttribute.SetIndexedBackground(TextColor::DARK_GREEN);
break; break;
case DispatchTypes::GraphicsOptions::BackgroundCyan: case DispatchTypes::GraphicsOptions::BackgroundCyan:
Log::Comment(L"Testing graphics 'Background Color Cyan'"); Log::Comment(L"Testing graphics 'Background Color Cyan'");
_testGetSet->_attribute = TextAttribute{ BACKGROUND_RED | BACKGROUND_INTENSITY }; _testGetSet->_attribute = TextAttribute{ BACKGROUND_RED | BACKGROUND_INTENSITY };
_testGetSet->_expectedAttribute = _testGetSet->_attribute; _testGetSet->_expectedAttribute = _testGetSet->_attribute;
_testGetSet->_expectedAttribute.SetIndexedBackground((BACKGROUND_BLUE | BACKGROUND_GREEN) >> 4); _testGetSet->_expectedAttribute.SetIndexedBackground(TextColor::DARK_CYAN);
break; break;
case DispatchTypes::GraphicsOptions::BackgroundRed: case DispatchTypes::GraphicsOptions::BackgroundRed:
Log::Comment(L"Testing graphics 'Background Color Red'"); Log::Comment(L"Testing graphics 'Background Color Red'");
_testGetSet->_attribute = TextAttribute{ BACKGROUND_BLUE | BACKGROUND_GREEN | BACKGROUND_INTENSITY }; _testGetSet->_attribute = TextAttribute{ BACKGROUND_BLUE | BACKGROUND_GREEN | BACKGROUND_INTENSITY };
_testGetSet->_expectedAttribute = _testGetSet->_attribute; _testGetSet->_expectedAttribute = _testGetSet->_attribute;
_testGetSet->_expectedAttribute.SetIndexedBackground(BACKGROUND_RED >> 4); _testGetSet->_expectedAttribute.SetIndexedBackground(TextColor::DARK_RED);
break; break;
case DispatchTypes::GraphicsOptions::BackgroundMagenta: case DispatchTypes::GraphicsOptions::BackgroundMagenta:
Log::Comment(L"Testing graphics 'Background Color Magenta'"); Log::Comment(L"Testing graphics 'Background Color Magenta'");
_testGetSet->_attribute = TextAttribute{ BACKGROUND_GREEN | BACKGROUND_INTENSITY }; _testGetSet->_attribute = TextAttribute{ BACKGROUND_GREEN | BACKGROUND_INTENSITY };
_testGetSet->_expectedAttribute = _testGetSet->_attribute; _testGetSet->_expectedAttribute = _testGetSet->_attribute;
_testGetSet->_expectedAttribute.SetIndexedBackground((BACKGROUND_BLUE | BACKGROUND_RED) >> 4); _testGetSet->_expectedAttribute.SetIndexedBackground(TextColor::DARK_MAGENTA);
break; break;
case DispatchTypes::GraphicsOptions::BackgroundYellow: case DispatchTypes::GraphicsOptions::BackgroundYellow:
Log::Comment(L"Testing graphics 'Background Color Yellow'"); Log::Comment(L"Testing graphics 'Background Color Yellow'");
_testGetSet->_attribute = TextAttribute{ BACKGROUND_BLUE | BACKGROUND_INTENSITY }; _testGetSet->_attribute = TextAttribute{ BACKGROUND_BLUE | BACKGROUND_INTENSITY };
_testGetSet->_expectedAttribute = _testGetSet->_attribute; _testGetSet->_expectedAttribute = _testGetSet->_attribute;
_testGetSet->_expectedAttribute.SetIndexedBackground((BACKGROUND_GREEN | BACKGROUND_RED) >> 4); _testGetSet->_expectedAttribute.SetIndexedBackground(TextColor::DARK_YELLOW);
break; break;
case DispatchTypes::GraphicsOptions::BackgroundWhite: case DispatchTypes::GraphicsOptions::BackgroundWhite:
Log::Comment(L"Testing graphics 'Background Color White'"); Log::Comment(L"Testing graphics 'Background Color White'");
_testGetSet->_attribute = TextAttribute{ BACKGROUND_INTENSITY }; _testGetSet->_attribute = TextAttribute{ BACKGROUND_INTENSITY };
_testGetSet->_expectedAttribute = _testGetSet->_attribute; _testGetSet->_expectedAttribute = _testGetSet->_attribute;
_testGetSet->_expectedAttribute.SetIndexedBackground((BACKGROUND_BLUE | BACKGROUND_GREEN | BACKGROUND_RED) >> 4); _testGetSet->_expectedAttribute.SetIndexedBackground(TextColor::DARK_WHITE);
break; break;
case DispatchTypes::GraphicsOptions::BackgroundDefault: case DispatchTypes::GraphicsOptions::BackgroundDefault:
Log::Comment(L"Testing graphics 'Background Color Default'"); Log::Comment(L"Testing graphics 'Background Color Default'");
@ -1417,97 +1417,97 @@ public:
Log::Comment(L"Testing graphics 'Bright Foreground Color Black'"); Log::Comment(L"Testing graphics 'Bright Foreground Color Black'");
_testGetSet->_attribute = TextAttribute{ FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE }; _testGetSet->_attribute = TextAttribute{ FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE };
_testGetSet->_expectedAttribute = _testGetSet->_attribute; _testGetSet->_expectedAttribute = _testGetSet->_attribute;
_testGetSet->_expectedAttribute.SetIndexedForeground(FOREGROUND_INTENSITY); _testGetSet->_expectedAttribute.SetIndexedForeground(TextColor::BRIGHT_BLACK);
break; break;
case DispatchTypes::GraphicsOptions::BrightForegroundBlue: case DispatchTypes::GraphicsOptions::BrightForegroundBlue:
Log::Comment(L"Testing graphics 'Bright Foreground Color Blue'"); Log::Comment(L"Testing graphics 'Bright Foreground Color Blue'");
_testGetSet->_attribute = TextAttribute{ FOREGROUND_RED | FOREGROUND_GREEN }; _testGetSet->_attribute = TextAttribute{ FOREGROUND_RED | FOREGROUND_GREEN };
_testGetSet->_expectedAttribute = _testGetSet->_attribute; _testGetSet->_expectedAttribute = _testGetSet->_attribute;
_testGetSet->_expectedAttribute.SetIndexedForeground(FOREGROUND_INTENSITY | FOREGROUND_BLUE); _testGetSet->_expectedAttribute.SetIndexedForeground(TextColor::BRIGHT_BLUE);
break; break;
case DispatchTypes::GraphicsOptions::BrightForegroundGreen: case DispatchTypes::GraphicsOptions::BrightForegroundGreen:
Log::Comment(L"Testing graphics 'Bright Foreground Color Green'"); Log::Comment(L"Testing graphics 'Bright Foreground Color Green'");
_testGetSet->_attribute = TextAttribute{ FOREGROUND_RED | FOREGROUND_BLUE }; _testGetSet->_attribute = TextAttribute{ FOREGROUND_RED | FOREGROUND_BLUE };
_testGetSet->_expectedAttribute = _testGetSet->_attribute; _testGetSet->_expectedAttribute = _testGetSet->_attribute;
_testGetSet->_expectedAttribute.SetIndexedForeground(FOREGROUND_INTENSITY | FOREGROUND_GREEN); _testGetSet->_expectedAttribute.SetIndexedForeground(TextColor::BRIGHT_GREEN);
break; break;
case DispatchTypes::GraphicsOptions::BrightForegroundCyan: case DispatchTypes::GraphicsOptions::BrightForegroundCyan:
Log::Comment(L"Testing graphics 'Bright Foreground Color Cyan'"); Log::Comment(L"Testing graphics 'Bright Foreground Color Cyan'");
_testGetSet->_attribute = TextAttribute{ FOREGROUND_RED }; _testGetSet->_attribute = TextAttribute{ FOREGROUND_RED };
_testGetSet->_expectedAttribute = _testGetSet->_attribute; _testGetSet->_expectedAttribute = _testGetSet->_attribute;
_testGetSet->_expectedAttribute.SetIndexedForeground(FOREGROUND_INTENSITY | FOREGROUND_BLUE | FOREGROUND_GREEN); _testGetSet->_expectedAttribute.SetIndexedForeground(TextColor::BRIGHT_CYAN);
break; break;
case DispatchTypes::GraphicsOptions::BrightForegroundRed: case DispatchTypes::GraphicsOptions::BrightForegroundRed:
Log::Comment(L"Testing graphics 'Bright Foreground Color Red'"); Log::Comment(L"Testing graphics 'Bright Foreground Color Red'");
_testGetSet->_attribute = TextAttribute{ FOREGROUND_BLUE | FOREGROUND_GREEN }; _testGetSet->_attribute = TextAttribute{ FOREGROUND_BLUE | FOREGROUND_GREEN };
_testGetSet->_expectedAttribute = _testGetSet->_attribute; _testGetSet->_expectedAttribute = _testGetSet->_attribute;
_testGetSet->_expectedAttribute.SetIndexedForeground(FOREGROUND_INTENSITY | FOREGROUND_RED); _testGetSet->_expectedAttribute.SetIndexedForeground(TextColor::BRIGHT_RED);
break; break;
case DispatchTypes::GraphicsOptions::BrightForegroundMagenta: case DispatchTypes::GraphicsOptions::BrightForegroundMagenta:
Log::Comment(L"Testing graphics 'Bright Foreground Color Magenta'"); Log::Comment(L"Testing graphics 'Bright Foreground Color Magenta'");
_testGetSet->_attribute = TextAttribute{ FOREGROUND_GREEN }; _testGetSet->_attribute = TextAttribute{ FOREGROUND_GREEN };
_testGetSet->_expectedAttribute = _testGetSet->_attribute; _testGetSet->_expectedAttribute = _testGetSet->_attribute;
_testGetSet->_expectedAttribute.SetIndexedForeground(FOREGROUND_INTENSITY | FOREGROUND_BLUE | FOREGROUND_RED); _testGetSet->_expectedAttribute.SetIndexedForeground(TextColor::BRIGHT_MAGENTA);
break; break;
case DispatchTypes::GraphicsOptions::BrightForegroundYellow: case DispatchTypes::GraphicsOptions::BrightForegroundYellow:
Log::Comment(L"Testing graphics 'Bright Foreground Color Yellow'"); Log::Comment(L"Testing graphics 'Bright Foreground Color Yellow'");
_testGetSet->_attribute = TextAttribute{ FOREGROUND_BLUE }; _testGetSet->_attribute = TextAttribute{ FOREGROUND_BLUE };
_testGetSet->_expectedAttribute = _testGetSet->_attribute; _testGetSet->_expectedAttribute = _testGetSet->_attribute;
_testGetSet->_expectedAttribute.SetIndexedForeground(FOREGROUND_INTENSITY | FOREGROUND_GREEN | FOREGROUND_RED); _testGetSet->_expectedAttribute.SetIndexedForeground(TextColor::BRIGHT_YELLOW);
break; break;
case DispatchTypes::GraphicsOptions::BrightForegroundWhite: case DispatchTypes::GraphicsOptions::BrightForegroundWhite:
Log::Comment(L"Testing graphics 'Bright Foreground Color White'"); Log::Comment(L"Testing graphics 'Bright Foreground Color White'");
_testGetSet->_attribute = TextAttribute{ 0 }; _testGetSet->_attribute = TextAttribute{ 0 };
_testGetSet->_expectedAttribute = _testGetSet->_attribute; _testGetSet->_expectedAttribute = _testGetSet->_attribute;
_testGetSet->_expectedAttribute.SetIndexedForeground(FOREGROUND_INTENSITY | FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED); _testGetSet->_expectedAttribute.SetIndexedForeground(TextColor::BRIGHT_WHITE);
break; break;
case DispatchTypes::GraphicsOptions::BrightBackgroundBlack: case DispatchTypes::GraphicsOptions::BrightBackgroundBlack:
Log::Comment(L"Testing graphics 'Bright Background Color Black'"); Log::Comment(L"Testing graphics 'Bright Background Color Black'");
_testGetSet->_attribute = TextAttribute{ BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE }; _testGetSet->_attribute = TextAttribute{ BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE };
_testGetSet->_expectedAttribute = _testGetSet->_attribute; _testGetSet->_expectedAttribute = _testGetSet->_attribute;
_testGetSet->_expectedAttribute.SetIndexedBackground(BACKGROUND_INTENSITY >> 4); _testGetSet->_expectedAttribute.SetIndexedBackground(TextColor::BRIGHT_BLACK);
break; break;
case DispatchTypes::GraphicsOptions::BrightBackgroundBlue: case DispatchTypes::GraphicsOptions::BrightBackgroundBlue:
Log::Comment(L"Testing graphics 'Bright Background Color Blue'"); Log::Comment(L"Testing graphics 'Bright Background Color Blue'");
_testGetSet->_attribute = TextAttribute{ BACKGROUND_RED | BACKGROUND_GREEN }; _testGetSet->_attribute = TextAttribute{ BACKGROUND_RED | BACKGROUND_GREEN };
_testGetSet->_expectedAttribute = _testGetSet->_attribute; _testGetSet->_expectedAttribute = _testGetSet->_attribute;
_testGetSet->_expectedAttribute.SetIndexedBackground((BACKGROUND_INTENSITY | BACKGROUND_BLUE) >> 4); _testGetSet->_expectedAttribute.SetIndexedBackground(TextColor::BRIGHT_BLUE);
break; break;
case DispatchTypes::GraphicsOptions::BrightBackgroundGreen: case DispatchTypes::GraphicsOptions::BrightBackgroundGreen:
Log::Comment(L"Testing graphics 'Bright Background Color Green'"); Log::Comment(L"Testing graphics 'Bright Background Color Green'");
_testGetSet->_attribute = TextAttribute{ BACKGROUND_RED | BACKGROUND_BLUE }; _testGetSet->_attribute = TextAttribute{ BACKGROUND_RED | BACKGROUND_BLUE };
_testGetSet->_expectedAttribute = _testGetSet->_attribute; _testGetSet->_expectedAttribute = _testGetSet->_attribute;
_testGetSet->_expectedAttribute.SetIndexedBackground((BACKGROUND_INTENSITY | BACKGROUND_GREEN) >> 4); _testGetSet->_expectedAttribute.SetIndexedBackground(TextColor::BRIGHT_GREEN);
break; break;
case DispatchTypes::GraphicsOptions::BrightBackgroundCyan: case DispatchTypes::GraphicsOptions::BrightBackgroundCyan:
Log::Comment(L"Testing graphics 'Bright Background Color Cyan'"); Log::Comment(L"Testing graphics 'Bright Background Color Cyan'");
_testGetSet->_attribute = TextAttribute{ BACKGROUND_RED }; _testGetSet->_attribute = TextAttribute{ BACKGROUND_RED };
_testGetSet->_expectedAttribute = _testGetSet->_attribute; _testGetSet->_expectedAttribute = _testGetSet->_attribute;
_testGetSet->_expectedAttribute.SetIndexedBackground((BACKGROUND_INTENSITY | BACKGROUND_BLUE | BACKGROUND_GREEN) >> 4); _testGetSet->_expectedAttribute.SetIndexedBackground(TextColor::BRIGHT_CYAN);
break; break;
case DispatchTypes::GraphicsOptions::BrightBackgroundRed: case DispatchTypes::GraphicsOptions::BrightBackgroundRed:
Log::Comment(L"Testing graphics 'Bright Background Color Red'"); Log::Comment(L"Testing graphics 'Bright Background Color Red'");
_testGetSet->_attribute = TextAttribute{ BACKGROUND_BLUE | BACKGROUND_GREEN }; _testGetSet->_attribute = TextAttribute{ BACKGROUND_BLUE | BACKGROUND_GREEN };
_testGetSet->_expectedAttribute = _testGetSet->_attribute; _testGetSet->_expectedAttribute = _testGetSet->_attribute;
_testGetSet->_expectedAttribute.SetIndexedBackground((BACKGROUND_INTENSITY | BACKGROUND_RED) >> 4); _testGetSet->_expectedAttribute.SetIndexedBackground(TextColor::BRIGHT_RED);
break; break;
case DispatchTypes::GraphicsOptions::BrightBackgroundMagenta: case DispatchTypes::GraphicsOptions::BrightBackgroundMagenta:
Log::Comment(L"Testing graphics 'Bright Background Color Magenta'"); Log::Comment(L"Testing graphics 'Bright Background Color Magenta'");
_testGetSet->_attribute = TextAttribute{ BACKGROUND_GREEN }; _testGetSet->_attribute = TextAttribute{ BACKGROUND_GREEN };
_testGetSet->_expectedAttribute = _testGetSet->_attribute; _testGetSet->_expectedAttribute = _testGetSet->_attribute;
_testGetSet->_expectedAttribute.SetIndexedBackground((BACKGROUND_INTENSITY | BACKGROUND_BLUE | BACKGROUND_RED) >> 4); _testGetSet->_expectedAttribute.SetIndexedBackground(TextColor::BRIGHT_MAGENTA);
break; break;
case DispatchTypes::GraphicsOptions::BrightBackgroundYellow: case DispatchTypes::GraphicsOptions::BrightBackgroundYellow:
Log::Comment(L"Testing graphics 'Bright Background Color Yellow'"); Log::Comment(L"Testing graphics 'Bright Background Color Yellow'");
_testGetSet->_attribute = TextAttribute{ BACKGROUND_BLUE }; _testGetSet->_attribute = TextAttribute{ BACKGROUND_BLUE };
_testGetSet->_expectedAttribute = _testGetSet->_attribute; _testGetSet->_expectedAttribute = _testGetSet->_attribute;
_testGetSet->_expectedAttribute.SetIndexedBackground((BACKGROUND_INTENSITY | BACKGROUND_GREEN | BACKGROUND_RED) >> 4); _testGetSet->_expectedAttribute.SetIndexedBackground(TextColor::BRIGHT_YELLOW);
break; break;
case DispatchTypes::GraphicsOptions::BrightBackgroundWhite: case DispatchTypes::GraphicsOptions::BrightBackgroundWhite:
Log::Comment(L"Testing graphics 'Bright Background Color White'"); Log::Comment(L"Testing graphics 'Bright Background Color White'");
_testGetSet->_attribute = TextAttribute{ 0 }; _testGetSet->_attribute = TextAttribute{ 0 };
_testGetSet->_expectedAttribute = _testGetSet->_attribute; _testGetSet->_expectedAttribute = _testGetSet->_attribute;
_testGetSet->_expectedAttribute.SetIndexedBackground((BACKGROUND_INTENSITY | BACKGROUND_BLUE | BACKGROUND_GREEN | BACKGROUND_RED) >> 4); _testGetSet->_expectedAttribute.SetIndexedBackground(TextColor::BRIGHT_WHITE);
break; break;
default: default:
VERIFY_FAIL(L"Test not implemented yet!"); VERIFY_FAIL(L"Test not implemented yet!");
@ -1545,7 +1545,7 @@ public:
cOptions = 1; cOptions = 1;
rgOptions[0] = DispatchTypes::GraphicsOptions::ForegroundCyan; rgOptions[0] = DispatchTypes::GraphicsOptions::ForegroundCyan;
_testGetSet->_expectedAttribute = {}; _testGetSet->_expectedAttribute = {};
_testGetSet->_expectedAttribute.SetIndexedForeground(3); _testGetSet->_expectedAttribute.SetIndexedForeground(TextColor::DARK_CYAN);
_testGetSet->_expectedAttribute.SetDefaultBackground(); _testGetSet->_expectedAttribute.SetDefaultBackground();
VERIFY_IS_TRUE(_pDispatch->SetGraphicsRendition({ rgOptions, cOptions })); VERIFY_IS_TRUE(_pDispatch->SetGraphicsRendition({ rgOptions, cOptions }));
@ -1561,7 +1561,7 @@ public:
cOptions = 1; cOptions = 1;
rgOptions[0] = DispatchTypes::GraphicsOptions::ForegroundRed; rgOptions[0] = DispatchTypes::GraphicsOptions::ForegroundRed;
_testGetSet->_expectedAttribute = {}; _testGetSet->_expectedAttribute = {};
_testGetSet->_expectedAttribute.SetIndexedForeground(FOREGROUND_RED); _testGetSet->_expectedAttribute.SetIndexedForeground(TextColor::DARK_RED);
_testGetSet->_expectedAttribute.SetDefaultBackground(); _testGetSet->_expectedAttribute.SetDefaultBackground();
VERIFY_IS_TRUE(_pDispatch->SetGraphicsRendition({ rgOptions, cOptions })); VERIFY_IS_TRUE(_pDispatch->SetGraphicsRendition({ rgOptions, cOptions }));
@ -1572,14 +1572,14 @@ public:
cOptions = 1; cOptions = 1;
rgOptions[0] = DispatchTypes::GraphicsOptions::ForegroundGreen; rgOptions[0] = DispatchTypes::GraphicsOptions::ForegroundGreen;
_testGetSet->_expectedAttribute = {}; _testGetSet->_expectedAttribute = {};
_testGetSet->_expectedAttribute.SetIndexedForeground(FOREGROUND_GREEN); _testGetSet->_expectedAttribute.SetIndexedForeground(TextColor::DARK_GREEN);
_testGetSet->_expectedAttribute.SetDefaultBackground(); _testGetSet->_expectedAttribute.SetDefaultBackground();
VERIFY_IS_TRUE(_pDispatch->SetGraphicsRendition({ rgOptions, cOptions })); VERIFY_IS_TRUE(_pDispatch->SetGraphicsRendition({ rgOptions, cOptions }));
// First pop: // First pop:
cOptions = 0; cOptions = 0;
_testGetSet->_expectedAttribute = {}; _testGetSet->_expectedAttribute = {};
_testGetSet->_expectedAttribute.SetIndexedForeground(FOREGROUND_RED); _testGetSet->_expectedAttribute.SetIndexedForeground(TextColor::DARK_RED);
_testGetSet->_expectedAttribute.SetDefaultBackground(); _testGetSet->_expectedAttribute.SetDefaultBackground();
VERIFY_IS_TRUE(_pDispatch->PopGraphicsRendition()); VERIFY_IS_TRUE(_pDispatch->PopGraphicsRendition());
@ -1593,22 +1593,22 @@ public:
cOptions = 1; cOptions = 1;
rgOptions[0] = DispatchTypes::GraphicsOptions::ForegroundGreen; rgOptions[0] = DispatchTypes::GraphicsOptions::ForegroundGreen;
_testGetSet->_expectedAttribute = {}; _testGetSet->_expectedAttribute = {};
_testGetSet->_expectedAttribute.SetIndexedForeground(FOREGROUND_GREEN); _testGetSet->_expectedAttribute.SetIndexedForeground(TextColor::DARK_GREEN);
_testGetSet->_expectedAttribute.SetDefaultBackground(); _testGetSet->_expectedAttribute.SetDefaultBackground();
VERIFY_IS_TRUE(_pDispatch->SetGraphicsRendition({ rgOptions, cOptions })); VERIFY_IS_TRUE(_pDispatch->SetGraphicsRendition({ rgOptions, cOptions }));
cOptions = 1; cOptions = 1;
rgOptions[0] = DispatchTypes::GraphicsOptions::BoldBright; rgOptions[0] = DispatchTypes::GraphicsOptions::BoldBright;
_testGetSet->_expectedAttribute = {}; _testGetSet->_expectedAttribute = {};
_testGetSet->_expectedAttribute.SetIndexedForeground(FOREGROUND_GREEN); _testGetSet->_expectedAttribute.SetIndexedForeground(TextColor::DARK_GREEN);
_testGetSet->_expectedAttribute.SetBold(true); _testGetSet->_expectedAttribute.SetBold(true);
_testGetSet->_expectedAttribute.SetDefaultBackground(); _testGetSet->_expectedAttribute.SetDefaultBackground();
VERIFY_IS_TRUE(_pDispatch->SetGraphicsRendition({ rgOptions, cOptions })); VERIFY_IS_TRUE(_pDispatch->SetGraphicsRendition({ rgOptions, cOptions }));
rgOptions[0] = DispatchTypes::GraphicsOptions::BackgroundBlue; rgOptions[0] = DispatchTypes::GraphicsOptions::BackgroundBlue;
_testGetSet->_expectedAttribute = {}; _testGetSet->_expectedAttribute = {};
_testGetSet->_expectedAttribute.SetIndexedForeground(FOREGROUND_GREEN); _testGetSet->_expectedAttribute.SetIndexedForeground(TextColor::DARK_GREEN);
_testGetSet->_expectedAttribute.SetIndexedBackground(BACKGROUND_BLUE >> 4); _testGetSet->_expectedAttribute.SetIndexedBackground(TextColor::DARK_BLUE);
_testGetSet->_expectedAttribute.SetBold(true); _testGetSet->_expectedAttribute.SetBold(true);
VERIFY_IS_TRUE(_pDispatch->SetGraphicsRendition({ rgOptions, cOptions })); VERIFY_IS_TRUE(_pDispatch->SetGraphicsRendition({ rgOptions, cOptions }));
@ -1624,8 +1624,8 @@ public:
rgOptions[0] = DispatchTypes::GraphicsOptions::BackgroundGreen; rgOptions[0] = DispatchTypes::GraphicsOptions::BackgroundGreen;
rgOptions[1] = DispatchTypes::GraphicsOptions::DoublyUnderlined; rgOptions[1] = DispatchTypes::GraphicsOptions::DoublyUnderlined;
_testGetSet->_expectedAttribute = {}; _testGetSet->_expectedAttribute = {};
_testGetSet->_expectedAttribute.SetIndexedForeground(FOREGROUND_GREEN); _testGetSet->_expectedAttribute.SetIndexedForeground(TextColor::DARK_GREEN);
_testGetSet->_expectedAttribute.SetIndexedBackground(BACKGROUND_GREEN >> 4); _testGetSet->_expectedAttribute.SetIndexedBackground(TextColor::DARK_GREEN);
_testGetSet->_expectedAttribute.SetBold(true); _testGetSet->_expectedAttribute.SetBold(true);
_testGetSet->_expectedAttribute.SetDoublyUnderlined(true); _testGetSet->_expectedAttribute.SetDoublyUnderlined(true);
VERIFY_IS_TRUE(_pDispatch->SetGraphicsRendition({ rgOptions, cOptions })); VERIFY_IS_TRUE(_pDispatch->SetGraphicsRendition({ rgOptions, cOptions }));
@ -1633,24 +1633,24 @@ public:
cOptions = 1; cOptions = 1;
rgOptions[0] = DispatchTypes::GraphicsOptions::ForegroundRed; rgOptions[0] = DispatchTypes::GraphicsOptions::ForegroundRed;
_testGetSet->_expectedAttribute = {}; _testGetSet->_expectedAttribute = {};
_testGetSet->_expectedAttribute.SetIndexedForeground(FOREGROUND_RED); _testGetSet->_expectedAttribute.SetIndexedForeground(TextColor::DARK_RED);
_testGetSet->_expectedAttribute.SetIndexedBackground(BACKGROUND_GREEN >> 4); _testGetSet->_expectedAttribute.SetIndexedBackground(TextColor::DARK_GREEN);
_testGetSet->_expectedAttribute.SetBold(true); _testGetSet->_expectedAttribute.SetBold(true);
_testGetSet->_expectedAttribute.SetDoublyUnderlined(true); _testGetSet->_expectedAttribute.SetDoublyUnderlined(true);
VERIFY_IS_TRUE(_pDispatch->SetGraphicsRendition({ rgOptions, cOptions })); VERIFY_IS_TRUE(_pDispatch->SetGraphicsRendition({ rgOptions, cOptions }));
rgOptions[0] = DispatchTypes::GraphicsOptions::NotBoldOrFaint; rgOptions[0] = DispatchTypes::GraphicsOptions::NotBoldOrFaint;
_testGetSet->_expectedAttribute = {}; _testGetSet->_expectedAttribute = {};
_testGetSet->_expectedAttribute.SetIndexedForeground(FOREGROUND_RED); _testGetSet->_expectedAttribute.SetIndexedForeground(TextColor::DARK_RED);
_testGetSet->_expectedAttribute.SetIndexedBackground(BACKGROUND_GREEN >> 4); _testGetSet->_expectedAttribute.SetIndexedBackground(TextColor::DARK_GREEN);
_testGetSet->_expectedAttribute.SetDoublyUnderlined(true); _testGetSet->_expectedAttribute.SetDoublyUnderlined(true);
VERIFY_IS_TRUE(_pDispatch->SetGraphicsRendition({ rgOptions, cOptions })); VERIFY_IS_TRUE(_pDispatch->SetGraphicsRendition({ rgOptions, cOptions }));
// And then restore... // And then restore...
cOptions = 0; cOptions = 0;
_testGetSet->_expectedAttribute = {}; _testGetSet->_expectedAttribute = {};
_testGetSet->_expectedAttribute.SetIndexedForeground(FOREGROUND_RED); _testGetSet->_expectedAttribute.SetIndexedForeground(TextColor::DARK_RED);
_testGetSet->_expectedAttribute.SetIndexedBackground(BACKGROUND_BLUE >> 4); _testGetSet->_expectedAttribute.SetIndexedBackground(TextColor::DARK_BLUE);
_testGetSet->_expectedAttribute.SetBold(true); _testGetSet->_expectedAttribute.SetBold(true);
VERIFY_IS_TRUE(_pDispatch->PopGraphicsRendition()); VERIFY_IS_TRUE(_pDispatch->PopGraphicsRendition());
} }
@ -1672,7 +1672,7 @@ public:
Log::Comment(L"Testing graphics 'Foreground Color Blue'"); Log::Comment(L"Testing graphics 'Foreground Color Blue'");
rgOptions[0] = DispatchTypes::GraphicsOptions::ForegroundBlue; 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(_pDispatch.get()->SetGraphicsRendition({ rgOptions, cOptions }));
Log::Comment(L"Enabling brightness"); Log::Comment(L"Enabling brightness");
@ -1683,7 +1683,7 @@ public:
Log::Comment(L"Testing graphics 'Foreground Color Green, with brightness'"); Log::Comment(L"Testing graphics 'Foreground Color Green, with brightness'");
rgOptions[0] = DispatchTypes::GraphicsOptions::ForegroundGreen; 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(_pDispatch.get()->SetGraphicsRendition({ rgOptions, cOptions }));
VERIFY_IS_TRUE(WI_IsFlagSet(_testGetSet->_attribute.GetLegacyAttributes(), FOREGROUND_GREEN)); VERIFY_IS_TRUE(WI_IsFlagSet(_testGetSet->_attribute.GetLegacyAttributes(), FOREGROUND_GREEN));
VERIFY_IS_TRUE(_testGetSet->_attribute.IsBold()); VERIFY_IS_TRUE(_testGetSet->_attribute.IsBold());
@ -1698,13 +1698,13 @@ public:
Log::Comment(L"Testing graphics 'Foreground Color Bright Blue'"); Log::Comment(L"Testing graphics 'Foreground Color Bright Blue'");
rgOptions[0] = DispatchTypes::GraphicsOptions::BrightForegroundBlue; 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(_pDispatch.get()->SetGraphicsRendition({ rgOptions, cOptions }));
VERIFY_IS_FALSE(_testGetSet->_attribute.IsBold()); VERIFY_IS_FALSE(_testGetSet->_attribute.IsBold());
Log::Comment(L"Testing graphics 'Foreground Color Blue', brightness of 9x series doesn't persist"); Log::Comment(L"Testing graphics 'Foreground Color Blue', brightness of 9x series doesn't persist");
rgOptions[0] = DispatchTypes::GraphicsOptions::ForegroundBlue; 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(_pDispatch.get()->SetGraphicsRendition({ rgOptions, cOptions }));
VERIFY_IS_FALSE(_testGetSet->_attribute.IsBold()); VERIFY_IS_FALSE(_testGetSet->_attribute.IsBold());
@ -1717,7 +1717,7 @@ public:
Log::Comment(L"Testing graphics 'Foreground Color Blue'"); Log::Comment(L"Testing graphics 'Foreground Color Blue'");
rgOptions[0] = DispatchTypes::GraphicsOptions::ForegroundBlue; 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(_pDispatch.get()->SetGraphicsRendition({ rgOptions, cOptions }));
VERIFY_IS_FALSE(_testGetSet->_attribute.IsBold()); VERIFY_IS_FALSE(_testGetSet->_attribute.IsBold());
@ -1729,19 +1729,19 @@ public:
Log::Comment(L"Testing graphics 'Foreground Color Bright Blue'"); Log::Comment(L"Testing graphics 'Foreground Color Bright Blue'");
rgOptions[0] = DispatchTypes::GraphicsOptions::BrightForegroundBlue; 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(_pDispatch.get()->SetGraphicsRendition({ rgOptions, cOptions }));
VERIFY_IS_TRUE(_testGetSet->_attribute.IsBold()); VERIFY_IS_TRUE(_testGetSet->_attribute.IsBold());
Log::Comment(L"Testing graphics 'Foreground Color Blue, with brightness', brightness of 9x series doesn't affect brightness"); Log::Comment(L"Testing graphics 'Foreground Color Blue, with brightness', brightness of 9x series doesn't affect brightness");
rgOptions[0] = DispatchTypes::GraphicsOptions::ForegroundBlue; 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(_pDispatch.get()->SetGraphicsRendition({ rgOptions, cOptions }));
VERIFY_IS_TRUE(_testGetSet->_attribute.IsBold()); VERIFY_IS_TRUE(_testGetSet->_attribute.IsBold());
Log::Comment(L"Testing graphics 'Foreground Color Green, with brightness'"); Log::Comment(L"Testing graphics 'Foreground Color Green, with brightness'");
rgOptions[0] = DispatchTypes::GraphicsOptions::ForegroundGreen; 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(_pDispatch.get()->SetGraphicsRendition({ rgOptions, cOptions }));
VERIFY_IS_TRUE(_testGetSet->_attribute.IsBold()); VERIFY_IS_TRUE(_testGetSet->_attribute.IsBold());
} }
@ -1971,16 +1971,16 @@ public:
Log::Comment(L"Requesting SGR attributes (standard colors)."); Log::Comment(L"Requesting SGR attributes (standard colors).");
_testGetSet->PrepData(); _testGetSet->PrepData();
_testGetSet->_attribute = {}; _testGetSet->_attribute = {};
_testGetSet->_attribute.SetIndexedForeground((BYTE)::XtermToWindowsIndex(3)); _testGetSet->_attribute.SetIndexedForeground(TextColor::DARK_YELLOW);
_testGetSet->_attribute.SetIndexedBackground((BYTE)::XtermToWindowsIndex(6)); _testGetSet->_attribute.SetIndexedBackground(TextColor::DARK_CYAN);
requestSetting(L"m"); requestSetting(L"m");
_testGetSet->ValidateInputEvent(L"\033P1$r0;33;46m\033\\"); _testGetSet->ValidateInputEvent(L"\033P1$r0;33;46m\033\\");
Log::Comment(L"Requesting SGR attributes (AIX colors)."); Log::Comment(L"Requesting SGR attributes (AIX colors).");
_testGetSet->PrepData(); _testGetSet->PrepData();
_testGetSet->_attribute = {}; _testGetSet->_attribute = {};
_testGetSet->_attribute.SetIndexedForeground((BYTE)::XtermToWindowsIndex(14)); _testGetSet->_attribute.SetIndexedForeground(TextColor::BRIGHT_CYAN);
_testGetSet->_attribute.SetIndexedBackground((BYTE)::XtermToWindowsIndex(11)); _testGetSet->_attribute.SetIndexedBackground(TextColor::BRIGHT_YELLOW);
requestSetting(L"m"); requestSetting(L"m");
_testGetSet->ValidateInputEvent(L"\033P1$r0;96;103m\033\\"); _testGetSet->ValidateInputEvent(L"\033P1$r0;96;103m\033\\");
@ -2297,14 +2297,14 @@ public:
rgOptions[0] = DispatchTypes::GraphicsOptions::ForegroundExtended; rgOptions[0] = DispatchTypes::GraphicsOptions::ForegroundExtended;
rgOptions[1] = DispatchTypes::GraphicsOptions::BlinkOrXterm256Index; rgOptions[1] = DispatchTypes::GraphicsOptions::BlinkOrXterm256Index;
rgOptions[2] = (DispatchTypes::GraphicsOptions)2; // Green 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 })); VERIFY_IS_TRUE(_pDispatch.get()->SetGraphicsRendition({ rgOptions, cOptions }));
Log::Comment(L"Test 2: Change Background"); Log::Comment(L"Test 2: Change Background");
rgOptions[0] = DispatchTypes::GraphicsOptions::BackgroundExtended; rgOptions[0] = DispatchTypes::GraphicsOptions::BackgroundExtended;
rgOptions[1] = DispatchTypes::GraphicsOptions::BlinkOrXterm256Index; rgOptions[1] = DispatchTypes::GraphicsOptions::BlinkOrXterm256Index;
rgOptions[2] = (DispatchTypes::GraphicsOptions)9; // Bright Red 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 })); VERIFY_IS_TRUE(_pDispatch.get()->SetGraphicsRendition({ rgOptions, cOptions }));
Log::Comment(L"Test 3: Change Foreground to RGB color"); Log::Comment(L"Test 3: Change Foreground to RGB color");
@ -2328,7 +2328,7 @@ public:
rgOptions[0] = DispatchTypes::GraphicsOptions::ForegroundExtended; rgOptions[0] = DispatchTypes::GraphicsOptions::ForegroundExtended;
rgOptions[1] = DispatchTypes::GraphicsOptions::BlinkOrXterm256Index; rgOptions[1] = DispatchTypes::GraphicsOptions::BlinkOrXterm256Index;
rgOptions[2] = (DispatchTypes::GraphicsOptions)9; // Bright Red 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 })); 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"); Log::Comment(L"Test 1: Change Indexed Foreground with missing index parameter");
rgOptions[0] = DispatchTypes::GraphicsOptions::ForegroundExtended; rgOptions[0] = DispatchTypes::GraphicsOptions::ForegroundExtended;
rgOptions[1] = DispatchTypes::GraphicsOptions::BlinkOrXterm256Index; rgOptions[1] = DispatchTypes::GraphicsOptions::BlinkOrXterm256Index;
_testGetSet->_expectedAttribute.SetIndexedForeground256(0); _testGetSet->_expectedAttribute.SetIndexedForeground256(TextColor::DARK_BLACK);
VERIFY_IS_TRUE(_pDispatch.get()->SetGraphicsRendition({ rgOptions, 2 })); VERIFY_IS_TRUE(_pDispatch.get()->SetGraphicsRendition({ rgOptions, 2 }));
Log::Comment(L"Test 2: Change Indexed Background with default index parameter"); Log::Comment(L"Test 2: Change Indexed Background with default index parameter");
rgOptions[0] = DispatchTypes::GraphicsOptions::BackgroundExtended; rgOptions[0] = DispatchTypes::GraphicsOptions::BackgroundExtended;
rgOptions[1] = DispatchTypes::GraphicsOptions::BlinkOrXterm256Index; rgOptions[1] = DispatchTypes::GraphicsOptions::BlinkOrXterm256Index;
rgOptions[2] = {}; rgOptions[2] = {};
_testGetSet->_expectedAttribute.SetIndexedBackground256(0); _testGetSet->_expectedAttribute.SetIndexedBackground256(TextColor::DARK_BLACK);
VERIFY_IS_TRUE(_pDispatch.get()->SetGraphicsRendition({ rgOptions, 3 })); VERIFY_IS_TRUE(_pDispatch.get()->SetGraphicsRendition({ rgOptions, 3 }));
Log::Comment(L"Test 3: Change RGB Foreground with all RGB parameters missing"); Log::Comment(L"Test 3: Change RGB Foreground with all RGB parameters missing");

View file

@ -8,7 +8,7 @@
using namespace Microsoft::Console; using namespace Microsoft::Console;
using namespace std::string_view_literals; using namespace std::string_view_literals;
static constexpr std::array<til::color, 16> campbellColorTable{ static constexpr std::array<til::color, 256> standard256ColorTable{
til::color{ 0x0C, 0x0C, 0x0C }, til::color{ 0x0C, 0x0C, 0x0C },
til::color{ 0xC5, 0x0F, 0x1F }, til::color{ 0xC5, 0x0F, 0x1F },
til::color{ 0x13, 0xA1, 0x0E }, til::color{ 0x13, 0xA1, 0x0E },
@ -25,25 +25,6 @@ static constexpr std::array<til::color, 16> campbellColorTable{
til::color{ 0xB4, 0x00, 0x9E }, til::color{ 0xB4, 0x00, 0x9E },
til::color{ 0x61, 0xD6, 0xD6 }, til::color{ 0x61, 0xD6, 0xD6 },
til::color{ 0xF2, 0xF2, 0xF2 }, til::color{ 0xF2, 0xF2, 0xF2 },
};
static constexpr std::array<til::color, 256> 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, 0x00 },
til::color{ 0x00, 0x00, 0x5F }, til::color{ 0x00, 0x00, 0x5F },
til::color{ 0x00, 0x00, 0x87 }, 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 } } 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:
// - <none>, throws if the table has less that 16 entries
void Utils::InitializeCampbellColorTable(const gsl::span<COLORREF> table)
{
THROW_HR_IF(E_INVALIDARG, table.size() < 16);
std::copy(campbellColorTable.begin(), campbellColorTable.end(), table.begin());
}
void Utils::InitializeCampbellColorTable(const gsl::span<til::color> table)
{
THROW_HR_IF(E_INVALIDARG, table.size() < 16);
std::copy(campbellColorTable.begin(), campbellColorTable.end(), table.begin());
}
gsl::span<const til::color> Utils::CampbellColorTable() gsl::span<const til::color> Utils::CampbellColorTable()
{ {
return gsl::make_span(campbellColorTable); return gsl::make_span(standard256ColorTable).first(16);
} }
// Function Description: // Function Description:
// - Fill the first 16 entries of a given color table with the Campbell color // - Fill up to 256 entries of a given color table with the default values
// scheme, in the Windows BGR order.
// Arguments: // Arguments:
// - table: a color table with at least 16 entries // - table: a color table to be filled
// Return Value: // Return Value:
// - <none>, throws if the table has less that 16 entries // - <none>
void Utils::InitializeCampbellColorTableForConhost(const gsl::span<COLORREF> table) void Utils::InitializeColorTable(const gsl::span<COLORREF> table)
{ {
THROW_HR_IF(E_INVALIDARG, table.size() < 16); const auto tableSize = std::min(table.size(), standard256ColorTable.size());
InitializeCampbellColorTable(table); std::copy_n(standard256ColorTable.begin(), tableSize, table.begin());
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:
// - <none>, throws if the table has less that 16 entries
void Utils::SwapANSIColorOrderForConhost(const gsl::span<COLORREF> 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:
// - <none>, throws if the table has less that 256 entries
void Utils::Initialize256ColorTable(const gsl::span<COLORREF> table)
{
THROW_HR_IF(E_INVALIDARG, table.size() < 256);
std::copy(standardXterm256ColorTable.begin(), standardXterm256ColorTable.end(), table.begin());
} }
#pragma warning(push) #pragma warning(push)

View file

@ -12,11 +12,7 @@ Abstract:
namespace Microsoft::Console::Utils namespace Microsoft::Console::Utils
{ {
void InitializeCampbellColorTable(const gsl::span<COLORREF> table); void InitializeColorTable(const gsl::span<COLORREF> table);
void InitializeCampbellColorTable(const gsl::span<til::color> table);
void InitializeCampbellColorTableForConhost(const gsl::span<COLORREF> table);
void SwapANSIColorOrderForConhost(const gsl::span<COLORREF> table);
void Initialize256ColorTable(const gsl::span<COLORREF> table);
gsl::span<const til::color> CampbellColorTable(); gsl::span<const til::color> CampbellColorTable();
std::optional<til::color> ColorFromXOrgAppColorName(const std::wstring_view wstr) noexcept; std::optional<til::color> ColorFromXOrgAppColorName(const std::wstring_view wstr) noexcept;

View file

@ -20,7 +20,6 @@ class UtilsTests
TEST_CLASS(UtilsTests); TEST_CLASS(UtilsTests);
TEST_METHOD(TestClampToShortMax); TEST_METHOD(TestClampToShortMax);
TEST_METHOD(TestSwapColorPalette);
TEST_METHOD(TestGuidToString); TEST_METHOD(TestGuidToString);
TEST_METHOD(TestSplitString); TEST_METHOD(TestSplitString);
TEST_METHOD(TestFilterStringForPaste); TEST_METHOD(TestFilterStringForPaste);
@ -55,35 +54,6 @@ void UtilsTests::TestClampToShortMax()
auto withinRangeActual = ClampToShortMax(withinRangeExpected, min); auto withinRangeActual = ClampToShortMax(withinRangeExpected, min);
VERIFY_ARE_EQUAL(withinRangeExpected, withinRangeActual); VERIFY_ARE_EQUAL(withinRangeExpected, withinRangeActual);
} }
void UtilsTests::TestSwapColorPalette()
{
std::array<COLORREF, COLOR_TABLE_SIZE> terminalTable;
std::array<COLORREF, COLOR_TABLE_SIZE> consoleTable;
gsl::span<COLORREF> terminalTableView = { &terminalTable[0], terminalTable.size() };
gsl::span<COLORREF> 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() void UtilsTests::TestGuidToString()
{ {