terminal
terminal copied to clipboard
Font sizes in WT and conhost
Windows Terminal version
1.16.2641.0
Windows build number
10.0.19044.1889
Other Software
No response
Steps to reproduce
Apologies if this has already been discussed somewhere.
I prefer Consolas 20px. This is how it looks like in conhost:
The cmd file used: sample.cmd.txt
I would like to get the same experience in WT, so I go to settings, select Consolas, 20, and...
Oh. Ok, it says "Size of the font in points", I should've paid attention.
Ok, let's google what points are and how they relate to pixels:
https://blog.gimm.io/difference-between-pixel-px-and-point-pt-font-sizes-in-email-signatures/
A point (pt) is equal to 0.352778 millimeters, 0.0138889 inches, or 1.333 pixels.
https://graphicdesign.stackexchange.com/questions/199/point-vs-pixel-what-is-the-difference
A px is therefore 0.75 pt
Ok, if one px is 0.75 pt, then 20 px is 15 pt, right?
No.
Well, apparently these are some other points then, but I'm getting tired and don't want to research it further. Let's try the scientific method.
10pt... No. 11pt... No. 12pt...

Close. Width is nearly perfect, but height is too small.
13pt...

Now height is nearly perfect, but width is too big. What the... Ok, the new WT supports fractional font sizes, so let's try that: ... 12.64pt...
Width is nearly perfect, height is nearly perfect, but... it's ugly. Too bold. With gaps.
No luck it seems. Let's try other apps just to check if it's possible.
Windows Notepad, 13pt:
A pixel-perfect match!

ConEmu, 20px:
Also a pixel-perfect match:

So it is doable.
Expected Behavior
I want to see exactly the same picture in WT I used to see in conhost for over a decade. With all its flexibility, advanced renderers etc. I expect it to be trivially achievable, if not out of the box.
Actual Behavior
No matter what I do, I cannot get the same results: the font is either too short or too wide, fractional sizes approximate it better, but the result is ugly. Meanwhile, in some other apps it just works.
P.S. I understand that fonts is a complex topic, vector curves not necessarily can perfectly fit into a pixel grid, there are different approximation methods etc., but I think there should be a way to get a familiar look & feel nevertheless.
And another related issue: as I mentioned above, lines appear thicker and somewhat blurrier in WT (Atlas) with certain font sizes. It is visible to some extent on double lines on the screenshots. It could be related to font hinting differences.
Replacing defaultParams->GetRenderingMode() with DWRITE_RENDERING_MODE_GDI_CLASSIC here:
https://github.com/microsoft/terminal/blob/cacf66860f6c175672b3d030dcd166e372b2a8cc/src/renderer/atlas/dwrite.cpp#L37
improves it significantly (notice also the absence of vertical artefacts within the █▄▌ and ▐▀ blocks in the 2nd case):

Test characters: ░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀
Apologies if this has already been discussed somewhere.
I don't think we have! I'm actually really happy for any feedback I can get, because as the person who mucked around in our text rendering the most lately, I really don't know if most of my decisions are "good". I just go by what I know, but that doesn't mean it's optimal or correct.
For instance cell height (or line height) is currently determined as the font's ascent + descent + lineGap which in case of Consolas is 2398 units, but most if not all glyphs in Consolas have an "advance height" of 2048 units (2048 units are 1em). Should I use the former, which is what others use or should I use the glyph advance height? I really don't know... it makes lines taller by 17%. However it's what is recommended by OpenType: https://learn.microsoft.com/en-us/typography/opentype/spec/recom#stypoascender-stypodescender-and-stypolinegap
In either case, as you might already know, font sizes in conhost aren't specified in "font sizes". They're given in line heights and the font size is determined to fit into that height. So if you specify a "font size" of 20px it'll result in exactly 20px tall cells and the actual font size in px will be some non-integer.
Given that Consolas' ascent + descent + lineGap is 2398 we arrive at a line height of 1.1708984375em. Since you're looking for a line height of 20px you're looking for a font size of 20 / 1.1708984375 == 17.0809px. Converted to points this results in 12.81067556.
Combined with ClearType AA this should result in an identical appearance. Try this config:
"defaults":
{
"antialiasingMode": "cleartype",
"font":
{
"face": "Consolas",
"size": 12.81067556
}
},
If there are still gaps, they should be fixed with https://github.com/microsoft/terminal/pull/14099.
Now the question is: How do you put that into our settings model if anything? And could we maybe merge this with my current work on allowing customized line heights?
BTW there was a discussion about font rendering a while ago over here: https://github.com/microsoft/terminal/issues/13936 Especially in the last few comments it contains some more nuances about why we look different from the rest. As I mentioned in that issue, I believe that what we're doing is technically the right thing to do (especially long term), but that doesn't mean that I'm not urgently looking for any ideas and suggestions what to do better, what to change and how to reconcile old with new, if we do decide that the new approach is in fact better than the old one (long term).
Edit: I'm going to mark it as "question" for now since it's not really a bug (like a crash). We can change it to Issue-Bug/Task/Feature later if it turns out to be something like that. 🙂
Thank you for the explanation.
Try this config
Thanks, it is really close now (and it only works in Atlas, right?). However, some extra boldness is still there, especially in horizontal lines, and it makes the picture somewhat heavy visually.
A real world example

How do you put that into our settings model if anything?
Depends what to put:
- some fine-grained controls to further tweak font size and rendering?
- a switch between font size and line height?
- just a single "vintage look" switch?
@lhecker It looks way better in 1.16.3463.0, thank you!
Almost pixel-perfect

I'm planning to add a "legacy font size switch" to the settings in the future, allowing you to set a row or line height instead of a font size. I'm just not sure how to best design the switch in the settings UI ¹ or how to store it in the settings.json and I haven't really committed myself to spend time on implementing it just yet. There's a lot of other interesting features I'm working on as well after all, like proper & full Unicode support in all console APIs (and VT), or a "AtlasEngine v2" kind of renderer, which will allow for arbitrarily overlapping glyphs...
¹ Maybe just a checkbox next to the font size?
² I added a cellHeight field in the font object in #14255. Maybe if you set that but leave the font size field empty, we use the cellHeight to derive a pixel-perfect font size from it?