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

Add support for soft fonts in the DX renderer #13362

Merged
4 commits merged into from
Jul 14, 2022
Merged

Conversation

j4james
Copy link
Collaborator

@j4james j4james commented Jun 23, 2022

Summary of the Pull Request

This PR adds support for downloadable soft fonts in the DirectX
renderer, potentially enabling them to be used in Windows Terminal.

References

Soft fonts were first implemented in conhost (with the GDI renderer) in
PR #10011.

PR Checklist

  • Closes #xxx
  • CLA signed.
  • Tests added/passed
  • Documentation updated.
  • Schema updated.
  • I've discussed this with core contributors already. If not
    checked, I'm ready to accept this work might be rejected in favor of a
    different grand plan. Issue number where discussion took place: #xxx

Detailed Description of the Pull Request / Additional comments

The way the DirectX implementation works is by building up a bitmap
containing all of the glyphs, and then drawing an appropriate subsection
of that bitmap for each character that needs to be rendered. The current
text color is applied with a color matrix effect, and the glyphs are
automatically scaled up to the current font size with a scaling effect.

By default the scaling uses a high quality cubic interpolation, which
gives it a smoother antialiased effect. But if the Text antialiasing
option is configured as Aliased, we use a simpler nearest-neighbor
interpolation, which more closely matches the rendering of the original
GDI implementation.

Validation Steps Performed

I've manually tested the renderer in conhost with the UseDx registry
entry. I've also tested in Windows Terminal using the experimental
passthrough mode.

@j4james j4james marked this pull request as ready for review June 23, 2022 02:41
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.

Got any cool sample scripts for testing this?

{
// We need to reset the clipping rect applied by the CustomTextRenderer,
// since the soft font will want to set its own clipping rect.
RETURN_IF_FAILED(_customRenderer->EndClip(_drawingContext.get()));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this necessary? The only place you push a clip, you've got a scope_exit to pop it. I don't think you're otherwise setting _clipRect anywhere, but maybe I'm mistaken. Maybe we need this just to make sure there's not already a clip rect

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not the soft font clipping that I'm worried here about - it's the CustomTextRenderer. It has a clipping rect that it keeps active until the end of the paint, only updating it when necessary. See here:

// If we already have a clip rectangle, check if it different than the previous one.
if (_clipRect.has_value())

By calling EndClip, we clear that rect so we can apply our own. The CustomTextRenderer will then reapply its rect when it needs it.

@zadjii-msft zadjii-msft added the AutoMerge Marked for automatic merge by the bot when requirements are met label Jul 14, 2022
@ghost
Copy link

ghost commented Jul 14, 2022

Hello @zadjii-msft!

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 9ae68cc into microsoft:main Jul 14, 2022
@j4james
Copy link
Collaborator Author

j4james commented Jul 14, 2022

Got any cool sample scripts for testing this?

There are a bunch of soft fonts you can download here:
https://vt100.net/dec/vt320/fonts

But they're designed for an 8-bit terminal, so you need to switch to ISO-2022 mode first with the DOCS sequence:

echo -e '\e%@'

After that you can just cat the files to switch the font.

There's also the CMatrix fork which uses soft fonts to produce the Japanese characters here:
https://github.com/jhamby/cmatrix

Just remember that if you want to test in Windows Terminal you have to use the passthrough mode for now.


// The bitmap and associated scaling/coloring effects are created on demand
// so we need make sure they're generated now.
RETURN_IF_FAILED(_createResources(d2dContext.Get()));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I haven't made it all the way through, but how do we handle device invalidation? Are the bitmaps okay to use cross-Context if we end up having to regenerate the context in the main renderer?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nevermind. Reset very obviously does that, and it happens to be called from releaseDeviceResources. Derp. Thanks.

@j4james j4james deleted the dx-soft-fonts branch August 31, 2022 00:26
ghost pushed a commit that referenced this pull request Sep 13, 2022
This PR introduces a mechanism for passing through downloadable soft
fonts to the conpty client, so that we can support DRCS (Dynamically
Redefinable Character Sets) in Windows Terminal.

Soft fonts were first implemented in conhost (with the GDI renderer) in
PR #10011, and were implemented in the DX renderer in PR #13362.

The way this works is by passing through the `DECDLD` sequence
containing the font definition, but with the character set ID patched to
use a hardcoded value (this is to make sure it's not going to override
the default character set). At the same time we send through an `SCS`
sequence to map this character set into the G1 table so we can easily
activate it.

We still need to process the `DECDLD` sequence locally, though, since
the initial character set mapping take place on the host side. This gets
the DRCS characters into our buffer as PUA Unicode characters. Then when
the VT engine needs to output these characters, it masks them with `7F`
to map them back to ASCII, and outputs an `SO` control to activate the
soft font in the conpty client.

## Validation Steps Performed

I've manually tested with a number of soft fonts and applications that
make use of soft fonts. But if you're testing with the VT320 fonts from
the vt100.net collection, note that you'll need to enable the ISO-2022
coding system first, since they use 8-bit C1 controls.
@ghost
Copy link

ghost commented Sep 13, 2022

🎉Windows Terminal Preview v1.16.252 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
AutoMerge Marked for automatic merge by the bot when requirements are met
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants