otlLib: Routines for working with OpenType Layout

The fontTools.otlLib library provides routines to help you create the subtables and other data structures you need when you are editing a font’s GSUB and GPOS tables: substitution and positioning rules, anchors, lookups, coverage tables and so on.

High-level OpenType Layout Lookup Builders

Common OpenType Layout Data Structures

Low-level GSUB Table Lookup Builders

These functions deal with the “simple” lookup types. See above for classes to help build more complex lookups (contextual and chaining lookups).

GPOS Shared Table Builders

The functions help build the GPOS shared tables as defined in the OpenType spec: value records, anchors, mark arrays and mark record tables.

fontTools.otlLib.builder.buildComponentRecord(anchors)[source]

[otTables.Anchor, otTables.Anchor, …] –> otTables.ComponentRecord

fontTools.otlLib.builder.buildDevice(deltas)[source]

{8:+1, 10:-3, …} –> otTables.Device

fontTools.otlLib.builder.buildMarkArray(marks, glyphMap)[source]

{“acute”: (markClass, otTables.Anchor)} –> otTables.MarkArray

fontTools.otlLib.builder.buildMarkArray(marks, glyphMap)[source]

{“acute”: (markClass, otTables.Anchor)} –> otTables.MarkArray

Low-level GPOS Table Lookup Builders

These functions deal with the “simple” lookup types. See above for classes to help build more complex lookups (contextual and chaining lookups).

fontTools.otlLib.builder.buildCursivePosSubtable(attach, glyphMap)[source]

{“alef”: (entry, exit)} –> otTables.CursivePos

fontTools.otlLib.builder.buildMarkBasePos(marks, bases, glyphMap)[source]

Build a list of MarkBasePos subtables.

a1, a2, a3, a4, a5 = buildAnchor(500, 100), … marks = {“acute”: (0, a1), “grave”: (0, a1), “cedilla”: (1, a2)} bases = {“a”: {0: a3, 1: a5}, “b”: {0: a4, 1: a5}}

fontTools.otlLib.builder.buildMarkBasePosSubtable(marks, bases, glyphMap)[source]

Build a single MarkBasePos subtable.

a1, a2, a3, a4, a5 = buildAnchor(500, 100), … marks = {“acute”: (0, a1), “grave”: (0, a1), “cedilla”: (1, a2)} bases = {“a”: {0: a3, 1: a5}, “b”: {0: a4, 1: a5}}

fontTools.otlLib.builder.buildMarkLigPos(marks, ligs, glyphMap)[source]

Build a list of MarkLigPos subtables.

a1, a2, a3, a4, a5 = buildAnchor(500, 100), … marks = {“acute”: (0, a1), “grave”: (0, a1), “cedilla”: (1, a2)} ligs = {“f_i”: [{0: a3, 1: a5}, {0: a4, 1: a5}], “c_t”: [{…}, {…}]}

fontTools.otlLib.builder.buildMarkLigPosSubtable(marks, ligs, glyphMap)[source]

Build a single MarkLigPos subtable.

a1, a2, a3, a4, a5 = buildAnchor(500, 100), … marks = {“acute”: (0, a1), “grave”: (0, a1), “cedilla”: (1, a2)} ligs = {“f_i”: [{0: a3, 1: a5}, {0: a4, 1: a5}], “c_t”: [{…}, {…}]}

fontTools.otlLib.builder.buildSinglePos(mapping, glyphMap)[source]

{“glyph”: ValueRecord} –> [otTables.SinglePos*]

fontTools.otlLib.builder.buildSinglePosSubtable(values, glyphMap)[source]

{glyphName: otBase.ValueRecord} –> otTables.SinglePos

GDEF Table Subtable Builders

These functions build subtables for elements of the GDEF table.

fontTools.otlLib.builder.buildAttachList(attachPoints, glyphMap)[source]

{“glyphName”: [4, 23]} –> otTables.AttachList, or None

fontTools.otlLib.builder.buildLigCaretList(coords, points, glyphMap)[source]

{“f_f_i”:[300,600]}, {“c_t”:[28]} –> otTables.LigCaretList, or None

fontTools.otlLib.builder.buildMarkGlyphSetsDef(markSets, glyphMap)[source]

[{“acute”,”grave”}, {“caron”,”grave”}] –> otTables.MarkGlyphSetsDef

STAT Table Builder

fontTools.otlLib.builder.buildStatTable(ttFont, axes, locations=None, elidedFallbackName=2)[source]

Add a ‘STAT’ table to ‘ttFont’.

‘axes’ is a list of dictionaries describing axes and their values.

Example:

axes = [
dict(

tag=”wght”, name=”Weight”, ordering=0, # optional values=[

dict(value=100, name=’Thin’), dict(value=300, name=’Light’), dict(value=400, name=’Regular’, flags=0x2), dict(value=900, name=’Black’),

],

)

]

Each axis dict must have ‘tag’ and ‘name’ items. ‘tag’ maps to the ‘AxisTag’ field. ‘name’ can be a name ID (int), a string, or a dictionary containing multilingual names (see the addMultilingualName() name table method), and will translate to the AxisNameID field.

An axis dict may contain an ‘ordering’ item that maps to the AxisOrdering field. If omitted, the order of the axes list is used to calculate AxisOrdering fields.

The axis dict may contain a ‘values’ item, which is a list of dictionaries describing AxisValue records belonging to this axis.

Each value dict must have a ‘name’ item, which can be a name ID (int), a string, or a dictionary containing multilingual names, like the axis name. It translates to the ValueNameID field.

Optionally the value dict can contain a ‘flags’ item. It maps to the AxisValue Flags field, and will be 0 when omitted.

The format of the AxisValue is determined by the remaining contents of the value dictionary:

If the value dict contains a ‘value’ item, an AxisValue record Format 1 is created. If in addition to the ‘value’ item it contains a ‘linkedValue’ item, an AxisValue record Format 3 is built.

If the value dict contains a ‘nominalValue’ item, an AxisValue record Format 2 is built. Optionally it may contain ‘rangeMinValue’ and ‘rangeMaxValue’ items. These map to -Infinity and +Infinity respectively if omitted.

You cannot specify Format 4 AxisValue tables this way, as they are not tied to a single axis, and specify a name for a location that is defined by multiple axes values. Instead, you need to supply the ‘locations’ argument.

The optional ‘locations’ argument specifies AxisValue Format 4 tables. It should be a list of dicts, where each dict has a ‘name’ item, which works just like the value dicts above, an optional ‘flags’ item (defaulting to 0x0), and a ‘location’ dict. A location dict key is an axis tag, and the associated value is the location on the specified axis. They map to the AxisIndex and Value fields of the AxisValueRecord.

Example:

locations = [

dict(name=’Regular ABCD’, location=dict(wght=300, ABCD=100)), dict(name=’Bold ABCD XYZ’, location=dict(wght=600, ABCD=200)),

]

The optional ‘elidedFallbackName’ argument can be a name ID (int), a string, or a dictionary containing multilingual names. It translates to the ElidedFallbackNameID field.

The ‘ttFont’ argument must be a TTFont instance that already has a ‘name’ table. If a ‘STAT’ table already exists, it will be overwritten by the newly created one.