Skip to content
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

Merged
55 commits merged into from
Jul 22, 2021
Merged

Allow users to set font features and font axes #10525

55 commits merged into from
Jul 22, 2021

Conversation

PankajBhojwani
Copy link
Contributor

@PankajBhojwani PankajBhojwani commented Jun 28, 2021

Adds support for users to be able to set font features and axes (see the spec for more details!)

Detailed Description

CustomTextLayout

  • Asks the DxFontRenderData for the font features when getting glyphs
  • If any features have been set/updated, we always skip the "isTextSimple" shortcut
  • Asks the _formatInUse for any font axes when mapping characters in _AnalyzeFontFallback

DxFontRenderData

  • Stores a map of font features (initialized to the standard feature list)
  • Stores a map of font axes
  • Has methods to add font features/axes to the map or update existing ones
  • Has methods to retrieve the font features/axes
  • Sets the font axes in the IDWriteTextFormat when creating it

Validation Steps Performed

It works!

Specified in #10457
Related to #1790
Closes #759
Closes #5828

@@ -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);
Copy link
Collaborator

@skyline75489 skyline75489 Jun 29, 2021

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.

Copy link
Collaborator

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.

Copy link
Contributor Author

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)

Copy link
Collaborator

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

Copy link
Contributor Author

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

Copy link
Collaborator

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.

Copy link
Member

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!

Copy link
Member

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?

Copy link
Member

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.

Copy link
Contributor Author

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())
Copy link
Collaborator

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.

Copy link
Contributor Author

@PankajBhojwani PankajBhojwani Jun 30, 2021

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

@PankajBhojwani PankajBhojwani changed the title Allow users to set font features Allow users to set font features and font axes Jun 30, 2021
src/cascadia/TerminalSettingsModel/FontConfig.h Outdated Show resolved Hide resolved
src/renderer/dx/DxFontRenderData.cpp Show resolved Hide resolved
src/renderer/dx/DxFontRenderData.cpp Outdated Show resolved Hide resolved
src/renderer/dx/DxFontRenderData.cpp Show resolved Hide resolved
src/renderer/dx/DxRenderer.cpp Outdated Show resolved Hide resolved
@ghost ghost added Needs-Author-Feedback The original author of the issue/PR needs to come back and respond to something and removed Needs-Author-Feedback The original author of the issue/PR needs to come back and respond to something labels Jul 20, 2021
Copy link
Member

@zadjii-msft zadjii-msft left a 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 ✔️

@zadjii-msft zadjii-msft dismissed their stale review July 21, 2021 15:40

I literally just said why

Copy link
Member

@DHowett DHowett left a 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!

@DHowett
Copy link
Member

DHowett commented Jul 21, 2021

You can mark this as closing #5828 as well!

@DHowett
Copy link
Member

DHowett commented Jul 21, 2021

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

@ghost ghost added Area-Settings Issues related to settings and customizability, for console or terminal Area-TerminalControl Issues pertaining to the terminal control (input, selection, keybindings, mouse interaction, etc.) labels Jul 21, 2021
Copy link
Member

@miniksa miniksa left a 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!

@PankajBhojwani PankajBhojwani added the AutoMerge Marked for automatic merge by the bot when requirements are met label Jul 22, 2021
@ghost
Copy link

ghost commented Jul 22, 2021

Hello @PankajBhojwani!

Because this pull request has the AutoMerge label, I will be glad to assist with helping to merge this pull request once all check-in policies pass.

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 (@msftbot) and give me an instruction to get started! Learn more here.

@ghost ghost merged commit 4c16cb2 into main Jul 22, 2021
@ghost ghost deleted the dev/pabhoj/font_feature branch July 22, 2021 23:15
@ghost
Copy link

ghost commented Aug 31, 2021

🎉Windows Terminal Preview v1.11.2421.0 has been released which incorporates this pull request.:tada:

Handy links:

This pull request was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area-Rendering Text rendering, emoji, complex glyph & font-fallback issues Area-Settings Issues related to settings and customizability, for console or terminal Area-TerminalControl Issues pertaining to the terminal control (input, selection, keybindings, mouse interaction, etc.) AutoMerge Marked for automatic merge by the bot when requirements are met Issue-Task It's a feature request, but it doesn't really need a major design. Priority-3 A description (P3) Product-Terminal The new Windows Terminal.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Request: Support for Font Width Variants Investigate/implement renderer setting to disable ligatures
6 participants