From b46d39306124363a4104afb74fa9b6657b1d17d0 Mon Sep 17 00:00:00 2001 From: "Dustin L. Howett (MSFT)" Date: Fri, 15 May 2020 15:43:00 -0700 Subject: [PATCH] Switch the Cascadia projects to til::color where it's easily possible to do so (#5847) This pull request moves swaths of Cascadia to use `til::color` for color interop. There are still some places where we use `COLORREF`, such as in the ABI boundaries between WinRT components. I've also added two more til::color helpers - `with_alpha`, which takes an existing color and sets its alpha component, and a `Windows::UI::Color` convertor pair. Future direction might include a `TerminalSettings::Color` type at the idl boundary so we can finally stop using UInt32s (!) for color. ## Validation Steps Performed Tested certain fragile areas: * [x] setting the background with OSC 11 * [x] setting the background when acrylic is in use (which requires low-alpha) --- src/cascadia/TerminalApp/ColorScheme.cpp | 22 +++---- src/cascadia/TerminalApp/ColorScheme.h | 22 +++---- src/cascadia/TerminalApp/JsonUtils.cpp | 4 +- src/cascadia/TerminalApp/JsonUtils.h | 2 +- src/cascadia/TerminalApp/Profile.cpp | 6 +- src/cascadia/TerminalApp/Profile.h | 14 ++--- src/cascadia/TerminalControl/TermControl.cpp | 28 +++------ src/cascadia/TerminalControl/TermControl.h | 2 +- src/cascadia/TerminalCore/Terminal.cpp | 2 +- src/cascadia/TerminalCore/Terminal.hpp | 4 +- src/cascadia/WinRTUtils/inc/Utils.h | 16 ----- .../WindowsTerminal/NonClientIslandWindow.cpp | 9 ++- .../WindowsTerminal/NonClientIslandWindow.h | 2 +- src/inc/DefaultSettings.h | 2 - src/inc/til/color.h | 61 +++++++++++++++++++ src/til/ut_til/ColorTests.cpp | 33 ++++++---- src/types/inc/utils.hpp | 4 +- src/types/utils.cpp | 12 ++-- 18 files changed, 143 insertions(+), 102 deletions(-) diff --git a/src/cascadia/TerminalApp/ColorScheme.cpp b/src/cascadia/TerminalApp/ColorScheme.cpp index 3636a5d5890..45d4e7748e4 100644 --- a/src/cascadia/TerminalApp/ColorScheme.cpp +++ b/src/cascadia/TerminalApp/ColorScheme.cpp @@ -47,7 +47,7 @@ ColorScheme::ColorScheme() : { } -ColorScheme::ColorScheme(std::wstring name, COLORREF defaultFg, COLORREF defaultBg, COLORREF cursorColor) : +ColorScheme::ColorScheme(std::wstring name, til::color defaultFg, til::color defaultBg, til::color cursorColor) : _schemeName{ name }, _table{}, _defaultForeground{ defaultFg }, @@ -70,15 +70,15 @@ ColorScheme::~ColorScheme() // - void ColorScheme::ApplyScheme(TerminalSettings terminalSettings) const { - terminalSettings.DefaultForeground(_defaultForeground); - terminalSettings.DefaultBackground(_defaultBackground); - terminalSettings.SelectionBackground(_selectionBackground); - terminalSettings.CursorColor(_cursorColor); + terminalSettings.DefaultForeground(static_cast(_defaultForeground)); + terminalSettings.DefaultBackground(static_cast(_defaultBackground)); + terminalSettings.SelectionBackground(static_cast(_selectionBackground)); + terminalSettings.CursorColor(static_cast(_cursorColor)); auto const tableCount = gsl::narrow_cast(_table.size()); for (int i = 0; i < tableCount; i++) { - terminalSettings.SetColorTableEntry(i, _table[i]); + terminalSettings.SetColorTableEntry(i, static_cast(_table[i])); } } @@ -167,27 +167,27 @@ std::wstring_view ColorScheme::GetName() const noexcept return { _schemeName }; } -std::array& ColorScheme::GetTable() noexcept +std::array& ColorScheme::GetTable() noexcept { return _table; } -COLORREF ColorScheme::GetForeground() const noexcept +til::color ColorScheme::GetForeground() const noexcept { return _defaultForeground; } -COLORREF ColorScheme::GetBackground() const noexcept +til::color ColorScheme::GetBackground() const noexcept { return _defaultBackground; } -COLORREF ColorScheme::GetSelectionBackground() const noexcept +til::color ColorScheme::GetSelectionBackground() const noexcept { return _selectionBackground; } -COLORREF ColorScheme::GetCursorColor() const noexcept +til::color ColorScheme::GetCursorColor() const noexcept { return _cursorColor; } diff --git a/src/cascadia/TerminalApp/ColorScheme.h b/src/cascadia/TerminalApp/ColorScheme.h index cf0addd4dc5..92f8f4f6d70 100644 --- a/src/cascadia/TerminalApp/ColorScheme.h +++ b/src/cascadia/TerminalApp/ColorScheme.h @@ -35,7 +35,7 @@ class TerminalApp::ColorScheme { public: ColorScheme(); - ColorScheme(std::wstring name, COLORREF defaultFg, COLORREF defaultBg, COLORREF cursorColor); + ColorScheme(std::wstring name, til::color defaultFg, til::color defaultBg, til::color cursorColor); ~ColorScheme(); void ApplyScheme(winrt::Microsoft::Terminal::Settings::TerminalSettings terminalSettings) const; @@ -45,21 +45,21 @@ class TerminalApp::ColorScheme void LayerJson(const Json::Value& json); std::wstring_view GetName() const noexcept; - std::array& GetTable() noexcept; - COLORREF GetForeground() const noexcept; - COLORREF GetBackground() const noexcept; - COLORREF GetSelectionBackground() const noexcept; - COLORREF GetCursorColor() const noexcept; + std::array& GetTable() noexcept; + til::color GetForeground() const noexcept; + til::color GetBackground() const noexcept; + til::color GetSelectionBackground() const noexcept; + til::color GetCursorColor() const noexcept; static std::optional GetNameFromJson(const Json::Value& json); private: std::wstring _schemeName; - std::array _table; - COLORREF _defaultForeground; - COLORREF _defaultBackground; - COLORREF _selectionBackground; - COLORREF _cursorColor; + std::array _table; + til::color _defaultForeground; + til::color _defaultBackground; + til::color _selectionBackground; + til::color _cursorColor; friend class TerminalAppLocalTests::SettingsTests; friend class TerminalAppLocalTests::ColorSchemeTests; diff --git a/src/cascadia/TerminalApp/JsonUtils.cpp b/src/cascadia/TerminalApp/JsonUtils.cpp index 8331612a8bc..f4282097b83 100644 --- a/src/cascadia/TerminalApp/JsonUtils.cpp +++ b/src/cascadia/TerminalApp/JsonUtils.cpp @@ -8,9 +8,9 @@ void TerminalApp::JsonUtils::GetOptionalColor(const Json::Value& json, std::string_view key, - std::optional& target) + std::optional& target) { - const auto conversionFn = [](const Json::Value& value) -> uint32_t { + const auto conversionFn = [](const Json::Value& value) -> til::color { return ::Microsoft::Console::Utils::ColorFromHexString(value.asString()); }; GetOptionalValue(json, diff --git a/src/cascadia/TerminalApp/JsonUtils.h b/src/cascadia/TerminalApp/JsonUtils.h index 423f43c274a..1845a9d6524 100644 --- a/src/cascadia/TerminalApp/JsonUtils.h +++ b/src/cascadia/TerminalApp/JsonUtils.h @@ -17,7 +17,7 @@ namespace TerminalApp::JsonUtils { void GetOptionalColor(const Json::Value& json, std::string_view key, - std::optional& target); + std::optional& target); void GetOptionalString(const Json::Value& json, std::string_view key, diff --git a/src/cascadia/TerminalApp/Profile.cpp b/src/cascadia/TerminalApp/Profile.cpp index deb59c70965..736a35d3dfc 100644 --- a/src/cascadia/TerminalApp/Profile.cpp +++ b/src/cascadia/TerminalApp/Profile.cpp @@ -551,17 +551,17 @@ void Profile::SetUseAcrylic(bool useAcrylic) noexcept _useAcrylic = useAcrylic; } -void Profile::SetDefaultForeground(COLORREF defaultForeground) noexcept +void Profile::SetDefaultForeground(til::color defaultForeground) noexcept { _defaultForeground = defaultForeground; } -void Profile::SetDefaultBackground(COLORREF defaultBackground) noexcept +void Profile::SetDefaultBackground(til::color defaultBackground) noexcept { _defaultBackground = defaultBackground; } -void Profile::SetSelectionBackground(COLORREF selectionBackground) noexcept +void Profile::SetSelectionBackground(til::color selectionBackground) noexcept { _selectionBackground = selectionBackground; } diff --git a/src/cascadia/TerminalApp/Profile.h b/src/cascadia/TerminalApp/Profile.h index 878f4ad0894..b6f422c52c5 100644 --- a/src/cascadia/TerminalApp/Profile.h +++ b/src/cascadia/TerminalApp/Profile.h @@ -79,9 +79,9 @@ class TerminalApp::Profile final void SetStartingDirectory(std::wstring startingDirectory) noexcept; void SetName(const std::wstring_view name) noexcept; void SetUseAcrylic(bool useAcrylic) noexcept; - void SetDefaultForeground(COLORREF defaultForeground) noexcept; - void SetDefaultBackground(COLORREF defaultBackground) noexcept; - void SetSelectionBackground(COLORREF selectionBackground) noexcept; + void SetDefaultForeground(til::color defaultForeground) noexcept; + void SetDefaultBackground(til::color defaultBackground) noexcept; + void SetSelectionBackground(til::color selectionBackground) noexcept; void SetCloseOnExitMode(CloseOnExitMode mode) noexcept; void SetConnectionType(GUID connectionType) noexcept; @@ -137,10 +137,10 @@ class TerminalApp::Profile final // If this is set, then our colors should come from the associated color scheme std::optional _schemeName; - std::optional _defaultForeground; - std::optional _defaultBackground; - std::optional _selectionBackground; - std::optional _cursorColor; + std::optional _defaultForeground; + std::optional _defaultBackground; + std::optional _selectionBackground; + std::optional _cursorColor; std::optional _tabTitle; bool _suppressApplicationTitle; int32_t _historySize; diff --git a/src/cascadia/TerminalControl/TermControl.cpp b/src/cascadia/TerminalControl/TermControl.cpp index cf2d682aff8..0540cad2b59 100644 --- a/src/cascadia/TerminalControl/TermControl.cpp +++ b/src/cascadia/TerminalControl/TermControl.cpp @@ -253,7 +253,7 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation { _InitializeBackgroundBrush(); - uint32_t bg = _settings.DefaultBackground(); + COLORREF bg = _settings.DefaultBackground(); _BackgroundColorChanged(bg); // Apply padding as swapChainPanel's margin @@ -274,7 +274,7 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation // set TSF Foreground Media::SolidColorBrush foregroundBrush{}; - foregroundBrush.Color(ColorRefToColor(_settings.DefaultForeground())); + foregroundBrush.Color(static_cast(_settings.DefaultForeground())); TSFInputControl().Foreground(foregroundBrush); TSFInputControl().Margin(newMargin); @@ -405,37 +405,29 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation // - color: The background color to use as a uint32 (aka DWORD COLORREF) // Return Value: // - - winrt::fire_and_forget TermControl::_BackgroundColorChanged(const uint32_t color) + winrt::fire_and_forget TermControl::_BackgroundColorChanged(const COLORREF color) { + til::color newBgColor{ color }; + auto weakThis{ get_weak() }; co_await winrt::resume_foreground(Dispatcher()); if (auto control{ weakThis.get() }) { - const auto R = GetRValue(color); - const auto G = GetGValue(color); - const auto B = GetBValue(color); - - winrt::Windows::UI::Color bgColor{}; - bgColor.R = R; - bgColor.G = G; - bgColor.B = B; - bgColor.A = 255; - if (auto acrylic = RootGrid().Background().try_as()) { - acrylic.FallbackColor(bgColor); - acrylic.TintColor(bgColor); + acrylic.FallbackColor(newBgColor); + acrylic.TintColor(newBgColor); } else if (auto solidColor = RootGrid().Background().try_as()) { - solidColor.Color(bgColor); + solidColor.Color(newBgColor); } // Set the default background as transparent to prevent the // DX layer from overwriting the background image or acrylic effect - _settings.DefaultBackground(ARGB(0, R, G, B)); + _settings.DefaultBackground(static_cast(newBgColor.with_alpha(0))); } } @@ -1309,7 +1301,7 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation { _settings.UseAcrylic(false); _InitializeBackgroundBrush(); - uint32_t bg = _settings.DefaultBackground(); + COLORREF bg = _settings.DefaultBackground(); _BackgroundColorChanged(bg); } else diff --git a/src/cascadia/TerminalControl/TermControl.h b/src/cascadia/TerminalControl/TermControl.h index c42f2246abe..ecb7c52cb02 100644 --- a/src/cascadia/TerminalControl/TermControl.h +++ b/src/cascadia/TerminalControl/TermControl.h @@ -174,7 +174,7 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation void _ApplyUISettings(); void _InitializeBackgroundBrush(); - winrt::fire_and_forget _BackgroundColorChanged(const uint32_t color); + winrt::fire_and_forget _BackgroundColorChanged(const COLORREF color); bool _InitializeTerminal(); void _UpdateFont(const bool initialUpdate = false); void _SetFontSize(int fontSize); diff --git a/src/cascadia/TerminalCore/Terminal.cpp b/src/cascadia/TerminalCore/Terminal.cpp index 025d2abc7be..5b6452f88b0 100644 --- a/src/cascadia/TerminalCore/Terminal.cpp +++ b/src/cascadia/TerminalCore/Terminal.cpp @@ -875,7 +875,7 @@ void Terminal::SetCursorPositionChangedCallback(std::function pfn) noexc // - Allows setting a callback for when the background color is changed // Arguments: // - pfn: a function callback that takes a uint32 (DWORD COLORREF) color in the format 0x00BBGGRR -void Terminal::SetBackgroundCallback(std::function pfn) noexcept +void Terminal::SetBackgroundCallback(std::function pfn) noexcept { _pfnBackgroundColorChanged.swap(pfn); } diff --git a/src/cascadia/TerminalCore/Terminal.hpp b/src/cascadia/TerminalCore/Terminal.hpp index 8655987ae33..fd0e70e4db3 100644 --- a/src/cascadia/TerminalCore/Terminal.hpp +++ b/src/cascadia/TerminalCore/Terminal.hpp @@ -171,7 +171,7 @@ class Microsoft::Terminal::Core::Terminal final : void SetTitleChangedCallback(std::function pfn) noexcept; void SetScrollPositionChangedCallback(std::function pfn) noexcept; void SetCursorPositionChangedCallback(std::function pfn) noexcept; - void SetBackgroundCallback(std::function pfn) noexcept; + void SetBackgroundCallback(std::function pfn) noexcept; void SetCursorOn(const bool isOn); bool IsCursorBlinkingAllowed() const noexcept; @@ -196,7 +196,7 @@ class Microsoft::Terminal::Core::Terminal final : std::function _pfnWriteInput; std::function _pfnTitleChanged; std::function _pfnScrollPositionChanged; - std::function _pfnBackgroundColorChanged; + std::function _pfnBackgroundColorChanged; std::function _pfnCursorPositionChanged; std::unique_ptr<::Microsoft::Console::VirtualTerminal::StateMachine> _stateMachine; diff --git a/src/cascadia/WinRTUtils/inc/Utils.h b/src/cascadia/WinRTUtils/inc/Utils.h index 2cbffd71cdc..07b9b4fe894 100644 --- a/src/cascadia/WinRTUtils/inc/Utils.h +++ b/src/cascadia/WinRTUtils/inc/Utils.h @@ -3,22 +3,6 @@ #pragma once -// Method Description: -// - Converts a COLORREF to Color -// Arguments: -// - colorref: COLORREF to convert to Color -// Return Value: -// - Color containing the RGB values from colorref -inline winrt::Windows::UI::Color ColorRefToColor(const COLORREF& colorref) -{ - winrt::Windows::UI::Color color; - color.A = 255; - color.R = GetRValue(colorref); - color.G = GetGValue(colorref); - color.B = GetBValue(colorref); - return color; -} - // Method Description: // - Scales a Rect based on a scale factor // Arguments: diff --git a/src/cascadia/WindowsTerminal/NonClientIslandWindow.cpp b/src/cascadia/WindowsTerminal/NonClientIslandWindow.cpp index ff636036f19..86f20c9e05c 100644 --- a/src/cascadia/WindowsTerminal/NonClientIslandWindow.cpp +++ b/src/cascadia/WindowsTerminal/NonClientIslandWindow.cpp @@ -20,7 +20,7 @@ static constexpr int AutohideTaskbarSize = 2; NonClientIslandWindow::NonClientIslandWindow(const ElementTheme& requestedTheme) noexcept : IslandWindow{}, - _backgroundBrushColor{ RGB(0, 0, 0) }, + _backgroundBrushColor{ 0, 0, 0 }, _theme{ requestedTheme }, _isMaximized{ false } { @@ -735,13 +735,12 @@ void NonClientIslandWindow::_UpdateFrameMargins() const noexcept const auto backgroundBrush = _titlebar.Background(); const auto backgroundSolidBrush = backgroundBrush.as(); - const auto backgroundColor = backgroundSolidBrush.Color(); - const auto color = RGB(backgroundColor.R, backgroundColor.G, backgroundColor.B); + const til::color backgroundColor = backgroundSolidBrush.Color(); - if (!_backgroundBrush || color != _backgroundBrushColor) + if (!_backgroundBrush || backgroundColor != _backgroundBrushColor) { // Create brush for titlebar color. - _backgroundBrush = wil::unique_hbrush(CreateSolidBrush(color)); + _backgroundBrush = wil::unique_hbrush(CreateSolidBrush(backgroundColor)); } // To hide the original title bar, we have to paint on top of it with diff --git a/src/cascadia/WindowsTerminal/NonClientIslandWindow.h b/src/cascadia/WindowsTerminal/NonClientIslandWindow.h index f14b4ab38c2..1e796f38084 100644 --- a/src/cascadia/WindowsTerminal/NonClientIslandWindow.h +++ b/src/cascadia/WindowsTerminal/NonClientIslandWindow.h @@ -53,7 +53,7 @@ class NonClientIslandWindow : public IslandWindow winrt::Windows::UI::Xaml::UIElement _clientContent{ nullptr }; wil::unique_hbrush _backgroundBrush; - COLORREF _backgroundBrushColor; + til::color _backgroundBrushColor; winrt::Windows::UI::Xaml::Controls::Border _dragBar{ nullptr }; wil::unique_hwnd _dragBarWindow; diff --git a/src/inc/DefaultSettings.h b/src/inc/DefaultSettings.h index 08d39f4b0d3..71946cc072d 100644 --- a/src/inc/DefaultSettings.h +++ b/src/inc/DefaultSettings.h @@ -23,8 +23,6 @@ constexpr COLORREF DEFAULT_FOREGROUND_WITH_ALPHA = OPACITY_OPAQUE | DEFAULT_FORE constexpr COLORREF DEFAULT_BACKGROUND = COLOR_BLACK; constexpr COLORREF DEFAULT_BACKGROUND_WITH_ALPHA = OPACITY_OPAQUE | DEFAULT_BACKGROUND; -constexpr COLORREF POWERSHELL_BLUE = RGB(1, 36, 86); - constexpr short DEFAULT_HISTORY_SIZE = 9001; #pragma warning(push) diff --git a/src/inc/til/color.h b/src/inc/til/color.h index 59d35dd4fd2..31ba570309d 100644 --- a/src/inc/til/color.h +++ b/src/inc/til/color.h @@ -101,6 +101,16 @@ namespace til // Terminal Implementation Library. Also: "Today I Learned" { } + constexpr color with_alpha(uint8_t alpha) const + { + return color{ + r, + g, + b, + alpha + }; + } + #ifdef D3DCOLORVALUE_DEFINED constexpr operator D3DCOLORVALUE() const { @@ -108,10 +118,61 @@ namespace til // Terminal Implementation Library. Also: "Today I Learned" } #endif +#ifdef WINRT_Windows_UI_H + constexpr color(const winrt::Windows::UI::Color& winUIColor) : + color(winUIColor.R, winUIColor.G, winUIColor.B, winUIColor.A) + { + } + + operator winrt::Windows::UI::Color() const + { + winrt::Windows::UI::Color ret; + ret.R = r; + ret.G = g; + ret.B = b; + ret.A = a; + return ret; + } +#endif + constexpr bool operator==(const til::color& other) const { return r == other.r && g == other.g && b == other.b && a == other.a; } + + constexpr bool operator!=(const til::color& other) const + { + return !(*this == other); + } + + std::wstring to_string() const + { + std::wstringstream wss; + wss << L"Color #" << std::uppercase << std::setfill(L'0') << std::hex; + // Force the compiler to promote from byte to int. Without it, the + // stringstream will try to write the components as chars + wss << std::setw(2) << static_cast(a); + wss << std::setw(2) << static_cast(r); + wss << std::setw(2) << static_cast(g); + wss << std::setw(2) << static_cast(b); + + return wss.str(); + } }; #pragma warning(pop) } + +#ifdef __WEX_COMMON_H__ +namespace WEX::TestExecution +{ + template<> + class VerifyOutputTraits<::til::color> + { + public: + static WEX::Common::NoThrowString ToString(const ::til::color& color) + { + return WEX::Common::NoThrowString(color.to_string().c_str()); + } + }; +}; +#endif diff --git a/src/til/ut_til/ColorTests.cpp b/src/til/ut_til/ColorTests.cpp index 83f37d966f7..ca92bed8a52 100644 --- a/src/til/ut_til/ColorTests.cpp +++ b/src/til/ut_til/ColorTests.cpp @@ -4,19 +4,6 @@ #include "precomp.h" #include "WexTestClass.h" -namespace WEX::TestExecution -{ - template<> - class VerifyOutputTraits - { - public: - static WEX::Common::NoThrowString ToString(const til::color& c) - { - return WEX::Common::NoThrowString().Format(L"(RGBA: %2.02x%2.02x%2.02x%2.02x)", c.r, c.g, c.b, c.a); - } - }; -} - using namespace WEX::Common; using namespace WEX::Logging; using namespace WEX::TestExecution; @@ -101,4 +88,24 @@ class ColorTests VERIFY_ARE_EQUAL(t2, static_cast(q2)); } + + TEST_METHOD(WithAlpha) + { + const COLORREF c = 0x00FEEDFAu; // remember, this one is in 0BGR + const til::color fromColorRef{ c }; + + VERIFY_ARE_EQUAL(0xfa, fromColorRef.r); + VERIFY_ARE_EQUAL(0xed, fromColorRef.g); + VERIFY_ARE_EQUAL(0xfe, fromColorRef.b); + VERIFY_ARE_EQUAL(0xff, fromColorRef.a); // COLORREF do not have an alpha channel + + const auto colorWithAlpha{ fromColorRef.with_alpha(0x7f) }; + + VERIFY_ARE_NOT_EQUAL(colorWithAlpha, fromColorRef); + + VERIFY_ARE_EQUAL(0xfa, colorWithAlpha.r); + VERIFY_ARE_EQUAL(0xed, colorWithAlpha.g); + VERIFY_ARE_EQUAL(0xfe, colorWithAlpha.b); + VERIFY_ARE_EQUAL(0x7f, colorWithAlpha.a); + } }; diff --git a/src/types/inc/utils.hpp b/src/types/inc/utils.hpp index ff1c8dd1781..418cbf2b1d6 100644 --- a/src/types/inc/utils.hpp +++ b/src/types/inc/utils.hpp @@ -33,8 +33,8 @@ namespace Microsoft::Console::Utils GUID GuidFromString(const std::wstring wstr); GUID CreateGuid(); - std::string ColorToHexString(const COLORREF color); - COLORREF ColorFromHexString(const std::string wstr); + std::string ColorToHexString(const til::color color); + til::color ColorFromHexString(const std::string_view wstr); void InitializeCampbellColorTable(const gsl::span table); void InitializeCampbellColorTableForConhost(const gsl::span table); diff --git a/src/types/utils.cpp b/src/types/utils.cpp index 75994421d9e..a12a462e854 100644 --- a/src/types/utils.cpp +++ b/src/types/utils.cpp @@ -51,15 +51,15 @@ GUID Utils::CreateGuid() // - color: the COLORREF to create the string for // Return Value: // - a string representation of the color -std::string Utils::ColorToHexString(const COLORREF color) +std::string Utils::ColorToHexString(const til::color color) { std::stringstream ss; ss << "#" << std::uppercase << std::setfill('0') << std::hex; // Force the compiler to promote from byte to int. Without it, the // stringstream will try to write the components as chars - ss << std::setw(2) << static_cast(GetRValue(color)); - ss << std::setw(2) << static_cast(GetGValue(color)); - ss << std::setw(2) << static_cast(GetBValue(color)); + ss << std::setw(2) << static_cast(color.r); + ss << std::setw(2) << static_cast(color.g); + ss << std::setw(2) << static_cast(color.b); return ss.str(); } @@ -70,7 +70,7 @@ std::string Utils::ColorToHexString(const COLORREF color) // Return Value: // - A COLORREF if the string could successfully be parsed. If the string is not // the correct format, throws E_INVALIDARG -COLORREF Utils::ColorFromHexString(const std::string str) +til::color Utils::ColorFromHexString(const std::string_view str) { THROW_HR_IF(E_INVALIDARG, str.size() != 7 && str.size() != 4); THROW_HR_IF(E_INVALIDARG, str.at(0) != '#'); @@ -96,7 +96,7 @@ COLORREF Utils::ColorFromHexString(const std::string str) const BYTE g = gsl::narrow_cast(std::stoul(gStr, nullptr, 16)); const BYTE b = gsl::narrow_cast(std::stoul(bStr, nullptr, 16)); - return RGB(r, g, b); + return til::color{ r, g, b }; } // Routine Description: