Use hardwired baseline to match MapLibre behavior #20
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
node-fontnik always encoded glyph "top" metrics relative to the typeface's ascender, but it didn't actually tell the client what the ascender/descender was, so there was no way for Mapbox GL (and by extension MapLibre) to know what baseline to use. Mapbox effectively calibrated the baseline for its shaping code on DIN Pro, which has an ascender of 25 at 24pts (the font is proprietary, but you can see stats here).
You can see historical discussion at mapbox/mapbox-gl-js#191
There is a (open-source) PR to node-fontnik to expose the data at mapbox/node-fontnik#160, but it hasn't merged.
Post-fork, Mapbox GL implemented ascender/descender awareness -- I won't link to the PR here to avoid contamination concerns. I was actually a reviewer on the PR but have forgotten most of the details and don't think I should look at the code now. However, I think (??) one of the concerns was that in order to correctly handle verticalizing glyphs (for CJK labels that support vertical alignment) you need to know the actual baseline to know how to do your rotation.
What I haven't figured out is why Mapbox (including me while I was there) never just modified node-fontnik to do the simplest thing imaginable -- just use the "top" metric directly from the font without an ascender modification! My best guess is that we talked a lot about doing it the "right" way (including ascender metadata), but never looked for a fast fix because most of the fonts we used were close enough to the DIN Pro ascender that they looked OK? But honestly I think I may be missing/forgetting something.
At any rate, this PR does that simple thing -- it just returns the glyph's "top" metric, with an offset of 25 to account for the implicit DIN-Pro derived ascender baked into the renderer.
Here's a map before the change -- you can see that Atlas Grotesk on its own isn't properly centered in the collision box, and you can see when it's put next to Noto Sans Arabic, the baselines are way off:
And here's the map with the fonts re-generated using this change:
This change will affect all fonts generated with font-maker, so it would be good to test with a wide range to see if we're getting the better alignment we expect.
@bdon