From 62c95b5017e92a780cdc43008e30b4e43d2edc9b Mon Sep 17 00:00:00 2001 From: James Holderness Date: Thu, 13 Jan 2022 21:10:09 +0000 Subject: [PATCH] Move the common render settings into a shared class (#12127) ## Summary of the Pull Request This PR moves the color table and related render settings, which are common to both conhost and Windows Terminal, into a shared class that can be accessed directly from the renderer. This avoids the overhead of having to look up these properties via the `IRenderData` interface, which relies on inefficient virtual function calls. This also introduces the concept of color aliases, which determine the position in the color table that colors like the default foreground and background are stored. This allows the option of mapping them to one of the standard 16 colors, or to have their own separate table entries. ## References This is a continuation of the color table refactoring started in #11602 and #11784. The color alias functionality is a prerequisite for supporting a default bold color as proposed in #11939. The color aliases could also be a way for us to replace the PowerShell color quirk for #6807. ## PR Checklist * [x] Closes #12002 * [x] CLA signed. * [ ] Tests added/passed * [ ] Documentation updated. * [ ] Schema updated. * [ ] I've discussed this with core contributors already. If not checked, I'm ready to accept this work might be rejected in favor of a different grand plan. Issue number where discussion took place: #xxx ## Detailed Description of the Pull Request / Additional comments In addition to the color table, this new `RenderSettings` class manages the blinking state, the code for adjusting indistinguishable colors, and various boolean properties used in the color calculations. These boolean properties are now stored in a `til::enumset` so they can all be managed through a single `SetRenderMode` API, and easily extended with additional modes that we're likely to need in the future. In Windows Terminal we have an instance of `RenderSettings` stored in the `Terminal` class, and in conhost it's stored in the `Settings` class. In both cases, a reference to this class is passed to the `Renderer` constructor, so it now has direct access to that data. The renderer can then pass that reference to the render engines where it's needed in the `UpdateDrawingBrushes` method. This means the renderer no longer needs the `IRenderData` interface to access the `GetAttributeColors`, `GetCursorColor`, or `IsScreenReversed` methods, so those have now been removed. We still need access to `GetAttributeColors` in certain accessibility code, though, so I've kept that method in the `IUIAData` interface, but the implementation just forwards to the `RenderSettings` class. The implementation of the `RenderSettings::GetAttributeColors` method is loosely based on the original `Terminal` code, only the `CalculateRgbColors` call has now been incorporated directly into the code. This let us deduplicate some bits that were previously repeated in the section for adjusting indistinguishable colors. The last steps, where we calculate the alpha components, have now been split in to a separate `GetAttributeColorsWithAlpha` method, since that's typically not needed. ## Validation Steps Performed There were quite a lot changes needed in the unit tests, but they're mostly straightforward replacements of one method call with another. In the `TextAttributeTests`, where we were previously testing the `CalculateRgbColors` method, we're now running those tests though `RenderSettings::GetAttributeColors`, which incorporates the same functionality. The only complication is when testing the `IntenseIsBright` option, that needs to be set with an additional `SetRenderMode` call where previously it was just a parameter on `CalculateRgbColors`. In the `ScreenBufferTests` and `TextBufferTests`, calls to `LookupAttributeColors` have again been replaced by the `RenderSettings::GetAttributeColors` method, which serves the same purpose, and calls to `IsScreenReversed` have been replaced with an appropriate `GetRenderMode` call. In the `VtRendererTests`, all the calls to `UpdateDrawingBrushes` now just need to be passed a reference to a `RenderSettings` instance. --- src/buffer/out/TextAttribute.cpp | 35 --- src/buffer/out/TextAttribute.hpp | 7 - src/buffer/out/TextColor.h | 7 + .../out/ut_textbuffer/TextAttributeTests.cpp | 136 +++++---- .../TextBuffer.Unit.Tests.vcxproj | 3 + .../PublicTerminalCore/HwndTerminal.cpp | 3 +- src/cascadia/TerminalControl/ControlCore.cpp | 11 +- .../TerminalControl/IControlAppearance.idl | 3 +- src/cascadia/TerminalCore/ICoreAppearance.idl | 1 + src/cascadia/TerminalCore/ITerminalApi.hpp | 4 +- src/cascadia/TerminalCore/Terminal.cpp | 139 ++++----- src/cascadia/TerminalCore/Terminal.hpp | 28 +- src/cascadia/TerminalCore/TerminalApi.cpp | 23 +- .../TerminalCore/TerminalDispatch.cpp | 5 +- .../TerminalCore/TerminalSelection.cpp | 4 +- .../TerminalCore/terminalcore-common.vcxitems | 2 - .../TerminalCore/terminalrenderdata.cpp | 107 +------ .../TerminalSettingsModel/TerminalSettings.h | 2 +- .../ConptyRoundtripTests.cpp | 2 +- src/cascadia/inc/ControlProperties.h | 2 +- src/host/CursorBlinker.cpp | 9 +- src/host/consoleInformation.cpp | 30 -- src/host/getset.cpp | 29 -- src/host/getset.h | 1 - src/host/outputStream.cpp | 54 ++-- src/host/outputStream.hpp | 3 +- src/host/registry.cpp | 48 ++- src/host/renderData.cpp | 33 +- src/host/renderData.hpp | 5 +- src/host/server.h | 5 - src/host/settings.cpp | 88 ++---- src/host/settings.hpp | 34 +-- src/host/srvinit.cpp | 2 +- src/host/telemetry.cpp | 5 +- src/host/ut_host/ConptyOutputTests.cpp | 2 +- src/host/ut_host/ScreenBufferTests.cpp | 86 +++--- src/host/ut_host/TextBufferTests.cpp | 111 ++++--- src/host/ut_host/VtIoTests.cpp | 14 +- src/host/ut_host/VtRendererTests.cpp | 54 +++- src/interactivity/onecore/BgfxEngine.cpp | 1 + src/interactivity/onecore/BgfxEngine.hpp | 1 + src/interactivity/win32/Clipboard.cpp | 7 +- src/propslib/RegistrySerialization.cpp | 13 +- src/renderer/atlas/AtlasEngine.api.cpp | 4 - src/renderer/atlas/AtlasEngine.cpp | 4 +- src/renderer/atlas/AtlasEngine.h | 3 +- src/renderer/base/BlinkingState.cpp | 81 ----- src/renderer/base/RenderSettings.cpp | 289 ++++++++++++++++++ src/renderer/base/lib/base.vcxproj | 4 +- src/renderer/base/lib/base.vcxproj.filters | 8 +- src/renderer/base/renderer.cpp | 12 +- src/renderer/base/renderer.hpp | 5 +- src/renderer/base/sources.inc | 2 +- src/renderer/dx/DxRenderer.cpp | 20 +- src/renderer/dx/DxRenderer.hpp | 3 +- src/renderer/gdi/gdirenderer.hpp | 1 + src/renderer/gdi/state.cpp | 6 +- src/renderer/inc/BlinkingState.hpp | 37 --- src/renderer/inc/IRenderData.hpp | 3 - src/renderer/inc/IRenderEngine.hpp | 4 +- src/renderer/inc/RenderSettings.hpp | 55 ++++ src/renderer/uia/UiaRenderer.cpp | 2 + src/renderer/uia/UiaRenderer.hpp | 2 +- src/renderer/vt/Xterm256Engine.cpp | 2 + src/renderer/vt/Xterm256Engine.hpp | 1 + src/renderer/vt/XtermEngine.cpp | 2 + src/renderer/vt/XtermEngine.hpp | 1 + src/renderer/wddmcon/WddmConRenderer.cpp | 1 + src/renderer/wddmcon/WddmConRenderer.hpp | 1 + src/terminal/adapter/adaptDispatch.cpp | 51 +--- src/terminal/adapter/conGetSet.hpp | 6 +- .../adapter/ut_adapter/adapterTest.cpp | 17 +- .../TerminalCore => types}/ColorFix.cpp | 21 +- src/types/IBaseData.h | 1 - src/types/IUiaData.h | 1 + .../TerminalCore => types/inc}/ColorFix.hpp | 8 +- src/types/lib/types.vcxproj | 2 + src/types/lib/types.vcxproj.filters | 6 + src/types/sources.inc | 1 + 79 files changed, 902 insertions(+), 924 deletions(-) delete mode 100644 src/renderer/base/BlinkingState.cpp create mode 100644 src/renderer/base/RenderSettings.cpp delete mode 100644 src/renderer/inc/BlinkingState.hpp create mode 100644 src/renderer/inc/RenderSettings.hpp rename src/{cascadia/TerminalCore => types}/ColorFix.cpp (91%) rename src/{cascadia/TerminalCore => types/inc}/ColorFix.hpp (75%) diff --git a/src/buffer/out/TextAttribute.cpp b/src/buffer/out/TextAttribute.cpp index cefc7b6bc0a..e626db89f3b 100644 --- a/src/buffer/out/TextAttribute.cpp +++ b/src/buffer/out/TextAttribute.cpp @@ -124,41 +124,6 @@ bool TextAttribute::IsLegacy() const noexcept return _foreground.IsLegacy() && _background.IsLegacy(); } -// Routine Description: -// - Calculates rgb colors based off of current color table and active modification attributes. -// Arguments: -// - colorTable: the current color table rgb values. -// - defaultFgIndex: the color table index of the default foreground color. -// - defaultBgIndex: the color table index of the default background color. -// - reverseScreenMode: true if the screen mode is reversed. -// - blinkingIsFaint: true if blinking should be interpreted as faint. (defaults to false) -// - boldIsBright: true if "bold" should be interpreted as bright. (defaults to true) -// Return Value: -// - the foreground and background colors that should be displayed. -std::pair TextAttribute::CalculateRgbColors(const std::array& colorTable, - const size_t defaultFgIndex, - const size_t defaultBgIndex, - const bool reverseScreenMode, - const bool blinkingIsFaint, - const bool boldIsBright) const noexcept -{ - auto fg = _foreground.GetColor(colorTable, defaultFgIndex, boldIsBright && IsBold()); - auto bg = _background.GetColor(colorTable, defaultBgIndex); - if (IsFaint() || (IsBlinking() && blinkingIsFaint)) - { - fg = (fg >> 1) & 0x7F7F7F; // Divide foreground color components by two. - } - if (IsReverseVideo() ^ reverseScreenMode) - { - std::swap(fg, bg); - } - if (IsInvisible()) - { - fg = bg; - } - return { fg, bg }; -} - // Method description: // - Tells us whether the text is a hyperlink or not // Return value: diff --git a/src/buffer/out/TextAttribute.hpp b/src/buffer/out/TextAttribute.hpp index 54e143d1461..70b15073642 100644 --- a/src/buffer/out/TextAttribute.hpp +++ b/src/buffer/out/TextAttribute.hpp @@ -64,13 +64,6 @@ class TextAttribute final static TextAttribute StripErroneousVT16VersionsOfLegacyDefaults(const TextAttribute& attribute) noexcept; WORD GetLegacyAttributes() const noexcept; - std::pair CalculateRgbColors(const std::array& colorTable, - const size_t defaultFgIndex, - const size_t defaultBgIndex, - const bool reverseScreenMode = false, - const bool blinkingIsFaint = false, - const bool boldIsBright = true) const noexcept; - bool IsLeadingByte() const noexcept; bool IsTrailingByte() const noexcept; bool IsTopHorizontalDisplayed() const noexcept; diff --git a/src/buffer/out/TextColor.h b/src/buffer/out/TextColor.h index 75a8e7ae26c..c2b978eb6fe 100644 --- a/src/buffer/out/TextColor.h +++ b/src/buffer/out/TextColor.h @@ -45,6 +45,13 @@ enum class ColorType : BYTE IsRgb = 0x3 }; +enum class ColorAlias : size_t +{ + DefaultForeground, + DefaultBackground, + ENUM_COUNT // must be the last element in the enum class +}; + struct TextColor { public: diff --git a/src/buffer/out/ut_textbuffer/TextAttributeTests.cpp b/src/buffer/out/ut_textbuffer/TextAttributeTests.cpp index e5153618e64..ae39257a9f1 100644 --- a/src/buffer/out/ut_textbuffer/TextAttributeTests.cpp +++ b/src/buffer/out/ut_textbuffer/TextAttributeTests.cpp @@ -4,12 +4,14 @@ #include "precomp.h" #include "WexTestClass.h" #include "../../inc/consoletaeftemplates.hpp" +#include "../../../renderer/inc/RenderSettings.hpp" #include "../TextAttribute.hpp" using namespace WEX::Common; using namespace WEX::Logging; using namespace WEX::TestExecution; +using namespace Microsoft::Console::Render; class TextAttributeTests { @@ -24,7 +26,7 @@ class TextAttributeTests TEST_METHOD(TestRoundtripDefaultColors); TEST_METHOD(TestBoldAsBright); - std::array _colorTable; + RenderSettings _renderSettings; const COLORREF _defaultFg = RGB(1, 2, 3); const COLORREF _defaultBg = RGB(4, 5, 6); const size_t _defaultFgIndex = TextColor::DEFAULT_FOREGROUND; @@ -33,24 +35,8 @@ class TextAttributeTests bool TextAttributeTests::ClassSetup() { - _colorTable[0] = RGB(12, 12, 12); // Black - _colorTable[1] = RGB(0, 55, 218); // Dark Blue - _colorTable[2] = RGB(19, 161, 14); // Dark Green - _colorTable[3] = RGB(58, 150, 221); // Dark Cyan - _colorTable[4] = RGB(197, 15, 31); // Dark Red - _colorTable[5] = RGB(136, 23, 152); // Dark Magenta - _colorTable[6] = RGB(193, 156, 0); // Dark Yellow - _colorTable[7] = RGB(204, 204, 204); // Dark White - _colorTable[8] = RGB(118, 118, 118); // Bright Black - _colorTable[9] = RGB(59, 120, 255); // Bright Blue - _colorTable[10] = RGB(22, 198, 12); // Bright Green - _colorTable[11] = RGB(97, 214, 214); // Bright Cyan - _colorTable[12] = RGB(231, 72, 86); // Bright Red - _colorTable[13] = RGB(180, 0, 158); // Bright Magenta - _colorTable[14] = RGB(249, 241, 165); // Bright Yellow - _colorTable[15] = RGB(242, 242, 242); // White - _colorTable[_defaultFgIndex] = _defaultFg; - _colorTable[_defaultBgIndex] = _defaultBg; + _renderSettings.SetColorAlias(ColorAlias::DefaultForeground, _defaultFgIndex, _defaultFg); + _renderSettings.SetColorAlias(ColorAlias::DefaultBackground, _defaultBgIndex, _defaultBg); return true; } @@ -127,6 +113,7 @@ void TextAttributeTests::TestRoundtripExhaustive() void TextAttributeTests::TestTextAttributeColorGetters() { + const auto& colorTable = _renderSettings.GetColorTable(); const COLORREF red = RGB(255, 0, 0); const COLORREF faintRed = RGB(127, 0, 0); const COLORREF green = RGB(0, 255, 0); @@ -136,17 +123,17 @@ void TextAttributeTests::TestTextAttributeColorGetters() // values when reverse video is not set VERIFY_IS_FALSE(attr.IsReverseVideo()); - VERIFY_ARE_EQUAL(red, attr.GetForeground().GetColor(_colorTable, _defaultFgIndex)); - VERIFY_ARE_EQUAL(green, attr.GetBackground().GetColor(_colorTable, _defaultBgIndex)); - VERIFY_ARE_EQUAL(std::make_pair(red, green), attr.CalculateRgbColors(_colorTable, _defaultFgIndex, _defaultBgIndex)); + VERIFY_ARE_EQUAL(red, attr.GetForeground().GetColor(colorTable, _defaultFgIndex)); + VERIFY_ARE_EQUAL(green, attr.GetBackground().GetColor(colorTable, _defaultBgIndex)); + VERIFY_ARE_EQUAL(std::make_pair(red, green), _renderSettings.GetAttributeColors(attr)); // with reverse video set, calculated foreground/background values should be // switched while getters stay the same attr.SetReverseVideo(true); - VERIFY_ARE_EQUAL(red, attr.GetForeground().GetColor(_colorTable, _defaultFgIndex)); - VERIFY_ARE_EQUAL(green, attr.GetBackground().GetColor(_colorTable, _defaultBgIndex)); - VERIFY_ARE_EQUAL(std::make_pair(green, red), attr.CalculateRgbColors(_colorTable, _defaultFgIndex, _defaultBgIndex)); + VERIFY_ARE_EQUAL(red, attr.GetForeground().GetColor(colorTable, _defaultFgIndex)); + VERIFY_ARE_EQUAL(green, attr.GetBackground().GetColor(colorTable, _defaultBgIndex)); + VERIFY_ARE_EQUAL(std::make_pair(green, red), _renderSettings.GetAttributeColors(attr)); // reset the reverse video attr.SetReverseVideo(false); @@ -155,17 +142,17 @@ void TextAttributeTests::TestTextAttributeColorGetters() // while the background and getters stay the same attr.SetFaint(true); - VERIFY_ARE_EQUAL(red, attr.GetForeground().GetColor(_colorTable, _defaultFgIndex)); - VERIFY_ARE_EQUAL(green, attr.GetBackground().GetColor(_colorTable, _defaultBgIndex)); - VERIFY_ARE_EQUAL(std::make_pair(faintRed, green), attr.CalculateRgbColors(_colorTable, _defaultFgIndex, _defaultBgIndex)); + VERIFY_ARE_EQUAL(red, attr.GetForeground().GetColor(colorTable, _defaultFgIndex)); + VERIFY_ARE_EQUAL(green, attr.GetBackground().GetColor(colorTable, _defaultBgIndex)); + VERIFY_ARE_EQUAL(std::make_pair(faintRed, green), _renderSettings.GetAttributeColors(attr)); // with reverse video set, calculated foreground/background values should be // switched, and the background fainter, while getters stay the same attr.SetReverseVideo(true); - VERIFY_ARE_EQUAL(red, attr.GetForeground().GetColor(_colorTable, _defaultFgIndex)); - VERIFY_ARE_EQUAL(green, attr.GetBackground().GetColor(_colorTable, _defaultBgIndex)); - VERIFY_ARE_EQUAL(std::make_pair(green, faintRed), attr.CalculateRgbColors(_colorTable, _defaultFgIndex, _defaultBgIndex)); + VERIFY_ARE_EQUAL(red, attr.GetForeground().GetColor(colorTable, _defaultFgIndex)); + VERIFY_ARE_EQUAL(green, attr.GetBackground().GetColor(colorTable, _defaultBgIndex)); + VERIFY_ARE_EQUAL(std::make_pair(green, faintRed), _renderSettings.GetAttributeColors(attr)); // reset the reverse video and faint attributes attr.SetReverseVideo(false); @@ -175,21 +162,22 @@ void TextAttributeTests::TestTextAttributeColorGetters() // background, while getters stay the same attr.SetInvisible(true); - VERIFY_ARE_EQUAL(red, attr.GetForeground().GetColor(_colorTable, _defaultFgIndex)); - VERIFY_ARE_EQUAL(green, attr.GetBackground().GetColor(_colorTable, _defaultBgIndex)); - VERIFY_ARE_EQUAL(std::make_pair(green, green), attr.CalculateRgbColors(_colorTable, _defaultFgIndex, _defaultBgIndex)); + VERIFY_ARE_EQUAL(red, attr.GetForeground().GetColor(colorTable, _defaultFgIndex)); + VERIFY_ARE_EQUAL(green, attr.GetBackground().GetColor(colorTable, _defaultBgIndex)); + VERIFY_ARE_EQUAL(std::make_pair(green, green), _renderSettings.GetAttributeColors(attr)); // with reverse video set, the calculated background value should match // the foreground, while getters stay the same attr.SetReverseVideo(true); - VERIFY_ARE_EQUAL(red, attr.GetForeground().GetColor(_colorTable, _defaultFgIndex)); - VERIFY_ARE_EQUAL(green, attr.GetBackground().GetColor(_colorTable, _defaultBgIndex)); - VERIFY_ARE_EQUAL(std::make_pair(red, red), attr.CalculateRgbColors(_colorTable, _defaultFgIndex, _defaultBgIndex)); + VERIFY_ARE_EQUAL(red, attr.GetForeground().GetColor(colorTable, _defaultFgIndex)); + VERIFY_ARE_EQUAL(green, attr.GetBackground().GetColor(colorTable, _defaultBgIndex)); + VERIFY_ARE_EQUAL(std::make_pair(red, red), _renderSettings.GetAttributeColors(attr)); } void TextAttributeTests::TestReverseDefaultColors() { + const auto& colorTable = _renderSettings.GetColorTable(); const COLORREF red = RGB(255, 0, 0); const COLORREF green = RGB(0, 255, 0); TextAttribute attr{}; @@ -198,34 +186,34 @@ void TextAttributeTests::TestReverseDefaultColors() // values when reverse video is not set VERIFY_IS_FALSE(attr.IsReverseVideo()); - VERIFY_ARE_EQUAL(_defaultFg, attr.GetForeground().GetColor(_colorTable, _defaultFgIndex)); - VERIFY_ARE_EQUAL(_defaultBg, attr.GetBackground().GetColor(_colorTable, _defaultBgIndex)); - VERIFY_ARE_EQUAL(std::make_pair(_defaultFg, _defaultBg), attr.CalculateRgbColors(_colorTable, _defaultFgIndex, _defaultBgIndex)); + VERIFY_ARE_EQUAL(_defaultFg, attr.GetForeground().GetColor(colorTable, _defaultFgIndex)); + VERIFY_ARE_EQUAL(_defaultBg, attr.GetBackground().GetColor(colorTable, _defaultBgIndex)); + VERIFY_ARE_EQUAL(std::make_pair(_defaultFg, _defaultBg), _renderSettings.GetAttributeColors(attr)); // with reverse video set, calculated foreground/background values should be // switched while getters stay the same attr.SetReverseVideo(true); VERIFY_IS_TRUE(attr.IsReverseVideo()); - VERIFY_ARE_EQUAL(_defaultFg, attr.GetForeground().GetColor(_colorTable, _defaultFgIndex)); - VERIFY_ARE_EQUAL(_defaultBg, attr.GetBackground().GetColor(_colorTable, _defaultBgIndex)); - VERIFY_ARE_EQUAL(std::make_pair(_defaultBg, _defaultFg), attr.CalculateRgbColors(_colorTable, _defaultFgIndex, _defaultBgIndex)); + VERIFY_ARE_EQUAL(_defaultFg, attr.GetForeground().GetColor(colorTable, _defaultFgIndex)); + VERIFY_ARE_EQUAL(_defaultBg, attr.GetBackground().GetColor(colorTable, _defaultBgIndex)); + VERIFY_ARE_EQUAL(std::make_pair(_defaultBg, _defaultFg), _renderSettings.GetAttributeColors(attr)); attr.SetForeground(red); VERIFY_IS_TRUE(attr.IsReverseVideo()); - VERIFY_ARE_EQUAL(red, attr.GetForeground().GetColor(_colorTable, _defaultFgIndex)); - VERIFY_ARE_EQUAL(_defaultBg, attr.GetBackground().GetColor(_colorTable, _defaultBgIndex)); - VERIFY_ARE_EQUAL(std::make_pair(_defaultBg, red), attr.CalculateRgbColors(_colorTable, _defaultFgIndex, _defaultBgIndex)); + VERIFY_ARE_EQUAL(red, attr.GetForeground().GetColor(colorTable, _defaultFgIndex)); + VERIFY_ARE_EQUAL(_defaultBg, attr.GetBackground().GetColor(colorTable, _defaultBgIndex)); + VERIFY_ARE_EQUAL(std::make_pair(_defaultBg, red), _renderSettings.GetAttributeColors(attr)); attr.Invert(); VERIFY_IS_FALSE(attr.IsReverseVideo()); attr.SetDefaultForeground(); attr.SetBackground(green); - VERIFY_ARE_EQUAL(_defaultFg, attr.GetForeground().GetColor(_colorTable, _defaultFgIndex)); - VERIFY_ARE_EQUAL(green, attr.GetBackground().GetColor(_colorTable, _defaultBgIndex)); - VERIFY_ARE_EQUAL(std::make_pair(_defaultFg, green), attr.CalculateRgbColors(_colorTable, _defaultFgIndex, _defaultBgIndex)); + VERIFY_ARE_EQUAL(_defaultFg, attr.GetForeground().GetColor(colorTable, _defaultFgIndex)); + VERIFY_ARE_EQUAL(green, attr.GetBackground().GetColor(colorTable, _defaultBgIndex)); + VERIFY_ARE_EQUAL(std::make_pair(_defaultFg, green), _renderSettings.GetAttributeColors(attr)); } void TextAttributeTests::TestRoundtripDefaultColors() @@ -271,9 +259,10 @@ void TextAttributeTests::TestRoundtripDefaultColors() void TextAttributeTests::TestBoldAsBright() { - const COLORREF darkBlack = til::at(_colorTable, 0); - const COLORREF brightBlack = til::at(_colorTable, 8); - const COLORREF darkGreen = til::at(_colorTable, 2); + const auto& colorTable = _renderSettings.GetColorTable(); + const COLORREF darkBlack = til::at(colorTable, 0); + const COLORREF brightBlack = til::at(colorTable, 8); + const COLORREF darkGreen = til::at(colorTable, 2); TextAttribute attr{}; @@ -281,43 +270,58 @@ void TextAttributeTests::TestBoldAsBright() // values when not bold VERIFY_IS_FALSE(attr.IsBold()); - VERIFY_ARE_EQUAL(_defaultFg, attr.GetForeground().GetColor(_colorTable, _defaultFgIndex)); - VERIFY_ARE_EQUAL(_defaultBg, attr.GetBackground().GetColor(_colorTable, _defaultBgIndex)); - VERIFY_ARE_EQUAL(std::make_pair(_defaultFg, _defaultBg), attr.CalculateRgbColors(_colorTable, _defaultFgIndex, _defaultBgIndex, false, false, true)); - VERIFY_ARE_EQUAL(std::make_pair(_defaultFg, _defaultBg), attr.CalculateRgbColors(_colorTable, _defaultFgIndex, _defaultBgIndex, false, false, false)); + VERIFY_ARE_EQUAL(_defaultFg, attr.GetForeground().GetColor(colorTable, _defaultFgIndex)); + VERIFY_ARE_EQUAL(_defaultBg, attr.GetBackground().GetColor(colorTable, _defaultBgIndex)); + _renderSettings.SetRenderMode(RenderSettings::Mode::IntenseIsBright, true); + VERIFY_ARE_EQUAL(std::make_pair(_defaultFg, _defaultBg), _renderSettings.GetAttributeColors(attr)); + _renderSettings.SetRenderMode(RenderSettings::Mode::IntenseIsBright, false); + VERIFY_ARE_EQUAL(std::make_pair(_defaultFg, _defaultBg), _renderSettings.GetAttributeColors(attr)); // with bold set, calculated foreground/background values shouldn't change for the default colors. attr.SetBold(true); VERIFY_IS_TRUE(attr.IsBold()); - VERIFY_ARE_EQUAL(std::make_pair(_defaultFg, _defaultBg), attr.CalculateRgbColors(_colorTable, _defaultFgIndex, _defaultBgIndex, false, false, true)); - VERIFY_ARE_EQUAL(std::make_pair(_defaultFg, _defaultBg), attr.CalculateRgbColors(_colorTable, _defaultFgIndex, _defaultBgIndex, false, false, false)); + _renderSettings.SetRenderMode(RenderSettings::Mode::IntenseIsBright, true); + VERIFY_ARE_EQUAL(std::make_pair(_defaultFg, _defaultBg), _renderSettings.GetAttributeColors(attr)); + _renderSettings.SetRenderMode(RenderSettings::Mode::IntenseIsBright, false); + VERIFY_ARE_EQUAL(std::make_pair(_defaultFg, _defaultBg), _renderSettings.GetAttributeColors(attr)); attr.SetIndexedForeground(TextColor::DARK_BLACK); VERIFY_IS_TRUE(attr.IsBold()); Log::Comment(L"Foreground should be bright black when bold is bright is enabled"); - VERIFY_ARE_EQUAL(std::make_pair(brightBlack, _defaultBg), attr.CalculateRgbColors(_colorTable, _defaultFgIndex, _defaultBgIndex, false, false, true)); + _renderSettings.SetRenderMode(RenderSettings::Mode::IntenseIsBright, true); + VERIFY_ARE_EQUAL(std::make_pair(brightBlack, _defaultBg), _renderSettings.GetAttributeColors(attr)); 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, _defaultFgIndex, _defaultBgIndex, false, false, false)); + _renderSettings.SetRenderMode(RenderSettings::Mode::IntenseIsBright, false); + VERIFY_ARE_EQUAL(std::make_pair(darkBlack, _defaultBg), _renderSettings.GetAttributeColors(attr)); attr.SetIndexedBackground(TextColor::DARK_GREEN); VERIFY_IS_TRUE(attr.IsBold()); Log::Comment(L"background should be unaffected by 'bold is bright'"); - VERIFY_ARE_EQUAL(std::make_pair(brightBlack, darkGreen), attr.CalculateRgbColors(_colorTable, _defaultFgIndex, _defaultBgIndex, false, false, true)); - VERIFY_ARE_EQUAL(std::make_pair(darkBlack, darkGreen), attr.CalculateRgbColors(_colorTable, _defaultFgIndex, _defaultBgIndex, false, false, false)); + _renderSettings.SetRenderMode(RenderSettings::Mode::IntenseIsBright, true); + VERIFY_ARE_EQUAL(std::make_pair(brightBlack, darkGreen), _renderSettings.GetAttributeColors(attr)); + _renderSettings.SetRenderMode(RenderSettings::Mode::IntenseIsBright, false); + VERIFY_ARE_EQUAL(std::make_pair(darkBlack, darkGreen), _renderSettings.GetAttributeColors(attr)); attr.SetBold(false); VERIFY_IS_FALSE(attr.IsBold()); Log::Comment(L"when not bold, 'bold is bright' changes nothing"); - VERIFY_ARE_EQUAL(std::make_pair(darkBlack, darkGreen), attr.CalculateRgbColors(_colorTable, _defaultFgIndex, _defaultBgIndex, false, false, true)); - VERIFY_ARE_EQUAL(std::make_pair(darkBlack, darkGreen), attr.CalculateRgbColors(_colorTable, _defaultFgIndex, _defaultBgIndex, false, false, false)); + _renderSettings.SetRenderMode(RenderSettings::Mode::IntenseIsBright, true); + VERIFY_ARE_EQUAL(std::make_pair(darkBlack, darkGreen), _renderSettings.GetAttributeColors(attr)); + _renderSettings.SetRenderMode(RenderSettings::Mode::IntenseIsBright, false); + VERIFY_ARE_EQUAL(std::make_pair(darkBlack, darkGreen), _renderSettings.GetAttributeColors(attr)); Log::Comment(L"When set to a bright color, and bold, 'bold is bright' changes nothing"); attr.SetBold(true); attr.SetIndexedForeground(TextColor::BRIGHT_BLACK); VERIFY_IS_TRUE(attr.IsBold()); - VERIFY_ARE_EQUAL(std::make_pair(brightBlack, darkGreen), attr.CalculateRgbColors(_colorTable, _defaultFgIndex, _defaultBgIndex, false, false, true)); - VERIFY_ARE_EQUAL(std::make_pair(brightBlack, darkGreen), attr.CalculateRgbColors(_colorTable, _defaultFgIndex, _defaultBgIndex, false, false, false)); + _renderSettings.SetRenderMode(RenderSettings::Mode::IntenseIsBright, true); + VERIFY_ARE_EQUAL(std::make_pair(brightBlack, darkGreen), _renderSettings.GetAttributeColors(attr)); + _renderSettings.SetRenderMode(RenderSettings::Mode::IntenseIsBright, false); + VERIFY_ARE_EQUAL(std::make_pair(brightBlack, darkGreen), _renderSettings.GetAttributeColors(attr)); + + // Restore the default IntenseIsBright mode. + _renderSettings.SetRenderMode(RenderSettings::Mode::IntenseIsBright, true); } diff --git a/src/buffer/out/ut_textbuffer/TextBuffer.Unit.Tests.vcxproj b/src/buffer/out/ut_textbuffer/TextBuffer.Unit.Tests.vcxproj index 631466ee300..dab7c2bf390 100644 --- a/src/buffer/out/ut_textbuffer/TextBuffer.Unit.Tests.vcxproj +++ b/src/buffer/out/ut_textbuffer/TextBuffer.Unit.Tests.vcxproj @@ -19,6 +19,9 @@ + + {af0a096a-8b3a-4949-81ef-7df8f0fee91f} + {18d09a24-8240-42d6-8cb6-236eee820263} diff --git a/src/cascadia/PublicTerminalCore/HwndTerminal.cpp b/src/cascadia/PublicTerminalCore/HwndTerminal.cpp index 72422675694..1f188b21037 100644 --- a/src/cascadia/PublicTerminalCore/HwndTerminal.cpp +++ b/src/cascadia/PublicTerminalCore/HwndTerminal.cpp @@ -214,7 +214,8 @@ HRESULT HwndTerminal::Initialize() _terminal = std::make_unique<::Microsoft::Terminal::Core::Terminal>(); auto renderThread = std::make_unique<::Microsoft::Console::Render::RenderThread>(); auto* const localPointerToThread = renderThread.get(); - _renderer = std::make_unique<::Microsoft::Console::Render::Renderer>(_terminal.get(), nullptr, 0, std::move(renderThread)); + const auto& renderSettings = _terminal->GetRenderSettings(); + _renderer = std::make_unique<::Microsoft::Console::Render::Renderer>(renderSettings, _terminal.get(), nullptr, 0, std::move(renderThread)); RETURN_HR_IF_NULL(E_POINTER, localPointerToThread); RETURN_IF_FAILED(localPointerToThread->Initialize(_renderer.get())); diff --git a/src/cascadia/TerminalControl/ControlCore.cpp b/src/cascadia/TerminalControl/ControlCore.cpp index 0e5f2916f09..f8e0d436830 100644 --- a/src/cascadia/TerminalControl/ControlCore.cpp +++ b/src/cascadia/TerminalControl/ControlCore.cpp @@ -122,7 +122,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation auto* const localPointerToThread = renderThread.get(); // Now create the renderer and initialize the render thread. - _renderer = std::make_unique<::Microsoft::Console::Render::Renderer>(_terminal.get(), nullptr, 0, std::move(renderThread)); + const auto& renderSettings = _terminal->GetRenderSettings(); + _renderer = std::make_unique<::Microsoft::Console::Render::Renderer>(renderSettings, _terminal.get(), nullptr, 0, std::move(renderThread)); _renderer->SetRendererEnteredErrorStateCallback([weakThis = get_weak()]() { if (auto strongThis{ weakThis.get() }) @@ -281,7 +282,6 @@ namespace winrt::Microsoft::Terminal::Control::implementation _renderEngine->SetPixelShaderPath(_settings->PixelShaderPath()); _renderEngine->SetForceFullRepaintRendering(_settings->ForceFullRepaintRendering()); _renderEngine->SetSoftwareRendering(_settings->SoftwareRendering()); - _renderEngine->SetIntenseIsBold(_settings->IntenseIsBold()); _updateAntiAliasingMode(); @@ -677,7 +677,6 @@ namespace winrt::Microsoft::Terminal::Control::implementation _renderEngine->SetSelectionBackground(til::color{ newAppearance->SelectionBackground() }); _renderEngine->SetRetroTerminalEffect(newAppearance->RetroTerminalEffect()); _renderEngine->SetPixelShaderPath(newAppearance->PixelShaderPath()); - _renderEngine->SetIntenseIsBold(_settings->IntenseIsBold()); _renderer->TriggerRedrawAll(); } } @@ -1109,7 +1108,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation til::color ControlCore::BackgroundColor() const { - return _terminal->GetColorTableEntry(TextColor::DEFAULT_BACKGROUND); + return _terminal->GetRenderSettings().GetColorAlias(ColorAlias::DefaultBackground); } // Method Description: @@ -1395,8 +1394,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation auto lock = _terminal->LockForWriting(); auto& renderTarget = *_renderer; - auto& blinkingState = _terminal->GetBlinkingState(); - blinkingState.ToggleBlinkingRendition(renderTarget); + auto& renderSettings = _terminal->GetRenderSettings(); + renderSettings.ToggleBlinkRendition(renderTarget); } void ControlCore::BlinkCursor() diff --git a/src/cascadia/TerminalControl/IControlAppearance.idl b/src/cascadia/TerminalControl/IControlAppearance.idl index 15269cccf2e..96c3db75a11 100644 --- a/src/cascadia/TerminalControl/IControlAppearance.idl +++ b/src/cascadia/TerminalControl/IControlAppearance.idl @@ -11,8 +11,7 @@ namespace Microsoft.Terminal.Control Windows.UI.Xaml.Media.Stretch BackgroundImageStretchMode { get; }; Windows.UI.Xaml.HorizontalAlignment BackgroundImageHorizontalAlignment { get; }; Windows.UI.Xaml.VerticalAlignment BackgroundImageVerticalAlignment { get; }; - Boolean IntenseIsBold { get; }; - // IntenseIsBright is in Core Appearance + // IntenseIsBold and IntenseIsBright are in Core Appearance Double Opacity { get; }; // Experimental settings diff --git a/src/cascadia/TerminalCore/ICoreAppearance.idl b/src/cascadia/TerminalCore/ICoreAppearance.idl index 30813644f07..131410be780 100644 --- a/src/cascadia/TerminalCore/ICoreAppearance.idl +++ b/src/cascadia/TerminalCore/ICoreAppearance.idl @@ -97,6 +97,7 @@ namespace Microsoft.Terminal.Core Microsoft.Terminal.Core.Color CursorColor; CursorStyle CursorShape; UInt32 CursorHeight; + Boolean IntenseIsBold; Boolean IntenseIsBright; Boolean AdjustIndistinguishableColors; }; diff --git a/src/cascadia/TerminalCore/ITerminalApi.hpp b/src/cascadia/TerminalCore/ITerminalApi.hpp index f8943c5cb5a..4e463c16664 100644 --- a/src/cascadia/TerminalCore/ITerminalApi.hpp +++ b/src/cascadia/TerminalCore/ITerminalApi.hpp @@ -5,6 +5,7 @@ #include "../../terminal/adapter/DispatchTypes.hpp" #include "../../terminal/input/terminalInput.hpp" #include "../../buffer/out/TextAttribute.hpp" +#include "../../renderer/inc/RenderSettings.hpp" #include "../../types/inc/Viewport.hpp" namespace Microsoft::Terminal::Core @@ -42,12 +43,13 @@ namespace Microsoft::Terminal::Core virtual COLORREF GetColorTableEntry(const size_t tableIndex) const noexcept = 0; virtual bool SetColorTableEntry(const size_t tableIndex, const COLORREF color) noexcept = 0; + virtual void SetColorAliasIndex(const ColorAlias alias, const size_t tableIndex) noexcept = 0; virtual bool SetCursorStyle(const ::Microsoft::Console::VirtualTerminal::DispatchTypes::CursorStyle cursorStyle) noexcept = 0; virtual bool SetInputMode(const ::Microsoft::Console::VirtualTerminal::TerminalInput::Mode mode, const bool enabled) noexcept = 0; + virtual bool SetRenderMode(const ::Microsoft::Console::Render::RenderSettings::Mode mode, const bool enabled) noexcept = 0; - virtual bool SetScreenMode(const bool reverseMode) noexcept = 0; virtual bool EnableXtermBracketedPasteMode(const bool enabled) noexcept = 0; virtual bool IsXtermBracketedPasteModeEnabled() const = 0; diff --git a/src/cascadia/TerminalCore/Terminal.cpp b/src/cascadia/TerminalCore/Terminal.cpp index 4c9d38227b2..bcb6fa07b3f 100644 --- a/src/cascadia/TerminalCore/Terminal.cpp +++ b/src/cascadia/TerminalCore/Terminal.cpp @@ -39,8 +39,6 @@ static std::wstring _KeyEventsToText(std::deque>& i Terminal::Terminal() : _mutableViewport{ Viewport::Empty() }, _title{}, - _colorTable{}, - _screenReversed{ false }, _pfnWriteInput{ nullptr }, _scrollOffset{ 0 }, _snapOnInput{ true }, @@ -49,9 +47,7 @@ Terminal::Terminal() : _selection{ std::nullopt }, _taskbarState{ 0 }, _taskbarProgress{ 0 }, - _trimBlockSelection{ false }, - _intenseIsBright{ true }, - _adjustIndistinguishableColors{ true } + _trimBlockSelection{ false } { auto dispatch = std::make_unique(*this); auto engine = std::make_unique(std::move(dispatch)); @@ -77,11 +73,8 @@ Terminal::Terminal() : _terminalInput = std::make_unique(passAlongInput); - _InitializeColorTable(); - - _colorTable.at(TextColor::DEFAULT_FOREGROUND) = RGB(255, 255, 255); - _colorTable.at(TextColor::DEFAULT_BACKGROUND) = RGB(0, 0, 0); - _colorTable.at(TextColor::CURSOR_COLOR) = INVALID_COLOR; + _renderSettings.SetColorAlias(ColorAlias::DefaultForeground, TextColor::DEFAULT_FOREGROUND, RGB(255, 255, 255)); + _renderSettings.SetColorAlias(ColorAlias::DefaultBackground, TextColor::DEFAULT_BACKGROUND, RGB(0, 0, 0)); } void Terminal::Create(COORD viewportSize, SHORT scrollbackLines, IRenderTarget& renderTarget) @@ -179,29 +172,22 @@ void Terminal::UpdateSettings(ICoreSettings settings) // - appearance: an ICoreAppearance with new settings values for us to use. void Terminal::UpdateAppearance(const ICoreAppearance& appearance) { - _intenseIsBright = appearance.IntenseIsBright(); - _adjustIndistinguishableColors = appearance.AdjustIndistinguishableColors(); + _renderSettings.SetRenderMode(RenderSettings::Mode::IntenseIsBold, appearance.IntenseIsBold()); + _renderSettings.SetRenderMode(RenderSettings::Mode::IntenseIsBright, appearance.IntenseIsBright()); + _renderSettings.SetRenderMode(RenderSettings::Mode::DistinguishableColors, appearance.AdjustIndistinguishableColors()); - // Set the default background as transparent to prevent the - // DX layer from overwriting the background image or acrylic effect const til::color newBackgroundColor{ appearance.DefaultBackground() }; - _colorTable.at(TextColor::DEFAULT_BACKGROUND) = newBackgroundColor; + _renderSettings.SetColorAlias(ColorAlias::DefaultBackground, TextColor::DEFAULT_BACKGROUND, newBackgroundColor); const til::color newForegroundColor{ appearance.DefaultForeground() }; - _colorTable.at(TextColor::DEFAULT_FOREGROUND) = newForegroundColor; + _renderSettings.SetColorAlias(ColorAlias::DefaultForeground, TextColor::DEFAULT_FOREGROUND, newForegroundColor); const til::color newCursorColor{ appearance.CursorColor() }; - _colorTable.at(TextColor::CURSOR_COLOR) = newCursorColor; - - _intenseIsBright = appearance.IntenseIsBright(); - _adjustIndistinguishableColors = appearance.AdjustIndistinguishableColors(); + _renderSettings.SetColorTableEntry(TextColor::CURSOR_COLOR, newCursorColor); for (int i = 0; i < 16; i++) { - _colorTable.at(i) = til::color{ appearance.GetColorTableEntry(i) }; - } - if (_adjustIndistinguishableColors) - { - _MakeAdjustedColorArray(); + _renderSettings.SetColorTableEntry(i, til::color{ appearance.GetColorTableEntry(i) }); } + _renderSettings.MakeAdjustedColorArray(); CursorType cursorShape = CursorType::VerticalBar; switch (appearance.CursorShape()) @@ -1219,15 +1205,6 @@ void Microsoft::Terminal::Core::Terminal::TaskbarProgressChangedCallback(std::fu _pfnTaskbarProgressChanged.swap(pfn); } -void Terminal::_InitializeColorTable() -try -{ - const gsl::span tableView = { _colorTable.data(), _colorTable.size() }; - // First set up the basic 256 colors - Utils::InitializeColorTable(tableView); -} -CATCH_LOG() - // Method Description: // - Sets the cursor to be currently on. On/Off is tracked independently of // cursor visibility (hidden/visible). On/off is controlled by the cursor @@ -1280,11 +1257,6 @@ const std::optional Terminal::GetTabColor() const noexcept return _startingTabColor.has_value() ? _startingTabColor : _tabColor; } -BlinkingState& Terminal::GetBlinkingState() const noexcept -{ - return _blinkingState; -} - // Method Description: // - Gets the internal taskbar state value // Return Value: @@ -1307,57 +1279,54 @@ Scheme Terminal::GetColorScheme() const noexcept { Scheme s; - s.Foreground = til::color{ _colorTable.at(TextColor::DEFAULT_FOREGROUND) }; - s.Background = til::color{ _colorTable.at(TextColor::DEFAULT_BACKGROUND) }; + s.Foreground = til::color{ _renderSettings.GetColorAlias(ColorAlias::DefaultForeground) }; + s.Background = til::color{ _renderSettings.GetColorAlias(ColorAlias::DefaultBackground) }; // SelectionBackground is stored in the ControlAppearance - s.CursorColor = til::color{ _colorTable.at(TextColor::CURSOR_COLOR) }; - - s.Black = til::color{ _colorTable[0] }; - s.Red = til::color{ _colorTable[1] }; - s.Green = til::color{ _colorTable[2] }; - s.Yellow = til::color{ _colorTable[3] }; - s.Blue = til::color{ _colorTable[4] }; - s.Purple = til::color{ _colorTable[5] }; - s.Cyan = til::color{ _colorTable[6] }; - s.White = til::color{ _colorTable[7] }; - s.BrightBlack = til::color{ _colorTable[8] }; - s.BrightRed = til::color{ _colorTable[9] }; - s.BrightGreen = til::color{ _colorTable[10] }; - s.BrightYellow = til::color{ _colorTable[11] }; - s.BrightBlue = til::color{ _colorTable[12] }; - s.BrightPurple = til::color{ _colorTable[13] }; - s.BrightCyan = til::color{ _colorTable[14] }; - s.BrightWhite = til::color{ _colorTable[15] }; + s.CursorColor = til::color{ _renderSettings.GetColorTableEntry(TextColor::CURSOR_COLOR) }; + + s.Black = til::color{ _renderSettings.GetColorTableEntry(TextColor::DARK_BLACK) }; + s.Red = til::color{ _renderSettings.GetColorTableEntry(TextColor::DARK_RED) }; + s.Green = til::color{ _renderSettings.GetColorTableEntry(TextColor::DARK_GREEN) }; + s.Yellow = til::color{ _renderSettings.GetColorTableEntry(TextColor::DARK_YELLOW) }; + s.Blue = til::color{ _renderSettings.GetColorTableEntry(TextColor::DARK_BLUE) }; + s.Purple = til::color{ _renderSettings.GetColorTableEntry(TextColor::DARK_MAGENTA) }; + s.Cyan = til::color{ _renderSettings.GetColorTableEntry(TextColor::DARK_CYAN) }; + s.White = til::color{ _renderSettings.GetColorTableEntry(TextColor::DARK_WHITE) }; + s.BrightBlack = til::color{ _renderSettings.GetColorTableEntry(TextColor::BRIGHT_BLACK) }; + s.BrightRed = til::color{ _renderSettings.GetColorTableEntry(TextColor::BRIGHT_RED) }; + s.BrightGreen = til::color{ _renderSettings.GetColorTableEntry(TextColor::BRIGHT_GREEN) }; + s.BrightYellow = til::color{ _renderSettings.GetColorTableEntry(TextColor::BRIGHT_YELLOW) }; + s.BrightBlue = til::color{ _renderSettings.GetColorTableEntry(TextColor::BRIGHT_BLUE) }; + s.BrightPurple = til::color{ _renderSettings.GetColorTableEntry(TextColor::BRIGHT_MAGENTA) }; + s.BrightCyan = til::color{ _renderSettings.GetColorTableEntry(TextColor::BRIGHT_CYAN) }; + s.BrightWhite = til::color{ _renderSettings.GetColorTableEntry(TextColor::BRIGHT_WHITE) }; return s; } void Terminal::ApplyScheme(const Scheme& colorScheme) { - _colorTable.at(TextColor::DEFAULT_FOREGROUND) = til::color{ colorScheme.Foreground }; - _colorTable.at(TextColor::DEFAULT_BACKGROUND) = til::color{ colorScheme.Background }; - - _colorTable[0] = til::color{ colorScheme.Black }; - _colorTable[1] = til::color{ colorScheme.Red }; - _colorTable[2] = til::color{ colorScheme.Green }; - _colorTable[3] = til::color{ colorScheme.Yellow }; - _colorTable[4] = til::color{ colorScheme.Blue }; - _colorTable[5] = til::color{ colorScheme.Purple }; - _colorTable[6] = til::color{ colorScheme.Cyan }; - _colorTable[7] = til::color{ colorScheme.White }; - _colorTable[8] = til::color{ colorScheme.BrightBlack }; - _colorTable[9] = til::color{ colorScheme.BrightRed }; - _colorTable[10] = til::color{ colorScheme.BrightGreen }; - _colorTable[11] = til::color{ colorScheme.BrightYellow }; - _colorTable[12] = til::color{ colorScheme.BrightBlue }; - _colorTable[13] = til::color{ colorScheme.BrightPurple }; - _colorTable[14] = til::color{ colorScheme.BrightCyan }; - _colorTable[15] = til::color{ colorScheme.BrightWhite }; - - _colorTable.at(TextColor::CURSOR_COLOR) = til::color{ colorScheme.CursorColor }; - - if (_adjustIndistinguishableColors) - { - _MakeAdjustedColorArray(); - } + _renderSettings.SetColorAlias(ColorAlias::DefaultForeground, TextColor::DEFAULT_FOREGROUND, til::color{ colorScheme.Foreground }); + _renderSettings.SetColorAlias(ColorAlias::DefaultBackground, TextColor::DEFAULT_BACKGROUND, til::color{ colorScheme.Background }); + + _renderSettings.SetColorTableEntry(TextColor::DARK_BLACK, til::color{ colorScheme.Black }); + _renderSettings.SetColorTableEntry(TextColor::DARK_RED, til::color{ colorScheme.Red }); + _renderSettings.SetColorTableEntry(TextColor::DARK_GREEN, til::color{ colorScheme.Green }); + _renderSettings.SetColorTableEntry(TextColor::DARK_YELLOW, til::color{ colorScheme.Yellow }); + _renderSettings.SetColorTableEntry(TextColor::DARK_BLUE, til::color{ colorScheme.Blue }); + _renderSettings.SetColorTableEntry(TextColor::DARK_MAGENTA, til::color{ colorScheme.Purple }); + _renderSettings.SetColorTableEntry(TextColor::DARK_CYAN, til::color{ colorScheme.Cyan }); + _renderSettings.SetColorTableEntry(TextColor::DARK_WHITE, til::color{ colorScheme.White }); + _renderSettings.SetColorTableEntry(TextColor::BRIGHT_BLACK, til::color{ colorScheme.BrightBlack }); + _renderSettings.SetColorTableEntry(TextColor::BRIGHT_RED, til::color{ colorScheme.BrightRed }); + _renderSettings.SetColorTableEntry(TextColor::BRIGHT_GREEN, til::color{ colorScheme.BrightGreen }); + _renderSettings.SetColorTableEntry(TextColor::BRIGHT_YELLOW, til::color{ colorScheme.BrightYellow }); + _renderSettings.SetColorTableEntry(TextColor::BRIGHT_BLUE, til::color{ colorScheme.BrightBlue }); + _renderSettings.SetColorTableEntry(TextColor::BRIGHT_MAGENTA, til::color{ colorScheme.BrightPurple }); + _renderSettings.SetColorTableEntry(TextColor::BRIGHT_CYAN, til::color{ colorScheme.BrightCyan }); + _renderSettings.SetColorTableEntry(TextColor::BRIGHT_WHITE, til::color{ colorScheme.BrightWhite }); + + _renderSettings.SetColorTableEntry(TextColor::CURSOR_COLOR, til::color{ colorScheme.CursorColor }); + + _renderSettings.MakeAdjustedColorArray(); } diff --git a/src/cascadia/TerminalCore/Terminal.hpp b/src/cascadia/TerminalCore/Terminal.hpp index 0429e295120..9fbc4700718 100644 --- a/src/cascadia/TerminalCore/Terminal.hpp +++ b/src/cascadia/TerminalCore/Terminal.hpp @@ -8,7 +8,7 @@ #include "../../inc/DefaultSettings.h" #include "../../buffer/out/textBuffer.hpp" #include "../../types/inc/sgrStack.hpp" -#include "../../renderer/inc/BlinkingState.hpp" +#include "../../renderer/inc/RenderSettings.hpp" #include "../../terminal/parser/StateMachine.hpp" #include "../../terminal/input/terminalInput.hpp" @@ -55,6 +55,8 @@ class Microsoft::Terminal::Core::Terminal final : public Microsoft::Console::Render::IRenderData, public Microsoft::Console::Types::IUiaData { + using RenderSettings = Microsoft::Console::Render::RenderSettings; + public: Terminal(); ~Terminal(){}; @@ -88,6 +90,9 @@ class Microsoft::Terminal::Core::Terminal final : int ViewStartIndex() const noexcept; int ViewEndIndex() const noexcept; + RenderSettings& GetRenderSettings() noexcept { return _renderSettings; }; + const RenderSettings& GetRenderSettings() const noexcept { return _renderSettings; }; + #pragma region ITerminalApi // These methods are defined in TerminalApi.cpp bool PrintString(std::wstring_view stringView) noexcept override; @@ -109,11 +114,12 @@ class Microsoft::Terminal::Core::Terminal final : bool SetWindowTitle(std::wstring_view title) noexcept override; COLORREF GetColorTableEntry(const size_t tableIndex) const noexcept override; bool SetColorTableEntry(const size_t tableIndex, const COLORREF color) noexcept override; + void SetColorAliasIndex(const ColorAlias alias, const size_t tableIndex) noexcept override; bool SetCursorStyle(const ::Microsoft::Console::VirtualTerminal::DispatchTypes::CursorStyle cursorStyle) noexcept override; bool SetInputMode(const ::Microsoft::Console::VirtualTerminal::TerminalInput::Mode mode, const bool enabled) noexcept override; + bool SetRenderMode(const ::Microsoft::Console::Render::RenderSettings::Mode mode, const bool enabled) noexcept override; - bool SetScreenMode(const bool reverseMode) noexcept override; bool EnableXtermBracketedPasteMode(const bool enabled) noexcept override; bool IsXtermBracketedPasteModeEnabled() const noexcept override; @@ -156,7 +162,6 @@ class Microsoft::Terminal::Core::Terminal final : COORD GetTextBufferEndPosition() const noexcept override; const TextBuffer& GetTextBuffer() noexcept override; const FontInfo& GetFontInfo() noexcept override; - std::pair GetAttributeColors(const TextAttribute& attr) const noexcept override; void LockConsole() noexcept override; void UnlockConsole() noexcept override; @@ -170,9 +175,7 @@ class Microsoft::Terminal::Core::Terminal final : ULONG GetCursorHeight() const noexcept override; ULONG GetCursorPixelWidth() const noexcept override; CursorType GetCursorStyle() const noexcept override; - COLORREF GetCursorColor() const noexcept override; bool IsCursorDoubleWidth() const override; - bool IsScreenReversed() const noexcept override; const std::vector GetOverlays() const noexcept override; const bool IsGridLineDrawingAllowed() noexcept override; const std::wstring GetHyperlinkUri(uint16_t id) const noexcept override; @@ -181,6 +184,7 @@ class Microsoft::Terminal::Core::Terminal final : #pragma endregion #pragma region IUiaData + std::pair GetAttributeColors(const TextAttribute& attr) const noexcept override; std::vector GetSelectionRects() noexcept override; const bool IsSelectionActive() const noexcept override; const bool IsBlockSelection() const noexcept override; @@ -214,8 +218,6 @@ class Microsoft::Terminal::Core::Terminal final : winrt::Microsoft::Terminal::Core::Scheme GetColorScheme() const noexcept; void ApplyScheme(const winrt::Microsoft::Terminal::Core::Scheme& scheme); - Microsoft::Console::Render::BlinkingState& GetBlinkingState() const noexcept; - const size_t GetTaskbarState() const noexcept; const size_t GetTaskbarProgress() const noexcept; @@ -272,6 +274,7 @@ class Microsoft::Terminal::Core::Terminal final : std::function)> _pfnTabColorChanged; std::function _pfnTaskbarProgressChanged; + RenderSettings _renderSettings; std::unique_ptr<::Microsoft::Console::VirtualTerminal::StateMachine> _stateMachine; std::unique_ptr<::Microsoft::Console::VirtualTerminal::TerminalInput> _terminalInput; @@ -280,19 +283,13 @@ class Microsoft::Terminal::Core::Terminal final : std::optional _tabColor; std::optional _startingTabColor; - // This is still stored as a COLORREF because it interacts with some code in ConTypes - std::array _colorTable; CursorType _defaultCursorShape; - bool _screenReversed; - mutable Microsoft::Console::Render::BlinkingState _blinkingState; bool _snapOnInput; bool _altGrAliasing; bool _suppressApplicationTitle; bool _bracketedPasteMode; bool _trimBlockSelection; - bool _intenseIsBright; - bool _adjustIndistinguishableColors; size_t _taskbarState; size_t _taskbarProgress; @@ -369,8 +366,6 @@ class Microsoft::Terminal::Core::Terminal final : Microsoft::Console::Types::Viewport _GetMutableViewport() const noexcept; Microsoft::Console::Types::Viewport _GetVisibleViewport() const noexcept; - void _InitializeColorTable(); - void _WriteBuffer(const std::wstring_view& stringView); void _AdjustCursorPosition(const COORD proposedPosition); @@ -393,9 +388,6 @@ class Microsoft::Terminal::Core::Terminal final : Microsoft::Console::VirtualTerminal::SgrStack _sgrStack; - void _MakeAdjustedColorArray(); - std::array, 18> _adjustedForegroundColors; - #ifdef UNIT_TESTING friend class TerminalCoreUnitTests::TerminalBufferTests; friend class TerminalCoreUnitTests::TerminalApiTest; diff --git a/src/cascadia/TerminalCore/TerminalApi.cpp b/src/cascadia/TerminalCore/TerminalApi.cpp index 52463987a38..e2e5eb35253 100644 --- a/src/cascadia/TerminalCore/TerminalApi.cpp +++ b/src/cascadia/TerminalCore/TerminalApi.cpp @@ -6,6 +6,7 @@ #include "../src/inc/unicode.hpp" using namespace Microsoft::Terminal::Core; +using namespace Microsoft::Console::Render; using namespace Microsoft::Console::Types; using namespace Microsoft::Console::VirtualTerminal; @@ -371,7 +372,7 @@ CATCH_RETURN_FALSE() COLORREF Terminal::GetColorTableEntry(const size_t tableIndex) const noexcept try { - return _colorTable.at(tableIndex); + return _renderSettings.GetColorTableEntry(tableIndex); } catch (...) { @@ -389,9 +390,9 @@ catch (...) bool Terminal::SetColorTableEntry(const size_t tableIndex, const COLORREF color) noexcept try { - _colorTable.at(tableIndex) = color; + _renderSettings.SetColorTableEntry(tableIndex, color); - if (tableIndex == TextColor::DEFAULT_BACKGROUND) + if (tableIndex == _renderSettings.GetColorAliasIndex(ColorAlias::DefaultBackground)) { _pfnBackgroundColorChanged(color); } @@ -402,6 +403,18 @@ try } CATCH_RETURN_FALSE() +// Method Description: +// - Sets the position in the color table for the given color alias. +// Arguments: +// - alias: the color alias to update. +// - tableIndex: the new position of the alias in the color table. +// Return Value: +// - +void Terminal::SetColorAliasIndex(const ColorAlias alias, const size_t tableIndex) noexcept +{ + _renderSettings.SetColorAliasIndex(alias, tableIndex); +} + // Method Description: // - Sets the cursor style to the given style. // Arguments: @@ -463,10 +476,10 @@ try } CATCH_RETURN_FALSE() -bool Terminal::SetScreenMode(const bool reverseMode) noexcept +bool Terminal::SetRenderMode(const RenderSettings::Mode mode, const bool enabled) noexcept try { - _screenReversed = reverseMode; + _renderSettings.SetRenderMode(mode, enabled); // Repaint everything - the colors will have changed _buffer->GetRenderTarget().TriggerRedrawAll(); diff --git a/src/cascadia/TerminalCore/TerminalDispatch.cpp b/src/cascadia/TerminalCore/TerminalDispatch.cpp index 215e495da19..0c3dae74a8a 100644 --- a/src/cascadia/TerminalCore/TerminalDispatch.cpp +++ b/src/cascadia/TerminalCore/TerminalDispatch.cpp @@ -7,6 +7,7 @@ using namespace Microsoft::Console; using namespace ::Microsoft::Terminal::Core; +using namespace ::Microsoft::Console::Render; using namespace ::Microsoft::Console::VirtualTerminal; // NOTE: @@ -247,6 +248,7 @@ CATCH_LOG_RETURN_FALSE() bool TerminalDispatch::SetDefaultForeground(const DWORD color) noexcept try { + _terminalApi.SetColorAliasIndex(ColorAlias::DefaultForeground, TextColor::DEFAULT_FOREGROUND); return _terminalApi.SetColorTableEntry(TextColor::DEFAULT_FOREGROUND, color); } CATCH_LOG_RETURN_FALSE() @@ -260,6 +262,7 @@ CATCH_LOG_RETURN_FALSE() bool TerminalDispatch::SetDefaultBackground(const DWORD color) noexcept try { + _terminalApi.SetColorAliasIndex(ColorAlias::DefaultBackground, TextColor::DEFAULT_BACKGROUND); return _terminalApi.SetColorTableEntry(TextColor::DEFAULT_BACKGROUND, color); } CATCH_LOG_RETURN_FALSE() @@ -347,7 +350,7 @@ bool TerminalDispatch::SetCursorKeysMode(const bool applicationMode) noexcept // - True if handled successfully. False otherwise. bool TerminalDispatch::SetScreenMode(const bool reverseMode) noexcept { - return _terminalApi.SetScreenMode(reverseMode); + return _terminalApi.SetRenderMode(RenderSettings::Mode::ScreenReversed, reverseMode); } // Method Description: diff --git a/src/cascadia/TerminalCore/TerminalSelection.cpp b/src/cascadia/TerminalCore/TerminalSelection.cpp index f45d18f821d..7b7fec12dba 100644 --- a/src/cascadia/TerminalCore/TerminalSelection.cpp +++ b/src/cascadia/TerminalCore/TerminalSelection.cpp @@ -478,7 +478,9 @@ const TextBuffer::TextAndColor Terminal::RetrieveSelectedTextFromBuffer(bool sin const auto selectionRects = _GetSelectionRects(); - const auto GetAttributeColors = std::bind(&Terminal::GetAttributeColors, this, std::placeholders::_1); + const auto GetAttributeColors = [&](const auto& attr) { + return _renderSettings.GetAttributeColors(attr); + }; // GH#6740: Block selection should preserve the visual structure: // - CRLFs need to be added - so the lines structure is preserved diff --git a/src/cascadia/TerminalCore/terminalcore-common.vcxitems b/src/cascadia/TerminalCore/terminalcore-common.vcxitems index f74187ac696..5b777af15c0 100644 --- a/src/cascadia/TerminalCore/terminalcore-common.vcxitems +++ b/src/cascadia/TerminalCore/terminalcore-common.vcxitems @@ -8,7 +8,6 @@ - Create @@ -20,7 +19,6 @@ - diff --git a/src/cascadia/TerminalCore/terminalrenderdata.cpp b/src/cascadia/TerminalCore/terminalrenderdata.cpp index 3e19898b1a4..a085a3b0548 100644 --- a/src/cascadia/TerminalCore/terminalrenderdata.cpp +++ b/src/cascadia/TerminalCore/terminalrenderdata.cpp @@ -3,16 +3,12 @@ #include "pch.h" #include "Terminal.hpp" -#include "ColorFix.hpp" #include using namespace Microsoft::Terminal::Core; using namespace Microsoft::Console::Types; using namespace Microsoft::Console::Render; -static constexpr size_t DefaultBgIndex{ 16 }; -static constexpr size_t DefaultFgIndex{ 17 }; - Viewport Terminal::GetViewport() noexcept { return _GetVisibleViewport(); @@ -42,59 +38,6 @@ void Terminal::SetFontInfo(const FontInfo& fontInfo) _fontInfo = fontInfo; } -std::pair Terminal::GetAttributeColors(const TextAttribute& attr) const noexcept -{ - std::pair colors; - _blinkingState.RecordBlinkingUsage(attr); - const auto fgTextColor = attr.GetForeground(); - const auto bgTextColor = attr.GetBackground(); - - // We want to nudge the foreground color to make it more perceivable only for the - // default color pairs within the color table - if (_adjustIndistinguishableColors && - !(attr.IsFaint() || (attr.IsBlinking() && _blinkingState.IsBlinkingFaint())) && - (fgTextColor.IsDefault() || fgTextColor.IsLegacy()) && - (bgTextColor.IsDefault() || bgTextColor.IsLegacy())) - { - const auto bgIndex = bgTextColor.IsDefault() ? DefaultBgIndex : bgTextColor.GetIndex(); - auto fgIndex = fgTextColor.IsDefault() ? DefaultFgIndex : fgTextColor.GetIndex(); - - if (fgTextColor.IsIndex16() && (fgIndex < 8) && attr.IsBold() && _intenseIsBright) - { - // There is a special case for bold here - we need to get the bright version of the foreground color - fgIndex += 8; - } - - if (attr.IsReverseVideo() ^ _screenReversed) - { - colors.first = _adjustedForegroundColors[fgIndex][bgIndex]; - colors.second = fgTextColor.GetColor(_colorTable, TextColor::DEFAULT_FOREGROUND); - } - else - { - colors.first = _adjustedForegroundColors[bgIndex][fgIndex]; - colors.second = bgTextColor.GetColor(_colorTable, TextColor::DEFAULT_BACKGROUND); - } - } - else - { - colors = attr.CalculateRgbColors(_colorTable, - TextColor::DEFAULT_FOREGROUND, - TextColor::DEFAULT_BACKGROUND, - _screenReversed, - _blinkingState.IsBlinkingFaint(), - _intenseIsBright); - } - colors.first |= 0xff000000; - // We only care about alpha for the default BG (which enables acrylic) - // If the bg isn't the default bg color, or reverse video is enabled, make it fully opaque. - if (!attr.BackgroundIsDefault() || (attr.IsReverseVideo() ^ _screenReversed)) - { - colors.second |= 0xff000000; - } - return colors; -} - COORD Terminal::GetCursorPosition() const noexcept { const auto& cursor = _buffer->GetCursor(); @@ -128,11 +71,6 @@ CursorType Terminal::GetCursorStyle() const noexcept return _buffer->GetCursor().GetType(); } -COLORREF Terminal::GetCursorColor() const noexcept -{ - return _colorTable.at(TextColor::CURSOR_COLOR); -} - bool Terminal::IsCursorDoubleWidth() const { const auto position = _buffer->GetCursor().GetPosition(); @@ -186,6 +124,11 @@ const std::vector Terminal::GetPatternId(const COORD location) const noe return {}; } +std::pair Terminal::GetAttributeColors(const TextAttribute& attr) const noexcept +{ + return _renderSettings.GetAttributeColors(attr); +} + std::vector Terminal::GetSelectionRects() noexcept try { @@ -278,15 +221,6 @@ void Terminal::UnlockConsole() noexcept _readWriteLock.unlock(); } -// Method Description: -// - Returns whether the screen is inverted; -// Return Value: -// - false. -bool Terminal::IsScreenReversed() const noexcept -{ - return _screenReversed; -} - const bool Terminal::IsUiaDataInitialized() const noexcept { // GH#11135: Windows Terminal needs to create and return an automation peer @@ -295,34 +229,3 @@ const bool Terminal::IsUiaDataInitialized() const noexcept // UiaData are not yet initialized. return !!_buffer; } - -// Method Description: -// - Creates the adjusted color array, which contains the possible foreground colors, -// adjusted for perceivability -// - The adjusted color array is 2-d, and effectively maps a background and foreground -// color pair to the adjusted foreground for that color pair -void Terminal::_MakeAdjustedColorArray() -{ - // The color table has 16 colors, but the adjusted color table needs to be 18 - // to include the default background and default foreground colors - std::array colorTableWithDefaults; - std::copy_n(std::begin(_colorTable), 16, std::begin(colorTableWithDefaults)); - colorTableWithDefaults[DefaultBgIndex] = _colorTable.at(TextColor::DEFAULT_BACKGROUND); - colorTableWithDefaults[DefaultFgIndex] = _colorTable.at(TextColor::DEFAULT_FOREGROUND); - for (auto fgIndex = 0; fgIndex < 18; ++fgIndex) - { - const auto fg = til::at(colorTableWithDefaults, fgIndex); - for (auto bgIndex = 0; bgIndex < 18; ++bgIndex) - { - if (fgIndex == bgIndex) - { - _adjustedForegroundColors[bgIndex][fgIndex] = fg; - } - else - { - const auto bg = til::at(colorTableWithDefaults, bgIndex); - _adjustedForegroundColors[bgIndex][fgIndex] = ColorFix::GetPerceivableColor(fg, bg); - } - } - } -} diff --git a/src/cascadia/TerminalSettingsModel/TerminalSettings.h b/src/cascadia/TerminalSettingsModel/TerminalSettings.h index 23ebb390b93..6409a2861fc 100644 --- a/src/cascadia/TerminalSettingsModel/TerminalSettings.h +++ b/src/cascadia/TerminalSettingsModel/TerminalSettings.h @@ -104,6 +104,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation // passed to the terminal only upon creation. INHERITABLE_SETTING(Model::TerminalSettings, Windows::Foundation::IReference, StartingTabColor, nullptr); + INHERITABLE_SETTING(Model::TerminalSettings, bool, IntenseIsBold); INHERITABLE_SETTING(Model::TerminalSettings, bool, IntenseIsBright); INHERITABLE_SETTING(Model::TerminalSettings, bool, AdjustIndistinguishableColors); @@ -150,7 +151,6 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation INHERITABLE_SETTING(Model::TerminalSettings, bool, ForceVTInput, false); INHERITABLE_SETTING(Model::TerminalSettings, hstring, PixelShaderPath); - INHERITABLE_SETTING(Model::TerminalSettings, bool, IntenseIsBold); INHERITABLE_SETTING(Model::TerminalSettings, bool, Elevate, false); diff --git a/src/cascadia/UnitTests_TerminalCore/ConptyRoundtripTests.cpp b/src/cascadia/UnitTests_TerminalCore/ConptyRoundtripTests.cpp index 4be7a402f9b..0a9bd6734b6 100644 --- a/src/cascadia/UnitTests_TerminalCore/ConptyRoundtripTests.cpp +++ b/src/cascadia/UnitTests_TerminalCore/ConptyRoundtripTests.cpp @@ -107,7 +107,7 @@ class TerminalCoreUnitTests::ConptyRoundtripTests final VERIFY_SUCCEEDED(currentBuffer.SetViewportOrigin(true, { 0, 0 }, true)); VERIFY_ARE_EQUAL(COORD({ 0, 0 }), currentBuffer.GetTextBuffer().GetCursor().GetPosition()); - g.pRender = new Renderer(&gci.renderData, nullptr, 0, nullptr); + g.pRender = new Renderer(gci.GetRenderSettings(), &gci.renderData, nullptr, 0, nullptr); // Set up an xterm-256 renderer for conpty wil::unique_hfile hFile = wil::unique_hfile(INVALID_HANDLE_VALUE); diff --git a/src/cascadia/inc/ControlProperties.h b/src/cascadia/inc/ControlProperties.h index d4aeb7fc825..8243177ce11 100644 --- a/src/cascadia/inc/ControlProperties.h +++ b/src/cascadia/inc/ControlProperties.h @@ -11,6 +11,7 @@ X(til::color, CursorColor, DEFAULT_CURSOR_COLOR) \ X(winrt::Microsoft::Terminal::Core::CursorStyle, CursorShape, winrt::Microsoft::Terminal::Core::CursorStyle::Vintage) \ X(uint32_t, CursorHeight, DEFAULT_CURSOR_HEIGHT) \ + X(bool, IntenseIsBold) \ X(bool, IntenseIsBright, true) \ X(bool, AdjustIndistinguishableColors, true) @@ -24,7 +25,6 @@ X(winrt::Windows::UI::Xaml::Media::Stretch, BackgroundImageStretchMode, winrt::Windows::UI::Xaml::Media::Stretch::UniformToFill) \ X(winrt::Windows::UI::Xaml::HorizontalAlignment, BackgroundImageHorizontalAlignment, winrt::Windows::UI::Xaml::HorizontalAlignment::Center) \ X(winrt::Windows::UI::Xaml::VerticalAlignment, BackgroundImageVerticalAlignment, winrt::Windows::UI::Xaml::VerticalAlignment::Center) \ - X(bool, IntenseIsBold) \ X(bool, RetroTerminalEffect, false) \ X(winrt::hstring, PixelShaderPath) diff --git a/src/host/CursorBlinker.cpp b/src/host/CursorBlinker.cpp index fae8eefc795..bab71cccbda 100644 --- a/src/host/CursorBlinker.cpp +++ b/src/host/CursorBlinker.cpp @@ -8,6 +8,7 @@ using namespace Microsoft::Console; using namespace Microsoft::Console::Interactivity; +using namespace Microsoft::Console::Render; CursorBlinker::CursorBlinker() : _hCaretBlinkTimer(INVALID_HANDLE_VALUE), @@ -32,8 +33,8 @@ void CursorBlinker::UpdateSystemMetrics() // If animations are disabled, or the blink rate is infinite, blinking is not allowed. BOOL animationsEnabled = TRUE; SystemParametersInfoW(SPI_GETCLIENTAREAANIMATION, 0, &animationsEnabled, 0); - auto& blinkingState = ServiceLocator::LocateGlobals().getConsoleInformation().GetBlinkingState(); - blinkingState.SetBlinkingAllowed(animationsEnabled && _uCaretBlinkTime != INFINITE); + auto& renderSettings = ServiceLocator::LocateGlobals().getConsoleInformation().GetRenderSettings(); + renderSettings.SetRenderMode(RenderSettings::Mode::BlinkAllowed, animationsEnabled && _uCaretBlinkTime != INFINITE); } void CursorBlinker::SettingsChanged() @@ -69,7 +70,7 @@ void CursorBlinker::TimerRoutine(SCREEN_INFORMATION& ScreenInfo) { auto& buffer = ScreenInfo.GetTextBuffer(); auto& cursor = buffer.GetCursor(); - const CONSOLE_INFORMATION& gci = ServiceLocator::LocateGlobals().getConsoleInformation(); + auto& gci = ServiceLocator::LocateGlobals().getConsoleInformation(); auto* const pAccessibilityNotifier = ServiceLocator::LocateAccessibilityNotifier(); if (!WI_IsFlagSet(gci.Flags, CONSOLE_HAS_FOCUS)) @@ -139,7 +140,7 @@ void CursorBlinker::TimerRoutine(SCREEN_INFORMATION& ScreenInfo) } DoBlinkingRenditionAndScroll: - gci.GetBlinkingState().ToggleBlinkingRendition(ScreenInfo.GetRenderTarget()); + gci.GetRenderSettings().ToggleBlinkRendition(ScreenInfo.GetRenderTarget()); DoScroll: Scrolling::s_ScrollIfNecessary(ScreenInfo); diff --git a/src/host/consoleInformation.cpp b/src/host/consoleInformation.cpp index 8ace241782b..66124615eb8 100644 --- a/src/host/consoleInformation.cpp +++ b/src/host/consoleInformation.cpp @@ -12,7 +12,6 @@ #include "../types/inc/convert.hpp" using Microsoft::Console::Interactivity::ServiceLocator; -using Microsoft::Console::Render::BlinkingState; using Microsoft::Console::VirtualTerminal::VtIo; CONSOLE_INFORMATION::CONSOLE_INFORMATION() : @@ -219,24 +218,6 @@ InputBuffer* const CONSOLE_INFORMATION::GetActiveInputBuffer() const return pInputBuffer; } -// Method Description: -// - Get the colors of a particular text attribute, using our color table, -// and our configured default attributes. -// Arguments: -// - attr: the TextAttribute to retrieve the foreground and background color of. -// Return Value: -// - The color values of the attribute's foreground and background. -std::pair CONSOLE_INFORMATION::LookupAttributeColors(const TextAttribute& attr) const noexcept -{ - _blinkingState.RecordBlinkingUsage(attr); - return attr.CalculateRgbColors( - GetColorTable(), - GetDefaultForegroundIndex(), - GetDefaultBackgroundIndex(), - IsScreenReversed(), - _blinkingState.IsBlinkingFaint()); -} - // Method Description: // - Set the console's title, and trigger a renderer update of the title. // This does not include the title prefix, such as "Mark", "Select", or "Scroll" @@ -355,17 +336,6 @@ Microsoft::Console::CursorBlinker& CONSOLE_INFORMATION::GetCursorBlinker() noexc return _blinker; } -// Method Description: -// - return a reference to the console's blinking state. -// Arguments: -// - -// Return Value: -// - a reference to the console's blinking state. -BlinkingState& CONSOLE_INFORMATION::GetBlinkingState() const noexcept -{ - return _blinkingState; -} - // Method Description: // - Generates a CHAR_INFO for this output cell, using the TextAttribute // GetLegacyAttributes method to generate the legacy style attributes. diff --git a/src/host/getset.cpp b/src/host/getset.cpp index 7e894c161f4..82241ea09e1 100644 --- a/src/host/getset.cpp +++ b/src/host/getset.cpp @@ -1247,35 +1247,6 @@ void ApiRoutines::GetConsoleDisplayModeImpl(ULONG& flags) noexcept CATCH_RETURN(); } -// Routine Description: -// - A private API call for changing the screen mode between normal and reverse. -// When in reverse screen mode, the background and foreground colors are switched. -// Parameters: -// - reverseMode - set to true to enable reverse screen mode, false for normal mode. -// Return value: -// - STATUS_SUCCESS if handled successfully. Otherwise, an appropriate error code. -[[nodiscard]] NTSTATUS DoSrvPrivateSetScreenMode(const bool reverseMode) -{ - try - { - Globals& g = ServiceLocator::LocateGlobals(); - CONSOLE_INFORMATION& gci = g.getConsoleInformation(); - - gci.SetScreenReversed(reverseMode); - - if (g.pRender) - { - g.pRender->TriggerRedrawAll(); - } - - return STATUS_SUCCESS; - } - catch (...) - { - return NTSTATUS_FROM_HRESULT(wil::ResultFromCaughtException()); - } -} - // Routine Description: // - A private API call for setting the ENABLE_WRAP_AT_EOL_OUTPUT mode. // This controls whether the cursor moves to the beginning of the next row diff --git a/src/host/getset.h b/src/host/getset.h index 3ffe0a56130..873d4661775 100644 --- a/src/host/getset.h +++ b/src/host/getset.h @@ -18,7 +18,6 @@ Revision History: #include "../inc/conattrs.hpp" class SCREEN_INFORMATION; -[[nodiscard]] NTSTATUS DoSrvPrivateSetScreenMode(const bool reverseMode); [[nodiscard]] NTSTATUS DoSrvPrivateSetAutoWrapMode(const bool wrapAtEOL); void DoSrvPrivateShowCursor(SCREEN_INFORMATION& screenInfo, const bool show) noexcept; diff --git a/src/host/outputStream.cpp b/src/host/outputStream.cpp index cfeaa42455b..683874e0640 100644 --- a/src/host/outputStream.cpp +++ b/src/host/outputStream.cpp @@ -294,16 +294,24 @@ bool ConhostInternalGetSet::GetParserMode(const Microsoft::Console::VirtualTermi } // Routine Description: -// - Connects the PrivateSetScreenMode call directly into our Driver Message servicing call inside Conhost.exe -// PrivateSetScreenMode is an internal-only "API" call that the vt commands can execute, -// but it is not represented as a function call on our public API surface. +// - Sets the various render modes. // Arguments: -// - reverseMode - set to true to enable reverse screen mode, false for normal mode. +// - mode - the render mode to change. +// - enabled - set to true to enable the mode, false to disable it. // Return Value: -// - true if successful (see DoSrvPrivateSetScreenMode). false otherwise. -bool ConhostInternalGetSet::PrivateSetScreenMode(const bool reverseMode) +// - true if successful. false otherwise. +bool ConhostInternalGetSet::SetRenderMode(const RenderSettings::Mode mode, const bool enabled) { - return NT_SUCCESS(DoSrvPrivateSetScreenMode(reverseMode)); + auto& g = ServiceLocator::LocateGlobals(); + auto& renderSettings = g.getConsoleInformation().GetRenderSettings(); + renderSettings.SetRenderMode(mode, enabled); + + if (g.pRender) + { + g.pRender->TriggerRedrawAll(); + } + + return true; } // Routine Description: @@ -603,7 +611,6 @@ try { auto& g = ServiceLocator::LocateGlobals(); auto& gci = g.getConsoleInformation(); - return gci.GetColorTableEntry(tableIndex); } catch (...) @@ -624,20 +631,8 @@ try { auto& g = ServiceLocator::LocateGlobals(); auto& gci = g.getConsoleInformation(); - gci.SetColorTableEntry(tableIndex, color); - // If we're setting the default foreground or background colors - // we need to make sure the index is correctly set as well. - if (tableIndex == TextColor::DEFAULT_FOREGROUND) - { - gci.SetDefaultForegroundIndex(TextColor::DEFAULT_FOREGROUND); - } - if (tableIndex == TextColor::DEFAULT_BACKGROUND) - { - gci.SetDefaultBackgroundIndex(TextColor::DEFAULT_BACKGROUND); - } - // Update the screen colors if we're not a pty // No need to force a redraw in pty mode. if (g.pRender && !gci.IsInVtIoMode()) @@ -645,10 +640,27 @@ try g.pRender->TriggerRedrawAll(); } - return true; + // If we're a conpty, always return false, so that we send the updated color + // value to the terminal. Still handle the sequence so apps that use + // the API or VT to query the values of the color table still read the + // correct color. + return !gci.IsInVtIoMode(); } CATCH_RETURN_FALSE() +// Routine Description: +// - Sets the position in the color table for the given color alias. +// Arguments: +// - alias: the color alias to update. +// - tableIndex: the new position of the alias in the color table. +// Return Value: +// - +void ConhostInternalGetSet::SetColorAliasIndex(const ColorAlias alias, const size_t tableIndex) noexcept +{ + auto& renderSettings = ServiceLocator::LocateGlobals().getConsoleInformation().GetRenderSettings(); + renderSettings.SetColorAliasIndex(alias, tableIndex); +} + // Routine Description: // - Connects the PrivateFillRegion call directly into our Driver Message servicing // call inside Conhost.exe diff --git a/src/host/outputStream.hpp b/src/host/outputStream.hpp index 70d98001103..c74fdf30252 100644 --- a/src/host/outputStream.hpp +++ b/src/host/outputStream.hpp @@ -75,8 +75,8 @@ class ConhostInternalGetSet final : public Microsoft::Console::VirtualTerminal:: bool SetInputMode(const Microsoft::Console::VirtualTerminal::TerminalInput::Mode mode, const bool enabled) override; bool SetParserMode(const Microsoft::Console::VirtualTerminal::StateMachine::Mode mode, const bool enabled) override; bool GetParserMode(const Microsoft::Console::VirtualTerminal::StateMachine::Mode mode) const override; + bool SetRenderMode(const RenderSettings::Mode mode, const bool enabled) override; - bool PrivateSetScreenMode(const bool reverseMode) override; bool PrivateSetAutoWrapMode(const bool wrapAtEOL) override; bool PrivateShowCursor(const bool show) noexcept override; @@ -120,6 +120,7 @@ class ConhostInternalGetSet final : public Microsoft::Console::VirtualTerminal:: COLORREF GetColorTableEntry(const size_t tableIndex) const noexcept override; bool SetColorTableEntry(const size_t tableIndex, const COLORREF color) noexcept override; + void SetColorAliasIndex(const ColorAlias alias, const size_t tableIndex) noexcept override; bool PrivateFillRegion(const COORD startPosition, const size_t fillLength, diff --git a/src/host/registry.cpp b/src/host/registry.cpp index 49bd0642354..1f591b00dc6 100644 --- a/src/host/registry.cpp +++ b/src/host/registry.cpp @@ -250,17 +250,14 @@ void Registry::LoadFromRegistry(_In_ PCWSTR const pwszConsoleTitle) // Now load complex properties // Some properties shouldn't be filled by the registry if a copy already exists from the process start information. - DWORD dwValue; + const auto loadDWORD = [=](const auto valueName) { + DWORD value; + const auto status = RegistrySerialization::s_QueryValue(hTitleKey, valueName, sizeof(value), REG_DWORD, (PBYTE)&value, nullptr); + return NT_SUCCESS(status) ? std::optional{ value } : std::nullopt; + }; // Window Origin Autopositioning Setting - Status = RegistrySerialization::s_QueryValue(hTitleKey, - CONSOLE_REGISTRY_WINDOWPOS, - sizeof(dwValue), - REG_DWORD, - (PBYTE)&dwValue, - nullptr); - - if (NT_SUCCESS(Status)) + if (const auto windowPos = loadDWORD(CONSOLE_REGISTRY_WINDOWPOS)) { // The presence of a position key means autopositioning is false. _pSettings->SetAutoPosition(FALSE); @@ -269,15 +266,9 @@ void Registry::LoadFromRegistry(_In_ PCWSTR const pwszConsoleTitle) // HOWEVER, the defaults might not have been auto-pos, so don't assume that they are. // Code Page - Status = RegistrySerialization::s_QueryValue(hTitleKey, - CONSOLE_REGISTRY_CODEPAGE, - sizeof(dwValue), - REG_DWORD, - (PBYTE)&dwValue, - nullptr); - if (NT_SUCCESS(Status)) + if (const auto codePage = loadDWORD(CONSOLE_REGISTRY_CODEPAGE)) { - _pSettings->SetCodePage(dwValue); + _pSettings->SetCodePage(codePage.value()); // If this routine specified default settings for console property, // then make sure code page value when East Asian environment. @@ -302,18 +293,25 @@ void Registry::LoadFromRegistry(_In_ PCWSTR const pwszConsoleTitle) { WCHAR awchBuffer[64]; StringCchPrintfW(awchBuffer, ARRAYSIZE(awchBuffer), CONSOLE_REGISTRY_COLORTABLE, i); - Status = RegistrySerialization::s_QueryValue(hTitleKey, - awchBuffer, - sizeof(dwValue), - REG_DWORD, - (PBYTE)&dwValue, - nullptr); - if (NT_SUCCESS(Status)) + if (const auto color = loadDWORD(awchBuffer)) { - _pSettings->SetLegacyColorTableEntry(i, dwValue); + _pSettings->SetLegacyColorTableEntry(i, color.value()); } } + if (const auto color = loadDWORD(CONSOLE_REGISTRY_DEFAULTFOREGROUND)) + { + _pSettings->SetColorTableEntry(TextColor::DEFAULT_FOREGROUND, color.value()); + } + if (const auto color = loadDWORD(CONSOLE_REGISTRY_DEFAULTBACKGROUND)) + { + _pSettings->SetColorTableEntry(TextColor::DEFAULT_BACKGROUND, color.value()); + } + if (const auto color = loadDWORD(CONSOLE_REGISTRY_CURSORCOLOR)) + { + _pSettings->SetColorTableEntry(TextColor::CURSOR_COLOR, color.value()); + } + GetEditKeys(hConsoleKey); // Close the registry keys diff --git a/src/host/renderData.cpp b/src/host/renderData.cpp index 89d38a78e04..299e1f06ab6 100644 --- a/src/host/renderData.cpp +++ b/src/host/renderData.cpp @@ -203,19 +203,6 @@ ULONG RenderData::GetCursorPixelWidth() const noexcept return ServiceLocator::LocateGlobals().cursorPixelWidth; } -// Method Description: -// - Get the color of the cursor. If the color is INVALID_COLOR, the cursor -// should be drawn by inverting the color of the cursor. -// Arguments: -// - -// Return Value: -// - the color of the cursor. -COLORREF RenderData::GetCursorColor() const noexcept -{ - const CONSOLE_INFORMATION& gci = ServiceLocator::LocateGlobals().getConsoleInformation(); - return gci.GetColorTableEntry(TextColor::CURSOR_COLOR); -} - // Routine Description: // - Retrieves overlays to be drawn on top of the main screen buffer area. // - Overlays are drawn from first to last @@ -341,7 +328,9 @@ const std::vector RenderData::GetPatternId(const COORD /*location*/) con { return {}; } +#pragma endregion +#pragma region IUiaData // Routine Description: // - Converts a text attribute into the RGB values that should be presented, applying // relevant table translation information and preferences. @@ -349,12 +338,10 @@ const std::vector RenderData::GetPatternId(const COORD /*location*/) con // - ARGB color values for the foreground and background std::pair RenderData::GetAttributeColors(const TextAttribute& attr) const noexcept { - const CONSOLE_INFORMATION& gci = ServiceLocator::LocateGlobals().getConsoleInformation(); - return gci.LookupAttributeColors(attr); + const auto& renderSettings = ServiceLocator::LocateGlobals().getConsoleInformation().GetRenderSettings(); + return renderSettings.GetAttributeColors(attr); } -#pragma endregion -#pragma region IUiaData // Routine Description: // - Determines whether the selection area is empty. // Arguments: @@ -457,16 +444,4 @@ void RenderData::ColorSelection(const COORD coordSelectionStart, const COORD coo { Selection::Instance().ColorSelection(coordSelectionStart, coordSelectionEnd, attr); } - -// Method Description: -// - Returns true if the screen is globally inverted -// Arguments: -// - -// Return Value: -// - true if the screen is globally inverted -bool RenderData::IsScreenReversed() const noexcept -{ - const CONSOLE_INFORMATION& gci = ServiceLocator::LocateGlobals().getConsoleInformation(); - return gci.IsScreenReversed(); -} #pragma endregion diff --git a/src/host/renderData.hpp b/src/host/renderData.hpp index b39c4995190..7958bc5bf21 100644 --- a/src/host/renderData.hpp +++ b/src/host/renderData.hpp @@ -28,7 +28,6 @@ class RenderData final : COORD GetTextBufferEndPosition() const noexcept override; const TextBuffer& GetTextBuffer() noexcept override; const FontInfo& GetFontInfo() noexcept override; - std::pair GetAttributeColors(const TextAttribute& attr) const noexcept override; std::vector GetSelectionRects() noexcept override; @@ -43,11 +42,8 @@ class RenderData final : ULONG GetCursorHeight() const noexcept override; CursorType GetCursorStyle() const noexcept override; ULONG GetCursorPixelWidth() const noexcept override; - COLORREF GetCursorColor() const noexcept override; bool IsCursorDoubleWidth() const override; - bool IsScreenReversed() const noexcept override; - const std::vector GetOverlays() const noexcept override; const bool IsGridLineDrawingAllowed() noexcept override; @@ -61,6 +57,7 @@ class RenderData final : #pragma endregion #pragma region IUiaData + std::pair GetAttributeColors(const TextAttribute& attr) const noexcept override; const bool IsSelectionActive() const override; const bool IsBlockSelection() const noexcept override; void ClearSelection() override; diff --git a/src/host/server.h b/src/host/server.h index cd6baf49392..c57619972a6 100644 --- a/src/host/server.h +++ b/src/host/server.h @@ -28,7 +28,6 @@ Revision History: #include "../server/WaitQueue.h" #include "../host/RenderData.hpp" -#include "../renderer/inc/BlinkingState.hpp" // clang-format off // Flags flags @@ -124,8 +123,6 @@ class CONSOLE_INFORMATION : COOKED_READ_DATA& CookedReadData() noexcept; void SetCookedReadData(COOKED_READ_DATA* readData) noexcept; - std::pair LookupAttributeColors(const TextAttribute& attr) const noexcept; - void SetTitle(const std::wstring_view newTitle); void SetTitlePrefix(const std::wstring_view newTitlePrefix); void SetOriginalTitle(const std::wstring_view originalTitle); @@ -141,7 +138,6 @@ class CONSOLE_INFORMATION : friend class SCREEN_INFORMATION; friend class CommonState; Microsoft::Console::CursorBlinker& GetCursorBlinker() noexcept; - Microsoft::Console::Render::BlinkingState& GetBlinkingState() const noexcept; CHAR_INFO AsCharInfo(const OutputCellView& cell) const noexcept; @@ -159,7 +155,6 @@ class CONSOLE_INFORMATION : Microsoft::Console::VirtualTerminal::VtIo _vtIo; Microsoft::Console::CursorBlinker _blinker; - mutable Microsoft::Console::Render::BlinkingState _blinkingState; }; #define ConsoleLocked() (ServiceLocator::LocateGlobals()->getConsoleInformation()->ConsoleLock.OwningThread == NtCurrentTeb()->ClientId.UniqueThread) diff --git a/src/host/settings.cpp b/src/host/settings.cpp index cda78119dd4..24d86dc6082 100644 --- a/src/host/settings.cpp +++ b/src/host/settings.cpp @@ -53,11 +53,8 @@ Settings::Settings() : _fUseWindowSizePixels(false), _fAutoReturnOnNewline(true), // the historic Windows behavior defaults this to on. _fRenderGridWorldwide(false), // historically grid lines were only rendered in DBCS codepages, so this is false by default unless otherwise specified. - _fScreenReversed(false), // window size pixels initialized below _fInterceptCopyPaste(0), - _defaultForegroundIndex(TextColor::DARK_WHITE), - _defaultBackgroundIndex(TextColor::DARK_BLACK), _fUseDx(UseDx::Disabled), _fCopyColor(false) { @@ -79,13 +76,6 @@ Settings::Settings() : wcscpy_s(_FaceName, DEFAULT_TT_FONT_FACENAME); _CursorType = CursorType::Legacy; - - gsl::span tableView = { _colorTable.data(), _colorTable.size() }; - ::Microsoft::Console::Utils::InitializeColorTable(tableView); - - _colorTable.at(TextColor::DEFAULT_FOREGROUND) = INVALID_COLOR; - _colorTable.at(TextColor::DEFAULT_BACKGROUND) = INVALID_COLOR; - _colorTable.at(TextColor::CURSOR_COLOR) = INVALID_COLOR; } // Routine Description: @@ -124,8 +114,7 @@ void Settings::ApplyDesktopSpecificDefaults() _uNumberOfHistoryBuffers = 4; _bHistoryNoDup = FALSE; - gsl::span tableView = { _colorTable.data(), 16 }; - ::Microsoft::Console::Utils::InitializeColorTable(tableView); + _renderSettings.ResetColorTable(); _fTrimLeadingZeros = false; _fEnableColorSelection = false; @@ -234,9 +223,9 @@ void Settings::InitFromStateInfo(_In_ PCONSOLE_STATE_INFO pStateInfo) _bWindowAlpha = pStateInfo->bWindowTransparency; _CursorType = static_cast(pStateInfo->CursorType); _fInterceptCopyPaste = pStateInfo->InterceptCopyPaste; - _colorTable.at(TextColor::DEFAULT_FOREGROUND) = pStateInfo->DefaultForeground; - _colorTable.at(TextColor::DEFAULT_BACKGROUND) = pStateInfo->DefaultBackground; - _colorTable.at(TextColor::CURSOR_COLOR) = pStateInfo->CursorColor; + SetColorTableEntry(TextColor::DEFAULT_FOREGROUND, pStateInfo->DefaultForeground); + SetColorTableEntry(TextColor::DEFAULT_BACKGROUND, pStateInfo->DefaultBackground); + SetColorTableEntry(TextColor::CURSOR_COLOR, pStateInfo->CursorColor); _TerminalScrolling = pStateInfo->TerminalScrolling; } @@ -279,9 +268,9 @@ CONSOLE_STATE_INFO Settings::CreateConsoleStateInfo() const csi.bWindowTransparency = _bWindowAlpha; csi.CursorType = static_cast(_CursorType); csi.InterceptCopyPaste = _fInterceptCopyPaste; - csi.DefaultForeground = _colorTable.at(TextColor::DEFAULT_FOREGROUND); - csi.DefaultBackground = _colorTable.at(TextColor::DEFAULT_BACKGROUND); - csi.CursorColor = _colorTable.at(TextColor::CURSOR_COLOR); + csi.DefaultForeground = GetColorTableEntry(TextColor::DEFAULT_FOREGROUND); + csi.DefaultBackground = GetColorTableEntry(TextColor::DEFAULT_BACKGROUND); + csi.CursorColor = GetColorTableEntry(TextColor::CURSOR_COLOR); csi.TerminalScrolling = _TerminalScrolling; return csi; } @@ -333,22 +322,22 @@ void Settings::Validate() WI_ClearAllFlags(_wFillAttribute, ~(FG_ATTRS | BG_ATTRS)); WI_ClearAllFlags(_wPopupFillAttribute, ~(FG_ATTRS | BG_ATTRS)); - const auto defaultForeground = _colorTable.at(TextColor::DEFAULT_FOREGROUND); - const auto defaultBackground = _colorTable.at(TextColor::DEFAULT_BACKGROUND); - const auto cursorColor = _colorTable.at(TextColor::CURSOR_COLOR); + const auto defaultForeground = GetColorTableEntry(TextColor::DEFAULT_FOREGROUND); + const auto defaultBackground = GetColorTableEntry(TextColor::DEFAULT_BACKGROUND); + const auto cursorColor = GetColorTableEntry(TextColor::CURSOR_COLOR); // If the extended color options are set to invalid values (all the same color), reset them. if (cursorColor != INVALID_COLOR && cursorColor == defaultBackground) { // INVALID_COLOR is used to represent "Invert Colors" - _colorTable.at(TextColor::CURSOR_COLOR) = INVALID_COLOR; + SetColorTableEntry(TextColor::CURSOR_COLOR, INVALID_COLOR); } if (defaultForeground != INVALID_COLOR && defaultForeground == defaultBackground) { // INVALID_COLOR is used as an "unset" sentinel in future attribute functions. - _colorTable.at(TextColor::DEFAULT_FOREGROUND) = INVALID_COLOR; - _colorTable.at(TextColor::DEFAULT_BACKGROUND) = INVALID_COLOR; + SetColorTableEntry(TextColor::DEFAULT_FOREGROUND, INVALID_COLOR); + SetColorTableEntry(TextColor::DEFAULT_BACKGROUND, INVALID_COLOR); // If the damaged settings _further_ propagated to the default fill attribute, fix it. if (_wFillAttribute == 0) { @@ -414,15 +403,6 @@ void Settings::SetGridRenderingAllowedWorldwide(const bool fGridRenderingAllowed } } -bool Settings::IsScreenReversed() const -{ - return _fScreenReversed; -} -void Settings::SetScreenReversed(const bool fScreenReversed) -{ - _fScreenReversed = fScreenReversed; -} - bool Settings::GetFilterOnPaste() const { return _fFilterOnPaste; @@ -751,24 +731,24 @@ void Settings::UnsetStartupFlag(const DWORD dwFlagToUnset) _dwStartupFlags &= ~dwFlagToUnset; } -void Settings::SetColorTableEntry(const size_t index, const COLORREF ColorValue) +void Settings::SetColorTableEntry(const size_t index, const COLORREF color) { - _colorTable.at(index) = ColorValue; + _renderSettings.SetColorTableEntry(index, color); } COLORREF Settings::GetColorTableEntry(const size_t index) const { - return _colorTable.at(index); + return _renderSettings.GetColorTableEntry(index); } -void Settings::SetLegacyColorTableEntry(const size_t index, const COLORREF ColorValue) +void Settings::SetLegacyColorTableEntry(const size_t index, const COLORREF color) { - _colorTable.at(TextColor::TransposeLegacyIndex(index)) = ColorValue; + SetColorTableEntry(TextColor::TransposeLegacyIndex(index), color); } COLORREF Settings::GetLegacyColorTableEntry(const size_t index) const { - return _colorTable.at(TextColor::TransposeLegacyIndex(index)); + return GetColorTableEntry(TextColor::TransposeLegacyIndex(index)); } CursorType Settings::GetCursorType() const noexcept @@ -793,33 +773,15 @@ void Settings::SetInterceptCopyPaste(const bool interceptCopyPaste) noexcept void Settings::CalculateDefaultColorIndices() noexcept { - const auto foregroundColor = _colorTable.at(TextColor::DEFAULT_FOREGROUND); + const auto foregroundColor = GetColorTableEntry(TextColor::DEFAULT_FOREGROUND); const auto foregroundIndex = TextColor::TransposeLegacyIndex(_wFillAttribute & FG_ATTRS); - _defaultForegroundIndex = foregroundColor != INVALID_COLOR ? TextColor::DEFAULT_FOREGROUND : foregroundIndex; + const auto foregroundAlias = foregroundColor != INVALID_COLOR ? TextColor::DEFAULT_FOREGROUND : foregroundIndex; + _renderSettings.SetColorAliasIndex(ColorAlias::DefaultForeground, foregroundAlias); - const auto backgroundColor = _colorTable.at(TextColor::DEFAULT_BACKGROUND); + const auto backgroundColor = GetColorTableEntry(TextColor::DEFAULT_BACKGROUND); const auto backgroundIndex = TextColor::TransposeLegacyIndex((_wFillAttribute & BG_ATTRS) >> 4); - _defaultBackgroundIndex = backgroundColor != INVALID_COLOR ? TextColor::DEFAULT_BACKGROUND : backgroundIndex; -} - -size_t Settings::GetDefaultForegroundIndex() const noexcept -{ - return _defaultForegroundIndex; -} - -void Settings::SetDefaultForegroundIndex(const size_t index) noexcept -{ - _defaultForegroundIndex = index; -} - -size_t Settings::GetDefaultBackgroundIndex() const noexcept -{ - return _defaultBackgroundIndex; -} - -void Settings::SetDefaultBackgroundIndex(const size_t index) noexcept -{ - _defaultBackgroundIndex = index; + const auto backgroundAlias = backgroundColor != INVALID_COLOR ? TextColor::DEFAULT_BACKGROUND : backgroundIndex; + _renderSettings.SetColorAliasIndex(ColorAlias::DefaultBackground, backgroundAlias); } bool Settings::IsTerminalScrolling() const noexcept diff --git a/src/host/settings.hpp b/src/host/settings.hpp index 3929b4df920..e8c4d0b61bf 100644 --- a/src/host/settings.hpp +++ b/src/host/settings.hpp @@ -18,13 +18,11 @@ Revision History: --*/ #pragma once -#include "../buffer/out/TextAttribute.hpp" - // To prevent invisible windows, set a lower threshold on window alpha channel. constexpr unsigned short MIN_WINDOW_OPACITY = 0x4D; // 0x4D is approximately 30% visible/opaque (70% transparent). Valid range is 0x00-0xff. #include "ConsoleArguments.hpp" -#include "../inc/conattrs.hpp" +#include "../renderer/inc/RenderSettings.hpp" enum class UseDx : DWORD { @@ -35,6 +33,8 @@ enum class UseDx : DWORD class Settings { + using RenderSettings = Microsoft::Console::Render::RenderSettings; + public: Settings(); @@ -47,6 +47,9 @@ class Settings CONSOLE_STATE_INFO CreateConsoleStateInfo() const; + RenderSettings& GetRenderSettings() noexcept { return _renderSettings; }; + const RenderSettings& GetRenderSettings() const noexcept { return _renderSettings; }; + DWORD GetVirtTermLevel() const; void SetVirtTermLevel(const DWORD dwVirtTermLevel); @@ -59,9 +62,6 @@ class Settings bool IsGridRenderingAllowedWorldwide() const; void SetGridRenderingAllowedWorldwide(const bool fGridRenderingAllowed); - bool IsScreenReversed() const; - void SetScreenReversed(const bool fScreenReversed); - bool GetFilterOnPaste() const; void SetFilterOnPaste(const bool fFilterOnPaste); @@ -166,15 +166,9 @@ class Settings bool GetHistoryNoDup() const; void SetHistoryNoDup(const bool fHistoryNoDup); - // The first 16 items of the color table are the same as the 16-color palette. - inline const std::array& GetColorTable() const noexcept - { - return _colorTable; - } - - void SetColorTableEntry(const size_t index, const COLORREF ColorValue); + void SetColorTableEntry(const size_t index, const COLORREF color); COLORREF GetColorTableEntry(const size_t index) const; - void SetLegacyColorTableEntry(const size_t index, const COLORREF ColorValue); + void SetLegacyColorTableEntry(const size_t index, const COLORREF color); COLORREF GetLegacyColorTableEntry(const size_t index) const; CursorType GetCursorType() const noexcept; @@ -184,10 +178,6 @@ class Settings void SetInterceptCopyPaste(const bool interceptCopyPaste) noexcept; void CalculateDefaultColorIndices() noexcept; - size_t GetDefaultForegroundIndex() const noexcept; - void SetDefaultForegroundIndex(const size_t index) noexcept; - size_t GetDefaultBackgroundIndex() const noexcept; - void SetDefaultBackgroundIndex(const size_t index) noexcept; bool IsTerminalScrolling() const noexcept; void SetTerminalScrolling(const bool terminalScrollingEnabled) noexcept; @@ -196,6 +186,8 @@ class Settings bool GetCopyColor() const noexcept; private: + RenderSettings _renderSettings; + DWORD _dwHotKey; DWORD _dwStartupFlags; WORD _wFillAttribute; @@ -235,12 +227,9 @@ class Settings DWORD _dwVirtTermLevel; bool _fAutoReturnOnNewline; bool _fRenderGridWorldwide; - bool _fScreenReversed; UseDx _fUseDx; bool _fCopyColor; - std::array _colorTable; - // this is used for the special STARTF_USESIZE mode. bool _fUseWindowSizePixels; COORD _dwWindowSizePixels; @@ -249,9 +238,6 @@ class Settings bool _fInterceptCopyPaste; - size_t _defaultForegroundIndex; - size_t _defaultBackgroundIndex; - bool _TerminalScrolling; friend class RegistrySerialization; }; diff --git a/src/host/srvinit.cpp b/src/host/srvinit.cpp index 49acf6f6ac2..f5fa04f1fe1 100644 --- a/src/host/srvinit.cpp +++ b/src/host/srvinit.cpp @@ -819,7 +819,7 @@ PWSTR TranslateConsoleTitle(_In_ PCWSTR pwszConsoleTitle, const BOOL fUnexpand, // and we can't do that until the renderer is constructed. auto* const localPointerToThread = renderThread.get(); - g.pRender = new Renderer(&gci.renderData, nullptr, 0, std::move(renderThread)); + g.pRender = new Renderer(gci.GetRenderSettings(), &gci.renderData, nullptr, 0, std::move(renderThread)); THROW_IF_FAILED(localPointerToThread->Initialize(g.pRender)); diff --git a/src/host/telemetry.cpp b/src/host/telemetry.cpp index 4888b38eb46..79126afaacf 100644 --- a/src/host/telemetry.cpp +++ b/src/host/telemetry.cpp @@ -356,6 +356,7 @@ void Telemetry::LogProcessConnected(const HANDLE hProcess) void Telemetry::WriteFinalTraceLog() { const CONSOLE_INFORMATION& gci = Microsoft::Console::Interactivity::ServiceLocator::LocateGlobals().getConsoleInformation(); + const auto& renderSettings = gci.GetRenderSettings(); // This is a bit of processing, so don't do it for the 95% of machines that aren't being sampled. if (TraceLoggingProviderEnabled(g_hConhostV2EventTraceProvider, 0, MICROSOFT_KEYWORD_MEASURES)) { @@ -419,7 +420,7 @@ void Telemetry::WriteFinalTraceLog() TraceLoggingBool(gci.GetQuickEdit(), "QuickEdit"), TraceLoggingValue(gci.GetWindowAlpha(), "WindowAlpha"), TraceLoggingBool(gci.GetWrapText(), "WrapText"), - TraceLoggingUInt32Array((UINT32 const*)gci.GetColorTable().data(), 16, "ColorTable"), + TraceLoggingUInt32Array((UINT32 const*)renderSettings.GetColorTable().data(), 16, "ColorTable"), TraceLoggingValue(gci.CP, "CodePageInput"), TraceLoggingValue(gci.OutputCP, "CodePageOutput"), TraceLoggingValue(gci.GetFontSize().X, "FontSizeX"), @@ -453,7 +454,7 @@ void Telemetry::WriteFinalTraceLog() TraceLoggingValue(gci.GetShowWindow(), "ShowWindow"), TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES), TelemetryPrivacyDataTag(PDT_ProductAndServiceUsage)); - static_assert(sizeof(UINT32) == sizeof(gci.GetColorTable()[0]), "gci.Get16ColorTable()"); + static_assert(sizeof(UINT32) == sizeof(renderSettings.GetColorTable()[0]), "gci.Get16ColorTable()"); // I could use the TraceLoggingUIntArray, but then we would have to know the order of the enums on the backend. // So just log each enum count separately with its string representation which makes it more human readable. diff --git a/src/host/ut_host/ConptyOutputTests.cpp b/src/host/ut_host/ConptyOutputTests.cpp index 80ea088ec21..bb4033f207b 100644 --- a/src/host/ut_host/ConptyOutputTests.cpp +++ b/src/host/ut_host/ConptyOutputTests.cpp @@ -79,7 +79,7 @@ class ConptyOutputTests VERIFY_SUCCEEDED(currentBuffer.SetViewportOrigin(true, { 0, 0 }, true)); VERIFY_ARE_EQUAL(COORD({ 0, 0 }), currentBuffer.GetTextBuffer().GetCursor().GetPosition()); - g.pRender = new Renderer(&gci.renderData, nullptr, 0, nullptr); + g.pRender = new Renderer(gci.GetRenderSettings(), &gci.renderData, nullptr, 0, nullptr); // Set up an xterm-256 renderer for conpty wil::unique_hfile hFile = wil::unique_hfile(INVALID_HANDLE_VALUE); diff --git a/src/host/ut_host/ScreenBufferTests.cpp b/src/host/ut_host/ScreenBufferTests.cpp index 04a9b14d998..6532bd0b044 100644 --- a/src/host/ut_host/ScreenBufferTests.cpp +++ b/src/host/ut_host/ScreenBufferTests.cpp @@ -24,6 +24,7 @@ using namespace WEX::Logging; using namespace WEX::TestExecution; using namespace Microsoft::Console::Types; using namespace Microsoft::Console::Interactivity; +using namespace Microsoft::Console::Render; using namespace Microsoft::Console::VirtualTerminal; class ScreenBufferTests @@ -1378,6 +1379,7 @@ void ScreenBufferTests::VtScrollMarginsNewlineColor() const TextBuffer& tbi = si.GetTextBuffer(); StateMachine& stateMachine = si.GetStateMachine(); Cursor& cursor = si.GetTextBuffer().GetCursor(); + auto& renderSettings = gci.GetRenderSettings(); Log::Comment(NoThrowString().Format(L"Make sure the viewport is at 0,0")); VERIFY_SUCCEEDED(si.SetViewportOrigin(true, COORD({ 0, 0 }), true)); @@ -1431,7 +1433,7 @@ void ScreenBufferTests::VtScrollMarginsNewlineColor() const auto& attr = attrs[x]; VERIFY_ARE_EQUAL(false, attr.IsLegacy()); VERIFY_ARE_EQUAL(defaultAttrs, attr); - VERIFY_ARE_EQUAL(std::make_pair(yellow, magenta), gci.LookupAttributeColors(attr)); + VERIFY_ARE_EQUAL(std::make_pair(yellow, magenta), renderSettings.GetAttributeColors(attr)); } } } @@ -2243,6 +2245,7 @@ void ScreenBufferTests::SetDefaultsIndividuallyBothDefault() const TextBuffer& tbi = si.GetTextBuffer(); StateMachine& stateMachine = si.GetStateMachine(); Cursor& cursor = si.GetTextBuffer().GetCursor(); + auto& renderSettings = gci.GetRenderSettings(); Log::Comment(NoThrowString().Format(L"Make sure the viewport is at 0,0")); VERIFY_SUCCEEDED(si.SetViewportOrigin(true, COORD({ 0, 0 }), true)); @@ -2330,12 +2333,12 @@ void ScreenBufferTests::SetDefaultsIndividuallyBothDefault() VERIFY_ARE_EQUAL(expectedTwo, attrE); VERIFY_ARE_EQUAL(expectedSix, attrF); - VERIFY_ARE_EQUAL(std::make_pair(yellow, magenta), gci.LookupAttributeColors(attrA)); - VERIFY_ARE_EQUAL(std::make_pair(brightGreen, darkBlue), gci.LookupAttributeColors(attrB)); - VERIFY_ARE_EQUAL(std::make_pair(yellow, darkBlue), gci.LookupAttributeColors(attrC)); - VERIFY_ARE_EQUAL(std::make_pair(yellow, magenta), gci.LookupAttributeColors(attrD)); - VERIFY_ARE_EQUAL(std::make_pair(brightGreen, darkBlue), gci.LookupAttributeColors(attrE)); - VERIFY_ARE_EQUAL(std::make_pair(brightGreen, magenta), gci.LookupAttributeColors(attrF)); + VERIFY_ARE_EQUAL(std::make_pair(yellow, magenta), renderSettings.GetAttributeColors(attrA)); + VERIFY_ARE_EQUAL(std::make_pair(brightGreen, darkBlue), renderSettings.GetAttributeColors(attrB)); + VERIFY_ARE_EQUAL(std::make_pair(yellow, darkBlue), renderSettings.GetAttributeColors(attrC)); + VERIFY_ARE_EQUAL(std::make_pair(yellow, magenta), renderSettings.GetAttributeColors(attrD)); + VERIFY_ARE_EQUAL(std::make_pair(brightGreen, darkBlue), renderSettings.GetAttributeColors(attrE)); + VERIFY_ARE_EQUAL(std::make_pair(brightGreen, magenta), renderSettings.GetAttributeColors(attrF)); } void ScreenBufferTests::SetDefaultsTogether() @@ -2347,6 +2350,7 @@ void ScreenBufferTests::SetDefaultsTogether() const TextBuffer& tbi = si.GetTextBuffer(); StateMachine& stateMachine = si.GetStateMachine(); Cursor& cursor = si.GetTextBuffer().GetCursor(); + auto& renderSettings = gci.GetRenderSettings(); Log::Comment(NoThrowString().Format(L"Make sure the viewport is at 0,0")); VERIFY_SUCCEEDED(si.SetViewportOrigin(true, COORD({ 0, 0 }), true)); @@ -2408,9 +2412,9 @@ void ScreenBufferTests::SetDefaultsTogether() VERIFY_ARE_EQUAL(expectedTwo, attrB); VERIFY_ARE_EQUAL(expectedDefaults, attrC); - VERIFY_ARE_EQUAL(std::make_pair(yellow, magenta), gci.LookupAttributeColors(attrA)); - VERIFY_ARE_EQUAL(std::make_pair(yellow, color250), gci.LookupAttributeColors(attrB)); - VERIFY_ARE_EQUAL(std::make_pair(yellow, magenta), gci.LookupAttributeColors(attrC)); + VERIFY_ARE_EQUAL(std::make_pair(yellow, magenta), renderSettings.GetAttributeColors(attrA)); + VERIFY_ARE_EQUAL(std::make_pair(yellow, color250), renderSettings.GetAttributeColors(attrB)); + VERIFY_ARE_EQUAL(std::make_pair(yellow, magenta), renderSettings.GetAttributeColors(attrC)); } void ScreenBufferTests::ReverseResetWithDefaultBackground() @@ -2421,6 +2425,7 @@ void ScreenBufferTests::ReverseResetWithDefaultBackground() const TextBuffer& tbi = si.GetTextBuffer(); StateMachine& stateMachine = si.GetStateMachine(); Cursor& cursor = si.GetTextBuffer().GetCursor(); + auto& renderSettings = gci.GetRenderSettings(); Log::Comment(NoThrowString().Format(L"Make sure the viewport is at 0,0")); VERIFY_SUCCEEDED(si.SetViewportOrigin(true, COORD({ 0, 0 }), true)); @@ -2475,9 +2480,9 @@ void ScreenBufferTests::ReverseResetWithDefaultBackground() VERIFY_ARE_EQUAL(expectedReversed, attrB); VERIFY_ARE_EQUAL(expectedDefaults, attrC); - VERIFY_ARE_EQUAL(magenta, gci.LookupAttributeColors(attrA).second); - VERIFY_ARE_EQUAL(magenta, gci.LookupAttributeColors(attrB).first); - VERIFY_ARE_EQUAL(magenta, gci.LookupAttributeColors(attrC).second); + VERIFY_ARE_EQUAL(magenta, renderSettings.GetAttributeColors(attrA).second); + VERIFY_ARE_EQUAL(magenta, renderSettings.GetAttributeColors(attrB).first); + VERIFY_ARE_EQUAL(magenta, renderSettings.GetAttributeColors(attrC).second); } void ScreenBufferTests::BackspaceDefaultAttrs() @@ -2491,6 +2496,7 @@ void ScreenBufferTests::BackspaceDefaultAttrs() const TextBuffer& tbi = si.GetTextBuffer(); StateMachine& stateMachine = si.GetStateMachine(); Cursor& cursor = si.GetTextBuffer().GetCursor(); + auto& renderSettings = gci.GetRenderSettings(); Log::Comment(NoThrowString().Format(L"Make sure the viewport is at 0,0")); VERIFY_SUCCEEDED(si.SetViewportOrigin(true, COORD({ 0, 0 }), true)); @@ -2529,8 +2535,8 @@ void ScreenBufferTests::BackspaceDefaultAttrs() VERIFY_ARE_EQUAL(expectedDefaults, attrA); VERIFY_ARE_EQUAL(expectedDefaults, attrB); - VERIFY_ARE_EQUAL(magenta, gci.LookupAttributeColors(attrA).second); - VERIFY_ARE_EQUAL(magenta, gci.LookupAttributeColors(attrB).second); + VERIFY_ARE_EQUAL(magenta, renderSettings.GetAttributeColors(attrA).second); + VERIFY_ARE_EQUAL(magenta, renderSettings.GetAttributeColors(attrB).second); } void ScreenBufferTests::BackspaceDefaultAttrsWriteCharsLegacy() @@ -2555,6 +2561,7 @@ void ScreenBufferTests::BackspaceDefaultAttrsWriteCharsLegacy() const TextBuffer& tbi = si.GetTextBuffer(); StateMachine& stateMachine = si.GetStateMachine(); Cursor& cursor = si.GetTextBuffer().GetCursor(); + auto& renderSettings = gci.GetRenderSettings(); Log::Comment(NoThrowString().Format(L"Make sure the viewport is at 0,0")); VERIFY_SUCCEEDED(si.SetViewportOrigin(true, COORD({ 0, 0 }), true)); @@ -2607,8 +2614,8 @@ void ScreenBufferTests::BackspaceDefaultAttrsWriteCharsLegacy() VERIFY_ARE_EQUAL(expectedDefaults, attrA); VERIFY_ARE_EQUAL(expectedDefaults, attrB); - VERIFY_ARE_EQUAL(magenta, gci.LookupAttributeColors(attrA).second); - VERIFY_ARE_EQUAL(magenta, gci.LookupAttributeColors(attrB).second); + VERIFY_ARE_EQUAL(magenta, renderSettings.GetAttributeColors(attrA).second); + VERIFY_ARE_EQUAL(magenta, renderSettings.GetAttributeColors(attrB).second); } void ScreenBufferTests::BackspaceDefaultAttrsInPrompt() @@ -2621,6 +2628,7 @@ void ScreenBufferTests::BackspaceDefaultAttrsInPrompt() const TextBuffer& tbi = si.GetTextBuffer(); StateMachine& stateMachine = si.GetStateMachine(); Cursor& cursor = si.GetTextBuffer().GetCursor(); + // Make sure we're in VT mode WI_SetFlag(si.OutputMode, ENABLE_VIRTUAL_TERMINAL_PROCESSING); VERIFY_IS_TRUE(WI_IsFlagSet(si.OutputMode, ENABLE_VIRTUAL_TERMINAL_PROCESSING)); @@ -2700,6 +2708,7 @@ void ScreenBufferTests::SetGlobalColorTable() StateMachine& stateMachine = mainBuffer.GetStateMachine(); Cursor& mainCursor = mainBuffer.GetTextBuffer().GetCursor(); + const auto& renderSettings = gci.GetRenderSettings(); Log::Comment(NoThrowString().Format(L"Make sure the viewport is at 0,0")); VERIFY_SUCCEEDED(mainBuffer.SetViewportOrigin(true, COORD({ 0, 0 }), true)); @@ -2719,7 +2728,7 @@ void ScreenBufferTests::SetGlobalColorTable() const std::vector attrs{ attrRow->begin(), attrRow->end() }; const auto attrA = attrs[0]; LOG_ATTR(attrA); - VERIFY_ARE_EQUAL(originalRed, gci.LookupAttributeColors(attrA).second); + VERIFY_ARE_EQUAL(originalRed, renderSettings.GetAttributeColors(attrA).second); } Log::Comment(NoThrowString().Format(L"Create an alt buffer")); @@ -2745,7 +2754,7 @@ void ScreenBufferTests::SetGlobalColorTable() const std::vector attrs{ attrRow->begin(), attrRow->end() }; const auto attrA = attrs[0]; LOG_ATTR(attrA); - VERIFY_ARE_EQUAL(originalRed, gci.LookupAttributeColors(attrA).second); + VERIFY_ARE_EQUAL(originalRed, renderSettings.GetAttributeColors(attrA).second); } Log::Comment(NoThrowString().Format(L"Change the value of red to RGB(0x11, 0x22, 0x33)")); @@ -2762,8 +2771,8 @@ void ScreenBufferTests::SetGlobalColorTable() const auto attrB = attrs[1]; LOG_ATTR(attrA); LOG_ATTR(attrB); - VERIFY_ARE_EQUAL(testColor, gci.LookupAttributeColors(attrA).second); - VERIFY_ARE_EQUAL(testColor, gci.LookupAttributeColors(attrB).second); + VERIFY_ARE_EQUAL(testColor, renderSettings.GetAttributeColors(attrA).second); + VERIFY_ARE_EQUAL(testColor, renderSettings.GetAttributeColors(attrB).second); } Log::Comment(NoThrowString().Format(L"Switch back to the main buffer")); @@ -2785,8 +2794,8 @@ void ScreenBufferTests::SetGlobalColorTable() const auto attrB = attrs[1]; LOG_ATTR(attrA); LOG_ATTR(attrB); - VERIFY_ARE_EQUAL(testColor, gci.LookupAttributeColors(attrA).second); - VERIFY_ARE_EQUAL(testColor, gci.LookupAttributeColors(attrB).second); + VERIFY_ARE_EQUAL(testColor, renderSettings.GetAttributeColors(attrA).second); + VERIFY_ARE_EQUAL(testColor, renderSettings.GetAttributeColors(attrB).second); } } @@ -2806,6 +2815,7 @@ void ScreenBufferTests::SetColorTableThreeDigits() StateMachine& stateMachine = mainBuffer.GetStateMachine(); Cursor& mainCursor = mainBuffer.GetTextBuffer().GetCursor(); + const auto& renderSettings = gci.GetRenderSettings(); Log::Comment(NoThrowString().Format(L"Make sure the viewport is at 0,0")); VERIFY_SUCCEEDED(mainBuffer.SetViewportOrigin(true, COORD({ 0, 0 }), true)); @@ -2825,7 +2835,7 @@ void ScreenBufferTests::SetColorTableThreeDigits() const std::vector attrs{ attrRow->begin(), attrRow->end() }; const auto attrA = attrs[0]; LOG_ATTR(attrA); - VERIFY_ARE_EQUAL(originalRed, gci.LookupAttributeColors(attrA).second); + VERIFY_ARE_EQUAL(originalRed, renderSettings.GetAttributeColors(attrA).second); } Log::Comment(NoThrowString().Format(L"Create an alt buffer")); @@ -2851,7 +2861,7 @@ void ScreenBufferTests::SetColorTableThreeDigits() const std::vector attrs{ attrRow->begin(), attrRow->end() }; const auto attrA = attrs[0]; LOG_ATTR(attrA); - VERIFY_ARE_EQUAL(originalRed, gci.LookupAttributeColors(attrA).second); + VERIFY_ARE_EQUAL(originalRed, renderSettings.GetAttributeColors(attrA).second); } Log::Comment(NoThrowString().Format(L"Change the value of red to RGB(0x11, 0x22, 0x33)")); @@ -2870,7 +2880,7 @@ void ScreenBufferTests::SetColorTableThreeDigits() const auto attrB = attrs[1]; // TODO MSFT:20105972 - attrA and attrB should both be the same color now LOG_ATTR(attrB); - VERIFY_ARE_EQUAL(testColor, gci.LookupAttributeColors(attrB).second); + VERIFY_ARE_EQUAL(testColor, renderSettings.GetAttributeColors(attrB).second); } } @@ -3202,6 +3212,7 @@ void ScreenBufferTests::DontResetColorsAboveVirtualBottom() auto& tbi = si.GetTextBuffer(); auto& stateMachine = si.GetStateMachine(); auto& cursor = si.GetTextBuffer().GetCursor(); + const auto& renderSettings = gci.GetRenderSettings(); VERIFY_SUCCESS_NTSTATUS(si.SetViewportOrigin(true, { 0, 1 }, true)); cursor.SetPosition({ 0, si.GetViewport().BottomInclusive() }); @@ -3231,9 +3242,9 @@ void ScreenBufferTests::DontResetColorsAboveVirtualBottom() const auto attrB = attrs[1]; LOG_ATTR(attrA); LOG_ATTR(attrB); - VERIFY_ARE_EQUAL(std::make_pair(darkRed, darkBlue), gci.LookupAttributeColors(attrA)); + VERIFY_ARE_EQUAL(std::make_pair(darkRed, darkBlue), renderSettings.GetAttributeColors(attrA)); - VERIFY_ARE_EQUAL(std::make_pair(darkWhite, darkBlack), gci.LookupAttributeColors(attrB)); + VERIFY_ARE_EQUAL(std::make_pair(darkWhite, darkBlack), renderSettings.GetAttributeColors(attrB)); } Log::Comment(NoThrowString().Format(L"Emulate scrolling up with the mouse")); @@ -3264,11 +3275,11 @@ void ScreenBufferTests::DontResetColorsAboveVirtualBottom() LOG_ATTR(attrA); LOG_ATTR(attrB); LOG_ATTR(attrC); - VERIFY_ARE_EQUAL(std::make_pair(darkRed, darkBlue), gci.LookupAttributeColors(attrA)); + VERIFY_ARE_EQUAL(std::make_pair(darkRed, darkBlue), renderSettings.GetAttributeColors(attrA)); - VERIFY_ARE_EQUAL(std::make_pair(darkWhite, darkBlack), gci.LookupAttributeColors(attrB)); + VERIFY_ARE_EQUAL(std::make_pair(darkWhite, darkBlack), renderSettings.GetAttributeColors(attrB)); - VERIFY_ARE_EQUAL(std::make_pair(darkWhite, darkBlack), gci.LookupAttributeColors(attrC)); + VERIFY_ARE_EQUAL(std::make_pair(darkWhite, darkBlack), renderSettings.GetAttributeColors(attrC)); } } @@ -4625,24 +4636,25 @@ void ScreenBufferTests::SetScreenMode() auto& gci = ServiceLocator::LocateGlobals().getConsoleInformation(); auto& si = gci.GetActiveOutputBuffer(); auto& stateMachine = si.GetStateMachine(); + const auto& renderSettings = gci.GetRenderSettings(); const auto rgbForeground = RGB(12, 34, 56); const auto rgbBackground = RGB(78, 90, 12); const auto testAttr = TextAttribute{ rgbForeground, rgbBackground }; Log::Comment(L"By default the screen mode is normal."); - VERIFY_IS_FALSE(gci.IsScreenReversed()); - VERIFY_ARE_EQUAL(std::make_pair(rgbForeground, rgbBackground), gci.LookupAttributeColors(testAttr)); + VERIFY_IS_FALSE(renderSettings.GetRenderMode(RenderSettings::Mode::ScreenReversed)); + VERIFY_ARE_EQUAL(std::make_pair(rgbForeground, rgbBackground), renderSettings.GetAttributeColors(testAttr)); Log::Comment(L"When DECSCNM is set, background and foreground colors are switched."); stateMachine.ProcessString(L"\x1B[?5h"); - VERIFY_IS_TRUE(gci.IsScreenReversed()); - VERIFY_ARE_EQUAL(std::make_pair(rgbBackground, rgbForeground), gci.LookupAttributeColors(testAttr)); + VERIFY_IS_TRUE(renderSettings.GetRenderMode(RenderSettings::Mode::ScreenReversed)); + VERIFY_ARE_EQUAL(std::make_pair(rgbBackground, rgbForeground), renderSettings.GetAttributeColors(testAttr)); Log::Comment(L"When DECSCNM is reset, the colors are normal again."); stateMachine.ProcessString(L"\x1B[?5l"); - VERIFY_IS_FALSE(gci.IsScreenReversed()); - VERIFY_ARE_EQUAL(std::make_pair(rgbForeground, rgbBackground), gci.LookupAttributeColors(testAttr)); + VERIFY_IS_FALSE(renderSettings.GetRenderMode(RenderSettings::Mode::ScreenReversed)); + VERIFY_ARE_EQUAL(std::make_pair(rgbForeground, rgbBackground), renderSettings.GetAttributeColors(testAttr)); } void ScreenBufferTests::SetOriginMode() diff --git a/src/host/ut_host/TextBufferTests.cpp b/src/host/ut_host/TextBufferTests.cpp index 529f2c38f4b..baa3513d0f3 100644 --- a/src/host/ut_host/TextBufferTests.cpp +++ b/src/host/ut_host/TextBufferTests.cpp @@ -641,6 +641,7 @@ void TextBufferTests::TestMixedRgbAndLegacyForeground() const TextBuffer& tbi = si.GetTextBuffer(); StateMachine& stateMachine = si.GetStateMachine(); const Cursor& cursor = tbi.GetCursor(); + const auto& renderSettings = gci.GetRenderSettings(); // Case 1 - // Write '\E[m\E[38;2;64;128;255mX\E[49mX\E[m' @@ -670,10 +671,10 @@ void TextBufferTests::TestMixedRgbAndLegacyForeground() VERIFY_ARE_EQUAL(attrB.IsLegacy(), false); const auto fgColor = RGB(64, 128, 255); - const auto bgColor = gci.LookupAttributeColors(si.GetAttributes()).second; + const auto bgColor = renderSettings.GetAttributeColors(si.GetAttributes()).second; - VERIFY_ARE_EQUAL(gci.LookupAttributeColors(attrA), std::make_pair(fgColor, bgColor)); - VERIFY_ARE_EQUAL(gci.LookupAttributeColors(attrB), std::make_pair(fgColor, bgColor)); + VERIFY_ARE_EQUAL(renderSettings.GetAttributeColors(attrA), std::make_pair(fgColor, bgColor)); + VERIFY_ARE_EQUAL(renderSettings.GetAttributeColors(attrB), std::make_pair(fgColor, bgColor)); const auto reset = L"\x1b[0m"; stateMachine.ProcessString(reset); @@ -686,6 +687,7 @@ void TextBufferTests::TestMixedRgbAndLegacyBackground() const TextBuffer& tbi = si.GetTextBuffer(); StateMachine& stateMachine = si.GetStateMachine(); const Cursor& cursor = tbi.GetCursor(); + const auto& renderSettings = gci.GetRenderSettings(); // Case 2 - // \E[m\E[48;2;64;128;255mX\E[39mX\E[m @@ -714,10 +716,10 @@ void TextBufferTests::TestMixedRgbAndLegacyBackground() VERIFY_ARE_EQUAL(attrB.IsLegacy(), false); const auto bgColor = RGB(64, 128, 255); - const auto fgColor = gci.LookupAttributeColors(si.GetAttributes()).first; + const auto fgColor = renderSettings.GetAttributeColors(si.GetAttributes()).first; - VERIFY_ARE_EQUAL(gci.LookupAttributeColors(attrA), std::make_pair(fgColor, bgColor)); - VERIFY_ARE_EQUAL(gci.LookupAttributeColors(attrB), std::make_pair(fgColor, bgColor)); + VERIFY_ARE_EQUAL(renderSettings.GetAttributeColors(attrA), std::make_pair(fgColor, bgColor)); + VERIFY_ARE_EQUAL(renderSettings.GetAttributeColors(attrB), std::make_pair(fgColor, bgColor)); const auto reset = L"\x1b[0m"; stateMachine.ProcessString(reset); @@ -730,6 +732,7 @@ void TextBufferTests::TestMixedRgbAndLegacyUnderline() const TextBuffer& tbi = si.GetTextBuffer(); StateMachine& stateMachine = si.GetStateMachine(); const Cursor& cursor = tbi.GetCursor(); + const auto& renderSettings = gci.GetRenderSettings(); // Case 3 - // '\E[m\E[48;2;64;128;255mX\E[4mX\E[m' @@ -756,10 +759,10 @@ void TextBufferTests::TestMixedRgbAndLegacyUnderline() VERIFY_ARE_EQUAL(attrB.IsLegacy(), false); const auto bgColor = RGB(64, 128, 255); - const auto fgColor = gci.LookupAttributeColors(si.GetAttributes()).first; + const auto fgColor = renderSettings.GetAttributeColors(si.GetAttributes()).first; - VERIFY_ARE_EQUAL(gci.LookupAttributeColors(attrA), std::make_pair(fgColor, bgColor)); - VERIFY_ARE_EQUAL(gci.LookupAttributeColors(attrB), std::make_pair(fgColor, bgColor)); + VERIFY_ARE_EQUAL(renderSettings.GetAttributeColors(attrA), std::make_pair(fgColor, bgColor)); + VERIFY_ARE_EQUAL(renderSettings.GetAttributeColors(attrB), std::make_pair(fgColor, bgColor)); VERIFY_ARE_EQUAL(attrA.IsUnderlined(), false); VERIFY_ARE_EQUAL(attrB.IsUnderlined(), true); @@ -775,6 +778,8 @@ void TextBufferTests::TestMixedRgbAndLegacyBrightness() const TextBuffer& tbi = si.GetTextBuffer(); StateMachine& stateMachine = si.GetStateMachine(); const Cursor& cursor = tbi.GetCursor(); + const auto& renderSettings = gci.GetRenderSettings(); + // Case 4 - // '\E[m\E[32mX\E[1mX' // Make sure that the second X is a BRIGHT green, not white. @@ -803,8 +808,8 @@ void TextBufferTests::TestMixedRgbAndLegacyBrightness() VERIFY_ARE_EQUAL(attrA.IsLegacy(), false); VERIFY_ARE_EQUAL(attrB.IsLegacy(), false); - VERIFY_ARE_EQUAL(gci.LookupAttributeColors(attrA).first, dark_green); - VERIFY_ARE_EQUAL(gci.LookupAttributeColors(attrB).first, bright_green); + VERIFY_ARE_EQUAL(renderSettings.GetAttributeColors(attrA).first, dark_green); + VERIFY_ARE_EQUAL(renderSettings.GetAttributeColors(attrB).first, bright_green); const auto reset = L"\x1b[0m"; stateMachine.ProcessString(reset); @@ -817,6 +822,7 @@ void TextBufferTests::TestRgbEraseLine() TextBuffer& tbi = si.GetTextBuffer(); StateMachine& stateMachine = si.GetStateMachine(); Cursor& cursor = tbi.GetCursor(); + const auto& renderSettings = gci.GetRenderSettings(); WI_SetFlag(si.OutputMode, ENABLE_VIRTUAL_TERMINAL_PROCESSING); cursor.SetXPosition(0); @@ -854,14 +860,14 @@ void TextBufferTests::TestRgbEraseLine() const auto attr0 = attrs[0]; VERIFY_ARE_EQUAL(attr0.IsLegacy(), false); - VERIFY_ARE_EQUAL(gci.LookupAttributeColors(attr0).second, RGB(64, 128, 255)); + VERIFY_ARE_EQUAL(renderSettings.GetAttributeColors(attr0).second, RGB(64, 128, 255)); for (auto i = 1; i < len; i++) { const auto attr = attrs[i]; LOG_ATTR(attr); VERIFY_ARE_EQUAL(attr.IsLegacy(), false); - VERIFY_ARE_EQUAL(gci.LookupAttributeColors(attr).second, RGB(128, 128, 255)); + VERIFY_ARE_EQUAL(renderSettings.GetAttributeColors(attr).second, RGB(128, 128, 255)); } std::wstring reset = L"\x1b[0m"; stateMachine.ProcessString(reset); @@ -875,6 +881,7 @@ void TextBufferTests::TestUnBold() TextBuffer& tbi = si.GetTextBuffer(); StateMachine& stateMachine = si.GetStateMachine(); Cursor& cursor = tbi.GetCursor(); + const auto& renderSettings = gci.GetRenderSettings(); WI_SetFlag(si.OutputMode, ENABLE_VIRTUAL_TERMINAL_PROCESSING); cursor.SetXPosition(0); @@ -911,8 +918,8 @@ void TextBufferTests::TestUnBold() LOG_ATTR(attrA); LOG_ATTR(attrB); - VERIFY_ARE_EQUAL(gci.LookupAttributeColors(attrA).first, bright_green); - VERIFY_ARE_EQUAL(gci.LookupAttributeColors(attrB).first, dark_green); + VERIFY_ARE_EQUAL(renderSettings.GetAttributeColors(attrA).first, bright_green); + VERIFY_ARE_EQUAL(renderSettings.GetAttributeColors(attrB).first, dark_green); std::wstring reset = L"\x1b[0m"; stateMachine.ProcessString(reset); @@ -925,6 +932,7 @@ void TextBufferTests::TestUnBoldRgb() TextBuffer& tbi = si.GetTextBuffer(); StateMachine& stateMachine = si.GetStateMachine(); Cursor& cursor = tbi.GetCursor(); + const auto& renderSettings = gci.GetRenderSettings(); WI_SetFlag(si.OutputMode, ENABLE_VIRTUAL_TERMINAL_PROCESSING); cursor.SetXPosition(0); @@ -965,8 +973,8 @@ void TextBufferTests::TestUnBoldRgb() VERIFY_ARE_EQUAL(attrA.IsLegacy(), false); VERIFY_ARE_EQUAL(attrB.IsLegacy(), false); - VERIFY_ARE_EQUAL(gci.LookupAttributeColors(attrA).first, bright_green); - VERIFY_ARE_EQUAL(gci.LookupAttributeColors(attrB).first, dark_green); + VERIFY_ARE_EQUAL(renderSettings.GetAttributeColors(attrA).first, bright_green); + VERIFY_ARE_EQUAL(renderSettings.GetAttributeColors(attrB).first, dark_green); std::wstring reset = L"\x1b[0m"; stateMachine.ProcessString(reset); @@ -979,6 +987,7 @@ void TextBufferTests::TestComplexUnBold() TextBuffer& tbi = si.GetTextBuffer(); StateMachine& stateMachine = si.GetStateMachine(); Cursor& cursor = tbi.GetCursor(); + const auto& renderSettings = gci.GetRenderSettings(); WI_SetFlag(si.OutputMode, ENABLE_VIRTUAL_TERMINAL_PROCESSING); cursor.SetXPosition(0); @@ -1037,22 +1046,22 @@ void TextBufferTests::TestComplexUnBold() VERIFY_ARE_EQUAL(attrE.IsLegacy(), false); VERIFY_ARE_EQUAL(attrF.IsLegacy(), false); - VERIFY_ARE_EQUAL(gci.LookupAttributeColors(attrA), std::make_pair(bright_green, RGB(1, 2, 3))); + VERIFY_ARE_EQUAL(renderSettings.GetAttributeColors(attrA), std::make_pair(bright_green, RGB(1, 2, 3))); VERIFY_IS_TRUE(attrA.IsBold()); - VERIFY_ARE_EQUAL(gci.LookupAttributeColors(attrB), std::make_pair(dark_green, RGB(1, 2, 3))); + VERIFY_ARE_EQUAL(renderSettings.GetAttributeColors(attrB), std::make_pair(dark_green, RGB(1, 2, 3))); VERIFY_IS_FALSE(attrB.IsBold()); - VERIFY_ARE_EQUAL(gci.LookupAttributeColors(attrC), std::make_pair(RGB(32, 32, 32), RGB(1, 2, 3))); + VERIFY_ARE_EQUAL(renderSettings.GetAttributeColors(attrC), std::make_pair(RGB(32, 32, 32), RGB(1, 2, 3))); VERIFY_IS_FALSE(attrC.IsBold()); - VERIFY_ARE_EQUAL(gci.LookupAttributeColors(attrD), gci.LookupAttributeColors(attrC)); + VERIFY_ARE_EQUAL(renderSettings.GetAttributeColors(attrD), renderSettings.GetAttributeColors(attrC)); VERIFY_IS_TRUE(attrD.IsBold()); - VERIFY_ARE_EQUAL(gci.LookupAttributeColors(attrE), std::make_pair(RGB(64, 64, 64), RGB(1, 2, 3))); + VERIFY_ARE_EQUAL(renderSettings.GetAttributeColors(attrE), std::make_pair(RGB(64, 64, 64), RGB(1, 2, 3))); VERIFY_IS_TRUE(attrE.IsBold()); - VERIFY_ARE_EQUAL(gci.LookupAttributeColors(attrF), std::make_pair(RGB(64, 64, 64), RGB(1, 2, 3))); + VERIFY_ARE_EQUAL(renderSettings.GetAttributeColors(attrF), std::make_pair(RGB(64, 64, 64), RGB(1, 2, 3))); VERIFY_IS_FALSE(attrF.IsBold()); std::wstring reset = L"\x1b[0m"; @@ -1066,6 +1075,7 @@ void TextBufferTests::CopyAttrs() TextBuffer& tbi = si.GetTextBuffer(); StateMachine& stateMachine = si.GetStateMachine(); Cursor& cursor = tbi.GetCursor(); + const auto& renderSettings = gci.GetRenderSettings(); WI_SetFlag(si.OutputMode, ENABLE_VIRTUAL_TERMINAL_PROCESSING); cursor.SetXPosition(0); @@ -1103,8 +1113,8 @@ void TextBufferTests::CopyAttrs() LOG_ATTR(attrA); LOG_ATTR(attrB); - VERIFY_ARE_EQUAL(gci.LookupAttributeColors(attrA).first, dark_blue); - VERIFY_ARE_EQUAL(gci.LookupAttributeColors(attrB).first, dark_magenta); + VERIFY_ARE_EQUAL(renderSettings.GetAttributeColors(attrA).first, dark_blue); + VERIFY_ARE_EQUAL(renderSettings.GetAttributeColors(attrB).first, dark_magenta); } void TextBufferTests::EmptySgrTest() @@ -1114,6 +1124,7 @@ void TextBufferTests::EmptySgrTest() TextBuffer& tbi = si.GetTextBuffer(); StateMachine& stateMachine = si.GetStateMachine(); Cursor& cursor = tbi.GetCursor(); + const auto& renderSettings = gci.GetRenderSettings(); WI_SetFlag(si.OutputMode, ENABLE_VIRTUAL_TERMINAL_PROCESSING); cursor.SetXPosition(0); @@ -1121,7 +1132,7 @@ void TextBufferTests::EmptySgrTest() std::wstring reset = L"\x1b[0m"; stateMachine.ProcessString(reset); - const auto [defaultFg, defaultBg] = gci.LookupAttributeColors(si.GetAttributes()); + const auto [defaultFg, defaultBg] = renderSettings.GetAttributeColors(si.GetAttributes()); // Case 1 - // Write '\x1b[0mX\x1b[31mX\x1b[31;m' @@ -1156,11 +1167,11 @@ void TextBufferTests::EmptySgrTest() LOG_ATTR(attrB); LOG_ATTR(attrC); - VERIFY_ARE_EQUAL(gci.LookupAttributeColors(attrA), std::make_pair(defaultFg, defaultBg)); + VERIFY_ARE_EQUAL(renderSettings.GetAttributeColors(attrA), std::make_pair(defaultFg, defaultBg)); - VERIFY_ARE_EQUAL(gci.LookupAttributeColors(attrB), std::make_pair(darkRed, defaultBg)); + VERIFY_ARE_EQUAL(renderSettings.GetAttributeColors(attrB), std::make_pair(darkRed, defaultBg)); - VERIFY_ARE_EQUAL(gci.LookupAttributeColors(attrC), std::make_pair(defaultFg, defaultBg)); + VERIFY_ARE_EQUAL(renderSettings.GetAttributeColors(attrC), std::make_pair(defaultFg, defaultBg)); stateMachine.ProcessString(reset); } @@ -1172,6 +1183,7 @@ void TextBufferTests::TestReverseReset() TextBuffer& tbi = si.GetTextBuffer(); StateMachine& stateMachine = si.GetStateMachine(); Cursor& cursor = tbi.GetCursor(); + const auto& renderSettings = gci.GetRenderSettings(); WI_SetFlag(si.OutputMode, ENABLE_VIRTUAL_TERMINAL_PROCESSING); @@ -1180,7 +1192,7 @@ void TextBufferTests::TestReverseReset() std::wstring reset = L"\x1b[0m"; stateMachine.ProcessString(reset); - const auto [defaultFg, defaultBg] = gci.LookupAttributeColors(si.GetAttributes()); + const auto [defaultFg, defaultBg] = renderSettings.GetAttributeColors(si.GetAttributes()); // Case 1 - // Write '\E[42m\E[38;2;128;5;255mX\E[7mX\E[27mX' @@ -1217,11 +1229,11 @@ void TextBufferTests::TestReverseReset() LOG_ATTR(attrB); LOG_ATTR(attrC); - VERIFY_ARE_EQUAL(gci.LookupAttributeColors(attrA), std::make_pair(rgbColor, dark_green)); + VERIFY_ARE_EQUAL(renderSettings.GetAttributeColors(attrA), std::make_pair(rgbColor, dark_green)); - VERIFY_ARE_EQUAL(gci.LookupAttributeColors(attrB), std::make_pair(dark_green, rgbColor)); + VERIFY_ARE_EQUAL(renderSettings.GetAttributeColors(attrB), std::make_pair(dark_green, rgbColor)); - VERIFY_ARE_EQUAL(gci.LookupAttributeColors(attrC), std::make_pair(rgbColor, dark_green)); + VERIFY_ARE_EQUAL(renderSettings.GetAttributeColors(attrC), std::make_pair(rgbColor, dark_green)); stateMachine.ProcessString(reset); } @@ -1235,6 +1247,7 @@ void TextBufferTests::CopyLastAttr() TextBuffer& tbi = si.GetTextBuffer(); StateMachine& stateMachine = si.GetStateMachine(); Cursor& cursor = tbi.GetCursor(); + auto& renderSettings = gci.GetRenderSettings(); WI_SetFlag(si.OutputMode, ENABLE_VIRTUAL_TERMINAL_PROCESSING); @@ -1243,7 +1256,7 @@ void TextBufferTests::CopyLastAttr() std::wstring reset = L"\x1b[0m"; stateMachine.ProcessString(reset); - const auto [defaultFg, defaultBg] = gci.LookupAttributeColors(si.GetAttributes()); + const auto [defaultFg, defaultBg] = renderSettings.GetAttributeColors(si.GetAttributes()); const COLORREF solFg = RGB(101, 123, 131); const COLORREF solBg = RGB(0, 43, 54); @@ -1330,17 +1343,17 @@ void TextBufferTests::CopyLastAttr() LOG_ATTR(attr3B); LOG_ATTR(attr3C); - VERIFY_ARE_EQUAL(gci.LookupAttributeColors(attr1A), std::make_pair(solFg, solBg)); + VERIFY_ARE_EQUAL(renderSettings.GetAttributeColors(attr1A), std::make_pair(solFg, solBg)); - VERIFY_ARE_EQUAL(gci.LookupAttributeColors(attr2A), std::make_pair(solFg, solBg)); + VERIFY_ARE_EQUAL(renderSettings.GetAttributeColors(attr2A), std::make_pair(solFg, solBg)); - VERIFY_ARE_EQUAL(gci.LookupAttributeColors(attr2B), std::make_pair(solCyan, solBg)); + VERIFY_ARE_EQUAL(renderSettings.GetAttributeColors(attr2B), std::make_pair(solCyan, solBg)); - VERIFY_ARE_EQUAL(gci.LookupAttributeColors(attr3A), std::make_pair(solFg, solBg)); + VERIFY_ARE_EQUAL(renderSettings.GetAttributeColors(attr3A), std::make_pair(solFg, solBg)); - VERIFY_ARE_EQUAL(gci.LookupAttributeColors(attr3B), std::make_pair(solCyan, solBg)); + VERIFY_ARE_EQUAL(renderSettings.GetAttributeColors(attr3B), std::make_pair(solCyan, solBg)); - VERIFY_ARE_EQUAL(gci.LookupAttributeColors(attr3C), std::make_pair(solFg, solBg)); + VERIFY_ARE_EQUAL(renderSettings.GetAttributeColors(attr3C), std::make_pair(solFg, solBg)); stateMachine.ProcessString(reset); } @@ -1352,6 +1365,8 @@ void TextBufferTests::TestRgbThenBold() const TextBuffer& tbi = si.GetTextBuffer(); StateMachine& stateMachine = si.GetStateMachine(); const Cursor& cursor = tbi.GetCursor(); + const auto& renderSettings = gci.GetRenderSettings(); + // See MSFT:16398982 Log::Comment(NoThrowString().Format( L"Test that a bold following a RGB color doesn't remove the RGB color")); @@ -1381,8 +1396,8 @@ void TextBufferTests::TestRgbThenBold() VERIFY_ARE_EQUAL(attrA.IsLegacy(), false); VERIFY_ARE_EQUAL(attrB.IsLegacy(), false); - VERIFY_ARE_EQUAL(gci.LookupAttributeColors(attrA), std::make_pair(foreground, background)); - VERIFY_ARE_EQUAL(gci.LookupAttributeColors(attrB), std::make_pair(foreground, background)); + VERIFY_ARE_EQUAL(renderSettings.GetAttributeColors(attrA), std::make_pair(foreground, background)); + VERIFY_ARE_EQUAL(renderSettings.GetAttributeColors(attrB), std::make_pair(foreground, background)); const auto reset = L"\x1b[0m"; stateMachine.ProcessString(reset); @@ -1395,6 +1410,8 @@ void TextBufferTests::TestResetClearsBoldness() const TextBuffer& tbi = si.GetTextBuffer(); StateMachine& stateMachine = si.GetStateMachine(); const Cursor& cursor = tbi.GetCursor(); + const auto& renderSettings = gci.GetRenderSettings(); + Log::Comment(NoThrowString().Format( L"Test that resetting bold attributes clears the boldness.")); const auto x0 = cursor.GetPosition().X; @@ -1404,7 +1421,7 @@ void TextBufferTests::TestResetClearsBoldness() TextAttribute defaultAttribute; si.SetAttributes(defaultAttribute); - const auto [defaultFg, defaultBg] = gci.LookupAttributeColors(si.GetAttributes()); + const auto [defaultFg, defaultBg] = renderSettings.GetAttributeColors(si.GetAttributes()); const auto dark_green = gci.GetColorTableEntry(TextColor::DARK_GREEN); const auto bright_green = gci.GetColorTableEntry(TextColor::BRIGHT_GREEN); @@ -1433,10 +1450,10 @@ void TextBufferTests::TestResetClearsBoldness() LOG_ATTR(attrC); LOG_ATTR(attrD); - VERIFY_ARE_EQUAL(gci.LookupAttributeColors(attrA).first, dark_green); - VERIFY_ARE_EQUAL(gci.LookupAttributeColors(attrB).first, bright_green); - VERIFY_ARE_EQUAL(gci.LookupAttributeColors(attrC).first, defaultFg); - VERIFY_ARE_EQUAL(gci.LookupAttributeColors(attrD).first, dark_green); + VERIFY_ARE_EQUAL(renderSettings.GetAttributeColors(attrA).first, dark_green); + VERIFY_ARE_EQUAL(renderSettings.GetAttributeColors(attrB).first, bright_green); + VERIFY_ARE_EQUAL(renderSettings.GetAttributeColors(attrC).first, defaultFg); + VERIFY_ARE_EQUAL(renderSettings.GetAttributeColors(attrD).first, dark_green); VERIFY_IS_FALSE(attrA.IsBold()); VERIFY_IS_TRUE(attrB.IsBold()); diff --git a/src/host/ut_host/VtIoTests.cpp b/src/host/ut_host/VtIoTests.cpp index 6b79f5f4571..98f6e77d307 100644 --- a/src/host/ut_host/VtIoTests.cpp +++ b/src/host/ut_host/VtIoTests.cpp @@ -325,21 +325,11 @@ class MockRenderData : public IRenderData, IUiaData return 12ul; } - COLORREF GetCursorColor() const noexcept override - { - return COLORREF{}; - } - bool IsCursorDoubleWidth() const override { return false; } - bool IsScreenReversed() const noexcept override - { - return false; - } - const std::vector GetOverlays() const noexcept override { return std::vector{}; @@ -418,7 +408,7 @@ void VtIoTests::RendererDtorAndThread() auto data = std::make_unique(); auto thread = std::make_unique(); auto* pThread = thread.get(); - auto pRenderer = std::make_unique(data.get(), nullptr, 0, std::move(thread)); + auto pRenderer = std::make_unique(RenderSettings{}, data.get(), nullptr, 0, std::move(thread)); VERIFY_SUCCEEDED(pThread->Initialize(pRenderer.get())); // Sleep for a hot sec to make sure the thread starts before we enable painting // If you don't, the thread might wait on the paint enabled event AFTER @@ -444,7 +434,7 @@ void VtIoTests::RendererDtorAndThreadAndDx() auto data = std::make_unique(); auto thread = std::make_unique(); auto* pThread = thread.get(); - auto pRenderer = std::make_unique(data.get(), nullptr, 0, std::move(thread)); + auto pRenderer = std::make_unique(RenderSettings{}, data.get(), nullptr, 0, std::move(thread)); VERIFY_SUCCEEDED(pThread->Initialize(pRenderer.get())); auto dxEngine = std::make_unique<::Microsoft::Console::Render::DxEngine>(); diff --git a/src/host/ut_host/VtRendererTests.cpp b/src/host/ut_host/VtRendererTests.cpp index 85612eebc0f..9678380e674 100644 --- a/src/host/ut_host/VtRendererTests.cpp +++ b/src/host/ut_host/VtRendererTests.cpp @@ -399,6 +399,7 @@ void VtRendererTest::Xterm256TestColors() std::unique_ptr engine = std::make_unique(std::move(hFile), SetUpViewport()); auto pfn = std::bind(&VtRendererTest::WriteCallback, this, std::placeholders::_1, std::placeholders::_2); engine->SetTestCallback(pfn); + RenderSettings renderSettings; RenderData renderData; // Verify the first paint emits a clear and go home @@ -419,6 +420,7 @@ void VtRendererTest::Xterm256TestColors() qExpectedInput.push_back("\x1b[38;2;1;2;3m"); qExpectedInput.push_back("\x1b[48;2;5;6;7m"); VERIFY_SUCCEEDED(engine->UpdateDrawingBrushes({ 0x00030201, 0x00070605 }, + renderSettings, &renderData, false, false)); @@ -428,6 +430,7 @@ void VtRendererTest::Xterm256TestColors() L"----Change only the BG----")); qExpectedInput.push_back("\x1b[48;2;7;8;9m"); VERIFY_SUCCEEDED(engine->UpdateDrawingBrushes({ 0x00030201, 0x00090807 }, + renderSettings, &renderData, false, false)); @@ -436,6 +439,7 @@ void VtRendererTest::Xterm256TestColors() L"----Change only the FG----")); qExpectedInput.push_back("\x1b[38;2;10;11;12m"); VERIFY_SUCCEEDED(engine->UpdateDrawingBrushes({ 0x000c0b0a, 0x00090807 }, + renderSettings, &renderData, false, false)); @@ -446,6 +450,7 @@ void VtRendererTest::Xterm256TestColors() L"Make sure that color setting persists across EndPaint/StartPaint")); qExpectedInput.push_back(EMPTY_CALLBACK_SENTINEL); VERIFY_SUCCEEDED(engine->UpdateDrawingBrushes({ 0x000c0b0a, 0x00090807 }, + renderSettings, &renderData, false, false)); @@ -461,6 +466,7 @@ void VtRendererTest::Xterm256TestColors() qExpectedInput.push_back("\x1b[m"); VERIFY_SUCCEEDED(engine->UpdateDrawingBrushes({}, + renderSettings, &renderData, false, false)); @@ -473,6 +479,7 @@ void VtRendererTest::Xterm256TestColors() textAttributes.SetIndexedBackground(TextColor::DARK_RED); qExpectedInput.push_back("\x1b[41m"); // Background DARK_RED VERIFY_SUCCEEDED(engine->UpdateDrawingBrushes(textAttributes, + renderSettings, &renderData, false, false)); @@ -482,6 +489,7 @@ void VtRendererTest::Xterm256TestColors() textAttributes.SetIndexedForeground(TextColor::DARK_WHITE); qExpectedInput.push_back("\x1b[37m"); // Foreground DARK_WHITE VERIFY_SUCCEEDED(engine->UpdateDrawingBrushes(textAttributes, + renderSettings, &renderData, false, false)); @@ -491,6 +499,7 @@ void VtRendererTest::Xterm256TestColors() textAttributes.SetBackground(RGB(19, 161, 14)); qExpectedInput.push_back("\x1b[48;2;19;161;14m"); // Background RGB(19,161,14) VERIFY_SUCCEEDED(engine->UpdateDrawingBrushes(textAttributes, + renderSettings, &renderData, false, false)); @@ -500,6 +509,7 @@ void VtRendererTest::Xterm256TestColors() textAttributes.SetForeground(RGB(193, 156, 0)); qExpectedInput.push_back("\x1b[38;2;193;156;0m"); // Foreground RGB(193,156,0) VERIFY_SUCCEEDED(engine->UpdateDrawingBrushes(textAttributes, + renderSettings, &renderData, false, false)); @@ -509,6 +519,7 @@ void VtRendererTest::Xterm256TestColors() textAttributes.SetDefaultBackground(); qExpectedInput.push_back("\x1b[49m"); // Background default VERIFY_SUCCEEDED(engine->UpdateDrawingBrushes(textAttributes, + renderSettings, &renderData, false, false)); @@ -518,6 +529,7 @@ void VtRendererTest::Xterm256TestColors() textAttributes.SetIndexedForeground256(TextColor::DARK_WHITE); qExpectedInput.push_back("\x1b[38;5;7m"); // Foreground DARK_WHITE (256-Color Index) VERIFY_SUCCEEDED(engine->UpdateDrawingBrushes(textAttributes, + renderSettings, &renderData, false, false)); @@ -527,6 +539,7 @@ void VtRendererTest::Xterm256TestColors() textAttributes.SetIndexedBackground256(TextColor::DARK_RED); qExpectedInput.push_back("\x1b[48;5;1m"); // Background DARK_RED (256-Color Index) VERIFY_SUCCEEDED(engine->UpdateDrawingBrushes(textAttributes, + renderSettings, &renderData, false, false)); @@ -536,6 +549,7 @@ void VtRendererTest::Xterm256TestColors() textAttributes.SetDefaultForeground(); qExpectedInput.push_back("\x1b[39m"); // Background default VERIFY_SUCCEEDED(engine->UpdateDrawingBrushes(textAttributes, + renderSettings, &renderData, false, false)); @@ -545,6 +559,7 @@ void VtRendererTest::Xterm256TestColors() textAttributes = {}; qExpectedInput.push_back("\x1b[m"); VERIFY_SUCCEEDED(engine->UpdateDrawingBrushes(textAttributes, + renderSettings, &renderData, false, false)); @@ -555,6 +570,7 @@ void VtRendererTest::Xterm256TestColors() L"Make sure that color setting persists across EndPaint/StartPaint")); qExpectedInput.push_back(EMPTY_CALLBACK_SENTINEL); VERIFY_SUCCEEDED(engine->UpdateDrawingBrushes({}, + renderSettings, &renderData, false, false)); @@ -803,6 +819,7 @@ void VtRendererTest::Xterm256TestAttributesAcrossReset() std::unique_ptr engine = std::make_unique(std::move(hFile), SetUpViewport()); auto pfn = std::bind(&VtRendererTest::WriteCallback, this, std::placeholders::_1, std::placeholders::_2); engine->SetTestCallback(pfn); + RenderSettings renderSettings; RenderData renderData; Log::Comment(L"Make sure rendition attributes are retained when colors are reset"); @@ -810,7 +827,7 @@ void VtRendererTest::Xterm256TestAttributesAcrossReset() Log::Comment(L"----Start With All Attributes Reset----"); TextAttribute textAttributes = {}; qExpectedInput.push_back("\x1b[m"); - VERIFY_SUCCEEDED(engine->UpdateDrawingBrushes(textAttributes, &renderData, false, false)); + VERIFY_SUCCEEDED(engine->UpdateDrawingBrushes(textAttributes, renderSettings, &renderData, false, false)); switch (renditionAttribute) { @@ -856,29 +873,29 @@ void VtRendererTest::Xterm256TestAttributesAcrossReset() break; } qExpectedInput.push_back(renditionSequence.str()); - VERIFY_SUCCEEDED(engine->UpdateDrawingBrushes(textAttributes, &renderData, false, false)); + VERIFY_SUCCEEDED(engine->UpdateDrawingBrushes(textAttributes, renderSettings, &renderData, false, false)); Log::Comment(L"----Set Green Foreground----"); textAttributes.SetIndexedForeground(TextColor::DARK_GREEN); qExpectedInput.push_back("\x1b[32m"); - VERIFY_SUCCEEDED(engine->UpdateDrawingBrushes(textAttributes, &renderData, false, false)); + VERIFY_SUCCEEDED(engine->UpdateDrawingBrushes(textAttributes, renderSettings, &renderData, false, false)); Log::Comment(L"----Reset Default Foreground and Retain Rendition----"); textAttributes.SetDefaultForeground(); qExpectedInput.push_back("\x1b[m"); qExpectedInput.push_back(renditionSequence.str()); - VERIFY_SUCCEEDED(engine->UpdateDrawingBrushes(textAttributes, &renderData, false, false)); + VERIFY_SUCCEEDED(engine->UpdateDrawingBrushes(textAttributes, renderSettings, &renderData, false, false)); Log::Comment(L"----Set Green Background----"); textAttributes.SetIndexedBackground(TextColor::DARK_GREEN); qExpectedInput.push_back("\x1b[42m"); - VERIFY_SUCCEEDED(engine->UpdateDrawingBrushes(textAttributes, &renderData, false, false)); + VERIFY_SUCCEEDED(engine->UpdateDrawingBrushes(textAttributes, renderSettings, &renderData, false, false)); Log::Comment(L"----Reset Default Background and Retain Rendition----"); textAttributes.SetDefaultBackground(); qExpectedInput.push_back("\x1b[m"); qExpectedInput.push_back(renditionSequence.str()); - VERIFY_SUCCEEDED(engine->UpdateDrawingBrushes(textAttributes, &renderData, false, false)); + VERIFY_SUCCEEDED(engine->UpdateDrawingBrushes(textAttributes, renderSettings, &renderData, false, false)); VerifyExpectedInputsDrained(); } @@ -1076,6 +1093,7 @@ void VtRendererTest::XtermTestColors() std::unique_ptr engine = std::make_unique(std::move(hFile), SetUpViewport(), false); auto pfn = std::bind(&VtRendererTest::WriteCallback, this, std::placeholders::_1, std::placeholders::_2); engine->SetTestCallback(pfn); + RenderSettings renderSettings; RenderData renderData; // Verify the first paint emits a clear and go home @@ -1095,6 +1113,7 @@ void VtRendererTest::XtermTestColors() qExpectedInput.push_back("\x1b[m"); VERIFY_SUCCEEDED(engine->UpdateDrawingBrushes({}, + renderSettings, &renderData, false, false)); @@ -1107,6 +1126,7 @@ void VtRendererTest::XtermTestColors() textAttributes.SetIndexedBackground(TextColor::DARK_RED); qExpectedInput.push_back("\x1b[41m"); // Background DARK_RED VERIFY_SUCCEEDED(engine->UpdateDrawingBrushes(textAttributes, + renderSettings, &renderData, false, false)); @@ -1116,6 +1136,7 @@ void VtRendererTest::XtermTestColors() textAttributes.SetIndexedForeground(TextColor::DARK_WHITE); qExpectedInput.push_back("\x1b[37m"); // Foreground DARK_WHITE VERIFY_SUCCEEDED(engine->UpdateDrawingBrushes(textAttributes, + renderSettings, &renderData, false, false)); @@ -1125,6 +1146,7 @@ void VtRendererTest::XtermTestColors() textAttributes.SetBackground(RGB(19, 161, 14)); qExpectedInput.push_back("\x1b[42m"); // Background DARK_GREEN VERIFY_SUCCEEDED(engine->UpdateDrawingBrushes(textAttributes, + renderSettings, &renderData, false, false)); @@ -1134,6 +1156,7 @@ void VtRendererTest::XtermTestColors() textAttributes.SetForeground(RGB(193, 156, 0)); qExpectedInput.push_back("\x1b[33m"); // Foreground DARK_YELLOW VERIFY_SUCCEEDED(engine->UpdateDrawingBrushes(textAttributes, + renderSettings, &renderData, false, false)); @@ -1144,6 +1167,7 @@ void VtRendererTest::XtermTestColors() qExpectedInput.push_back("\x1b[m"); // Both foreground and background default qExpectedInput.push_back("\x1b[33m"); // Reapply foreground DARK_YELLOW VERIFY_SUCCEEDED(engine->UpdateDrawingBrushes(textAttributes, + renderSettings, &renderData, false, false)); @@ -1153,6 +1177,7 @@ void VtRendererTest::XtermTestColors() textAttributes.SetIndexedForeground256(TextColor::DARK_WHITE); qExpectedInput.push_back("\x1b[37m"); // Foreground DARK_WHITE VERIFY_SUCCEEDED(engine->UpdateDrawingBrushes(textAttributes, + renderSettings, &renderData, false, false)); @@ -1162,6 +1187,7 @@ void VtRendererTest::XtermTestColors() textAttributes.SetIndexedBackground256(TextColor::DARK_RED); qExpectedInput.push_back("\x1b[41m"); // Background DARK_RED VERIFY_SUCCEEDED(engine->UpdateDrawingBrushes(textAttributes, + renderSettings, &renderData, false, false)); @@ -1172,6 +1198,7 @@ void VtRendererTest::XtermTestColors() qExpectedInput.push_back("\x1b[m"); // Both foreground and background default qExpectedInput.push_back("\x1b[41m"); // Reapply background DARK_RED VERIFY_SUCCEEDED(engine->UpdateDrawingBrushes(textAttributes, + renderSettings, &renderData, false, false)); @@ -1181,6 +1208,7 @@ void VtRendererTest::XtermTestColors() textAttributes = {}; qExpectedInput.push_back("\x1b[m"); VERIFY_SUCCEEDED(engine->UpdateDrawingBrushes(textAttributes, + renderSettings, &renderData, false, false)); @@ -1191,6 +1219,7 @@ void VtRendererTest::XtermTestColors() L"Make sure that color setting persists across EndPaint/StartPaint")); qExpectedInput.push_back(EMPTY_CALLBACK_SENTINEL); VERIFY_SUCCEEDED(engine->UpdateDrawingBrushes({}, + renderSettings, &renderData, false, false)); @@ -1323,6 +1352,7 @@ void VtRendererTest::XtermTestAttributesAcrossReset() std::unique_ptr engine = std::make_unique(std::move(hFile), SetUpViewport(), false); auto pfn = std::bind(&VtRendererTest::WriteCallback, this, std::placeholders::_1, std::placeholders::_2); engine->SetTestCallback(pfn); + RenderSettings renderSettings; RenderData renderData; Log::Comment(L"Make sure rendition attributes are retained when colors are reset"); @@ -1330,7 +1360,7 @@ void VtRendererTest::XtermTestAttributesAcrossReset() Log::Comment(L"----Start With All Attributes Reset----"); TextAttribute textAttributes = {}; qExpectedInput.push_back("\x1b[m"); - VERIFY_SUCCEEDED(engine->UpdateDrawingBrushes(textAttributes, &renderData, false, false)); + VERIFY_SUCCEEDED(engine->UpdateDrawingBrushes(textAttributes, renderSettings, &renderData, false, false)); switch (renditionAttribute) { @@ -1348,29 +1378,29 @@ void VtRendererTest::XtermTestAttributesAcrossReset() break; } qExpectedInput.push_back(renditionSequence.str()); - VERIFY_SUCCEEDED(engine->UpdateDrawingBrushes(textAttributes, &renderData, false, false)); + VERIFY_SUCCEEDED(engine->UpdateDrawingBrushes(textAttributes, renderSettings, &renderData, false, false)); Log::Comment(L"----Set Green Foreground----"); textAttributes.SetIndexedForeground(TextColor::DARK_GREEN); qExpectedInput.push_back("\x1b[32m"); - VERIFY_SUCCEEDED(engine->UpdateDrawingBrushes(textAttributes, &renderData, false, false)); + VERIFY_SUCCEEDED(engine->UpdateDrawingBrushes(textAttributes, renderSettings, &renderData, false, false)); Log::Comment(L"----Reset Default Foreground and Retain Rendition----"); textAttributes.SetDefaultForeground(); qExpectedInput.push_back("\x1b[m"); qExpectedInput.push_back(renditionSequence.str()); - VERIFY_SUCCEEDED(engine->UpdateDrawingBrushes(textAttributes, &renderData, false, false)); + VERIFY_SUCCEEDED(engine->UpdateDrawingBrushes(textAttributes, renderSettings, &renderData, false, false)); Log::Comment(L"----Set Green Background----"); textAttributes.SetIndexedBackground(TextColor::DARK_GREEN); qExpectedInput.push_back("\x1b[42m"); - VERIFY_SUCCEEDED(engine->UpdateDrawingBrushes(textAttributes, &renderData, false, false)); + VERIFY_SUCCEEDED(engine->UpdateDrawingBrushes(textAttributes, renderSettings, &renderData, false, false)); Log::Comment(L"----Reset Default Background and Retain Rendition----"); textAttributes.SetDefaultBackground(); qExpectedInput.push_back("\x1b[m"); qExpectedInput.push_back(renditionSequence.str()); - VERIFY_SUCCEEDED(engine->UpdateDrawingBrushes(textAttributes, &renderData, false, false)); + VERIFY_SUCCEEDED(engine->UpdateDrawingBrushes(textAttributes, renderSettings, &renderData, false, false)); VerifyExpectedInputsDrained(); } diff --git a/src/interactivity/onecore/BgfxEngine.cpp b/src/interactivity/onecore/BgfxEngine.cpp index 1f05709f0b5..54e1e218441 100644 --- a/src/interactivity/onecore/BgfxEngine.cpp +++ b/src/interactivity/onecore/BgfxEngine.cpp @@ -195,6 +195,7 @@ BgfxEngine::BgfxEngine(PVOID SharedViewBase, LONG DisplayHeight, LONG DisplayWid } [[nodiscard]] HRESULT BgfxEngine::UpdateDrawingBrushes(const TextAttribute& textAttributes, + const RenderSettings& /*renderSettings*/, const gsl::not_null /*pData*/, const bool /*usingSoftFont*/, bool const /*isSettingDefaultBrushes*/) noexcept diff --git a/src/interactivity/onecore/BgfxEngine.hpp b/src/interactivity/onecore/BgfxEngine.hpp index adb3b930a11..634a46fe412 100644 --- a/src/interactivity/onecore/BgfxEngine.hpp +++ b/src/interactivity/onecore/BgfxEngine.hpp @@ -59,6 +59,7 @@ namespace Microsoft::Console::Render [[nodiscard]] HRESULT PaintCursor(const CursorOptions& options) noexcept override; [[nodiscard]] HRESULT UpdateDrawingBrushes(const TextAttribute& textAttributes, + const RenderSettings& renderSettings, const gsl::not_null pData, const bool usingSoftFont, bool const isSettingDefaultBrushes) noexcept override; diff --git a/src/interactivity/win32/Clipboard.cpp b/src/interactivity/win32/Clipboard.cpp index fc10c15fd5e..e2d285795d3 100644 --- a/src/interactivity/win32/Clipboard.cpp +++ b/src/interactivity/win32/Clipboard.cpp @@ -207,9 +207,10 @@ void Clipboard::StoreSelectionToClipboard(bool const copyFormatting) const auto& gci = ServiceLocator::LocateGlobals().getConsoleInformation(); const auto& buffer = gci.GetActiveOutputBuffer().GetTextBuffer(); + const auto& renderSettings = gci.GetRenderSettings(); - const auto GetAttributeColors = [=, &gci](const auto& attr) { - return gci.LookupAttributeColors(attr); + const auto GetAttributeColors = [&](const auto& attr) { + return renderSettings.GetAttributeColors(attr); }; bool includeCRLF, trimTrailingWhitespace; @@ -277,7 +278,7 @@ void Clipboard::CopyTextToSystemClipboard(const TextBuffer::TextAndColor& rows, const auto& gci = ServiceLocator::LocateGlobals().getConsoleInformation(); const auto& fontData = gci.GetActiveOutputBuffer().GetCurrentFont(); int const iFontHeightPoints = fontData.GetUnscaledSize().Y * 72 / ServiceLocator::LocateGlobals().dpi; - const auto bgColor = gci.LookupAttributeColors({}).second; + const auto bgColor = gci.GetRenderSettings().GetAttributeColors({}).second; std::string HTMLToPlaceOnClip = TextBuffer::GenHTML(rows, iFontHeightPoints, fontData.GetFaceName(), bgColor); CopyToSystemClipboard(HTMLToPlaceOnClip, L"HTML Format"); diff --git a/src/propslib/RegistrySerialization.cpp b/src/propslib/RegistrySerialization.cpp index 4c45ba05c77..2352e068213 100644 --- a/src/propslib/RegistrySerialization.cpp +++ b/src/propslib/RegistrySerialization.cpp @@ -61,10 +61,15 @@ const RegistrySerialization::_RegPropertyMap RegistrySerialization::s_PropertyMa { _RegPropertyType::Boolean, CONSOLE_REGISTRY_INTERCEPTCOPYPASTE, SET_FIELD_AND_SIZE(_fInterceptCopyPaste) }, { _RegPropertyType::Boolean, CONSOLE_REGISTRY_TERMINALSCROLLING, SET_FIELD_AND_SIZE(_TerminalScrolling) }, { _RegPropertyType::Dword, CONSOLE_REGISTRY_USEDX, SET_FIELD_AND_SIZE(_fUseDx) }, - { _RegPropertyType::Boolean, CONSOLE_REGISTRY_COPYCOLOR, SET_FIELD_AND_SIZE(_fCopyColor) }, - { _RegPropertyType::Dword, CONSOLE_REGISTRY_DEFAULTFOREGROUND, SET_FIELD_AND_SIZE(_colorTable[TextColor::DEFAULT_FOREGROUND]) }, - { _RegPropertyType::Dword, CONSOLE_REGISTRY_DEFAULTBACKGROUND, SET_FIELD_AND_SIZE(_colorTable[TextColor::DEFAULT_BACKGROUND]) }, - { _RegPropertyType::Dword, CONSOLE_REGISTRY_CURSORCOLOR, SET_FIELD_AND_SIZE(_colorTable[TextColor::CURSOR_COLOR]) } + { _RegPropertyType::Boolean, CONSOLE_REGISTRY_COPYCOLOR, SET_FIELD_AND_SIZE(_fCopyColor) } + + // Special cases that are handled manually in Registry::LoadFromRegistry: + // - CONSOLE_REGISTRY_WINDOWPOS + // - CONSOLE_REGISTRY_CODEPAGE + // - CONSOLE_REGISTRY_COLORTABLE + // - CONSOLE_REGISTRY_DEFAULTFOREGROUND + // - CONSOLE_REGISTRY_DEFAULTBACKGROUND + // - CONSOLE_REGISTRY_CURSORCOLOR }; const size_t RegistrySerialization::s_PropertyMappingsSize = ARRAYSIZE(s_PropertyMappings); diff --git a/src/renderer/atlas/AtlasEngine.api.cpp b/src/renderer/atlas/AtlasEngine.api.cpp index ca78fd75e08..c8e9ca67b2a 100644 --- a/src/renderer/atlas/AtlasEngine.api.cpp +++ b/src/renderer/atlas/AtlasEngine.api.cpp @@ -370,10 +370,6 @@ void AtlasEngine::SetSoftwareRendering(bool enable) noexcept { } -void AtlasEngine::SetIntenseIsBold(bool enable) noexcept -{ -} - void AtlasEngine::SetWarningCallback(std::function pfn) noexcept { _api.warningCallback = std::move(pfn); diff --git a/src/renderer/atlas/AtlasEngine.cpp b/src/renderer/atlas/AtlasEngine.cpp index e294c614517..5752380c5bd 100644 --- a/src/renderer/atlas/AtlasEngine.cpp +++ b/src/renderer/atlas/AtlasEngine.cpp @@ -562,10 +562,10 @@ try } CATCH_RETURN() -[[nodiscard]] HRESULT AtlasEngine::UpdateDrawingBrushes(const TextAttribute& textAttributes, const gsl::not_null pData, const bool usingSoftFont, const bool isSettingDefaultBrushes) noexcept +[[nodiscard]] HRESULT AtlasEngine::UpdateDrawingBrushes(const TextAttribute& textAttributes, const RenderSettings& renderSettings, const gsl::not_null /*pData*/, const bool usingSoftFont, const bool isSettingDefaultBrushes) noexcept try { - const auto [fg, bg] = pData->GetAttributeColors(textAttributes); + const auto [fg, bg] = renderSettings.GetAttributeColorsWithAlpha(textAttributes); if (!isSettingDefaultBrushes) { diff --git a/src/renderer/atlas/AtlasEngine.h b/src/renderer/atlas/AtlasEngine.h index 8247e4c8cff..a9123128df4 100644 --- a/src/renderer/atlas/AtlasEngine.h +++ b/src/renderer/atlas/AtlasEngine.h @@ -43,7 +43,7 @@ namespace Microsoft::Console::Render [[nodiscard]] HRESULT PaintBufferGridLines(GridLineSet lines, COLORREF color, size_t cchLine, COORD coordTarget) noexcept override; [[nodiscard]] HRESULT PaintSelection(SMALL_RECT rect) noexcept override; [[nodiscard]] HRESULT PaintCursor(const CursorOptions& options) noexcept override; - [[nodiscard]] HRESULT UpdateDrawingBrushes(const TextAttribute& textAttributes, gsl::not_null pData, bool usingSoftFont, bool isSettingDefaultBrushes) noexcept override; + [[nodiscard]] HRESULT UpdateDrawingBrushes(const TextAttribute& textAttributes, const RenderSettings& renderSettings, gsl::not_null pData, bool usingSoftFont, bool isSettingDefaultBrushes) noexcept override; [[nodiscard]] HRESULT UpdateFont(const FontInfoDesired& FontInfoDesired, _Out_ FontInfo& FontInfo) noexcept override; [[nodiscard]] HRESULT UpdateSoftFont(gsl::span bitPattern, SIZE cellSize, size_t centeringHint) noexcept override; [[nodiscard]] HRESULT UpdateDpi(int iDpi) noexcept override; @@ -71,7 +71,6 @@ namespace Microsoft::Console::Render void SetRetroTerminalEffect(bool enable) noexcept override; void SetSelectionBackground(COLORREF color, float alpha = 0.5f) noexcept override; void SetSoftwareRendering(bool enable) noexcept override; - void SetIntenseIsBold(bool enable) noexcept override; void SetWarningCallback(std::function pfn) noexcept override; [[nodiscard]] HRESULT SetWindowSize(SIZE pixels) noexcept override; void ToggleShaderEffects() noexcept override; diff --git a/src/renderer/base/BlinkingState.cpp b/src/renderer/base/BlinkingState.cpp deleted file mode 100644 index c3f37bfb99f..00000000000 --- a/src/renderer/base/BlinkingState.cpp +++ /dev/null @@ -1,81 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT license. - -#include "precomp.h" - -#include "../inc/BlinkingState.hpp" - -using namespace Microsoft::Console::Render; - -// Method Description: -// - Updates the flag indicating whether cells with the blinking attribute -// can animate on and off. -// Arguments: -// - blinkingAllowed: true if blinking is permitted. -// Return Value: -// - -void BlinkingState::SetBlinkingAllowed(const bool blinkingAllowed) noexcept -{ - _blinkingAllowed = blinkingAllowed; - if (!_blinkingAllowed) - { - _blinkingShouldBeFaint = false; - } -} - -// Method Description: -// - Makes a record of whether the given attribute has blinking enabled or -// not, so we can determine whether the screen will need to be refreshed -// when the blinking rendition state changes. -// Arguments: -// - attr: a text attribute that is expected to be rendered. -// Return Value: -// - -void BlinkingState::RecordBlinkingUsage(const TextAttribute& attr) noexcept -{ - _blinkingIsInUse = _blinkingIsInUse || attr.IsBlinking(); -} - -// Method Description: -// - Determines whether cells with the blinking attribute should be rendered -// as normal or faint, based on the current position in the blinking cycle. -// Arguments: -// - -// Return Value: -// - True if blinking cells should be rendered as faint. -bool BlinkingState::IsBlinkingFaint() const noexcept -{ - return _blinkingShouldBeFaint; -} - -// Method Description: -// - Increments the position in the blinking cycle, toggling the blinking -// rendition state on every second call, potentially triggering a redraw of -// the given render target if there are blinking cells currently in view. -// Arguments: -// - renderTarget: the render target that will be redrawn. -// Return Value: -// - -void BlinkingState::ToggleBlinkingRendition(IRenderTarget& renderTarget) noexcept -try -{ - if (_blinkingAllowed) - { - // This method is called with the frequency of the cursor blink rate, - // but we only want our cells to blink at half that frequency. We thus - // have a blinking cycle that loops through four phases... - _blinkingCycle = (_blinkingCycle + 1) % 4; - // ... and two of those four render the blinking attributes as faint. - _blinkingShouldBeFaint = _blinkingCycle >= 2; - // Every two cycles (when the state changes), we need to trigger a - // redraw, but only if there are actually blinking attributes in use. - if (_blinkingIsInUse && _blinkingCycle % 2 == 0) - { - // We reset the _blinkingIsInUse flag before redrawing, so we can - // get a fresh assessment of the current blinking attribute usage. - _blinkingIsInUse = false; - renderTarget.TriggerRedrawAll(); - } - } -} -CATCH_LOG() diff --git a/src/renderer/base/RenderSettings.cpp b/src/renderer/base/RenderSettings.cpp new file mode 100644 index 00000000000..4b5a5f18769 --- /dev/null +++ b/src/renderer/base/RenderSettings.cpp @@ -0,0 +1,289 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +#include "precomp.h" + +#include "../inc/RenderSettings.hpp" +#include "../inc/IRenderTarget.hpp" +#include "../../types/inc/ColorFix.hpp" +#include "../../types/inc/colorTable.hpp" + +using namespace Microsoft::Console::Render; +using Microsoft::Console::Utils::InitializeColorTable; + +static constexpr size_t AdjustedFgIndex{ 16 }; +static constexpr size_t AdjustedBgIndex{ 17 }; + +RenderSettings::RenderSettings() noexcept +{ + InitializeColorTable(_colorTable); + + SetColorTableEntry(TextColor::DEFAULT_FOREGROUND, INVALID_COLOR); + SetColorTableEntry(TextColor::DEFAULT_BACKGROUND, INVALID_COLOR); + SetColorTableEntry(TextColor::CURSOR_COLOR, INVALID_COLOR); + + SetColorAliasIndex(ColorAlias::DefaultForeground, TextColor::DARK_WHITE); + SetColorAliasIndex(ColorAlias::DefaultBackground, TextColor::DARK_BLACK); +} + +// Routine Description: +// - Updates the specified render mode. +// Arguments: +// - mode - The render mode to change. +// - enabled - Set to true to enable the mode, false to disable it. +void RenderSettings::SetRenderMode(const Mode mode, const bool enabled) noexcept +{ + _renderMode.set(mode, enabled); + // If blinking is disabled, make sure blinking content is not faint. + if (mode == Mode::BlinkAllowed && !enabled) + { + _blinkShouldBeFaint = false; + } +} + +// Routine Description: +// - Retrieves the specified render mode. +// Arguments: +// - mode - The render mode to query. +// Return Value: +// - True if the mode is enabled. False if disabled. +bool RenderSettings::GetRenderMode(const Mode mode) const noexcept +{ + return _renderMode.test(mode); +} + +// Routine Description: +// - Returns a reference to the active color table array. +const std::array& RenderSettings::GetColorTable() const noexcept +{ + return _colorTable; +} + +// Routine Description: +// - Resets the first 16 color table entries with default values. +void RenderSettings::ResetColorTable() noexcept +{ + InitializeColorTable({ _colorTable.data(), 16 }); +} + +// Routine Description: +// - Creates the adjusted color array, which contains the possible foreground colors, +// adjusted for perceivability +// - The adjusted color array is 2-d, and effectively maps a background and foreground +// color pair to the adjusted foreground for that color pair +void RenderSettings::MakeAdjustedColorArray() noexcept +{ + // The color table has 16 colors, but the adjusted color table needs to be 18 + // to include the default background and default foreground colors + std::array colorTableWithDefaults; + std::copy_n(std::begin(_colorTable), 16, std::begin(colorTableWithDefaults)); + colorTableWithDefaults[AdjustedFgIndex] = GetColorAlias(ColorAlias::DefaultForeground); + colorTableWithDefaults[AdjustedBgIndex] = GetColorAlias(ColorAlias::DefaultBackground); + + for (auto fgIndex = 0; fgIndex < 18; ++fgIndex) + { + const auto fg = til::at(colorTableWithDefaults, fgIndex); + for (auto bgIndex = 0; bgIndex < 18; ++bgIndex) + { + if (fgIndex == bgIndex) + { + _adjustedForegroundColors[bgIndex][fgIndex] = fg; + } + else + { + const auto bg = til::at(colorTableWithDefaults, bgIndex); + _adjustedForegroundColors[bgIndex][fgIndex] = ColorFix::GetPerceivableColor(fg, bg); + } + } + } +} + +// Routine Description: +// - Updates the given index in the color table to a new value. +// Arguments: +// - tableIndex - The index of the color to update. +// - color - The new COLORREF to use as that color table value. +void RenderSettings::SetColorTableEntry(const size_t tableIndex, const COLORREF color) +{ + _colorTable.at(tableIndex) = color; +} + +// Routine Description: +// - Retrieves the value in the color table at the specified index. +// Arguments: +// - tableIndex - The index of the color to retrieve. +// Return Value: +// - The COLORREF value for the color at that index in the table. +COLORREF RenderSettings::GetColorTableEntry(const size_t tableIndex) const +{ + return _colorTable.at(tableIndex); +} + +// Routine Description: +// - Sets the position in the color table for the given color alias and updates the color. +// Arguments: +// - alias - The color alias to update. +// - tableIndex - The new position of the alias in the color table. +// - color - The new COLORREF to assign to that alias. +void RenderSettings::SetColorAlias(const ColorAlias alias, const size_t tableIndex, const COLORREF color) +{ + SetColorAliasIndex(alias, tableIndex); + SetColorTableEntry(tableIndex, color); +} + +// Routine Description: +// - Retrieves the value in the color table of the given color alias. +// Arguments: +// - alias - The color alias to retrieve. +// Return Value: +// - The COLORREF value of the alias. +COLORREF RenderSettings::GetColorAlias(const ColorAlias alias) const +{ + return GetColorTableEntry(GetColorAliasIndex(alias)); +} + +// Routine Description: +// - Sets the position in the color table for the given color alias. +// Arguments: +// - alias - The color alias to update. +// - tableIndex - The new position of the alias in the color table. +void RenderSettings::SetColorAliasIndex(const ColorAlias alias, const size_t tableIndex) noexcept +{ + gsl::at(_colorAliasIndices, static_cast(alias)) = tableIndex; +} + +// Routine Description: +// - Retrieves the position in the color table of the given color alias. +// Arguments: +// - alias - The color alias to retrieve. +// Return Value: +// - The position in the color table where the color is stored. +size_t RenderSettings::GetColorAliasIndex(const ColorAlias alias) const noexcept +{ + return gsl::at(_colorAliasIndices, static_cast(alias)); +} + +// Routine Description: +// - Calculates the RGB colors of a given text attribute, using the current +// color table configuration and active render settings. +// Arguments: +// - attr - The TextAttribute to retrieve the colors for. +// Return Value: +// - The color values of the attribute's foreground and background. +std::pair RenderSettings::GetAttributeColors(const TextAttribute& attr) const noexcept +{ + _blinkIsInUse = _blinkIsInUse || attr.IsBlinking(); + + const auto fgTextColor = attr.GetForeground(); + const auto bgTextColor = attr.GetBackground(); + + const auto defaultFgIndex = GetColorAliasIndex(ColorAlias::DefaultForeground); + const auto defaultBgIndex = GetColorAliasIndex(ColorAlias::DefaultBackground); + + const auto brightenFg = attr.IsBold() && GetRenderMode(Mode::IntenseIsBright); + const auto dimFg = attr.IsFaint() || (_blinkShouldBeFaint && attr.IsBlinking()); + const auto swapFgAndBg = attr.IsReverseVideo() ^ GetRenderMode(Mode::ScreenReversed); + + // We want to nudge the foreground color to make it more perceivable only for the + // default color pairs within the color table + if (GetRenderMode(Mode::DistinguishableColors) && + !dimFg && + (fgTextColor.IsDefault() || fgTextColor.IsLegacy()) && + (bgTextColor.IsDefault() || bgTextColor.IsLegacy())) + { + const auto bgIndex = bgTextColor.IsDefault() ? AdjustedBgIndex : bgTextColor.GetIndex(); + auto fgIndex = fgTextColor.IsDefault() ? AdjustedFgIndex : fgTextColor.GetIndex(); + + if (fgTextColor.IsIndex16() && (fgIndex < 8) && brightenFg) + { + // There is a special case for bold here - we need to get the bright version of the foreground color + fgIndex += 8; + } + + if (swapFgAndBg) + { + const auto fg = _adjustedForegroundColors[fgIndex][bgIndex]; + const auto bg = fgTextColor.GetColor(_colorTable, defaultFgIndex); + return { fg, bg }; + } + else + { + const auto fg = _adjustedForegroundColors[bgIndex][fgIndex]; + const auto bg = bgTextColor.GetColor(_colorTable, defaultBgIndex); + return { fg, bg }; + } + } + else + { + auto fg = fgTextColor.GetColor(_colorTable, defaultFgIndex, brightenFg); + auto bg = bgTextColor.GetColor(_colorTable, defaultBgIndex); + + if (dimFg) + { + fg = (fg >> 1) & 0x7F7F7F; // Divide foreground color components by two. + } + if (swapFgAndBg) + { + std::swap(fg, bg); + } + if (attr.IsInvisible()) + { + fg = bg; + } + + return { fg, bg }; + } +} + +// Routine Description: +// - Calculates the RGBA colors of a given text attribute, using the current +// color table configuration and active render settings. This differs from +// GetAttributeColors in that it also sets the alpha color components. +// Arguments: +// - attr - The TextAttribute to retrieve the colors for. +// Return Value: +// - The color values of the attribute's foreground and background. +std::pair RenderSettings::GetAttributeColorsWithAlpha(const TextAttribute& attr) const noexcept +{ + auto [fg, bg] = GetAttributeColors(attr); + + fg |= 0xff000000; + // We only care about alpha for the default BG (which enables acrylic) + // If the bg isn't the default bg color, or reverse video is enabled, make it fully opaque. + if (!attr.BackgroundIsDefault() || (attr.IsReverseVideo() ^ GetRenderMode(Mode::ScreenReversed)) || attr.IsInvisible()) + { + bg |= 0xff000000; + } + + return { fg, bg }; +} + +// Routine Description: +// - Increments the position in the blink cycle, toggling the blink rendition +// state on every second call, potentially triggering a redraw of the given +// render target if there are blinking cells currently in view. +// Arguments: +// - renderTarget: the render target that will be redrawn. +void RenderSettings::ToggleBlinkRendition(IRenderTarget& renderTarget) noexcept +try +{ + if (GetRenderMode(Mode::BlinkAllowed)) + { + // This method is called with the frequency of the cursor blink rate, + // but we only want our cells to blink at half that frequency. We thus + // have a blink cycle that loops through four phases... + _blinkCycle = (_blinkCycle + 1) % 4; + // ... and two of those four render the blink attributes as faint. + _blinkShouldBeFaint = _blinkCycle >= 2; + // Every two cycles (when the state changes), we need to trigger a + // redraw, but only if there are actually blink attributes in use. + if (_blinkIsInUse && _blinkCycle % 2 == 0) + { + // We reset the _blinkIsInUse flag before redrawing, so we can + // get a fresh assessment of the current blink attribute usage. + _blinkIsInUse = false; + renderTarget.TriggerRedrawAll(); + } + } +} +CATCH_LOG() diff --git a/src/renderer/base/lib/base.vcxproj b/src/renderer/base/lib/base.vcxproj index 9014520b75b..1bcfe8dddb0 100644 --- a/src/renderer/base/lib/base.vcxproj +++ b/src/renderer/base/lib/base.vcxproj @@ -10,12 +10,12 @@ - + @@ -23,7 +23,6 @@ - @@ -34,6 +33,7 @@ + diff --git a/src/renderer/base/lib/base.vcxproj.filters b/src/renderer/base/lib/base.vcxproj.filters index 562b0452c39..bda75e18fe8 100644 --- a/src/renderer/base/lib/base.vcxproj.filters +++ b/src/renderer/base/lib/base.vcxproj.filters @@ -42,7 +42,7 @@ Source Files - + Source Files @@ -80,15 +80,15 @@ Header Files - - Header Files\inc - Header Files\inc Header Files\inc + + Header Files\inc + diff --git a/src/renderer/base/renderer.cpp b/src/renderer/base/renderer.cpp index 95dd7e8ae18..41208fc0346 100644 --- a/src/renderer/base/renderer.cpp +++ b/src/renderer/base/renderer.cpp @@ -28,10 +28,12 @@ static constexpr auto renderBackoffBaseTimeMilliseconds{ 150 }; // - pEngine - The output engine for targeting each rendering frame // Return Value: // - An instance of a Renderer. -Renderer::Renderer(IRenderData* pData, +Renderer::Renderer(const RenderSettings& renderSettings, + IRenderData* pData, _In_reads_(cEngines) IRenderEngine** const rgpEngines, const size_t cEngines, std::unique_ptr thread) : + _renderSettings(renderSettings), _pData(THROW_HR_IF_NULL(E_INVALIDARG, pData)), _pThread{ std::move(thread) }, _viewport{ pData->GetViewport() } @@ -744,7 +746,7 @@ void Renderer::_PaintBufferOutputHelper(_In_ IRenderEngine* const pEngine, const COORD target, const bool lineWrapped) { - auto globalInvert{ _pData->IsScreenReversed() }; + auto globalInvert{ _renderSettings.GetRenderMode(RenderSettings::Mode::ScreenReversed) }; // If we have valid data, let's figure out how to draw it. if (it) @@ -983,7 +985,7 @@ void Renderer::_PaintBufferOutputGridLineHelper(_In_ IRenderEngine* const pEngin if (lines.any()) { // Get the current foreground color to render the lines. - const COLORREF rgb = _pData->GetAttributeColors(textAttribute).first; + const COLORREF rgb = _renderSettings.GetAttributeColors(textAttribute).first; // Draw the lines LOG_IF_FAILED(pEngine->PaintBufferGridLines(lines, rgb, cchLine, coordTarget)); } @@ -1031,7 +1033,7 @@ void Renderer::_PaintBufferOutputGridLineHelper(_In_ IRenderEngine* const pEngin // The viewport X offset is saved in the options and handled with a transform. coordCursor.Y -= view.Top; - COLORREF cursorColor = _pData->GetCursorColor(); + COLORREF cursorColor = _renderSettings.GetColorTableEntry(TextColor::CURSOR_COLOR); bool useColor = cursorColor != INVALID_COLOR; // Build up the cursor parameters including position, color, and drawing options @@ -1216,7 +1218,7 @@ void Renderer::_PaintSelection(_In_ IRenderEngine* const pEngine) { // The last color needs to be each engine's responsibility. If it's local to this function, // then on the next engine we might not update the color. - return pEngine->UpdateDrawingBrushes(textAttributes, _pData, usingSoftFont, isSettingDefaultBrushes); + return pEngine->UpdateDrawingBrushes(textAttributes, _renderSettings, _pData, usingSoftFont, isSettingDefaultBrushes); } // Routine Description: diff --git a/src/renderer/base/renderer.hpp b/src/renderer/base/renderer.hpp index 74f99f41be8..32e7d29b6d7 100644 --- a/src/renderer/base/renderer.hpp +++ b/src/renderer/base/renderer.hpp @@ -17,6 +17,7 @@ Author(s): #pragma once #include "../inc/IRenderTarget.hpp" +#include "../inc/RenderSettings.hpp" #include "thread.hpp" @@ -28,7 +29,8 @@ namespace Microsoft::Console::Render class Renderer : public IRenderTarget { public: - Renderer(IRenderData* pData, + Renderer(const RenderSettings& renderSettings, + IRenderData* pData, _In_reads_(cEngines) IRenderEngine** const pEngine, const size_t cEngines, std::unique_ptr thread); @@ -99,6 +101,7 @@ namespace Microsoft::Console::Render [[nodiscard]] std::optional _GetCursorInfo(); [[nodiscard]] HRESULT _PrepareRenderInfo(_In_ IRenderEngine* const pEngine); + const RenderSettings& _renderSettings; std::array _engines{}; IRenderData* _pData = nullptr; // Non-ownership pointer std::unique_ptr _pThread; diff --git a/src/renderer/base/sources.inc b/src/renderer/base/sources.inc index cc66054ddc6..68150be0172 100644 --- a/src/renderer/base/sources.inc +++ b/src/renderer/base/sources.inc @@ -24,12 +24,12 @@ PRECOMPILED_CXX = 1 PRECOMPILED_INCLUDE = ..\precomp.h SOURCES = \ - ..\BlinkingState.cpp \ ..\FontInfo.cpp \ ..\FontInfoBase.cpp \ ..\FontInfoDesired.cpp \ ..\FontResource.cpp \ ..\RenderEngineBase.cpp \ + ..\RenderSettings.cpp \ ..\renderer.cpp \ ..\thread.cpp \ diff --git a/src/renderer/dx/DxRenderer.cpp b/src/renderer/dx/DxRenderer.cpp index aeb23fde44d..d4a5f6ba3d4 100644 --- a/src/renderer/dx/DxRenderer.cpp +++ b/src/renderer/dx/DxRenderer.cpp @@ -94,7 +94,6 @@ DxEngine::DxEngine() : _dpi{ USER_DEFAULT_SCREEN_DPI }, _scale{ 1.0f }, _prevScale{ 1.0f }, - _intenseIsBold{ true }, _chainMode{ SwapChainMode::ForComposition }, _customLayout{}, _customRenderer{ ::Microsoft::WRL::Make() }, @@ -1036,17 +1035,6 @@ try } CATCH_LOG() -void DxEngine::SetIntenseIsBold(bool enable) noexcept -try -{ - if (_intenseIsBold != enable) - { - _intenseIsBold = enable; - LOG_IF_FAILED(InvalidateAll()); - } -} -CATCH_LOG() - HANDLE DxEngine::GetSwapChainHandle() noexcept { if (!_swapChainHandle) @@ -1922,17 +1910,19 @@ CATCH_RETURN() // - Updates the default brush colors used for drawing // Arguments: // - textAttributes - Text attributes to use for the brush color +// - renderSettings - The color table and modes required for rendering // - pData - The interface to console data structures required for rendering // - usingSoftFont - Whether we're rendering characters from a soft font // - isSettingDefaultBrushes - Lets us know that these are the default brushes to paint the swapchain background or selection // Return Value: // - S_OK or relevant DirectX error. [[nodiscard]] HRESULT DxEngine::UpdateDrawingBrushes(const TextAttribute& textAttributes, - const gsl::not_null pData, + const RenderSettings& renderSettings, + const gsl::not_null /*pData*/, const bool /*usingSoftFont*/, const bool isSettingDefaultBrushes) noexcept { - const auto [colorForeground, colorBackground] = pData->GetAttributeColors(textAttributes); + const auto [colorForeground, colorBackground] = renderSettings.GetAttributeColorsWithAlpha(textAttributes); const bool usingCleartype = _antialiasingMode == D2D1_TEXT_ANTIALIAS_MODE_CLEARTYPE; const bool usingTransparency = _defaultBackgroundIsTransparent; @@ -1972,7 +1962,7 @@ CATCH_RETURN() if (_drawingContext) { _drawingContext->forceGrayscaleAA = _ShouldForceGrayscaleAA(); - _drawingContext->useBoldFont = _intenseIsBold && textAttributes.IsBold(); + _drawingContext->useBoldFont = textAttributes.IsBold() && renderSettings.GetRenderMode(RenderSettings::Mode::IntenseIsBold); _drawingContext->useItalicFont = textAttributes.IsItalic(); } diff --git a/src/renderer/dx/DxRenderer.hpp b/src/renderer/dx/DxRenderer.hpp index 527f7776f13..e93c3f1c7c2 100644 --- a/src/renderer/dx/DxRenderer.hpp +++ b/src/renderer/dx/DxRenderer.hpp @@ -106,6 +106,7 @@ namespace Microsoft::Console::Render [[nodiscard]] HRESULT PaintCursor(const CursorOptions& options) noexcept override; [[nodiscard]] HRESULT UpdateDrawingBrushes(const TextAttribute& textAttributes, + const RenderSettings& renderSettings, const gsl::not_null pData, const bool usingSoftFont, const bool isSettingDefaultBrushes) noexcept override; @@ -129,7 +130,6 @@ namespace Microsoft::Console::Render void SetSelectionBackground(const COLORREF color, const float alpha = 0.5f) noexcept override; void SetAntialiasingMode(const D2D1_TEXT_ANTIALIAS_MODE antialiasingMode) noexcept override; void EnableTransparentBackground(const bool isTransparent) noexcept override; - void SetIntenseIsBold(const bool opacity) noexcept override; void UpdateHyperlinkHoveredId(const uint16_t hoveredId) noexcept override; @@ -258,7 +258,6 @@ namespace Microsoft::Console::Render D2D1_TEXT_ANTIALIAS_MODE _antialiasingMode; bool _defaultBackgroundIsTransparent; - bool _intenseIsBold; // DirectX constant buffers need to be a multiple of 16; align to pad the size. __declspec(align(16)) struct diff --git a/src/renderer/gdi/gdirenderer.hpp b/src/renderer/gdi/gdirenderer.hpp index 33ed8352129..6ae3b0e20ea 100644 --- a/src/renderer/gdi/gdirenderer.hpp +++ b/src/renderer/gdi/gdirenderer.hpp @@ -61,6 +61,7 @@ namespace Microsoft::Console::Render [[nodiscard]] HRESULT PaintCursor(const CursorOptions& options) noexcept override; [[nodiscard]] HRESULT UpdateDrawingBrushes(const TextAttribute& textAttributes, + const RenderSettings& renderSettings, const gsl::not_null pData, const bool usingSoftFont, const bool isSettingDefaultBrushes) noexcept override; diff --git a/src/renderer/gdi/state.cpp b/src/renderer/gdi/state.cpp index 954d55c9dd8..17b939591c2 100644 --- a/src/renderer/gdi/state.cpp +++ b/src/renderer/gdi/state.cpp @@ -268,6 +268,7 @@ GdiEngine::~GdiEngine() // - This method will set the GDI brushes in the drawing context (and update the hung-window background color) // Arguments: // - textAttributes - Text attributes to use for the brush color +// - renderSettings - The color table and modes required for rendering // - pData - The interface to console data structures required for rendering // - usingSoftFont - Whether we're rendering characters from a soft font // - isSettingDefaultBrushes - Lets us know that the default brushes are being set so we can update the DC background @@ -275,7 +276,8 @@ GdiEngine::~GdiEngine() // Return Value: // - S_OK if set successfully or relevant GDI error via HRESULT. [[nodiscard]] HRESULT GdiEngine::UpdateDrawingBrushes(const TextAttribute& textAttributes, - const gsl::not_null pData, + const RenderSettings& renderSettings, + const gsl::not_null /*pData*/, const bool usingSoftFont, const bool isSettingDefaultBrushes) noexcept { @@ -284,7 +286,7 @@ GdiEngine::~GdiEngine() RETURN_HR_IF_NULL(HRESULT_FROM_WIN32(ERROR_INVALID_STATE), _hdcMemoryContext); // Set the colors for painting text - const auto [colorForeground, colorBackground] = pData->GetAttributeColors(textAttributes); + const auto [colorForeground, colorBackground] = renderSettings.GetAttributeColors(textAttributes); if (colorForeground != _lastFg) { diff --git a/src/renderer/inc/BlinkingState.hpp b/src/renderer/inc/BlinkingState.hpp deleted file mode 100644 index 17ff2504c35..00000000000 --- a/src/renderer/inc/BlinkingState.hpp +++ /dev/null @@ -1,37 +0,0 @@ -/*++ -Copyright (c) Microsoft Corporation -Licensed under the MIT license. - -Module Name: -- BlinkingState.hpp - -Abstract: -- This serves as a structure holding the state of the blinking rendition. - -- It tracks the position in the blinking cycle, which determines whether any - blinking cells should be rendered as on or off/faint. It also records whether - blinking attributes are actually in use or not, so we can decide whether the - screen needs to be refreshed when the blinking cycle changes. ---*/ - -#pragma once - -#include "IRenderTarget.hpp" - -namespace Microsoft::Console::Render -{ - class BlinkingState - { - public: - void SetBlinkingAllowed(const bool blinkingAllowed) noexcept; - void RecordBlinkingUsage(const TextAttribute& attr) noexcept; - bool IsBlinkingFaint() const noexcept; - void ToggleBlinkingRendition(IRenderTarget& renderTarget) noexcept; - - private: - bool _blinkingAllowed = true; - size_t _blinkingCycle = 0; - bool _blinkingIsInUse = false; - bool _blinkingShouldBeFaint = false; - }; -} diff --git a/src/renderer/inc/IRenderData.hpp b/src/renderer/inc/IRenderData.hpp index 4020e1a0827..6e4f1b9183f 100644 --- a/src/renderer/inc/IRenderData.hpp +++ b/src/renderer/inc/IRenderData.hpp @@ -52,11 +52,8 @@ namespace Microsoft::Console::Render virtual ULONG GetCursorHeight() const noexcept = 0; virtual CursorType GetCursorStyle() const noexcept = 0; virtual ULONG GetCursorPixelWidth() const noexcept = 0; - virtual COLORREF GetCursorColor() const noexcept = 0; virtual bool IsCursorDoubleWidth() const = 0; - virtual bool IsScreenReversed() const noexcept = 0; - virtual const std::vector GetOverlays() const noexcept = 0; virtual const bool IsGridLineDrawingAllowed() noexcept = 0; diff --git a/src/renderer/inc/IRenderEngine.hpp b/src/renderer/inc/IRenderEngine.hpp index c3aa8000fbc..85be8e90e8c 100644 --- a/src/renderer/inc/IRenderEngine.hpp +++ b/src/renderer/inc/IRenderEngine.hpp @@ -20,6 +20,7 @@ Author(s): #include "Cluster.hpp" #include "FontInfoDesired.hpp" #include "IRenderData.hpp" +#include "RenderSettings.hpp" #include "../../buffer/out/LineRendition.hpp" #pragma warning(push) @@ -76,7 +77,7 @@ namespace Microsoft::Console::Render [[nodiscard]] virtual HRESULT PaintBufferGridLines(GridLineSet lines, COLORREF color, size_t cchLine, COORD coordTarget) noexcept = 0; [[nodiscard]] virtual HRESULT PaintSelection(SMALL_RECT rect) noexcept = 0; [[nodiscard]] virtual HRESULT PaintCursor(const CursorOptions& options) noexcept = 0; - [[nodiscard]] virtual HRESULT UpdateDrawingBrushes(const TextAttribute& textAttributes, gsl::not_null pData, bool usingSoftFont, bool isSettingDefaultBrushes) noexcept = 0; + [[nodiscard]] virtual HRESULT UpdateDrawingBrushes(const TextAttribute& textAttributes, const RenderSettings& renderSettings, gsl::not_null pData, bool usingSoftFont, bool isSettingDefaultBrushes) noexcept = 0; [[nodiscard]] virtual HRESULT UpdateFont(const FontInfoDesired& FontInfoDesired, _Out_ FontInfo& FontInfo) noexcept = 0; [[nodiscard]] virtual HRESULT UpdateSoftFont(gsl::span bitPattern, SIZE cellSize, size_t centeringHint) noexcept = 0; [[nodiscard]] virtual HRESULT UpdateDpi(int iDpi) noexcept = 0; @@ -111,7 +112,6 @@ namespace Microsoft::Console::Render virtual void SetRetroTerminalEffect(bool enable) noexcept {} virtual void SetSelectionBackground(const COLORREF color, const float alpha = 0.5f) noexcept {} virtual void SetSoftwareRendering(bool enable) noexcept {} - virtual void SetIntenseIsBold(bool enable) noexcept {} virtual void SetWarningCallback(std::function pfn) noexcept {} virtual [[nodiscard]] HRESULT SetWindowSize(const SIZE pixels) noexcept { return E_NOTIMPL; } virtual void ToggleShaderEffects() noexcept {} diff --git a/src/renderer/inc/RenderSettings.hpp b/src/renderer/inc/RenderSettings.hpp new file mode 100644 index 00000000000..d90283c9f6f --- /dev/null +++ b/src/renderer/inc/RenderSettings.hpp @@ -0,0 +1,55 @@ +/*++ +Copyright (c) Microsoft Corporation +Licensed under the MIT license. + +Module Name: +- RenderSettings.hpp + +Abstract: +- This class manages the runtime settings that are relevant to the renderer. +--*/ + +#pragma once + +#include "../../buffer/out/TextAttribute.hpp" + +namespace Microsoft::Console::Render +{ + class RenderSettings + { + public: + enum class Mode : size_t + { + BlinkAllowed, + DistinguishableColors, + IntenseIsBold, + IntenseIsBright, + ScreenReversed + }; + + RenderSettings() noexcept; + void SetRenderMode(const Mode mode, const bool enabled) noexcept; + bool GetRenderMode(const Mode mode) const noexcept; + const std::array& GetColorTable() const noexcept; + void ResetColorTable() noexcept; + void MakeAdjustedColorArray() noexcept; + void SetColorTableEntry(const size_t tableIndex, const COLORREF color); + COLORREF GetColorTableEntry(const size_t tableIndex) const; + void SetColorAlias(const ColorAlias alias, const size_t tableIndex, const COLORREF color); + COLORREF GetColorAlias(const ColorAlias alias) const; + void SetColorAliasIndex(const ColorAlias alias, const size_t tableIndex) noexcept; + size_t GetColorAliasIndex(const ColorAlias alias) const noexcept; + std::pair GetAttributeColors(const TextAttribute& attr) const noexcept; + std::pair GetAttributeColorsWithAlpha(const TextAttribute& attr) const noexcept; + void ToggleBlinkRendition(class IRenderTarget& renderTarget) noexcept; + + private: + til::enumset _renderMode{ Mode::BlinkAllowed, Mode::IntenseIsBright }; + std::array _colorTable; + std::array(ColorAlias::ENUM_COUNT)> _colorAliasIndices; + std::array, 18> _adjustedForegroundColors; + size_t _blinkCycle = 0; + mutable bool _blinkIsInUse = false; + bool _blinkShouldBeFaint = false; + }; +} diff --git a/src/renderer/uia/UiaRenderer.cpp b/src/renderer/uia/UiaRenderer.cpp index 9424501538c..2d0f1580ae9 100644 --- a/src/renderer/uia/UiaRenderer.cpp +++ b/src/renderer/uia/UiaRenderer.cpp @@ -370,12 +370,14 @@ void UiaEngine::WaitUntilCanRender() noexcept // For UIA, this doesn't mean anything. So do nothing. // Arguments: // - textAttributes - +// - renderSettings - // - pData - // - usingSoftFont - // - isSettingDefaultBrushes - // Return Value: // - S_FALSE since we do nothing [[nodiscard]] HRESULT UiaEngine::UpdateDrawingBrushes(const TextAttribute& /*textAttributes*/, + const RenderSettings& /*renderSettings*/, const gsl::not_null /*pData*/, const bool /*usingSoftFont*/, const bool /*isSettingDefaultBrushes*/) noexcept diff --git a/src/renderer/uia/UiaRenderer.hpp b/src/renderer/uia/UiaRenderer.hpp index d660fe7138e..1f5d1ecfe9d 100644 --- a/src/renderer/uia/UiaRenderer.hpp +++ b/src/renderer/uia/UiaRenderer.hpp @@ -52,7 +52,7 @@ namespace Microsoft::Console::Render [[nodiscard]] HRESULT PaintBufferGridLines(const GridLineSet lines, const COLORREF color, const size_t cchLine, const COORD coordTarget) noexcept override; [[nodiscard]] HRESULT PaintSelection(const SMALL_RECT rect) noexcept override; [[nodiscard]] HRESULT PaintCursor(const CursorOptions& options) noexcept override; - [[nodiscard]] HRESULT UpdateDrawingBrushes(const TextAttribute& textAttributes, const gsl::not_null pData, const bool usingSoftFont, const bool isSettingDefaultBrushes) noexcept override; + [[nodiscard]] HRESULT UpdateDrawingBrushes(const TextAttribute& textAttributes, const RenderSettings& renderSettings, const gsl::not_null pData, const bool usingSoftFont, const bool isSettingDefaultBrushes) noexcept override; [[nodiscard]] HRESULT UpdateFont(const FontInfoDesired& FontInfoDesired, _Out_ FontInfo& FontInfo) noexcept override; [[nodiscard]] HRESULT UpdateDpi(const int iDpi) noexcept override; [[nodiscard]] HRESULT UpdateViewport(const SMALL_RECT srNewViewport) noexcept override; diff --git a/src/renderer/vt/Xterm256Engine.cpp b/src/renderer/vt/Xterm256Engine.cpp index 4edece71563..791cfe6690d 100644 --- a/src/renderer/vt/Xterm256Engine.cpp +++ b/src/renderer/vt/Xterm256Engine.cpp @@ -19,6 +19,7 @@ Xterm256Engine::Xterm256Engine(_In_ wil::unique_hfile hPipe, // color sequences. // Arguments: // - textAttributes - Text attributes to use for the colors and character rendition +// - renderSettings - The color table and modes required for rendering // - pData - The interface to console data structures required for rendering // - usingSoftFont - Whether we're rendering characters from a soft font // - isSettingDefaultBrushes: indicates if we should change the background color of @@ -26,6 +27,7 @@ Xterm256Engine::Xterm256Engine(_In_ wil::unique_hfile hPipe, // Return Value: // - S_OK if we succeeded, else an appropriate HRESULT for failing to allocate or write. [[nodiscard]] HRESULT Xterm256Engine::UpdateDrawingBrushes(const TextAttribute& textAttributes, + const RenderSettings& /*renderSettings*/, const gsl::not_null pData, const bool /*usingSoftFont*/, const bool /*isSettingDefaultBrushes*/) noexcept diff --git a/src/renderer/vt/Xterm256Engine.hpp b/src/renderer/vt/Xterm256Engine.hpp index 4e5913e07e1..5c8cde61831 100644 --- a/src/renderer/vt/Xterm256Engine.hpp +++ b/src/renderer/vt/Xterm256Engine.hpp @@ -29,6 +29,7 @@ namespace Microsoft::Console::Render virtual ~Xterm256Engine() override = default; [[nodiscard]] HRESULT UpdateDrawingBrushes(const TextAttribute& textAttributes, + const RenderSettings& renderSettings, const gsl::not_null pData, const bool usingSoftFont, const bool isSettingDefaultBrushes) noexcept override; diff --git a/src/renderer/vt/XtermEngine.cpp b/src/renderer/vt/XtermEngine.cpp index e78812db026..4b3807df270 100644 --- a/src/renderer/vt/XtermEngine.cpp +++ b/src/renderer/vt/XtermEngine.cpp @@ -136,6 +136,7 @@ XtermEngine::XtermEngine(_In_ wil::unique_hfile hPipe, // 16-color attributes. // Arguments: // - textAttributes - Text attributes to use for the colors and character rendition +// - renderSettings - The color table and modes required for rendering // - pData - The interface to console data structures required for rendering // - usingSoftFont - Whether we're rendering characters from a soft font // - isSettingDefaultBrushes: indicates if we should change the background color of @@ -143,6 +144,7 @@ XtermEngine::XtermEngine(_In_ wil::unique_hfile hPipe, // Return Value: // - S_OK if we succeeded, else an appropriate HRESULT for failing to allocate or write. [[nodiscard]] HRESULT XtermEngine::UpdateDrawingBrushes(const TextAttribute& textAttributes, + const RenderSettings& /*renderSettings*/, const gsl::not_null /*pData*/, const bool /*usingSoftFont*/, const bool /*isSettingDefaultBrushes*/) noexcept diff --git a/src/renderer/vt/XtermEngine.hpp b/src/renderer/vt/XtermEngine.hpp index a46458ad64e..1cda1782710 100644 --- a/src/renderer/vt/XtermEngine.hpp +++ b/src/renderer/vt/XtermEngine.hpp @@ -39,6 +39,7 @@ namespace Microsoft::Console::Render [[nodiscard]] HRESULT PaintCursor(const CursorOptions& options) noexcept override; [[nodiscard]] virtual HRESULT UpdateDrawingBrushes(const TextAttribute& textAttributes, + const RenderSettings& renderSettings, const gsl::not_null pData, const bool usingSoftFont, const bool isSettingDefaultBrushes) noexcept override; diff --git a/src/renderer/wddmcon/WddmConRenderer.cpp b/src/renderer/wddmcon/WddmConRenderer.cpp index ae99e9e6c15..b52404fef3a 100644 --- a/src/renderer/wddmcon/WddmConRenderer.cpp +++ b/src/renderer/wddmcon/WddmConRenderer.cpp @@ -306,6 +306,7 @@ bool WddmConEngine::IsInitialized() } [[nodiscard]] HRESULT WddmConEngine::UpdateDrawingBrushes(const TextAttribute& textAttributes, + const RenderSettings& /*renderSettings*/, const gsl::not_null /*pData*/, const bool /*usingSoftFont*/, bool const /*isSettingDefaultBrushes*/) noexcept diff --git a/src/renderer/wddmcon/WddmConRenderer.hpp b/src/renderer/wddmcon/WddmConRenderer.hpp index 3d7d3ccb134..4a8bf83ef47 100644 --- a/src/renderer/wddmcon/WddmConRenderer.hpp +++ b/src/renderer/wddmcon/WddmConRenderer.hpp @@ -51,6 +51,7 @@ namespace Microsoft::Console::Render [[nodiscard]] HRESULT PaintCursor(const CursorOptions& options) noexcept override; [[nodiscard]] HRESULT UpdateDrawingBrushes(const TextAttribute& textAttributes, + const RenderSettings& renderSettings, const gsl::not_null pData, const bool usingSoftFont, bool const isSettingDefaultBrushes) noexcept override; diff --git a/src/terminal/adapter/adaptDispatch.cpp b/src/terminal/adapter/adaptDispatch.cpp index af1f4d62822..c58ede1860e 100644 --- a/src/terminal/adapter/adaptDispatch.cpp +++ b/src/terminal/adapter/adaptDispatch.cpp @@ -11,6 +11,7 @@ #include "../parser/ascii.hpp" using namespace Microsoft::Console::Types; +using namespace Microsoft::Console::Render; using namespace Microsoft::Console::VirtualTerminal; // Routine Description: @@ -1270,7 +1271,7 @@ bool AdaptDispatch::SetScreenMode(const bool reverseMode) return false; } - return _pConApi->PrivateSetScreenMode(reverseMode); + return _pConApi->SetRenderMode(RenderSettings::Mode::ScreenReversed, reverseMode); } // Routine Description: @@ -2245,11 +2246,6 @@ bool AdaptDispatch::SetCursorStyle(const DispatchTypes::CursorStyle cursorStyle) // True if handled successfully. False otherwise. bool AdaptDispatch::SetCursorColor(const COLORREF cursorColor) { - if (_pConApi->IsConsolePty()) - { - return false; - } - return _pConApi->SetColorTableEntry(TextColor::CURSOR_COLOR, cursorColor); } @@ -2273,18 +2269,7 @@ bool AdaptDispatch::SetClipboard(const std::wstring_view /*content*/) noexcept // True if handled successfully. False otherwise. bool AdaptDispatch::SetColorTableEntry(const size_t tableIndex, const DWORD dwColor) { - const bool success = _pConApi->SetColorTableEntry(tableIndex, dwColor); - - // If we're a conpty, always return false, so that we send the updated color - // value to the terminal. Still handle the sequence so apps that use - // the API or VT to query the values of the color table still read the - // correct color. - if (_pConApi->IsConsolePty()) - { - return false; - } - - return success; + return _pConApi->SetColorTableEntry(tableIndex, dwColor); } // Method Description: @@ -2295,19 +2280,8 @@ bool AdaptDispatch::SetColorTableEntry(const size_t tableIndex, const DWORD dwCo // True if handled successfully. False otherwise. bool AdaptDispatch::SetDefaultForeground(const DWORD dwColor) { - bool success = true; - success = _pConApi->SetColorTableEntry(TextColor::DEFAULT_FOREGROUND, dwColor); - - // If we're a conpty, always return false, so that we send the updated color - // value to the terminal. Still handle the sequence so apps that use - // the API or VT to query the values of the color table still read the - // correct color. - if (_pConApi->IsConsolePty()) - { - return false; - } - - return success; + _pConApi->SetColorAliasIndex(ColorAlias::DefaultForeground, TextColor::DEFAULT_FOREGROUND); + return _pConApi->SetColorTableEntry(TextColor::DEFAULT_FOREGROUND, dwColor); } // Method Description: @@ -2318,19 +2292,8 @@ bool AdaptDispatch::SetDefaultForeground(const DWORD dwColor) // True if handled successfully. False otherwise. bool AdaptDispatch::SetDefaultBackground(const DWORD dwColor) { - bool success = true; - success = _pConApi->SetColorTableEntry(TextColor::DEFAULT_BACKGROUND, dwColor); - - // If we're a conpty, always return false, so that we send the updated color - // value to the terminal. Still handle the sequence so apps that use - // the API or VT to query the values of the color table still read the - // correct color. - if (_pConApi->IsConsolePty()) - { - return false; - } - - return success; + _pConApi->SetColorAliasIndex(ColorAlias::DefaultBackground, TextColor::DEFAULT_BACKGROUND); + return _pConApi->SetColorTableEntry(TextColor::DEFAULT_BACKGROUND, dwColor); } //Routine Description: diff --git a/src/terminal/adapter/conGetSet.hpp b/src/terminal/adapter/conGetSet.hpp index 1c975e2d42d..aa4d14aefbd 100644 --- a/src/terminal/adapter/conGetSet.hpp +++ b/src/terminal/adapter/conGetSet.hpp @@ -20,6 +20,7 @@ Author(s): #include "../../types/inc/IInputEvent.hpp" #include "../../buffer/out/LineRendition.hpp" #include "../../buffer/out/TextAttribute.hpp" +#include "../../renderer/inc/RenderSettings.hpp" #include "../../inc/conattrs.hpp" #include @@ -29,6 +30,8 @@ namespace Microsoft::Console::VirtualTerminal { class ConGetSet { + using RenderSettings = Microsoft::Console::Render::RenderSettings; + public: virtual ~ConGetSet() = default; virtual bool GetConsoleScreenBufferInfoEx(CONSOLE_SCREEN_BUFFER_INFOEX& screenBufferInfo) const = 0; @@ -52,8 +55,8 @@ namespace Microsoft::Console::VirtualTerminal virtual bool SetInputMode(const TerminalInput::Mode mode, const bool enabled) = 0; virtual bool SetParserMode(const StateMachine::Mode mode, const bool enabled) = 0; virtual bool GetParserMode(const StateMachine::Mode mode) const = 0; + virtual bool SetRenderMode(const RenderSettings::Mode mode, const bool enabled) = 0; - virtual bool PrivateSetScreenMode(const bool reverseMode) = 0; virtual bool PrivateSetAutoWrapMode(const bool wrapAtEOL) = 0; virtual bool PrivateShowCursor(const bool show) = 0; @@ -88,6 +91,7 @@ namespace Microsoft::Console::VirtualTerminal virtual COLORREF GetColorTableEntry(const size_t tableIndex) const = 0; virtual bool SetColorTableEntry(const size_t tableIndex, const COLORREF color) = 0; + virtual void SetColorAliasIndex(const ColorAlias alias, const size_t tableIndex) = 0; virtual bool PrivateFillRegion(const COORD startPosition, const size_t fillLength, diff --git a/src/terminal/adapter/ut_adapter/adapterTest.cpp b/src/terminal/adapter/ut_adapter/adapterTest.cpp index bd330088c1c..a735d4b52ad 100644 --- a/src/terminal/adapter/ut_adapter/adapterTest.cpp +++ b/src/terminal/adapter/ut_adapter/adapterTest.cpp @@ -145,11 +145,11 @@ class TestGetSet final : public ConGetSet return false; } - bool PrivateSetScreenMode(const bool /*reverseMode*/) override + bool SetRenderMode(const RenderSettings::Mode /*mode*/, const bool /*enabled*/) override { - Log::Comment(L"PrivateSetScreenMode MOCK called..."); + Log::Comment(L"SetRenderMode MOCK called..."); - return true; + return false; } bool PrivateSetAutoWrapMode(const bool /*wrapAtEOL*/) override @@ -455,6 +455,11 @@ class TestGetSet final : public ConGetSet return _setColorTableEntryResult; } + void SetColorAliasIndex(const ColorAlias /*alias*/, const size_t /*tableIndex*/) noexcept override + { + Log::Comment(L"SetColorAliasIndex MOCK called..."); + } + bool PrivateFillRegion(const COORD /*startPosition*/, const size_t /*fillLength*/, const wchar_t /*fillChar*/, @@ -2368,12 +2373,6 @@ class AdapterTest _testGetSet->_expectedColorTableIndex = i; VERIFY_IS_TRUE(_pDispatch.get()->SetColorTableEntry(i, testColor)); } - - // Test in pty mode - we should fail, but SetColorTableEntry should still be called - _testGetSet->_isPty = true; - - _testGetSet->_expectedColorTableIndex = 15; // Windows BRIGHT_WHITE - VERIFY_IS_FALSE(_pDispatch.get()->SetColorTableEntry(15, testColor)); } TEST_METHOD(SoftFontSizeDetection) diff --git a/src/cascadia/TerminalCore/ColorFix.cpp b/src/types/ColorFix.cpp similarity index 91% rename from src/cascadia/TerminalCore/ColorFix.cpp rename to src/types/ColorFix.cpp index 577cfe41871..d1bef88c8ae 100644 --- a/src/cascadia/TerminalCore/ColorFix.cpp +++ b/src/types/ColorFix.cpp @@ -5,10 +5,9 @@ // https://github.com/Maximus5/ConEmu/blob/master/src/ConEmu/ColorFix.cpp // and then adjusted to fit our style guidelines -#include "pch.h" +#include "precomp.h" -#include -#include "ColorFix.hpp" +#include "inc/ColorFix.hpp" static constexpr double gMinThreshold = 12.0; static constexpr double gExpThreshold = 20.0; @@ -23,7 +22,7 @@ static constexpr double rad180 = 3.141592653589793238; static constexpr double rad275 = 4.799655442984406336; static constexpr double rad360 = 6.283185307179586476; -ColorFix::ColorFix(COLORREF color) +ColorFix::ColorFix(COLORREF color) noexcept { rgb = color; _ToLab(); @@ -31,7 +30,7 @@ ColorFix::ColorFix(COLORREF color) // Method Description: // - Helper function to calculate HPrime -double ColorFix::_GetHPrimeFn(double x, double y) +double ColorFix::_GetHPrimeFn(double x, double y) noexcept { if (x == 0 && y == 0) { @@ -49,7 +48,7 @@ double ColorFix::_GetHPrimeFn(double x, double y) // - x2: the second color // Return Value: // - The DeltaE value between x1 and x2 -double ColorFix::_GetDeltaE(ColorFix x1, ColorFix x2) +double ColorFix::_GetDeltaE(ColorFix x1, ColorFix x2) noexcept { constexpr double kSubL = 1; constexpr double kSubC = 1; @@ -125,7 +124,7 @@ double ColorFix::_GetDeltaE(ColorFix x1, ColorFix x2) // - Populates our L, A, B values, based on our r, g, b values // - Converts a color in rgb format to a color in lab format // - Reference: http://www.easyrgb.com/index.php?X=MATH&H=01#text1 -void ColorFix::_ToLab() +void ColorFix::_ToLab() noexcept { double var_R = r / 255.0; double var_G = g / 255.0; @@ -171,9 +170,9 @@ void ColorFix::_ToRGB() var_X = (pow(var_X, 3) > 0.008856) ? pow(var_X, 3) : (var_X - 16. / 116.) / 7.787; var_Z = (pow(var_Z, 3) > 0.008856) ? pow(var_Z, 3) : (var_Z - 16. / 116.) / 7.787; - double X = 95.047 * var_X; //ref_X = 95.047 (Observer= 2 degrees, Illuminant= D65) - double Y = 100.000 * var_Y; //ref_Y = 100.000 - double Z = 108.883 * var_Z; //ref_Z = 108.883 + const double X = 95.047 * var_X; //ref_X = 95.047 (Observer= 2 degrees, Illuminant= D65) + const double Y = 100.000 * var_Y; //ref_Y = 100.000 + const double Z = 108.883 * var_Z; //ref_Z = 108.883 var_X = X / 100.; //X from 0 to 95.047 (Observer = 2 degrees, Illuminant = D65) var_Y = Y / 100.; //Y from 0 to 100.000 @@ -202,7 +201,7 @@ void ColorFix::_ToRGB() // - The foreground color after performing any necessary changes to make it more perceivable COLORREF ColorFix::GetPerceivableColor(COLORREF fg, COLORREF bg) { - ColorFix backLab(bg); + const ColorFix backLab(bg); ColorFix frontLab(fg); const double de1 = _GetDeltaE(frontLab, backLab); if (de1 < gMinThreshold) diff --git a/src/types/IBaseData.h b/src/types/IBaseData.h index 6b9f8b722f7..58804c38269 100644 --- a/src/types/IBaseData.h +++ b/src/types/IBaseData.h @@ -37,7 +37,6 @@ namespace Microsoft::Console::Types virtual COORD GetTextBufferEndPosition() const noexcept = 0; virtual const TextBuffer& GetTextBuffer() noexcept = 0; virtual const FontInfo& GetFontInfo() noexcept = 0; - virtual std::pair GetAttributeColors(const TextAttribute& attr) const noexcept = 0; virtual std::vector GetSelectionRects() noexcept = 0; diff --git a/src/types/IUiaData.h b/src/types/IUiaData.h index a1ea9990b7c..de89520c72f 100644 --- a/src/types/IUiaData.h +++ b/src/types/IUiaData.h @@ -33,6 +33,7 @@ namespace Microsoft::Console::Types IUiaData& operator=(IUiaData&&) = default; public: + virtual std::pair GetAttributeColors(const TextAttribute& attr) const noexcept = 0; virtual const bool IsSelectionActive() const = 0; virtual const bool IsBlockSelection() const = 0; virtual void ClearSelection() = 0; diff --git a/src/cascadia/TerminalCore/ColorFix.hpp b/src/types/inc/ColorFix.hpp similarity index 75% rename from src/cascadia/TerminalCore/ColorFix.hpp rename to src/types/inc/ColorFix.hpp index aa32ecebd6b..c926fee3a28 100644 --- a/src/cascadia/TerminalCore/ColorFix.hpp +++ b/src/types/inc/ColorFix.hpp @@ -21,7 +21,7 @@ Author(s): struct ColorFix { public: - ColorFix(COLORREF color); + ColorFix(COLORREF color) noexcept; static COLORREF GetPerceivableColor(COLORREF fg, COLORREF bg); @@ -42,8 +42,8 @@ struct ColorFix }; private: - static double _GetHPrimeFn(double x, double y); - static double _GetDeltaE(ColorFix x1, ColorFix x2); - void _ToLab(); + static double _GetHPrimeFn(double x, double y) noexcept; + static double _GetDeltaE(ColorFix x1, ColorFix x2) noexcept; + void _ToLab() noexcept; void _ToRGB(); }; diff --git a/src/types/lib/types.vcxproj b/src/types/lib/types.vcxproj index 83fcbf96131..bebe7059a3d 100644 --- a/src/types/lib/types.vcxproj +++ b/src/types/lib/types.vcxproj @@ -11,6 +11,7 @@ + @@ -40,6 +41,7 @@ + diff --git a/src/types/lib/types.vcxproj.filters b/src/types/lib/types.vcxproj.filters index 9c7fb4b3890..c547708c049 100644 --- a/src/types/lib/types.vcxproj.filters +++ b/src/types/lib/types.vcxproj.filters @@ -15,6 +15,9 @@ + + Source Files + Source Files @@ -92,6 +95,9 @@ Header Files + + Header Files + Header Files diff --git a/src/types/sources.inc b/src/types/sources.inc index 601ecf3a194..701bc9861b9 100644 --- a/src/types/sources.inc +++ b/src/types/sources.inc @@ -29,6 +29,7 @@ PRECOMPILED_INCLUDE = ..\precomp.h SOURCES= \ ..\CodepointWidthDetector.cpp \ + ..\ColorFix.cpp \ ..\IInputEvent.cpp \ ..\FocusEvent.cpp \ ..\GlyphWidth.cpp \