inter
inter copied to clipboard
using fontmake command to build fonts instead of custom fontbuild script?
Hello! thanks for using our open source tools and libraries to build the Inter fonts! :)
I was prompted by https://github.com/rsms/inter/issues/184 to take a look at your build setup, and I noticed that you have a custom fontbuild python script which imports from fontmake, and even sub-classes the fontmake.FontProject class.
So I was wondering, why don't you simply run the fontmake script instead?
Fontmake is primarily (I'd like to say exclusively) a command line tool, it was never designed to be used as a library. It doesn't have a supported programmatic interface, but it's simply the CLI frontend for other libraries (glyphsLib, ufo2ft, fonttools) which actually do the heavy lifting. If you do import it, you are doing it, as they say, "at your own risk".
@madig and I are also making a lot of changes lately and introduced new features (e.g. we introduced a new instantiator module that is meant to replace mutatorMath [which is no longer supported] for generating instance UFOs using fontTools.varLib for the interpolation).
I would recommend that you change your build setup to calling fontmake command directly. If you want to use python to orchestrate the build rather than make or a shell script, you can run fontmake as a subprocress.
If there are any features that are missing and you would like to see exposed from the CLI interface, please let us know!
Hello!
Fontmake is great and as you already spotted, the fontbuild program is based on fontmake.
There are a few things that I needed which either fontmake didn’t support or I couldn’t figure out if it supported:
a. Per-glyph exceptions. A few specific glyphs of Inter requires decomposition and overlap removal to properly work as multi-axis variable fonts. I introduced a directive that can be added to a glyph’s notes, e.g. !post:removeoverlap which the build script looks for to determine if a glyph is subject to exceptions.
b. Font version information is applied at compile time. The font's version changes with every git commit and thus it was infeasible to write that information over and over to the UFO files, especially since the UFO files used to be part of the source code.
c. Font metadata is not always 100% quality from glyphslib and the UFOs it creates. For instance, sometimes it would write italicAngle=-0 which in some cases would cause issues when compared to signed zero IEEE 754 floating point (i.e. 0.0 != -0.0 in all cases.) A few more things like that. Most of this is work-arounds for bugs and shortcomings in various text engines.
d. Automatic minimal glyph decomposition. Since Inter compiles to a VF, I wanted to minimize glyph decomposition since a) it often yields different shapes & points causing VF matching to fail, and b) file size. However, some glyphs makes use of mirroring transformation, which is unsupported (by most text engines? by OTF/TTF in general?); for instance, /q is a mirrored version of /p. In the italic masters, this will yield a /q slanting in the opposite direction, unless q is decomposed (composedGlyphIsNonTrivial is the function used to determine which glyphs needs to be decomposed).
e. One program for simplicity. I wanted one single program for the sake of simplicity, and thus fontbuild accepts a command like glyphsync or compile which performs a logical subtask of the build process (like syncing glyphs and designspace + ufo files, or compiling constant/static font files, respectively.)
It would be amazing if fontmake would support some of these use cases! Maybe it does already :–) I’ve been reading the source code of fontmake and fonttools to learn about their features (I also put up a copy of the fonttools docs here https://rsms.me/fonttools-docs/) But, it’s a lot of source code to read through :–)
So to sum things up, I think it would be really nice to see the following in fontmake:
- Automatic decomposition of glyphs that makes use of complex transforms of components
- A configurable glyph “directive” syntax for applying specific edits to specific glyphs. For instance, decomposition & overlap removal, as in the case of Inter.
- Some way of running a script or something to edit font metadata in memory before it goes into fonttools. E.g. to update version, fixup italicAngle, patch style names, etc.
Thank you so much for reaching out!
All of this sounds like the job for a custom build script that calls stuff directly instead of mutating fontmake. Fontmake is just a layer of glue.
Rough steps:
- Call glyphsLib.to_designspace(Glyphs_file).
- Modify the UFOs as you see fit.
- Call
ufo2ft.compileVariableTTF. - Receive variations.
For Cantarell, I made these scripts:
- https://gitlab.gnome.org/GNOME/cantarell-fonts/blob/respacing/scripts/make-static-fonts.py
- https://gitlab.gnome.org/GNOME/cantarell-fonts/blob/respacing/scripts/make-variable-font.py
Not much manipulation going on in there but you can work with the font objects in-memory.
a. Per-glyph exceptions.
Use ufo2ft's secret undocumented (pre)filters. In a UFO's lib, insert:
<key>com.github.googlei18n.ufo2ft.filters</key>
<array>
<dict>
<key>name</key>
<string>decomposeComponents</key>
<key>include</key>
<array>
<string>someglyphname</string>
<string>anotherglyphname</string>
</array>
</dict>
<dict>
<key>name</key>
<string>removeOverlaps</key>
<key>include</key>
<array>
<string>someglyphname</string>
<string>anotherglyphname</string>
</array>
</dict>
</array>
Since the key is an array, you can construct filter chains. I started documenting them at https://github.com/googlefonts/ufo2ft/pull/286/files and then got distracted by other things. You could also insert them programmatically at build time from a predefined list or something.
A configurable glyph “directive” syntax for applying specific edits to specific glyphs.
Glyphs and UFOs support a glyph lib key for information like this, but I don't know of an easy way in Glyphs' UI to edit it. I suppose scrawling into notes gets the job done, even if it's more or less abusing the feature.
I see. Thanks for explaining @madig! I’ve simplified the fontbuild program to not make use of fontmake anymore. Landed in aa7ad2d7a0e255d4052c4999ec62d88c699586ac
Thanks for the precious feedback, we'll try to incorporate some of those suggested features in the fontmake pipeline.
Note that mutatorMath is kind of deprecated now. We have replaced it with the fontmake.instantiator module which @madig wrote. Unlike mutatorMath, this supports sparse masters and FeatureVariations-stlye glyph substitution rules, and uses fontTools.varLib to compute the instance UFOs' interpolation factors, so you should get an output that's more consistent with the one you would get using the VF (also produced using varLib).