From d0c37fd3f193917ef02723cef2eef9690ab07edb Mon Sep 17 00:00:00 2001 From: Pankaj Bhojwani Date: Wed, 23 Jun 2021 13:11:04 -0700 Subject: [PATCH 01/49] hm --- src/cascadia/TerminalControl/ControlCore.cpp | 4 ++++ src/cascadia/TerminalControl/ControlCore.h | 1 + src/cascadia/TerminalControl/IControlSettings.idl | 1 + .../TerminalSettingsModel/TerminalSettings.cpp | 2 ++ src/cascadia/TerminalSettingsModel/TerminalSettings.h | 3 +++ src/renderer/dx/CustomTextLayout.cpp | 2 ++ src/renderer/dx/CustomTextLayout.h | 1 + src/renderer/dx/DxFontInfo.cpp | 10 ++++++++++ src/renderer/dx/DxFontInfo.h | 6 ++++++ src/renderer/dx/DxFontRenderData.cpp | 5 +++++ src/renderer/dx/DxFontRenderData.h | 3 +++ 11 files changed, 38 insertions(+) diff --git a/src/cascadia/TerminalControl/ControlCore.cpp b/src/cascadia/TerminalControl/ControlCore.cpp index 7e9e9c7d78c..d355a872091 100644 --- a/src/cascadia/TerminalControl/ControlCore.cpp +++ b/src/cascadia/TerminalControl/ControlCore.cpp @@ -505,6 +505,10 @@ namespace winrt::Microsoft::Terminal::Control::implementation const auto fontFace = _settings.FontFace(); const short fontHeight = ::base::saturated_cast(_settings.FontSize()); const auto fontWeight = _settings.FontWeight(); + for (const auto& [tag, param] : _settings.FontFeatures()) + { + _fontFeatures[tag.data()] = param; + } // The font width doesn't terribly matter, we'll only be using the // height to look it up // The other params here also largely don't matter. diff --git a/src/cascadia/TerminalControl/ControlCore.h b/src/cascadia/TerminalControl/ControlCore.h index f37fdcb3939..872dbca8ee2 100644 --- a/src/cascadia/TerminalControl/ControlCore.h +++ b/src/cascadia/TerminalControl/ControlCore.h @@ -184,6 +184,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation FontInfoDesired _desiredFont; FontInfo _actualFont; + std::unordered_map _fontFeatures; // storage location for the leading surrogate of a utf-16 surrogate pair std::optional _leadingSurrogate{ std::nullopt }; diff --git a/src/cascadia/TerminalControl/IControlSettings.idl b/src/cascadia/TerminalControl/IControlSettings.idl index 1bbc178090c..eb0119a6778 100644 --- a/src/cascadia/TerminalControl/IControlSettings.idl +++ b/src/cascadia/TerminalControl/IControlSettings.idl @@ -36,6 +36,7 @@ namespace Microsoft.Terminal.Control Int32 FontSize; Windows.UI.Text.FontWeight FontWeight; String Padding; + Windows.Foundation.Collections.IMap FontFeatures; Microsoft.Terminal.Control.IKeyBindings KeyBindings; diff --git a/src/cascadia/TerminalSettingsModel/TerminalSettings.cpp b/src/cascadia/TerminalSettingsModel/TerminalSettings.cpp index 19ddf5e1576..44389c64042 100644 --- a/src/cascadia/TerminalSettingsModel/TerminalSettings.cpp +++ b/src/cascadia/TerminalSettingsModel/TerminalSettings.cpp @@ -287,6 +287,8 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation const til::color colorRef{ profile.TabColor().Value() }; _TabColor = static_cast(colorRef); } + std::unordered_map featMap{ {L"ss04", 1} }; + _FontFeatures = single_threaded_map(std::move(featMap)); } // Method Description: diff --git a/src/cascadia/TerminalSettingsModel/TerminalSettings.h b/src/cascadia/TerminalSettingsModel/TerminalSettings.h index 4f8a850009d..e1170d30bed 100644 --- a/src/cascadia/TerminalSettingsModel/TerminalSettings.h +++ b/src/cascadia/TerminalSettingsModel/TerminalSettings.h @@ -21,6 +21,8 @@ Author(s): #include #include +using IFontFeatureMap = winrt::Windows::Foundation::Collections::IMap; + // fwdecl unittest classes namespace SettingsModelLocalTests { @@ -119,6 +121,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation INHERITABLE_SETTING(Model::TerminalSettings, int32_t, FontSize, DEFAULT_FONT_SIZE); INHERITABLE_SETTING(Model::TerminalSettings, winrt::Windows::UI::Text::FontWeight, FontWeight); + INHERITABLE_SETTING(Model::TerminalSettings, IFontFeatureMap, FontFeatures); INHERITABLE_SETTING(Model::TerminalSettings, hstring, BackgroundImage); INHERITABLE_SETTING(Model::TerminalSettings, double, BackgroundImageOpacity, 1.0); diff --git a/src/renderer/dx/CustomTextLayout.cpp b/src/renderer/dx/CustomTextLayout.cpp index 0e25d96a27c..e14887b815e 100644 --- a/src/renderer/dx/CustomTextLayout.cpp +++ b/src/renderer/dx/CustomTextLayout.cpp @@ -32,6 +32,8 @@ CustomTextLayout::CustomTextLayout(gsl::not_null const fontRe { _localeName.resize(gsl::narrow_cast(fontRenderData->DefaultTextFormat()->GetLocaleNameLength()) + 1); // +1 for null THROW_IF_FAILED(fontRenderData->DefaultTextFormat()->GetLocaleName(_localeName.data(), gsl::narrow(_localeName.size()))); + + // TODO: construct the font feature vector } //Routine Description: diff --git a/src/renderer/dx/CustomTextLayout.h b/src/renderer/dx/CustomTextLayout.h index 2ac04278bf1..3d049b488f9 100644 --- a/src/renderer/dx/CustomTextLayout.h +++ b/src/renderer/dx/CustomTextLayout.h @@ -167,6 +167,7 @@ namespace Microsoft::Console::Render std::wstring _localeName; ::Microsoft::WRL::ComPtr _numberSubstitution; DWRITE_READING_DIRECTION _readingDirection; + std::vector _features; // Text analysis results std::vector _runs; diff --git a/src/renderer/dx/DxFontInfo.cpp b/src/renderer/dx/DxFontInfo.cpp index 03c224868f4..3421653024e 100644 --- a/src/renderer/dx/DxFontInfo.cpp +++ b/src/renderer/dx/DxFontInfo.cpp @@ -91,6 +91,16 @@ void DxFontInfo::SetStretch(const DWRITE_FONT_STRETCH stretch) noexcept _stretch = stretch; } +std::unordered_map DxFontInfo::GetFeatures() const noexcept +{ + return _features; +} + +void DxFontInfo::SetFeatures(std::unordered_map features) noexcept +{ + _features = features; +} + bool DxFontInfo::GetFallback() const noexcept { return _didFallback; diff --git a/src/renderer/dx/DxFontInfo.h b/src/renderer/dx/DxFontInfo.h index 924202632ee..2c1b780a8c6 100644 --- a/src/renderer/dx/DxFontInfo.h +++ b/src/renderer/dx/DxFontInfo.h @@ -39,6 +39,9 @@ namespace Microsoft::Console::Render DWRITE_FONT_STRETCH GetStretch() const noexcept; void SetStretch(const DWRITE_FONT_STRETCH stretch) noexcept; + std::unordered_map GetFeatures() const noexcept; + void SetFeatures(const std::unordered_map features) noexcept; + bool GetFallback() const noexcept; void SetFromEngine(const std::wstring_view familyName, @@ -75,6 +78,9 @@ namespace Microsoft::Console::Render // The stretch of the font is the spacing between each letter DWRITE_FONT_STRETCH _stretch; + // The font features to apply to the text + std::unordered_map _features; + // Indicates whether we couldn't match the user request and had to choose from a hardcoded default list. bool _didFallback; }; diff --git a/src/renderer/dx/DxFontRenderData.cpp b/src/renderer/dx/DxFontRenderData.cpp index 20340ba6dc1..b397de12b37 100644 --- a/src/renderer/dx/DxFontRenderData.cpp +++ b/src/renderer/dx/DxFontRenderData.cpp @@ -93,6 +93,11 @@ DxFontRenderData::DxFontRenderData(::Microsoft::WRL::ComPtr dwr return _defaultFontInfo.GetStretch(); } +[[nodiscard]] std::unordered_map DxFontRenderData::DefaultFontFeatures() noexcept +{ + return _defaultFontInfo.GetFeatures(); +} + [[nodiscard]] Microsoft::WRL::ComPtr DxFontRenderData::DefaultTextFormat() { return TextFormatWithAttribute(_defaultFontInfo.GetWeight(), _defaultFontInfo.GetStyle(), _defaultFontInfo.GetStretch()); diff --git a/src/renderer/dx/DxFontRenderData.h b/src/renderer/dx/DxFontRenderData.h index 990bcbd966e..4327aa93395 100644 --- a/src/renderer/dx/DxFontRenderData.h +++ b/src/renderer/dx/DxFontRenderData.h @@ -51,6 +51,9 @@ namespace Microsoft::Console::Render // The stretch of default font [[nodiscard]] DWRITE_FONT_STRETCH DefaultFontStretch() noexcept; + // The font features of the default font + [[nodiscard]] std::unordered_map DefaultFontFeatures() noexcept; + // The DirectWrite format object representing the size and other text properties to be applied (by default) [[nodiscard]] Microsoft::WRL::ComPtr DefaultTextFormat(); From e3bba2b8ab907ed6ea2acf6be90f639e36c3455c Mon Sep 17 00:00:00 2001 From: Pankaj Bhojwani Date: Thu, 24 Jun 2021 11:06:12 -0700 Subject: [PATCH 02/49] hmm --- src/cascadia/TerminalControl/ControlCore.cpp | 1 + src/renderer/base/RenderEngineBase.cpp | 6 ++++++ src/renderer/base/renderer.cpp | 8 ++++++++ src/renderer/base/renderer.hpp | 2 ++ src/renderer/dx/DxRenderer.cpp | 5 +++++ src/renderer/dx/DxRenderer.hpp | 2 ++ src/renderer/inc/IRenderEngine.hpp | 1 + src/renderer/inc/IRenderer.hpp | 2 ++ src/renderer/inc/RenderEngineBase.hpp | 2 ++ 9 files changed, 29 insertions(+) diff --git a/src/cascadia/TerminalControl/ControlCore.cpp b/src/cascadia/TerminalControl/ControlCore.cpp index d355a872091..45b568b38f0 100644 --- a/src/cascadia/TerminalControl/ControlCore.cpp +++ b/src/cascadia/TerminalControl/ControlCore.cpp @@ -598,6 +598,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation // TODO: MSFT:20895307 If the font doesn't exist, this doesn't // actually fail. We need a way to gracefully fallback. + _renderer->AddFontFeatures(_fontFeatures); _renderer->TriggerFontChange(newDpi, _desiredFont, _actualFont); // If the actual font isn't what was requested... diff --git a/src/renderer/base/RenderEngineBase.cpp b/src/renderer/base/RenderEngineBase.cpp index f31fff625d7..cdfee8071ac 100644 --- a/src/renderer/base/RenderEngineBase.cpp +++ b/src/renderer/base/RenderEngineBase.cpp @@ -69,3 +69,9 @@ void RenderEngineBase::WaitUntilCanRender() noexcept { // do nothing by default } + + +HRESULT RenderEngineBase::UpdateFontFeatures(const std::unordered_map /*features*/) noexcept +{ + return S_FALSE; +} diff --git a/src/renderer/base/renderer.cpp b/src/renderer/base/renderer.cpp index b53bc6eadf6..14053071ed5 100644 --- a/src/renderer/base/renderer.cpp +++ b/src/renderer/base/renderer.cpp @@ -508,6 +508,14 @@ HRESULT Renderer::_PaintTitle(IRenderEngine* const pEngine) return pEngine->UpdateTitle(newTitle); } +void Renderer::AddFontFeatures(const std::unordered_map features) +{ + std::for_each(_rgpEngines.begin(), _rgpEngines.end(), [&](IRenderEngine* const pEngine) { + LOG_IF_FAILED(pEngine->UpdateFontFeatures(features)); + }); +} + + // Routine Description: // - Called when a change in font or DPI has been detected. // Arguments: diff --git a/src/renderer/base/renderer.hpp b/src/renderer/base/renderer.hpp index 6f8f6d7a8c4..b2b5abd7dd2 100644 --- a/src/renderer/base/renderer.hpp +++ b/src/renderer/base/renderer.hpp @@ -82,6 +82,8 @@ namespace Microsoft::Console::Render void UpdateLastHoveredInterval(const std::optional::interval>& newInterval); + void AddFontFeatures(const std::unordered_map features); + private: std::deque _rgpEngines; diff --git a/src/renderer/dx/DxRenderer.cpp b/src/renderer/dx/DxRenderer.cpp index c94a7147e05..aeb8925e3e1 100644 --- a/src/renderer/dx/DxRenderer.cpp +++ b/src/renderer/dx/DxRenderer.cpp @@ -1975,6 +1975,11 @@ CATCH_RETURN() return S_OK; } +[[nodiscard]] HRESULT DxEngine::UpdateFontFeatures(const std::unordered_map features) noexcept +{ + return S_OK; +} + // Routine Description: // - Updates the font used for drawing // Arguments: diff --git a/src/renderer/dx/DxRenderer.hpp b/src/renderer/dx/DxRenderer.hpp index cbd34ea3b78..2c94c8c3b54 100644 --- a/src/renderer/dx/DxRenderer.hpp +++ b/src/renderer/dx/DxRenderer.hpp @@ -122,6 +122,8 @@ namespace Microsoft::Console::Render [[nodiscard]] ::Microsoft::Console::Types::Viewport GetViewportInCharacters(const ::Microsoft::Console::Types::Viewport& viewInPixels) noexcept; [[nodiscard]] ::Microsoft::Console::Types::Viewport GetViewportInPixels(const ::Microsoft::Console::Types::Viewport& viewInCharacters) noexcept; + [[nodiscard]] HRESULT UpdateFontFeatures(const std::unordered_map features) noexcept override; + float GetScaling() const noexcept; void SetSelectionBackground(const COLORREF color, const float alpha = 0.5f) noexcept; diff --git a/src/renderer/inc/IRenderEngine.hpp b/src/renderer/inc/IRenderEngine.hpp index 3d6631e410e..503d2d4f232 100644 --- a/src/renderer/inc/IRenderEngine.hpp +++ b/src/renderer/inc/IRenderEngine.hpp @@ -110,6 +110,7 @@ namespace Microsoft::Console::Render [[nodiscard]] virtual HRESULT GetFontSize(_Out_ COORD* const pFontSize) noexcept = 0; [[nodiscard]] virtual HRESULT IsGlyphWideByFont(const std::wstring_view glyph, _Out_ bool* const pResult) noexcept = 0; [[nodiscard]] virtual HRESULT UpdateTitle(const std::wstring_view newTitle) noexcept = 0; + [[nodiscard]] virtual HRESULT UpdateFontFeatures(const std::unordered_map features) noexcept = 0; }; inline Microsoft::Console::Render::IRenderEngine::~IRenderEngine() {} diff --git a/src/renderer/inc/IRenderer.hpp b/src/renderer/inc/IRenderer.hpp index 79058c5ae5a..07e2f01678d 100644 --- a/src/renderer/inc/IRenderer.hpp +++ b/src/renderer/inc/IRenderer.hpp @@ -62,6 +62,8 @@ namespace Microsoft::Console::Render virtual void AddRenderEngine(_In_ IRenderEngine* const pEngine) = 0; + virtual void AddFontFeatures(const std::unordered_map features) = 0; + protected: IRenderer() = default; }; diff --git a/src/renderer/inc/RenderEngineBase.hpp b/src/renderer/inc/RenderEngineBase.hpp index 725347d8215..72e97d9c3ef 100644 --- a/src/renderer/inc/RenderEngineBase.hpp +++ b/src/renderer/inc/RenderEngineBase.hpp @@ -47,6 +47,8 @@ namespace Microsoft::Console::Render [[nodiscard]] virtual bool RequiresContinuousRedraw() noexcept override; + [[nodiscard]] HRESULT UpdateFontFeatures(const std::unordered_map features) noexcept override; + void WaitUntilCanRender() noexcept override; protected: From 575a2d61a5cc3966958ca76d6bad32bbb0c93eb5 Mon Sep 17 00:00:00 2001 From: Pankaj Bhojwani Date: Mon, 28 Jun 2021 14:18:20 -0700 Subject: [PATCH 03/49] did user set features --- src/cascadia/TerminalControl/ControlCore.cpp | 7 ++++- src/cascadia/TerminalControl/ControlCore.h | 2 +- .../TerminalSettings.cpp | 2 +- .../UnitTests_Control/MockControlSettings.h | 4 +++ src/renderer/base/RenderEngineBase.cpp | 6 ---- src/renderer/base/renderer.cpp | 8 ----- src/renderer/base/renderer.hpp | 2 -- src/renderer/dx/CustomTextLayout.cpp | 25 +++++++++++----- src/renderer/dx/DxFontInfo.cpp | 29 +++++++++++++++++-- src/renderer/dx/DxFontInfo.h | 18 ++++++++++-- src/renderer/dx/DxFontRenderData.cpp | 11 +++++++ src/renderer/dx/DxFontRenderData.h | 5 ++++ src/renderer/dx/DxRenderer.cpp | 4 +-- src/renderer/dx/DxRenderer.hpp | 4 +-- src/renderer/inc/IRenderEngine.hpp | 1 - src/renderer/inc/IRenderer.hpp | 2 -- src/renderer/inc/RenderEngineBase.hpp | 2 -- 17 files changed, 92 insertions(+), 40 deletions(-) diff --git a/src/cascadia/TerminalControl/ControlCore.cpp b/src/cascadia/TerminalControl/ControlCore.cpp index 45b568b38f0..2fea30a1626 100644 --- a/src/cascadia/TerminalControl/ControlCore.cpp +++ b/src/cascadia/TerminalControl/ControlCore.cpp @@ -159,6 +159,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation // Initialize our font with the renderer // We don't have to care about DPI. We'll get a change message immediately if it's not 96 // and react accordingly. + dxEngine->UpdateFontFeatures(_fontFeatures); _updateFont(true); const COORD windowSize{ static_cast(windowWidth), @@ -596,9 +597,13 @@ namespace winrt::Microsoft::Terminal::Control::implementation const int newDpi = static_cast(static_cast(USER_DEFAULT_SCREEN_DPI) * _compositionScale); + if (_renderEngine) + { + _renderEngine->UpdateFontFeatures(_fontFeatures); + } + // TODO: MSFT:20895307 If the font doesn't exist, this doesn't // actually fail. We need a way to gracefully fallback. - _renderer->AddFontFeatures(_fontFeatures); _renderer->TriggerFontChange(newDpi, _desiredFont, _actualFont); // If the actual font isn't what was requested... diff --git a/src/cascadia/TerminalControl/ControlCore.h b/src/cascadia/TerminalControl/ControlCore.h index 872dbca8ee2..384e97691a9 100644 --- a/src/cascadia/TerminalControl/ControlCore.h +++ b/src/cascadia/TerminalControl/ControlCore.h @@ -184,7 +184,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation FontInfoDesired _desiredFont; FontInfo _actualFont; - std::unordered_map _fontFeatures; + std::unordered_map _fontFeatures; // storage location for the leading surrogate of a utf-16 surrogate pair std::optional _leadingSurrogate{ std::nullopt }; diff --git a/src/cascadia/TerminalSettingsModel/TerminalSettings.cpp b/src/cascadia/TerminalSettingsModel/TerminalSettings.cpp index 44389c64042..d33a698bcc8 100644 --- a/src/cascadia/TerminalSettingsModel/TerminalSettings.cpp +++ b/src/cascadia/TerminalSettingsModel/TerminalSettings.cpp @@ -287,7 +287,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation const til::color colorRef{ profile.TabColor().Value() }; _TabColor = static_cast(colorRef); } - std::unordered_map featMap{ {L"ss04", 1} }; + std::unordered_map featMap{ {L"subs", 1} }; _FontFeatures = single_threaded_map(std::move(featMap)); } diff --git a/src/cascadia/UnitTests_Control/MockControlSettings.h b/src/cascadia/UnitTests_Control/MockControlSettings.h index f3c1930189f..5e827bf883d 100644 --- a/src/cascadia/UnitTests_Control/MockControlSettings.h +++ b/src/cascadia/UnitTests_Control/MockControlSettings.h @@ -8,6 +8,8 @@ Licensed under the MIT license. #include #include +using IFontFeatureMap = winrt::Windows::Foundation::Collections::IMap; + namespace ControlUnitTests { class MockControlSettings : public winrt::implements @@ -80,6 +82,8 @@ namespace ControlUnitTests WINRT_PROPERTY(winrt::hstring, PixelShaderPath); + WINRT_PROPERTY(IFontFeatureMap, FontFeatures); + private: std::array _ColorTable; diff --git a/src/renderer/base/RenderEngineBase.cpp b/src/renderer/base/RenderEngineBase.cpp index cdfee8071ac..f31fff625d7 100644 --- a/src/renderer/base/RenderEngineBase.cpp +++ b/src/renderer/base/RenderEngineBase.cpp @@ -69,9 +69,3 @@ void RenderEngineBase::WaitUntilCanRender() noexcept { // do nothing by default } - - -HRESULT RenderEngineBase::UpdateFontFeatures(const std::unordered_map /*features*/) noexcept -{ - return S_FALSE; -} diff --git a/src/renderer/base/renderer.cpp b/src/renderer/base/renderer.cpp index 14053071ed5..b53bc6eadf6 100644 --- a/src/renderer/base/renderer.cpp +++ b/src/renderer/base/renderer.cpp @@ -508,14 +508,6 @@ HRESULT Renderer::_PaintTitle(IRenderEngine* const pEngine) return pEngine->UpdateTitle(newTitle); } -void Renderer::AddFontFeatures(const std::unordered_map features) -{ - std::for_each(_rgpEngines.begin(), _rgpEngines.end(), [&](IRenderEngine* const pEngine) { - LOG_IF_FAILED(pEngine->UpdateFontFeatures(features)); - }); -} - - // Routine Description: // - Called when a change in font or DPI has been detected. // Arguments: diff --git a/src/renderer/base/renderer.hpp b/src/renderer/base/renderer.hpp index b2b5abd7dd2..6f8f6d7a8c4 100644 --- a/src/renderer/base/renderer.hpp +++ b/src/renderer/base/renderer.hpp @@ -82,8 +82,6 @@ namespace Microsoft::Console::Render void UpdateLastHoveredInterval(const std::optional::interval>& newInterval); - void AddFontFeatures(const std::unordered_map features); - private: std::deque _rgpEngines; diff --git a/src/renderer/dx/CustomTextLayout.cpp b/src/renderer/dx/CustomTextLayout.cpp index e14887b815e..e53c0d811bf 100644 --- a/src/renderer/dx/CustomTextLayout.cpp +++ b/src/renderer/dx/CustomTextLayout.cpp @@ -353,7 +353,7 @@ CATCH_RETURN() _glyphIndices.resize(totalGlyphsArrayCount); } - if (_isEntireTextSimple) + if (_isEntireTextSimple && !_fontRenderData->DidUserSetFeatures()) { // When the entire text is simple, we can skip GetGlyphs and directly retrieve glyph indices and // advances(in font design unit). With the help of font metrics, we can calculate the actual glyph @@ -392,6 +392,17 @@ CATCH_RETURN() std::vector textProps(textLength); std::vector glyphProps(maxGlyphCount); + const auto features = _fontRenderData->DefaultFontFeatures(); + std::vector featureVector; + for (const auto& [tag, param] : features) + { + featureVector.push_back(DWRITE_FONT_FEATURE{ tag, param }); + } + DWRITE_FONT_FEATURE* featureList = &featureVector[0]; + DWRITE_TYPOGRAPHIC_FEATURES typographicFeatures = { &featureList[0], gsl::narrow(featureVector.size()) }; + DWRITE_TYPOGRAPHIC_FEATURES const* typographicFeaturesPointer = &typographicFeatures; + const uint32_t fontFeatureLengths[1] = { textLength }; + // Get the glyphs from the text, retrying if needed. int tries = 0; @@ -408,9 +419,9 @@ CATCH_RETURN() &run.script, _localeName.data(), (run.isNumberSubstituted) ? _numberSubstitution.Get() : nullptr, - nullptr, // features - nullptr, // featureLengths - 0, // featureCount + &typographicFeaturesPointer, // features + fontFeatureLengths, // featureLengths + 1, // featureCount maxGlyphCount, // maxGlyphCount &_glyphClusters.at(textStart), &textProps.at(0), @@ -458,9 +469,9 @@ CATCH_RETURN() (run.bidiLevel & 1), // isRightToLeft &run.script, _localeName.data(), - nullptr, // features - nullptr, // featureRangeLengths - 0, // featureRanges + &typographicFeaturesPointer, // features + fontFeatureLengths, // featureLengths + 1, // featureCount &_glyphAdvances.at(glyphStart), &_glyphOffsets.at(glyphStart)); diff --git a/src/renderer/dx/DxFontInfo.cpp b/src/renderer/dx/DxFontInfo.cpp index 3421653024e..25ccb8c74b9 100644 --- a/src/renderer/dx/DxFontInfo.cpp +++ b/src/renderer/dx/DxFontInfo.cpp @@ -91,14 +91,37 @@ void DxFontInfo::SetStretch(const DWRITE_FONT_STRETCH stretch) noexcept _stretch = stretch; } +bool DxFontInfo::DidUserSetFeatures() const noexcept +{ + return _didUserSetFeatures; +} + std::unordered_map DxFontInfo::GetFeatures() const noexcept { - return _features; + std::unordered_map dwriteFeatures; + for (const auto& [tag, param] : _features) + { + if (tag.length() != 4) + { + // ignore badly formed tags + // maybe this shouldn't be here? maybe this check should be at settings model side to output a warning to user? + continue; + } + dwriteFeatures[DWRITE_MAKE_FONT_FEATURE_TAG(tag[0], tag[1], tag[2], tag[3])] = param; + } + return dwriteFeatures; } -void DxFontInfo::SetFeatures(std::unordered_map features) noexcept +void DxFontInfo::SetFeatures(std::unordered_map features) noexcept { - _features = features; + if (!features.empty()) + { + for (const auto& [tag, param] : features) + { + _features[tag] = param; + } + _didUserSetFeatures = true; + } } bool DxFontInfo::GetFallback() const noexcept diff --git a/src/renderer/dx/DxFontInfo.h b/src/renderer/dx/DxFontInfo.h index 2c1b780a8c6..4a078216dd3 100644 --- a/src/renderer/dx/DxFontInfo.h +++ b/src/renderer/dx/DxFontInfo.h @@ -39,8 +39,9 @@ namespace Microsoft::Console::Render DWRITE_FONT_STRETCH GetStretch() const noexcept; void SetStretch(const DWRITE_FONT_STRETCH stretch) noexcept; + bool DidUserSetFeatures() const noexcept; std::unordered_map GetFeatures() const noexcept; - void SetFeatures(const std::unordered_map features) noexcept; + void SetFeatures(const std::unordered_map features) noexcept; bool GetFallback() const noexcept; @@ -78,8 +79,21 @@ namespace Microsoft::Console::Render // The stretch of the font is the spacing between each letter DWRITE_FONT_STRETCH _stretch; + bool _didUserSetFeatures{ false }; // The font features to apply to the text - std::unordered_map _features; + std::unordered_map _features{ + { L"rlig", 1 }, + { L"rclt", 1 }, + { L"locl", 1 }, + { L"ccmp", 1 }, + { L"calt", 1 }, + { L"liga", 1 }, + { L"clig", 1 }, + { L"kern", 1 }, + { L"mark", 1 }, + { L"mkmk", 1 }, + { L"dist", 1 } + }; // Indicates whether we couldn't match the user request and had to choose from a hardcoded default list. bool _didFallback; diff --git a/src/renderer/dx/DxFontRenderData.cpp b/src/renderer/dx/DxFontRenderData.cpp index b397de12b37..9d1ef84c012 100644 --- a/src/renderer/dx/DxFontRenderData.cpp +++ b/src/renderer/dx/DxFontRenderData.cpp @@ -197,6 +197,7 @@ DxFontRenderData::DxFontRenderData(::Microsoft::WRL::ComPtr dwr desired.GetWeight(), DWRITE_FONT_STYLE_NORMAL, DWRITE_FONT_STRETCH_NORMAL); + _defaultFontInfo.SetFeatures(_features); _BuildFontRenderData(desired, actual, dpi); } @@ -446,6 +447,16 @@ try } CATCH_RETURN() +bool DxFontRenderData::DidUserSetFeatures() const noexcept +{ + return _defaultFontInfo.DidUserSetFeatures(); +} + +void DxFontRenderData::SetFeatures(std::unordered_map features) +{ + _features = features; +} + // Routine Description: // - Build the needed data for rendering according to the font used // Arguments: diff --git a/src/renderer/dx/DxFontRenderData.h b/src/renderer/dx/DxFontRenderData.h index 4327aa93395..ebceb7db1d4 100644 --- a/src/renderer/dx/DxFontRenderData.h +++ b/src/renderer/dx/DxFontRenderData.h @@ -77,10 +77,15 @@ namespace Microsoft::Console::Render [[nodiscard]] static HRESULT STDMETHODCALLTYPE s_CalculateBoxEffect(IDWriteTextFormat* format, size_t widthPixels, IDWriteFontFace1* face, float fontScale, IBoxDrawingEffect** effect) noexcept; + bool DidUserSetFeatures() const noexcept; + void SetFeatures(std::unordered_map features); + private: void _BuildFontRenderData(const FontInfoDesired& desired, FontInfo& actual, const int dpi); Microsoft::WRL::ComPtr _BuildTextFormat(const DxFontInfo fontInfo, const std::wstring_view localeName); + std::unordered_map _features; + ::Microsoft::WRL::ComPtr _dwriteFactory; ::Microsoft::WRL::ComPtr _dwriteTextAnalyzer; diff --git a/src/renderer/dx/DxRenderer.cpp b/src/renderer/dx/DxRenderer.cpp index aeb8925e3e1..e9620f761a0 100644 --- a/src/renderer/dx/DxRenderer.cpp +++ b/src/renderer/dx/DxRenderer.cpp @@ -1975,9 +1975,9 @@ CATCH_RETURN() return S_OK; } -[[nodiscard]] HRESULT DxEngine::UpdateFontFeatures(const std::unordered_map features) noexcept +void DxEngine::UpdateFontFeatures(const std::unordered_map features) noexcept { - return S_OK; + _fontRenderData->SetFeatures(features); } // Routine Description: diff --git a/src/renderer/dx/DxRenderer.hpp b/src/renderer/dx/DxRenderer.hpp index 2c94c8c3b54..5a854b29b8a 100644 --- a/src/renderer/dx/DxRenderer.hpp +++ b/src/renderer/dx/DxRenderer.hpp @@ -72,6 +72,8 @@ namespace Microsoft::Console::Render HANDLE GetSwapChainHandle(); + void UpdateFontFeatures(const std::unordered_map features) noexcept; + // IRenderEngine Members [[nodiscard]] HRESULT Invalidate(const SMALL_RECT* const psrRegion) noexcept override; [[nodiscard]] HRESULT InvalidateCursor(const SMALL_RECT* const psrRegion) noexcept override; @@ -122,8 +124,6 @@ namespace Microsoft::Console::Render [[nodiscard]] ::Microsoft::Console::Types::Viewport GetViewportInCharacters(const ::Microsoft::Console::Types::Viewport& viewInPixels) noexcept; [[nodiscard]] ::Microsoft::Console::Types::Viewport GetViewportInPixels(const ::Microsoft::Console::Types::Viewport& viewInCharacters) noexcept; - [[nodiscard]] HRESULT UpdateFontFeatures(const std::unordered_map features) noexcept override; - float GetScaling() const noexcept; void SetSelectionBackground(const COLORREF color, const float alpha = 0.5f) noexcept; diff --git a/src/renderer/inc/IRenderEngine.hpp b/src/renderer/inc/IRenderEngine.hpp index 503d2d4f232..3d6631e410e 100644 --- a/src/renderer/inc/IRenderEngine.hpp +++ b/src/renderer/inc/IRenderEngine.hpp @@ -110,7 +110,6 @@ namespace Microsoft::Console::Render [[nodiscard]] virtual HRESULT GetFontSize(_Out_ COORD* const pFontSize) noexcept = 0; [[nodiscard]] virtual HRESULT IsGlyphWideByFont(const std::wstring_view glyph, _Out_ bool* const pResult) noexcept = 0; [[nodiscard]] virtual HRESULT UpdateTitle(const std::wstring_view newTitle) noexcept = 0; - [[nodiscard]] virtual HRESULT UpdateFontFeatures(const std::unordered_map features) noexcept = 0; }; inline Microsoft::Console::Render::IRenderEngine::~IRenderEngine() {} diff --git a/src/renderer/inc/IRenderer.hpp b/src/renderer/inc/IRenderer.hpp index 07e2f01678d..79058c5ae5a 100644 --- a/src/renderer/inc/IRenderer.hpp +++ b/src/renderer/inc/IRenderer.hpp @@ -62,8 +62,6 @@ namespace Microsoft::Console::Render virtual void AddRenderEngine(_In_ IRenderEngine* const pEngine) = 0; - virtual void AddFontFeatures(const std::unordered_map features) = 0; - protected: IRenderer() = default; }; diff --git a/src/renderer/inc/RenderEngineBase.hpp b/src/renderer/inc/RenderEngineBase.hpp index 72e97d9c3ef..725347d8215 100644 --- a/src/renderer/inc/RenderEngineBase.hpp +++ b/src/renderer/inc/RenderEngineBase.hpp @@ -47,8 +47,6 @@ namespace Microsoft::Console::Render [[nodiscard]] virtual bool RequiresContinuousRedraw() noexcept override; - [[nodiscard]] HRESULT UpdateFontFeatures(const std::unordered_map features) noexcept override; - void WaitUntilCanRender() noexcept override; protected: From 7a4055304f72be6643d6dc2633c38fdb33ffa483 Mon Sep 17 00:00:00 2001 From: Pankaj Bhojwani Date: Mon, 28 Jun 2021 14:56:13 -0700 Subject: [PATCH 04/49] remove this --- src/renderer/dx/CustomTextLayout.cpp | 2 -- src/renderer/dx/CustomTextLayout.h | 1 - 2 files changed, 3 deletions(-) diff --git a/src/renderer/dx/CustomTextLayout.cpp b/src/renderer/dx/CustomTextLayout.cpp index e53c0d811bf..a948c561ee5 100644 --- a/src/renderer/dx/CustomTextLayout.cpp +++ b/src/renderer/dx/CustomTextLayout.cpp @@ -32,8 +32,6 @@ CustomTextLayout::CustomTextLayout(gsl::not_null const fontRe { _localeName.resize(gsl::narrow_cast(fontRenderData->DefaultTextFormat()->GetLocaleNameLength()) + 1); // +1 for null THROW_IF_FAILED(fontRenderData->DefaultTextFormat()->GetLocaleName(_localeName.data(), gsl::narrow(_localeName.size()))); - - // TODO: construct the font feature vector } //Routine Description: diff --git a/src/renderer/dx/CustomTextLayout.h b/src/renderer/dx/CustomTextLayout.h index 3d049b488f9..2ac04278bf1 100644 --- a/src/renderer/dx/CustomTextLayout.h +++ b/src/renderer/dx/CustomTextLayout.h @@ -167,7 +167,6 @@ namespace Microsoft::Console::Render std::wstring _localeName; ::Microsoft::WRL::ComPtr _numberSubstitution; DWRITE_READING_DIRECTION _readingDirection; - std::vector _features; // Text analysis results std::vector _runs; From ae9e1b550ea2c0b7105431ad397f9f33f3375e7c Mon Sep 17 00:00:00 2001 From: Pankaj Bhojwani Date: Mon, 28 Jun 2021 14:58:18 -0700 Subject: [PATCH 05/49] spell --- .github/actions/spelling/allow/allow.txt | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/.github/actions/spelling/allow/allow.txt b/.github/actions/spelling/allow/allow.txt index fcaaf797ab6..b2553b55623 100644 --- a/.github/actions/spelling/allow/allow.txt +++ b/.github/actions/spelling/allow/allow.txt @@ -1,6 +1,9 @@ Apc apc +calt +ccmp clickable +clig copyable dalet Dcs @@ -25,8 +28,11 @@ hyperlinks img It'd kje +liga lje +locl maxed +mkmk mru nje ogonek @@ -36,10 +42,12 @@ postmodern ptys qof qps +rclt reimplementation reserialization reserialize reserializes +rlig runtimes shcha Sos From afd89edbe110dc2c030c22fe7bf9b0ee64fb185f Mon Sep 17 00:00:00 2001 From: Pankaj Bhojwani Date: Mon, 28 Jun 2021 15:11:26 -0700 Subject: [PATCH 06/49] format --- src/cascadia/TerminalSettingsModel/TerminalSettings.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cascadia/TerminalSettingsModel/TerminalSettings.cpp b/src/cascadia/TerminalSettingsModel/TerminalSettings.cpp index d33a698bcc8..8da43a617b1 100644 --- a/src/cascadia/TerminalSettingsModel/TerminalSettings.cpp +++ b/src/cascadia/TerminalSettingsModel/TerminalSettings.cpp @@ -287,7 +287,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation const til::color colorRef{ profile.TabColor().Value() }; _TabColor = static_cast(colorRef); } - std::unordered_map featMap{ {L"subs", 1} }; + std::unordered_map featMap{ { L"subs", 1 } }; _FontFeatures = single_threaded_map(std::move(featMap)); } From acc03bba022c38f7518d5fc9ef89df3bae7b9c09 Mon Sep 17 00:00:00 2001 From: Pankaj Bhojwani Date: Tue, 29 Jun 2021 10:10:47 -0700 Subject: [PATCH 07/49] don't involve dxfontinfo --- src/renderer/dx/CustomTextLayout.cpp | 11 +++------- src/renderer/dx/DxFontInfo.cpp | 33 ---------------------------- src/renderer/dx/DxFontInfo.h | 20 ----------------- src/renderer/dx/DxFontRenderData.cpp | 32 ++++++++++++++++++++++----- src/renderer/dx/DxFontRenderData.h | 21 +++++++++++++++--- 5 files changed, 47 insertions(+), 70 deletions(-) diff --git a/src/renderer/dx/CustomTextLayout.cpp b/src/renderer/dx/CustomTextLayout.cpp index a948c561ee5..8e7d2bade86 100644 --- a/src/renderer/dx/CustomTextLayout.cpp +++ b/src/renderer/dx/CustomTextLayout.cpp @@ -390,14 +390,9 @@ CATCH_RETURN() std::vector textProps(textLength); std::vector glyphProps(maxGlyphCount); - const auto features = _fontRenderData->DefaultFontFeatures(); - std::vector featureVector; - for (const auto& [tag, param] : features) - { - featureVector.push_back(DWRITE_FONT_FEATURE{ tag, param }); - } - DWRITE_FONT_FEATURE* featureList = &featureVector[0]; - DWRITE_TYPOGRAPHIC_FEATURES typographicFeatures = { &featureList[0], gsl::narrow(featureVector.size()) }; + auto features = _fontRenderData->DefaultFontFeatures(); + DWRITE_FONT_FEATURE* featureList = &features[0]; + DWRITE_TYPOGRAPHIC_FEATURES typographicFeatures = { &featureList[0], gsl::narrow(features.size()) }; DWRITE_TYPOGRAPHIC_FEATURES const* typographicFeaturesPointer = &typographicFeatures; const uint32_t fontFeatureLengths[1] = { textLength }; diff --git a/src/renderer/dx/DxFontInfo.cpp b/src/renderer/dx/DxFontInfo.cpp index 25ccb8c74b9..03c224868f4 100644 --- a/src/renderer/dx/DxFontInfo.cpp +++ b/src/renderer/dx/DxFontInfo.cpp @@ -91,39 +91,6 @@ void DxFontInfo::SetStretch(const DWRITE_FONT_STRETCH stretch) noexcept _stretch = stretch; } -bool DxFontInfo::DidUserSetFeatures() const noexcept -{ - return _didUserSetFeatures; -} - -std::unordered_map DxFontInfo::GetFeatures() const noexcept -{ - std::unordered_map dwriteFeatures; - for (const auto& [tag, param] : _features) - { - if (tag.length() != 4) - { - // ignore badly formed tags - // maybe this shouldn't be here? maybe this check should be at settings model side to output a warning to user? - continue; - } - dwriteFeatures[DWRITE_MAKE_FONT_FEATURE_TAG(tag[0], tag[1], tag[2], tag[3])] = param; - } - return dwriteFeatures; -} - -void DxFontInfo::SetFeatures(std::unordered_map features) noexcept -{ - if (!features.empty()) - { - for (const auto& [tag, param] : features) - { - _features[tag] = param; - } - _didUserSetFeatures = true; - } -} - bool DxFontInfo::GetFallback() const noexcept { return _didFallback; diff --git a/src/renderer/dx/DxFontInfo.h b/src/renderer/dx/DxFontInfo.h index 4a078216dd3..924202632ee 100644 --- a/src/renderer/dx/DxFontInfo.h +++ b/src/renderer/dx/DxFontInfo.h @@ -39,10 +39,6 @@ namespace Microsoft::Console::Render DWRITE_FONT_STRETCH GetStretch() const noexcept; void SetStretch(const DWRITE_FONT_STRETCH stretch) noexcept; - bool DidUserSetFeatures() const noexcept; - std::unordered_map GetFeatures() const noexcept; - void SetFeatures(const std::unordered_map features) noexcept; - bool GetFallback() const noexcept; void SetFromEngine(const std::wstring_view familyName, @@ -79,22 +75,6 @@ namespace Microsoft::Console::Render // The stretch of the font is the spacing between each letter DWRITE_FONT_STRETCH _stretch; - bool _didUserSetFeatures{ false }; - // The font features to apply to the text - std::unordered_map _features{ - { L"rlig", 1 }, - { L"rclt", 1 }, - { L"locl", 1 }, - { L"ccmp", 1 }, - { L"calt", 1 }, - { L"liga", 1 }, - { L"clig", 1 }, - { L"kern", 1 }, - { L"mark", 1 }, - { L"mkmk", 1 }, - { L"dist", 1 } - }; - // Indicates whether we couldn't match the user request and had to choose from a hardcoded default list. bool _didFallback; }; diff --git a/src/renderer/dx/DxFontRenderData.cpp b/src/renderer/dx/DxFontRenderData.cpp index 9d1ef84c012..d28c2a89c4b 100644 --- a/src/renderer/dx/DxFontRenderData.cpp +++ b/src/renderer/dx/DxFontRenderData.cpp @@ -93,9 +93,9 @@ DxFontRenderData::DxFontRenderData(::Microsoft::WRL::ComPtr dwr return _defaultFontInfo.GetStretch(); } -[[nodiscard]] std::unordered_map DxFontRenderData::DefaultFontFeatures() noexcept +[[nodiscard]] std::vector DxFontRenderData::DefaultFontFeatures() noexcept { - return _defaultFontInfo.GetFeatures(); + return _featureVector; } [[nodiscard]] Microsoft::WRL::ComPtr DxFontRenderData::DefaultTextFormat() @@ -197,7 +197,6 @@ DxFontRenderData::DxFontRenderData(::Microsoft::WRL::ComPtr dwr desired.GetWeight(), DWRITE_FONT_STYLE_NORMAL, DWRITE_FONT_STRETCH_NORMAL); - _defaultFontInfo.SetFeatures(_features); _BuildFontRenderData(desired, actual, dpi); } @@ -449,12 +448,33 @@ CATCH_RETURN() bool DxFontRenderData::DidUserSetFeatures() const noexcept { - return _defaultFontInfo.DidUserSetFeatures(); + return _didUserSetFeatures; } -void DxFontRenderData::SetFeatures(std::unordered_map features) +void DxFontRenderData::SetFeatures(std::unordered_map features) noexcept { - _features = features; + // update our feature map + if (!features.empty()) + { + for (const auto& [tag, param] : features) + { + _featureMap[tag] = param; + } + _didUserSetFeatures = true; + } + + // convert the data to DWRITE_FONT_FEATURE and store it in a vector for CustomTextLayout + for (const auto& [tag, param] : _featureMap) + { + if (tag.length() != 4) + { + // ignore badly formed tags + // maybe this shouldn't be here? maybe this check should be at settings model side to output a warning to user? + continue; + } + const auto dwriteTag = DWRITE_MAKE_FONT_FEATURE_TAG(tag[0], tag[1], tag[2], tag[3]); + _featureVector.push_back(DWRITE_FONT_FEATURE{ dwriteTag, param }); + } } // Routine Description: diff --git a/src/renderer/dx/DxFontRenderData.h b/src/renderer/dx/DxFontRenderData.h index ebceb7db1d4..344554f527a 100644 --- a/src/renderer/dx/DxFontRenderData.h +++ b/src/renderer/dx/DxFontRenderData.h @@ -52,7 +52,7 @@ namespace Microsoft::Console::Render [[nodiscard]] DWRITE_FONT_STRETCH DefaultFontStretch() noexcept; // The font features of the default font - [[nodiscard]] std::unordered_map DefaultFontFeatures() noexcept; + [[nodiscard]] std::vector DefaultFontFeatures() noexcept; // The DirectWrite format object representing the size and other text properties to be applied (by default) [[nodiscard]] Microsoft::WRL::ComPtr DefaultTextFormat(); @@ -78,13 +78,28 @@ namespace Microsoft::Console::Render [[nodiscard]] static HRESULT STDMETHODCALLTYPE s_CalculateBoxEffect(IDWriteTextFormat* format, size_t widthPixels, IDWriteFontFace1* face, float fontScale, IBoxDrawingEffect** effect) noexcept; bool DidUserSetFeatures() const noexcept; - void SetFeatures(std::unordered_map features); + void SetFeatures(std::unordered_map features) noexcept; private: void _BuildFontRenderData(const FontInfoDesired& desired, FontInfo& actual, const int dpi); Microsoft::WRL::ComPtr _BuildTextFormat(const DxFontInfo fontInfo, const std::wstring_view localeName); - std::unordered_map _features; + bool _didUserSetFeatures{ false }; + // The font features to apply to the text + std::unordered_map _featureMap{ + { L"rlig", 1 }, + { L"rclt", 1 }, + { L"locl", 1 }, + { L"ccmp", 1 }, + { L"calt", 1 }, + { L"liga", 1 }, + { L"clig", 1 }, + { L"kern", 1 }, + { L"mark", 1 }, + { L"mkmk", 1 }, + { L"dist", 1 } + }; + std::vector _featureVector; ::Microsoft::WRL::ComPtr _dwriteFactory; From 797bae570ed7125d5f97f6d120df0ee9f8f9cba8 Mon Sep 17 00:00:00 2001 From: Pankaj Bhojwani Date: Tue, 29 Jun 2021 16:28:46 -0700 Subject: [PATCH 08/49] pipe axes through --- src/cascadia/TerminalControl/ControlCore.cpp | 6 ++++ src/cascadia/TerminalControl/ControlCore.h | 1 + .../TerminalControl/IControlSettings.idl | 1 + .../TerminalSettings.cpp | 3 ++ .../TerminalSettingsModel/TerminalSettings.h | 2 ++ src/renderer/dx/DxFontRenderData.cpp | 30 +++++++++++++++++++ src/renderer/dx/DxFontRenderData.h | 8 +++++ src/renderer/dx/DxRenderer.cpp | 5 ++++ src/renderer/dx/DxRenderer.hpp | 1 + 9 files changed, 57 insertions(+) diff --git a/src/cascadia/TerminalControl/ControlCore.cpp b/src/cascadia/TerminalControl/ControlCore.cpp index 2fea30a1626..e73197e0bfa 100644 --- a/src/cascadia/TerminalControl/ControlCore.cpp +++ b/src/cascadia/TerminalControl/ControlCore.cpp @@ -160,6 +160,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation // We don't have to care about DPI. We'll get a change message immediately if it's not 96 // and react accordingly. dxEngine->UpdateFontFeatures(_fontFeatures); + dxEngine->UpdateFontAxes(_fontAxes); _updateFont(true); const COORD windowSize{ static_cast(windowWidth), @@ -510,6 +511,10 @@ namespace winrt::Microsoft::Terminal::Control::implementation { _fontFeatures[tag.data()] = param; } + for (const auto& [axis, value] : _settings.FontAxes()) + { + _fontAxes[axis.data()] = value; + } // The font width doesn't terribly matter, we'll only be using the // height to look it up // The other params here also largely don't matter. @@ -600,6 +605,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation if (_renderEngine) { _renderEngine->UpdateFontFeatures(_fontFeatures); + _renderEngine->UpdateFontAxes(_fontAxes); } // TODO: MSFT:20895307 If the font doesn't exist, this doesn't diff --git a/src/cascadia/TerminalControl/ControlCore.h b/src/cascadia/TerminalControl/ControlCore.h index 384e97691a9..53a3869f54f 100644 --- a/src/cascadia/TerminalControl/ControlCore.h +++ b/src/cascadia/TerminalControl/ControlCore.h @@ -185,6 +185,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation FontInfoDesired _desiredFont; FontInfo _actualFont; std::unordered_map _fontFeatures; + std::unordered_map _fontAxes; // storage location for the leading surrogate of a utf-16 surrogate pair std::optional _leadingSurrogate{ std::nullopt }; diff --git a/src/cascadia/TerminalControl/IControlSettings.idl b/src/cascadia/TerminalControl/IControlSettings.idl index eb0119a6778..d218f90f070 100644 --- a/src/cascadia/TerminalControl/IControlSettings.idl +++ b/src/cascadia/TerminalControl/IControlSettings.idl @@ -37,6 +37,7 @@ namespace Microsoft.Terminal.Control Windows.UI.Text.FontWeight FontWeight; String Padding; Windows.Foundation.Collections.IMap FontFeatures; + Windows.Foundation.Collections.IMap FontAxes; Microsoft.Terminal.Control.IKeyBindings KeyBindings; diff --git a/src/cascadia/TerminalSettingsModel/TerminalSettings.cpp b/src/cascadia/TerminalSettingsModel/TerminalSettings.cpp index 8da43a617b1..fbf0683116f 100644 --- a/src/cascadia/TerminalSettingsModel/TerminalSettings.cpp +++ b/src/cascadia/TerminalSettingsModel/TerminalSettings.cpp @@ -289,6 +289,9 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation } std::unordered_map featMap{ { L"subs", 1 } }; _FontFeatures = single_threaded_map(std::move(featMap)); + + std::unordered_map axesMap{ { L"wght", 900 }, { L"slnt", 70 } }; + _FontAxes = single_threaded_map(std::move(axesMap)); } // Method Description: diff --git a/src/cascadia/TerminalSettingsModel/TerminalSettings.h b/src/cascadia/TerminalSettingsModel/TerminalSettings.h index e1170d30bed..189578b268a 100644 --- a/src/cascadia/TerminalSettingsModel/TerminalSettings.h +++ b/src/cascadia/TerminalSettingsModel/TerminalSettings.h @@ -21,6 +21,7 @@ Author(s): #include #include +using IFontAxesMap = winrt::Windows::Foundation::Collections::IMap; using IFontFeatureMap = winrt::Windows::Foundation::Collections::IMap; // fwdecl unittest classes @@ -121,6 +122,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation INHERITABLE_SETTING(Model::TerminalSettings, int32_t, FontSize, DEFAULT_FONT_SIZE); INHERITABLE_SETTING(Model::TerminalSettings, winrt::Windows::UI::Text::FontWeight, FontWeight); + INHERITABLE_SETTING(Model::TerminalSettings, IFontAxesMap, FontAxes); INHERITABLE_SETTING(Model::TerminalSettings, IFontFeatureMap, FontFeatures); INHERITABLE_SETTING(Model::TerminalSettings, hstring, BackgroundImage); diff --git a/src/renderer/dx/DxFontRenderData.cpp b/src/renderer/dx/DxFontRenderData.cpp index d28c2a89c4b..40d0a598c3e 100644 --- a/src/renderer/dx/DxFontRenderData.cpp +++ b/src/renderer/dx/DxFontRenderData.cpp @@ -477,6 +477,15 @@ void DxFontRenderData::SetFeatures(std::unordered_map axes) noexcept +{ + // update our axis map + for (const auto& [axis, value] : axes) + { + _axesMap[axis] = value; + } +} + // Routine Description: // - Build the needed data for rendering according to the font used // Arguments: @@ -685,5 +694,26 @@ Microsoft::WRL::ComPtr DxFontRenderData::_BuildTextFormat(con _fontSize, localeName.data(), &format)); + + // Set the font axes + ::Microsoft::WRL::ComPtr format3; + if (!FAILED(format->QueryInterface(IID_PPV_ARGS(&format3)))) + { + std::vector axesVector; + for (const auto& [axis, value] : _axesMap) + { + if (axis.length() != 4) + { + // ignore badly formed tags + // maybe this shouldn't be here? maybe this check should be at settings model side to output a warning to user? + continue; + } + const auto dwriteTag = DWRITE_MAKE_FONT_AXIS_TAG(axis[0], axis[1], axis[2], axis[3]); + axesVector.push_back(DWRITE_FONT_AXIS_VALUE{ dwriteTag, gsl::narrow(value) }); + } + DWRITE_FONT_AXIS_VALUE* axesList = &axesVector[0]; + format3->SetFontAxisValues(axesList, gsl::narrow(axesVector.size())); + } + return format; } diff --git a/src/renderer/dx/DxFontRenderData.h b/src/renderer/dx/DxFontRenderData.h index 344554f527a..9d1c70702fa 100644 --- a/src/renderer/dx/DxFontRenderData.h +++ b/src/renderer/dx/DxFontRenderData.h @@ -79,6 +79,7 @@ namespace Microsoft::Console::Render bool DidUserSetFeatures() const noexcept; void SetFeatures(std::unordered_map features) noexcept; + void SetAxes(std::unordered_map axes) noexcept; private: void _BuildFontRenderData(const FontInfoDesired& desired, FontInfo& actual, const int dpi); @@ -101,6 +102,13 @@ namespace Microsoft::Console::Render }; std::vector _featureVector; + // The font axes to apply to the text + std::unordered_map _axesMap{ + { L"wght", 400 }, + { L"wdth", 100 }, + { L"slnt", -20 } + }; + ::Microsoft::WRL::ComPtr _dwriteFactory; ::Microsoft::WRL::ComPtr _dwriteTextAnalyzer; diff --git a/src/renderer/dx/DxRenderer.cpp b/src/renderer/dx/DxRenderer.cpp index e9620f761a0..dbb4e7791b4 100644 --- a/src/renderer/dx/DxRenderer.cpp +++ b/src/renderer/dx/DxRenderer.cpp @@ -1980,6 +1980,11 @@ void DxEngine::UpdateFontFeatures(const std::unordered_mapSetFeatures(features); } +void DxEngine::UpdateFontAxes(const std::unordered_map axes) noexcept +{ + _fontRenderData->SetAxes(axes); +} + // Routine Description: // - Updates the font used for drawing // Arguments: diff --git a/src/renderer/dx/DxRenderer.hpp b/src/renderer/dx/DxRenderer.hpp index 5a854b29b8a..2cc45ed3641 100644 --- a/src/renderer/dx/DxRenderer.hpp +++ b/src/renderer/dx/DxRenderer.hpp @@ -73,6 +73,7 @@ namespace Microsoft::Console::Render HANDLE GetSwapChainHandle(); void UpdateFontFeatures(const std::unordered_map features) noexcept; + void UpdateFontAxes(const std::unordered_map axes) noexcept; // IRenderEngine Members [[nodiscard]] HRESULT Invalidate(const SMALL_RECT* const psrRegion) noexcept override; From a23254cbaf72bbd5c284e9d5f6d269c97136692f Mon Sep 17 00:00:00 2001 From: Pankaj Bhojwani Date: Wed, 30 Jun 2021 11:59:24 -0700 Subject: [PATCH 09/49] works, needs cleaning up --- src/renderer/dx/CustomTextLayout.cpp | 109 +++++++++++++++++++++------ src/renderer/dx/CustomTextLayout.h | 1 + src/renderer/dx/DxFontRenderData.cpp | 2 +- src/renderer/dx/DxFontRenderData.h | 6 +- 4 files changed, 91 insertions(+), 27 deletions(-) diff --git a/src/renderer/dx/CustomTextLayout.cpp b/src/renderer/dx/CustomTextLayout.cpp index 8e7d2bade86..5a919e665f6 100644 --- a/src/renderer/dx/CustomTextLayout.cpp +++ b/src/renderer/dx/CustomTextLayout.cpp @@ -1264,29 +1264,65 @@ CATCH_RETURN(); fallback = _fontRenderData->SystemFontFallback(); } - // Walk through and analyze the entire string - while (textLength > 0) + ::Microsoft::WRL::ComPtr fallback1; + ::Microsoft::WRL::ComPtr format3; + if (!FAILED(_formatInUse->QueryInterface(IID_PPV_ARGS(&format3))) && !FAILED(fallback->QueryInterface(IID_PPV_ARGS(&fallback1)))) { - UINT32 mappedLength = 0; - ::Microsoft::WRL::ComPtr mappedFont; - FLOAT scale = 0.0f; - - fallback->MapCharacters(source, - textPosition, - textLength, - collection.Get(), - familyName.data(), - weight, - style, - stretch, - &mappedLength, - &mappedFont, - &scale); - - RETURN_IF_FAILED(_SetMappedFont(textPosition, mappedLength, mappedFont.Get(), scale)); + const auto axesCount = format3->GetFontAxisValueCount(); + std::vector axesVector; + axesVector.resize(axesCount); + const auto res = format3->GetFontAxisValues(axesVector.data(), axesCount); - textPosition += mappedLength; - textLength -= mappedLength; + // Walk through and analyze the entire string + while (textLength > 0) + { + UINT32 mappedLength = 0; + ::Microsoft::WRL::ComPtr mappedFont; + FLOAT scale = 0.0f; + + fallback1->MapCharacters(source, + textPosition, + textLength, + collection.Get(), + familyName.data(), + axesVector.data(), + axesCount, + &mappedLength, + &scale, + &mappedFont); + + RETURN_IF_FAILED(_SetMappedFontFace(textPosition, mappedLength, mappedFont, scale)); + + textPosition += mappedLength; + textLength -= mappedLength; + } + } + else + { + // Walk through and analyze the entire string + while (textLength > 0) + { + UINT32 mappedLength = 0; + ::Microsoft::WRL::ComPtr mappedFont; + FLOAT scale = 0.0f; + + fallback->MapCharacters(source, + textPosition, + textLength, + collection.Get(), + familyName.data(), + weight, + style, + stretch, + &mappedLength, + &mappedFont, + &scale); + + RETURN_IF_FAILED(_SetMappedFont(textPosition, mappedLength, mappedFont.Get(), scale)); + + textPosition += mappedLength; + textLength -= mappedLength; + } } } CATCH_RETURN(); @@ -1339,6 +1375,37 @@ CATCH_RETURN(); return S_OK; } + +[[nodiscard]] HRESULT STDMETHODCALLTYPE CustomTextLayout::_SetMappedFontFace(UINT32 textPosition, + UINT32 textLength, + ::Microsoft::WRL::ComPtr const fontFace, + FLOAT const scale) +{ + try + { + _SetCurrentRun(textPosition); + _SplitCurrentRun(textPosition); + while (textLength > 0) + { + auto& run = _FetchNextRun(textLength); + + if (fontFace != nullptr) + { + RETURN_IF_FAILED(fontFace.As(&run.fontFace)); + } + else + { + run.fontFace = _fontInUse; + } + + // Store the font scale as well. + run.fontScale = scale; + } + } + CATCH_RETURN(); + + return S_OK; +} #pragma endregion #pragma region internal methods for mimicking text analyzer to identify and split box drawing regions diff --git a/src/renderer/dx/CustomTextLayout.h b/src/renderer/dx/CustomTextLayout.h index 2ac04278bf1..81d1e9769e6 100644 --- a/src/renderer/dx/CustomTextLayout.h +++ b/src/renderer/dx/CustomTextLayout.h @@ -127,6 +127,7 @@ namespace Microsoft::Console::Render [[nodiscard]] HRESULT STDMETHODCALLTYPE _AnalyzeFontFallback(IDWriteTextAnalysisSource* const source, UINT32 textPosition, UINT32 textLength); [[nodiscard]] HRESULT STDMETHODCALLTYPE _SetMappedFont(UINT32 textPosition, UINT32 textLength, IDWriteFont* const font, FLOAT const scale); + [[nodiscard]] HRESULT STDMETHODCALLTYPE _SetMappedFontFace(UINT32 textPosition, UINT32 textLength, ::Microsoft::WRL::ComPtr const fontFace, FLOAT const scale); [[nodiscard]] HRESULT STDMETHODCALLTYPE _AnalyzeBoxDrawing(gsl::not_null const source, UINT32 textPosition, UINT32 textLength); [[nodiscard]] HRESULT STDMETHODCALLTYPE _SetBoxEffect(UINT32 textPosition, UINT32 textLength); diff --git a/src/renderer/dx/DxFontRenderData.cpp b/src/renderer/dx/DxFontRenderData.cpp index 40d0a598c3e..6fb199a0d87 100644 --- a/src/renderer/dx/DxFontRenderData.cpp +++ b/src/renderer/dx/DxFontRenderData.cpp @@ -697,7 +697,7 @@ Microsoft::WRL::ComPtr DxFontRenderData::_BuildTextFormat(con // Set the font axes ::Microsoft::WRL::ComPtr format3; - if (!FAILED(format->QueryInterface(IID_PPV_ARGS(&format3)))) + if (!FAILED(format->QueryInterface(IID_PPV_ARGS(&format3))) && !_axesMap.empty()) { std::vector axesVector; for (const auto& [axis, value] : _axesMap) diff --git a/src/renderer/dx/DxFontRenderData.h b/src/renderer/dx/DxFontRenderData.h index 9d1c70702fa..d88b2ae306a 100644 --- a/src/renderer/dx/DxFontRenderData.h +++ b/src/renderer/dx/DxFontRenderData.h @@ -103,11 +103,7 @@ namespace Microsoft::Console::Render std::vector _featureVector; // The font axes to apply to the text - std::unordered_map _axesMap{ - { L"wght", 400 }, - { L"wdth", 100 }, - { L"slnt", -20 } - }; + std::unordered_map _axesMap; ::Microsoft::WRL::ComPtr _dwriteFactory; From 64e42bfdba09576a97dbc00322e7512557d13592 Mon Sep 17 00:00:00 2001 From: Pankaj Bhojwani Date: Wed, 30 Jun 2021 14:08:04 -0700 Subject: [PATCH 10/49] fix some failings --- src/cascadia/UnitTests_Control/MockControlSettings.h | 2 ++ src/renderer/dx/CustomTextLayout.cpp | 2 +- src/renderer/dx/DxFontRenderData.cpp | 2 +- src/renderer/dx/DxFontRenderData.h | 2 +- 4 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/cascadia/UnitTests_Control/MockControlSettings.h b/src/cascadia/UnitTests_Control/MockControlSettings.h index 5e827bf883d..d444089112d 100644 --- a/src/cascadia/UnitTests_Control/MockControlSettings.h +++ b/src/cascadia/UnitTests_Control/MockControlSettings.h @@ -9,6 +9,7 @@ Licensed under the MIT license. #include using IFontFeatureMap = winrt::Windows::Foundation::Collections::IMap; +using IFontAxesMap = winrt::Windows::Foundation::Collections::IMap; namespace ControlUnitTests { @@ -83,6 +84,7 @@ namespace ControlUnitTests WINRT_PROPERTY(winrt::hstring, PixelShaderPath); WINRT_PROPERTY(IFontFeatureMap, FontFeatures); + WINRT_PROPERTY(IFontAxesMap, FontAxes); private: std::array _ColorTable; diff --git a/src/renderer/dx/CustomTextLayout.cpp b/src/renderer/dx/CustomTextLayout.cpp index 5a919e665f6..e866d4ce67b 100644 --- a/src/renderer/dx/CustomTextLayout.cpp +++ b/src/renderer/dx/CustomTextLayout.cpp @@ -391,7 +391,7 @@ CATCH_RETURN() std::vector glyphProps(maxGlyphCount); auto features = _fontRenderData->DefaultFontFeatures(); - DWRITE_FONT_FEATURE* featureList = &features[0]; + DWRITE_FONT_FEATURE* featureList = features.data(); DWRITE_TYPOGRAPHIC_FEATURES typographicFeatures = { &featureList[0], gsl::narrow(features.size()) }; DWRITE_TYPOGRAPHIC_FEATURES const* typographicFeaturesPointer = &typographicFeatures; const uint32_t fontFeatureLengths[1] = { textLength }; diff --git a/src/renderer/dx/DxFontRenderData.cpp b/src/renderer/dx/DxFontRenderData.cpp index 6fb199a0d87..40d1a24191c 100644 --- a/src/renderer/dx/DxFontRenderData.cpp +++ b/src/renderer/dx/DxFontRenderData.cpp @@ -93,7 +93,7 @@ DxFontRenderData::DxFontRenderData(::Microsoft::WRL::ComPtr dwr return _defaultFontInfo.GetStretch(); } -[[nodiscard]] std::vector DxFontRenderData::DefaultFontFeatures() noexcept +[[nodiscard]] std::vector DxFontRenderData::DefaultFontFeatures() { return _featureVector; } diff --git a/src/renderer/dx/DxFontRenderData.h b/src/renderer/dx/DxFontRenderData.h index d88b2ae306a..37e98a32b37 100644 --- a/src/renderer/dx/DxFontRenderData.h +++ b/src/renderer/dx/DxFontRenderData.h @@ -52,7 +52,7 @@ namespace Microsoft::Console::Render [[nodiscard]] DWRITE_FONT_STRETCH DefaultFontStretch() noexcept; // The font features of the default font - [[nodiscard]] std::vector DefaultFontFeatures() noexcept; + [[nodiscard]] std::vector DefaultFontFeatures(); // The DirectWrite format object representing the size and other text properties to be applied (by default) [[nodiscard]] Microsoft::WRL::ComPtr DefaultTextFormat(); From 5f23633e2a99540d5b8276f91a327f0acdca6012 Mon Sep 17 00:00:00 2001 From: Pankaj Bhojwani Date: Wed, 30 Jun 2021 14:23:36 -0700 Subject: [PATCH 11/49] noexcept --- src/renderer/dx/DxFontRenderData.cpp | 6 +++--- src/renderer/dx/DxFontRenderData.h | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/renderer/dx/DxFontRenderData.cpp b/src/renderer/dx/DxFontRenderData.cpp index 40d1a24191c..445bbfa83cf 100644 --- a/src/renderer/dx/DxFontRenderData.cpp +++ b/src/renderer/dx/DxFontRenderData.cpp @@ -93,7 +93,7 @@ DxFontRenderData::DxFontRenderData(::Microsoft::WRL::ComPtr dwr return _defaultFontInfo.GetStretch(); } -[[nodiscard]] std::vector DxFontRenderData::DefaultFontFeatures() +[[nodiscard]] std::vector DxFontRenderData::DefaultFontFeatures() noexcept { return _featureVector; } @@ -451,7 +451,7 @@ bool DxFontRenderData::DidUserSetFeatures() const noexcept return _didUserSetFeatures; } -void DxFontRenderData::SetFeatures(std::unordered_map features) noexcept +void DxFontRenderData::SetFeatures(std::unordered_map features) { // update our feature map if (!features.empty()) @@ -477,7 +477,7 @@ void DxFontRenderData::SetFeatures(std::unordered_map axes) noexcept +void DxFontRenderData::SetAxes(std::unordered_map axes) { // update our axis map for (const auto& [axis, value] : axes) diff --git a/src/renderer/dx/DxFontRenderData.h b/src/renderer/dx/DxFontRenderData.h index 37e98a32b37..3ae0157373e 100644 --- a/src/renderer/dx/DxFontRenderData.h +++ b/src/renderer/dx/DxFontRenderData.h @@ -52,7 +52,7 @@ namespace Microsoft::Console::Render [[nodiscard]] DWRITE_FONT_STRETCH DefaultFontStretch() noexcept; // The font features of the default font - [[nodiscard]] std::vector DefaultFontFeatures(); + [[nodiscard]] std::vector DefaultFontFeatures() noexcept; // The DirectWrite format object representing the size and other text properties to be applied (by default) [[nodiscard]] Microsoft::WRL::ComPtr DefaultTextFormat(); @@ -78,8 +78,8 @@ namespace Microsoft::Console::Render [[nodiscard]] static HRESULT STDMETHODCALLTYPE s_CalculateBoxEffect(IDWriteTextFormat* format, size_t widthPixels, IDWriteFontFace1* face, float fontScale, IBoxDrawingEffect** effect) noexcept; bool DidUserSetFeatures() const noexcept; - void SetFeatures(std::unordered_map features) noexcept; - void SetAxes(std::unordered_map axes) noexcept; + void SetFeatures(std::unordered_map features); + void SetAxes(std::unordered_map axes); private: void _BuildFontRenderData(const FontInfoDesired& desired, FontInfo& actual, const int dpi); From 0a9b1ebd31903ecbb7c4cc8eb3bc337e15f72702 Mon Sep 17 00:00:00 2001 From: Pankaj Bhojwani Date: Wed, 30 Jun 2021 16:12:52 -0700 Subject: [PATCH 12/49] comments --- src/cascadia/TerminalControl/ControlCore.cpp | 1 + src/renderer/dx/CustomTextLayout.cpp | 2 ++ src/renderer/dx/DxFontRenderData.cpp | 12 +++++++++++- src/renderer/dx/DxRenderer.cpp | 8 ++++++++ 4 files changed, 22 insertions(+), 1 deletion(-) diff --git a/src/cascadia/TerminalControl/ControlCore.cpp b/src/cascadia/TerminalControl/ControlCore.cpp index e73197e0bfa..ea1e3d13b50 100644 --- a/src/cascadia/TerminalControl/ControlCore.cpp +++ b/src/cascadia/TerminalControl/ControlCore.cpp @@ -604,6 +604,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation if (_renderEngine) { + // Make sure to call these before we call TriggerFontChange _renderEngine->UpdateFontFeatures(_fontFeatures); _renderEngine->UpdateFontAxes(_fontAxes); } diff --git a/src/renderer/dx/CustomTextLayout.cpp b/src/renderer/dx/CustomTextLayout.cpp index e866d4ce67b..fb7e022e2b1 100644 --- a/src/renderer/dx/CustomTextLayout.cpp +++ b/src/renderer/dx/CustomTextLayout.cpp @@ -390,6 +390,7 @@ CATCH_RETURN() std::vector textProps(textLength); std::vector glyphProps(maxGlyphCount); + // Get the features to apply to the font auto features = _fontRenderData->DefaultFontFeatures(); DWRITE_FONT_FEATURE* featureList = features.data(); DWRITE_TYPOGRAPHIC_FEATURES typographicFeatures = { &featureList[0], gsl::narrow(features.size()) }; @@ -1268,6 +1269,7 @@ CATCH_RETURN(); ::Microsoft::WRL::ComPtr format3; if (!FAILED(_formatInUse->QueryInterface(IID_PPV_ARGS(&format3))) && !FAILED(fallback->QueryInterface(IID_PPV_ARGS(&fallback1)))) { + // If the OS supports IDWriteFontFallback1 and IDWriteTextFormat3, we can apply axes of variation to the font const auto axesCount = format3->GetFontAxisValueCount(); std::vector axesVector; axesVector.resize(axesCount); diff --git a/src/renderer/dx/DxFontRenderData.cpp b/src/renderer/dx/DxFontRenderData.cpp index 445bbfa83cf..aa2526a6c5b 100644 --- a/src/renderer/dx/DxFontRenderData.cpp +++ b/src/renderer/dx/DxFontRenderData.cpp @@ -446,11 +446,17 @@ try } CATCH_RETURN() +// Routine Description: +// - Returns whether the user set or updated any of the font features to be applied bool DxFontRenderData::DidUserSetFeatures() const noexcept { return _didUserSetFeatures; } +// Routine Description: +// - Updates our internal map of font features with the given features +// Arguments: +// - features - the features to update our map with void DxFontRenderData::SetFeatures(std::unordered_map features) { // update our feature map @@ -477,6 +483,10 @@ void DxFontRenderData::SetFeatures(std::unordered_map axes) { // update our axis map @@ -695,7 +705,7 @@ Microsoft::WRL::ComPtr DxFontRenderData::_BuildTextFormat(con localeName.data(), &format)); - // Set the font axes + // If the OS supports IDWriteTextFormat3, set the font axes ::Microsoft::WRL::ComPtr format3; if (!FAILED(format->QueryInterface(IID_PPV_ARGS(&format3))) && !_axesMap.empty()) { diff --git a/src/renderer/dx/DxRenderer.cpp b/src/renderer/dx/DxRenderer.cpp index dbb4e7791b4..dfcf6231905 100644 --- a/src/renderer/dx/DxRenderer.cpp +++ b/src/renderer/dx/DxRenderer.cpp @@ -1975,11 +1975,19 @@ CATCH_RETURN() return S_OK; } +// Routine Description: +// - Updates the font render data's internal map of font features with the given features +// Arguments: +// - features - the features to update the map with void DxEngine::UpdateFontFeatures(const std::unordered_map features) noexcept { _fontRenderData->SetFeatures(features); } +// Routine Description: +// - Updates the font render data's internal map of font axes with the given axes +// Arguments: +// - axes - the axes to update the map with void DxEngine::UpdateFontAxes(const std::unordered_map axes) noexcept { _fontRenderData->SetAxes(axes); From 8ec55ad9e36fe0bc3cfc6b6f3c37fd29a156c604 Mon Sep 17 00:00:00 2001 From: Pankaj Bhojwani Date: Thu, 1 Jul 2021 15:40:31 -0700 Subject: [PATCH 13/49] start json parsing --- src/cascadia/TerminalSettingsModel/FontConfig.cpp | 8 ++++++++ src/cascadia/TerminalSettingsModel/FontConfig.h | 5 +++++ src/cascadia/TerminalSettingsModel/FontConfig.idl | 2 ++ 3 files changed, 15 insertions(+) diff --git a/src/cascadia/TerminalSettingsModel/FontConfig.cpp b/src/cascadia/TerminalSettingsModel/FontConfig.cpp index a7c22a58163..d7cb3dccd85 100644 --- a/src/cascadia/TerminalSettingsModel/FontConfig.cpp +++ b/src/cascadia/TerminalSettingsModel/FontConfig.cpp @@ -14,6 +14,7 @@ static constexpr std::string_view FontInfoKey{ "font" }; static constexpr std::string_view FontFaceKey{ "face" }; static constexpr std::string_view FontSizeKey{ "size" }; static constexpr std::string_view FontWeightKey{ "weight" }; +static constexpr std::string_view FontFeaturesKey{ "features" }; static constexpr std::string_view LegacyFontFaceKey{ "fontFace" }; static constexpr std::string_view LegacyFontSizeKey{ "fontSize" }; static constexpr std::string_view LegacyFontWeightKey{ "fontWeight" }; @@ -65,6 +66,13 @@ void FontConfig::LayerJson(const Json::Value& json) JsonUtils::GetValueForKey(fontInfoJson, FontFaceKey, _FontFace); JsonUtils::GetValueForKey(fontInfoJson, FontSizeKey, _FontSize); JsonUtils::GetValueForKey(fontInfoJson, FontWeightKey, _FontWeight); + + if (fontInfoJson.isMember(JsonKey(FontFeaturesKey))) + { + const auto fontFeaturesJson = fontInfoJson[JsonKey(FontFeaturesKey)]; + + const auto ay = 1; + } } else { diff --git a/src/cascadia/TerminalSettingsModel/FontConfig.h b/src/cascadia/TerminalSettingsModel/FontConfig.h index 5ed2bef3d21..16b4d4d21f2 100644 --- a/src/cascadia/TerminalSettingsModel/FontConfig.h +++ b/src/cascadia/TerminalSettingsModel/FontConfig.h @@ -23,6 +23,9 @@ Author(s): #include "IInheritable.h" #include +using IFontAxesMap = winrt::Windows::Foundation::Collections::IMap; +using IFontFeatureMap = winrt::Windows::Foundation::Collections::IMap; + namespace winrt::Microsoft::Terminal::Settings::Model::implementation { struct FontConfig : FontConfigT, IInheritable @@ -39,6 +42,8 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation INHERITABLE_SETTING(Model::FontConfig, hstring, FontFace, DEFAULT_FONT_FACE); INHERITABLE_SETTING(Model::FontConfig, int32_t, FontSize, DEFAULT_FONT_SIZE); INHERITABLE_SETTING(Model::FontConfig, Windows::UI::Text::FontWeight, FontWeight, DEFAULT_FONT_WEIGHT); + INHERITABLE_SETTING(Model::FontConfig, IFontAxesMap, FontAxes); + INHERITABLE_SETTING(Model::FontConfig, IFontFeatureMap, FontFeatures); private: winrt::weak_ref _sourceProfile; diff --git a/src/cascadia/TerminalSettingsModel/FontConfig.idl b/src/cascadia/TerminalSettingsModel/FontConfig.idl index 7bca0ef119d..4a4709d2b67 100644 --- a/src/cascadia/TerminalSettingsModel/FontConfig.idl +++ b/src/cascadia/TerminalSettingsModel/FontConfig.idl @@ -16,5 +16,7 @@ namespace Microsoft.Terminal.Settings.Model INHERITABLE_FONT_SETTING(String, FontFace); INHERITABLE_FONT_SETTING(Int32, FontSize); INHERITABLE_FONT_SETTING(Windows.UI.Text.FontWeight, FontWeight); + Windows.Foundation.Collections.IMap FontFeatures; + Windows.Foundation.Collections.IMap FontAxes; } } From 9d08385e1ac970b495888b0eba3fbd6f0c1a1e85 Mon Sep 17 00:00:00 2001 From: Pankaj Bhojwani Date: Fri, 2 Jul 2021 11:02:31 -0700 Subject: [PATCH 14/49] json parsing --- src/cascadia/TerminalControl/ControlCore.cpp | 18 +++++++-- .../TerminalSettingsModel/FontConfig.cpp | 33 +++++++++++++++- .../TerminalSettings.cpp | 7 +--- src/renderer/dx/DxFontRenderData.cpp | 38 ++++++++++++++----- src/renderer/dx/DxFontRenderData.h | 15 +------- 5 files changed, 78 insertions(+), 33 deletions(-) diff --git a/src/cascadia/TerminalControl/ControlCore.cpp b/src/cascadia/TerminalControl/ControlCore.cpp index ea1e3d13b50..9141bf1fdc4 100644 --- a/src/cascadia/TerminalControl/ControlCore.cpp +++ b/src/cascadia/TerminalControl/ControlCore.cpp @@ -507,13 +507,23 @@ namespace winrt::Microsoft::Terminal::Control::implementation const auto fontFace = _settings.FontFace(); const short fontHeight = ::base::saturated_cast(_settings.FontSize()); const auto fontWeight = _settings.FontWeight(); - for (const auto& [tag, param] : _settings.FontFeatures()) + const auto fontFeatures = _settings.FontFeatures(); + const auto fontAxes = _settings.FontAxes(); + _fontFeatures.clear(); + if (fontFeatures) { - _fontFeatures[tag.data()] = param; + for (const auto& [tag, param] : _settings.FontFeatures()) + { + _fontFeatures[tag.data()] = param; + } } - for (const auto& [axis, value] : _settings.FontAxes()) + _fontAxes.clear(); + if (fontAxes) { - _fontAxes[axis.data()] = value; + for (const auto& [axis, value] : _settings.FontAxes()) + { + _fontAxes[axis.data()] = value; + } } // The font width doesn't terribly matter, we'll only be using the // height to look it up diff --git a/src/cascadia/TerminalSettingsModel/FontConfig.cpp b/src/cascadia/TerminalSettingsModel/FontConfig.cpp index d7cb3dccd85..2643562fecc 100644 --- a/src/cascadia/TerminalSettingsModel/FontConfig.cpp +++ b/src/cascadia/TerminalSettingsModel/FontConfig.cpp @@ -10,11 +10,13 @@ using namespace Microsoft::Terminal::Settings::Model; using namespace winrt::Microsoft::Terminal::Settings::Model::implementation; +static constexpr size_t TagLength{ 4 }; static constexpr std::string_view FontInfoKey{ "font" }; static constexpr std::string_view FontFaceKey{ "face" }; static constexpr std::string_view FontSizeKey{ "size" }; static constexpr std::string_view FontWeightKey{ "weight" }; static constexpr std::string_view FontFeaturesKey{ "features" }; +static constexpr std::string_view FontAxesKey{ "axes" }; static constexpr std::string_view LegacyFontFaceKey{ "fontFace" }; static constexpr std::string_view LegacyFontSizeKey{ "fontSize" }; static constexpr std::string_view LegacyFontWeightKey{ "fontWeight" }; @@ -69,9 +71,36 @@ void FontConfig::LayerJson(const Json::Value& json) if (fontInfoJson.isMember(JsonKey(FontFeaturesKey))) { + std::unordered_map featureMap; const auto fontFeaturesJson = fontInfoJson[JsonKey(FontFeaturesKey)]; - - const auto ay = 1; + const auto featureNames = fontFeaturesJson.getMemberNames(); + for (const auto& featureName : featureNames) + { + // Check that the feature is well-formed, i.e. that the length of the tag is exactly TagLength + // and the value is an UInt + if (featureName.length() == TagLength && fontFeaturesJson[JsonKey(featureName)].isUInt()) + { + featureMap[winrt::to_hstring(featureName)] = fontFeaturesJson[JsonKey(featureName)].asUInt(); + } + } + _FontFeatures = single_threaded_map(std::move(featureMap)); + } + + if (fontInfoJson.isMember(JsonKey(FontAxesKey))) + { + std::unordered_map axesMap; + const auto fontAxesJson = fontInfoJson[JsonKey(FontAxesKey)]; + const auto axesNames = fontAxesJson.getMemberNames(); + for (const auto& axisName : axesNames) + { + // Check that the axis is well-formed, i.e. that the length of the tag is exactly TagLength + // and the value is an Int64 + if (fontAxesJson[JsonKey(axisName)].isInt64()) + { + axesMap[winrt::to_hstring(axisName)] = fontAxesJson[JsonKey(axisName)].asInt64(); + } + } + _FontAxes = single_threaded_map(std::move(axesMap)); } } else diff --git a/src/cascadia/TerminalSettingsModel/TerminalSettings.cpp b/src/cascadia/TerminalSettingsModel/TerminalSettings.cpp index 763bd9aab6b..43a96fb6277 100644 --- a/src/cascadia/TerminalSettingsModel/TerminalSettings.cpp +++ b/src/cascadia/TerminalSettingsModel/TerminalSettings.cpp @@ -263,6 +263,8 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation _FontFace = profile.FontInfo().FontFace(); _FontSize = profile.FontInfo().FontSize(); _FontWeight = profile.FontInfo().FontWeight(); + _FontFeatures = profile.FontInfo().FontFeatures(); + _FontAxes = profile.FontInfo().FontAxes(); _Padding = profile.Padding(); _Commandline = profile.Commandline(); @@ -287,11 +289,6 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation const til::color colorRef{ profile.TabColor().Value() }; _TabColor = static_cast(colorRef); } - std::unordered_map featMap{ { L"subs", 1 } }; - _FontFeatures = single_threaded_map(std::move(featMap)); - - std::unordered_map axesMap{ { L"wght", 900 }, { L"slnt", 70 } }; - _FontAxes = single_threaded_map(std::move(axesMap)); } // Method Description: diff --git a/src/renderer/dx/DxFontRenderData.cpp b/src/renderer/dx/DxFontRenderData.cpp index aa2526a6c5b..ffd91a67740 100644 --- a/src/renderer/dx/DxFontRenderData.cpp +++ b/src/renderer/dx/DxFontRenderData.cpp @@ -453,13 +453,36 @@ bool DxFontRenderData::DidUserSetFeatures() const noexcept return _didUserSetFeatures; } +// Routine Description: +// - Clears our internal feature map and populates it with the list of standard features +void DxFontRenderData::InitializeFeatureMap() +{ + _featureMap.clear(); + _featureMap = { + { L"rlig", 1 }, + { L"rclt", 1 }, + { L"locl", 1 }, + { L"ccmp", 1 }, + { L"calt", 1 }, + { L"liga", 1 }, + { L"clig", 1 }, + { L"kern", 1 }, + { L"mark", 1 }, + { L"mkmk", 1 }, + { L"dist", 1 } + }; +} + // Routine Description: // - Updates our internal map of font features with the given features // Arguments: // - features - the features to update our map with void DxFontRenderData::SetFeatures(std::unordered_map features) { - // update our feature map + // Populate our feature map with the standard list + InitializeFeatureMap(); + + // Update our feature map with the provided features if (!features.empty()) { for (const auto& [tag, param] : features) @@ -469,15 +492,10 @@ void DxFontRenderData::SetFeatures(std::unordered_map axes) { - // update our axis map + _axesMap.clear(); + + // Update our axis map with the provided axes for (const auto& [axis, value] : axes) { _axesMap[axis] = value; diff --git a/src/renderer/dx/DxFontRenderData.h b/src/renderer/dx/DxFontRenderData.h index 3ae0157373e..e8e948759c7 100644 --- a/src/renderer/dx/DxFontRenderData.h +++ b/src/renderer/dx/DxFontRenderData.h @@ -78,6 +78,7 @@ namespace Microsoft::Console::Render [[nodiscard]] static HRESULT STDMETHODCALLTYPE s_CalculateBoxEffect(IDWriteTextFormat* format, size_t widthPixels, IDWriteFontFace1* face, float fontScale, IBoxDrawingEffect** effect) noexcept; bool DidUserSetFeatures() const noexcept; + void InitializeFeatureMap(); void SetFeatures(std::unordered_map features); void SetAxes(std::unordered_map axes); @@ -87,19 +88,7 @@ namespace Microsoft::Console::Render bool _didUserSetFeatures{ false }; // The font features to apply to the text - std::unordered_map _featureMap{ - { L"rlig", 1 }, - { L"rclt", 1 }, - { L"locl", 1 }, - { L"ccmp", 1 }, - { L"calt", 1 }, - { L"liga", 1 }, - { L"clig", 1 }, - { L"kern", 1 }, - { L"mark", 1 }, - { L"mkmk", 1 }, - { L"dist", 1 } - }; + std::unordered_map _featureMap; std::vector _featureVector; // The font axes to apply to the text From 87fca5cc88a56c46d1c6e6a0d3c2839de5e70d62 Mon Sep 17 00:00:00 2001 From: Pankaj Bhojwani Date: Fri, 2 Jul 2021 11:15:19 -0700 Subject: [PATCH 15/49] mark todos, consistent naming --- src/cascadia/TerminalControl/ControlCore.cpp | 8 ++++---- src/cascadia/TerminalSettingsModel/FontConfig.cpp | 2 ++ src/renderer/dx/DxFontRenderData.cpp | 8 ++------ src/renderer/dx/DxRenderer.cpp | 4 ++-- src/renderer/dx/DxRenderer.hpp | 4 ++-- 5 files changed, 12 insertions(+), 14 deletions(-) diff --git a/src/cascadia/TerminalControl/ControlCore.cpp b/src/cascadia/TerminalControl/ControlCore.cpp index 9141bf1fdc4..e212c9cce61 100644 --- a/src/cascadia/TerminalControl/ControlCore.cpp +++ b/src/cascadia/TerminalControl/ControlCore.cpp @@ -159,8 +159,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation // Initialize our font with the renderer // We don't have to care about DPI. We'll get a change message immediately if it's not 96 // and react accordingly. - dxEngine->UpdateFontFeatures(_fontFeatures); - dxEngine->UpdateFontAxes(_fontAxes); + dxEngine->SetFontFeatures(_fontFeatures); + dxEngine->SetFontAxes(_fontAxes); _updateFont(true); const COORD windowSize{ static_cast(windowWidth), @@ -615,8 +615,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation if (_renderEngine) { // Make sure to call these before we call TriggerFontChange - _renderEngine->UpdateFontFeatures(_fontFeatures); - _renderEngine->UpdateFontAxes(_fontAxes); + _renderEngine->SetFontFeatures(_fontFeatures); + _renderEngine->SetFontAxes(_fontAxes); } // TODO: MSFT:20895307 If the font doesn't exist, this doesn't diff --git a/src/cascadia/TerminalSettingsModel/FontConfig.cpp b/src/cascadia/TerminalSettingsModel/FontConfig.cpp index 2643562fecc..f570256fd00 100644 --- a/src/cascadia/TerminalSettingsModel/FontConfig.cpp +++ b/src/cascadia/TerminalSettingsModel/FontConfig.cpp @@ -78,6 +78,7 @@ void FontConfig::LayerJson(const Json::Value& json) { // Check that the feature is well-formed, i.e. that the length of the tag is exactly TagLength // and the value is an UInt + // todo: ouput a warning if we find a badly formed feature? if (featureName.length() == TagLength && fontFeaturesJson[JsonKey(featureName)].isUInt()) { featureMap[winrt::to_hstring(featureName)] = fontFeaturesJson[JsonKey(featureName)].asUInt(); @@ -95,6 +96,7 @@ void FontConfig::LayerJson(const Json::Value& json) { // Check that the axis is well-formed, i.e. that the length of the tag is exactly TagLength // and the value is an Int64 + // todo: ouput a warning if we find a badly formed axis? if (fontAxesJson[JsonKey(axisName)].isInt64()) { axesMap[winrt::to_hstring(axisName)] = fontAxesJson[JsonKey(axisName)].asInt64(); diff --git a/src/renderer/dx/DxFontRenderData.cpp b/src/renderer/dx/DxFontRenderData.cpp index ffd91a67740..d38270e4d63 100644 --- a/src/renderer/dx/DxFontRenderData.cpp +++ b/src/renderer/dx/DxFontRenderData.cpp @@ -514,6 +514,8 @@ void DxFontRenderData::SetAxes(std::unordered_map ax { _axesMap[axis] = value; } + + // todo: We probably want a 'complete missing axes values' here } // Routine Description: @@ -732,12 +734,6 @@ Microsoft::WRL::ComPtr DxFontRenderData::_BuildTextFormat(con std::vector axesVector; for (const auto& [axis, value] : _axesMap) { - if (axis.length() != 4) - { - // ignore badly formed tags - // maybe this shouldn't be here? maybe this check should be at settings model side to output a warning to user? - continue; - } const auto dwriteTag = DWRITE_MAKE_FONT_AXIS_TAG(axis[0], axis[1], axis[2], axis[3]); axesVector.push_back(DWRITE_FONT_AXIS_VALUE{ dwriteTag, gsl::narrow(value) }); } diff --git a/src/renderer/dx/DxRenderer.cpp b/src/renderer/dx/DxRenderer.cpp index dfcf6231905..e73cdaad1f3 100644 --- a/src/renderer/dx/DxRenderer.cpp +++ b/src/renderer/dx/DxRenderer.cpp @@ -1979,7 +1979,7 @@ CATCH_RETURN() // - Updates the font render data's internal map of font features with the given features // Arguments: // - features - the features to update the map with -void DxEngine::UpdateFontFeatures(const std::unordered_map features) noexcept +void DxEngine::SetFontFeatures(const std::unordered_map features) noexcept { _fontRenderData->SetFeatures(features); } @@ -1988,7 +1988,7 @@ void DxEngine::UpdateFontFeatures(const std::unordered_map axes) noexcept +void DxEngine::SetFontAxes(const std::unordered_map axes) noexcept { _fontRenderData->SetAxes(axes); } diff --git a/src/renderer/dx/DxRenderer.hpp b/src/renderer/dx/DxRenderer.hpp index 2cc45ed3641..027daf71927 100644 --- a/src/renderer/dx/DxRenderer.hpp +++ b/src/renderer/dx/DxRenderer.hpp @@ -72,8 +72,8 @@ namespace Microsoft::Console::Render HANDLE GetSwapChainHandle(); - void UpdateFontFeatures(const std::unordered_map features) noexcept; - void UpdateFontAxes(const std::unordered_map axes) noexcept; + void SetFontFeatures(const std::unordered_map features) noexcept; + void SetFontAxes(const std::unordered_map axes) noexcept; // IRenderEngine Members [[nodiscard]] HRESULT Invalidate(const SMALL_RECT* const psrRegion) noexcept override; From b14360cc3033c3663f9790dc96417ea15e21925d Mon Sep 17 00:00:00 2001 From: Pankaj Bhojwani Date: Fri, 2 Jul 2021 11:52:29 -0700 Subject: [PATCH 16/49] fix errors? --- src/renderer/dx/CustomTextLayout.cpp | 5 +++-- src/renderer/dx/DxFontRenderData.cpp | 16 ++++++++-------- src/renderer/dx/DxFontRenderData.h | 2 +- 3 files changed, 12 insertions(+), 11 deletions(-) diff --git a/src/renderer/dx/CustomTextLayout.cpp b/src/renderer/dx/CustomTextLayout.cpp index fb7e022e2b1..cc5d017d2e1 100644 --- a/src/renderer/dx/CustomTextLayout.cpp +++ b/src/renderer/dx/CustomTextLayout.cpp @@ -396,6 +396,7 @@ CATCH_RETURN() DWRITE_TYPOGRAPHIC_FEATURES typographicFeatures = { &featureList[0], gsl::narrow(features.size()) }; DWRITE_TYPOGRAPHIC_FEATURES const* typographicFeaturesPointer = &typographicFeatures; const uint32_t fontFeatureLengths[1] = { textLength }; + const auto featureLengthsSpan = gsl::make_span(fontFeatureLengths); // Get the glyphs from the text, retrying if needed. @@ -414,7 +415,7 @@ CATCH_RETURN() _localeName.data(), (run.isNumberSubstituted) ? _numberSubstitution.Get() : nullptr, &typographicFeaturesPointer, // features - fontFeatureLengths, // featureLengths + featureLengthsSpan.data(), // featureLengths 1, // featureCount maxGlyphCount, // maxGlyphCount &_glyphClusters.at(textStart), @@ -464,7 +465,7 @@ CATCH_RETURN() &run.script, _localeName.data(), &typographicFeaturesPointer, // features - fontFeatureLengths, // featureLengths + featureLengthsSpan.data(), // featureLengths 1, // featureCount &_glyphAdvances.at(glyphStart), &_glyphOffsets.at(glyphStart)); diff --git a/src/renderer/dx/DxFontRenderData.cpp b/src/renderer/dx/DxFontRenderData.cpp index d38270e4d63..1e17f11f574 100644 --- a/src/renderer/dx/DxFontRenderData.cpp +++ b/src/renderer/dx/DxFontRenderData.cpp @@ -93,7 +93,7 @@ DxFontRenderData::DxFontRenderData(::Microsoft::WRL::ComPtr dwr return _defaultFontInfo.GetStretch(); } -[[nodiscard]] std::vector DxFontRenderData::DefaultFontFeatures() noexcept +[[nodiscard]] std::vector DxFontRenderData::DefaultFontFeatures() { return _featureVector; } @@ -485,7 +485,7 @@ void DxFontRenderData::SetFeatures(std::unordered_map ax _axesMap.clear(); // Update our axis map with the provided axes - for (const auto& [axis, value] : axes) + for (const auto [axis, value] : axes) { _axesMap[axis] = value; } @@ -732,12 +732,12 @@ Microsoft::WRL::ComPtr DxFontRenderData::_BuildTextFormat(con if (!FAILED(format->QueryInterface(IID_PPV_ARGS(&format3))) && !_axesMap.empty()) { std::vector axesVector; - for (const auto& [axis, value] : _axesMap) + for (const auto [axis, value] : _axesMap) { - const auto dwriteTag = DWRITE_MAKE_FONT_AXIS_TAG(axis[0], axis[1], axis[2], axis[3]); + const auto dwriteTag = DWRITE_MAKE_FONT_AXIS_TAG(gsl::at(axis, 0), gsl::at(axis, 1), gsl::at(axis, 2), gsl::at(axis, 3)); axesVector.push_back(DWRITE_FONT_AXIS_VALUE{ dwriteTag, gsl::narrow(value) }); } - DWRITE_FONT_AXIS_VALUE* axesList = &axesVector[0]; + DWRITE_FONT_AXIS_VALUE const* axesList = &axesVector[0]; format3->SetFontAxisValues(axesList, gsl::narrow(axesVector.size())); } diff --git a/src/renderer/dx/DxFontRenderData.h b/src/renderer/dx/DxFontRenderData.h index e8e948759c7..b15b26a0e58 100644 --- a/src/renderer/dx/DxFontRenderData.h +++ b/src/renderer/dx/DxFontRenderData.h @@ -52,7 +52,7 @@ namespace Microsoft::Console::Render [[nodiscard]] DWRITE_FONT_STRETCH DefaultFontStretch() noexcept; // The font features of the default font - [[nodiscard]] std::vector DefaultFontFeatures() noexcept; + [[nodiscard]] std::vector DefaultFontFeatures(); // The DirectWrite format object representing the size and other text properties to be applied (by default) [[nodiscard]] Microsoft::WRL::ComPtr DefaultTextFormat(); From 5c1be4fb94b342501376d94167d2906cf39c576d Mon Sep 17 00:00:00 2001 From: Pankaj Bhojwani Date: Fri, 2 Jul 2021 12:01:02 -0700 Subject: [PATCH 17/49] more errors --- src/renderer/dx/DxFontRenderData.cpp | 2 +- src/renderer/dx/DxRenderer.cpp | 4 ++-- src/renderer/dx/DxRenderer.hpp | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/renderer/dx/DxFontRenderData.cpp b/src/renderer/dx/DxFontRenderData.cpp index 1e17f11f574..1a0becce0d6 100644 --- a/src/renderer/dx/DxFontRenderData.cpp +++ b/src/renderer/dx/DxFontRenderData.cpp @@ -737,7 +737,7 @@ Microsoft::WRL::ComPtr DxFontRenderData::_BuildTextFormat(con const auto dwriteTag = DWRITE_MAKE_FONT_AXIS_TAG(gsl::at(axis, 0), gsl::at(axis, 1), gsl::at(axis, 2), gsl::at(axis, 3)); axesVector.push_back(DWRITE_FONT_AXIS_VALUE{ dwriteTag, gsl::narrow(value) }); } - DWRITE_FONT_AXIS_VALUE const* axesList = &axesVector[0]; + DWRITE_FONT_AXIS_VALUE const* axesList = &gsl::at(axesVector, 0); format3->SetFontAxisValues(axesList, gsl::narrow(axesVector.size())); } diff --git a/src/renderer/dx/DxRenderer.cpp b/src/renderer/dx/DxRenderer.cpp index e73cdaad1f3..a0acfefc860 100644 --- a/src/renderer/dx/DxRenderer.cpp +++ b/src/renderer/dx/DxRenderer.cpp @@ -1979,7 +1979,7 @@ CATCH_RETURN() // - Updates the font render data's internal map of font features with the given features // Arguments: // - features - the features to update the map with -void DxEngine::SetFontFeatures(const std::unordered_map features) noexcept +void DxEngine::SetFontFeatures(const std::unordered_map features) { _fontRenderData->SetFeatures(features); } @@ -1988,7 +1988,7 @@ void DxEngine::SetFontFeatures(const std::unordered_map axes) noexcept +void DxEngine::SetFontAxes(const std::unordered_map axes) { _fontRenderData->SetAxes(axes); } diff --git a/src/renderer/dx/DxRenderer.hpp b/src/renderer/dx/DxRenderer.hpp index 027daf71927..e66a0e64643 100644 --- a/src/renderer/dx/DxRenderer.hpp +++ b/src/renderer/dx/DxRenderer.hpp @@ -72,8 +72,8 @@ namespace Microsoft::Console::Render HANDLE GetSwapChainHandle(); - void SetFontFeatures(const std::unordered_map features) noexcept; - void SetFontAxes(const std::unordered_map axes) noexcept; + void SetFontFeatures(const std::unordered_map features); + void SetFontAxes(const std::unordered_map axes); // IRenderEngine Members [[nodiscard]] HRESULT Invalidate(const SMALL_RECT* const psrRegion) noexcept override; From 1bb1d10919dd9fb2caa729df124d7b49b8d5ec16 Mon Sep 17 00:00:00 2001 From: Pankaj Bhojwani Date: Tue, 6 Jul 2021 11:32:51 -0700 Subject: [PATCH 18/49] json utils works, todo complete missing axes --- src/cascadia/TerminalControl/ControlCore.h | 2 +- .../TerminalControl/IControlSettings.idl | 2 +- .../TerminalSettingsModel/FontConfig.cpp | 38 +---- .../TerminalSettingsModel/FontConfig.h | 2 +- .../TerminalSettingsModel/FontConfig.idl | 2 +- .../TerminalSettingsModel/JsonUtils.h | 156 ++++++++++++++++++ .../TerminalSettingsModel/TerminalSettings.h | 2 +- .../UnitTests_Control/MockControlSettings.h | 2 +- src/renderer/dx/CustomTextLayout.cpp | 89 +++++++++- src/renderer/dx/CustomTextLayout.h | 5 + src/renderer/dx/DxFontRenderData.cpp | 2 +- src/renderer/dx/DxFontRenderData.h | 4 +- src/renderer/dx/DxRenderer.cpp | 2 +- src/renderer/dx/DxRenderer.hpp | 2 +- 14 files changed, 257 insertions(+), 53 deletions(-) diff --git a/src/cascadia/TerminalControl/ControlCore.h b/src/cascadia/TerminalControl/ControlCore.h index 3fb8bf6d096..a8f20f6559a 100644 --- a/src/cascadia/TerminalControl/ControlCore.h +++ b/src/cascadia/TerminalControl/ControlCore.h @@ -184,7 +184,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation FontInfoDesired _desiredFont; FontInfo _actualFont; std::unordered_map _fontFeatures; - std::unordered_map _fontAxes; + std::unordered_map _fontAxes; // storage location for the leading surrogate of a utf-16 surrogate pair std::optional _leadingSurrogate{ std::nullopt }; diff --git a/src/cascadia/TerminalControl/IControlSettings.idl b/src/cascadia/TerminalControl/IControlSettings.idl index d218f90f070..fd0a4d2a7aa 100644 --- a/src/cascadia/TerminalControl/IControlSettings.idl +++ b/src/cascadia/TerminalControl/IControlSettings.idl @@ -37,7 +37,7 @@ namespace Microsoft.Terminal.Control Windows.UI.Text.FontWeight FontWeight; String Padding; Windows.Foundation.Collections.IMap FontFeatures; - Windows.Foundation.Collections.IMap FontAxes; + Windows.Foundation.Collections.IMap FontAxes; Microsoft.Terminal.Control.IKeyBindings KeyBindings; diff --git a/src/cascadia/TerminalSettingsModel/FontConfig.cpp b/src/cascadia/TerminalSettingsModel/FontConfig.cpp index f570256fd00..579479a74e5 100644 --- a/src/cascadia/TerminalSettingsModel/FontConfig.cpp +++ b/src/cascadia/TerminalSettingsModel/FontConfig.cpp @@ -68,42 +68,8 @@ void FontConfig::LayerJson(const Json::Value& json) JsonUtils::GetValueForKey(fontInfoJson, FontFaceKey, _FontFace); JsonUtils::GetValueForKey(fontInfoJson, FontSizeKey, _FontSize); JsonUtils::GetValueForKey(fontInfoJson, FontWeightKey, _FontWeight); - - if (fontInfoJson.isMember(JsonKey(FontFeaturesKey))) - { - std::unordered_map featureMap; - const auto fontFeaturesJson = fontInfoJson[JsonKey(FontFeaturesKey)]; - const auto featureNames = fontFeaturesJson.getMemberNames(); - for (const auto& featureName : featureNames) - { - // Check that the feature is well-formed, i.e. that the length of the tag is exactly TagLength - // and the value is an UInt - // todo: ouput a warning if we find a badly formed feature? - if (featureName.length() == TagLength && fontFeaturesJson[JsonKey(featureName)].isUInt()) - { - featureMap[winrt::to_hstring(featureName)] = fontFeaturesJson[JsonKey(featureName)].asUInt(); - } - } - _FontFeatures = single_threaded_map(std::move(featureMap)); - } - - if (fontInfoJson.isMember(JsonKey(FontAxesKey))) - { - std::unordered_map axesMap; - const auto fontAxesJson = fontInfoJson[JsonKey(FontAxesKey)]; - const auto axesNames = fontAxesJson.getMemberNames(); - for (const auto& axisName : axesNames) - { - // Check that the axis is well-formed, i.e. that the length of the tag is exactly TagLength - // and the value is an Int64 - // todo: ouput a warning if we find a badly formed axis? - if (fontAxesJson[JsonKey(axisName)].isInt64()) - { - axesMap[winrt::to_hstring(axisName)] = fontAxesJson[JsonKey(axisName)].asInt64(); - } - } - _FontAxes = single_threaded_map(std::move(axesMap)); - } + JsonUtils::GetValueForKey(fontInfoJson, FontFeaturesKey, _FontFeatures); + JsonUtils::GetValueForKey(fontInfoJson, FontAxesKey, _FontAxes); } else { diff --git a/src/cascadia/TerminalSettingsModel/FontConfig.h b/src/cascadia/TerminalSettingsModel/FontConfig.h index 16b4d4d21f2..29d51e684cb 100644 --- a/src/cascadia/TerminalSettingsModel/FontConfig.h +++ b/src/cascadia/TerminalSettingsModel/FontConfig.h @@ -23,7 +23,7 @@ Author(s): #include "IInheritable.h" #include -using IFontAxesMap = winrt::Windows::Foundation::Collections::IMap; +using IFontAxesMap = winrt::Windows::Foundation::Collections::IMap; using IFontFeatureMap = winrt::Windows::Foundation::Collections::IMap; namespace winrt::Microsoft::Terminal::Settings::Model::implementation diff --git a/src/cascadia/TerminalSettingsModel/FontConfig.idl b/src/cascadia/TerminalSettingsModel/FontConfig.idl index 4a4709d2b67..3532a1ca03c 100644 --- a/src/cascadia/TerminalSettingsModel/FontConfig.idl +++ b/src/cascadia/TerminalSettingsModel/FontConfig.idl @@ -17,6 +17,6 @@ namespace Microsoft.Terminal.Settings.Model INHERITABLE_FONT_SETTING(Int32, FontSize); INHERITABLE_FONT_SETTING(Windows.UI.Text.FontWeight, FontWeight); Windows.Foundation.Collections.IMap FontFeatures; - Windows.Foundation.Collections.IMap FontAxes; + Windows.Foundation.Collections.IMap FontAxes; } } diff --git a/src/cascadia/TerminalSettingsModel/JsonUtils.h b/src/cascadia/TerminalSettingsModel/JsonUtils.h index efb3c076457..49d5fb3504e 100644 --- a/src/cascadia/TerminalSettingsModel/JsonUtils.h +++ b/src/cascadia/TerminalSettingsModel/JsonUtils.h @@ -177,6 +177,110 @@ namespace Microsoft::Terminal::Settings::Model::JsonUtils } }; + template + struct ConversionTrait> + { + std::unordered_map FromJson(const Json::Value& json) const + { + ConversionTrait trait; + std::unordered_map val; + + for (const auto& element : json.getMemberNames()) + { + val[element.c_str()] = trait.FromJson(json[JsonKey(element)]); + } + + return val; + } + + bool CanConvert(const Json::Value& json) const + { + if (!json.isObject()) + { + return false; + } + ConversionTrait trait; + for (const auto& element : json.getMemberNames()) + { + if (!trait.CanConvert(json[JsonKey(element)])) + { + return false; + } + } + return true; + } + + Json::Value ToJson(const std::unordered_map& val) + { + ConversionTrait trait; + Json::Value json{ Json::objectValue }; + + for (const auto& [k, v] : val) + { + json[JsonKey(k)] = trait.ToJson(v); + } + + return json; + } + + std::string TypeDescription() const + { + return "map"; + } + }; + + template + struct ConversionTrait> + { + std::unordered_map FromJson(const Json::Value& json) const + { + ConversionTrait trait; + std::unordered_map val; + + for (const auto& element : json.getMemberNames()) + { + val[til::u8u16(Detail::GetStringView(json))] = trait.FromJson(json[JsonKey(element)]); + } + + return val; + } + + bool CanConvert(const Json::Value& json) const + { + if (!json.isObject()) + { + return false; + } + ConversionTrait trait; + for (const auto& element : json.getMemberNames()) + { + if (!trait.CanConvert(json[JsonKey(element)])) + { + return false; + } + } + return true; + } + + Json::Value ToJson(const std::unordered_map& val) + { + ConversionTrait trait; + Json::Value json{ Json::objectValue }; + + for (const auto& [k, v] : val) + { + json[JsonKey(k)] = trait.ToJson(v); + } + + return json; + } + + std::string TypeDescription() const + { + return "map"; + } + }; + #ifdef WINRT_BASE_H template<> struct ConversionTrait : public ConversionTrait @@ -206,6 +310,58 @@ namespace Microsoft::Terminal::Settings::Model::JsonUtils return ConversionTrait::CanConvert(json) || json.isNull(); } }; + + template + struct ConversionTrait> + { + winrt::Windows::Foundation::Collections::IMap FromJson(const Json::Value& json) const + { + ConversionTrait trait; + std::unordered_map val; + + for (const auto& element : json.getMemberNames()) + { + val[winrt::to_hstring(element)] = trait.FromJson(json[JsonKey(element)]); + } + + return winrt::single_threaded_map(std::move(val)); + } + + bool CanConvert(const Json::Value& json) const + { + if (!json.isObject()) + { + return false; + } + ConversionTrait trait; + for (const auto& element : json.getMemberNames()) + { + if (!trait.CanConvert(json[JsonKey(element)])) + { + return false; + } + } + return true; + } + + Json::Value ToJson(const winrt::Windows::Foundation::Collections::IMap& val) + { + ConversionTrait trait; + Json::Value json{ Json::objectValue }; + + for (const auto& [k, v] : val) + { + json[JsonKey(k)] = trait.ToJson(v); + } + + return json; + } + + std::string TypeDescription() const + { + return "map"; + } + }; #endif template<> diff --git a/src/cascadia/TerminalSettingsModel/TerminalSettings.h b/src/cascadia/TerminalSettingsModel/TerminalSettings.h index 189578b268a..f7c8067b5f9 100644 --- a/src/cascadia/TerminalSettingsModel/TerminalSettings.h +++ b/src/cascadia/TerminalSettingsModel/TerminalSettings.h @@ -21,7 +21,7 @@ Author(s): #include #include -using IFontAxesMap = winrt::Windows::Foundation::Collections::IMap; +using IFontAxesMap = winrt::Windows::Foundation::Collections::IMap; using IFontFeatureMap = winrt::Windows::Foundation::Collections::IMap; // fwdecl unittest classes diff --git a/src/cascadia/UnitTests_Control/MockControlSettings.h b/src/cascadia/UnitTests_Control/MockControlSettings.h index d444089112d..84ffb16daf0 100644 --- a/src/cascadia/UnitTests_Control/MockControlSettings.h +++ b/src/cascadia/UnitTests_Control/MockControlSettings.h @@ -9,7 +9,7 @@ Licensed under the MIT license. #include using IFontFeatureMap = winrt::Windows::Foundation::Collections::IMap; -using IFontAxesMap = winrt::Windows::Foundation::Collections::IMap; +using IFontAxesMap = winrt::Windows::Foundation::Collections::IMap; namespace ControlUnitTests { diff --git a/src/renderer/dx/CustomTextLayout.cpp b/src/renderer/dx/CustomTextLayout.cpp index cc5d017d2e1..1b48f919c51 100644 --- a/src/renderer/dx/CustomTextLayout.cpp +++ b/src/renderer/dx/CustomTextLayout.cpp @@ -1224,6 +1224,87 @@ CATCH_RETURN(); #pragma endregion #pragma region internal methods for mimicking text analyzer pattern but for font fallback +// Method Description: +// - Fill any missing axis values that might be known but were unspecified, such as omitting +// the 'wght' axis tag but specifying the old DWRITE_FONT_WEIGHT enum +// Arguments: +// - todo: fill this out +std::vector CustomTextLayout::GetAxisVector(DWRITE_FONT_WEIGHT /*fontWeight*/, + DWRITE_FONT_STRETCH /*fontStretch*/, + DWRITE_FONT_STYLE /*fontStyle*/, + float /*fontSize*/, + ::Microsoft::WRL::ComPtr format) +{ + // todo: complete this function + //enum AxisTagPresence + //{ + // AxisTagPresenceNone = 0, + // AxisTagPresenceWeight = 1, + // AxisTagPresenceWidth = 2, + // AxisTagPresenceItalic = 4, + // AxisTagPresenceSlant = 8, + // AxisTagPresenceOpticalSize = 16, + //}; + const auto axesCount = format->GetFontAxisValueCount(); + std::vector axesVector; + axesVector.resize(axesCount); + format->GetFontAxisValues(axesVector.data(), axesCount); + + //uint32_t axisTagPresence = AxisTagPresenceNone; + //for (auto& fontAxisValue : axesVector) + //{ + // switch (fontAxisValue.axisTag) + // { + // case DWRITE_FONT_AXIS_TAG_WEIGHT: + // axisTagPresence |= AxisTagPresenceWeight; + // break; + // case DWRITE_FONT_AXIS_TAG_WIDTH: + // axisTagPresence |= AxisTagPresenceWidth; + // break; + // case DWRITE_FONT_AXIS_TAG_ITALIC: + // axisTagPresence |= AxisTagPresenceItalic; + // break; + // case DWRITE_FONT_AXIS_TAG_SLANT: + // axisTagPresence |= AxisTagPresenceSlant; + // break; + // case DWRITE_FONT_AXIS_TAG_OPTICAL_SIZE: + // axisTagPresence |= AxisTagPresenceOpticalSize; + // break; + // } + //} + + //if ((axisTagPresence & AxisTagPresenceWeight) == 0) + //{ + // axesVector.push_back({ DWRITE_FONT_AXIS_TAG_WEIGHT, float(fontWeight) }); + //} + //if ((axisTagPresence & AxisTagPresenceWidth) == 0) + //{ + // auto ayy1 = 1; + // //auto value = FontStretchToWidthAxisValue(fontStretch); + // axesVector.push_back({ DWRITE_FONT_AXIS_TAG_WIDTH, gsl::narrow(ayy1) }); + //} + //if ((axisTagPresence & AxisTagPresenceItalic) == 0) + //{ + // auto ayy2 = 1; + // //auto value = FontStyleToItalicFixedAxisValue(fontStyle); + // axesVector.push_back({ DWRITE_FONT_AXIS_TAG_ITALIC, gsl::narrow(ayy2) }); + //} + //if ((axisTagPresence & AxisTagPresenceSlant) == 0) + //{ + // auto ayy3 = 1; + // //auto value = FontStyleToSlantFixedAxisValue(fontStyle); + // axesVector.push_back({ DWRITE_FONT_AXIS_TAG_SLANT, gsl::narrow(ayy3) }); + //} + //if ((axisTagPresence & AxisTagPresenceOpticalSize) == 0) + //{ + // auto pointSize = 1; + // //const auto pointSize = DIPsToPoints(fontSize); + // axesVector.push_back({ DWRITE_FONT_AXIS_TAG_OPTICAL_SIZE, gsl::narrow(pointSize) }); + //} + + return axesVector; +} + // Routine Description: // - Mimics an IDWriteTextAnalyser but for font fallback calculations. // Arguments: @@ -1271,11 +1352,7 @@ CATCH_RETURN(); if (!FAILED(_formatInUse->QueryInterface(IID_PPV_ARGS(&format3))) && !FAILED(fallback->QueryInterface(IID_PPV_ARGS(&fallback1)))) { // If the OS supports IDWriteFontFallback1 and IDWriteTextFormat3, we can apply axes of variation to the font - const auto axesCount = format3->GetFontAxisValueCount(); - std::vector axesVector; - axesVector.resize(axesCount); - const auto res = format3->GetFontAxisValues(axesVector.data(), axesCount); - + const auto axesVector = GetAxisVector(weight, stretch, style, format1->GetFontSize(), format3); // Walk through and analyze the entire string while (textLength > 0) { @@ -1289,7 +1366,7 @@ CATCH_RETURN(); collection.Get(), familyName.data(), axesVector.data(), - axesCount, + gsl::narrow(axesVector.size()), &mappedLength, &scale, &mappedFont); diff --git a/src/renderer/dx/CustomTextLayout.h b/src/renderer/dx/CustomTextLayout.h index 81d1e9769e6..11daba99322 100644 --- a/src/renderer/dx/CustomTextLayout.h +++ b/src/renderer/dx/CustomTextLayout.h @@ -125,6 +125,11 @@ namespace Microsoft::Console::Render void _SplitCurrentRun(const UINT32 splitPosition); void _OrderRuns(); + std::vector GetAxisVector(DWRITE_FONT_WEIGHT fontWeight, + DWRITE_FONT_STRETCH fontStretch, + DWRITE_FONT_STYLE fontStyle, + float fontSize, + ::Microsoft::WRL::ComPtr format); [[nodiscard]] HRESULT STDMETHODCALLTYPE _AnalyzeFontFallback(IDWriteTextAnalysisSource* const source, UINT32 textPosition, UINT32 textLength); [[nodiscard]] HRESULT STDMETHODCALLTYPE _SetMappedFont(UINT32 textPosition, UINT32 textLength, IDWriteFont* const font, FLOAT const scale); [[nodiscard]] HRESULT STDMETHODCALLTYPE _SetMappedFontFace(UINT32 textPosition, UINT32 textLength, ::Microsoft::WRL::ComPtr const fontFace, FLOAT const scale); diff --git a/src/renderer/dx/DxFontRenderData.cpp b/src/renderer/dx/DxFontRenderData.cpp index 1a0becce0d6..4e2fcc9b4f1 100644 --- a/src/renderer/dx/DxFontRenderData.cpp +++ b/src/renderer/dx/DxFontRenderData.cpp @@ -505,7 +505,7 @@ void DxFontRenderData::SetFeatures(std::unordered_map axes) +void DxFontRenderData::SetAxes(std::unordered_map axes) { _axesMap.clear(); diff --git a/src/renderer/dx/DxFontRenderData.h b/src/renderer/dx/DxFontRenderData.h index b15b26a0e58..6328bcbfd9f 100644 --- a/src/renderer/dx/DxFontRenderData.h +++ b/src/renderer/dx/DxFontRenderData.h @@ -80,7 +80,7 @@ namespace Microsoft::Console::Render bool DidUserSetFeatures() const noexcept; void InitializeFeatureMap(); void SetFeatures(std::unordered_map features); - void SetAxes(std::unordered_map axes); + void SetAxes(std::unordered_map axes); private: void _BuildFontRenderData(const FontInfoDesired& desired, FontInfo& actual, const int dpi); @@ -92,7 +92,7 @@ namespace Microsoft::Console::Render std::vector _featureVector; // The font axes to apply to the text - std::unordered_map _axesMap; + std::unordered_map _axesMap; ::Microsoft::WRL::ComPtr _dwriteFactory; diff --git a/src/renderer/dx/DxRenderer.cpp b/src/renderer/dx/DxRenderer.cpp index a0acfefc860..b47b5ea786e 100644 --- a/src/renderer/dx/DxRenderer.cpp +++ b/src/renderer/dx/DxRenderer.cpp @@ -1988,7 +1988,7 @@ void DxEngine::SetFontFeatures(const std::unordered_map axes) +void DxEngine::SetFontAxes(const std::unordered_map axes) { _fontRenderData->SetAxes(axes); } diff --git a/src/renderer/dx/DxRenderer.hpp b/src/renderer/dx/DxRenderer.hpp index e66a0e64643..75319aaf704 100644 --- a/src/renderer/dx/DxRenderer.hpp +++ b/src/renderer/dx/DxRenderer.hpp @@ -73,7 +73,7 @@ namespace Microsoft::Console::Render HANDLE GetSwapChainHandle(); void SetFontFeatures(const std::unordered_map features); - void SetFontAxes(const std::unordered_map axes); + void SetFontAxes(const std::unordered_map axes); // IRenderEngine Members [[nodiscard]] HRESULT Invalidate(const SMALL_RECT* const psrRegion) noexcept override; From 6abfc8727a538d6a67275773fab34c81b49fa999 Mon Sep 17 00:00:00 2001 From: Pankaj Bhojwani Date: Tue, 6 Jul 2021 12:10:47 -0700 Subject: [PATCH 19/49] fix json utils --- src/cascadia/TerminalSettingsModel/FontConfig.cpp | 1 - src/cascadia/TerminalSettingsModel/JsonUtils.h | 9 +++------ src/renderer/dx/CustomTextLayout.cpp | 2 +- src/renderer/dx/CustomTextLayout.h | 2 +- 4 files changed, 5 insertions(+), 9 deletions(-) diff --git a/src/cascadia/TerminalSettingsModel/FontConfig.cpp b/src/cascadia/TerminalSettingsModel/FontConfig.cpp index 579479a74e5..2d19809bbde 100644 --- a/src/cascadia/TerminalSettingsModel/FontConfig.cpp +++ b/src/cascadia/TerminalSettingsModel/FontConfig.cpp @@ -10,7 +10,6 @@ using namespace Microsoft::Terminal::Settings::Model; using namespace winrt::Microsoft::Terminal::Settings::Model::implementation; -static constexpr size_t TagLength{ 4 }; static constexpr std::string_view FontInfoKey{ "font" }; static constexpr std::string_view FontFaceKey{ "face" }; static constexpr std::string_view FontSizeKey{ "size" }; diff --git a/src/cascadia/TerminalSettingsModel/JsonUtils.h b/src/cascadia/TerminalSettingsModel/JsonUtils.h index 49d5fb3504e..db8ca75ae6d 100644 --- a/src/cascadia/TerminalSettingsModel/JsonUtils.h +++ b/src/cascadia/TerminalSettingsModel/JsonUtils.h @@ -182,12 +182,11 @@ namespace Microsoft::Terminal::Settings::Model::JsonUtils { std::unordered_map FromJson(const Json::Value& json) const { - ConversionTrait trait; std::unordered_map val; for (const auto& element : json.getMemberNames()) { - val[element.c_str()] = trait.FromJson(json[JsonKey(element)]); + GetValueForKey(json, element, val[element.c_str()]); } return val; @@ -234,12 +233,11 @@ namespace Microsoft::Terminal::Settings::Model::JsonUtils { std::unordered_map FromJson(const Json::Value& json) const { - ConversionTrait trait; std::unordered_map val; for (const auto& element : json.getMemberNames()) { - val[til::u8u16(Detail::GetStringView(json))] = trait.FromJson(json[JsonKey(element)]); + GetValueForKey(json, element, val[til::u8u16(std::string_view{ element.c_str() })]); } return val; @@ -316,12 +314,11 @@ namespace Microsoft::Terminal::Settings::Model::JsonUtils { winrt::Windows::Foundation::Collections::IMap FromJson(const Json::Value& json) const { - ConversionTrait trait; std::unordered_map val; for (const auto& element : json.getMemberNames()) { - val[winrt::to_hstring(element)] = trait.FromJson(json[JsonKey(element)]); + GetValueForKey(json, element, val[winrt::to_hstring(element)]); } return winrt::single_threaded_map(std::move(val)); diff --git a/src/renderer/dx/CustomTextLayout.cpp b/src/renderer/dx/CustomTextLayout.cpp index 1b48f919c51..13763c318a3 100644 --- a/src/renderer/dx/CustomTextLayout.cpp +++ b/src/renderer/dx/CustomTextLayout.cpp @@ -1233,7 +1233,7 @@ std::vector CustomTextLayout::GetAxisVector(DWRITE_FONT_ DWRITE_FONT_STRETCH /*fontStretch*/, DWRITE_FONT_STYLE /*fontStyle*/, float /*fontSize*/, - ::Microsoft::WRL::ComPtr format) + ::Microsoft::WRL::ComPtr& format) { // todo: complete this function //enum AxisTagPresence diff --git a/src/renderer/dx/CustomTextLayout.h b/src/renderer/dx/CustomTextLayout.h index 11daba99322..2c93aac8b76 100644 --- a/src/renderer/dx/CustomTextLayout.h +++ b/src/renderer/dx/CustomTextLayout.h @@ -129,7 +129,7 @@ namespace Microsoft::Console::Render DWRITE_FONT_STRETCH fontStretch, DWRITE_FONT_STYLE fontStyle, float fontSize, - ::Microsoft::WRL::ComPtr format); + ::Microsoft::WRL::ComPtr& format); [[nodiscard]] HRESULT STDMETHODCALLTYPE _AnalyzeFontFallback(IDWriteTextAnalysisSource* const source, UINT32 textPosition, UINT32 textLength); [[nodiscard]] HRESULT STDMETHODCALLTYPE _SetMappedFont(UINT32 textPosition, UINT32 textLength, IDWriteFont* const font, FLOAT const scale); [[nodiscard]] HRESULT STDMETHODCALLTYPE _SetMappedFontFace(UINT32 textPosition, UINT32 textLength, ::Microsoft::WRL::ComPtr const fontFace, FLOAT const scale); From 6310190af232065f2e322847d46c096648a229dd Mon Sep 17 00:00:00 2001 From: Pankaj Bhojwani Date: Tue, 6 Jul 2021 13:03:42 -0700 Subject: [PATCH 20/49] fix utils again --- src/cascadia/TerminalSettingsModel/JsonUtils.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cascadia/TerminalSettingsModel/JsonUtils.h b/src/cascadia/TerminalSettingsModel/JsonUtils.h index db8ca75ae6d..ef6ad4b43fa 100644 --- a/src/cascadia/TerminalSettingsModel/JsonUtils.h +++ b/src/cascadia/TerminalSettingsModel/JsonUtils.h @@ -237,7 +237,7 @@ namespace Microsoft::Terminal::Settings::Model::JsonUtils for (const auto& element : json.getMemberNames()) { - GetValueForKey(json, element, val[til::u8u16(std::string_view{ element.c_str() })]); + GetValueForKey(json, element, val[til::u8u16(element)]); } return val; From f97d5a26f633243cf9b206c11b330aadde97316c Mon Sep 17 00:00:00 2001 From: Pankaj Bhojwani Date: Tue, 6 Jul 2021 15:34:20 -0700 Subject: [PATCH 21/49] copy/duplicate --- src/cascadia/TerminalSettingsModel/CascadiaSettings.cpp | 2 ++ src/cascadia/TerminalSettingsModel/FontConfig.cpp | 4 ++++ src/cascadia/TerminalSettingsModel/FontConfig.idl | 8 ++++++++ src/cascadia/TerminalSettingsModel/JsonUtils.h | 9 +++------ 4 files changed, 17 insertions(+), 6 deletions(-) diff --git a/src/cascadia/TerminalSettingsModel/CascadiaSettings.cpp b/src/cascadia/TerminalSettingsModel/CascadiaSettings.cpp index 0323d381757..0ef82a8ca01 100644 --- a/src/cascadia/TerminalSettingsModel/CascadiaSettings.cpp +++ b/src/cascadia/TerminalSettingsModel/CascadiaSettings.cpp @@ -333,6 +333,8 @@ winrt::Microsoft::Terminal::Settings::Model::Profile CascadiaSettings::Duplicate DUPLICATE_FONT_SETTING_MACRO(FontFace); DUPLICATE_FONT_SETTING_MACRO(FontSize); DUPLICATE_FONT_SETTING_MACRO(FontWeight); + DUPLICATE_FONT_SETTING_MACRO(FontFeatures); + DUPLICATE_FONT_SETTING_MACRO(FontAxes); DUPLICATE_APPEARANCE_SETTING_MACRO(ColorSchemeName); DUPLICATE_APPEARANCE_SETTING_MACRO(Foreground); diff --git a/src/cascadia/TerminalSettingsModel/FontConfig.cpp b/src/cascadia/TerminalSettingsModel/FontConfig.cpp index 2d19809bbde..2d5f1bcd912 100644 --- a/src/cascadia/TerminalSettingsModel/FontConfig.cpp +++ b/src/cascadia/TerminalSettingsModel/FontConfig.cpp @@ -31,6 +31,8 @@ winrt::com_ptr FontConfig::CopyFontInfo(const winrt::com_ptr_FontFace = source->_FontFace; fontInfo->_FontSize = source->_FontSize; fontInfo->_FontWeight = source->_FontWeight; + fontInfo->_FontAxes = source->_FontAxes; + fontInfo->_FontFeatures = source->_FontFeatures; return fontInfo; } @@ -41,6 +43,8 @@ Json::Value FontConfig::ToJson() const JsonUtils::SetValueForKey(json, FontFaceKey, _FontFace); JsonUtils::SetValueForKey(json, FontSizeKey, _FontSize); JsonUtils::SetValueForKey(json, FontWeightKey, _FontWeight); + JsonUtils::SetValueForKey(json, FontAxesKey, _FontAxes); + JsonUtils::SetValueForKey(json, FontFeaturesKey, _FontFeatures); return json; } diff --git a/src/cascadia/TerminalSettingsModel/FontConfig.idl b/src/cascadia/TerminalSettingsModel/FontConfig.idl index 3532a1ca03c..45da66d6a04 100644 --- a/src/cascadia/TerminalSettingsModel/FontConfig.idl +++ b/src/cascadia/TerminalSettingsModel/FontConfig.idl @@ -16,7 +16,15 @@ namespace Microsoft.Terminal.Settings.Model INHERITABLE_FONT_SETTING(String, FontFace); INHERITABLE_FONT_SETTING(Int32, FontSize); INHERITABLE_FONT_SETTING(Windows.UI.Text.FontWeight, FontWeight); + Windows.Foundation.Collections.IMap FontFeatures; + Boolean HasFontFeatures { get; }; + void ClearFontFeatures(); + Microsoft.Terminal.Settings.Model.FontConfig FontFeaturesOverrideSource { get; }; + Windows.Foundation.Collections.IMap FontAxes; + Boolean HasFontAxes { get; }; + void ClearFontAxes(); + Microsoft.Terminal.Settings.Model.FontConfig FontAxesOverrideSource { get; }; } } diff --git a/src/cascadia/TerminalSettingsModel/JsonUtils.h b/src/cascadia/TerminalSettingsModel/JsonUtils.h index ef6ad4b43fa..5575a0e23b2 100644 --- a/src/cascadia/TerminalSettingsModel/JsonUtils.h +++ b/src/cascadia/TerminalSettingsModel/JsonUtils.h @@ -211,12 +211,11 @@ namespace Microsoft::Terminal::Settings::Model::JsonUtils Json::Value ToJson(const std::unordered_map& val) { - ConversionTrait trait; Json::Value json{ Json::objectValue }; for (const auto& [k, v] : val) { - json[JsonKey(k)] = trait.ToJson(v); + SetValueForKey(json, k, v); } return json; @@ -262,12 +261,11 @@ namespace Microsoft::Terminal::Settings::Model::JsonUtils Json::Value ToJson(const std::unordered_map& val) { - ConversionTrait trait; Json::Value json{ Json::objectValue }; for (const auto& [k, v] : val) { - json[JsonKey(k)] = trait.ToJson(v); + SetValueForKey(json, til::u16u8(k), v); } return json; @@ -343,12 +341,11 @@ namespace Microsoft::Terminal::Settings::Model::JsonUtils Json::Value ToJson(const winrt::Windows::Foundation::Collections::IMap& val) { - ConversionTrait trait; Json::Value json{ Json::objectValue }; for (const auto& [k, v] : val) { - json[JsonKey(k)] = trait.ToJson(v); + SetValueForKey(json, til::u16u8(k), v); } return json; From deaa7e95d72f421074428d678c510649614f0f9d Mon Sep 17 00:00:00 2001 From: Pankaj Bhojwani Date: Wed, 7 Jul 2021 15:21:19 -0700 Subject: [PATCH 22/49] complete get axis vector, fix redundancy --- src/renderer/dx/CustomTextLayout.cpp | 243 +++++++++++++++------------ src/renderer/dx/CustomTextLayout.h | 17 +- 2 files changed, 145 insertions(+), 115 deletions(-) diff --git a/src/renderer/dx/CustomTextLayout.cpp b/src/renderer/dx/CustomTextLayout.cpp index 13763c318a3..b4fb9b38d7f 100644 --- a/src/renderer/dx/CustomTextLayout.cpp +++ b/src/renderer/dx/CustomTextLayout.cpp @@ -1224,83 +1224,144 @@ CATCH_RETURN(); #pragma endregion #pragma region internal methods for mimicking text analyzer pattern but for font fallback +// Method Description: +// - Converts a DWRITE_FONT_STRETCH enum into the corresponding float value to +// create a DWRITE_FONT_AXIS_VALUE with +// Arguments: +// - fontStretch: the old DWRITE_FONT_STRETCH enum to be converted into an axis value +// Return value: +// - The float value corresponding to the passed in fontStretch +float CustomTextLayout::_FontStretchToWidthAxisValue(const DWRITE_FONT_STRETCH fontStretch) +{ + switch (fontStretch) + { + case DWRITE_FONT_STRETCH_ULTRA_CONDENSED: + return 50.0f; + case DWRITE_FONT_STRETCH_EXTRA_CONDENSED: + return 62.5f; + case DWRITE_FONT_STRETCH_CONDENSED: + return 75.0f; + case DWRITE_FONT_STRETCH_SEMI_CONDENSED: + return 87.5f; + case DWRITE_FONT_STRETCH_MEDIUM: + return 100.0f; + case DWRITE_FONT_STRETCH_SEMI_EXPANDED: + return 112.5f; + case DWRITE_FONT_STRETCH_EXPANDED: + return 125.0f; + case DWRITE_FONT_STRETCH_EXTRA_EXPANDED: + return 150.0f; + case DWRITE_FONT_STRETCH_ULTRA_EXPANDED: + return 200.0f; + default: + return 100.0f; + } +} + +// Method Description: +// - Converts a DWRITE_FONT_STYLE enum into the corresponding float value to +// create a DWRITE_FONT_AXIS_VALUE with +// Arguments: +// - fontStyle: the old DWRITE_FONT_STYLE enum to be converted into an axis value +// Return value: +// - The float value corresponding to the passed in fontStyle +float CustomTextLayout::_FontStyleToSlantFixedAxisValue(const DWRITE_FONT_STYLE fontStyle) +{ + // Both DWRITE_FONT_STYLE_OBLIQUE and DWRITE_FONT_STYLE_ITALIC default to having slant. + // Though an italic font technically need not have slant (there exist upright ones), the + // vast majority of italic fonts are also slanted. Ideally the slant comes from the + // 'slnt' value in the STAT or fvar table, or the post table italic angle. + + return (fontStyle == DWRITE_FONT_STYLE_ITALIC) ? -12.0f : + (fontStyle == DWRITE_FONT_STYLE_OBLIQUE) ? -20.0f : + /*fontStyle == DWRITE_FONT_STYLE_NORMAL*/ 0.0f; +} + +// Method Description: +// - Converts a float fontSize into the corresponding float value to create a DWRITE_FONT_AXIS_VALUE with +// Arguments: +// - fontSize: the old float value to be converted into an axis value +// Return value: +// - The float value corresponding to the passed in fontSize +float CustomTextLayout::_DIPsToPoints(const float fontSize) +{ + return fontSize * (72.0f / 96.0f); +} + // Method Description: // - Fill any missing axis values that might be known but were unspecified, such as omitting // the 'wght' axis tag but specifying the old DWRITE_FONT_WEIGHT enum // Arguments: -// - todo: fill this out -std::vector CustomTextLayout::GetAxisVector(DWRITE_FONT_WEIGHT /*fontWeight*/, - DWRITE_FONT_STRETCH /*fontStretch*/, - DWRITE_FONT_STYLE /*fontStyle*/, - float /*fontSize*/, - ::Microsoft::WRL::ComPtr& format) +// - fontWeight: the old DWRITE_FONT_WEIGHT enum to be converted into an axis value +// - fontStretch: the old DWRITE_FONT_STRETCH enum to be converted into an axis value +// - fontStyle: the old DWRITE_FONT_STYLE enum to be converted into an axis value +// - fontSize: the number to convert into an axis value +// - format: the IDWriteTextFormat3 to get the defined axes from +// Return value: +// - The fully formed axes vector +std::vector CustomTextLayout::_GetAxisVector(const DWRITE_FONT_WEIGHT fontWeight, + const DWRITE_FONT_STRETCH fontStretch, + const DWRITE_FONT_STYLE fontStyle, + const float fontSize, + const ::Microsoft::WRL::ComPtr& format) { - // todo: complete this function - //enum AxisTagPresence - //{ - // AxisTagPresenceNone = 0, - // AxisTagPresenceWeight = 1, - // AxisTagPresenceWidth = 2, - // AxisTagPresenceItalic = 4, - // AxisTagPresenceSlant = 8, - // AxisTagPresenceOpticalSize = 16, - //}; + enum AxisTagPresence + { + AxisTagPresenceNone = 0, + AxisTagPresenceWeight = 1, + AxisTagPresenceWidth = 2, + AxisTagPresenceItalic = 4, + AxisTagPresenceSlant = 8, + AxisTagPresenceOpticalSize = 16, + }; const auto axesCount = format->GetFontAxisValueCount(); std::vector axesVector; axesVector.resize(axesCount); format->GetFontAxisValues(axesVector.data(), axesCount); - //uint32_t axisTagPresence = AxisTagPresenceNone; - //for (auto& fontAxisValue : axesVector) - //{ - // switch (fontAxisValue.axisTag) - // { - // case DWRITE_FONT_AXIS_TAG_WEIGHT: - // axisTagPresence |= AxisTagPresenceWeight; - // break; - // case DWRITE_FONT_AXIS_TAG_WIDTH: - // axisTagPresence |= AxisTagPresenceWidth; - // break; - // case DWRITE_FONT_AXIS_TAG_ITALIC: - // axisTagPresence |= AxisTagPresenceItalic; - // break; - // case DWRITE_FONT_AXIS_TAG_SLANT: - // axisTagPresence |= AxisTagPresenceSlant; - // break; - // case DWRITE_FONT_AXIS_TAG_OPTICAL_SIZE: - // axisTagPresence |= AxisTagPresenceOpticalSize; - // break; - // } - //} + uint32_t axisTagPresence = AxisTagPresenceNone; + for (auto& fontAxisValue : axesVector) + { + switch (fontAxisValue.axisTag) + { + case DWRITE_FONT_AXIS_TAG_WEIGHT: + axisTagPresence |= AxisTagPresenceWeight; + break; + case DWRITE_FONT_AXIS_TAG_WIDTH: + axisTagPresence |= AxisTagPresenceWidth; + break; + case DWRITE_FONT_AXIS_TAG_ITALIC: + axisTagPresence |= AxisTagPresenceItalic; + break; + case DWRITE_FONT_AXIS_TAG_SLANT: + axisTagPresence |= AxisTagPresenceSlant; + break; + case DWRITE_FONT_AXIS_TAG_OPTICAL_SIZE: + axisTagPresence |= AxisTagPresenceOpticalSize; + break; + } + } - //if ((axisTagPresence & AxisTagPresenceWeight) == 0) - //{ - // axesVector.push_back({ DWRITE_FONT_AXIS_TAG_WEIGHT, float(fontWeight) }); - //} - //if ((axisTagPresence & AxisTagPresenceWidth) == 0) - //{ - // auto ayy1 = 1; - // //auto value = FontStretchToWidthAxisValue(fontStretch); - // axesVector.push_back({ DWRITE_FONT_AXIS_TAG_WIDTH, gsl::narrow(ayy1) }); - //} - //if ((axisTagPresence & AxisTagPresenceItalic) == 0) - //{ - // auto ayy2 = 1; - // //auto value = FontStyleToItalicFixedAxisValue(fontStyle); - // axesVector.push_back({ DWRITE_FONT_AXIS_TAG_ITALIC, gsl::narrow(ayy2) }); - //} - //if ((axisTagPresence & AxisTagPresenceSlant) == 0) - //{ - // auto ayy3 = 1; - // //auto value = FontStyleToSlantFixedAxisValue(fontStyle); - // axesVector.push_back({ DWRITE_FONT_AXIS_TAG_SLANT, gsl::narrow(ayy3) }); - //} - //if ((axisTagPresence & AxisTagPresenceOpticalSize) == 0) - //{ - // auto pointSize = 1; - // //const auto pointSize = DIPsToPoints(fontSize); - // axesVector.push_back({ DWRITE_FONT_AXIS_TAG_OPTICAL_SIZE, gsl::narrow(pointSize) }); - //} + if ((axisTagPresence & AxisTagPresenceWeight) == 0) + { + axesVector.push_back({ DWRITE_FONT_AXIS_TAG_WEIGHT, float(fontWeight) }); + } + if ((axisTagPresence & AxisTagPresenceWidth) == 0) + { + axesVector.push_back({ DWRITE_FONT_AXIS_TAG_WIDTH, _FontStretchToWidthAxisValue(fontStretch) }); + } + if ((axisTagPresence & AxisTagPresenceItalic) == 0) + { + axesVector.push_back({ DWRITE_FONT_AXIS_TAG_ITALIC, (fontStyle == DWRITE_FONT_STYLE_ITALIC ? 1.0f : 0.0f) }); + } + if ((axisTagPresence & AxisTagPresenceSlant) == 0) + { + axesVector.push_back({ DWRITE_FONT_AXIS_TAG_SLANT, _FontStyleToSlantFixedAxisValue(fontStyle) }); + } + if ((axisTagPresence & AxisTagPresenceOpticalSize) == 0) + { + axesVector.push_back({ DWRITE_FONT_AXIS_TAG_OPTICAL_SIZE, _DIPsToPoints(fontSize) }); + } return axesVector; } @@ -1352,7 +1413,7 @@ std::vector CustomTextLayout::GetAxisVector(DWRITE_FONT_ if (!FAILED(_formatInUse->QueryInterface(IID_PPV_ARGS(&format3))) && !FAILED(fallback->QueryInterface(IID_PPV_ARGS(&fallback1)))) { // If the OS supports IDWriteFontFallback1 and IDWriteTextFormat3, we can apply axes of variation to the font - const auto axesVector = GetAxisVector(weight, stretch, style, format1->GetFontSize(), format3); + const auto axesVector = _GetAxisVector(weight, stretch, style, format1->GetFontSize(), format3); // Walk through and analyze the entire string while (textLength > 0) { @@ -1398,7 +1459,9 @@ std::vector CustomTextLayout::GetAxisVector(DWRITE_FONT_ &mappedFont, &scale); - RETURN_IF_FAILED(_SetMappedFont(textPosition, mappedLength, mappedFont.Get(), scale)); + ::Microsoft::WRL::ComPtr face; + RETURN_IF_FAILED(mappedFont.Get()->CreateFontFace(&face)); + RETURN_IF_FAILED(_SetMappedFontFace(textPosition, mappedLength, face, scale)); textPosition += mappedLength; textLength -= mappedLength; @@ -1416,50 +1479,14 @@ std::vector CustomTextLayout::GetAxisVector(DWRITE_FONT_ // Arguments: // - textPosition - the index to start the substring operation // - textLength - the length of the substring operation -// - font - the font that applies to the substring range +// - fontFace - the fontFace that applies to the substring range // - scale - the scale of the font to apply // Return Value: // - S_OK or appropriate STL/GSL failure code. -[[nodiscard]] HRESULT STDMETHODCALLTYPE CustomTextLayout::_SetMappedFont(UINT32 textPosition, - UINT32 textLength, - _In_ IDWriteFont* const font, - FLOAT const scale) -{ - try - { - _SetCurrentRun(textPosition); - _SplitCurrentRun(textPosition); - while (textLength > 0) - { - auto& run = _FetchNextRun(textLength); - - if (font != nullptr) - { - // Get font face from font metadata - ::Microsoft::WRL::ComPtr face; - RETURN_IF_FAILED(font->CreateFontFace(&face)); - - // QI for Face5 interface from base face interface, store into run - RETURN_IF_FAILED(face.As(&run.fontFace)); - } - else - { - run.fontFace = _fontInUse; - } - - // Store the font scale as well. - run.fontScale = scale; - } - } - CATCH_RETURN(); - - return S_OK; -} - [[nodiscard]] HRESULT STDMETHODCALLTYPE CustomTextLayout::_SetMappedFontFace(UINT32 textPosition, - UINT32 textLength, - ::Microsoft::WRL::ComPtr const fontFace, - FLOAT const scale) + UINT32 textLength, + ::Microsoft::WRL::ComPtr const fontFace, + FLOAT const scale) { try { diff --git a/src/renderer/dx/CustomTextLayout.h b/src/renderer/dx/CustomTextLayout.h index 2c93aac8b76..3ea4928250c 100644 --- a/src/renderer/dx/CustomTextLayout.h +++ b/src/renderer/dx/CustomTextLayout.h @@ -125,14 +125,17 @@ namespace Microsoft::Console::Render void _SplitCurrentRun(const UINT32 splitPosition); void _OrderRuns(); - std::vector GetAxisVector(DWRITE_FONT_WEIGHT fontWeight, - DWRITE_FONT_STRETCH fontStretch, - DWRITE_FONT_STYLE fontStyle, - float fontSize, - ::Microsoft::WRL::ComPtr& format); + float _FontStretchToWidthAxisValue(const DWRITE_FONT_STRETCH fontStretch); + float _FontStyleToSlantFixedAxisValue(const DWRITE_FONT_STYLE fontStyle); + float _DIPsToPoints(const float fontSize); + std::vector _GetAxisVector(const DWRITE_FONT_WEIGHT fontWeight, + const DWRITE_FONT_STRETCH fontStretch, + const DWRITE_FONT_STYLE fontStyle, + const float fontSize, + const ::Microsoft::WRL::ComPtr& format); + [[nodiscard]] HRESULT STDMETHODCALLTYPE _AnalyzeFontFallback(IDWriteTextAnalysisSource* const source, UINT32 textPosition, UINT32 textLength); - [[nodiscard]] HRESULT STDMETHODCALLTYPE _SetMappedFont(UINT32 textPosition, UINT32 textLength, IDWriteFont* const font, FLOAT const scale); - [[nodiscard]] HRESULT STDMETHODCALLTYPE _SetMappedFontFace(UINT32 textPosition, UINT32 textLength, ::Microsoft::WRL::ComPtr const fontFace, FLOAT const scale); + [[nodiscard]] HRESULT STDMETHODCALLTYPE _SetMappedFontFace(UINT32 textPosition, UINT32 textLength, ::Microsoft::WRL::ComPtr const fontFace, FLOAT const scale); [[nodiscard]] HRESULT STDMETHODCALLTYPE _AnalyzeBoxDrawing(gsl::not_null const source, UINT32 textPosition, UINT32 textLength); [[nodiscard]] HRESULT STDMETHODCALLTYPE _SetBoxEffect(UINT32 textPosition, UINT32 textLength); From c9fcf2bb527aa0b6733f5fba65e1015ef89771a1 Mon Sep 17 00:00:00 2001 From: Pankaj Bhojwani Date: Wed, 7 Jul 2021 15:22:21 -0700 Subject: [PATCH 23/49] format --- src/renderer/dx/CustomTextLayout.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/renderer/dx/CustomTextLayout.cpp b/src/renderer/dx/CustomTextLayout.cpp index b4fb9b38d7f..33c7ca52e0c 100644 --- a/src/renderer/dx/CustomTextLayout.cpp +++ b/src/renderer/dx/CustomTextLayout.cpp @@ -1272,9 +1272,9 @@ float CustomTextLayout::_FontStyleToSlantFixedAxisValue(const DWRITE_FONT_STYLE // vast majority of italic fonts are also slanted. Ideally the slant comes from the // 'slnt' value in the STAT or fvar table, or the post table italic angle. - return (fontStyle == DWRITE_FONT_STYLE_ITALIC) ? -12.0f : - (fontStyle == DWRITE_FONT_STYLE_OBLIQUE) ? -20.0f : - /*fontStyle == DWRITE_FONT_STYLE_NORMAL*/ 0.0f; + return (fontStyle == DWRITE_FONT_STYLE_ITALIC) ? -12.0f : + (fontStyle == DWRITE_FONT_STYLE_OBLIQUE) ? -20.0f : + /*fontStyle == DWRITE_FONT_STYLE_NORMAL*/ 0.0f; } // Method Description: @@ -1484,9 +1484,9 @@ std::vector CustomTextLayout::_GetAxisVector(const DWRIT // Return Value: // - S_OK or appropriate STL/GSL failure code. [[nodiscard]] HRESULT STDMETHODCALLTYPE CustomTextLayout::_SetMappedFontFace(UINT32 textPosition, - UINT32 textLength, - ::Microsoft::WRL::ComPtr const fontFace, - FLOAT const scale) + UINT32 textLength, + ::Microsoft::WRL::ComPtr const fontFace, + FLOAT const scale) { try { From 51ffd3782414d863dadc39a96b2d8cb9357b5240 Mon Sep 17 00:00:00 2001 From: Pankaj Bhojwani Date: Wed, 7 Jul 2021 15:36:10 -0700 Subject: [PATCH 24/49] noexcept --- src/renderer/dx/CustomTextLayout.cpp | 10 +++++++--- src/renderer/dx/CustomTextLayout.h | 6 +++--- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/src/renderer/dx/CustomTextLayout.cpp b/src/renderer/dx/CustomTextLayout.cpp index 33c7ca52e0c..4dac0d7b88b 100644 --- a/src/renderer/dx/CustomTextLayout.cpp +++ b/src/renderer/dx/CustomTextLayout.cpp @@ -1231,7 +1231,7 @@ CATCH_RETURN(); // - fontStretch: the old DWRITE_FONT_STRETCH enum to be converted into an axis value // Return value: // - The float value corresponding to the passed in fontStretch -float CustomTextLayout::_FontStretchToWidthAxisValue(const DWRITE_FONT_STRETCH fontStretch) +float CustomTextLayout::_FontStretchToWidthAxisValue(const DWRITE_FONT_STRETCH fontStretch) noexcept { switch (fontStretch) { @@ -1265,7 +1265,7 @@ float CustomTextLayout::_FontStretchToWidthAxisValue(const DWRITE_FONT_STRETCH f // - fontStyle: the old DWRITE_FONT_STYLE enum to be converted into an axis value // Return value: // - The float value corresponding to the passed in fontStyle -float CustomTextLayout::_FontStyleToSlantFixedAxisValue(const DWRITE_FONT_STYLE fontStyle) +float CustomTextLayout::_FontStyleToSlantFixedAxisValue(const DWRITE_FONT_STYLE fontStyle) noexcept { // Both DWRITE_FONT_STYLE_OBLIQUE and DWRITE_FONT_STYLE_ITALIC default to having slant. // Though an italic font technically need not have slant (there exist upright ones), the @@ -1283,7 +1283,7 @@ float CustomTextLayout::_FontStyleToSlantFixedAxisValue(const DWRITE_FONT_STYLE // - fontSize: the old float value to be converted into an axis value // Return value: // - The float value corresponding to the passed in fontSize -float CustomTextLayout::_DIPsToPoints(const float fontSize) +float CustomTextLayout::_DIPsToPoints(const float fontSize) noexcept { return fontSize * (72.0f / 96.0f); } @@ -1440,6 +1440,10 @@ std::vector CustomTextLayout::_GetAxisVector(const DWRIT } else { + // The chunk of code below is very similar to the one above, unfortunately this needs + // to stay for Win7 compatibility reasons. It is also not possible to combine the two + // because they call different versions of MapCharacters + // Walk through and analyze the entire string while (textLength > 0) { diff --git a/src/renderer/dx/CustomTextLayout.h b/src/renderer/dx/CustomTextLayout.h index 3ea4928250c..c5e2af51fa9 100644 --- a/src/renderer/dx/CustomTextLayout.h +++ b/src/renderer/dx/CustomTextLayout.h @@ -125,9 +125,9 @@ namespace Microsoft::Console::Render void _SplitCurrentRun(const UINT32 splitPosition); void _OrderRuns(); - float _FontStretchToWidthAxisValue(const DWRITE_FONT_STRETCH fontStretch); - float _FontStyleToSlantFixedAxisValue(const DWRITE_FONT_STYLE fontStyle); - float _DIPsToPoints(const float fontSize); + float _FontStretchToWidthAxisValue(const DWRITE_FONT_STRETCH fontStretch) noexcept; + float _FontStyleToSlantFixedAxisValue(const DWRITE_FONT_STYLE fontStyle) noexcept; + float _DIPsToPoints(const float fontSize) noexcept; std::vector _GetAxisVector(const DWRITE_FONT_WEIGHT fontWeight, const DWRITE_FONT_STRETCH fontStretch, const DWRITE_FONT_STYLE fontStyle, From cfa1e4b617b961ad86cad54e0fdad2cef45ff9bf Mon Sep 17 00:00:00 2001 From: Pankaj Bhojwani Date: Fri, 9 Jul 2021 15:34:01 -0700 Subject: [PATCH 25/49] nits --- .../TerminalSettingsModel/JsonUtils.h | 54 +------------------ src/renderer/dx/CustomTextLayout.cpp | 26 ++++----- src/renderer/dx/CustomTextLayout.h | 2 +- src/renderer/dx/DxFontRenderData.cpp | 2 - 4 files changed, 16 insertions(+), 68 deletions(-) diff --git a/src/cascadia/TerminalSettingsModel/JsonUtils.h b/src/cascadia/TerminalSettingsModel/JsonUtils.h index 5575a0e23b2..f5846c78534 100644 --- a/src/cascadia/TerminalSettingsModel/JsonUtils.h +++ b/src/cascadia/TerminalSettingsModel/JsonUtils.h @@ -223,57 +223,7 @@ namespace Microsoft::Terminal::Settings::Model::JsonUtils std::string TypeDescription() const { - return "map"; - } - }; - - template - struct ConversionTrait> - { - std::unordered_map FromJson(const Json::Value& json) const - { - std::unordered_map val; - - for (const auto& element : json.getMemberNames()) - { - GetValueForKey(json, element, val[til::u8u16(element)]); - } - - return val; - } - - bool CanConvert(const Json::Value& json) const - { - if (!json.isObject()) - { - return false; - } - ConversionTrait trait; - for (const auto& element : json.getMemberNames()) - { - if (!trait.CanConvert(json[JsonKey(element)])) - { - return false; - } - } - return true; - } - - Json::Value ToJson(const std::unordered_map& val) - { - Json::Value json{ Json::objectValue }; - - for (const auto& [k, v] : val) - { - SetValueForKey(json, til::u16u8(k), v); - } - - return json; - } - - std::string TypeDescription() const - { - return "map"; + return fmt::format("map (string, {})", ConversionTrait{}.TypeDescription()); } }; @@ -353,7 +303,7 @@ namespace Microsoft::Terminal::Settings::Model::JsonUtils std::string TypeDescription() const { - return "map"; + return fmt::format("map (string, {})", ConversionTrait{}.TypeDescription()); } }; #endif diff --git a/src/renderer/dx/CustomTextLayout.cpp b/src/renderer/dx/CustomTextLayout.cpp index 4dac0d7b88b..aa4b0fe1448 100644 --- a/src/renderer/dx/CustomTextLayout.cpp +++ b/src/renderer/dx/CustomTextLayout.cpp @@ -1303,7 +1303,7 @@ std::vector CustomTextLayout::_GetAxisVector(const DWRIT const DWRITE_FONT_STRETCH fontStretch, const DWRITE_FONT_STYLE fontStyle, const float fontSize, - const ::Microsoft::WRL::ComPtr& format) + IDWriteTextFormat3* format) { enum AxisTagPresence { @@ -1320,45 +1320,45 @@ std::vector CustomTextLayout::_GetAxisVector(const DWRIT format->GetFontAxisValues(axesVector.data(), axesCount); uint32_t axisTagPresence = AxisTagPresenceNone; - for (auto& fontAxisValue : axesVector) + for (const auto& fontAxisValue : axesVector) { switch (fontAxisValue.axisTag) { case DWRITE_FONT_AXIS_TAG_WEIGHT: - axisTagPresence |= AxisTagPresenceWeight; + WI_SetFlag(axisTagPresence, AxisTagPresence::AxisTagPresenceWeight); break; case DWRITE_FONT_AXIS_TAG_WIDTH: - axisTagPresence |= AxisTagPresenceWidth; + WI_SetFlag(axisTagPresence, AxisTagPresence::AxisTagPresenceWidth); break; case DWRITE_FONT_AXIS_TAG_ITALIC: - axisTagPresence |= AxisTagPresenceItalic; + WI_SetFlag(axisTagPresence, AxisTagPresence::AxisTagPresenceItalic); break; case DWRITE_FONT_AXIS_TAG_SLANT: - axisTagPresence |= AxisTagPresenceSlant; + WI_SetFlag(axisTagPresence, AxisTagPresence::AxisTagPresenceSlant); break; case DWRITE_FONT_AXIS_TAG_OPTICAL_SIZE: - axisTagPresence |= AxisTagPresenceOpticalSize; + WI_SetFlag(axisTagPresence, AxisTagPresence::AxisTagPresenceOpticalSize); break; } } - if ((axisTagPresence & AxisTagPresenceWeight) == 0) + if (!WI_IsFlagSet(axisTagPresence, AxisTagPresence::AxisTagPresenceWeight)) { axesVector.push_back({ DWRITE_FONT_AXIS_TAG_WEIGHT, float(fontWeight) }); } - if ((axisTagPresence & AxisTagPresenceWidth) == 0) + if (!WI_IsFlagSet(axisTagPresence, AxisTagPresence::AxisTagPresenceWidth)) { axesVector.push_back({ DWRITE_FONT_AXIS_TAG_WIDTH, _FontStretchToWidthAxisValue(fontStretch) }); } - if ((axisTagPresence & AxisTagPresenceItalic) == 0) + if (!WI_IsFlagSet(axisTagPresence, AxisTagPresence::AxisTagPresenceItalic)) { axesVector.push_back({ DWRITE_FONT_AXIS_TAG_ITALIC, (fontStyle == DWRITE_FONT_STYLE_ITALIC ? 1.0f : 0.0f) }); } - if ((axisTagPresence & AxisTagPresenceSlant) == 0) + if (!WI_IsFlagSet(axisTagPresence, AxisTagPresence::AxisTagPresenceSlant)) { axesVector.push_back({ DWRITE_FONT_AXIS_TAG_SLANT, _FontStyleToSlantFixedAxisValue(fontStyle) }); } - if ((axisTagPresence & AxisTagPresenceOpticalSize) == 0) + if (!WI_IsFlagSet(axisTagPresence, AxisTagPresence::AxisTagPresenceOpticalSize)) { axesVector.push_back({ DWRITE_FONT_AXIS_TAG_OPTICAL_SIZE, _DIPsToPoints(fontSize) }); } @@ -1413,7 +1413,7 @@ std::vector CustomTextLayout::_GetAxisVector(const DWRIT if (!FAILED(_formatInUse->QueryInterface(IID_PPV_ARGS(&format3))) && !FAILED(fallback->QueryInterface(IID_PPV_ARGS(&fallback1)))) { // If the OS supports IDWriteFontFallback1 and IDWriteTextFormat3, we can apply axes of variation to the font - const auto axesVector = _GetAxisVector(weight, stretch, style, format1->GetFontSize(), format3); + const auto axesVector = _GetAxisVector(weight, stretch, style, format1->GetFontSize(), format3.Get()); // Walk through and analyze the entire string while (textLength > 0) { diff --git a/src/renderer/dx/CustomTextLayout.h b/src/renderer/dx/CustomTextLayout.h index c5e2af51fa9..8ce411d333f 100644 --- a/src/renderer/dx/CustomTextLayout.h +++ b/src/renderer/dx/CustomTextLayout.h @@ -132,7 +132,7 @@ namespace Microsoft::Console::Render const DWRITE_FONT_STRETCH fontStretch, const DWRITE_FONT_STYLE fontStyle, const float fontSize, - const ::Microsoft::WRL::ComPtr& format); + IDWriteTextFormat3* format); [[nodiscard]] HRESULT STDMETHODCALLTYPE _AnalyzeFontFallback(IDWriteTextAnalysisSource* const source, UINT32 textPosition, UINT32 textLength); [[nodiscard]] HRESULT STDMETHODCALLTYPE _SetMappedFontFace(UINT32 textPosition, UINT32 textLength, ::Microsoft::WRL::ComPtr const fontFace, FLOAT const scale); diff --git a/src/renderer/dx/DxFontRenderData.cpp b/src/renderer/dx/DxFontRenderData.cpp index 4e2fcc9b4f1..67fbc585890 100644 --- a/src/renderer/dx/DxFontRenderData.cpp +++ b/src/renderer/dx/DxFontRenderData.cpp @@ -514,8 +514,6 @@ void DxFontRenderData::SetAxes(std::unordered_map ax { _axesMap[axis] = value; } - - // todo: We probably want a 'complete missing axes values' here } // Routine Description: From f99069e19f8bb54ef6efece13224d1710e9e585f Mon Sep 17 00:00:00 2001 From: Pankaj Bhojwani Date: Mon, 12 Jul 2021 10:52:49 -0700 Subject: [PATCH 26/49] changes from comments --- src/renderer/dx/CustomTextLayout.cpp | 59 +++++++++------------------- src/renderer/dx/CustomTextLayout.h | 11 ++++++ src/renderer/dx/DxFontRenderData.cpp | 19 ++++----- src/renderer/dx/DxFontRenderData.h | 4 +- 4 files changed, 39 insertions(+), 54 deletions(-) diff --git a/src/renderer/dx/CustomTextLayout.cpp b/src/renderer/dx/CustomTextLayout.cpp index aa4b0fe1448..eab945008d7 100644 --- a/src/renderer/dx/CustomTextLayout.cpp +++ b/src/renderer/dx/CustomTextLayout.cpp @@ -14,6 +14,9 @@ using namespace Microsoft::Console::Render; +// 10 elements from DWRITE_FONT_STRETCH_UNDEFINED (0) to DWRITE_FONT_STRETCH_ULTRA_EXPANDED (9) +static constexpr auto fontStretchEnumToVal = std::array{ 100.0f, 50.0f, 62.5f, 75.0f, 87.5f, 100.0f, 112.5f, 125.0f, 150.0f, 200.0f }; + // Routine Description: // - Creates a CustomTextLayout object for calculating which glyphs should be placed and where // Arguments: @@ -395,8 +398,7 @@ CATCH_RETURN() DWRITE_FONT_FEATURE* featureList = features.data(); DWRITE_TYPOGRAPHIC_FEATURES typographicFeatures = { &featureList[0], gsl::narrow(features.size()) }; DWRITE_TYPOGRAPHIC_FEATURES const* typographicFeaturesPointer = &typographicFeatures; - const uint32_t fontFeatureLengths[1] = { textLength }; - const auto featureLengthsSpan = gsl::make_span(fontFeatureLengths); + const uint32_t fontFeatureLengths[] = { textLength }; // Get the glyphs from the text, retrying if needed. @@ -415,7 +417,7 @@ CATCH_RETURN() _localeName.data(), (run.isNumberSubstituted) ? _numberSubstitution.Get() : nullptr, &typographicFeaturesPointer, // features - featureLengthsSpan.data(), // featureLengths + fontFeatureLengths, // featureLengths 1, // featureCount maxGlyphCount, // maxGlyphCount &_glyphClusters.at(textStart), @@ -465,7 +467,7 @@ CATCH_RETURN() &run.script, _localeName.data(), &typographicFeaturesPointer, // features - featureLengthsSpan.data(), // featureLengths + fontFeatureLengths, // featureLengths 1, // featureCount &_glyphAdvances.at(glyphStart), &_glyphOffsets.at(glyphStart)); @@ -1233,28 +1235,13 @@ CATCH_RETURN(); // - The float value corresponding to the passed in fontStretch float CustomTextLayout::_FontStretchToWidthAxisValue(const DWRITE_FONT_STRETCH fontStretch) noexcept { - switch (fontStretch) + if (fontStretch > fontStretchEnumToVal.size()) { - case DWRITE_FONT_STRETCH_ULTRA_CONDENSED: - return 50.0f; - case DWRITE_FONT_STRETCH_EXTRA_CONDENSED: - return 62.5f; - case DWRITE_FONT_STRETCH_CONDENSED: - return 75.0f; - case DWRITE_FONT_STRETCH_SEMI_CONDENSED: - return 87.5f; - case DWRITE_FONT_STRETCH_MEDIUM: - return 100.0f; - case DWRITE_FONT_STRETCH_SEMI_EXPANDED: - return 112.5f; - case DWRITE_FONT_STRETCH_EXPANDED: - return 125.0f; - case DWRITE_FONT_STRETCH_EXTRA_EXPANDED: - return 150.0f; - case DWRITE_FONT_STRETCH_ULTRA_EXPANDED: - return 200.0f; - default: - return 100.0f; + return fontStretchEnumToVal[DWRITE_FONT_STRETCH_NORMAL]; + } + else + { + return fontStretchEnumToVal[fontStretch]; } } @@ -1305,21 +1292,12 @@ std::vector CustomTextLayout::_GetAxisVector(const DWRIT const float fontSize, IDWriteTextFormat3* format) { - enum AxisTagPresence - { - AxisTagPresenceNone = 0, - AxisTagPresenceWeight = 1, - AxisTagPresenceWidth = 2, - AxisTagPresenceItalic = 4, - AxisTagPresenceSlant = 8, - AxisTagPresenceOpticalSize = 16, - }; const auto axesCount = format->GetFontAxisValueCount(); std::vector axesVector; axesVector.resize(axesCount); format->GetFontAxisValues(axesVector.data(), axesCount); - uint32_t axisTagPresence = AxisTagPresenceNone; + auto axisTagPresence = AxisTagPresence::AxisTagPresenceNone; for (const auto& fontAxisValue : axesVector) { switch (fontAxisValue.axisTag) @@ -1344,23 +1322,23 @@ std::vector CustomTextLayout::_GetAxisVector(const DWRIT if (!WI_IsFlagSet(axisTagPresence, AxisTagPresence::AxisTagPresenceWeight)) { - axesVector.push_back({ DWRITE_FONT_AXIS_TAG_WEIGHT, float(fontWeight) }); + axesVector.emplace_back(DWRITE_FONT_AXIS_VALUE{ DWRITE_FONT_AXIS_TAG_WEIGHT, float(fontWeight) }); } if (!WI_IsFlagSet(axisTagPresence, AxisTagPresence::AxisTagPresenceWidth)) { - axesVector.push_back({ DWRITE_FONT_AXIS_TAG_WIDTH, _FontStretchToWidthAxisValue(fontStretch) }); + axesVector.emplace_back(DWRITE_FONT_AXIS_VALUE{ DWRITE_FONT_AXIS_TAG_WIDTH, _FontStretchToWidthAxisValue(fontStretch) }); } if (!WI_IsFlagSet(axisTagPresence, AxisTagPresence::AxisTagPresenceItalic)) { - axesVector.push_back({ DWRITE_FONT_AXIS_TAG_ITALIC, (fontStyle == DWRITE_FONT_STYLE_ITALIC ? 1.0f : 0.0f) }); + axesVector.emplace_back(DWRITE_FONT_AXIS_VALUE{ DWRITE_FONT_AXIS_TAG_ITALIC, (fontStyle == DWRITE_FONT_STYLE_ITALIC ? 1.0f : 0.0f) }); } if (!WI_IsFlagSet(axisTagPresence, AxisTagPresence::AxisTagPresenceSlant)) { - axesVector.push_back({ DWRITE_FONT_AXIS_TAG_SLANT, _FontStyleToSlantFixedAxisValue(fontStyle) }); + axesVector.emplace_back(DWRITE_FONT_AXIS_VALUE{ DWRITE_FONT_AXIS_TAG_SLANT, _FontStyleToSlantFixedAxisValue(fontStyle) }); } if (!WI_IsFlagSet(axisTagPresence, AxisTagPresence::AxisTagPresenceOpticalSize)) { - axesVector.push_back({ DWRITE_FONT_AXIS_TAG_OPTICAL_SIZE, _DIPsToPoints(fontSize) }); + axesVector.emplace_back(DWRITE_FONT_AXIS_VALUE{ DWRITE_FONT_AXIS_TAG_OPTICAL_SIZE, _DIPsToPoints(fontSize) }); } return axesVector; @@ -1463,6 +1441,7 @@ std::vector CustomTextLayout::_GetAxisVector(const DWRIT &mappedFont, &scale); + RETURN_LAST_ERROR_IF(!mappedFont.Get()); ::Microsoft::WRL::ComPtr face; RETURN_IF_FAILED(mappedFont.Get()->CreateFontFace(&face)); RETURN_IF_FAILED(_SetMappedFontFace(textPosition, mappedLength, face, scale)); diff --git a/src/renderer/dx/CustomTextLayout.h b/src/renderer/dx/CustomTextLayout.h index 8ce411d333f..f78bc3ff0dd 100644 --- a/src/renderer/dx/CustomTextLayout.h +++ b/src/renderer/dx/CustomTextLayout.h @@ -16,6 +16,17 @@ namespace Microsoft::Console::Render { + enum class AxisTagPresence : BYTE + { + AxisTagPresenceNone = 0x00, + AxisTagPresenceWeight = 0x01, + AxisTagPresenceWidth = 0x02, + AxisTagPresenceItalic = 0x04, + AxisTagPresenceSlant = 0x08, + AxisTagPresenceOpticalSize = 0x10, + }; + DEFINE_ENUM_FLAG_OPERATORS(AxisTagPresence); + class CustomTextLayout : public ::Microsoft::WRL::RuntimeClass<::Microsoft::WRL::RuntimeClassFlags<::Microsoft::WRL::ClassicCom | ::Microsoft::WRL::InhibitFtmBase>, IDWriteTextAnalysisSource, IDWriteTextAnalysisSink> { public: diff --git a/src/renderer/dx/DxFontRenderData.cpp b/src/renderer/dx/DxFontRenderData.cpp index 67fbc585890..9b8dda41a97 100644 --- a/src/renderer/dx/DxFontRenderData.cpp +++ b/src/renderer/dx/DxFontRenderData.cpp @@ -93,7 +93,7 @@ DxFontRenderData::DxFontRenderData(::Microsoft::WRL::ComPtr dwr return _defaultFontInfo.GetStretch(); } -[[nodiscard]] std::vector DxFontRenderData::DefaultFontFeatures() +[[nodiscard]] const std::vector& DxFontRenderData::DefaultFontFeatures() const { return _featureVector; } @@ -507,12 +507,13 @@ void DxFontRenderData::SetFeatures(std::unordered_map axes) { - _axesMap.clear(); + _axesVector.clear(); // Update our axis map with the provided axes for (const auto [axis, value] : axes) { - _axesMap[axis] = value; + const auto dwriteTag = DWRITE_MAKE_FONT_AXIS_TAG(gsl::at(axis, 0), gsl::at(axis, 1), gsl::at(axis, 2), gsl::at(axis, 3)); + _axesVector.emplace_back(DWRITE_FONT_AXIS_VALUE{ dwriteTag, gsl::narrow(value) }); } } @@ -727,16 +728,10 @@ Microsoft::WRL::ComPtr DxFontRenderData::_BuildTextFormat(con // If the OS supports IDWriteTextFormat3, set the font axes ::Microsoft::WRL::ComPtr format3; - if (!FAILED(format->QueryInterface(IID_PPV_ARGS(&format3))) && !_axesMap.empty()) + if (!FAILED(format->QueryInterface(IID_PPV_ARGS(&format3))) && !_axesVector.empty()) { - std::vector axesVector; - for (const auto [axis, value] : _axesMap) - { - const auto dwriteTag = DWRITE_MAKE_FONT_AXIS_TAG(gsl::at(axis, 0), gsl::at(axis, 1), gsl::at(axis, 2), gsl::at(axis, 3)); - axesVector.push_back(DWRITE_FONT_AXIS_VALUE{ dwriteTag, gsl::narrow(value) }); - } - DWRITE_FONT_AXIS_VALUE const* axesList = &gsl::at(axesVector, 0); - format3->SetFontAxisValues(axesList, gsl::narrow(axesVector.size())); + DWRITE_FONT_AXIS_VALUE const* axesList = &gsl::at(_axesVector, 0); + format3->SetFontAxisValues(axesList, gsl::narrow(_axesVector.size())); } return format; diff --git a/src/renderer/dx/DxFontRenderData.h b/src/renderer/dx/DxFontRenderData.h index 6328bcbfd9f..b36e6850f80 100644 --- a/src/renderer/dx/DxFontRenderData.h +++ b/src/renderer/dx/DxFontRenderData.h @@ -52,7 +52,7 @@ namespace Microsoft::Console::Render [[nodiscard]] DWRITE_FONT_STRETCH DefaultFontStretch() noexcept; // The font features of the default font - [[nodiscard]] std::vector DefaultFontFeatures(); + [[nodiscard]] const std::vector& DefaultFontFeatures() const; // The DirectWrite format object representing the size and other text properties to be applied (by default) [[nodiscard]] Microsoft::WRL::ComPtr DefaultTextFormat(); @@ -92,7 +92,7 @@ namespace Microsoft::Console::Render std::vector _featureVector; // The font axes to apply to the text - std::unordered_map _axesMap; + std::vector _axesVector; ::Microsoft::WRL::ComPtr _dwriteFactory; From f22eecddbb28519487c8a20ffa9028f3a3a75b8a Mon Sep 17 00:00:00 2001 From: Pankaj Bhojwani Date: Mon, 12 Jul 2021 13:04:57 -0700 Subject: [PATCH 27/49] put span back --- src/renderer/dx/CustomTextLayout.cpp | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/renderer/dx/CustomTextLayout.cpp b/src/renderer/dx/CustomTextLayout.cpp index 664eef63e80..484f8b44c5e 100644 --- a/src/renderer/dx/CustomTextLayout.cpp +++ b/src/renderer/dx/CustomTextLayout.cpp @@ -405,6 +405,7 @@ CATCH_RETURN() DWRITE_TYPOGRAPHIC_FEATURES typographicFeatures = { &featureList[0], gsl::narrow(features.size()) }; DWRITE_TYPOGRAPHIC_FEATURES const* typographicFeaturesPointer = &typographicFeatures; const uint32_t fontFeatureLengths[] = { textLength }; + const auto featureLengthsSpan = gsl::make_span(fontFeatureLengths); // Get the glyphs from the text, retrying if needed. @@ -423,7 +424,7 @@ CATCH_RETURN() _localeName.data(), (run.isNumberSubstituted) ? _numberSubstitution.Get() : nullptr, &typographicFeaturesPointer, // features - fontFeatureLengths, // featureLengths + featureLengthsSpan.data(), // featureLengths 1, // featureCount maxGlyphCount, // maxGlyphCount &_glyphClusters.at(textStart), @@ -473,7 +474,7 @@ CATCH_RETURN() &run.script, _localeName.data(), &typographicFeaturesPointer, // features - fontFeatureLengths, // featureLengths + featureLengthsSpan.data(), // featureLengths 1, // featureCount &_glyphAdvances.at(glyphStart), &_glyphOffsets.at(glyphStart)); @@ -1243,11 +1244,11 @@ float CustomTextLayout::_FontStretchToWidthAxisValue(const DWRITE_FONT_STRETCH f { if (fontStretch > fontStretchEnumToVal.size()) { - return fontStretchEnumToVal[DWRITE_FONT_STRETCH_NORMAL]; + return gsl::at(fontStretchEnumToVal, DWRITE_FONT_STRETCH_NORMAL); } else { - return fontStretchEnumToVal[fontStretch]; + return gsl::at(fontStretchEnumToVal, fontStretch); } } @@ -1298,6 +1299,11 @@ std::vector CustomTextLayout::_GetAxisVector(const DWRIT const float fontSize, IDWriteTextFormat3* format) { + if (!format) + { + // return early + return {}; + } const auto axesCount = format->GetFontAxisValueCount(); std::vector axesVector; axesVector.resize(axesCount); From 4c5e9e9f22964639c404a1515ab55d060f2fd0d5 Mon Sep 17 00:00:00 2001 From: Pankaj Bhojwani Date: Mon, 12 Jul 2021 16:47:07 -0700 Subject: [PATCH 28/49] errors --- src/renderer/dx/CustomTextLayout.cpp | 7 +++---- src/renderer/dx/DxFontRenderData.cpp | 2 +- src/renderer/dx/DxFontRenderData.h | 2 +- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/renderer/dx/CustomTextLayout.cpp b/src/renderer/dx/CustomTextLayout.cpp index 484f8b44c5e..6b9d7def9f4 100644 --- a/src/renderer/dx/CustomTextLayout.cpp +++ b/src/renderer/dx/CustomTextLayout.cpp @@ -405,7 +405,6 @@ CATCH_RETURN() DWRITE_TYPOGRAPHIC_FEATURES typographicFeatures = { &featureList[0], gsl::narrow(features.size()) }; DWRITE_TYPOGRAPHIC_FEATURES const* typographicFeaturesPointer = &typographicFeatures; const uint32_t fontFeatureLengths[] = { textLength }; - const auto featureLengthsSpan = gsl::make_span(fontFeatureLengths); // Get the glyphs from the text, retrying if needed. @@ -424,7 +423,7 @@ CATCH_RETURN() _localeName.data(), (run.isNumberSubstituted) ? _numberSubstitution.Get() : nullptr, &typographicFeaturesPointer, // features - featureLengthsSpan.data(), // featureLengths + &fontFeatureLengths[0], // featureLengths 1, // featureCount maxGlyphCount, // maxGlyphCount &_glyphClusters.at(textStart), @@ -474,7 +473,7 @@ CATCH_RETURN() &run.script, _localeName.data(), &typographicFeaturesPointer, // features - featureLengthsSpan.data(), // featureLengths + &fontFeatureLengths[0], // featureLengths 1, // featureCount &_glyphAdvances.at(glyphStart), &_glyphOffsets.at(glyphStart)); @@ -1334,7 +1333,7 @@ std::vector CustomTextLayout::_GetAxisVector(const DWRIT if (!WI_IsFlagSet(axisTagPresence, AxisTagPresence::AxisTagPresenceWeight)) { - axesVector.emplace_back(DWRITE_FONT_AXIS_VALUE{ DWRITE_FONT_AXIS_TAG_WEIGHT, float(fontWeight) }); + axesVector.emplace_back(DWRITE_FONT_AXIS_VALUE{ DWRITE_FONT_AXIS_TAG_WEIGHT, gsl::narrow(fontWeight) }); } if (!WI_IsFlagSet(axisTagPresence, AxisTagPresence::AxisTagPresenceWidth)) { diff --git a/src/renderer/dx/DxFontRenderData.cpp b/src/renderer/dx/DxFontRenderData.cpp index c2b90f558ee..616e2ff4b3b 100644 --- a/src/renderer/dx/DxFontRenderData.cpp +++ b/src/renderer/dx/DxFontRenderData.cpp @@ -93,7 +93,7 @@ DxFontRenderData::DxFontRenderData(::Microsoft::WRL::ComPtr dwr return _defaultFontInfo.GetStretch(); } -[[nodiscard]] const std::vector& DxFontRenderData::DefaultFontFeatures() const +[[nodiscard]] const std::vector& DxFontRenderData::DefaultFontFeatures() const noexcept { return _featureVector; } diff --git a/src/renderer/dx/DxFontRenderData.h b/src/renderer/dx/DxFontRenderData.h index 36610d2d65e..14faeff76c8 100644 --- a/src/renderer/dx/DxFontRenderData.h +++ b/src/renderer/dx/DxFontRenderData.h @@ -52,7 +52,7 @@ namespace Microsoft::Console::Render [[nodiscard]] DWRITE_FONT_STRETCH DefaultFontStretch() noexcept; // The font features of the default font - [[nodiscard]] const std::vector& DefaultFontFeatures() const; + [[nodiscard]] const std::vector& DefaultFontFeatures() const noexcept; // The DirectWrite format object representing the size and other text properties to be applied (by default) [[nodiscard]] Microsoft::WRL::ComPtr DefaultTextFormat(); From 1312325e81a4ee906d1768be01486b10fea5643a Mon Sep 17 00:00:00 2001 From: Pankaj Bhojwani Date: Mon, 12 Jul 2021 17:01:31 -0700 Subject: [PATCH 29/49] suppress --- src/renderer/dx/CustomTextLayout.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/renderer/dx/CustomTextLayout.cpp b/src/renderer/dx/CustomTextLayout.cpp index 6b9d7def9f4..39c86966aa0 100644 --- a/src/renderer/dx/CustomTextLayout.cpp +++ b/src/renderer/dx/CustomTextLayout.cpp @@ -410,6 +410,7 @@ CATCH_RETURN() int tries = 0; +#pragma warning(suppress : 26485) // so we can pass in the fontFeatureLengths to GetGlyphs without the analyzer complaining HRESULT hr = S_OK; do { From 8c8d5921122e38d31fabc2be457d4217a95c6839 Mon Sep 17 00:00:00 2001 From: Pankaj Bhojwani Date: Tue, 13 Jul 2021 10:50:40 -0700 Subject: [PATCH 30/49] address nits --- .../TerminalSettingsModel/FontConfig.idl | 2 + src/renderer/dx/CustomTextLayout.cpp | 128 +--------------- src/renderer/dx/CustomTextLayout.h | 20 --- src/renderer/dx/DxFontRenderData.cpp | 145 +++++++++++++++++- src/renderer/dx/DxFontRenderData.h | 20 +++ 5 files changed, 164 insertions(+), 151 deletions(-) diff --git a/src/cascadia/TerminalSettingsModel/FontConfig.idl b/src/cascadia/TerminalSettingsModel/FontConfig.idl index 45da66d6a04..add87a9f691 100644 --- a/src/cascadia/TerminalSettingsModel/FontConfig.idl +++ b/src/cascadia/TerminalSettingsModel/FontConfig.idl @@ -17,6 +17,8 @@ namespace Microsoft.Terminal.Settings.Model INHERITABLE_FONT_SETTING(Int32, FontSize); INHERITABLE_FONT_SETTING(Windows.UI.Text.FontWeight, FontWeight); + // The INHERITABLE_FONT_SETTING macro doesn't like Windows.Foundation.Collections.IMap + // (possibly because of the comma) so features and axes are being declared manually for now Windows.Foundation.Collections.IMap FontFeatures; Boolean HasFontFeatures { get; }; void ClearFontFeatures(); diff --git a/src/renderer/dx/CustomTextLayout.cpp b/src/renderer/dx/CustomTextLayout.cpp index 39c86966aa0..52b07adb962 100644 --- a/src/renderer/dx/CustomTextLayout.cpp +++ b/src/renderer/dx/CustomTextLayout.cpp @@ -14,9 +14,6 @@ using namespace Microsoft::Console::Render; -// 10 elements from DWRITE_FONT_STRETCH_UNDEFINED (0) to DWRITE_FONT_STRETCH_ULTRA_EXPANDED (9) -static constexpr auto fontStretchEnumToVal = std::array{ 100.0f, 50.0f, 62.5f, 75.0f, 87.5f, 100.0f, 112.5f, 125.0f, 150.0f, 200.0f }; - // Routine Description: // - Creates a CustomTextLayout object for calculating which glyphs should be placed and where // Arguments: @@ -1233,129 +1230,6 @@ CATCH_RETURN(); #pragma endregion #pragma region internal methods for mimicking text analyzer pattern but for font fallback -// Method Description: -// - Converts a DWRITE_FONT_STRETCH enum into the corresponding float value to -// create a DWRITE_FONT_AXIS_VALUE with -// Arguments: -// - fontStretch: the old DWRITE_FONT_STRETCH enum to be converted into an axis value -// Return value: -// - The float value corresponding to the passed in fontStretch -float CustomTextLayout::_FontStretchToWidthAxisValue(const DWRITE_FONT_STRETCH fontStretch) noexcept -{ - if (fontStretch > fontStretchEnumToVal.size()) - { - return gsl::at(fontStretchEnumToVal, DWRITE_FONT_STRETCH_NORMAL); - } - else - { - return gsl::at(fontStretchEnumToVal, fontStretch); - } -} - -// Method Description: -// - Converts a DWRITE_FONT_STYLE enum into the corresponding float value to -// create a DWRITE_FONT_AXIS_VALUE with -// Arguments: -// - fontStyle: the old DWRITE_FONT_STYLE enum to be converted into an axis value -// Return value: -// - The float value corresponding to the passed in fontStyle -float CustomTextLayout::_FontStyleToSlantFixedAxisValue(const DWRITE_FONT_STYLE fontStyle) noexcept -{ - // Both DWRITE_FONT_STYLE_OBLIQUE and DWRITE_FONT_STYLE_ITALIC default to having slant. - // Though an italic font technically need not have slant (there exist upright ones), the - // vast majority of italic fonts are also slanted. Ideally the slant comes from the - // 'slnt' value in the STAT or fvar table, or the post table italic angle. - - return (fontStyle == DWRITE_FONT_STYLE_ITALIC) ? -12.0f : - (fontStyle == DWRITE_FONT_STYLE_OBLIQUE) ? -20.0f : - /*fontStyle == DWRITE_FONT_STYLE_NORMAL*/ 0.0f; -} - -// Method Description: -// - Converts a float fontSize into the corresponding float value to create a DWRITE_FONT_AXIS_VALUE with -// Arguments: -// - fontSize: the old float value to be converted into an axis value -// Return value: -// - The float value corresponding to the passed in fontSize -float CustomTextLayout::_DIPsToPoints(const float fontSize) noexcept -{ - return fontSize * (72.0f / 96.0f); -} - -// Method Description: -// - Fill any missing axis values that might be known but were unspecified, such as omitting -// the 'wght' axis tag but specifying the old DWRITE_FONT_WEIGHT enum -// Arguments: -// - fontWeight: the old DWRITE_FONT_WEIGHT enum to be converted into an axis value -// - fontStretch: the old DWRITE_FONT_STRETCH enum to be converted into an axis value -// - fontStyle: the old DWRITE_FONT_STYLE enum to be converted into an axis value -// - fontSize: the number to convert into an axis value -// - format: the IDWriteTextFormat3 to get the defined axes from -// Return value: -// - The fully formed axes vector -std::vector CustomTextLayout::_GetAxisVector(const DWRITE_FONT_WEIGHT fontWeight, - const DWRITE_FONT_STRETCH fontStretch, - const DWRITE_FONT_STYLE fontStyle, - const float fontSize, - IDWriteTextFormat3* format) -{ - if (!format) - { - // return early - return {}; - } - const auto axesCount = format->GetFontAxisValueCount(); - std::vector axesVector; - axesVector.resize(axesCount); - format->GetFontAxisValues(axesVector.data(), axesCount); - - auto axisTagPresence = AxisTagPresence::AxisTagPresenceNone; - for (const auto& fontAxisValue : axesVector) - { - switch (fontAxisValue.axisTag) - { - case DWRITE_FONT_AXIS_TAG_WEIGHT: - WI_SetFlag(axisTagPresence, AxisTagPresence::AxisTagPresenceWeight); - break; - case DWRITE_FONT_AXIS_TAG_WIDTH: - WI_SetFlag(axisTagPresence, AxisTagPresence::AxisTagPresenceWidth); - break; - case DWRITE_FONT_AXIS_TAG_ITALIC: - WI_SetFlag(axisTagPresence, AxisTagPresence::AxisTagPresenceItalic); - break; - case DWRITE_FONT_AXIS_TAG_SLANT: - WI_SetFlag(axisTagPresence, AxisTagPresence::AxisTagPresenceSlant); - break; - case DWRITE_FONT_AXIS_TAG_OPTICAL_SIZE: - WI_SetFlag(axisTagPresence, AxisTagPresence::AxisTagPresenceOpticalSize); - break; - } - } - - if (!WI_IsFlagSet(axisTagPresence, AxisTagPresence::AxisTagPresenceWeight)) - { - axesVector.emplace_back(DWRITE_FONT_AXIS_VALUE{ DWRITE_FONT_AXIS_TAG_WEIGHT, gsl::narrow(fontWeight) }); - } - if (!WI_IsFlagSet(axisTagPresence, AxisTagPresence::AxisTagPresenceWidth)) - { - axesVector.emplace_back(DWRITE_FONT_AXIS_VALUE{ DWRITE_FONT_AXIS_TAG_WIDTH, _FontStretchToWidthAxisValue(fontStretch) }); - } - if (!WI_IsFlagSet(axisTagPresence, AxisTagPresence::AxisTagPresenceItalic)) - { - axesVector.emplace_back(DWRITE_FONT_AXIS_VALUE{ DWRITE_FONT_AXIS_TAG_ITALIC, (fontStyle == DWRITE_FONT_STYLE_ITALIC ? 1.0f : 0.0f) }); - } - if (!WI_IsFlagSet(axisTagPresence, AxisTagPresence::AxisTagPresenceSlant)) - { - axesVector.emplace_back(DWRITE_FONT_AXIS_VALUE{ DWRITE_FONT_AXIS_TAG_SLANT, _FontStyleToSlantFixedAxisValue(fontStyle) }); - } - if (!WI_IsFlagSet(axisTagPresence, AxisTagPresence::AxisTagPresenceOpticalSize)) - { - axesVector.emplace_back(DWRITE_FONT_AXIS_VALUE{ DWRITE_FONT_AXIS_TAG_OPTICAL_SIZE, _DIPsToPoints(fontSize) }); - } - - return axesVector; -} - // Routine Description: // - Mimics an IDWriteTextAnalyser but for font fallback calculations. // Arguments: @@ -1403,7 +1277,7 @@ std::vector CustomTextLayout::_GetAxisVector(const DWRIT if (!FAILED(_formatInUse->QueryInterface(IID_PPV_ARGS(&format3))) && !FAILED(fallback->QueryInterface(IID_PPV_ARGS(&fallback1)))) { // If the OS supports IDWriteFontFallback1 and IDWriteTextFormat3, we can apply axes of variation to the font - const auto axesVector = _GetAxisVector(weight, stretch, style, format1->GetFontSize(), format3.Get()); + const auto axesVector = _fontRenderData->GetAxisVector(weight, stretch, style, format1->GetFontSize(), format3.Get()); // Walk through and analyze the entire string while (textLength > 0) { diff --git a/src/renderer/dx/CustomTextLayout.h b/src/renderer/dx/CustomTextLayout.h index f78bc3ff0dd..2a47634575d 100644 --- a/src/renderer/dx/CustomTextLayout.h +++ b/src/renderer/dx/CustomTextLayout.h @@ -16,17 +16,6 @@ namespace Microsoft::Console::Render { - enum class AxisTagPresence : BYTE - { - AxisTagPresenceNone = 0x00, - AxisTagPresenceWeight = 0x01, - AxisTagPresenceWidth = 0x02, - AxisTagPresenceItalic = 0x04, - AxisTagPresenceSlant = 0x08, - AxisTagPresenceOpticalSize = 0x10, - }; - DEFINE_ENUM_FLAG_OPERATORS(AxisTagPresence); - class CustomTextLayout : public ::Microsoft::WRL::RuntimeClass<::Microsoft::WRL::RuntimeClassFlags<::Microsoft::WRL::ClassicCom | ::Microsoft::WRL::InhibitFtmBase>, IDWriteTextAnalysisSource, IDWriteTextAnalysisSink> { public: @@ -136,15 +125,6 @@ namespace Microsoft::Console::Render void _SplitCurrentRun(const UINT32 splitPosition); void _OrderRuns(); - float _FontStretchToWidthAxisValue(const DWRITE_FONT_STRETCH fontStretch) noexcept; - float _FontStyleToSlantFixedAxisValue(const DWRITE_FONT_STYLE fontStyle) noexcept; - float _DIPsToPoints(const float fontSize) noexcept; - std::vector _GetAxisVector(const DWRITE_FONT_WEIGHT fontWeight, - const DWRITE_FONT_STRETCH fontStretch, - const DWRITE_FONT_STYLE fontStyle, - const float fontSize, - IDWriteTextFormat3* format); - [[nodiscard]] HRESULT STDMETHODCALLTYPE _AnalyzeFontFallback(IDWriteTextAnalysisSource* const source, UINT32 textPosition, UINT32 textLength); [[nodiscard]] HRESULT STDMETHODCALLTYPE _SetMappedFontFace(UINT32 textPosition, UINT32 textLength, ::Microsoft::WRL::ComPtr const fontFace, FLOAT const scale); diff --git a/src/renderer/dx/DxFontRenderData.cpp b/src/renderer/dx/DxFontRenderData.cpp index 616e2ff4b3b..4377e2c0d42 100644 --- a/src/renderer/dx/DxFontRenderData.cpp +++ b/src/renderer/dx/DxFontRenderData.cpp @@ -12,6 +12,10 @@ static constexpr float POINTS_PER_INCH = 72.0f; static constexpr std::wstring_view FALLBACK_FONT_FACES[] = { L"Consolas", L"Lucida Console", L"Courier New" }; static constexpr std::wstring_view FALLBACK_LOCALE = L"en-us"; +static constexpr size_t TAG_LENGTH = 4; + +// 10 elements from DWRITE_FONT_STRETCH_UNDEFINED (0) to DWRITE_FONT_STRETCH_ULTRA_EXPANDED (9) +static constexpr auto fontStretchEnumToVal = std::array{ 100.0f, 50.0f, 62.5f, 75.0f, 87.5f, 100.0f, 112.5f, 125.0f, 150.0f, 200.0f }; using namespace Microsoft::Console::Render; @@ -475,6 +479,8 @@ void DxFontRenderData::InitializeFeatureMap() // Routine Description: // - Updates our internal map of font features with the given features +// - NOTE TO CALLER: Make sure to call UpdateFont after calling this for the feature changes +// to take place // Arguments: // - features - the features to update our map with void DxFontRenderData::SetFeatures(std::unordered_map features) @@ -487,7 +493,10 @@ void DxFontRenderData::SetFeatures(std::unordered_map axes) @@ -512,11 +523,137 @@ void DxFontRenderData::SetAxes(std::unordered_map ax // Update our axis map with the provided axes for (const auto [axis, value] : axes) { - const auto dwriteTag = DWRITE_MAKE_FONT_AXIS_TAG(gsl::at(axis, 0), gsl::at(axis, 1), gsl::at(axis, 2), gsl::at(axis, 3)); - _axesVector.emplace_back(DWRITE_FONT_AXIS_VALUE{ dwriteTag, gsl::narrow(value) }); + if (axis.length() == TAG_LENGTH) + { + const auto dwriteTag = DWRITE_MAKE_FONT_AXIS_TAG(gsl::at(axis, 0), gsl::at(axis, 1), gsl::at(axis, 2), gsl::at(axis, 3)); + _axesVector.emplace_back(DWRITE_FONT_AXIS_VALUE{ dwriteTag, gsl::narrow(value) }); + } + } +} + +// Method Description: +// - Converts a DWRITE_FONT_STRETCH enum into the corresponding float value to +// create a DWRITE_FONT_AXIS_VALUE with +// Arguments: +// - fontStretch: the old DWRITE_FONT_STRETCH enum to be converted into an axis value +// Return value: +// - The float value corresponding to the passed in fontStretch +float DxFontRenderData::FontStretchToWidthAxisValue(const DWRITE_FONT_STRETCH fontStretch) noexcept +{ + if (fontStretch > fontStretchEnumToVal.size()) + { + return gsl::at(fontStretchEnumToVal, DWRITE_FONT_STRETCH_NORMAL); + } + else + { + return gsl::at(fontStretchEnumToVal, fontStretch); } } +// Method Description: +// - Converts a DWRITE_FONT_STYLE enum into the corresponding float value to +// create a DWRITE_FONT_AXIS_VALUE with +// Arguments: +// - fontStyle: the old DWRITE_FONT_STYLE enum to be converted into an axis value +// Return value: +// - The float value corresponding to the passed in fontStyle +float DxFontRenderData::FontStyleToSlantFixedAxisValue(const DWRITE_FONT_STYLE fontStyle) noexcept +{ + // Both DWRITE_FONT_STYLE_OBLIQUE and DWRITE_FONT_STYLE_ITALIC default to having slant. + // Though an italic font technically need not have slant (there exist upright ones), the + // vast majority of italic fonts are also slanted. Ideally the slant comes from the + // 'slnt' value in the STAT or fvar table, or the post table italic angle. + + return (fontStyle == DWRITE_FONT_STYLE_ITALIC) ? -12.0f : + (fontStyle == DWRITE_FONT_STYLE_OBLIQUE) ? -20.0f : + /*fontStyle == DWRITE_FONT_STYLE_NORMAL*/ 0.0f; +} + +// Method Description: +// - Converts a float fontSize into the corresponding float value to create a DWRITE_FONT_AXIS_VALUE with +// Arguments: +// - fontSize: the old float value to be converted into an axis value +// Return value: +// - The float value corresponding to the passed in fontSize +float DxFontRenderData::DIPsToPoints(const float fontSize) noexcept +{ + return fontSize * (72.0f / 96.0f); +} + +// Method Description: +// - Fill any missing axis values that might be known but were unspecified, such as omitting +// the 'wght' axis tag but specifying the old DWRITE_FONT_WEIGHT enum +// Arguments: +// - fontWeight: the old DWRITE_FONT_WEIGHT enum to be converted into an axis value +// - fontStretch: the old DWRITE_FONT_STRETCH enum to be converted into an axis value +// - fontStyle: the old DWRITE_FONT_STYLE enum to be converted into an axis value +// - fontSize: the number to convert into an axis value +// - format: the IDWriteTextFormat3 to get the defined axes from +// Return value: +// - The fully formed axes vector +std::vector DxFontRenderData::GetAxisVector(const DWRITE_FONT_WEIGHT fontWeight, + const DWRITE_FONT_STRETCH fontStretch, + const DWRITE_FONT_STYLE fontStyle, + const float fontSize, + IDWriteTextFormat3* format) +{ + if (!format) + { + // return early + return {}; + } + const auto axesCount = format->GetFontAxisValueCount(); + std::vector axesVector; + axesVector.resize(axesCount); + format->GetFontAxisValues(axesVector.data(), axesCount); + + auto axisTagPresence = AxisTagPresence::AxisTagPresenceNone; + for (const auto& fontAxisValue : axesVector) + { + switch (fontAxisValue.axisTag) + { + case DWRITE_FONT_AXIS_TAG_WEIGHT: + WI_SetFlag(axisTagPresence, AxisTagPresence::AxisTagPresenceWeight); + break; + case DWRITE_FONT_AXIS_TAG_WIDTH: + WI_SetFlag(axisTagPresence, AxisTagPresence::AxisTagPresenceWidth); + break; + case DWRITE_FONT_AXIS_TAG_ITALIC: + WI_SetFlag(axisTagPresence, AxisTagPresence::AxisTagPresenceItalic); + break; + case DWRITE_FONT_AXIS_TAG_SLANT: + WI_SetFlag(axisTagPresence, AxisTagPresence::AxisTagPresenceSlant); + break; + case DWRITE_FONT_AXIS_TAG_OPTICAL_SIZE: + WI_SetFlag(axisTagPresence, AxisTagPresence::AxisTagPresenceOpticalSize); + break; + } + } + + if (!WI_IsFlagSet(axisTagPresence, AxisTagPresence::AxisTagPresenceWeight)) + { + axesVector.emplace_back(DWRITE_FONT_AXIS_VALUE{ DWRITE_FONT_AXIS_TAG_WEIGHT, gsl::narrow(fontWeight) }); + } + if (!WI_IsFlagSet(axisTagPresence, AxisTagPresence::AxisTagPresenceWidth)) + { + axesVector.emplace_back(DWRITE_FONT_AXIS_VALUE{ DWRITE_FONT_AXIS_TAG_WIDTH, FontStretchToWidthAxisValue(fontStretch) }); + } + if (!WI_IsFlagSet(axisTagPresence, AxisTagPresence::AxisTagPresenceItalic)) + { + axesVector.emplace_back(DWRITE_FONT_AXIS_VALUE{ DWRITE_FONT_AXIS_TAG_ITALIC, (fontStyle == DWRITE_FONT_STYLE_ITALIC ? 1.0f : 0.0f) }); + } + if (!WI_IsFlagSet(axisTagPresence, AxisTagPresence::AxisTagPresenceSlant)) + { + axesVector.emplace_back(DWRITE_FONT_AXIS_VALUE{ DWRITE_FONT_AXIS_TAG_SLANT, FontStyleToSlantFixedAxisValue(fontStyle) }); + } + if (!WI_IsFlagSet(axisTagPresence, AxisTagPresence::AxisTagPresenceOpticalSize)) + { + axesVector.emplace_back(DWRITE_FONT_AXIS_VALUE{ DWRITE_FONT_AXIS_TAG_OPTICAL_SIZE, DIPsToPoints(fontSize) }); + } + + return axesVector; +} + // Routine Description: // - Build the needed data for rendering according to the font used // Arguments: diff --git a/src/renderer/dx/DxFontRenderData.h b/src/renderer/dx/DxFontRenderData.h index 14faeff76c8..0337d5a2f55 100644 --- a/src/renderer/dx/DxFontRenderData.h +++ b/src/renderer/dx/DxFontRenderData.h @@ -16,6 +16,17 @@ namespace Microsoft::Console::Render { + enum class AxisTagPresence : BYTE + { + AxisTagPresenceNone = 0x00, + AxisTagPresenceWeight = 0x01, + AxisTagPresenceWidth = 0x02, + AxisTagPresenceItalic = 0x04, + AxisTagPresenceSlant = 0x08, + AxisTagPresenceOpticalSize = 0x10, + }; + DEFINE_ENUM_FLAG_OPERATORS(AxisTagPresence); + class DxFontRenderData { public: @@ -82,6 +93,15 @@ namespace Microsoft::Console::Render void SetFeatures(std::unordered_map features); void SetAxes(std::unordered_map axes); + float FontStretchToWidthAxisValue(const DWRITE_FONT_STRETCH fontStretch) noexcept; + float FontStyleToSlantFixedAxisValue(const DWRITE_FONT_STYLE fontStyle) noexcept; + float DIPsToPoints(const float fontSize) noexcept; + std::vector GetAxisVector(const DWRITE_FONT_WEIGHT fontWeight, + const DWRITE_FONT_STRETCH fontStretch, + const DWRITE_FONT_STYLE fontStyle, + const float fontSize, + IDWriteTextFormat3* format); + private: using FontAttributeMapKey = uint32_t; From 60225217ca2c673a0c3884d9b636f49683bdb8a8 Mon Sep 17 00:00:00 2001 From: Pankaj Bhojwani Date: Tue, 13 Jul 2021 10:59:44 -0700 Subject: [PATCH 31/49] spell --- .github/actions/spelling/allow/allow.txt | 1 + src/renderer/dx/DxFontRenderData.cpp | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/actions/spelling/allow/allow.txt b/.github/actions/spelling/allow/allow.txt index 0c5bf5cc859..7a2672d6de7 100644 --- a/.github/actions/spelling/allow/allow.txt +++ b/.github/actions/spelling/allow/allow.txt @@ -17,6 +17,7 @@ dzhe Enum'd formattings ftp +fvar geeksforgeeks ghe gje diff --git a/src/renderer/dx/DxFontRenderData.cpp b/src/renderer/dx/DxFontRenderData.cpp index 4377e2c0d42..9916a44e1e2 100644 --- a/src/renderer/dx/DxFontRenderData.cpp +++ b/src/renderer/dx/DxFontRenderData.cpp @@ -540,7 +540,7 @@ void DxFontRenderData::SetAxes(std::unordered_map ax // - The float value corresponding to the passed in fontStretch float DxFontRenderData::FontStretchToWidthAxisValue(const DWRITE_FONT_STRETCH fontStretch) noexcept { - if (fontStretch > fontStretchEnumToVal.size()) + if (gsl::narrow(fontStretch) > fontStretchEnumToVal.size()) { return gsl::at(fontStretchEnumToVal, DWRITE_FONT_STRETCH_NORMAL); } From 1ecc6634d666fbcd8e8a26c517499672d0cc085a Mon Sep 17 00:00:00 2001 From: Pankaj Bhojwani Date: Tue, 13 Jul 2021 11:04:28 -0700 Subject: [PATCH 32/49] format --- src/renderer/dx/DxFontRenderData.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/renderer/dx/DxFontRenderData.cpp b/src/renderer/dx/DxFontRenderData.cpp index 9916a44e1e2..4a7a9daa584 100644 --- a/src/renderer/dx/DxFontRenderData.cpp +++ b/src/renderer/dx/DxFontRenderData.cpp @@ -564,9 +564,9 @@ float DxFontRenderData::FontStyleToSlantFixedAxisValue(const DWRITE_FONT_STYLE f // vast majority of italic fonts are also slanted. Ideally the slant comes from the // 'slnt' value in the STAT or fvar table, or the post table italic angle. - return (fontStyle == DWRITE_FONT_STYLE_ITALIC) ? -12.0f : - (fontStyle == DWRITE_FONT_STYLE_OBLIQUE) ? -20.0f : - /*fontStyle == DWRITE_FONT_STYLE_NORMAL*/ 0.0f; + return (fontStyle == DWRITE_FONT_STYLE_ITALIC) ? -12.0f : + (fontStyle == DWRITE_FONT_STYLE_OBLIQUE) ? -20.0f : + /*fontStyle == DWRITE_FONT_STYLE_NORMAL*/ 0.0f; } // Method Description: From 968fb1be803968f70d215737011a0551d3dc1527 Mon Sep 17 00:00:00 2001 From: Pankaj Bhojwani Date: Tue, 13 Jul 2021 14:48:28 -0700 Subject: [PATCH 33/49] minor fixes --- src/renderer/dx/DxFontRenderData.cpp | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/src/renderer/dx/DxFontRenderData.cpp b/src/renderer/dx/DxFontRenderData.cpp index 4a7a9daa584..4f04c9095e1 100644 --- a/src/renderer/dx/DxFontRenderData.cpp +++ b/src/renderer/dx/DxFontRenderData.cpp @@ -512,7 +512,7 @@ void DxFontRenderData::SetFeatures(std::unordered_map ax // - The float value corresponding to the passed in fontStretch float DxFontRenderData::FontStretchToWidthAxisValue(const DWRITE_FONT_STRETCH fontStretch) noexcept { - if (gsl::narrow(fontStretch) > fontStretchEnumToVal.size()) + if (gsl::narrow_cast(fontStretch) > fontStretchEnumToVal.size()) { return gsl::at(fontStretchEnumToVal, DWRITE_FONT_STRETCH_NORMAL); } else { - return gsl::at(fontStretchEnumToVal, fontStretch); + return fontStretchEnumToVal[fontStretch]; } } @@ -597,11 +597,8 @@ std::vector DxFontRenderData::GetAxisVector(const DWRITE const float fontSize, IDWriteTextFormat3* format) { - if (!format) - { - // return early - return {}; - } + THROW_IF_NULL_ALLOC(format); + const auto axesCount = format->GetFontAxisValueCount(); std::vector axesVector; axesVector.resize(axesCount); From 6dd06f089ce4d0d1c016e433a3f82ba814933b33 Mon Sep 17 00:00:00 2001 From: Pankaj Bhojwani Date: Wed, 14 Jul 2021 10:04:24 -0700 Subject: [PATCH 34/49] fail fast if --- src/renderer/dx/DxFontRenderData.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/renderer/dx/DxFontRenderData.cpp b/src/renderer/dx/DxFontRenderData.cpp index 4f04c9095e1..2f1e6211c12 100644 --- a/src/renderer/dx/DxFontRenderData.cpp +++ b/src/renderer/dx/DxFontRenderData.cpp @@ -546,7 +546,7 @@ float DxFontRenderData::FontStretchToWidthAxisValue(const DWRITE_FONT_STRETCH fo } else { - return fontStretchEnumToVal[fontStretch]; + return til::at(fontStretchEnumToVal, fontStretch); } } @@ -597,7 +597,7 @@ std::vector DxFontRenderData::GetAxisVector(const DWRITE const float fontSize, IDWriteTextFormat3* format) { - THROW_IF_NULL_ALLOC(format); + FAIL_FAST_IF_NULL(format); const auto axesCount = format->GetFontAxisValueCount(); std::vector axesVector; From 4a0541b008fee3a89838176c9f0fcd8bd4f624a7 Mon Sep 17 00:00:00 2001 From: Pankaj Bhojwani Date: Thu, 15 Jul 2021 11:29:43 -0700 Subject: [PATCH 35/49] lhecker comments --- src/cascadia/TerminalControl/ControlCore.cpp | 67 ++++++++++----- src/cascadia/TerminalControl/ControlCore.h | 4 +- .../TerminalSettingsModel/FontConfig.idl | 15 +--- src/renderer/dx/CustomTextLayout.cpp | 6 +- src/renderer/dx/CustomTextLayout.h | 2 +- src/renderer/dx/DxFontRenderData.cpp | 85 +++++++++---------- src/renderer/dx/DxFontRenderData.h | 10 +-- 7 files changed, 98 insertions(+), 91 deletions(-) diff --git a/src/cascadia/TerminalControl/ControlCore.cpp b/src/cascadia/TerminalControl/ControlCore.cpp index aaf05269b11..8eb8926faea 100644 --- a/src/cascadia/TerminalControl/ControlCore.cpp +++ b/src/cascadia/TerminalControl/ControlCore.cpp @@ -159,8 +159,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation // Initialize our font with the renderer // We don't have to care about DPI. We'll get a change message immediately if it's not 96 // and react accordingly. - dxEngine->SetFontFeatures(_fontFeatures); - dxEngine->SetFontAxes(_fontAxes); + SetFontFeaturesInEngine(dxEngine.get()); + SetFontAxesInEngine(dxEngine.get()); _updateFont(true); const COORD windowSize{ static_cast(windowWidth), @@ -507,24 +507,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation const auto fontFace = _settings.FontFace(); const short fontHeight = ::base::saturated_cast(_settings.FontSize()); const auto fontWeight = _settings.FontWeight(); - const auto fontFeatures = _settings.FontFeatures(); - const auto fontAxes = _settings.FontAxes(); - _fontFeatures.clear(); - if (fontFeatures) - { - for (const auto& [tag, param] : _settings.FontFeatures()) - { - _fontFeatures[tag.data()] = param; - } - } - _fontAxes.clear(); - if (fontAxes) - { - for (const auto& [axis, value] : _settings.FontAxes()) - { - _fontAxes[axis.data()] = value; - } - } + // The font width doesn't terribly matter, we'll only be using the // height to look it up // The other params here also largely don't matter. @@ -614,9 +597,9 @@ namespace winrt::Microsoft::Terminal::Control::implementation if (_renderEngine) { - // Make sure to call these before we call TriggerFontChange - _renderEngine->SetFontFeatures(_fontFeatures); - _renderEngine->SetFontAxes(_fontAxes); + // Make sure to call SetFontFeatures/SetFontAxes before we call TriggerFontChange + SetFontFeaturesInEngine(_renderEngine.get()); + SetFontAxesInEngine(_renderEngine.get()); } _terminal->SetFontInfo(_actualFont); @@ -927,6 +910,44 @@ namespace winrt::Microsoft::Terminal::Control::implementation return fontSize.scale(til::math::rounding, 1.0f / ::base::saturated_cast(_compositionScale)); } + void ControlCore::SetFontFeaturesInEngine(::Microsoft::Console::Render::DxEngine* engine) + { + if (engine) + { + if (const auto fontFeatures = _settings.FontFeatures()) + { + std::unordered_map featureMap; + featureMap.reserve(fontFeatures.Size()); + + for (const auto& [tag, param] : fontFeatures) + { + featureMap.emplace(tag, param); + } + + engine->SetFontFeatures(featureMap); + } + } + } + + void ControlCore::SetFontAxesInEngine(::Microsoft::Console::Render::DxEngine* engine) + { + if (engine) + { + if (const auto fontAxes = _settings.FontAxes()) + { + std::unordered_map axesMap; + axesMap.reserve(fontAxes.Size()); + + for (const auto& [axis, value] : fontAxes) + { + axesMap.emplace(axis, value); + } + + engine->SetFontAxes(axesMap); + } + } + } + TerminalConnection::ConnectionState ControlCore::ConnectionState() const { return _connection.State(); diff --git a/src/cascadia/TerminalControl/ControlCore.h b/src/cascadia/TerminalControl/ControlCore.h index a8f20f6559a..2d42ffeb19a 100644 --- a/src/cascadia/TerminalControl/ControlCore.h +++ b/src/cascadia/TerminalControl/ControlCore.h @@ -54,6 +54,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation void ResetFontSize(); FontInfo GetFont() const; til::size FontSizeInDips() const; + void SetFontFeaturesInEngine(::Microsoft::Console::Render::DxEngine* engine); + void SetFontAxesInEngine(::Microsoft::Console::Render::DxEngine* engine); til::color BackgroundColor() const; void SetBackgroundOpacity(const float opacity); @@ -183,8 +185,6 @@ namespace winrt::Microsoft::Terminal::Control::implementation FontInfoDesired _desiredFont; FontInfo _actualFont; - std::unordered_map _fontFeatures; - std::unordered_map _fontAxes; // storage location for the leading surrogate of a utf-16 surrogate pair std::optional _leadingSurrogate{ std::nullopt }; diff --git a/src/cascadia/TerminalSettingsModel/FontConfig.idl b/src/cascadia/TerminalSettingsModel/FontConfig.idl index add87a9f691..c4b95b5b665 100644 --- a/src/cascadia/TerminalSettingsModel/FontConfig.idl +++ b/src/cascadia/TerminalSettingsModel/FontConfig.idl @@ -8,6 +8,8 @@ import "Profile.idl"; _BASE_INHERITABLE_SETTING(Type, Name); \ Microsoft.Terminal.Settings.Model.FontConfig Name##OverrideSource { get; } +#define COMMA , + namespace Microsoft.Terminal.Settings.Model { [default_interface] runtimeclass FontConfig { @@ -17,16 +19,7 @@ namespace Microsoft.Terminal.Settings.Model INHERITABLE_FONT_SETTING(Int32, FontSize); INHERITABLE_FONT_SETTING(Windows.UI.Text.FontWeight, FontWeight); - // The INHERITABLE_FONT_SETTING macro doesn't like Windows.Foundation.Collections.IMap - // (possibly because of the comma) so features and axes are being declared manually for now - Windows.Foundation.Collections.IMap FontFeatures; - Boolean HasFontFeatures { get; }; - void ClearFontFeatures(); - Microsoft.Terminal.Settings.Model.FontConfig FontFeaturesOverrideSource { get; }; - - Windows.Foundation.Collections.IMap FontAxes; - Boolean HasFontAxes { get; }; - void ClearFontAxes(); - Microsoft.Terminal.Settings.Model.FontConfig FontAxesOverrideSource { get; }; + INHERITABLE_FONT_SETTING(Windows.Foundation.Collections.IMap, FontFeatures); + INHERITABLE_FONT_SETTING(Windows.Foundation.Collections.IMap, FontAxes); } } diff --git a/src/renderer/dx/CustomTextLayout.cpp b/src/renderer/dx/CustomTextLayout.cpp index 52b07adb962..4e2b60d97ea 100644 --- a/src/renderer/dx/CustomTextLayout.cpp +++ b/src/renderer/dx/CustomTextLayout.cpp @@ -1327,9 +1327,9 @@ CATCH_RETURN(); &mappedFont, &scale); - RETURN_LAST_ERROR_IF(!mappedFont.Get()); + RETURN_LAST_ERROR_IF(!mappedFont); ::Microsoft::WRL::ComPtr face; - RETURN_IF_FAILED(mappedFont.Get()->CreateFontFace(&face)); + RETURN_IF_FAILED(mappedFont->CreateFontFace(&face)); RETURN_IF_FAILED(_SetMappedFontFace(textPosition, mappedLength, face, scale)); textPosition += mappedLength; @@ -1354,7 +1354,7 @@ CATCH_RETURN(); // - S_OK or appropriate STL/GSL failure code. [[nodiscard]] HRESULT STDMETHODCALLTYPE CustomTextLayout::_SetMappedFontFace(UINT32 textPosition, UINT32 textLength, - ::Microsoft::WRL::ComPtr const fontFace, + const ::Microsoft::WRL::ComPtr& fontFace, FLOAT const scale) { try diff --git a/src/renderer/dx/CustomTextLayout.h b/src/renderer/dx/CustomTextLayout.h index 2a47634575d..d1cbabfdbbc 100644 --- a/src/renderer/dx/CustomTextLayout.h +++ b/src/renderer/dx/CustomTextLayout.h @@ -126,7 +126,7 @@ namespace Microsoft::Console::Render void _OrderRuns(); [[nodiscard]] HRESULT STDMETHODCALLTYPE _AnalyzeFontFallback(IDWriteTextAnalysisSource* const source, UINT32 textPosition, UINT32 textLength); - [[nodiscard]] HRESULT STDMETHODCALLTYPE _SetMappedFontFace(UINT32 textPosition, UINT32 textLength, ::Microsoft::WRL::ComPtr const fontFace, FLOAT const scale); + [[nodiscard]] HRESULT STDMETHODCALLTYPE _SetMappedFontFace(UINT32 textPosition, UINT32 textLength, const ::Microsoft::WRL::ComPtr& fontFace, FLOAT const scale); [[nodiscard]] HRESULT STDMETHODCALLTYPE _AnalyzeBoxDrawing(gsl::not_null const source, UINT32 textPosition, UINT32 textLength); [[nodiscard]] HRESULT STDMETHODCALLTYPE _SetBoxEffect(UINT32 textPosition, UINT32 textLength); diff --git a/src/renderer/dx/DxFontRenderData.cpp b/src/renderer/dx/DxFontRenderData.cpp index 2f1e6211c12..0d33e4fd7e9 100644 --- a/src/renderer/dx/DxFontRenderData.cpp +++ b/src/renderer/dx/DxFontRenderData.cpp @@ -17,6 +17,9 @@ static constexpr size_t TAG_LENGTH = 4; // 10 elements from DWRITE_FONT_STRETCH_UNDEFINED (0) to DWRITE_FONT_STRETCH_ULTRA_EXPANDED (9) static constexpr auto fontStretchEnumToVal = std::array{ 100.0f, 50.0f, 62.5f, 75.0f, 87.5f, 100.0f, 112.5f, 125.0f, 150.0f, 200.0f }; +// DWRITE_FONT_STYLE_NORMAL (0), DWRITE_FONT_STYLE_OBLIQUE (1), DWRITE_FONT_STYLE_ITALIC (2) +static constexpr auto fontStyleEnumToVal = std::array{ 0.0f, -20.0f, -12.0f }; + using namespace Microsoft::Console::Render; DxFontRenderData::DxFontRenderData(::Microsoft::WRL::ComPtr dwriteFactory) noexcept : @@ -457,36 +460,28 @@ bool DxFontRenderData::DidUserSetFeatures() const noexcept return _didUserSetFeatures; } -// Routine Description: -// - Clears our internal feature map and populates it with the list of standard features -void DxFontRenderData::InitializeFeatureMap() -{ - _featureMap.clear(); - _featureMap = { - { L"rlig", 1 }, - { L"rclt", 1 }, - { L"locl", 1 }, - { L"ccmp", 1 }, - { L"calt", 1 }, - { L"liga", 1 }, - { L"clig", 1 }, - { L"kern", 1 }, - { L"mark", 1 }, - { L"mkmk", 1 }, - { L"dist", 1 } - }; -} - // Routine Description: // - Updates our internal map of font features with the given features // - NOTE TO CALLER: Make sure to call UpdateFont after calling this for the feature changes // to take place // Arguments: // - features - the features to update our map with -void DxFontRenderData::SetFeatures(std::unordered_map features) +void DxFontRenderData::SetFeatures(const std::unordered_map& features) { - // Populate our feature map with the standard list - InitializeFeatureMap(); + // Populate the feature map with the standard list first + std::unordered_map featureMap{ + { DWRITE_MAKE_FONT_FEATURE_TAG('r', 'l', 'i', 'g'), 1 }, + { DWRITE_MAKE_FONT_FEATURE_TAG('r', 'c', 'l', 't'), 1 }, + { DWRITE_MAKE_FONT_FEATURE_TAG('l', 'o', 'c', 'l'), 1 }, + { DWRITE_MAKE_FONT_FEATURE_TAG('c', 'c', 'm', 'p'), 1 }, + { DWRITE_MAKE_FONT_FEATURE_TAG('c', 'a', 'l', 't'), 1 }, + { DWRITE_MAKE_FONT_FEATURE_TAG('l', 'i', 'h', 'a'), 1 }, + { DWRITE_MAKE_FONT_FEATURE_TAG('c', 'l', 'i', 'g'), 1 }, + { DWRITE_MAKE_FONT_FEATURE_TAG('k', 'e', 'r', 'n'), 1 }, + { DWRITE_MAKE_FONT_FEATURE_TAG('m', 'a', 'r', 'k'), 1 }, + { DWRITE_MAKE_FONT_FEATURE_TAG('m', 'k', 'm', 'k'), 1 }, + { DWRITE_MAKE_FONT_FEATURE_TAG('d', 'i', 's', 't'), 1 } + }; // Update our feature map with the provided features if (!features.empty()) @@ -495,7 +490,7 @@ void DxFontRenderData::SetFeatures(std::unordered_map axes) +void DxFontRenderData::SetAxes(const std::unordered_map& axes) { _axesVector.clear(); @@ -525,7 +519,7 @@ void DxFontRenderData::SetAxes(std::unordered_map ax { if (axis.length() == TAG_LENGTH) { - const auto dwriteTag = DWRITE_MAKE_FONT_AXIS_TAG(gsl::at(axis, 0), gsl::at(axis, 1), gsl::at(axis, 2), gsl::at(axis, 3)); + const auto dwriteTag = DWRITE_MAKE_FONT_AXIS_TAG(til::at(axis, 0), til::at(axis, 1), til::at(axis, 2), til::at(axis, 3)); _axesVector.emplace_back(DWRITE_FONT_AXIS_VALUE{ dwriteTag, gsl::narrow(value) }); } } @@ -538,16 +532,14 @@ void DxFontRenderData::SetAxes(std::unordered_map ax // - fontStretch: the old DWRITE_FONT_STRETCH enum to be converted into an axis value // Return value: // - The float value corresponding to the passed in fontStretch -float DxFontRenderData::FontStretchToWidthAxisValue(const DWRITE_FONT_STRETCH fontStretch) noexcept +float DxFontRenderData::FontStretchToWidthAxisValue(DWRITE_FONT_STRETCH fontStretch) noexcept { if (gsl::narrow_cast(fontStretch) > fontStretchEnumToVal.size()) { - return gsl::at(fontStretchEnumToVal, DWRITE_FONT_STRETCH_NORMAL); - } - else - { - return til::at(fontStretchEnumToVal, fontStretch); + fontStretch = DWRITE_FONT_STRETCH_NORMAL; } + + return til::at(fontStretchEnumToVal, fontStretch); } // Method Description: @@ -557,16 +549,19 @@ float DxFontRenderData::FontStretchToWidthAxisValue(const DWRITE_FONT_STRETCH fo // - fontStyle: the old DWRITE_FONT_STYLE enum to be converted into an axis value // Return value: // - The float value corresponding to the passed in fontStyle -float DxFontRenderData::FontStyleToSlantFixedAxisValue(const DWRITE_FONT_STYLE fontStyle) noexcept +float DxFontRenderData::FontStyleToSlantFixedAxisValue(DWRITE_FONT_STYLE fontStyle) noexcept { // Both DWRITE_FONT_STYLE_OBLIQUE and DWRITE_FONT_STYLE_ITALIC default to having slant. // Though an italic font technically need not have slant (there exist upright ones), the // vast majority of italic fonts are also slanted. Ideally the slant comes from the // 'slnt' value in the STAT or fvar table, or the post table italic angle. - return (fontStyle == DWRITE_FONT_STYLE_ITALIC) ? -12.0f : - (fontStyle == DWRITE_FONT_STYLE_OBLIQUE) ? -20.0f : - /*fontStyle == DWRITE_FONT_STYLE_NORMAL*/ 0.0f; + if (gsl::narrow_cast(fontStyle) > fontStyleEnumToVal.size()) + { + fontStyle = DWRITE_FONT_STYLE_NORMAL; + } + + return til::at(fontStyleEnumToVal, fontStyle); } // Method Description: @@ -627,23 +622,23 @@ std::vector DxFontRenderData::GetAxisVector(const DWRITE } } - if (!WI_IsFlagSet(axisTagPresence, AxisTagPresence::AxisTagPresenceWeight)) + if (WI_IsFlagClear(axisTagPresence, AxisTagPresence::AxisTagPresenceWeight)) { axesVector.emplace_back(DWRITE_FONT_AXIS_VALUE{ DWRITE_FONT_AXIS_TAG_WEIGHT, gsl::narrow(fontWeight) }); } - if (!WI_IsFlagSet(axisTagPresence, AxisTagPresence::AxisTagPresenceWidth)) + if (WI_IsFlagClear(axisTagPresence, AxisTagPresence::AxisTagPresenceWidth)) { axesVector.emplace_back(DWRITE_FONT_AXIS_VALUE{ DWRITE_FONT_AXIS_TAG_WIDTH, FontStretchToWidthAxisValue(fontStretch) }); } - if (!WI_IsFlagSet(axisTagPresence, AxisTagPresence::AxisTagPresenceItalic)) + if (WI_IsFlagClear(axisTagPresence, AxisTagPresence::AxisTagPresenceItalic)) { axesVector.emplace_back(DWRITE_FONT_AXIS_VALUE{ DWRITE_FONT_AXIS_TAG_ITALIC, (fontStyle == DWRITE_FONT_STYLE_ITALIC ? 1.0f : 0.0f) }); } - if (!WI_IsFlagSet(axisTagPresence, AxisTagPresence::AxisTagPresenceSlant)) + if (WI_IsFlagClear(axisTagPresence, AxisTagPresence::AxisTagPresenceSlant)) { axesVector.emplace_back(DWRITE_FONT_AXIS_VALUE{ DWRITE_FONT_AXIS_TAG_SLANT, FontStyleToSlantFixedAxisValue(fontStyle) }); } - if (!WI_IsFlagSet(axisTagPresence, AxisTagPresence::AxisTagPresenceOpticalSize)) + if (WI_IsFlagClear(axisTagPresence, AxisTagPresence::AxisTagPresenceOpticalSize)) { axesVector.emplace_back(DWRITE_FONT_AXIS_VALUE{ DWRITE_FONT_AXIS_TAG_OPTICAL_SIZE, DIPsToPoints(fontSize) }); } @@ -864,7 +859,7 @@ Microsoft::WRL::ComPtr DxFontRenderData::_BuildTextFormat(con ::Microsoft::WRL::ComPtr format3; if (!FAILED(format->QueryInterface(IID_PPV_ARGS(&format3))) && !_axesVector.empty()) { - DWRITE_FONT_AXIS_VALUE const* axesList = &gsl::at(_axesVector, 0); + DWRITE_FONT_AXIS_VALUE const* axesList = _axesVector.data(); format3->SetFontAxisValues(axesList, gsl::narrow(_axesVector.size())); } diff --git a/src/renderer/dx/DxFontRenderData.h b/src/renderer/dx/DxFontRenderData.h index 0337d5a2f55..06c41df5193 100644 --- a/src/renderer/dx/DxFontRenderData.h +++ b/src/renderer/dx/DxFontRenderData.h @@ -89,12 +89,11 @@ namespace Microsoft::Console::Render [[nodiscard]] static HRESULT STDMETHODCALLTYPE s_CalculateBoxEffect(IDWriteTextFormat* format, size_t widthPixels, IDWriteFontFace1* face, float fontScale, IBoxDrawingEffect** effect) noexcept; bool DidUserSetFeatures() const noexcept; - void InitializeFeatureMap(); - void SetFeatures(std::unordered_map features); - void SetAxes(std::unordered_map axes); + void SetFeatures(const std::unordered_map& features); + void SetAxes(const std::unordered_map& axes); - float FontStretchToWidthAxisValue(const DWRITE_FONT_STRETCH fontStretch) noexcept; - float FontStyleToSlantFixedAxisValue(const DWRITE_FONT_STYLE fontStyle) noexcept; + float FontStretchToWidthAxisValue(DWRITE_FONT_STRETCH fontStretch) noexcept; + float FontStyleToSlantFixedAxisValue(DWRITE_FONT_STYLE fontStyle) noexcept; float DIPsToPoints(const float fontSize) noexcept; std::vector GetAxisVector(const DWRITE_FONT_WEIGHT fontWeight, const DWRITE_FONT_STRETCH fontStretch, @@ -107,7 +106,6 @@ namespace Microsoft::Console::Render bool _didUserSetFeatures{ false }; // The font features to apply to the text - std::unordered_map _featureMap; std::vector _featureVector; // The font axes to apply to the text From fc28c721e65de94236802a67f346e7b1ab1944fe Mon Sep 17 00:00:00 2001 From: Pankaj Bhojwani Date: Thu, 15 Jul 2021 13:09:14 -0700 Subject: [PATCH 36/49] try QI members --- src/renderer/dx/CustomTextLayout.cpp | 61 ++++++++++++++++++++-------- src/renderer/dx/CustomTextLayout.h | 4 ++ src/renderer/dx/DxFontRenderData.cpp | 2 + 3 files changed, 49 insertions(+), 18 deletions(-) diff --git a/src/renderer/dx/CustomTextLayout.cpp b/src/renderer/dx/CustomTextLayout.cpp index 4e2b60d97ea..4d82621fb64 100644 --- a/src/renderer/dx/CustomTextLayout.cpp +++ b/src/renderer/dx/CustomTextLayout.cpp @@ -101,6 +101,10 @@ CATCH_RETURN() *columns = 0; _formatInUse = _fontRenderData->DefaultTextFormat().Get(); + // the _formatInUse changed, make sure to clear _format1, _format3 and _fallback1 + _format1.Reset(); + _format3.Reset(); + _fallback1.Reset(); _fontInUse = _fontRenderData->DefaultFontFace().Get(); RETURN_IF_FAILED(_AnalyzeTextComplexity()); @@ -155,6 +159,11 @@ try _formatInUse = _fontRenderData->TextFormatWithAttribute(weight, style, stretch).Get(); _fontInUse = _fontRenderData->FontFaceWithAttribute(weight, style, stretch).Get(); + // the _formatInUse changed, make sure to clear _format1, _format3 and _fallback1 + _format1.Reset(); + _format3.Reset(); + _fallback1.Reset(); + RETURN_IF_FAILED(_AnalyzeTextComplexity()); RETURN_IF_FAILED(_AnalyzeRuns()); RETURN_IF_FAILED(_ShapeGlyphRuns()); @@ -1245,39 +1254,55 @@ CATCH_RETURN(); try { // Get the font fallback first - ::Microsoft::WRL::ComPtr format1; - if (FAILED(_formatInUse->QueryInterface(IID_PPV_ARGS(&format1)))) + if (!_format1) { - // If IDWriteTextFormat1 does not exist, return directly as this OS version doesn't have font fallback. - return S_FALSE; + if (FAILED(_formatInUse->QueryInterface(IID_PPV_ARGS(&_format1)))) + { + // If IDWriteTextFormat1 does not exist, return directly as this OS version doesn't have font fallback. + return S_FALSE; + } } - RETURN_HR_IF_NULL(E_NOINTERFACE, format1); + RETURN_HR_IF_NULL(E_NOINTERFACE, _format1); ::Microsoft::WRL::ComPtr fallback; - RETURN_IF_FAILED(format1->GetFontFallback(&fallback)); + RETURN_IF_FAILED(_format1->GetFontFallback(&fallback)); ::Microsoft::WRL::ComPtr collection; - RETURN_IF_FAILED(format1->GetFontCollection(&collection)); + RETURN_IF_FAILED(_format1->GetFontCollection(&collection)); std::wstring familyName; - familyName.resize(gsl::narrow_cast(format1->GetFontFamilyNameLength()) + 1); - RETURN_IF_FAILED(format1->GetFontFamilyName(familyName.data(), gsl::narrow(familyName.size()))); + familyName.resize(gsl::narrow_cast(_format1->GetFontFamilyNameLength()) + 1); + RETURN_IF_FAILED(_format1->GetFontFamilyName(familyName.data(), gsl::narrow(familyName.size()))); - const auto weight = format1->GetFontWeight(); - const auto style = format1->GetFontStyle(); - const auto stretch = format1->GetFontStretch(); + const auto weight = _format1->GetFontWeight(); + const auto style = _format1->GetFontStyle(); + const auto stretch = _format1->GetFontStretch(); if (!fallback) { fallback = _fontRenderData->SystemFontFallback(); } - ::Microsoft::WRL::ComPtr fallback1; - ::Microsoft::WRL::ComPtr format3; - if (!FAILED(_formatInUse->QueryInterface(IID_PPV_ARGS(&format3))) && !FAILED(fallback->QueryInterface(IID_PPV_ARGS(&fallback1)))) + // If the OS supports IDWriteFontFallback1 and IDWriteTextFormat3, we can use the + // newer MapCharacters to apply axes of variation to the font + bool useNewMapCharacters{ true }; + if (!_format3) + { + if (FAILED(_formatInUse->QueryInterface(IID_PPV_ARGS(&_format3)))) + { + useNewMapCharacters = false; + } + } + if (!_fallback1) + { + if (FAILED(fallback->QueryInterface(IID_PPV_ARGS(&_fallback1)))) + { + useNewMapCharacters = false; + } + } + if (useNewMapCharacters) { - // If the OS supports IDWriteFontFallback1 and IDWriteTextFormat3, we can apply axes of variation to the font - const auto axesVector = _fontRenderData->GetAxisVector(weight, stretch, style, format1->GetFontSize(), format3.Get()); + const auto axesVector = _fontRenderData->GetAxisVector(weight, stretch, style, _format1->GetFontSize(), _format3.Get()); // Walk through and analyze the entire string while (textLength > 0) { @@ -1285,7 +1310,7 @@ CATCH_RETURN(); ::Microsoft::WRL::ComPtr mappedFont; FLOAT scale = 0.0f; - fallback1->MapCharacters(source, + _fallback1->MapCharacters(source, textPosition, textLength, collection.Get(), diff --git a/src/renderer/dx/CustomTextLayout.h b/src/renderer/dx/CustomTextLayout.h index d1cbabfdbbc..7d7170b83d6 100644 --- a/src/renderer/dx/CustomTextLayout.h +++ b/src/renderer/dx/CustomTextLayout.h @@ -196,6 +196,10 @@ namespace Microsoft::Console::Render std::vector _glyphAdvances; + ::Microsoft::WRL::ComPtr _format1; + ::Microsoft::WRL::ComPtr _fallback1; + ::Microsoft::WRL::ComPtr _format3; + struct ScaleCorrection { UINT32 textIndex; diff --git a/src/renderer/dx/DxFontRenderData.cpp b/src/renderer/dx/DxFontRenderData.cpp index 0d33e4fd7e9..4a35f1fe2c2 100644 --- a/src/renderer/dx/DxFontRenderData.cpp +++ b/src/renderer/dx/DxFontRenderData.cpp @@ -592,6 +592,8 @@ std::vector DxFontRenderData::GetAxisVector(const DWRITE const float fontSize, IDWriteTextFormat3* format) { +#pragma warning(suppress : 26429) // the analyzer doesn't detect that our FAIL_FAST_IF_NULL macro + // checks format for nullness FAIL_FAST_IF_NULL(format); const auto axesCount = format->GetFontAxisValueCount(); From 2f8f4faafb17406d353e52b7c535e25f024b3981 Mon Sep 17 00:00:00 2001 From: Pankaj Bhojwani Date: Thu, 15 Jul 2021 14:09:06 -0700 Subject: [PATCH 37/49] comments on standard list of features --- src/renderer/dx/DxFontRenderData.cpp | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/renderer/dx/DxFontRenderData.cpp b/src/renderer/dx/DxFontRenderData.cpp index 4a35f1fe2c2..367a3cef3a3 100644 --- a/src/renderer/dx/DxFontRenderData.cpp +++ b/src/renderer/dx/DxFontRenderData.cpp @@ -470,17 +470,17 @@ void DxFontRenderData::SetFeatures(const std::unordered_map featureMap{ - { DWRITE_MAKE_FONT_FEATURE_TAG('r', 'l', 'i', 'g'), 1 }, - { DWRITE_MAKE_FONT_FEATURE_TAG('r', 'c', 'l', 't'), 1 }, - { DWRITE_MAKE_FONT_FEATURE_TAG('l', 'o', 'c', 'l'), 1 }, - { DWRITE_MAKE_FONT_FEATURE_TAG('c', 'c', 'm', 'p'), 1 }, - { DWRITE_MAKE_FONT_FEATURE_TAG('c', 'a', 'l', 't'), 1 }, - { DWRITE_MAKE_FONT_FEATURE_TAG('l', 'i', 'h', 'a'), 1 }, - { DWRITE_MAKE_FONT_FEATURE_TAG('c', 'l', 'i', 'g'), 1 }, - { DWRITE_MAKE_FONT_FEATURE_TAG('k', 'e', 'r', 'n'), 1 }, - { DWRITE_MAKE_FONT_FEATURE_TAG('m', 'a', 'r', 'k'), 1 }, - { DWRITE_MAKE_FONT_FEATURE_TAG('m', 'k', 'm', 'k'), 1 }, - { DWRITE_MAKE_FONT_FEATURE_TAG('d', 'i', 's', 't'), 1 } + { DWRITE_MAKE_FONT_FEATURE_TAG('r', 'l', 'i', 'g'), 1 }, // Required Ligatures + { DWRITE_MAKE_FONT_FEATURE_TAG('r', 'c', 'l', 't'), 1 }, // Required Contextual Alternates + { DWRITE_MAKE_FONT_FEATURE_TAG('l', 'o', 'c', 'l'), 1 }, // Localized Forms + { DWRITE_MAKE_FONT_FEATURE_TAG('c', 'c', 'm', 'p'), 1 }, // Glyph Composition / Decomposition + { DWRITE_MAKE_FONT_FEATURE_TAG('c', 'a', 'l', 't'), 1 }, // Contextual Alternates + { DWRITE_MAKE_FONT_FEATURE_TAG('l', 'i', 'g', 'a'), 1 }, // Standard Ligatures + { DWRITE_MAKE_FONT_FEATURE_TAG('c', 'l', 'i', 'g'), 1 }, // Contextual Ligatures + { DWRITE_MAKE_FONT_FEATURE_TAG('k', 'e', 'r', 'n'), 1 }, // Kerning + { DWRITE_MAKE_FONT_FEATURE_TAG('m', 'a', 'r', 'k'), 1 }, // Mark Positioning + { DWRITE_MAKE_FONT_FEATURE_TAG('m', 'k', 'm', 'k'), 1 }, // Mark to Mark Positioning + { DWRITE_MAKE_FONT_FEATURE_TAG('d', 'i', 's', 't'), 1 } // Distances }; // Update our feature map with the provided features From 7554210c22c6e2d89f3c069ccc67f6c8cf441428 Mon Sep 17 00:00:00 2001 From: Pankaj Bhojwani Date: Thu, 15 Jul 2021 15:12:14 -0700 Subject: [PATCH 38/49] undo QI members --- src/renderer/dx/CustomTextLayout.cpp | 59 +++++++++------------------- src/renderer/dx/CustomTextLayout.h | 4 -- 2 files changed, 18 insertions(+), 45 deletions(-) diff --git a/src/renderer/dx/CustomTextLayout.cpp b/src/renderer/dx/CustomTextLayout.cpp index 4d82621fb64..24f0205deab 100644 --- a/src/renderer/dx/CustomTextLayout.cpp +++ b/src/renderer/dx/CustomTextLayout.cpp @@ -101,10 +101,6 @@ CATCH_RETURN() *columns = 0; _formatInUse = _fontRenderData->DefaultTextFormat().Get(); - // the _formatInUse changed, make sure to clear _format1, _format3 and _fallback1 - _format1.Reset(); - _format3.Reset(); - _fallback1.Reset(); _fontInUse = _fontRenderData->DefaultFontFace().Get(); RETURN_IF_FAILED(_AnalyzeTextComplexity()); @@ -159,11 +155,6 @@ try _formatInUse = _fontRenderData->TextFormatWithAttribute(weight, style, stretch).Get(); _fontInUse = _fontRenderData->FontFaceWithAttribute(weight, style, stretch).Get(); - // the _formatInUse changed, make sure to clear _format1, _format3 and _fallback1 - _format1.Reset(); - _format3.Reset(); - _fallback1.Reset(); - RETURN_IF_FAILED(_AnalyzeTextComplexity()); RETURN_IF_FAILED(_AnalyzeRuns()); RETURN_IF_FAILED(_ShapeGlyphRuns()); @@ -1254,55 +1245,41 @@ CATCH_RETURN(); try { // Get the font fallback first - if (!_format1) + ::Microsoft::WRL::ComPtr format1; + if (FAILED(_formatInUse->QueryInterface(IID_PPV_ARGS(&format1)))) { - if (FAILED(_formatInUse->QueryInterface(IID_PPV_ARGS(&_format1)))) - { - // If IDWriteTextFormat1 does not exist, return directly as this OS version doesn't have font fallback. - return S_FALSE; - } + // If IDWriteTextFormat1 does not exist, return directly as this OS version doesn't have font fallback. + return S_FALSE; } - RETURN_HR_IF_NULL(E_NOINTERFACE, _format1); + RETURN_HR_IF_NULL(E_NOINTERFACE, format1); ::Microsoft::WRL::ComPtr fallback; - RETURN_IF_FAILED(_format1->GetFontFallback(&fallback)); + RETURN_IF_FAILED(format1->GetFontFallback(&fallback)); ::Microsoft::WRL::ComPtr collection; - RETURN_IF_FAILED(_format1->GetFontCollection(&collection)); + RETURN_IF_FAILED(format1->GetFontCollection(&collection)); std::wstring familyName; - familyName.resize(gsl::narrow_cast(_format1->GetFontFamilyNameLength()) + 1); - RETURN_IF_FAILED(_format1->GetFontFamilyName(familyName.data(), gsl::narrow(familyName.size()))); + familyName.resize(gsl::narrow_cast(format1->GetFontFamilyNameLength()) + 1); + RETURN_IF_FAILED(format1->GetFontFamilyName(familyName.data(), gsl::narrow(familyName.size()))); - const auto weight = _format1->GetFontWeight(); - const auto style = _format1->GetFontStyle(); - const auto stretch = _format1->GetFontStretch(); + const auto weight = format1->GetFontWeight(); + const auto style = format1->GetFontStyle(); + const auto stretch = format1->GetFontStretch(); if (!fallback) { fallback = _fontRenderData->SystemFontFallback(); } + ::Microsoft::WRL::ComPtr fallback1; + ::Microsoft::WRL::ComPtr format3; + // If the OS supports IDWriteFontFallback1 and IDWriteTextFormat3, we can use the // newer MapCharacters to apply axes of variation to the font - bool useNewMapCharacters{ true }; - if (!_format3) - { - if (FAILED(_formatInUse->QueryInterface(IID_PPV_ARGS(&_format3)))) - { - useNewMapCharacters = false; - } - } - if (!_fallback1) - { - if (FAILED(fallback->QueryInterface(IID_PPV_ARGS(&_fallback1)))) - { - useNewMapCharacters = false; - } - } - if (useNewMapCharacters) + if (!FAILED(_formatInUse->QueryInterface(IID_PPV_ARGS(&format3))) && !FAILED(fallback->QueryInterface(IID_PPV_ARGS(&fallback1)))) { - const auto axesVector = _fontRenderData->GetAxisVector(weight, stretch, style, _format1->GetFontSize(), _format3.Get()); + const auto axesVector = _fontRenderData->GetAxisVector(weight, stretch, style, format1->GetFontSize(), format3.Get()); // Walk through and analyze the entire string while (textLength > 0) { @@ -1310,7 +1287,7 @@ CATCH_RETURN(); ::Microsoft::WRL::ComPtr mappedFont; FLOAT scale = 0.0f; - _fallback1->MapCharacters(source, + fallback1->MapCharacters(source, textPosition, textLength, collection.Get(), diff --git a/src/renderer/dx/CustomTextLayout.h b/src/renderer/dx/CustomTextLayout.h index 7d7170b83d6..d1cbabfdbbc 100644 --- a/src/renderer/dx/CustomTextLayout.h +++ b/src/renderer/dx/CustomTextLayout.h @@ -196,10 +196,6 @@ namespace Microsoft::Console::Render std::vector _glyphAdvances; - ::Microsoft::WRL::ComPtr _format1; - ::Microsoft::WRL::ComPtr _fallback1; - ::Microsoft::WRL::ComPtr _format3; - struct ScaleCorrection { UINT32 textIndex; From a94a9aff5f526c8a1e19b3947c2161a2d241b284 Mon Sep 17 00:00:00 2001 From: Pankaj Bhojwani Date: Thu, 15 Jul 2021 16:20:04 -0700 Subject: [PATCH 39/49] try unify --- src/cascadia/TerminalControl/ControlCore.cpp | 66 ++++++-------------- src/cascadia/TerminalControl/ControlCore.h | 2 - src/renderer/base/renderer.cpp | 4 +- src/renderer/base/renderer.hpp | 4 +- src/renderer/dx/DxFontRenderData.cpp | 11 +++- src/renderer/dx/DxFontRenderData.h | 2 +- src/renderer/dx/DxRenderer.cpp | 4 +- src/renderer/dx/DxRenderer.hpp | 2 +- src/renderer/gdi/gdirenderer.hpp | 4 +- src/renderer/gdi/state.cpp | 2 +- src/renderer/inc/IRenderEngine.hpp | 4 +- src/renderer/inc/IRenderer.hpp | 4 +- src/renderer/uia/UiaRenderer.cpp | 2 +- src/renderer/uia/UiaRenderer.hpp | 2 +- src/renderer/vt/state.cpp | 4 +- src/renderer/vt/vtrenderer.hpp | 4 +- 16 files changed, 56 insertions(+), 65 deletions(-) diff --git a/src/cascadia/TerminalControl/ControlCore.cpp b/src/cascadia/TerminalControl/ControlCore.cpp index 8eb8926faea..eb2523c7a43 100644 --- a/src/cascadia/TerminalControl/ControlCore.cpp +++ b/src/cascadia/TerminalControl/ControlCore.cpp @@ -159,8 +159,6 @@ namespace winrt::Microsoft::Terminal::Control::implementation // Initialize our font with the renderer // We don't have to care about DPI. We'll get a change message immediately if it's not 96 // and react accordingly. - SetFontFeaturesInEngine(dxEngine.get()); - SetFontAxesInEngine(dxEngine.get()); _updateFont(true); const COORD windowSize{ static_cast(windowWidth), @@ -595,17 +593,31 @@ namespace winrt::Microsoft::Terminal::Control::implementation const int newDpi = static_cast(static_cast(USER_DEFAULT_SCREEN_DPI) * _compositionScale); - if (_renderEngine) + _terminal->SetFontInfo(_actualFont); + + std::unordered_map featureMap; + if (const auto fontFeatures = _settings.FontFeatures()) { - // Make sure to call SetFontFeatures/SetFontAxes before we call TriggerFontChange - SetFontFeaturesInEngine(_renderEngine.get()); - SetFontAxesInEngine(_renderEngine.get()); + featureMap.reserve(fontFeatures.Size()); + + for (const auto& [tag, param] : fontFeatures) + { + featureMap.emplace(tag, param); + } } - _terminal->SetFontInfo(_actualFont); + std::unordered_map axesMap; + if (const auto fontAxes = _settings.FontAxes()) + { + axesMap.reserve(fontAxes.Size()); + for (const auto& [axis, value] : fontAxes) + { + axesMap.emplace(axis, value); + } + } // TODO: MSFT:20895307 If the font doesn't exist, this doesn't // actually fail. We need a way to gracefully fallback. - _renderer->TriggerFontChange(newDpi, _desiredFont, _actualFont); + _renderer->TriggerFontChange(newDpi, _desiredFont, _actualFont, featureMap, axesMap); // If the actual font isn't what was requested... if (_actualFont.GetFaceName() != _desiredFont.GetFaceName()) @@ -910,44 +922,6 @@ namespace winrt::Microsoft::Terminal::Control::implementation return fontSize.scale(til::math::rounding, 1.0f / ::base::saturated_cast(_compositionScale)); } - void ControlCore::SetFontFeaturesInEngine(::Microsoft::Console::Render::DxEngine* engine) - { - if (engine) - { - if (const auto fontFeatures = _settings.FontFeatures()) - { - std::unordered_map featureMap; - featureMap.reserve(fontFeatures.Size()); - - for (const auto& [tag, param] : fontFeatures) - { - featureMap.emplace(tag, param); - } - - engine->SetFontFeatures(featureMap); - } - } - } - - void ControlCore::SetFontAxesInEngine(::Microsoft::Console::Render::DxEngine* engine) - { - if (engine) - { - if (const auto fontAxes = _settings.FontAxes()) - { - std::unordered_map axesMap; - axesMap.reserve(fontAxes.Size()); - - for (const auto& [axis, value] : fontAxes) - { - axesMap.emplace(axis, value); - } - - engine->SetFontAxes(axesMap); - } - } - } - TerminalConnection::ConnectionState ControlCore::ConnectionState() const { return _connection.State(); diff --git a/src/cascadia/TerminalControl/ControlCore.h b/src/cascadia/TerminalControl/ControlCore.h index 2d42ffeb19a..e4941e00a5e 100644 --- a/src/cascadia/TerminalControl/ControlCore.h +++ b/src/cascadia/TerminalControl/ControlCore.h @@ -54,8 +54,6 @@ namespace winrt::Microsoft::Terminal::Control::implementation void ResetFontSize(); FontInfo GetFont() const; til::size FontSizeInDips() const; - void SetFontFeaturesInEngine(::Microsoft::Console::Render::DxEngine* engine); - void SetFontAxesInEngine(::Microsoft::Console::Render::DxEngine* engine); til::color BackgroundColor() const; void SetBackgroundOpacity(const float opacity); diff --git a/src/renderer/base/renderer.cpp b/src/renderer/base/renderer.cpp index b53bc6eadf6..09e839a0af8 100644 --- a/src/renderer/base/renderer.cpp +++ b/src/renderer/base/renderer.cpp @@ -516,11 +516,11 @@ HRESULT Renderer::_PaintTitle(IRenderEngine* const pEngine) // - FontInfo - Data that will be fixed up/filled on return with the chosen font data. // Return Value: // - -void Renderer::TriggerFontChange(const int iDpi, const FontInfoDesired& FontInfoDesired, _Out_ FontInfo& FontInfo) +void Renderer::TriggerFontChange(const int iDpi, const FontInfoDesired& FontInfoDesired, _Out_ FontInfo& FontInfo, std::optional> features, std::optional> axes) { std::for_each(_rgpEngines.begin(), _rgpEngines.end(), [&](IRenderEngine* const pEngine) { LOG_IF_FAILED(pEngine->UpdateDpi(iDpi)); - LOG_IF_FAILED(pEngine->UpdateFont(FontInfoDesired, FontInfo)); + LOG_IF_FAILED(pEngine->UpdateFont(FontInfoDesired, FontInfo, features, axes)); }); _NotifyPaintFrame(); diff --git a/src/renderer/base/renderer.hpp b/src/renderer/base/renderer.hpp index 6f8f6d7a8c4..9f931ed1502 100644 --- a/src/renderer/base/renderer.hpp +++ b/src/renderer/base/renderer.hpp @@ -63,7 +63,9 @@ namespace Microsoft::Console::Render void TriggerFontChange(const int iDpi, const FontInfoDesired& FontInfoDesired, - _Out_ FontInfo& FontInfo) override; + _Out_ FontInfo& FontInfo, + std::optional> features = std::nullopt, + std::optional> axes = std::nullopt) override; [[nodiscard]] HRESULT GetProposedFont(const int iDpi, const FontInfoDesired& FontInfoDesired, diff --git a/src/renderer/dx/DxFontRenderData.cpp b/src/renderer/dx/DxFontRenderData.cpp index 367a3cef3a3..b65c7081659 100644 --- a/src/renderer/dx/DxFontRenderData.cpp +++ b/src/renderer/dx/DxFontRenderData.cpp @@ -190,7 +190,7 @@ DxFontRenderData::DxFontRenderData(::Microsoft::WRL::ComPtr dwr // - dpi - The DPI of the screen // Return Value: // - S_OK or relevant DirectX error -[[nodiscard]] HRESULT DxFontRenderData::UpdateFont(const FontInfoDesired& desired, FontInfo& actual, const int dpi) noexcept +[[nodiscard]] HRESULT DxFontRenderData::UpdateFont(const FontInfoDesired& desired, FontInfo& actual, const int dpi, std::optional> features, std::optional> axes) noexcept { try { @@ -204,7 +204,14 @@ DxFontRenderData::DxFontRenderData(::Microsoft::WRL::ComPtr dwr desired.GetWeight(), DWRITE_FONT_STYLE_NORMAL, DWRITE_FONT_STRETCH_NORMAL); - + if (features) + { + SetFeatures(features.value()); + } + if (axes) + { + SetAxes(axes.value()); + } _BuildFontRenderData(desired, actual, dpi); } CATCH_RETURN(); diff --git a/src/renderer/dx/DxFontRenderData.h b/src/renderer/dx/DxFontRenderData.h index 06c41df5193..449476ded3a 100644 --- a/src/renderer/dx/DxFontRenderData.h +++ b/src/renderer/dx/DxFontRenderData.h @@ -84,7 +84,7 @@ namespace Microsoft::Console::Render DWRITE_FONT_STYLE style, DWRITE_FONT_STRETCH stretch); - [[nodiscard]] HRESULT UpdateFont(const FontInfoDesired& desired, FontInfo& fiFontInfo, const int dpi) noexcept; + [[nodiscard]] HRESULT UpdateFont(const FontInfoDesired& desired, FontInfo& fiFontInfo, const int dpi, std::optional> features = std::nullopt, std::optional> axes = std::nullopt) noexcept; [[nodiscard]] static HRESULT STDMETHODCALLTYPE s_CalculateBoxEffect(IDWriteTextFormat* format, size_t widthPixels, IDWriteFontFace1* face, float fontScale, IBoxDrawingEffect** effect) noexcept; diff --git a/src/renderer/dx/DxRenderer.cpp b/src/renderer/dx/DxRenderer.cpp index 02bdb6c7a39..148707a13ef 100644 --- a/src/renderer/dx/DxRenderer.cpp +++ b/src/renderer/dx/DxRenderer.cpp @@ -2001,10 +2001,10 @@ void DxEngine::SetFontAxes(const std::unordered_map // - fiFontInfo - Filled with the nearest font actually chosen for drawing // Return Value: // - S_OK or relevant DirectX error -[[nodiscard]] HRESULT DxEngine::UpdateFont(const FontInfoDesired& pfiFontInfoDesired, FontInfo& fiFontInfo) noexcept +[[nodiscard]] HRESULT DxEngine::UpdateFont(const FontInfoDesired& pfiFontInfoDesired, FontInfo& fiFontInfo, std::optional> features, std::optional> axes) noexcept try { - RETURN_IF_FAILED(_fontRenderData->UpdateFont(pfiFontInfoDesired, fiFontInfo, _dpi)); + RETURN_IF_FAILED(_fontRenderData->UpdateFont(pfiFontInfoDesired, fiFontInfo, _dpi, features, axes)); // Prepare the text layout. _customLayout = WRL::Make(_fontRenderData.get()); diff --git a/src/renderer/dx/DxRenderer.hpp b/src/renderer/dx/DxRenderer.hpp index 75319aaf704..ca39f1402e2 100644 --- a/src/renderer/dx/DxRenderer.hpp +++ b/src/renderer/dx/DxRenderer.hpp @@ -111,7 +111,7 @@ namespace Microsoft::Console::Render [[nodiscard]] HRESULT UpdateDrawingBrushes(const TextAttribute& textAttributes, const gsl::not_null pData, const bool isSettingDefaultBrushes) noexcept override; - [[nodiscard]] HRESULT UpdateFont(const FontInfoDesired& fiFontInfoDesired, FontInfo& fiFontInfo) noexcept override; + [[nodiscard]] HRESULT UpdateFont(const FontInfoDesired& fiFontInfoDesired, FontInfo& fiFontInfo, std::optional> features = std::nullopt, std::optional> axes = std::nullopt) noexcept override; [[nodiscard]] HRESULT UpdateDpi(int const iDpi) noexcept override; [[nodiscard]] HRESULT UpdateViewport(const SMALL_RECT srNewViewport) noexcept override; diff --git a/src/renderer/gdi/gdirenderer.hpp b/src/renderer/gdi/gdirenderer.hpp index 230b09c4f6c..dd97b3503d6 100644 --- a/src/renderer/gdi/gdirenderer.hpp +++ b/src/renderer/gdi/gdirenderer.hpp @@ -63,7 +63,9 @@ namespace Microsoft::Console::Render const gsl::not_null pData, const bool isSettingDefaultBrushes) noexcept override; [[nodiscard]] HRESULT UpdateFont(const FontInfoDesired& FontInfoDesired, - _Out_ FontInfo& FontInfo) noexcept override; + _Out_ FontInfo& FontInfo, + std::optional> features = std::nullopt, + std::optional> axes = std::nullopt) noexcept override; [[nodiscard]] HRESULT UpdateDpi(const int iDpi) noexcept override; [[nodiscard]] HRESULT UpdateViewport(const SMALL_RECT srNewViewport) noexcept override; diff --git a/src/renderer/gdi/state.cpp b/src/renderer/gdi/state.cpp index 3311e75858e..2b9c7180a4a 100644 --- a/src/renderer/gdi/state.cpp +++ b/src/renderer/gdi/state.cpp @@ -323,7 +323,7 @@ GdiEngine::~GdiEngine() // - Font - reference to font information where the chosen font information will be populated. // Return Value: // - S_OK if set successfully or relevant GDI error via HRESULT. -[[nodiscard]] HRESULT GdiEngine::UpdateFont(const FontInfoDesired& FontDesired, _Out_ FontInfo& Font) noexcept +[[nodiscard]] HRESULT GdiEngine::UpdateFont(const FontInfoDesired& FontDesired, _Out_ FontInfo& Font, std::optional> /*features*/, std::optional> /*axes*/) noexcept { wil::unique_hfont hFont, hFontItalic; RETURN_IF_FAILED(_GetProposedFont(FontDesired, Font, _iCurrentDpi, hFont, hFontItalic)); diff --git a/src/renderer/inc/IRenderEngine.hpp b/src/renderer/inc/IRenderEngine.hpp index 3d6631e410e..dd8630f175a 100644 --- a/src/renderer/inc/IRenderEngine.hpp +++ b/src/renderer/inc/IRenderEngine.hpp @@ -98,7 +98,9 @@ namespace Microsoft::Console::Render const gsl::not_null pData, const bool isSettingDefaultBrushes) noexcept = 0; [[nodiscard]] virtual HRESULT UpdateFont(const FontInfoDesired& FontInfoDesired, - _Out_ FontInfo& FontInfo) noexcept = 0; + _Out_ FontInfo& FontInfo, + std::optional> features = std::nullopt, + std::optional> axes = std::nullopt) noexcept = 0; [[nodiscard]] virtual HRESULT UpdateDpi(const int iDpi) noexcept = 0; [[nodiscard]] virtual HRESULT UpdateViewport(const SMALL_RECT srNewViewport) noexcept = 0; diff --git a/src/renderer/inc/IRenderer.hpp b/src/renderer/inc/IRenderer.hpp index 79058c5ae5a..e2aef9aaf0a 100644 --- a/src/renderer/inc/IRenderer.hpp +++ b/src/renderer/inc/IRenderer.hpp @@ -48,7 +48,9 @@ namespace Microsoft::Console::Render virtual void TriggerTitleChange() = 0; virtual void TriggerFontChange(const int iDpi, const FontInfoDesired& FontInfoDesired, - _Out_ FontInfo& FontInfo) = 0; + _Out_ FontInfo& FontInfo, + std::optional> features = std::nullopt, + std::optional> axes = std::nullopt) = 0; [[nodiscard]] virtual HRESULT GetProposedFont(const int iDpi, const FontInfoDesired& FontInfoDesired, diff --git a/src/renderer/uia/UiaRenderer.cpp b/src/renderer/uia/UiaRenderer.cpp index ba7ca8e5f64..b9fc7828073 100644 --- a/src/renderer/uia/UiaRenderer.cpp +++ b/src/renderer/uia/UiaRenderer.cpp @@ -381,7 +381,7 @@ CATCH_RETURN(); // - fiFontInfo - // Return Value: // - S_FALSE since we do nothing -[[nodiscard]] HRESULT UiaEngine::UpdateFont(const FontInfoDesired& /*pfiFontInfoDesired*/, FontInfo& /*fiFontInfo*/) noexcept +[[nodiscard]] HRESULT UiaEngine::UpdateFont(const FontInfoDesired& /*pfiFontInfoDesired*/, FontInfo& /*fiFontInfo*/, std::optional> /*features*/, std::optional> /*axes*/) noexcept { return S_FALSE; } diff --git a/src/renderer/uia/UiaRenderer.hpp b/src/renderer/uia/UiaRenderer.hpp index 3ead4673b70..b65abaff4bf 100644 --- a/src/renderer/uia/UiaRenderer.hpp +++ b/src/renderer/uia/UiaRenderer.hpp @@ -63,7 +63,7 @@ namespace Microsoft::Console::Render [[nodiscard]] HRESULT UpdateDrawingBrushes(const TextAttribute& textAttributes, const gsl::not_null pData, const bool isSettingDefaultBrushes) noexcept override; - [[nodiscard]] HRESULT UpdateFont(const FontInfoDesired& fiFontInfoDesired, FontInfo& fiFontInfo) noexcept override; + [[nodiscard]] HRESULT UpdateFont(const FontInfoDesired& fiFontInfoDesired, FontInfo& fiFontInfo, std::optional> features = std::nullopt, std::optional> axes = std::nullopt) noexcept override; [[nodiscard]] HRESULT UpdateDpi(int const iDpi) noexcept override; [[nodiscard]] HRESULT UpdateViewport(const SMALL_RECT srNewViewport) noexcept override; diff --git a/src/renderer/vt/state.cpp b/src/renderer/vt/state.cpp index 5fc18533891..47db2b1b371 100644 --- a/src/renderer/vt/state.cpp +++ b/src/renderer/vt/state.cpp @@ -187,7 +187,9 @@ VtEngine::VtEngine(_In_ wil::unique_hfile pipe, // Return Value: // - HRESULT S_OK [[nodiscard]] HRESULT VtEngine::UpdateFont(const FontInfoDesired& /*pfiFontDesired*/, - _Out_ FontInfo& /*pfiFont*/) noexcept + _Out_ FontInfo& /*pfiFont*/, + std::optional> /*features*/, + std::optional> /*axes*/) noexcept { return S_OK; } diff --git a/src/renderer/vt/vtrenderer.hpp b/src/renderer/vt/vtrenderer.hpp index f7b0a788b66..6ab176ef54f 100644 --- a/src/renderer/vt/vtrenderer.hpp +++ b/src/renderer/vt/vtrenderer.hpp @@ -77,7 +77,9 @@ namespace Microsoft::Console::Render const gsl::not_null pData, const bool isSettingDefaultBrushes) noexcept = 0; [[nodiscard]] HRESULT UpdateFont(const FontInfoDesired& pfiFontInfoDesired, - _Out_ FontInfo& pfiFontInfo) noexcept override; + _Out_ FontInfo& pfiFontInfo, + std::optional> features = std::nullopt, + std::optional> axes = std::nullopt) noexcept override; [[nodiscard]] HRESULT UpdateDpi(const int iDpi) noexcept override; [[nodiscard]] HRESULT UpdateViewport(const SMALL_RECT srNewViewport) noexcept override; From 851af8258844ea8703cf4e1d5932a9714cfe5711 Mon Sep 17 00:00:00 2001 From: Pankaj Bhojwani Date: Fri, 16 Jul 2021 16:08:44 -0700 Subject: [PATCH 40/49] new api for dx --- src/cascadia/TerminalControl/ControlCore.cpp | 65 +++++++++++--------- src/renderer/base/renderer.cpp | 4 +- src/renderer/base/renderer.hpp | 4 +- src/renderer/dx/DxFontRenderData.cpp | 14 ++--- src/renderer/dx/DxFontRenderData.h | 2 +- src/renderer/dx/DxRenderer.cpp | 17 ++++- src/renderer/dx/DxRenderer.hpp | 3 +- src/renderer/gdi/gdirenderer.hpp | 4 +- src/renderer/gdi/state.cpp | 2 +- src/renderer/inc/IRenderEngine.hpp | 4 +- src/renderer/inc/IRenderer.hpp | 4 +- src/renderer/uia/UiaRenderer.cpp | 2 +- src/renderer/uia/UiaRenderer.hpp | 2 +- src/renderer/vt/state.cpp | 4 +- src/renderer/vt/vtrenderer.hpp | 4 +- 15 files changed, 70 insertions(+), 65 deletions(-) diff --git a/src/cascadia/TerminalControl/ControlCore.cpp b/src/cascadia/TerminalControl/ControlCore.cpp index eb2523c7a43..cedff3c808f 100644 --- a/src/cascadia/TerminalControl/ControlCore.cpp +++ b/src/cascadia/TerminalControl/ControlCore.cpp @@ -155,6 +155,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation // Set up the DX Engine auto dxEngine = std::make_unique<::Microsoft::Console::Render::DxEngine>(); _renderer->AddRenderEngine(dxEngine.get()); + _renderEngine = std::move(dxEngine); // Initialize our font with the renderer // We don't have to care about DPI. We'll get a change message immediately if it's not 96 @@ -168,12 +169,12 @@ namespace winrt::Microsoft::Terminal::Control::implementation // Then, using the font, get the number of characters that can fit. // Resize our terminal connection to match that size, and initialize the terminal with that size. const auto viewInPixels = Viewport::FromDimensions({ 0, 0 }, windowSize); - LOG_IF_FAILED(dxEngine->SetWindowSize({ viewInPixels.Width(), viewInPixels.Height() })); + LOG_IF_FAILED(_renderEngine->SetWindowSize({ viewInPixels.Width(), viewInPixels.Height() })); // Update DxEngine's SelectionBackground - dxEngine->SetSelectionBackground(til::color{ _settings.SelectionBackground() }); + _renderEngine->SetSelectionBackground(til::color{ _settings.SelectionBackground() }); - const auto vp = dxEngine->GetViewportInCharacters(viewInPixels); + const auto vp = _renderEngine->GetViewportInCharacters(viewInPixels); const auto width = vp.Width(); const auto height = vp.Height(); _connection.Resize(height, width); @@ -188,27 +189,26 @@ namespace winrt::Microsoft::Terminal::Control::implementation // after Enable, then it'll be possible to paint the frame once // _before_ the warning handler is set up, and then warnings from // the first paint will be ignored! - dxEngine->SetWarningCallback(std::bind(&ControlCore::_rendererWarning, this, std::placeholders::_1)); + _renderEngine->SetWarningCallback(std::bind(&ControlCore::_rendererWarning, this, std::placeholders::_1)); // Tell the DX Engine to notify us when the swap chain changes. // We do this after we initially set the swapchain so as to avoid unnecessary callbacks (and locking problems) - dxEngine->SetCallback(std::bind(&ControlCore::_renderEngineSwapChainChanged, this)); + _renderEngine->SetCallback(std::bind(&ControlCore::_renderEngineSwapChainChanged, this)); - dxEngine->SetRetroTerminalEffect(_settings.RetroTerminalEffect()); - dxEngine->SetPixelShaderPath(_settings.PixelShaderPath()); - dxEngine->SetForceFullRepaintRendering(_settings.ForceFullRepaintRendering()); - dxEngine->SetSoftwareRendering(_settings.SoftwareRendering()); + _renderEngine->SetRetroTerminalEffect(_settings.RetroTerminalEffect()); + _renderEngine->SetPixelShaderPath(_settings.PixelShaderPath()); + _renderEngine->SetForceFullRepaintRendering(_settings.ForceFullRepaintRendering()); + _renderEngine->SetSoftwareRendering(_settings.SoftwareRendering()); - _updateAntiAliasingMode(dxEngine.get()); + _updateAntiAliasingMode(_renderEngine.get()); // GH#5098: Inform the engine of the opacity of the default text background. if (_settings.UseAcrylic()) { - dxEngine->SetDefaultTextBackgroundOpacity(::base::saturated_cast(_settings.TintOpacity())); + _renderEngine->SetDefaultTextBackgroundOpacity(::base::saturated_cast(_settings.TintOpacity())); } - THROW_IF_FAILED(dxEngine->Enable()); - _renderEngine = std::move(dxEngine); + THROW_IF_FAILED(_renderEngine->Enable()); _initializedTerminal = true; } // scope for TerminalLock @@ -595,29 +595,34 @@ namespace winrt::Microsoft::Terminal::Control::implementation _terminal->SetFontInfo(_actualFont); - std::unordered_map featureMap; - if (const auto fontFeatures = _settings.FontFeatures()) + if (_renderEngine) { - featureMap.reserve(fontFeatures.Size()); - - for (const auto& [tag, param] : fontFeatures) + std::unordered_map featureMap; + if (const auto fontFeatures = _settings.FontFeatures()) { - featureMap.emplace(tag, param); - } - } - std::unordered_map axesMap; - if (const auto fontAxes = _settings.FontAxes()) - { - axesMap.reserve(fontAxes.Size()); + featureMap.reserve(fontFeatures.Size()); - for (const auto& [axis, value] : fontAxes) + for (const auto& [tag, param] : fontFeatures) + { + featureMap.emplace(tag, param); + } + } + std::unordered_map axesMap; + if (const auto fontAxes = _settings.FontAxes()) { - axesMap.emplace(axis, value); + axesMap.reserve(fontAxes.Size()); + + for (const auto& [axis, value] : fontAxes) + { + axesMap.emplace(axis, value); + } } + + // TODO: MSFT:20895307 If the font doesn't exist, this doesn't + // actually fail. We need a way to gracefully fallback. + LOG_IF_FAILED(_renderEngine->UpdateDpi(newDpi)); + LOG_IF_FAILED(_renderEngine->UpdateFont(_desiredFont, _actualFont, featureMap, axesMap)); } - // TODO: MSFT:20895307 If the font doesn't exist, this doesn't - // actually fail. We need a way to gracefully fallback. - _renderer->TriggerFontChange(newDpi, _desiredFont, _actualFont, featureMap, axesMap); // If the actual font isn't what was requested... if (_actualFont.GetFaceName() != _desiredFont.GetFaceName()) diff --git a/src/renderer/base/renderer.cpp b/src/renderer/base/renderer.cpp index 09e839a0af8..b53bc6eadf6 100644 --- a/src/renderer/base/renderer.cpp +++ b/src/renderer/base/renderer.cpp @@ -516,11 +516,11 @@ HRESULT Renderer::_PaintTitle(IRenderEngine* const pEngine) // - FontInfo - Data that will be fixed up/filled on return with the chosen font data. // Return Value: // - -void Renderer::TriggerFontChange(const int iDpi, const FontInfoDesired& FontInfoDesired, _Out_ FontInfo& FontInfo, std::optional> features, std::optional> axes) +void Renderer::TriggerFontChange(const int iDpi, const FontInfoDesired& FontInfoDesired, _Out_ FontInfo& FontInfo) { std::for_each(_rgpEngines.begin(), _rgpEngines.end(), [&](IRenderEngine* const pEngine) { LOG_IF_FAILED(pEngine->UpdateDpi(iDpi)); - LOG_IF_FAILED(pEngine->UpdateFont(FontInfoDesired, FontInfo, features, axes)); + LOG_IF_FAILED(pEngine->UpdateFont(FontInfoDesired, FontInfo)); }); _NotifyPaintFrame(); diff --git a/src/renderer/base/renderer.hpp b/src/renderer/base/renderer.hpp index 9f931ed1502..6f8f6d7a8c4 100644 --- a/src/renderer/base/renderer.hpp +++ b/src/renderer/base/renderer.hpp @@ -63,9 +63,7 @@ namespace Microsoft::Console::Render void TriggerFontChange(const int iDpi, const FontInfoDesired& FontInfoDesired, - _Out_ FontInfo& FontInfo, - std::optional> features = std::nullopt, - std::optional> axes = std::nullopt) override; + _Out_ FontInfo& FontInfo) override; [[nodiscard]] HRESULT GetProposedFont(const int iDpi, const FontInfoDesired& FontInfoDesired, diff --git a/src/renderer/dx/DxFontRenderData.cpp b/src/renderer/dx/DxFontRenderData.cpp index b65c7081659..b621383c0c3 100644 --- a/src/renderer/dx/DxFontRenderData.cpp +++ b/src/renderer/dx/DxFontRenderData.cpp @@ -190,7 +190,7 @@ DxFontRenderData::DxFontRenderData(::Microsoft::WRL::ComPtr dwr // - dpi - The DPI of the screen // Return Value: // - S_OK or relevant DirectX error -[[nodiscard]] HRESULT DxFontRenderData::UpdateFont(const FontInfoDesired& desired, FontInfo& actual, const int dpi, std::optional> features, std::optional> axes) noexcept +[[nodiscard]] HRESULT DxFontRenderData::UpdateFont(const FontInfoDesired& desired, FontInfo& actual, const int dpi, std::unordered_map features, std::unordered_map axes) noexcept { try { @@ -204,14 +204,10 @@ DxFontRenderData::DxFontRenderData(::Microsoft::WRL::ComPtr dwr desired.GetWeight(), DWRITE_FONT_STYLE_NORMAL, DWRITE_FONT_STRETCH_NORMAL); - if (features) - { - SetFeatures(features.value()); - } - if (axes) - { - SetAxes(axes.value()); - } + + SetFeatures(features); + SetAxes(axes); + _BuildFontRenderData(desired, actual, dpi); } CATCH_RETURN(); diff --git a/src/renderer/dx/DxFontRenderData.h b/src/renderer/dx/DxFontRenderData.h index 449476ded3a..57c82b4a5f8 100644 --- a/src/renderer/dx/DxFontRenderData.h +++ b/src/renderer/dx/DxFontRenderData.h @@ -84,7 +84,7 @@ namespace Microsoft::Console::Render DWRITE_FONT_STYLE style, DWRITE_FONT_STRETCH stretch); - [[nodiscard]] HRESULT UpdateFont(const FontInfoDesired& desired, FontInfo& fiFontInfo, const int dpi, std::optional> features = std::nullopt, std::optional> axes = std::nullopt) noexcept; + [[nodiscard]] HRESULT UpdateFont(const FontInfoDesired& desired, FontInfo& fiFontInfo, const int dpi, std::unordered_map features = {}, std::unordered_map axes = {}) noexcept; [[nodiscard]] static HRESULT STDMETHODCALLTYPE s_CalculateBoxEffect(IDWriteTextFormat* format, size_t widthPixels, IDWriteFontFace1* face, float fontScale, IBoxDrawingEffect** effect) noexcept; diff --git a/src/renderer/dx/DxRenderer.cpp b/src/renderer/dx/DxRenderer.cpp index 148707a13ef..7a22472d903 100644 --- a/src/renderer/dx/DxRenderer.cpp +++ b/src/renderer/dx/DxRenderer.cpp @@ -1996,12 +1996,27 @@ void DxEngine::SetFontAxes(const std::unordered_map // Routine Description: // - Updates the font used for drawing +// - This is the version that complies with the IRenderEngine interface // Arguments: // - pfiFontInfoDesired - Information specifying the font that is requested // - fiFontInfo - Filled with the nearest font actually chosen for drawing // Return Value: // - S_OK or relevant DirectX error -[[nodiscard]] HRESULT DxEngine::UpdateFont(const FontInfoDesired& pfiFontInfoDesired, FontInfo& fiFontInfo, std::optional> features, std::optional> axes) noexcept +[[nodiscard]] HRESULT DxEngine::UpdateFont(const FontInfoDesired& pfiFontInfoDesired, FontInfo& fiFontInfo) noexcept +{ + return UpdateFont(pfiFontInfoDesired, fiFontInfo, {}, {}); +} + +// Routine Description: +// - Updates the font used for drawing +// Arguments: +// - pfiFontInfoDesired - Information specifying the font that is requested +// - fiFontInfo - Filled with the nearest font actually chosen for drawing +// - features - The map of font features to use +// - axes - The map of font axes to use +// Return Value: +// - S_OK or relevant DirectX error +[[nodiscard]] HRESULT DxEngine::UpdateFont(const FontInfoDesired& pfiFontInfoDesired, FontInfo& fiFontInfo, std::unordered_map features, std::unordered_map axes) noexcept try { RETURN_IF_FAILED(_fontRenderData->UpdateFont(pfiFontInfoDesired, fiFontInfo, _dpi, features, axes)); diff --git a/src/renderer/dx/DxRenderer.hpp b/src/renderer/dx/DxRenderer.hpp index ca39f1402e2..2c7650f3bb5 100644 --- a/src/renderer/dx/DxRenderer.hpp +++ b/src/renderer/dx/DxRenderer.hpp @@ -111,7 +111,8 @@ namespace Microsoft::Console::Render [[nodiscard]] HRESULT UpdateDrawingBrushes(const TextAttribute& textAttributes, const gsl::not_null pData, const bool isSettingDefaultBrushes) noexcept override; - [[nodiscard]] HRESULT UpdateFont(const FontInfoDesired& fiFontInfoDesired, FontInfo& fiFontInfo, std::optional> features = std::nullopt, std::optional> axes = std::nullopt) noexcept override; + [[nodiscard]] HRESULT UpdateFont(const FontInfoDesired& fiFontInfoDesired, FontInfo& fiFontInfo) noexcept override; + [[nodiscard]] HRESULT UpdateFont(const FontInfoDesired& fiFontInfoDesired, FontInfo& fiFontInfo, std::unordered_map features, std::unordered_map axes) noexcept; [[nodiscard]] HRESULT UpdateDpi(int const iDpi) noexcept override; [[nodiscard]] HRESULT UpdateViewport(const SMALL_RECT srNewViewport) noexcept override; diff --git a/src/renderer/gdi/gdirenderer.hpp b/src/renderer/gdi/gdirenderer.hpp index dd97b3503d6..230b09c4f6c 100644 --- a/src/renderer/gdi/gdirenderer.hpp +++ b/src/renderer/gdi/gdirenderer.hpp @@ -63,9 +63,7 @@ namespace Microsoft::Console::Render const gsl::not_null pData, const bool isSettingDefaultBrushes) noexcept override; [[nodiscard]] HRESULT UpdateFont(const FontInfoDesired& FontInfoDesired, - _Out_ FontInfo& FontInfo, - std::optional> features = std::nullopt, - std::optional> axes = std::nullopt) noexcept override; + _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/gdi/state.cpp b/src/renderer/gdi/state.cpp index 2b9c7180a4a..3311e75858e 100644 --- a/src/renderer/gdi/state.cpp +++ b/src/renderer/gdi/state.cpp @@ -323,7 +323,7 @@ GdiEngine::~GdiEngine() // - Font - reference to font information where the chosen font information will be populated. // Return Value: // - S_OK if set successfully or relevant GDI error via HRESULT. -[[nodiscard]] HRESULT GdiEngine::UpdateFont(const FontInfoDesired& FontDesired, _Out_ FontInfo& Font, std::optional> /*features*/, std::optional> /*axes*/) noexcept +[[nodiscard]] HRESULT GdiEngine::UpdateFont(const FontInfoDesired& FontDesired, _Out_ FontInfo& Font) noexcept { wil::unique_hfont hFont, hFontItalic; RETURN_IF_FAILED(_GetProposedFont(FontDesired, Font, _iCurrentDpi, hFont, hFontItalic)); diff --git a/src/renderer/inc/IRenderEngine.hpp b/src/renderer/inc/IRenderEngine.hpp index dd8630f175a..3d6631e410e 100644 --- a/src/renderer/inc/IRenderEngine.hpp +++ b/src/renderer/inc/IRenderEngine.hpp @@ -98,9 +98,7 @@ namespace Microsoft::Console::Render const gsl::not_null pData, const bool isSettingDefaultBrushes) noexcept = 0; [[nodiscard]] virtual HRESULT UpdateFont(const FontInfoDesired& FontInfoDesired, - _Out_ FontInfo& FontInfo, - std::optional> features = std::nullopt, - std::optional> axes = std::nullopt) noexcept = 0; + _Out_ FontInfo& FontInfo) noexcept = 0; [[nodiscard]] virtual HRESULT UpdateDpi(const int iDpi) noexcept = 0; [[nodiscard]] virtual HRESULT UpdateViewport(const SMALL_RECT srNewViewport) noexcept = 0; diff --git a/src/renderer/inc/IRenderer.hpp b/src/renderer/inc/IRenderer.hpp index e2aef9aaf0a..79058c5ae5a 100644 --- a/src/renderer/inc/IRenderer.hpp +++ b/src/renderer/inc/IRenderer.hpp @@ -48,9 +48,7 @@ namespace Microsoft::Console::Render virtual void TriggerTitleChange() = 0; virtual void TriggerFontChange(const int iDpi, const FontInfoDesired& FontInfoDesired, - _Out_ FontInfo& FontInfo, - std::optional> features = std::nullopt, - std::optional> axes = std::nullopt) = 0; + _Out_ FontInfo& FontInfo) = 0; [[nodiscard]] virtual HRESULT GetProposedFont(const int iDpi, const FontInfoDesired& FontInfoDesired, diff --git a/src/renderer/uia/UiaRenderer.cpp b/src/renderer/uia/UiaRenderer.cpp index b9fc7828073..ba7ca8e5f64 100644 --- a/src/renderer/uia/UiaRenderer.cpp +++ b/src/renderer/uia/UiaRenderer.cpp @@ -381,7 +381,7 @@ CATCH_RETURN(); // - fiFontInfo - // Return Value: // - S_FALSE since we do nothing -[[nodiscard]] HRESULT UiaEngine::UpdateFont(const FontInfoDesired& /*pfiFontInfoDesired*/, FontInfo& /*fiFontInfo*/, std::optional> /*features*/, std::optional> /*axes*/) noexcept +[[nodiscard]] HRESULT UiaEngine::UpdateFont(const FontInfoDesired& /*pfiFontInfoDesired*/, FontInfo& /*fiFontInfo*/) noexcept { return S_FALSE; } diff --git a/src/renderer/uia/UiaRenderer.hpp b/src/renderer/uia/UiaRenderer.hpp index b65abaff4bf..3ead4673b70 100644 --- a/src/renderer/uia/UiaRenderer.hpp +++ b/src/renderer/uia/UiaRenderer.hpp @@ -63,7 +63,7 @@ namespace Microsoft::Console::Render [[nodiscard]] HRESULT UpdateDrawingBrushes(const TextAttribute& textAttributes, const gsl::not_null pData, const bool isSettingDefaultBrushes) noexcept override; - [[nodiscard]] HRESULT UpdateFont(const FontInfoDesired& fiFontInfoDesired, FontInfo& fiFontInfo, std::optional> features = std::nullopt, std::optional> axes = std::nullopt) noexcept override; + [[nodiscard]] HRESULT UpdateFont(const FontInfoDesired& fiFontInfoDesired, FontInfo& fiFontInfo) noexcept override; [[nodiscard]] HRESULT UpdateDpi(int const iDpi) noexcept override; [[nodiscard]] HRESULT UpdateViewport(const SMALL_RECT srNewViewport) noexcept override; diff --git a/src/renderer/vt/state.cpp b/src/renderer/vt/state.cpp index 47db2b1b371..5fc18533891 100644 --- a/src/renderer/vt/state.cpp +++ b/src/renderer/vt/state.cpp @@ -187,9 +187,7 @@ VtEngine::VtEngine(_In_ wil::unique_hfile pipe, // Return Value: // - HRESULT S_OK [[nodiscard]] HRESULT VtEngine::UpdateFont(const FontInfoDesired& /*pfiFontDesired*/, - _Out_ FontInfo& /*pfiFont*/, - std::optional> /*features*/, - std::optional> /*axes*/) noexcept + _Out_ FontInfo& /*pfiFont*/) noexcept { return S_OK; } diff --git a/src/renderer/vt/vtrenderer.hpp b/src/renderer/vt/vtrenderer.hpp index 6ab176ef54f..f7b0a788b66 100644 --- a/src/renderer/vt/vtrenderer.hpp +++ b/src/renderer/vt/vtrenderer.hpp @@ -77,9 +77,7 @@ namespace Microsoft::Console::Render const gsl::not_null pData, const bool isSettingDefaultBrushes) noexcept = 0; [[nodiscard]] HRESULT UpdateFont(const FontInfoDesired& pfiFontInfoDesired, - _Out_ FontInfo& pfiFontInfo, - std::optional> features = std::nullopt, - std::optional> axes = std::nullopt) noexcept override; + _Out_ FontInfo& pfiFontInfo) noexcept override; [[nodiscard]] HRESULT UpdateDpi(const int iDpi) noexcept override; [[nodiscard]] HRESULT UpdateViewport(const SMALL_RECT srNewViewport) noexcept override; From 17637d841e8e98f563bff27bf7b6b8345003744f Mon Sep 17 00:00:00 2001 From: Pankaj Bhojwani Date: Fri, 16 Jul 2021 16:24:50 -0700 Subject: [PATCH 41/49] nits --- src/cascadia/TerminalControl/ControlCore.cpp | 1 - src/renderer/dx/DxFontRenderData.cpp | 34 +++++++++++--------- src/renderer/dx/DxFontRenderData.h | 12 +++---- 3 files changed, 25 insertions(+), 22 deletions(-) diff --git a/src/cascadia/TerminalControl/ControlCore.cpp b/src/cascadia/TerminalControl/ControlCore.cpp index cedff3c808f..87b82ff6f6c 100644 --- a/src/cascadia/TerminalControl/ControlCore.cpp +++ b/src/cascadia/TerminalControl/ControlCore.cpp @@ -505,7 +505,6 @@ namespace winrt::Microsoft::Terminal::Control::implementation const auto fontFace = _settings.FontFace(); const short fontHeight = ::base::saturated_cast(_settings.FontSize()); const auto fontWeight = _settings.FontWeight(); - // The font width doesn't terribly matter, we'll only be using the // height to look it up // The other params here also largely don't matter. diff --git a/src/renderer/dx/DxFontRenderData.cpp b/src/renderer/dx/DxFontRenderData.cpp index b621383c0c3..4e893575e44 100644 --- a/src/renderer/dx/DxFontRenderData.cpp +++ b/src/renderer/dx/DxFontRenderData.cpp @@ -465,7 +465,7 @@ bool DxFontRenderData::DidUserSetFeatures() const noexcept // Routine Description: // - Updates our internal map of font features with the given features -// - NOTE TO CALLER: Make sure to call UpdateFont after calling this for the feature changes +// - NOTE TO CALLER: Make sure to call _BuildFontRenderData after calling this for the feature changes // to take place // Arguments: // - features - the features to update our map with @@ -498,6 +498,10 @@ void DxFontRenderData::SetFeatures(const std::unordered_map(value) }); + _axesVector.emplace_back(DWRITE_FONT_AXIS_VALUE{ dwriteTag, gsl::narrow_cast(value) }); } } } @@ -604,46 +608,46 @@ std::vector DxFontRenderData::GetAxisVector(const DWRITE axesVector.resize(axesCount); format->GetFontAxisValues(axesVector.data(), axesCount); - auto axisTagPresence = AxisTagPresence::AxisTagPresenceNone; + auto axisTagPresence = AxisTagPresence::None; for (const auto& fontAxisValue : axesVector) { switch (fontAxisValue.axisTag) { case DWRITE_FONT_AXIS_TAG_WEIGHT: - WI_SetFlag(axisTagPresence, AxisTagPresence::AxisTagPresenceWeight); + WI_SetFlag(axisTagPresence, AxisTagPresence::Weight); break; case DWRITE_FONT_AXIS_TAG_WIDTH: - WI_SetFlag(axisTagPresence, AxisTagPresence::AxisTagPresenceWidth); + WI_SetFlag(axisTagPresence, AxisTagPresence::Width); break; case DWRITE_FONT_AXIS_TAG_ITALIC: - WI_SetFlag(axisTagPresence, AxisTagPresence::AxisTagPresenceItalic); + WI_SetFlag(axisTagPresence, AxisTagPresence::Italic); break; case DWRITE_FONT_AXIS_TAG_SLANT: - WI_SetFlag(axisTagPresence, AxisTagPresence::AxisTagPresenceSlant); + WI_SetFlag(axisTagPresence, AxisTagPresence::Slant); break; case DWRITE_FONT_AXIS_TAG_OPTICAL_SIZE: - WI_SetFlag(axisTagPresence, AxisTagPresence::AxisTagPresenceOpticalSize); + WI_SetFlag(axisTagPresence, AxisTagPresence::OpticalSize); break; } } - if (WI_IsFlagClear(axisTagPresence, AxisTagPresence::AxisTagPresenceWeight)) + if (WI_IsFlagClear(axisTagPresence, AxisTagPresence::Weight)) { axesVector.emplace_back(DWRITE_FONT_AXIS_VALUE{ DWRITE_FONT_AXIS_TAG_WEIGHT, gsl::narrow(fontWeight) }); } - if (WI_IsFlagClear(axisTagPresence, AxisTagPresence::AxisTagPresenceWidth)) + if (WI_IsFlagClear(axisTagPresence, AxisTagPresence::Width)) { axesVector.emplace_back(DWRITE_FONT_AXIS_VALUE{ DWRITE_FONT_AXIS_TAG_WIDTH, FontStretchToWidthAxisValue(fontStretch) }); } - if (WI_IsFlagClear(axisTagPresence, AxisTagPresence::AxisTagPresenceItalic)) + if (WI_IsFlagClear(axisTagPresence, AxisTagPresence::Italic)) { axesVector.emplace_back(DWRITE_FONT_AXIS_VALUE{ DWRITE_FONT_AXIS_TAG_ITALIC, (fontStyle == DWRITE_FONT_STYLE_ITALIC ? 1.0f : 0.0f) }); } - if (WI_IsFlagClear(axisTagPresence, AxisTagPresence::AxisTagPresenceSlant)) + if (WI_IsFlagClear(axisTagPresence, AxisTagPresence::Slant)) { axesVector.emplace_back(DWRITE_FONT_AXIS_VALUE{ DWRITE_FONT_AXIS_TAG_SLANT, FontStyleToSlantFixedAxisValue(fontStyle) }); } - if (WI_IsFlagClear(axisTagPresence, AxisTagPresence::AxisTagPresenceOpticalSize)) + if (WI_IsFlagClear(axisTagPresence, AxisTagPresence::OpticalSize)) { axesVector.emplace_back(DWRITE_FONT_AXIS_VALUE{ DWRITE_FONT_AXIS_TAG_OPTICAL_SIZE, DIPsToPoints(fontSize) }); } diff --git a/src/renderer/dx/DxFontRenderData.h b/src/renderer/dx/DxFontRenderData.h index 57c82b4a5f8..361c8e6713f 100644 --- a/src/renderer/dx/DxFontRenderData.h +++ b/src/renderer/dx/DxFontRenderData.h @@ -18,12 +18,12 @@ namespace Microsoft::Console::Render { enum class AxisTagPresence : BYTE { - AxisTagPresenceNone = 0x00, - AxisTagPresenceWeight = 0x01, - AxisTagPresenceWidth = 0x02, - AxisTagPresenceItalic = 0x04, - AxisTagPresenceSlant = 0x08, - AxisTagPresenceOpticalSize = 0x10, + None = 0x00, + Weight = 0x01, + Width = 0x02, + Italic = 0x04, + Slant = 0x08, + OpticalSize = 0x10, }; DEFINE_ENUM_FLAG_OPERATORS(AxisTagPresence); From 97ccdd8ad5707d51bf557848e05898d35174cf87 Mon Sep 17 00:00:00 2001 From: Pankaj Bhojwani Date: Fri, 16 Jul 2021 16:32:20 -0700 Subject: [PATCH 42/49] json utils --- .../TerminalSettingsModel/JsonUtils.h | 20 +++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/src/cascadia/TerminalSettingsModel/JsonUtils.h b/src/cascadia/TerminalSettingsModel/JsonUtils.h index f5846c78534..fa8dbcb499b 100644 --- a/src/cascadia/TerminalSettingsModel/JsonUtils.h +++ b/src/cascadia/TerminalSettingsModel/JsonUtils.h @@ -183,10 +183,12 @@ namespace Microsoft::Terminal::Settings::Model::JsonUtils std::unordered_map FromJson(const Json::Value& json) const { std::unordered_map val; + val.reserve(json.size()); - for (const auto& element : json.getMemberNames()) + ConversionTrait trait; + for (auto it = json.begin(), end = json.end(); it != end; ++it) { - GetValueForKey(json, element, val[element.c_str()]); + GetValue(*it, val[it.name()], trait); } return val; @@ -199,9 +201,9 @@ namespace Microsoft::Terminal::Settings::Model::JsonUtils return false; } ConversionTrait trait; - for (const auto& element : json.getMemberNames()) + for (const auto& v : json) { - if (!trait.CanConvert(json[JsonKey(element)])) + if (!trait.CanConvert(v)) { return false; } @@ -263,10 +265,12 @@ namespace Microsoft::Terminal::Settings::Model::JsonUtils winrt::Windows::Foundation::Collections::IMap FromJson(const Json::Value& json) const { std::unordered_map val; + val.reserve(json.size()); - for (const auto& element : json.getMemberNames()) + ConversionTrait trait; + for (auto it = json.begin(), end = json.end(); it != end; ++it) { - GetValueForKey(json, element, val[winrt::to_hstring(element)]); + GetValue(*it, val[winrt::to_hstring(it.name())], trait); } return winrt::single_threaded_map(std::move(val)); @@ -279,9 +283,9 @@ namespace Microsoft::Terminal::Settings::Model::JsonUtils return false; } ConversionTrait trait; - for (const auto& element : json.getMemberNames()) + for (const auto& v : json) { - if (!trait.CanConvert(json[JsonKey(element)])) + if (!trait.CanConvert(v)) { return false; } From 104af53b76cb7fff532de0b6adbd2fd28a9837e8 Mon Sep 17 00:00:00 2001 From: Pankaj Bhojwani Date: Fri, 16 Jul 2021 16:46:35 -0700 Subject: [PATCH 43/49] private helpers --- src/renderer/dx/DxFontRenderData.cpp | 8 ++++---- src/renderer/dx/DxFontRenderData.h | 4 ++-- src/renderer/dx/DxRenderer.cpp | 18 ------------------ src/renderer/dx/DxRenderer.hpp | 3 --- 4 files changed, 6 insertions(+), 27 deletions(-) diff --git a/src/renderer/dx/DxFontRenderData.cpp b/src/renderer/dx/DxFontRenderData.cpp index 4e893575e44..04584f4acf7 100644 --- a/src/renderer/dx/DxFontRenderData.cpp +++ b/src/renderer/dx/DxFontRenderData.cpp @@ -205,8 +205,8 @@ DxFontRenderData::DxFontRenderData(::Microsoft::WRL::ComPtr dwr DWRITE_FONT_STYLE_NORMAL, DWRITE_FONT_STRETCH_NORMAL); - SetFeatures(features); - SetAxes(axes); + _SetFeatures(features); + _SetAxes(axes); _BuildFontRenderData(desired, actual, dpi); } @@ -469,7 +469,7 @@ bool DxFontRenderData::DidUserSetFeatures() const noexcept // to take place // Arguments: // - features - the features to update our map with -void DxFontRenderData::SetFeatures(const std::unordered_map& features) +void DxFontRenderData::_SetFeatures(const std::unordered_map& features) { // Populate the feature map with the standard list first std::unordered_map featureMap{ @@ -517,7 +517,7 @@ void DxFontRenderData::SetFeatures(const std::unordered_map& axes) +void DxFontRenderData::_SetAxes(const std::unordered_map& axes) { _axesVector.clear(); diff --git a/src/renderer/dx/DxFontRenderData.h b/src/renderer/dx/DxFontRenderData.h index 361c8e6713f..685e039b97c 100644 --- a/src/renderer/dx/DxFontRenderData.h +++ b/src/renderer/dx/DxFontRenderData.h @@ -89,8 +89,6 @@ namespace Microsoft::Console::Render [[nodiscard]] static HRESULT STDMETHODCALLTYPE s_CalculateBoxEffect(IDWriteTextFormat* format, size_t widthPixels, IDWriteFontFace1* face, float fontScale, IBoxDrawingEffect** effect) noexcept; bool DidUserSetFeatures() const noexcept; - void SetFeatures(const std::unordered_map& features); - void SetAxes(const std::unordered_map& axes); float FontStretchToWidthAxisValue(DWRITE_FONT_STRETCH fontStretch) noexcept; float FontStyleToSlantFixedAxisValue(DWRITE_FONT_STYLE fontStyle) noexcept; @@ -117,6 +115,8 @@ namespace Microsoft::Console::Render return (weight << 16) | (style << 8) | stretch; }; + void _SetFeatures(const std::unordered_map& features); + void _SetAxes(const std::unordered_map& axes); void _BuildFontRenderData(const FontInfoDesired& desired, FontInfo& actual, const int dpi); Microsoft::WRL::ComPtr _BuildTextFormat(const DxFontInfo fontInfo, const std::wstring_view localeName); diff --git a/src/renderer/dx/DxRenderer.cpp b/src/renderer/dx/DxRenderer.cpp index 7a22472d903..958f20d73f5 100644 --- a/src/renderer/dx/DxRenderer.cpp +++ b/src/renderer/dx/DxRenderer.cpp @@ -1976,24 +1976,6 @@ CATCH_RETURN() return S_OK; } -// Routine Description: -// - Updates the font render data's internal map of font features with the given features -// Arguments: -// - features - the features to update the map with -void DxEngine::SetFontFeatures(const std::unordered_map features) -{ - _fontRenderData->SetFeatures(features); -} - -// Routine Description: -// - Updates the font render data's internal map of font axes with the given axes -// Arguments: -// - axes - the axes to update the map with -void DxEngine::SetFontAxes(const std::unordered_map axes) -{ - _fontRenderData->SetAxes(axes); -} - // Routine Description: // - Updates the font used for drawing // - This is the version that complies with the IRenderEngine interface diff --git a/src/renderer/dx/DxRenderer.hpp b/src/renderer/dx/DxRenderer.hpp index 2c7650f3bb5..33ad3a314e7 100644 --- a/src/renderer/dx/DxRenderer.hpp +++ b/src/renderer/dx/DxRenderer.hpp @@ -72,9 +72,6 @@ namespace Microsoft::Console::Render HANDLE GetSwapChainHandle(); - void SetFontFeatures(const std::unordered_map features); - void SetFontAxes(const std::unordered_map axes); - // IRenderEngine Members [[nodiscard]] HRESULT Invalidate(const SMALL_RECT* const psrRegion) noexcept override; [[nodiscard]] HRESULT InvalidateCursor(const SMALL_RECT* const psrRegion) noexcept override; From e0a6a6c3b9ae5c63cae3bef031901d367cc7d9d3 Mon Sep 17 00:00:00 2001 From: Pankaj Bhojwani Date: Fri, 16 Jul 2021 16:49:45 -0700 Subject: [PATCH 44/49] format --- src/renderer/dx/DxFontRenderData.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/renderer/dx/DxFontRenderData.cpp b/src/renderer/dx/DxFontRenderData.cpp index 04584f4acf7..b1da84354dd 100644 --- a/src/renderer/dx/DxFontRenderData.cpp +++ b/src/renderer/dx/DxFontRenderData.cpp @@ -483,7 +483,7 @@ void DxFontRenderData::_SetFeatures(const std::unordered_map DxFontRenderData::GetAxisVector(const DWRITE const float fontSize, IDWriteTextFormat3* format) { -#pragma warning(suppress : 26429) // the analyzer doesn't detect that our FAIL_FAST_IF_NULL macro - // checks format for nullness +#pragma warning(suppress : 26429) // the analyzer doesn't detect that our FAIL_FAST_IF_NULL macro \ + // checks format for nullness FAIL_FAST_IF_NULL(format); const auto axesCount = format->GetFontAxisValueCount(); From 9ebaaeb72735c62ab033fcededa3c1054fa057b2 Mon Sep 17 00:00:00 2001 From: Pankaj Bhojwani Date: Mon, 19 Jul 2021 09:32:44 -0700 Subject: [PATCH 45/49] analyzer complaints --- src/renderer/dx/DxFontRenderData.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/renderer/dx/DxFontRenderData.cpp b/src/renderer/dx/DxFontRenderData.cpp index b1da84354dd..9056b4285b2 100644 --- a/src/renderer/dx/DxFontRenderData.cpp +++ b/src/renderer/dx/DxFontRenderData.cpp @@ -522,6 +522,7 @@ void DxFontRenderData::_SetAxes(const std::unordered_map DxFontRenderData::GetAxisVector(const DWRITE_FONT_WEIGHT fontWeight, const DWRITE_FONT_STRETCH fontStretch, const DWRITE_FONT_STYLE fontStyle, const float fontSize, IDWriteTextFormat3* format) { -#pragma warning(suppress : 26429) // the analyzer doesn't detect that our FAIL_FAST_IF_NULL macro \ - // checks format for nullness FAIL_FAST_IF_NULL(format); const auto axesCount = format->GetFontAxisValueCount(); From 32a2e550c6f8830ebf37a287e4065e1d1a890bb2 Mon Sep 17 00:00:00 2001 From: Pankaj Bhojwani Date: Mon, 19 Jul 2021 09:40:20 -0700 Subject: [PATCH 46/49] format --- src/renderer/dx/DxFontRenderData.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/renderer/dx/DxFontRenderData.cpp b/src/renderer/dx/DxFontRenderData.cpp index 9056b4285b2..4d83f33b2f9 100644 --- a/src/renderer/dx/DxFontRenderData.cpp +++ b/src/renderer/dx/DxFontRenderData.cpp @@ -594,8 +594,8 @@ float DxFontRenderData::DIPsToPoints(const float fontSize) noexcept // - format: the IDWriteTextFormat3 to get the defined axes from // Return value: // - The fully formed axes vector -#pragma warning(suppress : 26429) // the analyzer doesn't detect that our FAIL_FAST_IF_NULL macro - // checks format for nullness +#pragma warning(suppress : 26429) // the analyzer doesn't detect that our FAIL_FAST_IF_NULL macro \ + // checks format for nullness std::vector DxFontRenderData::GetAxisVector(const DWRITE_FONT_WEIGHT fontWeight, const DWRITE_FONT_STRETCH fontStretch, const DWRITE_FONT_STYLE fontStyle, From 753c00c06143423b0a33ba6f9efb8b2f14c4e69f Mon Sep 17 00:00:00 2001 From: Pankaj Bhojwani Date: Tue, 20 Jul 2021 10:22:57 -0700 Subject: [PATCH 47/49] fixes --- src/cascadia/TerminalControl/ControlCore.cpp | 2 +- .../TerminalControl/IControlSettings.idl | 2 +- .../TerminalSettingsModel/FontConfig.h | 2 +- .../TerminalSettingsModel/FontConfig.idl | 2 +- .../TerminalSettingsModel/TerminalSettings.h | 2 +- .../UnitTests_Control/MockControlSettings.h | 2 +- src/renderer/dx/DxFontRenderData.cpp | 33 +++++++------------ src/renderer/dx/DxFontRenderData.h | 5 ++- src/renderer/dx/DxRenderer.cpp | 2 +- src/renderer/dx/DxRenderer.hpp | 2 +- 10 files changed, 22 insertions(+), 32 deletions(-) diff --git a/src/cascadia/TerminalControl/ControlCore.cpp b/src/cascadia/TerminalControl/ControlCore.cpp index 87b82ff6f6c..2afcdf642f4 100644 --- a/src/cascadia/TerminalControl/ControlCore.cpp +++ b/src/cascadia/TerminalControl/ControlCore.cpp @@ -606,7 +606,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation featureMap.emplace(tag, param); } } - std::unordered_map axesMap; + std::unordered_map axesMap; if (const auto fontAxes = _settings.FontAxes()) { axesMap.reserve(fontAxes.Size()); diff --git a/src/cascadia/TerminalControl/IControlSettings.idl b/src/cascadia/TerminalControl/IControlSettings.idl index fd0a4d2a7aa..56aab7395cc 100644 --- a/src/cascadia/TerminalControl/IControlSettings.idl +++ b/src/cascadia/TerminalControl/IControlSettings.idl @@ -37,7 +37,7 @@ namespace Microsoft.Terminal.Control Windows.UI.Text.FontWeight FontWeight; String Padding; Windows.Foundation.Collections.IMap FontFeatures; - Windows.Foundation.Collections.IMap FontAxes; + Windows.Foundation.Collections.IMap FontAxes; Microsoft.Terminal.Control.IKeyBindings KeyBindings; diff --git a/src/cascadia/TerminalSettingsModel/FontConfig.h b/src/cascadia/TerminalSettingsModel/FontConfig.h index 29d51e684cb..61f816dba87 100644 --- a/src/cascadia/TerminalSettingsModel/FontConfig.h +++ b/src/cascadia/TerminalSettingsModel/FontConfig.h @@ -23,7 +23,7 @@ Author(s): #include "IInheritable.h" #include -using IFontAxesMap = winrt::Windows::Foundation::Collections::IMap; +using IFontAxesMap = winrt::Windows::Foundation::Collections::IMap; using IFontFeatureMap = winrt::Windows::Foundation::Collections::IMap; namespace winrt::Microsoft::Terminal::Settings::Model::implementation diff --git a/src/cascadia/TerminalSettingsModel/FontConfig.idl b/src/cascadia/TerminalSettingsModel/FontConfig.idl index c4b95b5b665..37d2aeb8050 100644 --- a/src/cascadia/TerminalSettingsModel/FontConfig.idl +++ b/src/cascadia/TerminalSettingsModel/FontConfig.idl @@ -20,6 +20,6 @@ namespace Microsoft.Terminal.Settings.Model INHERITABLE_FONT_SETTING(Windows.UI.Text.FontWeight, FontWeight); INHERITABLE_FONT_SETTING(Windows.Foundation.Collections.IMap, FontFeatures); - INHERITABLE_FONT_SETTING(Windows.Foundation.Collections.IMap, FontAxes); + INHERITABLE_FONT_SETTING(Windows.Foundation.Collections.IMap, FontAxes); } } diff --git a/src/cascadia/TerminalSettingsModel/TerminalSettings.h b/src/cascadia/TerminalSettingsModel/TerminalSettings.h index 54fbac542b2..66e80558910 100644 --- a/src/cascadia/TerminalSettingsModel/TerminalSettings.h +++ b/src/cascadia/TerminalSettingsModel/TerminalSettings.h @@ -21,7 +21,7 @@ Author(s): #include #include -using IFontAxesMap = winrt::Windows::Foundation::Collections::IMap; +using IFontAxesMap = winrt::Windows::Foundation::Collections::IMap; using IFontFeatureMap = winrt::Windows::Foundation::Collections::IMap; // fwdecl unittest classes diff --git a/src/cascadia/UnitTests_Control/MockControlSettings.h b/src/cascadia/UnitTests_Control/MockControlSettings.h index 84ffb16daf0..94b8f2a9984 100644 --- a/src/cascadia/UnitTests_Control/MockControlSettings.h +++ b/src/cascadia/UnitTests_Control/MockControlSettings.h @@ -9,7 +9,7 @@ Licensed under the MIT license. #include using IFontFeatureMap = winrt::Windows::Foundation::Collections::IMap; -using IFontAxesMap = winrt::Windows::Foundation::Collections::IMap; +using IFontAxesMap = winrt::Windows::Foundation::Collections::IMap; namespace ControlUnitTests { diff --git a/src/renderer/dx/DxFontRenderData.cpp b/src/renderer/dx/DxFontRenderData.cpp index 4d83f33b2f9..1baed719083 100644 --- a/src/renderer/dx/DxFontRenderData.cpp +++ b/src/renderer/dx/DxFontRenderData.cpp @@ -13,12 +13,7 @@ static constexpr float POINTS_PER_INCH = 72.0f; static constexpr std::wstring_view FALLBACK_FONT_FACES[] = { L"Consolas", L"Lucida Console", L"Courier New" }; static constexpr std::wstring_view FALLBACK_LOCALE = L"en-us"; static constexpr size_t TAG_LENGTH = 4; - -// 10 elements from DWRITE_FONT_STRETCH_UNDEFINED (0) to DWRITE_FONT_STRETCH_ULTRA_EXPANDED (9) -static constexpr auto fontStretchEnumToVal = std::array{ 100.0f, 50.0f, 62.5f, 75.0f, 87.5f, 100.0f, 112.5f, 125.0f, 150.0f, 200.0f }; - -// DWRITE_FONT_STYLE_NORMAL (0), DWRITE_FONT_STYLE_OBLIQUE (1), DWRITE_FONT_STYLE_ITALIC (2) -static constexpr auto fontStyleEnumToVal = std::array{ 0.0f, -20.0f, -12.0f }; +static constexpr auto DIPsToPoints = [](const float fontSize) { return fontSize * (72.0f / 96.0f); }; using namespace Microsoft::Console::Render; @@ -190,7 +185,7 @@ DxFontRenderData::DxFontRenderData(::Microsoft::WRL::ComPtr dwr // - dpi - The DPI of the screen // Return Value: // - S_OK or relevant DirectX error -[[nodiscard]] HRESULT DxFontRenderData::UpdateFont(const FontInfoDesired& desired, FontInfo& actual, const int dpi, std::unordered_map features, std::unordered_map axes) noexcept +[[nodiscard]] HRESULT DxFontRenderData::UpdateFont(const FontInfoDesired& desired, FontInfo& actual, const int dpi, const std::unordered_map& features, const std::unordered_map& axes) noexcept { try { @@ -517,7 +512,7 @@ void DxFontRenderData::_SetFeatures(const std::unordered_map& axes) +void DxFontRenderData::_SetAxes(const std::unordered_map& axes) { _axesVector.clear(); @@ -528,7 +523,7 @@ void DxFontRenderData::_SetAxes(const std::unordered_map(value) }); + _axesVector.emplace_back(DWRITE_FONT_AXIS_VALUE{ dwriteTag, value }); } } } @@ -542,6 +537,9 @@ void DxFontRenderData::_SetAxes(const std::unordered_map(fontStretch) > fontStretchEnumToVal.size()) { fontStretch = DWRITE_FONT_STRETCH_NORMAL; @@ -559,6 +557,9 @@ float DxFontRenderData::FontStretchToWidthAxisValue(DWRITE_FONT_STRETCH fontStre // - The float value corresponding to the passed in fontStyle float DxFontRenderData::FontStyleToSlantFixedAxisValue(DWRITE_FONT_STYLE fontStyle) noexcept { + // DWRITE_FONT_STYLE_NORMAL (0), DWRITE_FONT_STYLE_OBLIQUE (1), DWRITE_FONT_STYLE_ITALIC (2) + static constexpr auto fontStyleEnumToVal = std::array{ 0.0f, -20.0f, -12.0f }; + // Both DWRITE_FONT_STYLE_OBLIQUE and DWRITE_FONT_STYLE_ITALIC default to having slant. // Though an italic font technically need not have slant (there exist upright ones), the // vast majority of italic fonts are also slanted. Ideally the slant comes from the @@ -572,20 +573,10 @@ float DxFontRenderData::FontStyleToSlantFixedAxisValue(DWRITE_FONT_STYLE fontSty return til::at(fontStyleEnumToVal, fontStyle); } -// Method Description: -// - Converts a float fontSize into the corresponding float value to create a DWRITE_FONT_AXIS_VALUE with -// Arguments: -// - fontSize: the old float value to be converted into an axis value -// Return value: -// - The float value corresponding to the passed in fontSize -float DxFontRenderData::DIPsToPoints(const float fontSize) noexcept -{ - return fontSize * (72.0f / 96.0f); -} - // Method Description: // - Fill any missing axis values that might be known but were unspecified, such as omitting // the 'wght' axis tag but specifying the old DWRITE_FONT_WEIGHT enum +// - Note to caller: make sure to only call this with a valid IDWriteTextFormat3! // Arguments: // - fontWeight: the old DWRITE_FONT_WEIGHT enum to be converted into an axis value // - fontStretch: the old DWRITE_FONT_STRETCH enum to be converted into an axis value @@ -867,7 +858,7 @@ Microsoft::WRL::ComPtr DxFontRenderData::_BuildTextFormat(con // If the OS supports IDWriteTextFormat3, set the font axes ::Microsoft::WRL::ComPtr format3; - if (!FAILED(format->QueryInterface(IID_PPV_ARGS(&format3))) && !_axesVector.empty()) + if (!_axesVector.empty() && !FAILED(format->QueryInterface(IID_PPV_ARGS(&format3)))) { DWRITE_FONT_AXIS_VALUE const* axesList = _axesVector.data(); format3->SetFontAxisValues(axesList, gsl::narrow(_axesVector.size())); diff --git a/src/renderer/dx/DxFontRenderData.h b/src/renderer/dx/DxFontRenderData.h index 685e039b97c..ada92b2ab89 100644 --- a/src/renderer/dx/DxFontRenderData.h +++ b/src/renderer/dx/DxFontRenderData.h @@ -84,7 +84,7 @@ namespace Microsoft::Console::Render DWRITE_FONT_STYLE style, DWRITE_FONT_STRETCH stretch); - [[nodiscard]] HRESULT UpdateFont(const FontInfoDesired& desired, FontInfo& fiFontInfo, const int dpi, std::unordered_map features = {}, std::unordered_map axes = {}) noexcept; + [[nodiscard]] HRESULT UpdateFont(const FontInfoDesired& desired, FontInfo& fiFontInfo, const int dpi, const std::unordered_map& features = {}, const std::unordered_map& axes = {}) noexcept; [[nodiscard]] static HRESULT STDMETHODCALLTYPE s_CalculateBoxEffect(IDWriteTextFormat* format, size_t widthPixels, IDWriteFontFace1* face, float fontScale, IBoxDrawingEffect** effect) noexcept; @@ -92,7 +92,6 @@ namespace Microsoft::Console::Render float FontStretchToWidthAxisValue(DWRITE_FONT_STRETCH fontStretch) noexcept; float FontStyleToSlantFixedAxisValue(DWRITE_FONT_STYLE fontStyle) noexcept; - float DIPsToPoints(const float fontSize) noexcept; std::vector GetAxisVector(const DWRITE_FONT_WEIGHT fontWeight, const DWRITE_FONT_STRETCH fontStretch, const DWRITE_FONT_STYLE fontStyle, @@ -116,7 +115,7 @@ namespace Microsoft::Console::Render }; void _SetFeatures(const std::unordered_map& features); - void _SetAxes(const std::unordered_map& axes); + void _SetAxes(const std::unordered_map& axes); void _BuildFontRenderData(const FontInfoDesired& desired, FontInfo& actual, const int dpi); Microsoft::WRL::ComPtr _BuildTextFormat(const DxFontInfo fontInfo, const std::wstring_view localeName); diff --git a/src/renderer/dx/DxRenderer.cpp b/src/renderer/dx/DxRenderer.cpp index 958f20d73f5..7748b155698 100644 --- a/src/renderer/dx/DxRenderer.cpp +++ b/src/renderer/dx/DxRenderer.cpp @@ -1998,7 +1998,7 @@ CATCH_RETURN() // - axes - The map of font axes to use // Return Value: // - S_OK or relevant DirectX error -[[nodiscard]] HRESULT DxEngine::UpdateFont(const FontInfoDesired& pfiFontInfoDesired, FontInfo& fiFontInfo, std::unordered_map features, std::unordered_map axes) noexcept +[[nodiscard]] HRESULT DxEngine::UpdateFont(const FontInfoDesired& pfiFontInfoDesired, FontInfo& fiFontInfo, const std::unordered_map& features, const std::unordered_map& axes) noexcept try { RETURN_IF_FAILED(_fontRenderData->UpdateFont(pfiFontInfoDesired, fiFontInfo, _dpi, features, axes)); diff --git a/src/renderer/dx/DxRenderer.hpp b/src/renderer/dx/DxRenderer.hpp index 33ad3a314e7..b74f0ba0fc2 100644 --- a/src/renderer/dx/DxRenderer.hpp +++ b/src/renderer/dx/DxRenderer.hpp @@ -109,7 +109,7 @@ namespace Microsoft::Console::Render const gsl::not_null pData, const bool isSettingDefaultBrushes) noexcept override; [[nodiscard]] HRESULT UpdateFont(const FontInfoDesired& fiFontInfoDesired, FontInfo& fiFontInfo) noexcept override; - [[nodiscard]] HRESULT UpdateFont(const FontInfoDesired& fiFontInfoDesired, FontInfo& fiFontInfo, std::unordered_map features, std::unordered_map axes) noexcept; + [[nodiscard]] HRESULT UpdateFont(const FontInfoDesired& fiFontInfoDesired, FontInfo& fiFontInfo, const std::unordered_map& features, const std::unordered_map& axes) noexcept; [[nodiscard]] HRESULT UpdateDpi(int const iDpi) noexcept override; [[nodiscard]] HRESULT UpdateViewport(const SMALL_RECT srNewViewport) noexcept override; From b2db07ea8558d3e0fa98baababcf505baa0da590 Mon Sep 17 00:00:00 2001 From: Pankaj Bhojwani Date: Tue, 20 Jul 2021 11:47:17 -0700 Subject: [PATCH 48/49] rename, real function --- src/renderer/dx/DxFontRenderData.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/renderer/dx/DxFontRenderData.cpp b/src/renderer/dx/DxFontRenderData.cpp index 1baed719083..952503ad63c 100644 --- a/src/renderer/dx/DxFontRenderData.cpp +++ b/src/renderer/dx/DxFontRenderData.cpp @@ -13,7 +13,10 @@ static constexpr float POINTS_PER_INCH = 72.0f; static constexpr std::wstring_view FALLBACK_FONT_FACES[] = { L"Consolas", L"Lucida Console", L"Courier New" }; static constexpr std::wstring_view FALLBACK_LOCALE = L"en-us"; static constexpr size_t TAG_LENGTH = 4; -static constexpr auto DIPsToPoints = [](const float fontSize) { return fontSize * (72.0f / 96.0f); }; +static constexpr float FontSizeToPoints(const float fontSize) +{ + return fontSize * (72.0f / 96.0f); +} using namespace Microsoft::Console::Render; @@ -576,7 +579,8 @@ float DxFontRenderData::FontStyleToSlantFixedAxisValue(DWRITE_FONT_STYLE fontSty // Method Description: // - Fill any missing axis values that might be known but were unspecified, such as omitting // the 'wght' axis tag but specifying the old DWRITE_FONT_WEIGHT enum -// - Note to caller: make sure to only call this with a valid IDWriteTextFormat3! +// - This function will only be called with a valid IDWriteTextFormat3 +// (on platforms where IDWriteTextFormat3 is supported) // Arguments: // - fontWeight: the old DWRITE_FONT_WEIGHT enum to be converted into an axis value // - fontStretch: the old DWRITE_FONT_STRETCH enum to be converted into an axis value @@ -641,7 +645,7 @@ std::vector DxFontRenderData::GetAxisVector(const DWRITE } if (WI_IsFlagClear(axisTagPresence, AxisTagPresence::OpticalSize)) { - axesVector.emplace_back(DWRITE_FONT_AXIS_VALUE{ DWRITE_FONT_AXIS_TAG_OPTICAL_SIZE, DIPsToPoints(fontSize) }); + axesVector.emplace_back(DWRITE_FONT_AXIS_VALUE{ DWRITE_FONT_AXIS_TAG_OPTICAL_SIZE, FontSizeToPoints(fontSize) }); } return axesVector; From 319e30a827d165b9f0e2e337fd89b6fc7436f40e Mon Sep 17 00:00:00 2001 From: Pankaj Bhojwani Date: Wed, 21 Jul 2021 11:14:30 -0700 Subject: [PATCH 49/49] remove opsz generation --- src/renderer/dx/CustomTextLayout.cpp | 2 +- src/renderer/dx/DxFontRenderData.cpp | 12 ------------ src/renderer/dx/DxFontRenderData.h | 2 -- 3 files changed, 1 insertion(+), 15 deletions(-) diff --git a/src/renderer/dx/CustomTextLayout.cpp b/src/renderer/dx/CustomTextLayout.cpp index 24f0205deab..bf60bce337c 100644 --- a/src/renderer/dx/CustomTextLayout.cpp +++ b/src/renderer/dx/CustomTextLayout.cpp @@ -1279,7 +1279,7 @@ CATCH_RETURN(); // newer MapCharacters to apply axes of variation to the font if (!FAILED(_formatInUse->QueryInterface(IID_PPV_ARGS(&format3))) && !FAILED(fallback->QueryInterface(IID_PPV_ARGS(&fallback1)))) { - const auto axesVector = _fontRenderData->GetAxisVector(weight, stretch, style, format1->GetFontSize(), format3.Get()); + const auto axesVector = _fontRenderData->GetAxisVector(weight, stretch, style, format3.Get()); // Walk through and analyze the entire string while (textLength > 0) { diff --git a/src/renderer/dx/DxFontRenderData.cpp b/src/renderer/dx/DxFontRenderData.cpp index 952503ad63c..321e5babccd 100644 --- a/src/renderer/dx/DxFontRenderData.cpp +++ b/src/renderer/dx/DxFontRenderData.cpp @@ -13,10 +13,6 @@ static constexpr float POINTS_PER_INCH = 72.0f; static constexpr std::wstring_view FALLBACK_FONT_FACES[] = { L"Consolas", L"Lucida Console", L"Courier New" }; static constexpr std::wstring_view FALLBACK_LOCALE = L"en-us"; static constexpr size_t TAG_LENGTH = 4; -static constexpr float FontSizeToPoints(const float fontSize) -{ - return fontSize * (72.0f / 96.0f); -} using namespace Microsoft::Console::Render; @@ -594,7 +590,6 @@ float DxFontRenderData::FontStyleToSlantFixedAxisValue(DWRITE_FONT_STYLE fontSty std::vector DxFontRenderData::GetAxisVector(const DWRITE_FONT_WEIGHT fontWeight, const DWRITE_FONT_STRETCH fontStretch, const DWRITE_FONT_STYLE fontStyle, - const float fontSize, IDWriteTextFormat3* format) { FAIL_FAST_IF_NULL(format); @@ -621,9 +616,6 @@ std::vector DxFontRenderData::GetAxisVector(const DWRITE case DWRITE_FONT_AXIS_TAG_SLANT: WI_SetFlag(axisTagPresence, AxisTagPresence::Slant); break; - case DWRITE_FONT_AXIS_TAG_OPTICAL_SIZE: - WI_SetFlag(axisTagPresence, AxisTagPresence::OpticalSize); - break; } } @@ -643,10 +635,6 @@ std::vector DxFontRenderData::GetAxisVector(const DWRITE { axesVector.emplace_back(DWRITE_FONT_AXIS_VALUE{ DWRITE_FONT_AXIS_TAG_SLANT, FontStyleToSlantFixedAxisValue(fontStyle) }); } - if (WI_IsFlagClear(axisTagPresence, AxisTagPresence::OpticalSize)) - { - axesVector.emplace_back(DWRITE_FONT_AXIS_VALUE{ DWRITE_FONT_AXIS_TAG_OPTICAL_SIZE, FontSizeToPoints(fontSize) }); - } return axesVector; } diff --git a/src/renderer/dx/DxFontRenderData.h b/src/renderer/dx/DxFontRenderData.h index ada92b2ab89..6546512501f 100644 --- a/src/renderer/dx/DxFontRenderData.h +++ b/src/renderer/dx/DxFontRenderData.h @@ -23,7 +23,6 @@ namespace Microsoft::Console::Render Width = 0x02, Italic = 0x04, Slant = 0x08, - OpticalSize = 0x10, }; DEFINE_ENUM_FLAG_OPERATORS(AxisTagPresence); @@ -95,7 +94,6 @@ namespace Microsoft::Console::Render std::vector GetAxisVector(const DWRITE_FONT_WEIGHT fontWeight, const DWRITE_FONT_STRETCH fontStretch, const DWRITE_FONT_STYLE fontStyle, - const float fontSize, IDWriteTextFormat3* format); private: