Component referring to another component (nested) are not exported correctly for ttf variable format. They take back the coordinates of the original glyph.


There should be a check to find any nested components.
I used Public Sans at commit https://github.com/uswds/public-sans/commit/0a09945b70a28abe75629abbb820c9313cf5ac45
But you can reproduce it with any font which have nested components (typically ohorn/uhorn with another accent)
This may be a more severe issue than just something messing up Samsa.
At https://github.com/arrowtype/recursive/issues/412, I have described issues that occur when printing static TTFs with many printers. In summary: PostScript-based printers really mess up nested components in TTF fonts. This includes even high-end setups used for offset printing. One example of where things go wrong in current Recursive TTFs:

(There are more examples in the issue.)
There are two possible culprits:
Worse, printers that have PostScript installed apparently never update that software.
So, this check plus a script that un-nests components are probably relatively high-priority, if Google Fonts wants to give people any confidence in using the library for more than just web design. Not _all_ of the alignment problems with TTFs & PostScript would be solved by this – it also messes up the positioning of glyph substituted via stylistic sets – but it seems that it would solve the majority of them.
There's a ufo2ft filter to unnest composites automatically. Insert the following into your UFO's lib.plist:
<key>com.github.googlei18n.ufo2ft.filters</key>
<array>
<dict>
<key>name</key>
<string>flattenComponents</string>
<key>pre</key>
<integer>1</integer>
</dict>
</array>
@madig THANK YOU, this is amazing news!
It's actually been in there for decades, but we don't have time to write docs so all the filters are secret.
quite depressing that in 2020 we can't still have nested glyf components
It's actually been in there for decades, but we don't have time to write docs so all the filters are secret.
I could be a good start to just drop some general lines about the existence of this mechanism and where to find the available filters and how to generally access and configure them.
I started something at https://github.com/googlefonts/ufo2ft/pull/286 last century but died before I could finish the job.
The stems of all .py files in https://github.com/googlefonts/ufo2ft/tree/master/Lib/ufo2ft/filters can be used as filters.
@madig: Would it be worth making FlattenComponents the default instead of DecomposeComponents?
Where?
ufo2ft
Where in ufo2ft? No idea what you're talking about.
He means as default filter in the ufo2ft.preProcessor. I would rather not do that. We can make it easier for users to specify that, if a custom filter in the lib.plist is too obscure. E.g. we can add a new option to ufo2ft.compileTTF function and even add a CLI flag to fontmake. But changing the default is not a good idea. There may be legitimate use-cases that may prefer to keep the current beaviour that allows for nested components.
Should we add a --filters argument to fontmake instead or additionally?
Can’t we just have a single option which does this?
If we aren’t prepared to make creating non-broken fonts the default, we should at least make it as easy as possible.
Technically, _the fonts_ aren't broken 😬
Can’t we just have a single option which does this?
What I’m suggesting as an alternative or as an additional option is to have a --filter argument to fontmake that works like --feature-writer does.
So one could do:
fontmake -m DS.designspace --filter flattenComponents
This would also work for propagateAnchors, decomposeTransformedComponents, or any custom filter.
Note to others here (and maybe this should be included in the check rationale, etc):
At least for Recursive (and another project, Name Sans) it is essential to not only flatten components but to first _also_ decompose transformed components. Otherwise, accents like the caron (which is a 180° rotated circumflex) get really misaligned.
In a lib.plist, that looks like this:
<key>com.github.googlei18n.ufo2ft.filters</key>
<array>
<dict>
<key>name</key>
<string>decomposeTransformedComponents</string>
<key>pre</key>
<integer>1</integer>
</dict>
<dict>
<key>name</key>
<string>flattenComponents</string>
<key>pre</key>
<integer>1</integer>
</dict>
</array>
See https://github.com/arrowtype/recursive/issues/412 for details.
Most helpful comment
There's a ufo2ft filter to unnest composites automatically. Insert the following into your UFO's lib.plist: