googlefonts / ufo2ft

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

trouble running ufo2ft filters (answer: I had a typo... but maybe the docs could improve in this aspect?) #792

Open arrowtype opened 1 year ago

arrowtype commented 1 year ago

I’ve realized what I was doing wrong, but I’m leaving the issue in case someone else has the same issue in the future. An explanation is at the bottom of this comment.

My problem

I’m building fonts from a Glyphs source, but having trouble applying ufo2ft filters.

For example, here’s what I’m getting when I try to add --filter PropagateAnchors.

▶ fontmake -g "Familyname.glyphspackage" -o variable --output-path "variable_ttf/Familyname-Variable.ttf" --filter PropagateAnchors                      
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] [--mti-source MTI_SOURCE] [--production-names | --no-production-names] [--subset | --no-subset] [-s | -S] [--timing]
                [--verbose LEVEL]
                [INPUTS ...]
fontmake: error: Failed to load --filter:
  AttributeError: module 'ufo2ft.filters' has no attribute 'PropagateAnchors'

I’m also having trouble running --filter DecomposeTransformedComponentsFilter, even though I am following the format suggested in USAGE.md:

DecomposeTransformedComponents: Decomposes any components which have a non-identity transformation matrix (i.e. which are translated or scaled). For example, a u glyph from an n component flipped horizontally. Fonts constructed in this way can have rasterizing and hinting errors (see here and here). To fix fonts with these errors, add --filter DecomposeTransformedComponentsFilter to the fontmake command line.

I’m building in a venv, with versions:

FontMake seems to be building without issue, otherwise.

Am I missing something?

One additional question

How can I run multiple filters? Would I add it twice, like --filter DecomposeTransformedComponentsFilter --filter PropagateAnchors, or once, with a comma-separated list, like --filter DecomposeTransformedComponentsFilter,PropagateAnchors, or in some other way?

UPDATE: I figured it out

I was missing something: it isn’t --filter PropagateAnchors, it’s --filter PropagateAnchorsFilter (with the Filter on the end).

Also, yes, using two filters seems to work well like this:

fontmake -g "familyname.glyphs" -o variable --filter DecomposeTransformedComponentsFilter --filter PropagateAnchorsFilter

Possible improvement to docs?

I was trying to use --filter PropagateAnchors because in USAGE.md, the filter is listed as simply PropagateAnchors – with code highlighting, suggesting that it is the literal code expected. However, the actual argument required is PropagateAnchorsFilter, with the repeated word "Filter". Maybe the docs should include this "Filter" with the labels? So, it could be adjusted like this:

- `PropagateAnchors`: Creates additional anchors for composite glyphs based on the anchors of their components.
+ `PropagateAnchorsFilter`: Creates additional anchors for composite glyphs based on the anchors of their components.

Or, perhaps even better, maybe these args could be simplified to also work with the simpler arg: --filter PropagateAnchors? I’m not sure what it would take to make this work, though, and it may not be worth the added lines of code.

Maintainers: feel free to close this if no action seems warranted. I just figured I might suggest possible improvements. Thanks!

anthrotype commented 1 year ago

Hey! thanks, I can see that can be confusing. The USAGE.md docs are correct though, when they mention the --filter CLI flag it says:

To apply filters via a command-line, use the --filter argument with the following syntax: --filter "python.package::ClassName(argument,argument)

note the "ClassName" there. The convention in ufo2ft filters is that the classe names all end with "Filter" (the module names containing those classes do not end with "Filters"). We could add a concrete example to make it clearer.

Maybe we could be more lenient and if we don't find the given class, attempt to find it with the "Filter" suffix appended..

arrowtype commented 1 year ago

Thanks for the reply!

Totally, I get that there is no actual fault or inaccuracy in the docs. I just got confused by not knowing offhand what the exact ufo2ft classnames are. The docs are helpful, but could perhaps be made a little more easy to use if the exact ufo2ft filter class names are listed.

But, right, I can see why that might not make sense, too. Largely, I posted this in case someone else trips on that and goes searching for the answer.

If making the class matching a little more lenient seems sensible, that could be nice.

Do the ufo2ft names include "Filter" when listed in a UFO lib? If not, that may be one reason to make the match a little more lenient.

anthrotype commented 1 year ago

Do the ufo2ft names include "Filter" when listed in a UFO lib? If not, that may be one reason to make the match a little more lenient.

you're right that they do not, and in fact the they are under a "name" key, unlike the feature writers which have a key called "class". A filter name != class name. I think this is because filters were implemented to support Glyphs.app's own filters like "Transformations" etc..

Maybe I'll move this issue over to ufo2ft and so someone can fix this. I don't have time right now, sorry. But thanks again

arrowtype commented 1 year ago

Okay, thanks again for taking the time to talk that through!