Skip to main content

A bridge between UFOs and FontTools.

Project description

GitHub Actions status PyPI Version Codecov Join the chat at https://gitter.im/fonttools-dev/ufo2ft

ufo2ft

ufo2ft (“UFO to FontTools”) is a fork of ufo2fdk whose goal is to generate OpenType font binaries from UFOs without the FDK dependency.

The library provides two functions, compileOTF and compileTTF, which work exactly the same way:

from defcon import Font
from ufo2ft import compileOTF
ufo = Font('MyFont-Regular.ufo')
otf = compileOTF(ufo)
otf.save('MyFont-Regular.otf')

In most cases, the behavior of ufo2ft should match that of ufo2fdk, whose documentation is retained further below (and hopefully is still accurate).

Modifying the behavior of ufo2ft

ufo2ft by default tries to do little more than what the UFO specification demands. Popular font design applications that came after the specification was made and specific workflows however may demand more. ufo2ft obeys certain keys in a UFO’s “lib”, i.e. key-value pairs in the UFO’s lib.plist file.

Filters (lib key: com.github.googlei18n.ufo2ft.filters)

Filters can modify glyphs before (“pre” = True) or after (“pre” = False) decomposition of composite glyphs. The default is running filters after decomposition (“pre” = False).

Example

You would insert the following into a UFO’s lib.plist:

<key>com.github.googlei18n.ufo2ft.filters</key>
<array>
    <dict>
        <key>name</key>
        <string>propagateAnchors</key>
        <key>pre</key>
        <true />
        <!-- Optionally, specify a list of glyphs to in- or exclude for
             this filter (the default is to include all glyphs). "include"
             and "exclude" are mutually exclusive. -->
        <key>include</key>
        <array>
            <string>a</string>
            <string>b</string>
        </array>
    </dict>
</array>

Or in code:

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")

Using code allows you to define an inclusion function (not available for exclusion), like so:

from defcon import Font
from ufo2ft import compileOTF

def my_filter_function(glyph):
    """Include all glyphs with a Unicode value between U+007F and U+00FF."""
    if glyph.unicode:
        return 0x007F < glyph.unicode < 0x00FF
    return False

ufo = Font("MyFont-Regular.ufo")
ufo.lib["com.github.googlei18n.ufo2ft.filters"] = [
    {"name": "propagateAnchors", "pre": True, "include": my_filter_function}
]
otf = compileOTF(ufo)
otf.save("MyFont-Regular.otf")
cubicToQuadratic

Converts outlines from cubic (PostScript flavor) to quadratic (TrueType flavor). It is run by default when producing TrueType-flavored OpenType fonts. Honors the UFO’s com.github.googlei18n.cu2qu.curve_type lib key.

<key>com.github.googlei18n.ufo2ft.filters</key>
<array>
    <dict>
        <key>name</key>
        <string>cubicToQuadratic</key>
        <!-- Optionally, the filter can save the result of the conversion
             to the UFO's lib key "com.github.googlei18n.cu2qu.curve_type",
             which can be either "cubic" or "quadratic". Turn this off if
             you want to run the filter multiple times. You can also
             manually set the lib key to "quadratic" if your font is made
             using quadratic curves, which saves you further explicit
             configuration. -->
        <key>rememberCurveType</key>
        <true /> <!-- The default. -->
        <!-- The conversion process is necessarily an approximation. Set
             the acceptable error here, expressed in the maximum distance
             between the original and converted curve, and it's relative
             to the UPM of the font (default: 1/1000 or 0.001) -->
        <key>conversionError</key>
        <real>0.001</real> <!-- The default. -->
        <!-- Cubic (PostScript flavored) curves are typically oriented
             counter-clockwise, quadratic (TrueType flavored) curves are
             typically oriented clockwise. Reversing the direction is
             recommended. -->
        <key>reverseDirection</key>
        <true /> <!-- The default. -->
    </dict>
</array>

When to modify the filter settings:

  • You want fine-grained control over the conversion error.

  • Your font is or some glyphs are drawn using quadratic curves and you want to prevent contour direction reversal.

decomposeComponents

What it does…

Example…

When to use…

When not to use…

flattenComponents

What it does…

Example…

When to use…

When not to use…

propagateAnchors

What it does…

Example…

When to use…

When not to use…

removeOverlaps

What it does…

Example…

When to use…

When not to use…

transformations

What it does…

Example…

When to use…

When not to use…

Naming Data

As with any OpenType compiler, you have to set the font naming data to a particular standard for your naming to be set correctly. In ufo2fdk, you can get away with setting two naming attributes in your font.info object for simple fonts:

  • familyName: The name for your family. For example, “My Garamond”.

  • styleName: The style name for this particular font. For example, “Display Light Italic”

ufo2fdk will create all of the other naming data based on thse two fields. If you want to use the fully automatic naming system, all of the other name attributes should be set to None in your font. However, if you want to override the automated system at any level, you can specify particular naming attributes and ufo2fdk will honor your settings. You don’t have to set all of the attributes, just the ones you don’t want to be automated. For example, in the family “My Garamond” you have eight weights. It would be nice to style map the italics to the romans for each weight. To do this, in the individual romans and italics, you need to set the style mapping data. This is done through the styleMapFamilyName and styleMapStyleName attributes. In each of your roman and italic pairs you would do this:

My Garamond-Light.ufo

  • familyName = “My Garamond”

  • styleName = “Light”

  • styleMapFamilyName = “My Garamond Display Light”

  • styleMapStyleName = “regular”

My Garamond-Light Italic.ufo

  • familyName = “My Garamond”

  • styleName = “Display Light Italic”

  • styleMapFamilyName = “My Garamond Display Light”

  • styleMapStyleName = “italic”

My Garamond-Book.ufo

  • familyName = “My Garamond”

  • styleName = “Book”

  • styleMapFamilyName = “My Garamond Display Book”

  • styleMapStyleName = “regular”

My Garamond-Book Italic.ufo

  • familyName = “My Garamond”

  • styleName = “Display Book Italic”

  • styleMapFamilyName = “My Garamond Display Book”

  • styleMapStyleName = “italic”

etc.

Additionally, if you have defined any naming data, or any data for that matter, in table definitions within your font’s features that data will be honored.

Feature generation

If your font’s features do not contain kerning/mark/mkmk features, ufo2ft will create them based on your font’s kerning/anchor data.

In addition to Adobe OpenType feature files, ufo2ft also supports the MTI/Monotype format. For example, a GPOS table in this format would be stored within the UFO at data/com.github.googlei18n.ufo2ft.mtiFeatures/GPOS.mti.

Fallbacks

Most of the fallbacks have static values. To see what is set for these, look at fontInfoData.py in the source code.

In some cases, the fallback values are dynamically generated from other data in the info object. These are handled internally with functions.

Merging TTX

If the UFO data directory has a com.github.fonttools.ttx folder with TTX files ending with .ttx, these will be merged in the generated font. The index TTX (generated when using using ttx -s) is not required.

Color fonts

ufo2ft supports building COLR and CPAL tables.

If there is com.github.googlei18n.ufo2ft.colorPalettes key in font lib, and com.github.googlei18n.ufo2ft.colorLayerMapping key in the font or in any of the glyphs lib, then ufo2ft will build CPAL table from the color palettes, and COLR table from the color layers.

colorPalettes is a array of palettes, each palette is a array of colors and each color is a array of floats representing RGBA colors. For example:

<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>

colorLayerMapping is a array of color layers, each color layer is a array of layer name and palette color index. It is a per-glyph key, but if present in the font lib then it will be used for all glyphs that lack it. For example:

<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>

With these this key present, ufo2ft will copy the color layers into individual glyphs and setup COLR table.

Alternatively, if the color layers are already separate UFO glyphs, the com.github.googlei18n.ufo2ft.colorLayers font lib key can be used. It uses a table keyed by base glyph, and the value is an array of color layers, each color layer is an array of glyph name and palette color index. For example:

<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>

Setup Notes

If you are installing ufo2ft from source, note that the strict dependency versions in requirements.txt are for testing, see setup.py’s install_requires and extras_requires for more relaxed dependency requirements.

Project details


Release history Release notifications | RSS feed

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

ufo2ft-3.6.8.tar.gz (443.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

ufo2ft-3.6.8-py3-none-any.whl (164.6 kB view details)

Uploaded Python 3

File details

Details for the file ufo2ft-3.6.8.tar.gz.

File metadata

  • Download URL: ufo2ft-3.6.8.tar.gz
  • Upload date:
  • Size: 443.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for ufo2ft-3.6.8.tar.gz
Algorithm Hash digest
SHA256 8946a6f1b645ab026dd0886a779e4f22d9a7a2f370371f79cea4d79281127476
MD5 c463cc36bd1e6afc9210e152850b5de4
BLAKE2b-256 e87163f7d9c84e1498f78279547bbd55513aa4f2a90dec7a9e24e36ce89b6189

See more details on using hashes here.

Provenance

The following attestation bundles were made for ufo2ft-3.6.8.tar.gz:

Publisher: ci.yml on googlefonts/ufo2ft

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file ufo2ft-3.6.8-py3-none-any.whl.

File metadata

  • Download URL: ufo2ft-3.6.8-py3-none-any.whl
  • Upload date:
  • Size: 164.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for ufo2ft-3.6.8-py3-none-any.whl
Algorithm Hash digest
SHA256 e241ba98f5890dcf77ed79fe5890ea5be913b83efeea7e7d0fdf071d3205fdd5
MD5 bbd3ad0f134d318a3e0f340089b18e58
BLAKE2b-256 210eb1b4d4d36042832d71da8391536de62f22dbedf1f883b3deb0acc6dc58ab

See more details on using hashes here.

Provenance

The following attestation bundles were made for ufo2ft-3.6.8-py3-none-any.whl:

Publisher: ci.yml on googlefonts/ufo2ft

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page