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

🔥 FAILS on Vertical Metrics #7

Closed
vv-monsalve opened this issue Aug 20, 2020 · 15 comments
Closed

🔥 FAILS on Vertical Metrics #7

vv-monsalve opened this issue Aug 20, 2020 · 15 comments

Comments

@vv-monsalve
Copy link
Contributor

vv-monsalve commented Aug 20, 2020

Vertical Metrics of the font are expected to follow this criterion.
winAscent and winDecent set to yMax and yMin (absolute highest and lowest point in the font)

The current values for Castoro are:

  • Highest: Atilde_acutecomb (top y: 1091.0)
  • Lowest: g_dotbelowcomb (bottom y: -430.0)

🔥 FAIL: Checking OS/2 usWinAscent & usWinDescent.
--- Rationale ---

A font's winAscent and winDescent values should be greater than the head
table's yMax, abs(yMin) values. If they are less than these values, clipping
can occur on Windows platforms
(https://github.com/RedHatBrand/Overpass/issues/33).

If the font includes tall/deep writing systems such as Arabic or Devanagari,
the winAscent and winDescent can be greater than the yMax and abs(yMin) to
accommodate vowel marks.

When the win Metrics are significantly greater than the upm, the linespacing
can appear too loose. To counteract this, enabling the OS/2 fsSelection bit 7
(Use_Typo_Metrics), will force Windows to use the OS/2 typo values instead.
This means the font developer can control the linespacing with the typo values,
whilst avoiding clipping by setting the win values to values greater than the
yMax and abs(yMin).


  • 🔥 FAIL OS/2.usWinAscent value should be equal or greater than 1091, but got 950 instead [code: ascent]
  • 🔥 FAIL OS/2.usWinDescent value should be equal or greater than 430, but got 300 instead [code: descent]
🔥 FAIL: Checking OS/2 Metrics match hhea Metrics.
--- Rationale ---

When OS/2 and hhea vertical metrics match, the same linespacing results on
macOS, GNU+Linux and Windows. Unfortunately as of 2018, Google Fonts has
released many fonts with vertical metrics that don't match in this way. When we
fix this issue in these existing families, we will create a visible change in
line/paragraph layout for either Windows or macOS users, which will upset some
of them.

But we have a duty to fix broken stuff, and inconsistent paragraph layout is
unacceptably broken when it is possible to avoid it.

If users complain and prefer the old broken version, they have the freedom to
take care of their own situation.


  • 🔥 FAIL OS/2 sTypoDescender (-245) and hhea descent (-254) must be equal. [code: descender]
@tiroj
Copy link
Contributor

tiroj commented Aug 20, 2020

Does this mean that you are relying on fsSelection bit 7 to always be reliably used to determine linespacing? And hence that the OS/2 win metrics can be allowed to change relative to font updates including new taller glyphs?

Since we want the fonts to be reliably used in environments other than Google Fonts services, I am wary about tying the win metrics to yMax and yMin, because that will introduce incompatible linespacing in many environments, and future updates would break backwards compatibility further.

@vv-monsalve
Copy link
Contributor Author

Does this mean that you are relying on fsSelection bit 7 to always be reliably used to determine linespacing? And hence that the OS/2 win metrics can be allowed to change relative to font updates including new taller glyphs?

Yes, it is the main idea.

Since we want the fonts to be reliably used in environments other than Google Fonts services, I am wary about tying the win metrics to yMax and yMin, because that will introduce incompatible linespacing in many environments, and future updates would break backwards compatibility further.

In a general sense, this approach implies to release the notion that sTypoAscender - sTypoDescender should be equal to unitsPerEm.

Marc said in a previous issue, "When I had linegaps, the accents on the first line of text would often get clipped in primitive editors. It would've been more beneficial to include the linegap values in the ascenders to stop this from happening."

This way, the TypoAscencer and TypoDescender numbers could be higher than the design values adding at least the Linegap value either directly to the ascender, as Marc suggested, or distributing it between Ascender and Descender values (depending on what is desired). Taking care of them not being higher than ~130% of UPM, and avoiding a high difference between the Typo and Win total values.

Dave has also said that for Google Fonts doesn't distinguish between desktop and web builds, but when a trade-off is required, what is best for the web is what is done.

However, I'm very curious about which environments do you refer and the reasoning on backward compatibility when you say "that will introduce incompatible linespacing in many environments, and future updates would break backwards compatibility further"

@vv-monsalve
Copy link
Contributor Author

This is Castoro with current vertical metrics
typoAscender: 755
typoDescender: -245
typoLine Gap: 250

Castoro-01


This is a version of the font using:
typoAscender: 950
typoDescender: -300
typoLine Gap: 0

Castoro-02


This is a version of the font with the Win values to preview the difference in linespacing between platforms

Castoro-03


A comparative gif between the three of them

Castoro-comparisson

@tiroj
Copy link
Contributor

tiroj commented Aug 20, 2020

Significant amounts of Windows software still uses the OS/2 win metrics for linespacing, due to implementation errors that date back to the 1980s. In 2004, we worked with Microsoft to define the fsSelection bit 7 mechanism that was supposed to indicate to software that the OS/2 typo metrics should be used for linespacing instead of the win metrics. [This was deemed the only safe way to introduce the change, because too many existing fonts had bad metrics data, and just switching to using typo metrics would have broken existing documents. The fsSelection mechanism provided a novel way for font makers to indicate that the typo values were reliable.] One of the reasons that Microsoft needed a solution at that time was to properly handle the Cambria Math font that we build for them, which required immense win metrics values to accommodate the tallest glyphs in the font without clipping; Microsoft needed a way to tell software to use the Cambria Math typo metrics for default linespacing instead of the win metrics. This meant that for Cambria Math and other fonts with abnormally tall glyphs (e.g. Aldhabi, STIX Two Math) we couldn't use Microsoft's recommended best practice of summing the typoAscender and typoDescender to the em height, handling leading in the typoLinegap, and summing the win metrics to equal the total height of the typo metrics. But that recommendation has still provided the best backwards compatibility, when appropriate, between software that uses the win metrics, that uses the typo metrics, that respects the fsSelection bit 7 setting, that doesn't respect the fsSelection bit 7 setting.

So my approach to setting vertical metrics is

a) set typo metrics to incorporate the body height in the typoAscender and typoDescender, then set typoLinegap to an appropriate leading for the primary script of the font*

b) if the tallest and deepest glyphs in the font (yMax and yMin) are shorter than the sum of the typo metrics, then match the win metrics to the sum of the typo metrics

c) if the tallest or deepest glyphs in the font are taller than the sum of the typo metrics, then set the win metrics to equal yMax and yMin, and ensure that fsSelection bit 7 is set.

Then there's the hhea metrics. I always used to set these to be directly equivalent to the corresponding OS/2 typo metrics. Then a few years ago Dave told me that Google's recommendation, based on how first-line from top of text frame distances were being handled in various places, was to make the hhea Ascender and Descender equal to corresponding OS/2 win metrics, and set the hhea LineGap to zero.

And this is the real problem: best practice recommendations keep changing, different companies institute different best practice recommendations, linespacing and text frame spacing on the Web is still in flux**, and every change in recommendations spawns more different ways of making fonts and more incompatible data across thousands of fonts that cannot be relied upon except in specific environments. I've been playing that game for too long to assume that what Google recommends now is what Google will recommend next year. So I'm not really keen to change the way I make fonts based on the current state of some environments.

  • I've been pushing for script and language system specific metrics in the BASE table for years. There's general support for the idea among stakeholders, but its stuck in spec limbo like other OT improvements. Using the method described here, in effect only the typoLinegap would ever need to be adjusted for different scripts and languages, much like one only needs to adjust leading in a page layout program.

** https://medium.com/microsoft-design/leading-trim-the-future-of-digital-typesetting-d082d84b202

@tiroj
Copy link
Contributor

tiroj commented Aug 20, 2020

Of course, I can totally meet Google's technical requirement to match OS/2 winAscent and winDescent to yMax and yMin. That's what the magic glyph is for.😁

@vv-monsalve
Copy link
Contributor Author

Thanks for all your elaboration on this. I understand your reasoning and concerns about the variability of recommendation through the years.

I always used to set these to be directly equivalent to the corresponding OS/2 typo metrics. Then a few years ago Dave told me that Google's recommendation, based on how first-line from top of text frame distances were being handled in various places, was to make the hhea Ascender and Descender equal to corresponding OS/2 win metrics, and set the hhea LineGap to zero.

I think it would be better to have @davelab6 or @m4rc1e thoughts on this.

@davelab6
Copy link
Contributor

I defer to Marc

@m4rc1e
Copy link

m4rc1e commented Aug 21, 2020

So my approach to setting vertical metrics is

a) set typo metrics to incorporate the body height in the typoAscender and typoDescender, then set typoLinegap to an appropriate leading for the primary script of the font*

b) if the tallest and deepest glyphs in the font (yMax and yMin) are shorter than the sum of the typo metrics, then match the win metrics to the sum of the typo metrics

c) if the tallest or deepest glyphs in the font are taller than the sum of the typo metrics, then set the win metrics to equal yMax and yMin, and ensure that fsSelection bit 7 is set.

This is pretty much what we do, except we don't set the hhea and typo linegaps, we just include the linegap dist in the ascenders. Tbh, I don't mind if you add linegaps. As long as the typo and hhea metrics are the same, win is set to yMin, yMax and fsSelection bit 7 is enabled, we're good.

@tiroj
Copy link
Contributor

tiroj commented Aug 21, 2020

For backwards compatibility with Windows apps that don’t respect fsSelection bit 7, I'm going to force the yMin to be the same in both roman and italic fonts, so at least those don't get inconsistent linespacing in those environments.

[PS. ignore some earlier comments in this thread; I hadn't taken into account some of the diacritics that overshot the win metrics of the original input design for this family.]

@vv-monsalve
Copy link
Contributor Author

vv-monsalve commented Aug 25, 2020

After pulling the latest sources on 9b93fe8, new fonts were built and tested. The Fail about OS/2 metrics mismatching hhea is still reported. For both Regular and Italic.

🔥 FAIL: Checking OS/2 Metrics match hhea Metrics.
--- Rationale ---

When OS/2 and hhea vertical metrics match, the same linespacing results on
macOS, GNU+Linux and Windows. Unfortunately as of 2018, Google Fonts has
released many fonts with vertical metrics that don't match in this way. When we
fix this issue in these existing families, we will create a visible change in
line/paragraph layout for either Windows or macOS users, which will upset some
of them.

But we have a duty to fix broken stuff, and inconsistent paragraph layout is
unacceptably broken when it is possible to avoid it.

If users complain and prefer the old broken version, they have the freedom to
take care of their own situation.


  • 🔥 FAIL OS/2 sTypoDescender (-245) and hhea descent (-254) must be equal. [code: descender]

@tiroj
Copy link
Contributor

tiroj commented Aug 25, 2020

FontLab 7 provides a single unified dialogue for setting vertical metrics which a) unhelpfully tries to be helpful in using descriptive terms that do not match the table data, and b) doesn't expose how it is actually going to write the data to multiple tables (of in UFO data in this case).

Screenshot 2020-08-25 at 4 38 57 PM

It looks like FL7 is incorrectly writing the hhea descender value to the UFO:

  <key>openTypeHheaAscender</key>
  <integer>755</integer>
  <key>openTypeHheaCaretOffset</key>
  <integer>-0</integer>
  <key>openTypeHheaDescender</key>
  <integer>-254</integer>
  <key>openTypeHheaLineGap</key>
  <integer>250</integer>

I'll report this as as bug to FontLab. For the time being, I can manually edit the UFO fontinfo.plsit file, but obviously the goal should be to generate the UFO from FL7 without needing to do any editing of the UFO prior to running the build script.

@tiroj
Copy link
Contributor

tiroj commented Aug 25, 2020

@vv-monsalve
Copy link
Contributor Author

It seems it can be modified here

Screen Shot 2020-08-25 at 19 07 36


After that, it is reported ok here
Screen Shot 2020-08-25 at 19 08 20

@tiroj
Copy link
Contributor

tiroj commented Aug 26, 2020

Ah, good find, thanks.

@tiroj
Copy link
Contributor

tiroj commented Aug 27, 2020

Fixed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants