This guide assumes that you have read the basic instructions in README.md.
fontmake has many more options than the basic ones outlined in README.md.
These options customize various elements of the font compilation process, and so
to understand the options, it helps to understand the general outline of the
process by which fontmake creates binary fonts.
Here are the basic operations:
- Convert Glyphs file to
.designspaceand.ufofiles. - Run pre-processing filters. (Convert cubics to quadratics for TTF outlines, decompose mixed glyphs, remove overlaps, etc.)
- Generate explicit feature files. (Turn anchor and kerning information in source file into Adobe feature file syntax, so that it can be compiled into OpenType layout.)
- Create outlines.
- Build OpenType tables.
- Run post-processing filters. (Rename glyphs to production names.)
For most people, the default settings will produce optimal results, but in some situations you may wish to alter the default operation.
-
--no-production-names: By default,fontmakerenames the glyphs in the output binary font file during post-processing based on the value of thepublic.postscriptNameslib key in the UFO file. (In the case of Glyphs source files, conversion to UFO populates this lib key with the production names from the Glyphs file.) Any encoded glyphs without production names are renamed touniXXXXbased on their Unicode code point, unencoded ligature glyphs are renamed based on the production names of their components, and other unencoded glyphs are not renamed. The--no-production-namesflag suppresses all glyph renaming. -
-a/-a "<arguments>": Run ttfautohint on TrueType output binary font files. If any arguments are provided in a quoted string, these are passed to thettfautohintbinary. -
--mti-source <plist>: Instead of generating feature files from the design sources, this takes an external plist file which links masters to Monotype FontDame feature definition files. You may safely ignore this option unless you are compiling Monotype-supplied font sources for the Noto project.
-
--no-write-skipexportglyphs: When converting the Glyphs sources to UFO, all glyphs, even glyphs not set to be exported into the font, are converted to UFO format. Glyphs which are set as unexported are listed in thepublic.skipExportGlyphslib key of the UFO and designspace files. Before this key was standardized by UFO, older versions offontmakewould use a private lib key,com.schriftgestaltung.Glyphs.Exportinstead. If you are managing a workflow which tracks files created by an older version offontmake, you may wish to use this flag to use the older lib key and maintain compatibility with those files. -
--instance-dir <path>: When generating static instances from Glyphs sources with the-iflag,fontmakewrites UFO files representing the instances to theinstance_ufodirectory by default before compiling them to binary. This flag directsfontmaketo write these temporary UFO files to another directory. If you pass the special value{tmp},fontmakeuses a temporary directory which it removes after processing. -
--master-dir <path>: Similarly, this specifies the directory to be used when writing UFO files representing the font masters. -
--designspace-path <path>: When converting the masters to UFO,fontmakealso creates a Designspace file in themaster_ufodirectory. This option specifies the path where the Designspace file should be written. -
--family-name <family name>: When this flag is provided, the masters are given the family name supplied, and only instances containing that family name are exported. For example, you can use this to create multiple optical-size-specific subfamilies from a single Glyphs file;--family-name "MyFont 12pt"will set the family name toMyFont 12ptand only export the instances which containMyFont 12ptin thefamilyNamecustom parameter of the instance definition. -
--subset/--no-subset: By default,fontmakedetermines whether or not to subset an instance based on the presence or absence of "Keep Glyphs" custom parameter on the instance. To turn off subsetting despite the presence of a "Keep Glyphs" custom parameter, use the--no-subsetflag.
-
--keep-overlaps: By default,fontmakeperforms overlap removal on TrueType outlines, except when producing interpolatable or variable fonts. This flag directsfontmaketo skip the overlap removal preprocessing step. -
--overlaps-backend booleanOperations|pathops: Chooses the library for overlap removal. Skia's pathops library is faster but requires an additional library to be installed, and also appears to fail on some glyphs, hence the default is thebooleanOperationslibrary. -
--no-optimize-gvar: When compiling a variable font, the variation information is stored in a table called thegvartable inside the binary. OpenType allows fonts to omit some variations in the outlines if the variation information can be inferred from the surrounding points - for example, points along a line will often change at a rate determined by the average of the variations of their neighbours. Omitting variations for such points makes the font size smaller, sofontmakeperforms this optimization by default: this is called "Interpolation of Untouched Points", or IUP. This flag turns off the IUP optimization. -
--keep-direction: Generally speaking, filled outlines in a TrueType font should have their points arranged in clockwise order and counter outlines should have their points in anti-clockwise order; design tools tend to order contours the other way around, sofontmakereverses the outlines when generating TrueType fonts. This flag keeps the outline direction as specified in the font source. -
--conversion-error ERROR: When TrueType outlines are converted to binary, the curves are converted from cubic Béziers in the design sources to quadratic Bézier splines. However, as this conversion involves a degree reduction, it is not completely accurate, and hence the quadratic curves approximate the cubic originals. This flag controls the maximum permissible error, measured in ems. the default is 0.001, or one unit at 1000upm. Larger values will result in smaller font sizes, particularly for CJK fonts, but at the cost of fidelity to the original curves. -
--no-generate-GDEF: As part of generating explicit feature files,fontmakeuses the glyph categories in the source file to create atable GDEF { ... } GDEF;statement in the generated feature file; this is then compiled into theGDEFtable of the font binaries. However, if the feature file in your source also contains atable GDEFstatement, the font will fail to compile. In this case, you can add the--no-generate-GDEFflag to turn off writing an additionaltable GDEFstatement in the generated feature file.
-
--cff-round-tolerance FLOAT: Controls the way that point coordinates are rounded in the CFF table. The default value of 0.5 rounds points to the nearest integer. Setting this value to 0 disables all coordinate rouding. -
--optimize-cff VALUE: By default, the CFF table is compressed in two ways: in specialization, drawing operations are chosen which most efficiently express the contour. For example, where there is a horizontal line, it is more efficient to use the specializedhlinetodrawing operator instead of the more generallinetooperator, as thelinetooperator takes two parameters (dx dy) anddywill always be zero in the case of horizontal lines, whereashlinetoonly takes adxparameter.
Additionally, there is subroutinization, which places common sequences of operations into subroutines; this is somewhat similar to components, but at a lower level - for example, a stem with a serif which occurs in multiple glyphs might be subroutinized.
This flag controls the degree of compression: 0 disables all optimizations; 1 applies specialization but disables subroutinization; and 2, the default, applies both specialization and subroutinization. You may want this flag if you are debugging CFF tables and want to compare the drawing operators more directly against the source outlines.
--subroutinizer compreffor|cffsubr: The work of CFF subroutinization, as described above, is one of the many things infontmakethat are outsourced to a separate Python library. The two libraries used arecompreffor(the default for CFF1 - indeed, it only supports CFF1) andcffsubr(the default for CFF2). If you want to see whethercffsubrcompresses the font better, you can use this flag to change the library used for subroutinization.
-
-i <instance name>:-iwas introduced in the Basic Usage section for interpolating masters and generating instances. The flag may also be followed by an argument which is a string or regular expression; if this is provided, then only those instances which match the string will be generated. For example,-i "Noto Sans Bold";-i ".* UI Condensed". -
--use-mutatormath: When generating instances from a designspace file, there are (again) two possible Python libraries which perform the interpolation: fontmake's internalinstantiatormodule, andmutatormath.instantiatoris a deliberately minimal implementation which works in most cases, but it does not support extrapolation (instances whose coordinates are placed outside of the range of the masters) or anisotropic locations (axes which have different degrees of variation on the X axis to the Y axis; these are not possible in OpenType variable fonts, but can be used to generate static instances in Fontlab VI and some Robofont extensions). -
-M,--masters-as-instances: This flag causesfontmaketo also create instance binaries for each master defined in the font, even if they are not explicitly exported as instances by default. -
--round-instances: This option rounds glyph outlines when generating instances. (XXX Surely they're rounded to ints when they're written to theglyftable anyway. What does this actually do?) -
--expand-features-to-instances: If any feature files within the design sources containinclude()statements, and these statements contain a relative path, instances may fail to build because they are being compiled in a different directory to the original where the included feature files cannot be found. In that case, you should use this flag to expand all theinclude()statements before the instance is compiled. We know that you shouldn't have to do this by hand, and we will make it the default one day. -
--interpolate-binary-layout <directory>: Whenfontmakegenerates instances, it creates a feature file for each master using feature writers, but it also creates an interpolated feature file using feature writers for static instances. But while feature writers can interpolate kerning and anchor positions, they do not interpolate explicitposstatements given in the source feature files - nor do they interpolate layout rules expressed in MonoType FontDame format. (See the--mti-sourceoption.) In order to perform this interpolation,fontmakeneeds to build the binary master files and interpolate the GPOS tables directly, rather than the textual representation of layout rules. Hence, if you have explicitposstatements in the feature files of your masters and you need these to interpolate in instances, use this flag.
As mentioned in the functional overview, fontmake has two "filtering" passes, a "preprocessing" pass on the UFO files which converts cubics to quadratics for TTF glyphs, removes overlaps, and so on, and a "postprocessing" pass on the output binary files. It is possible to add your own filters into this pipeline to further customize the font building process, and to achieve custom effects similar to Glyphs export filters.
This can be done in two ways: either by writing, manually or automatically, entries into a lib key (com.github.googlei18n.ufo2ft.filters) in the .designspace or UFO file, or on the command line. For example, when converting from Glyphs to UFO, fontmake (via the glyphsLib library) adds the following entry to the UFO lib.plist:
<key>com.github.googlei18n.ufo2ft.filters</key>
<array>
<dict>
<key>name</key>
<string>eraseOpenCorners</string>
<key>namespace</key>
<string>glyphsLib.filters</string>
<key>pre</key>
<true/>
</dict>
</array>This calls the EraseOpenCornersFilter class from the Python module glyphsLib.filters.eraseOpenCorners as part of the pre-processing step, which converts any external open corners in the glyph outlines into plain corners.
Any Python class inheriting from ufo2ft.filters.BaseFilter can be used as a filter, although the namespace must be provided, as in this case. Filters available through the ufo2ft library do not require a namespace key, as this library is the default source of filters. Filters can be further customized through optional arguments, as described below.
To apply filters via a command-line, use the --filter argument with the following syntax: --filter "python.package::ClassName(argument,argument); add the pseudo-argument pre=True to run the filter as a preprocessing step. For example, to use the ufostroker library to apply "noodling" effects to open paths in a source font, use --filter 'ufostroker::StrokeFilter(Width=50,pre=True).
The ufo2ft library provides some default filters described below. Most of the filters are called automatically as part of fontmake's ordinary pipeline, but some can be added manually. The filters are run in the following order:
-
(Any manually added pre-filters are called first.)
-
ExplodeColorLayerGlyphs: Called automatically to create glyphs out of color layers when constructing aCOLRfont withcolorPalettesandcolorLayerMappinglib keys. -
DecomposeComponents: Called automatically when producing OTF outlines, and called on glyphs which have components and outlines when producing TTF binaries. -
FlattenComponents: Called automatically to flatten nested components when the-fflag is passed tofontmake. -
RemoveOverlaps: Called automatically to remove overlaps. -
CubicToQuadratic: Called automatically when producing TTF binaries. -
(Any manually added post-filters are called last.)
Other filters available as part of ufo2ft are:
-
DecomposeTransformedComponents: Decomposes any components which have a non-identity transformation matrix (i.e. which are translated or scaled). For example, auglyph from anncomponent 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 DecomposeTransformedComponentsFilterto thefontmakecommand line. -
PropagateAnchors: Creates additional anchors for composite glyphs based on the anchors of their components. -
SortContours: Sorts the contours based on their bounding box size. Can be added manually to alleviate overlap removal bugs, but must be manually placed in the UFO lib so that it is executed betweenDecomposeComponentsandRemoveOverlaps. -
Transformations: Similar to the Glyphs "Transformations" filter, this allows for outlines to be scaled, translated or transformed on export. For example, to scale down and raise up the glyphs "A" and "B" of a font, add this to the lib file:
<key>com.github.googlei18n.ufo2ft.filters</key>
<array>
<dict>
<key>name</key>
<string>transformations</string>
<key>kwargs</key>
<dict>
<key>OffsetX</key>
<integer>0</integer>
<key>OffsetY</key>
<integer>150</integer>
<key>ScaleX</key>
<integer>75</integer>
<key>ScaleY</key>
<integer>75</integer>
</dict>
<key>include</key>
<array>
<string>A</string>
<string>B</string>
</array>
</dict>
</array>In a similar vein to the filter classes, fontmake allows you to customize the way that kerning and anchor rules in the font sources are turned into explicit rules in the autogenerated feature file. These generated rules are written by classes called feature writers. The feature writers can also be customized with a lib key, com.github.googlei18n.ufo2ft.featureWriters.
For example, all feature writers take the mode option, which takes either the value append or skip. The default is skip, which will skip writing the feature if the feature is already explicitly present in the design sources' features file.
However, note that even in
skipmode, if the existing feature code contains the magic string# Automatic Code, the feature code generated by fontmake will be inserted into the feature file at the location of the comment.
To change this to append for the kern feature writer (i.e. to add generated kerning rules from the kerning table onto the end of the manually supplied kern feature), you would add the following lib key:
<key>com.github.googlei18n.ufo2ft.featureWriters</key>
<array>
<dict>
<key>class</key>
<string>KernFeatureWriter</string>
<key>options</key>
<dict>
<key>mode</key>
<string>append</string>
</dict>
</dict>
</array>There is also a --feature-writer option, analogous to --filters, allowing you to load custom feature writers on the command line. The special value --feature-writer "None" disables all automatic feature generation.
ufo2ft provides three feature writer classes:
-
GdefFeatureWritergenerates thetable GDEF { } GDEF;statement, based on the categories of the glyphs (stored in thepublic.openTypeCategorieslib key of the source font) and ligature caret anchors (anchors starting withcaret_orvcaret_). It has no customizable parameters. It can be disabled with the--no-generate-GDEFflag. -
KernFeatureWritergenerates kerning features (or, for certain complex scripts,distfeatures) based on the kerning information in the design sources. It has two optional parameters in addition tomode:ignoreMarks, which defaults toTrue, will emit anLookupFlag IgnoreMarksin the generatedkernfeature; setting this toFalsewill generate kern rules which do not ignore mark glyphs. Additionally,quantizationcan be set to an integer value to round the kern rules to the nearest multiple of its value, which can help with compressing the tables. -
MarkFeatureWritergeneratesmarkandmkmkfeatures based on the anchor information in the design sources. It has one optional parameter,quantization, which rounds the anchor positions to the nearest multiple of its value, which makes anchors more likely to be shared in theGPOStable, potentially reducing its size at the expense of some fidelity.