googlefonts / ufo2ft

A bridge from UFOs to FontTools objects (and therefore, OTFs and TTFs).
MIT License
152 stars 43 forks source link

Fix issue with sparse masters when .notdef contain cubic curves #772

Closed anthrotype closed 1 year ago

anthrotype commented 1 year ago

I first push a reproducer for the issue I raised in https://github.com/googlefonts/ufo2ft/issues/501#issuecomment-1660173297

and then follow up with a fix.

EDIT:

previously we were copying ".notdef" glyph from the default master when a sparse layer didn't contain one already, but if the notdef contains some cubic curves then our own check fails because the .notdef that we inserted in the sparse masters' OutlineCompiler was not passed through cu2qu... Our intention is to have sparse masters not participate in the interpolation of that particular .notdef glyph so we make it empty (a gid0=.notdef still needs to be there for a valid TTF so we must have it there). Currently the same trick does not work for CFF2 variable fonts (https://github.com/fonttools/fonttools/issues/3233) but those are fine with cubics in .notdef glyph any way.. For now at least

anthrotype commented 1 year ago

as expected, the reproducer fails with:

ValueError: '.notdef' has cubic Bezier curves, but glyphDataFormat=0; either convert to quadratic (convertCubics=True) or use allQuadratic=False so that glyphDataFormat=1.

the sparse master is inheriting a .notdef glyph from the default master, but this contains cubic curves and it's not converted with cu2qu, but inserted in the outlineCompiler as is with all the cubics, leading to the above check failing.

I'd like to fix this by having the .notdef glyph for sparse masters be empty and rely on varLib treat it as missing/not participating, however this currently only works for TrueType-flavored VF builds, not for CFF2 (cf. https://github.com/fonttools/fonttools/issues/3233). Therefore for now I'll only do that for TTF-VFs, since they are the ones directly affected by the above crash (given the requirement to convert cubics to quads for TTFs). For CFF/CFF2, .notdef containing cubic curves works as expected.