googlefonts / nanoemoji

A wee tool to build color fonts.
Apache License 2.0
239 stars 19 forks source link

[maximum_color] colored .notdef produces invalid glyph order/cmap when COLR=>SVG #427

Closed anthrotype closed 2 years ago

anthrotype commented 2 years ago

The BungeeSpice font has a colored .notdef glyph. When running maximum_color COLR=>SVG, we reorder glyphs such that color glyphs that share some shapes are placed in continuous ranges so we can use a single SVG document for each reuse group. We place all non-color glyphs at the front of the glyph order, followed by the contiguous color glyph ranges from the reuse groups. Now, in this particular case this means that "space" (a non-color, since it's empty) gets shifted to the first glyph ID (0), and the colored .notdef is now in second position. This creates problems for cmap subtables which implicitly interpret gid0 to be the .notdef glyph. Effectively, the SPACE character 0x20 is lost and is no longer mapped to the "space" glyph after running through maximum_color on a font such as BungeeSpice that contains a colored .notdef glyph... A font that doesn't contain a mapping for 0x20 SPACE character is undesirable, not just because we borked the original font which did contain one, but more generally because it triggers different fallback behavior across different environments.

The fix is to treat .notdef specially and ensure it does not get shuffled with the rest of the color glyphs when going from COLR=>SVG.