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 Double-Height and Double-Width text to Windows Terminal #11595

Closed
Tracked by #13392
german-one opened this issue Oct 24, 2021 · 8 comments · Fixed by #13933
Closed
Tracked by #13392

Add support for Double-Height and Double-Width text to Windows Terminal #11595

german-one opened this issue Oct 24, 2021 · 8 comments · Fixed by #13933
Labels
Area-Rendering Text rendering, emoji, complex glyph & font-fallback issues Area-VT Virtual Terminal sequence support Help Wanted We encourage anyone to jump in on these. Issue-Feature Complex enough to require an in depth planning process and actual budgeted, scheduled work. Product-Terminal The new Windows Terminal. Resolution-Fix-Committed Fix is checked in, but it might be 3-4 weeks until a release.
Milestone

Comments

@german-one
Copy link
Contributor

german-one commented Oct 24, 2021

Description of the new feature/enhancement

At least Windows 11 ships with a conhost version which supports DECDHL and DECDWL. I'm used to telling people who are asking for a better VT support something like "Hey, check out the shiny Windows Terminal. It supports quite some escape sequences that the console host does not, and you can even set it as default terminal app." Now I have to add "... unless you're looking for double height/width text where you explicitly have to use the good ol' console." This feels rather odd 😄

Proposed technical implementation details (optional)

Consider adding this feature to Windows Terminal.
However, from what I've read, the current architecture of conpty doesn't seem to be ready yet. So, I suppose a lot of refactoring would be necessary to get to the preconditions 😧

Related: #7865, #8664
cc @j4james

@german-one german-one added the Issue-Feature Complex enough to require an in depth planning process and actual budgeted, scheduled work. label Oct 24, 2021
@ghost ghost added Needs-Triage It's a new issue that the core contributor team needs to triage at the next triage meeting Needs-Tag-Fix Doesn't match tag requirements labels Oct 24, 2021
@j4james
Copy link
Collaborator

j4james commented Oct 24, 2021

There are two aspects to this:

  1. We need to get the DX renderer to support it, and that may be a good first step, because that can actually be tested in conhost now without involving conpty (thanks to Fix conhost UseDx mode #10770). The main reason I've been putting that off is because the double-width attributes touch on aspects of the DX renderer that are fundamentally broken, and it annoys me every time I look at it. Those issues aside, it may not be that much work, but I'm no expert on DX.

  2. Once the renderer is in place, we need to get it working over conpty. I had a hacky idea for that which shouldn't be that complicated, but I'm not certain it would work, and in the ideal world this would all be solved by the conpty passthrough mode (ConPTY Passthrough mode  #1173). Since that's actually starting to look like it may be a real possibility, I'd rather not waste time on the hacky solution, and instead concentrate on the things that'll help make passthrough more feasible.

So I probably should take a stab at part 1 at some point, because we're going to need that either way. I'm less certain about part 2, but that's not to say it won't happen. At the moment I'm working on a bunch of other things, though, and I'm not the fastest of coders, but there's no reason why someone else couldn't take it on.

@german-one german-one changed the title Add support for Double-Hight and Double-Width text to Windows Terminal Add support for Double-Height and Double-Width text to Windows Terminal Oct 24, 2021
@zadjii-msft zadjii-msft added Area-Rendering Text rendering, emoji, complex glyph & font-fallback issues Area-VT Virtual Terminal sequence support Help Wanted We encourage anyone to jump in on these. Product-Terminal The new Windows Terminal. labels Oct 25, 2021
@ghost ghost removed the Needs-Tag-Fix Doesn't match tag requirements label Oct 25, 2021
@zadjii-msft zadjii-msft added this to the Terminal Backlog milestone Oct 25, 2021
@zadjii-msft
Copy link
Member

Yep, I pretty much have nothing to add. If you'd like to take a stab at it, we'd love the help 😄

@DHowett DHowett removed the Needs-Triage It's a new issue that the core contributor team needs to triage at the next triage meeting label Oct 29, 2021
@zadjii-msft zadjii-msft modified the milestones: Terminal Backlog, Backlog Jan 4, 2022
ghost pushed a commit that referenced this issue May 18, 2022
This PR adds support for the VT line rendition attributes in the DirectX
renderer, which allows for double-width and double-height line
renditions.

Line renditions were first implemented in conhost (with the GDI
renderer) in PR #8664.  Supporting them in the DX renderer now is a
small step towards #11595.

The DX implementation is very similar to the GDI one. When a particular
line rendition is requested, we create a transform that is applied to
the render target. And in the case of double-height renditions, we also
initialize some clipping offsets to allow for the fact that we only
render half of a line at a time.

One additional complication exists when drawing the cursor, which
requires a two part process where it first renders to a command list,
and then draw the command list in a second step. We need to temporarily
reset the transform in that first stage otherwise it ends up being
applied twice.

I've manually tested the renderer in conhost by setting the `UseDx`
registry entry and confirmed that it passes the _Vttest_ double-size
tests as well as several of my own tests. I've also checked that the
renderer can now handle horizontal scrolling, which is a feature we get
for free with the transforms.
@j4james
Copy link
Collaborator

j4james commented Sep 4, 2022

FYI, I've been playing around with part two of this recently, and I've got a solution which I think is not too terrible.

By default it won't affect the conpty output at all, but once you write anything with a double size, it switches to a mode where every line will be output with a line rendition prefix (it has to do this because it has no easy way of tracking the line rendition state in the client terminal). It remains in this mode until you do something like a cls, which resets everything to single width, and then it can safely switch back the initial mode.

So it's a bit hacky, and not exactly optimal when you're using double size text, but that's still better than nothing. And for anyone that isn't using line attributes, it shouldn't impact them at all.

What do you think? Would you be happy to accept a PR with this approach?

@german-one
Copy link
Contributor Author

@j4james
I second your ...

that's still better than nothing

... as long as you are satisfied. (I know you're actually fighting to get as close to the original behavior as possible.)

but once you write anything with a double size, it switches to a mode where every line will be output with a line rendition prefix

Sorry for my ignorance about graphics. This doesn't mean that the whole viewport is turned to double size incl. the existing text, right?

It remains in this mode until you do something like a cls

I hope something less drastic would work, too 😆

Would you be happy to accept a PR with this approach?

I guess you didn't ask me since my approval is worth nothing. However, yes I would.

@j4james
Copy link
Collaborator

j4james commented Sep 4, 2022

but once you write anything with a double size, it switches to a mode where every line will be output with a line rendition prefix

Sorry for my ignorance about graphics. This doesn't mean that the whole viewport is turned to double size incl. the existing text, right?

No, it's not as bad as that. Each line has its own state - could be single width, double width, the top half of a double height line, or the bottom half of a double height line. What I mean is that we have to write out that line rendition state every time we refresh a line. So even if everything is single width, you'll still see all the lines prefixed with a single-width sequence (\e#5), until the system figures out that it's safe to stop doing that.

It remains in this mode until you do something like a cls

I hope something less drastic would work, too 😆

It's basically any event that will force the full viewport to repaint. Clearing the screen is just the most common case. Some forms of scrolling could probably trigger it too. I suspect all of these cases are likely to be fairly drastic though.

That said, I would have thought most times you're using double size text would be in a full screen application from which you'd exit with a clear screen, or alt buffer switch. And if not, worst case is you're getting a bunch of unnecessary 3-byte prefixes in your output for a while.

If this turns out to be a massive performance issue, we can always look at optimising it further in the future. I just didn't want to overcomplicate the initial fix if it wasn't absolutely necessary. And long term I'm still hoping we'll get full passthrough mode working, but that seems to be stalled at the moment with miniksa gone.

@german-one
Copy link
Contributor Author

Haha, I've been under the impression that cls was necessary for turning back to default size 😄 Apparently I missed the fact that you've been only talking about the additional line state. I don't expect this to be a big performance issue btw.

I would have thought most times you're using double size text would be in a full screen application from which you'd exit with a clear screen, or alt buffer switch.

Not necessarily. It's a nice way to emphasize a heading to separate it from body text.

@DHowett
Copy link
Member

DHowett commented Sep 6, 2022

I'm actually really cool with this solution. ConPTY is an assemblage of tricks to get things "just right" (barring the instances where it is neither "just" nor "right") so this is totally in line with that. We can keep it until we either make ConPTY better or obviate the need for it. :)

@ghost ghost added the In-PR This issue has a related PR label Sep 6, 2022
@ghost ghost closed this as completed in #13933 Sep 9, 2022
ghost pushed a commit that referenced this issue Sep 9, 2022
This PR introduces a mechanism for passing through line rendition
attributes to the conpty client, so we can support double-width and
double-height text in Windows Terminal.

Line renditions were first implemented in conhost (with the GDI
renderer) in PR #8664, and were implemented in the DX renderer in PR
#13102.

By default this won't add any additional overhead to the conpty output,
but as soon as there is any usage of double-size text, we switch to a
mode in which every line output will be prefixed with a line rendition
sequence. This is to ensure that the line attributes in the client
terminal are always in sync with the host.

Since this does add some overhead to the conpty output, we'd prefer not
to remain in this mode longer than necessary. So whenever there is a
full repaint of the entire viewport, we check to see if all of the lines
are single-width. If that is the case, we can then safely skip the line
rendition sequences in future updates.

One other small optimization is when the conpty update is only writing
out a single character (this is something we already check for). When
that is the case, we can safely skip the line rendition prefix, because
a single character update should never include a change of the line
rendition.

## Validation Steps Performed

I've manually tested that Windows Terminal now passes the double-size
tests in _Vttest_, and also confirmed various edge cases are working
correctly in my own double-size tests.

Closes #11595
@ghost ghost added Resolution-Fix-Committed Fix is checked in, but it might be 3-4 weeks until a release. and removed In-PR This issue has a related PR labels Sep 9, 2022
@ghost
Copy link

ghost commented Jan 24, 2023

🎉This issue was addressed in #13933, which has now been successfully released as Windows Terminal Preview v1.17.1023.:tada:

Handy links:

This issue 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-VT Virtual Terminal sequence support Help Wanted We encourage anyone to jump in on these. Issue-Feature Complex enough to require an in depth planning process and actual budgeted, scheduled work. Product-Terminal The new Windows Terminal. Resolution-Fix-Committed Fix is checked in, but it might be 3-4 weeks until a release.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants