Hi,

I have a pending change which I would like to get into Qt 6.8 which will change 
default line heights of fonts in some cases, so I thought I would mention it 
here to hear if people have objections. Since it does change text layouts in 
some cases, it also adds a fallback mechanism to previous behavior, both per 
font with a style strategy in QFont and an application attribute. Some users 
will notice this and manually have to change their code if they are unhappy 
with the changes, but in practice it is a correctness fix.

https://codereview.qt-project.org/c/qt/qtbase/+/563751

Background is this:

In OpenType fonts there are three different sets of metrics providing the 
vertical metrics of the font

  *
The ascender/descender/lineGap in the HHEA table (predates OpenType)
  *
The winAscent/winDescent in the OS/2 table
  *
The typoAscender/typoDescender/typoLineGap also in the OS/2 table

Microsoft's approach is typically to add new fields to OpenType rather than 
risk breaking legacy software, so the format is kind of convoluted due to this. 
In most fonts the HHEA values will match the typo* values, but older 
implementations of the font system had platform-specific handling of these (as 
the spec says), so to ensure backwards-compatibility, Microsoft added the 
additional sets.

The winAscent/winDescent are used for clipping the glyphs, so they need to be 
set so that no glyph in the font is higher than winAscent+winDescent. Often the 
sum will match typoAscender-typoDescender+typoLineGap, but not always. The 
clipping requirement makes them less suitable for typography, since there's no 
way to add e.g. glyphs that are taller than the line height of the font. But 
many applications still used winAscent+winDescent for line heights, including 
Microsoft's own GDI. So to make it possible to keep the default of 
winAscent+winDescent for existing fonts but still allow fonts to expand beyond 
this, they later added the USE_TYPO_METRICS flag to the OS/2 table, which is 
supposed to be set if the typo* metrics are valid to use.

In Qt 5 we would have platform-specific handling of this:

  *
Windows would use winAscent+winDescent as default, unless USE_TYPO_METRICS was 
set, in which case the typo* metrics were used
  *
FreeType would use the typo* metrics if available
  *
macOS would use the original metrics in HHEA, even if the OS/2 table is present 
in the font, typically matching the typo* metrics.

Users were complaining about inconsistent layouts between platforms, and in Qt 
6.0 we tried to consolidate, by making all platforms use the OS/2 data if 
available, and prefer typo* metrics if the USE_TYPO_METRICS was set and win* 
metrics if not.

We early found out that this was not a viable plan on macOS, because some fonts 
that are only used on macOS have OS/2 tables with invalid data in them. So we 
changed macOS to use the platform values again instead. This typically matches 
the typo* values granted that those are set correctly, because there is no 
reason for these to be different. But we kept the changed default on FreeType, 
so that this now matches Windows.

Some recent discussions has made me regret this decision, though. The OpenType 
spec<https://learn.microsoft.com/en-us/typography/opentype/spec/os2#uswinascent>
 very clearly states:

Some legacy applications use the usWinAscent and usWinDescent values to 
determine default line spacing. This is strongly discouraged. The sTypo* fields 
should be used for this purpose.

So despite GDI choosing the backwards compatible route, the recommendation is 
to always use the typo* metrics for line spacing. This means that modern font 
systems that are not limited by compatibility concerns will use this, and this 
in turn means that fonts will be designed with this in mind. Font designers 
will often neglect to set the USE_TYPO_METRICS flag even if the typo* metrics 
are preferable, because the fonts work fine on FreeType and DirectWrite 
applications.

Now, the conservative approach would be to do what Microsoft did and keep the 
current default + add an opt-in for the correct behavior. But I fear becoming a 
primarily compatibility-driven toolkit can be inhibiting, like it is for GDI, 
so I would rather like to default to correctness, following the recommendation 
in the spec and introduce an opt-out for those users who want to get back the 
original behavior.

So that's what my change currently does. By default, macOS will still use HHEA 
(so font designers still need to make sure those are in sync with the other 
metrics) but Windows and FreeType will both now prefer the typo* metrics, even 
if the USE_TYPO_METRICS flag is unset. If PreferLegacyLineMetrics is set, then 
all platforms (including macOS) will use typo* metrics if USE_TYPO_METRICS is 
set and win* metrics otherwise, granted that the OS/2 table exists in the font. 
(I think changing macOS to correspond to the others here is ok, since it's a 
manual opt-in.)

Some users will see that text layouts get smaller and it might mess up their 
UIs, especially if they were designed with hardcoded sizes. These users can 
easily get back previous behavior by setting the opt-out flags though, so at 
least there is a very fast solution. And hopefully most users will be happy 
that Qt is working according to the spec.

Any comments or thoughts?


--

Eskil Abrahamsen Blomfeldt

Senior Manager, Graphics Engines



The Qt Company

Sandakerveien 116

0484, Oslo, Norway

eskil.abrahamsen-blomfe...@qt.io

+47 938 85 836

http://qt.io



The Future is Written with Qt

--


-- 
Development mailing list
Development@qt-project.org
https://lists.qt-project.org/listinfo/development

Reply via email to