googlefonts / nanoemoji

A wee tool to build color fonts.
Apache License 2.0
231 stars 17 forks source link

colr_to_svg: Support Format 5 (PaintVarLinearGradient) #426

Open m4rc1e opened 1 year ago

m4rc1e commented 1 year ago

Just tried running the maximum_color tool on Foldit and got the following traceback:

Traceback (most recent call last):
  File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/runpy.py", line 196, in _run_module_as_main
    return _run_code(code, main_globals, None,
  File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/runpy.py", line 86, in _run_code
    exec(code, run_globals)
  File "/Users/marcfoley/Type/nanoemoji/src/nanoemoji/generate_svgs_from_colr.py", line 63, in <module>
    app.run(main)
  File "/Users/marcfoley/Type/tools/venv/lib/python3.10/site-packages/absl/app.py", line 312, in run
    _run_main(main, args)
  File "/Users/marcfoley/Type/tools/venv/lib/python3.10/site-packages/absl/app.py", line 258, in _run_main
    sys.exit(main(argv))
  File "/Users/marcfoley/Type/nanoemoji/src/nanoemoji/generate_svgs_from_colr.py", line 54, in main
    for glyph_name, svg in colr_to_svg(lambda gn: _view_box(font, gn), font).items():
  File "/Users/marcfoley/Type/nanoemoji/src/nanoemoji/colr_to_svg.py", line 428, in colr_to_svg
    svgs = _colr_v1_to_svgs(view_box_callback, ttfont)
  File "/Users/marcfoley/Type/nanoemoji/src/nanoemoji/colr_to_svg.py", line 403, in _colr_v1_to_svgs
    return {
  File "/Users/marcfoley/Type/nanoemoji/src/nanoemoji/colr_to_svg.py", line 406, in <dictcomp>
    _colr_v1_glyph_to_svg(ttfont, glyph_set, view_box_callback, g)
  File "/Users/marcfoley/Type/nanoemoji/src/nanoemoji/colr_to_svg.py", line 363, in _colr_v1_glyph_to_svg
    _colr_v1_paint_to_svg(
  File "/Users/marcfoley/Type/nanoemoji/src/nanoemoji/colr_to_svg.py", line 283, in _colr_v1_paint_to_svg
    descend(parent_el, child_paint)
  File "/Users/marcfoley/Type/nanoemoji/src/nanoemoji/colr_to_svg.py", line 244, in descend
    _colr_v1_paint_to_svg(
  File "/Users/marcfoley/Type/nanoemoji/src/nanoemoji/colr_to_svg.py", line 269, in _colr_v1_paint_to_svg
    descend(svg_path, ot_paint.Paint)
  File "/Users/marcfoley/Type/nanoemoji/src/nanoemoji/colr_to_svg.py", line 244, in descend
    _colr_v1_paint_to_svg(
  File "/Users/marcfoley/Type/nanoemoji/src/nanoemoji/colr_to_svg.py", line 324, in _colr_v1_paint_to_svg
    raise NotImplementedError(ot_paint.Format)
NotImplementedError: 5

I wouldn't mind digging into this deeper since it'll probably improve my colr table knowldge which is very lacking atm.

btw, Foldit doesn't work in the latest Chrome yet (probably due to unsupported formats) but we'll make a pr and block it for the time being.

anthrotype commented 1 year ago

format 5 is PaintVarLinearGradient. OT-SVG does not support variations whatsoever, so converting a variable COLRv1 font to SVG won't work. We should provide a better error message perhaps.

For the same reason, a variable COLRv1 font like FoldIt doesn't work on latest stable Chrome. But it should work on Chrome Canary if you enable the experimental flag chrome://flags/#variable-colrv1

m4rc1e commented 1 year ago

Thanks Cosimo!

So running maximum_color won't work on colr v1 fonts which are variable? if that's the case, we'll need to amend our FB check so it skips VFs.

anthrotype commented 1 year ago

won't work on COLRv1 fonts that are variable in the COLR table itself. Nabla, for example, only varies in the outlines (gvar) but the COLR is static

m4rc1e commented 1 year ago

Understood. @felipesanches your latest fontbakery check https://github.com/googlefonts/fontbakery/pull/3887 doesn't take this issue into consideration.

anthrotype commented 1 year ago

but even in the case of a variable COLRv0 (CairoPlay) or COLRv1 with variable outlines but static COLR table (Nabla), running maximum_color will only add a non-variable SVG table (because SVG can't do OT variations). So you'll only see the default outlines in there. Arguably, the resulting VF with hybrid CORL+SVG is kind of broken if it contains variations, say, in the glyph metrics for example, and you variate those at runtime, the SVG outlines will stay static, but the rest of the variable tables will variate: e.g. the metrics of a Bold, with the SVG outlines of a Regular...

I believe (I hope) we currently subset away all the variation data when we serve these fonts to browsers that only understand OT-SVG but not COLR /cc @rsheeter

anthrotype commented 1 year ago

one thing maximum_color could do is, when it finds PaintVar* tables, it treats them as their static counterparts, basically ignoring all the deltas and taking only the default instance's values, perhaps with a warning to the user who may not be aware of the lack of variations in OT-SVG (but I wouldn't want to flood the console with too many warnings, perhaps only one if the COLR.VarStore is non empty).

rsheeter commented 1 year ago

+1 to treat them as their static counterpart; it's not perfect but it's far more likely to be useful than kerploding.

I believe (I hope) we currently subset away all the variation data when we serve these fonts to browsers that only understand OT-SVG but not COLR

We do not. The default request for a family is for a static instance, but if you ask for variation to be included we'll merrily do it.