Merge TTX files into the generated font
maincom.github.fonttools.ttx containing .ttx files, ufo2ft will automatically merge these files into the generated font. Note that an index TTX (generated via ttx -s) is not required for this process.repository·main·Indexed 41 days ago
https://github.com/googlefonts/ufo2ftA library and bridge between UFOs and FontTools designed to generate OpenType font binaries (OTF/TTF) from UFO files without requiring the FDK dependency. It provides tools for parsing OpenType layout features, compiling layout tables via FeatureCompiler, and extending functionality through custom feature writers and filters.
com.github.fonttools.ttx containing .ttx files, ufo2ft will automatically merge these files into the generated font. Note that an index TTX (generated via ttx -s) is not required for this process.In addition to Adobe OpenType feature files, ufo2ft supports the MTI/Monotype format. A GPOS table in this format should be stored within the UFO at:
data/com.github.googlei18n.ufo2ft.mtiFeatures/GPOS.mti.
You can modify the compilation behavior by adding configuration to the UFO's lib.plist file using the key com.github.googlei18n.ufo2ft.filters.
Filters can be configured with:
name: The name of the filter.pre: A boolean. If True, the filter runs before glyph decomposition. If False (default), it runs after decomposition.include: An array of glyph names to apply the filter to. (Mutually exclusive with exclude).exclude: An array of glyph names to skip. (Mutually exclusive with include).You can also define these filters programmatically by modifying the ufo.lib dictionary.
from defcon import Font
from ufo2ft import compileOTF
ufo = Font("MyFont-Regular.ufo")
ufo.lib["com.github.googlei18n.ufo2ft.filters"] = [
{"name": "propagateAnchors", "pre": True, "include": ["a", "b"]}
]
otf = compileOTF(ufo)
otf.save("MyFont-Regular.otf")To ensure correct OpenType naming, you must set naming attributes in your UFO's fontInfo object.
For simple automatic naming, set familyName and styleName. To allow the compiler to automate other fields, set them to None.
To implement custom style mapping (e.g., mapping italics to romans within a family), use the following attributes:
familyName: The name of the font family.styleName: The specific style of the font.styleMapFamilyName: The target family name for the style map.styleMapStyleName: The target style name for the style map.ufo2ft from source, be aware that the dependency versions listed in requirements.txt are strictly pinned for testing purposes. For general usage, refer to setup.py's install_requires and extras_requires for the actual, more relaxed dependency requirements.ufo2ft supports building COLR and CPAL tables for color fonts using specific UFO font library keys.
If you provide both com.github.googlei18n.ufo2ft.colorPalettes and com.github.googlei18n.ufo2ft.colorLayerMapping, ufo2ft will build the CPAL table from the palettes and the COLR table from the layer mappings.
com.github.googlei18n.ufo2ft.colorPalettes: An array of palettes. Each palette is an array of colors. Each color is an array of four floats representing RGBA.com.github.googlei18n.ufo2ft.colorLayerMapping: An array of color layers. Each layer is an array containing a layer name (string) and a palette color index (integer). This can be defined in the font lib (applying to all glyphs) or per-glyph.If your color layers are already defined as separate UFO glyphs, use the com.github.googlei18n.ufo2ft.colorLayers key. This is a dictionary keyed by the base glyph name. The value is an array of color layers, where each layer is an array containing a glyph name (string) and a palette color index (integer).
<!-- Example colorPalettes XML structure -->
<key>com.github.googlei18n.ufo2ft.colorPalettes</key>
<array>
<array>
<array>
<real>0.26</real>
<real>0.0</real>
<real>0.23</real>
<real>1.0</real>
</array>
<array>
<real>0.86</real>
<real>0.73</real>
<real>0.28</real>
<real>1.0</real>
</array>
</array>
</array>
<!-- Example colorLayerMapping XML structure -->
<key>com.github.googlei18n.ufo2ft.colorLayerMapping</key>
<array>
<array>
<string>color.1</string>
<integer>1</integer>
</array>
<array>
<string>color.2</string>
<integer>0</integer>
</array>
</array>
<!-- Example colorLayers XML structure -->
<key>com.github.googlei18n.ufo2ft.colorLayers</key>
<dict>
<key>alef-ar</key>
<array>
<array>
<string>alef-ar.color0</string>
<integer>2</integer>
</array>
</array>
<key>alefHamzaabove-ar</key>
<array>
<array>
<string>alefHamzaabove-ar.color0</string>
<integer>1</integer>
</array>
<array>
<string>alefHamzaabove-ar.color1</string>
<integer>2</integer>
</array>
</array>
</dict>Use ufo2ft to generate OpenType font binaries from UFO files. The library provides compileOTF and compileTTF functions, which behave identically. You can pass a defcon.Font object to these functions to obtain the compiled font object, which you can then save to disk.
from defcon import Font
from ufo2ft import compileOTF
ufo = Font('MyFont-Regular.ufo')
otf = compileOTF(ufo)
otf.save('MyFont-Regular.otf')To create a custom filter, your class must be compatible with the isValidFilter check. A valid filter class must be a class that implements a __call__ method with one of the following signatures:
For BaseFilter compatibility:
def __call__(self, font, glyphSet=None):
...For BaseIFilter compatibility:
def __call__(self, fonts, glyphSets=None, instantiator=None, **kwargs):
...If you are using the loadFilterFromString method, ensure your class is importable and follows the naming conventions expected by the loader if you are relying on automatic module/class name resolution.
To be compatible with ufo2ft, a custom feature writer class must satisfy these requirements:
type).tableTag attribute (a str) representing the table tag (e.g., "GSUB" or "GPOS").write method with the exact signature:
def write(self, font, feaFile, compiler=None):Classes that meet these criteria can be loaded via loadFeatureWriters or loadFeatureWriterFromString.
The compiler manages several TrueType component flags to ensure correct rendering:
hmtx values. The compiler can set this automatically if no component explicitly defines it, or via the TRUETYPE_METRICS_KEY in the UFO component library.TRUETYPE_OVERLAP_KEY is present and true in the UFO glyph library.TRUETYPE_ROUND_KEY in the UFO component library. By default, it is always set unless explicitly disabled in the UFO.If the info parameter is provided to the PostProcessor constructor, calling process() will trigger apply_fontinfo(). This uses ufo2ft.infoCompiler.InfoCompiler to apply font information from the DesignSpace variable-font's library to the compiled font (e.g., updating OS/2 and post tables).
It attempts to preserve existing usWeightClass, usWidthClass, and italicAngle values unless they are explicitly overridden in the info object.
You can register and load custom feature writers by adding a configuration entry to your UFO library (ufo.lib) using the key com.github.googlei18n.ufo2ft.featureWriters.
Each entry in the list should be a dictionary containing:
class (required): The name of the class to instantiate.module (optional): The full Python module path. Defaults to ufo2ft.featureWriters.options (optional): A dictionary of keyword arguments passed to the class constructor. Defaults to {}.To load these writers, use loadFeatureWriters(ufo, ignoreErrors=True). If the key is missing from the UFO lib, it returns None.
{
"module": "myTools.featureWriters", # default: ufo2ft.featureWriters
"class": "MyKernFeatureWriter", # required
"options": {"doThis": False, "doThat": True},
}