Repository: microsoft/terminal (language: cpp)

Issue:
Introduce a shared class for managing render settings
# Description of the new feature/enhancement

This is the final stage of the color table refactoring that I started in #11602 and #11784. What I would like to do now is move the color table and related render settings into a new class that can be shared between conhost and Windows Terminal. This would deduplicate some code that is used in both places, and hopefully make things easier to extend in the future.

An additional benefit is that we can pass a reference to this class into the renderer, so the render engines have direct access to this information, instead of having to lookup colors and render modes via the `IRenderData` interface. Considering the overhead of the virtual function calls, I'm hoping this should make things a little more efficient.

# Proposed technical implementation details (optional)

As I mentioned above, we would have a new class for maintaining what I refer to as `RenderSettings`. Initially this would hold the color table, and the properties needed to calculate the colors for a given `TextAttribute` (i.e. things like `_screenReversed`, `_intenseIsBright`, `_adjustIndistinguishableColors`, `_blinkingState`). Over time we can probably add more to it though.

In Windows Terminal you'd have an instance of this class in the `Terminal` class, and in conhost it would be in the `Settings` class. In both cases, a reference to that instance would be passed in to the `Renderer` class when it's constructed. The renderer in turn can pass that on to the render engines when required.

I'd also like to take this opportunity to introduce the concept of "render modes", and have the boolean properties like `_screenReversed` and `_intenseIsBright` stored in a `til::enumset`. This would make it easier to manage them via the VT mode sequences, and allow for the addition of more modes in the future without introducing a lot of boilerplate code.

The other concept I'd like to introduce is that of "color aliases", which would manage the mapping of special colors like "default foreground" to index positions in the color table. For now this is only needed for the default foreground and background, but in time I'd like to add more (e.g. the bold color proposed in #11939) so it would be good to get a framework in place that's easy to extend.


Discussion / hints:

Fix patch:
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<COLORREF, COLORREF> TextAttribute::CalculateRgbColors(const std::array<COLORREF, TextColor::TABLE_SIZE>& 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<COLORREF, COLORREF> CalculateRgbColors(const std::array<COLORREF, TextColor::TABLE_SIZE>& 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<COLORREF, TextColor::TABLE_SIZE> _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 @@
     </ClCompile>
   </ItemGroup>
   <ItemGroup>
+    <ProjectReference Include="..\..\..\renderer\base\lib\base.vcxproj">
+      <Project>{af0a096a-8b3a-4949-81ef-7df8f0fee91f}</Project>
+    </ProjectReference>
     <ProjectReference Include="..\..\..\types\lib\types.vcxproj">
       <Project>{18d09a24-8240-42d6-8cb6-236eee820263}</Project>
     </ProjectReference>
diff --git a/src/cascadia/PublicTerminalCore/HwndTerminal.cpp b/src/cascadia/PublicTerminalCore/HwndTerminal.cpp
index 7ce785831bd..e98e4a1e503 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 7ec3056a6ab..bf4f78d7fd6 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();
         }
     }
@@ -1112,7 +1111,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:
@@ -1398,8 +1397,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 4eaa385e2d4..299949e15ec 100644
--- a/src/cascadia/TerminalCore/Terminal.cpp
+++ b/src/cascadia/TerminalCore/Terminal.cpp
@@ -39,8 +39,6 @@ static std::wstring _KeyEventsToText(std::deque<std::unique_ptr<IInputEvent>>& 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<TerminalDispatch>(*this);
     auto engine = std::make_unique<OutputStateMachineEngine>(std::move(dispatch));
@@ -77,11 +73,8 @@ Terminal::Terminal() :
 
     _terminalInput = std::make_unique<TerminalInput>(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<COLORREF> 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<til::color> 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<COLORREF, COLORREF> 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<Microsoft::Console::Render::RenderOverlay> 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<COLORREF, COLORREF> GetAttributeColors(const TextAttribute& attr) const noexcept override;
     std::vector<Microsoft::Console::Types::Viewport> 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<void(const std::optional<til::color>)> _pfnTabColorChanged;
     std::function<void()> _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<til::color> _tabColor;
     std::optional<til::color> _startingTabColor;
 
-    // This is still stored as a COLORREF because it interacts with some code in ConTypes
-    std::array<COLORREF, TextColor::TABLE_SIZE> _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<std::array<COLORREF, 18>, 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:
+// - <none>
+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 367a8365a56..08328424755 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 @@
     <ClCompile Include="..\TerminalSelection.cpp" />
     <ClCompile Include="..\TerminalApi.cpp" />
     <ClCompile Include="..\Terminal.cpp" />
-    <ClCompile Include="..\ColorFix.cpp" />
     <ClCompile Include="..\pch.cpp">
       <PrecompiledHeader>Create</PrecompiledHeader>
     </ClCompile>
@@ -20,7 +19,6 @@
     <ClInclude Include="..\ITerminalApi.hpp" />
     <ClInclude Include="..\pch.h" />
     <ClInclude Include="..\Terminal.hpp" />
-    <ClInclude Include="..\ColorFix.hpp" />
   </ItemGroup>
 
 </Project>
diff --git a/src/cascadia/TerminalCore/terminalrenderdata.cpp b/src/cascadia/TerminalCore/terminalrenderdata.cpp
index def44aeb15b..1ce671e54c6 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 <DefaultSettings.h>
 
 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<COLORREF, COLORREF> Terminal::GetAttributeColors(const TextAttribute& attr) const noexcept
-{
-    std::pair<COLORREF, COLORREF> 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<size_t> Terminal::GetPatternId(const COORD location) const noe
     return {};
 }
 
+std::pair<COLORREF, COLORREF> Terminal::GetAttributeColors(const TextAttribute& attr) const noexcept
+{
+    return _renderSettings.GetAttributeColors(attr);
+}
+
 std::vector<Microsoft::Console::Types::Viewport> 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<COLORREF, 18> 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<Microsoft::Terminal::Core::Color>, 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 ae063f1939b..e5a9f8b5a70 100644
--- a/src/cascadia/UnitTests_TerminalCore/ConptyRoundtripTests.cpp
+++ b/src/cascadia/UnitTests_TerminalCore/ConptyRoundtripTests.cpp
@@ -108,7 +108,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<COLORREF, COLORREF> 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:
-// - <none>
-// 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:
+// - <none>
+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:
-// - <none>
-// 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<size_t> 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<size_t> RenderData::GetPatternId(const COORD /*location*/) con
 // - ARGB color values for the foreground and background
 std::pair<COLORREF, COLORREF> 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:
-// - <none>
-// 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<COLORREF, COLORREF> GetAttributeColors(const TextAttribute& attr) const noexcept override;
 
     std::vector<Microsoft::Console::Types::Viewport> 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<Microsoft::Console::Render::RenderOverlay> GetOverlays() const noexcept override;
 
     const bool IsGridLineDrawingAllowed() noexcept override;
@@ -61,6 +57,7 @@ class RenderData final :
 #pragma endregion
 
 #pragma region IUiaData
+    std::pair<COLORREF, COLORREF> 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<COLORREF, COLORREF> 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<COLORREF> 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<COLORREF> 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<CursorType>(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<unsigned int>(_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<COLORREF, TextColor::TABLE_SIZE>& 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<COLORREF, TextColor::TABLE_SIZE> _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<TextAttribute> 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<TextAttribute> 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<TextAttribute> 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<TextAttribute> 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 d58343d3d69..4538270a70e 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<RenderOverlay> GetOverlays() const noexcept override
     {
         return std::vector<RenderOverlay>{};
@@ -418,7 +408,7 @@ void VtIoTests::RendererDtorAndThread()
         auto data = std::make_unique<MockRenderData>();
         auto thread = std::make_unique<Microsoft::Console::Render::RenderThread>();
         auto* pThread = thread.get();
-        auto pRenderer = std::make_unique<Microsoft::Console::Render::Renderer>(data.get(), nullptr, 0, std::move(thread));
+        auto pRenderer = std::make_unique<Microsoft::Console::Render::Renderer>(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<MockRenderData>();
         auto thread = std::make_unique<Microsoft::Console::Render::RenderThread>();
         auto* pThread = thread.get();
-        auto pRenderer = std::make_unique<Microsoft::Console::Render::Renderer>(data.get(), nullptr, 0, std::move(thread));
+        auto pRenderer = std::make_unique<Microsoft::Console::Render::Renderer>(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 3d9a5b8aa1b..526236606df 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<Xterm256Engine> engine = std::make_unique<Xterm256Engine>(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<Xterm256Engine> engine = std::make_unique<Xterm256Engine>(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<XtermEngine> engine = std::make_unique<XtermEngine>(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<XtermEngine> engine = std::make_unique<XtermEngine>(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 ef9e951129b..c66b0112d0a 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<IRenderData*> /*pData*/,
                                                        const bool /*usingSoftFont*/,
                                                        bool const /*isSettingDefaultBrushes*/) noexcept
diff --git a/src/interactivity/onecore/BgfxEngine.hpp b/src/interactivity/onecore/BgfxEngine.hpp
index 4a01837d936..e28de8890d5 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<IRenderData*> 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 95c6a9a5ffd..404e88293f7 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<void(HRESULT)> pfn) noexcept
 {
     _api.warningCallback = std::move(pfn);
diff --git a/src/renderer/atlas/AtlasEngine.cpp b/src/renderer/atlas/AtlasEngine.cpp
index ac187dadc70..496cae12524 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<IRenderData*> pData, const bool usingSoftFont, const bool isSettingDefaultBrushes) noexcept
+[[nodiscard]] HRESULT AtlasEngine::UpdateDrawingBrushes(const TextAttribute& textAttributes, const RenderSettings& renderSettings, const gsl::not_null<IRenderData*> /*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 8bae3743620..28890689c4a 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<IRenderData*> pData, bool usingSoftFont, bool isSettingDefaultBrushes) noexcept override;
+        [[nodiscard]] HRESULT UpdateDrawingBrushes(const TextAttribute& textAttributes, const RenderSettings& renderSettings, gsl::not_null<IRenderData*> pData, bool usingSoftFont, bool isSettingDefaultBrushes) noexcept override;
         [[nodiscard]] HRESULT UpdateFont(const FontInfoDesired& FontInfoDesired, _Out_ FontInfo& FontInfo) noexcept override;
         [[nodiscard]] HRESULT UpdateSoftFont(gsl::span<const uint16_t> 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<void(HRESULT)> 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:
-// - <none>
-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:
-// - <none>
-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:
-// - <none>
-// 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:
-// - <none>
-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<COLORREF, TextColor::TABLE_SIZE>& 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<COLORREF, 18> 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<size_t>(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<size_t>(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<COLORREF, COLORREF> 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<COLORREF, COLORREF> 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 @@
   </PropertyGroup>
   <Import Project="$(SolutionDir)src\common.build.pre.props" />
   <ItemGroup>
-    <ClCompile Include="..\BlinkingState.cpp" />
     <ClCompile Include="..\FontInfo.cpp" />
     <ClCompile Include="..\FontInfoBase.cpp" />
     <ClCompile Include="..\FontInfoDesired.cpp" />
     <ClCompile Include="..\FontResource.cpp" />
     <ClCompile Include="..\RenderEngineBase.cpp" />
+    <ClCompile Include="..\RenderSettings.cpp" />
     <ClCompile Include="..\renderer.cpp" />
     <ClCompile Include="..\thread.cpp" />
     <ClCompile Include="..\precomp.cpp">
@@ -23,7 +23,6 @@
     </ClCompile>
   </ItemGroup>
   <ItemGroup>
-    <ClInclude Include="..\..\inc\BlinkingState.hpp" />
     <ClInclude Include="..\..\inc\Cluster.hpp" />
     <ClInclude Include="..\..\inc\FontInfo.hpp" />
     <ClInclude Include="..\..\inc\FontInfoBase.hpp" />
@@ -34,6 +33,7 @@
     <ClInclude Include="..\..\inc\IRenderEngine.hpp" />
     <ClInclude Include="..\..\inc\IRenderTarget.hpp" />
     <ClInclude Include="..\..\inc\RenderEngineBase.hpp" />
+    <ClInclude Include="..\..\inc\RenderSettings.hpp" />
     <ClInclude Include="..\precomp.h" />
     <ClInclude Include="..\renderer.hpp" />
     <ClInclude Include="..\thread.hpp" />
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 @@
     <ClCompile Include="..\RenderEngineBase.cpp">
       <Filter>Source Files</Filter>
     </ClCompile>
-    <ClCompile Include="..\BlinkingState.cpp">
+    <ClCompile Include="..\RenderSettings.cpp">
       <Filter>Source Files</Filter>
     </ClCompile>
   </ItemGroup>
@@ -80,15 +80,15 @@
     <ClInclude Include="..\..\inc\RenderEngineBase.hpp">
       <Filter>Header Files</Filter>
     </ClInclude>
-    <ClInclude Include="..\..\inc\BlinkingState.hpp">
-      <Filter>Header Files\inc</Filter>
-    </ClInclude>
     <ClInclude Include="..\..\inc\Cluster.hpp">
       <Filter>Header Files\inc</Filter>
     </ClInclude>
     <ClInclude Include="..\..\inc\IRenderTarget.hpp">
       <Filter>Header Files\inc</Filter>
     </ClInclude>
+    <ClInclude Include="..\..\inc\RenderSettings.hpp">
+      <Filter>Header Files\inc</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <Natvis Include="$(SolutionDir)tools\ConsoleTypes.natvis" />
diff --git a/src/renderer/base/renderer.cpp b/src/renderer/base/renderer.cpp
index 26ba9c3aa10..1e913ab3bba 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<RenderThread> 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
@@ -1215,7 +1217,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<RenderThread> thread);
@@ -99,6 +101,7 @@ namespace Microsoft::Console::Render
         [[nodiscard]] std::optional<CursorOptions> _GetCursorInfo();
         [[nodiscard]] HRESULT _PrepareRenderInfo(_In_ IRenderEngine* const pEngine);
 
+        const RenderSettings& _renderSettings;
         std::array<IRenderEngine*, 2> _engines{};
         IRenderData* _pData = nullptr; // Non-ownership pointer
         std::unique_ptr<RenderThread> _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 aae67a7bef9..1eb1102171a 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<CustomTextRenderer>() },
@@ -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)
@@ -1917,17 +1905,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<IRenderData*> pData,
+                                                     const RenderSettings& renderSettings,
+                                                     const gsl::not_null<IRenderData*> /*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;
@@ -1967,7 +1957,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 000cb23f749..811df82e4b2 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<IRenderData*> 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 2e09f374dd1..3b9fa789426 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<IRenderData*> pData,
                                                    const bool usingSoftFont,
                                                    const bool isSettingDefaultBrushes) noexcept override;
diff --git a/src/renderer/gdi/state.cpp b/src/renderer/gdi/state.cpp
index 722577c8ec0..b951d3dfe13 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<IRenderData*> pData,
+                                                      const RenderSettings& renderSettings,
+                                                      const gsl::not_null<IRenderData*> /*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<RenderOverlay> 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 ecf9daecfd3..7ffb946d7ca 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<IRenderData*> pData, bool usingSoftFont, bool isSettingDefaultBrushes) noexcept = 0;
+        [[nodiscard]] virtual HRESULT UpdateDrawingBrushes(const TextAttribute& textAttributes, const RenderSettings& renderSettings, gsl::not_null<IRenderData*> 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<const uint16_t> 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<void(HRESULT)> 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<COLORREF, TextColor::TABLE_SIZE>& 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<COLORREF, COLORREF> GetAttributeColors(const TextAttribute& attr) const noexcept;
+        std::pair<COLORREF, COLORREF> GetAttributeColorsWithAlpha(const TextAttribute& attr) const noexcept;
+        void ToggleBlinkRendition(class IRenderTarget& renderTarget) noexcept;
+
+    private:
+        til::enumset<Mode> _renderMode{ Mode::BlinkAllowed, Mode::IntenseIsBright };
+        std::array<COLORREF, TextColor::TABLE_SIZE> _colorTable;
+        std::array<size_t, static_cast<size_t>(ColorAlias::ENUM_COUNT)> _colorAliasIndices;
+        std::array<std::array<COLORREF, 18>, 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 8349d710acb..172cf500887 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 - <unused>
+// - renderSettings - <unused>
 // - pData - <unused>
 // - usingSoftFont - <unused>
 // - isSettingDefaultBrushes - <unused>
 // Return Value:
 // - S_FALSE since we do nothing
 [[nodiscard]] HRESULT UiaEngine::UpdateDrawingBrushes(const TextAttribute& /*textAttributes*/,
+                                                      const RenderSettings& /*renderSettings*/,
                                                       const gsl::not_null<IRenderData*> /*pData*/,
                                                       const bool /*usingSoftFont*/,
                                                       const bool /*isSettingDefaultBrushes*/) noexcept
diff --git a/src/renderer/uia/UiaRenderer.hpp b/src/renderer/uia/UiaRenderer.hpp
index 3b187f64652..eb75bd6e741 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<IRenderData*> pData, const bool usingSoftFont, const bool isSettingDefaultBrushes) noexcept override;
+        [[nodiscard]] HRESULT UpdateDrawingBrushes(const TextAttribute& textAttributes, const RenderSettings& renderSettings, const gsl::not_null<IRenderData*> 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<IRenderData*> 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<IRenderData*> pData,
                                                    const bool usingSoftFont,
                                                    const bool isSettingDefaultBrushes) noexcept override;
diff --git a/src/renderer/vt/XtermEngine.cpp b/src/renderer/vt/XtermEngine.cpp
index 9d5a74665cd..86ffc10706c 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<IRenderData*> /*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<IRenderData*> pData,
                                                            const bool usingSoftFont,
                                                            const bool isSettingDefaultBrushes) noexcept override;
diff --git a/src/renderer/wddmcon/WddmConRenderer.cpp b/src/renderer/wddmcon/WddmConRenderer.cpp
index 1ee11d74182..94eb912dcf1 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<IRenderData*> /*pData*/,
                                                           const bool /*usingSoftFont*/,
                                                           bool const /*isSettingDefaultBrushes*/) noexcept
diff --git a/src/renderer/wddmcon/WddmConRenderer.hpp b/src/renderer/wddmcon/WddmConRenderer.hpp
index de564c0017c..6e06982040f 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<IRenderData*> pData,
                                                    const bool usingSoftFont,
                                                    bool const isSettingDefaultBrushes) noexcept override;
diff --git a/src/terminal/adapter/adaptDispatch.cpp b/src/terminal/adapter/adaptDispatch.cpp
index 18d81fd56f7..505fcf028b9 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 <deque>
@@ -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 2f45b32a7b4..489fbc3b603 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 <Windows.h>
-#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<COLORREF, COLORREF> GetAttributeColors(const TextAttribute& attr) const noexcept = 0;
 
         virtual std::vector<Microsoft::Console::Types::Viewport> 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<COLORREF, COLORREF> 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 @@
   <Import Project="$(SolutionDir)src\common.build.pre.props" />
   <ItemGroup>
     <ClCompile Include="..\CodepointWidthDetector.cpp" />
+    <ClCompile Include="..\ColorFix.cpp" />
     <ClCompile Include="..\convert.cpp" />
     <ClCompile Include="..\colorTable.cpp" />
     <ClCompile Include="..\Environment.cpp" />
@@ -40,6 +41,7 @@
     <ClInclude Include="..\IBaseData.h" />
     <ClInclude Include="..\IControlAccessibilityInfo.h" />
     <ClInclude Include="..\inc\CodepointWidthDetector.hpp" />
+    <ClInclude Include="..\inc\ColorFix.hpp" />
     <ClInclude Include="..\inc\convert.hpp" />
     <ClInclude Include="..\inc\colorTable.hpp" />
     <ClInclude Include="..\inc\Environment.hpp" />
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 @@
     </Filter>
   </ItemGroup>
   <ItemGroup>
+    <ClCompile Include="..\ColorFix.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
     <ClCompile Include="..\convert.cpp">
       <Filter>Source Files</Filter>
     </ClCompile>
@@ -92,6 +95,9 @@
     <ClInclude Include="..\inc\Viewport.hpp">
       <Filter>Header Files</Filter>
     </ClInclude>
+    <ClInclude Include="..\inc\ColorFix.hpp">
+      <Filter>Header Files</Filter>
+    </ClInclude>
     <ClInclude Include="..\inc\convert.hpp">
       <Filter>Header Files</Filter>
     </ClInclude>
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 \


Test patch: