googlefonts / googlefonts/fontc
[glyphs] COLRv0 splitting drops color layers of non-default masters
- Dominant language
- Rust
- Stars
- 193
- Forks
- 21
- Avg merge
- 1d 17h
- Merged PRs (30d)
- 65
Description
I found this bug while reviewing fontc-vs-fontmake coverage ahead of 1.0 release.
For a .glyphs source with COLRv0 color layers (the `colorPalette` layer attribute) defined on more than one master, only the default master's layers survive compilation. `split_colrv0_glyph` skips any layer whose `associated_master_id` is not the default master's:
https://github.com/googlefonts/fontc/blob/50287ce7/glyphs2fontir/src/toir.rs#L466-L472
and each of the split glyphs it generates (`A.color0`, `A.color1`, ... for a color glyph `A`) is built from that single layer, re-keyed to the default master id:
https://github.com/googlefonts/fontc/blob/50287ce7/glyphs2fontir/src/toir.rs#L475-L478
Color layers associated with other masters are silently dropped, so in a variable font the COLRv0 layer glyphs are frozen at the default-master geometry instead of interpolating. No warning or error is emitted.
Presumably the original implementation (242e189a, "Produce COLRv0 where possible") was scoped to static COLRv0, since all its test fixtures are single-master.
Intermediate (brace) color layers make it worse: a brace layer carrying a `colorPalette` attribute passes the same filter, so it becomes a spurious extra `.color[i]` split glyph pinned at the brace-location geometry. And since nothing strips it from the original glyph it is also picked up by the regular intermediate-layer path and distorts the base glyph's own gvar.
glyphsLib collects color layers per associated master, so fontmake's layer glyphs do interpolate:
https://github.com/googlefonts/glyphsLib/blob/v6.14.0/Lib/glyphsLib/builder/glyph.py#L294-L315
and since 6.14.0 (googlefonts/glyphsLib#1154) it also attaches brace color layers to the matching color glyph as intermediate sources:
https://github.com/googlefonts/glyphsLib/blob/v6.14.0/Lib/glyphsLib/builder/glyph.py#L33-L107
So this is a silent output divergence from fontmake, not a missing feature.
I have a working local patch but I don't think it will make 1.0 and that's ok, full COLR-parity with fontmake was not in scope for 1.0.
Contributor guide
No contributing guide indexed for this repository
Research direction
Start in glyphs2fontir/src/toir.rs at split_colrv0_glyph and inspect the existing single-master COLRv0 fixtures. Compare the layer handling with the referenced glyphsLib builder implementation. Done means non-default master and brace color layers are preserved and interpolate correctly without distorting the base glyph, with no silent layer loss.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- compilers
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 55/100