wez / wezterm

A GPU-accelerated cross-platform terminal emulator and multiplexer written by @wez and implemented in Rust
https://wezfurlong.org/wezterm/
Other
17.84k stars 799 forks source link

fonts: Prefer actual italic over oblique #1646

Closed valpackett closed 2 years ago

valpackett commented 2 years ago

Some font families like Victor Mono have both Italic and Oblique styles. The Oblique style is marked as Italic too:

Pattern has 27 elts (size 32)
        family: "Victor Mono"(s) "Victor Mono Medium"(s)
        style: "Medium Oblique"(s) "Italic"(s)
        fullname: "Victor Mono Medium Oblique"(s)
        slant: 110(i)(s)

while Italic is only Italic:

Pattern has 27 elts (size 32)
        family: "Victor Mono"(s) "Victor Mono Medium"(s)
        style: "Medium Italic"(s) "Italic"(s)
        fullname: "Victor Mono Medium Italic"(s)
        slant: 100(i)(s)

My fontconfig alias matching #1250 actually does prefer Italic due to asking fontconfig for fcwrap::FC_SLANT_ITALIC.

But the native matcher only considers italic-ness as a boolean property:

https://github.com/wez/wezterm/blob/85a8434ecb646556ced7d53dd18bebcdb9c9db3b/wezterm-font/src/ftwrap.rs#L339-L341

and does not implement "slant 100 is more Italic than slant 110" into the "best match" ordering.

wez commented 2 years ago

I think 84d4187c9af93be5b7b41cd1cfcf96d316ee9c74 takes care of this; could you give it a try?

I haven't written up docs yet, but it allows for speciying slant="Oblique" (or "Normal", or "Italic") in the config, as well as respects the CSS matching guidance on matching the slant.

freetype doesn't expose anything other than an italic boolean, but I've augmented the existing gross italic matching to consider fonts with oblique in their name as "Oblique".

valpackett commented 2 years ago

No, the parser still says the oblique ttf is italic:

When Intensity=Normal Italic=true:
wezterm.font_with_fallback({
  -- /usr/local/share/fonts/VictorMono/VictorMono-MediumOblique.ttf, FontConfig
  {family="Victor Mono", weight="Medium", slant="Italic"},

freetype doesn't expose anything other than an italic boolean, but I've augmented the existing gross italic matching to consider fonts with oblique in their name as "Oblique".

well that matching is only used when face.italic() == false, but it is true here!

wez commented 2 years ago

how about with 1aad1cf1a2185c8fc67bbedcca363f56fc8cac98 ?

wez commented 2 years ago

Reading around this a bit more, I understand why this is a PITA.

Oblique is a font that is presented at an angle but that has no special design distinction from the font appearance at the normal angle. In other words, it is presented just as a skewed font, similar to how we might synthesize "italics".

Italic is a font that is designed to be presented at an angle, usually with some design flourish such as cursive appearance.

There's no metadata in the font file format to definitively know whether a font is italic vs. oblique. The font formats only track an italic boolean/bit as the "obliqueness" is purely a matter of style.

I don't know of a better way to detect whether a font is oblique other than grubbing around with the font name, which feels pretty gross :-p

valpackett commented 2 years ago

how about with https://github.com/wez/wezterm/commit/1aad1cf1a2185c8fc67bbedcca363f56fc8cac98 ?

That works.


Yeah, and this is only an issue if a family has both italic and oblique styles, which I haven't encountered before trying out Victor Mono.

github-actions[bot] commented 1 year ago

I'm going to lock this issue because it has been closed for 30 days ⏳. This helps our maintainers find and focus on the active issues. If you have found a problem that seems similar to this, please open a new issue and complete the issue template so we can capture all the details necessary to investigate further.