googlefonts / gftools

Misc tools for working with the Google Fonts library
Apache License 2.0
242 stars 71 forks source link

[Builder] instantiateUFO not creating instance UFOs from a designspace, even though FontMake will, if `name` attributes not in DS instances #966

Closed arrowtype closed 3 months ago

arrowtype commented 3 months ago

My immediate issue is solved, and I’m partly making this issue in case others come across it in the future. Also, though, there may be an opportunity for the builder to eliminate this issue entirely, or else to provide a more clear error message, here.

Situation

I have a project using the GF Builder to build a designspace + UFOs into static and variable fonts. It’s a relatively simple setup of two sources, interpolating into four weights (for romans and for italics).

I was having no issue creating variable fonts with a custom recipe. However, I could not get static fonts to build.

I eventually found that the instantiateUFO operation was not creating instance UFOs, for... some reason. However, when I ran the equivalent / reported fontmake command, it would build instance UFOs with no issue. This was baffling, and I tried a bunch of experiments to get things working.

Eventually, I saw in the Builder docs that "instantiateUFO: Creates an interpolated UFO for a given instance_name." I finally realized my problem: my designspace was set up without name attributes for each instance.

That is, my instances started with this:

<instance familyname="Familyname" stylename="Regular" filename="../instance_ufo/Familyname-Regular.ufo" postscriptfontname="Familyname-Regular" stylemapfamilyname="Familyname" stylemapstylename="regular">

...rather than this:

<instance name="Familyname Regular" familyname="Familyname" stylename="Regular" filename="../instance_ufo/Familyname-Regular.ufo" postscriptfontname="Familyname-Regular" stylemapfamilyname="Familyname" stylemapstylename="regular">

They were missing name="Familyname Regular", and I guess instantiateUFO requires that to process the instances.

Possible improvements to the Builder

Just to brainstorm, I think the builder might be eliminate this problem in one of two ways:

  1. If an instance record doesn’t include a name attribute, the builder could compose one, e.g. from the familyname and stylename attributes.
  2. If composing an instance name isn’t feasible, the builder could perhaps include a clearer error message when and why instantiateUFO has failed. Something like, instantiateUFO missing required 'name' attribute in instance "Familyname Regular" would have been super helpful.

The error logs

To make this issue more easily searchable, here’s how the console looked while I was experiencing this issue:

Building "Familyname"...
[1/80] instantiateUfo
fontmake -i  -o ufo -m sources/ufo/FamilynameRoman.designspace --ufo-structure=json --output-dir sources/ufo/instance_ufos
[2/80] instantiateUfo
fontmake -i  -o ufo -m sources/ufo/FamilynameItalic.designspace --ufo-structure=json --output-dir sources/ufo/instance_ufos
[3/80] buildVariable
fontmake --output-path /tmp/tmpw3zr76_b -o variable -m sources/ufo/FamilynameRoman.designspace --filter ... --filter FlattenComponentsFilter --filter DecomposeTransformedComponentsFilter
[4/80] buildTTF
FAILED: /tmp/tmp2ma_vwwn 
/gftools/bin/python -m gftools.builder.jobrunner fontmake --output-path /tmp/tmp2ma_vwwn -o ttf -u sources/ufo/instance_ufos/Familyname-Regular.ufo.json --filter ...  --filter FlattenComponentsFilter --filter DecomposeTransformedComponentsFilter 

Command failed:
fontmake --output-path /tmp/tmp2ma_vwwn -o ttf -u sources/ufo/instance_ufos/Familyname-Regular.ufo.json --filter ... --filter FlattenComponentsFilter --filter DecomposeTransformedComponentsFilter

usage: fontmake [-h] [--version] [-g GLYPHS | -u UFO [UFO ...] | -m
                DESIGNSPACE] [--glyph-data GLYPHDATA] [-o FORMAT [FORMAT ...]]
                [--output-path OUTPUT_PATH | --output-dir OUTPUT_DIR]
                [-i [INSTANCE_NAME]]
                [--variable-fonts [VARIABLE_FONT_FILENAME]] [-M]
                [--family-name FAMILY_NAME] [--round-instances]
                [--designspace-path DESIGNSPACE_PATH]
                [--master-dir MASTER_DIR] [--instance-dir INSTANCE_DIR]
                [--no-write-skipexportglyphs] [--validate-ufo]
                [--check-compatibility | --no-check-compatibility]
                [--expand-features-to-instances]
                [--fea-include-dir FEA_INCLUDE_DIR] [--no-generate-GDEF]
                [--save-ufo-as-zip | --ufo-structure {package,zip,json}]
                [--indent-json] [--keep-overlaps] [--overlaps-backend BACKEND]
                [--keep-direction]
                [--ttf-curves {cu2qu,mixed,keep-quad,keep-cubic}] [-e ERROR]
                [-f] [-a [AUTOHINT]] [-A] [--cff-round-tolerance FLOAT]
                [--optimize-cff OPTIMIZE_CFF]
                [--subroutinizer {compreffor,cffsubr}] [--no-optimize-gvar]
                [--filter CLASS] [--no-auto-use-my-metrics]
                [--drop-implied-oncurves]
                [--interpolate-binary-layout [MASTER_DIR]]
                [--feature-writer CLASS] [--debug-feature-file FILE]
                [--no-variable-features] [--mti-source MTI_SOURCE]
                [--production-names | --no-production-names]
                [--subset | --no-subset] [-s | -S] [--timing]
                [--verbose LEVEL]
                [INPUTS ...]
fontmake: error: sources/ufo/instance_ufos/Familyname-Regular.ufo.json not found

# then, the fontmake error repeats for the other instances

Thanks!

Thanks for reading, and thanks for all your help as I figure out how to be productive with the Builder!

simoncozens commented 3 months ago

Thanks very much for the report and the suggestions; I'll try to implement both of them.

arrowtype commented 3 months ago

Thanks so much, Simon! It was a small thing and obvious in hindsight, but was a bit tricky to find. I appreciate it!