googlefonts / googlefonts/fontc

[glyphs] COLRv0 splitting drops color layers of non-default masters

Open
#2,105 1 comment 0 reactions 0 assignees View on GitHub
bug
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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.