Line height of a font is disregarded
The GNOME text stack seems to determine the line-height of a text span by looking at a font's ascent and descent (FreeType's FT_Face.ascender
and FT_Face.descender
fields) but ignores possible line gap (the result of FT_Face.height
- FT_Face.ascender
+ FT_Face.descender
). This results in shifted-upwards looking text in text spans and more compact lists.
Side note before you read on: determining line-spacing or vertical metrics for a font is tricky because there are three different, organically grown sets of values for this in the OpenType specification and decades worth of applications and operating systems doing whatever they want. The OpenType specification strongly recommends applications to use the OS/2 table, sTypo* metrics for determining line height and turning on bit 7 in the OS/2 table, fsSelection bit field to tell the renderer that they really mean it. Variable fonts add another layer of bugs-in-hiding to this, because two of those three sets of values can be varied through the MVAR table. FreeType tries to handle this under the hood and present the developer just one set of values: FT_Face.height
, FT_Face.ascender
and FT_Face.descender
, the line gap being encoded into height
(line gap = height - ascender + descender).
Steps to reproduce
I made two fonts:
- Cantarell-VF-NoUseTypoMetrics.ttf -- This has the vertical metrics settings used by Cantarell as shipped currently.
- Cantarell-VF-UseTypoMetrics.ttf -- This turns on bit 7 in the OS/2 table, fsSelection field. The OpenType specification recommends that I should have done this from the start.
- Install the Cantarell-VF-NoUseTypoMetrics.ttf font.
- Restart the desktop, run Nautilus or Rhythmbox. Look at text runs that are bold, light or anything not regular.
- Remove Cantarell-VF-NoUseTypoMetrics.ttf and install Cantarell-VF-UseTypoMetrics.ttf instead
- Repeat 2 and compare.
Current behavior
With the currently released FreeType, the regular face appears normal but other instances like bold are shifted upwards, as current FreeType sets the sTypo* metrics for variable font instances but defaults to hhea metrics for the default outlines ("Regular").
Expected outcome
The text rendering stack should take line gap into consideration (FreeType's height - ascender + descender) and apply it somewhere, e.g. at the top. In the case of Cantarell, the line gap is indeed applied to the top in the hhea and win metrics for compatibility reasons. The hhea, typo and win metrics sum up to a height of 1200 font units.
The fact that the regular may look normal while e.g. the bold looks shifted may be noteworthy. It means that for the regular, the default outlines are used instead of the regular instance. Here it should make no semantic difference, it appears to be a FreeType bug that I'm adressing.
Version information
Fedora 29, Gnome 3.30.2.
Screenshots
Note that in the shots below, I'm actually using my WIP patch for FreeType to opportunistically use sTypo* metrics by default. If you install the fonts above on your system, you'll most likely get the regular face normally and the bold shifted upwards.
Open the shots in separate tabs and quickly switch between them if you don't see the difference
Not using typo metrics (default now):
Using typo metrics (note how all labels in Nautilus are shifted upwards slightly):