Fontmake is a tool to generate font binaries. Run
fontmake --help to see all the options.
Fontmake makes use of a variety of Python libraries to build TTF fonts from UFO or Glyphs source files:
.glyphsfiles into UFO format;
You don’t have to understand this very well to start working with the tools, but it can come in handy if you have a bug to report, or if you want to understand the relationship between the different libraries. See “What happens when you build a variable font (using the open source tool chain)” for more details.
Unfortunately, Fontmake is not enough to generate fonts that can be onboarded to Google Fonts. Some post-processing is needed to meet GF requirements. The
gftools scripts are an enhanced collection of helpers to do that post-processing.
gftools --help to see the available scripts.
These scripts are extremely useful to batch patch binaries (as well as UFO).
You can use for example
gftools gen-stat to easily patch a
STAT table to your variable font:
gftools gen-stat path/to/*.ttf --src stat.yaml --in-place
--inplace would be to override the font files,
--src would be to use an external
yaml file with axis values instructions, for example:
# stat.yaml - name: Width tag: wdth values: - name: Condensed value: 75 - name: Normal value: 100 - name: Weight tag: wght values: - name: Regular value: 400 linkedValue: 700 flags: 2 - name: Bold value: 700
If you need to patch a different STAT table on separated fonts of the same family—for example in the case of Italic—you can add file name informations, such as:
# stat.yaml Fontname[wght].ttf: - name: Weight tag: wght values: - name: Regular value: 400 flags: 2 - name: Italic tag: ital - name: Regular value: 0 linkedValue: 1 flags: 2 Fontname-Italic[wght].ttf: - name: Weight tag: wght values: - name: Regular value: 400 - name: Italic tag: ital - name: Italic value: 1
Google Fonts has a policy of building all exports in one step to simplify the font generation process. To generate the font with Fontmake, and then post-process the binaries with some
gftools scripts, users often created a bash shell script.
Example: Public Sans
As you can see in the example, these build scripts were extremely long and redundant. That is why
gftools builder was created.
gftools builder is a command line tool that wraps Fontmake to generate efficiently several font formats in one command, as well as several
gftools fix-* and
gftools gen-stat scripts to post-process the generated fonts following Google Fonts’ specifications.
gftools builder --help to see all the options.
The Builder can take source files (
.designspace) as direct argument.
You can do that if:
gftools builder FontName.glyphs FontName-italic.glyphs
This will generate Static
Variable TTF, using the Axis Registry to set up the
yaml with more detailed instruction file is a preferred option to have more control over the outcome. Once this “config” file set up, you would just have to run, for example:
gftools builder config.yaml
For Example: JetBrains Mono
# config.yaml sources: - FontName[axis].glyphs - FontName-Italic[axis].glyphs axisOrder: - wght - ital familyName: "Font Name"
GF only needs
TTF fonts, so you can avoid building OTF as well by adding:
→ Note that the
ital axis shouldn’t be in the source files if the Roman is separated for from the Italic. Although, the axis order is here to describe the entire design space of the family, so the
ital should be mentioned to set up properly the style linking between the two files, as well as a complete
For example: Texturina, Montserrat, Roboto Serif.
If there is a non-registered axis or there is an Optical Size axis, you would have to detail the STAT table informations because, in that case, the Axis Registry can’t be used:
sources: - FontName[opsz,wght].glyphs - FontName-Italic[opsz,wght].glyphs axisOrder: - opsz - wght - ital FamilyName: "Font Name" stat: FontName[opsz,wght].ttf: - name: Optical size tag: opsz values: - name: 12pt value: 12 - ... - name: Weight tag: wght values: - name: Regular value: 400 linkedValue: 700 flags: 2 - ... - name: Bold value: 700 - name: Italic tag: ital values: - name: Roman value: 0 linkedValue: 1 flags: 2 FontName-Italic[opsz,wght].ttf: - name: Optical size tag: opsz values: - name: 12pt value: 12 - ... - name: Weight tag: wght values: - name: Regular value: 400 linkedValue: 700 flags: 2 - ... - name: Bold value: 700 - name: Italic tag: ital values: - name: Italic value: 1
If you want a STAT table format 2 (min and max ranges) your axis value should look like this:
stat: - name: Width tag: wdth values: - name: Condensed rangeMinValue: 40 nominalValue: 50 rangeMaxValue: 75 ...
If you want a STAT table format 4 (multi axes) you should add this after defining the axes, at the same level as the “normal” stat definition:
stat: … statFormat4: - name: Green location: wght: 300 wdth: 200 - name: Blue location: wght: 400 wdth: 200
If there is a VTT manual hinting program you should add this to this example:
vttSources: FontName[opsz,wght].ttf: VTT/roman-hinting.ttx FontName-Italic[opsz,wght].ttf: VTT/italic-hinting.ttx
If you want to set up static instances, different from the one set up in your
.designspace file or in your
instances: FontName[opsz,wght].ttf: - familyName: "FontName 8pt" styleName: "Regular" coordinates: opsz: 8 wght: 400 - familyName: "FontName 8pt" styleName: "Medium" coordinates: opsz: 8 wght: 500
Unfortunately, the Builder yet can’t do everything. You will have to use a external bash script in these cases:
WOFF. use homebrew webfont tools.
.ufo: the build script should contain a step that converts the sources to UFO. Use Fontlab to UFO or FontForge to UFO for example.