Repository navigation
Conversation
- Compose each base + combining-mark cluster into the font's precomposed glyph via font-aware NFC before GSUB, matching HarfBuzz: decomposed input (i + U+0300, or Arabic alef + fathatan + hamza-above) shapes to the precomposed glyph instead of separate marks - Only apply the result when it changes the glyph count (composition or its decompose fallback); leave pure canonical reordering alone so it can't disturb downstream GSUB (e.g. Arabic shadda + vowel calt) - Decompose back any composed codepoint the font has no glyph for, so its marks stay available for GPOS mark positioning - Scope to the default shaper and the Arabic/Hebrew/Thai shapers that inherit it; Indic/Hangul/Universal keep their own composition - Add 6 canonical-composition shaping tests (FiraSans Latin, Amiri Arabic incl. the reorder regression)
ba42df6 to
01044a2
Compare
|
I reviewed with Astra and suggested some things. Please look at #403 (seems i cannot update this PR because it was open when i was not a maintainer) |
|
Thanks, looks good to me, and thanks for catching the missing glyph sync without GSUB. Closing this in favor of #403. One thing for later: clusters that don't compose keep their typed mark order (e.g. |
This behavior is observed on the wild or is just hypothetical? Having use case with actual fonts increases the chance of accepting the changes |
|
It's observed in real text: vocalized Arabic is often typed with the vowel before shadda. With Amiri, Allah typed as alef, lam, lam, fatha, shadda, heh: HarfBuzz reorders shadda first and gets the Allah ligature and the small fatha ( |
Problem
HarfBuzz normalizes each base + combining-mark cluster before GSUB/GPOS: the marks are reordered by combining class and composed onto the base when the font has a precomposed glyph. The default shaper does no such step, so decomposed input shapes as separate glyphs instead of the precomposed glyph HarfBuzz and browsers produce — e.g.
"i"+ U+0300 →[i, gravecomb]instead of[igrave]; Arabic alef + fathatan + hamza-above → three glyphs instead of[alef-with-hamza, fathatan](the hamza composes onto the alef across the lower-class fathatan).Fix
Apply font-aware NFC per cluster at the start of the default shaper's feature assignment, before GSUB:
normalize('NFC'), but only when the font has a glyph for the precomposed codepoint; otherwise leave the marks decomposed for GPOS mark positioning.calt).Scoped to the default shaper and the Arabic/Hebrew/Thai shapers that inherit its
assignFeatures; the Indic/Hangul/Universal shapers keep their own composition.Tests
Adds 6 shaping tests (FiraSans Latin + Amiri Arabic), including a regression test that a non-composing mark cluster is left unreordered.