-
Notifications
You must be signed in to change notification settings - Fork 8.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Allow users to set font features and font axes #10525
Conversation
src/renderer/dx/DxFontRenderData.h
Outdated
@@ -74,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<std::wstring_view, uint32_t> features); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we just use UpdateFont
as the single point of entry of font settings? In my understanding the features are basically like weight & style & etc, right? I'm OK with DidUserSetFeatures
, because it's read-only. But for anything that can change the internal properties in DxFontRenderData
, I'd like to do it through UpdateFont
.
So the idea is roughly: move _features
into FontInfoDesired
&. Update _desiredFont->features
in ControlCore
. Pass the features
inside _desiredFont
through UpdateFont
. Then continue.
This would be a less invasive way. BTW this also eliminates DxEngine::UpdateFontFeatures
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is features
something we need in both FontInfoBase
& DxFontInfo
? If it is, then it calls for the merging of these classes.
CC @miniksa for suggestions.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We cannot move _features
into FontInfoDesired
or FontInfo
because that part of the code is shared with conhost. The features need to be specific to only the DxEngine (similar to the way we do pixel shader path)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No i mean technically all you need is a std::unordered_map, right? No DX structure related whatsoever. That is the low level representation. And you can convert that into DX structure in upper layer.
Unless there’s other regulations, then I am OK
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry it took a while to get back to you on this!
Even though its a low level representation, conhost will never use the map in font info, so it is very wasteful to always ask conhost to allocate space for an empty map especially considering that the majority use case is conhost
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If it’s not used in conhost, I assume the compiler will maybe try to optimize them away, right? Even without optimization, I would personally trade the few bytes for architectural benefits without doubt.
I am gonna leave the choice to you guys, especially @miniksa since he created all the DX classes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nah. The compiler cannot optimize out members from a class. Memory layouts aren't malleable like that!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We could do it as a std::optional<std::unordered_map<std::wstring_view, uint32_t>>
right? I don't think that will alloc unless it is actually used?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As before this parameter should be taken by const-reference, as you don't actually store it anywhere.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As discussed, we use UpdateFont
now for the features and axes. _SetFeatures
and _SetAxes
are now just private helper functions inside DxFontRenderData
@@ -351,7 +351,7 @@ CATCH_RETURN() | |||
_glyphIndices.resize(totalGlyphsArrayCount); | |||
} | |||
|
|||
if (_isEntireTextSimple) | |||
if (_isEntireTextSimple && !_fontRenderData->DidUserSetFeatures()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am a bi confused by this. Say without this PR, we have ligature enabled by default, and we think some text can be simple. But with this PR and people disabling ligature, suddenly all text is complicated now? If anything, isn’t text w/o ligature a “simple” one instead?
I mean code-wise, I get it. You have to pass the Feature structure in. But it seems wrong logically.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The thing is we cannot detect what glyphs get affected/don't get affected based on how the user changed the default features (there's just way too many features to track). So as long as the user changed something, we cannot take the shortcut and need to call GetGlyphs
instead
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay, i'm clearing off my block, since it was pretty trivially fixable. I think everyone else on this thread's got a handle for what's up, I'll leave it to them to ✔️
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm cool with this, and pretty excited to boot. Let's get a second signoff and gogogo!
You can mark this as closing #5828 as well! |
I edited your link to the standard feature list to be a commit-based permalink so that if fdwr ever changes that code it still points to the same ole place |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You made it! Thank you for grinding this out. I know it's been a journey. Looks good; let's ship it!
Hello @PankajBhojwani! Because this pull request has the p.s. you can customize the way I help with merging this pull request, such as holding this pull request until a specific person approves. Simply @mention me (
|
🎉 Handy links: |
Adds support for users to be able to set font features and axes (see the spec for more details!)
Detailed Description
CustomTextLayout
DxFontRenderData
for the font features when getting glyphs_formatInUse
for any font axes when mapping characters in_AnalyzeFontFallback
DxFontRenderData
IDWriteTextFormat
when creating itValidation Steps Performed
It works!
Specified in #10457
Related to #1790
Closes #759
Closes #5828