Skip to content

Allow users to set font features and font axes - #10525

Merged
55 commits merged into
mainfrom
dev/pabhoj/font_feature
Jul 22, 2021
Merged

55 commits merged into
mainfrom
dev/pabhoj/font_feature

Conversation

@PankajBhojwani

@PankajBhojwani PankajBhojwani commented Jun 28, 2021 •

Copy link
Copy Markdown
Contributor

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

Comment thread src/renderer/dx/DxFontRenderData.h Outdated
[[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);

@skyline75489 Chester Liu (skyline75489) Jun 29, 2021 •

Copy link
Copy Markdown
Collaborator

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
Copy Markdown
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 Michael Niksa (@miniksa) for suggestions.

Copy link
Copy Markdown
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
Copy Markdown
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
Copy Markdown
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
Copy Markdown
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 Michael Niksa (@miniksa) since he created all the DX classes.

Copy link
Copy Markdown
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
Copy Markdown
Contributor

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
Copy Markdown
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
Copy Markdown
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

}

if (_isEntireTextSimple)
if (_isEntireTextSimple && !_fontRenderData->DidUserSetFeatures())

Copy link
Copy Markdown
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.

@PankajBhojwani PankajBhojwani Jun 30, 2021 •

Copy link
Copy Markdown
Contributor Author

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
Comment thread src/renderer/dx/CustomTextLayout.cpp Resolved
Comment thread src/renderer/dx/CustomTextLayout.h Resolved
Comment thread src/renderer/dx/DxFontRenderData.cpp Resolved
Comment thread src/renderer/dx/DxFontRenderData.cpp Resolved
Comment thread src/renderer/dx/DxFontRenderData.cpp Resolved
Comment thread src/renderer/dx/DxRenderer.cpp 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

@zadjii-msft Mike Griese (zadjii-msft) left a comment

Copy link
Copy Markdown
Member

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
Mike Griese (zadjii-msft) dismissed their stale review July 21, 2021 15:40

I literally just said why

Copy link
Copy Markdown
Member

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
Copy Markdown
Member

You can mark this as closing #5828 as well!

@DHowett

Copy link
Copy Markdown
Member

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

@miniksa Michael Niksa (miniksa) left a comment

Copy link
Copy Markdown
Contributor

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
Copy Markdown

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
Copy Markdown

🎉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