feaLib: Read and write OpenType feature files

Overview

fontTools’ feaLib allows for the creation and parsing of Adobe Font Development Kit for OpenType feature (.fea) files. The syntax of these files is described here.

.fea files are primarily used for writing human-readable definitions for the OpenType features stored in a font’s GSUB and GPOS tables.

Supporting modules

feaLib contains modules for parsing and inspecting .fea files as well as utilities for converting .fea rules into GSUB and GPOS tables and inserting them into fonts.

The fontTools.feaLib.parser.Parser class can be used to parse files into an abstract syntax tree, and from there the fontTools.feaLib.builder.Builder class can add features to an existing font file. You can inspect the parsed syntax tree, walk the tree and do clever things with it, and also generate your own feature files programmatically, by using the classes in the fontTools.feaLib.ast module.

fontTools.feaLib.builder

fontTools.feaLib.builder.addOpenTypeFeatures(font, featurefile, tables=None, debug=False)[source]

Add features from a file to a font. Note that this replaces any features currently present.

Parameters:
  • font (feaLib.ttLib.TTFont) – The font object.

  • featurefile – Either a path or file object (in which case we parse it into an AST), or a pre-parsed AST instance.

  • tables – If passed, restrict the set of affected tables to those in the list.

  • debug – Whether to add source debugging information to the font in the Debg table

fontTools.feaLib.builder.addOpenTypeFeaturesFromString(font, features, filename=None, tables=None, debug=False)[source]

Add features from a string to a font. Note that this replaces any features currently present.

Parameters:
  • font (feaLib.ttLib.TTFont) – The font object.

  • features – A string containing feature code.

  • filename – The directory containing filename is used as the root of relative include() paths; if None is provided, the current directory is assumed.

  • tables – If passed, restrict the set of affected tables to those in the list.

  • debug – Whether to add source debugging information to the font in the Debg table

class fontTools.feaLib.builder.Builder(font, featurefile)[source]

Bases: object

supportedTables = frozenset({'BASE', 'GDEF', 'GPOS', 'GSUB', 'OS/2', 'STAT', 'head', 'hhea', 'name', 'vhea'})
build(tables=None, debug=False)[source]
get_chained_lookup_(location, builder_class)[source]
add_lookup_to_feature_(lookup, feature_name)[source]
get_lookup_(location, builder_class)[source]
build_feature_aalt_()[source]
build_head()[source]
build_hhea()[source]
build_vhea()[source]
get_user_name_id(table)[source]
buildFeatureParams(tag)[source]
build_name()[source]
build_OS_2()[source]
setElidedFallbackName(value, location)[source]
addDesignAxis(designAxis, location)[source]
addAxisValueRecord(axisValueRecord, location)[source]
build_STAT()[source]
build_codepages_(pages)[source]
buildBASE()[source]
buildBASECoord(c)[source]
buildBASEAxis(axis)[source]
buildGDEF()[source]
buildGDEFGlyphClassDef_()[source]
buildGDEFMarkAttachClassDef_()[source]
buildGDEFMarkGlyphSetsDef_()[source]
buildDebg()[source]
buildLookups_(tag)[source]
makeTable(tag)[source]
makeFeatureVariations(table, table_tag)[source]
any_feature_variations(feature_tag, table_tag)[source]
get_lookup_name_(lookup)[source]
add_language_system(location, script, language)[source]
get_default_language_systems_()[source]
start_feature(location, name, use_extension=False)[source]
end_feature()[source]
start_lookup_block(location, name, use_extension=False)[source]
end_lookup_block()[source]
add_lookup_call(lookup_name)[source]
set_font_revision(location, revision)[source]
set_language(location, language, include_default, required)[source]
getMarkAttachClass_(location, glyphs)[source]
getMarkFilterSet_(location, glyphs)[source]
set_lookup_flag(location, value, markAttach, markFilter)[source]
set_script(location, script)[source]
find_lookup_builders_(lookups)[source]

Helper for building chain contextual substitutions

Given a list of lookup names, finds the LookupBuilder for each name. If an input name is None, it gets mapped to a None LookupBuilder.

add_attach_points(location, glyphs, contourPoints)[source]
add_feature_reference(location, featureName)[source]
add_featureName(tag)[source]
add_cv_parameter(tag)[source]
add_to_cv_num_named_params(tag)[source]

Adds new items to self.cv_num_named_params_ or increments the count of existing items.

add_cv_character(character, tag)[source]
set_base_axis(bases, scripts, vertical, minmax=[])[source]
set_size_parameters(location, DesignSize, SubfamilyID, RangeStart, RangeEnd)[source]
add_any_subst_(location, mapping)[source]
add_single_subst(location, prefix, suffix, mapping, forceChain)[source]
add_multiple_subst(location, prefix, glyph, suffix, replacements, forceChain=False)[source]
add_alternate_subst(location, prefix, glyph, suffix, replacement)[source]
add_ligature_subst(location, prefix, glyphs, suffix, replacement, forceChain)[source]
add_chain_context_subst(location, prefix, glyphs, suffix, lookups)[source]
add_single_subst_chained_(location, prefix, suffix, mapping)[source]
add_multi_subst_chained_(location, prefix, glyph, suffix, replacements)[source]
add_ligature_subst_chained_(location, prefix, glyphs, suffix, replacement)[source]
add_reverse_chain_single_subst(location, old_prefix, old_suffix, mapping)[source]
add_single_pos(location, prefix, suffix, pos, forceChain)[source]
add_class_pair_pos(location, glyphclass1, value1, glyphclass2, value2)[source]
add_specific_pair_pos(location, glyph1, value1, glyph2, value2)[source]
add_cursive_pos(location, glyphclass, entryAnchor, exitAnchor)[source]
add_mark_base_pos(location, bases, marks)[source]
add_mark_lig_pos(location, ligatures, components)[source]
add_mark_mark_pos(location, baseMarks, marks)[source]
add_chain_context_pos(location, prefix, glyphs, suffix, lookups)[source]
add_single_pos_chained_(location, prefix, suffix, pos)[source]
add_marks_(location, lookupBuilder, marks)[source]

Helper for add_mark_{base,liga,mark}_pos.

add_subtable_break(location)[source]
setGlyphClass_(location, glyph, glyphClass)[source]
add_glyphClassDef(location, baseGlyphs, ligatureGlyphs, markGlyphs, componentGlyphs)[source]
add_ligatureCaretByIndex_(location, glyphs, carets)[source]
makeLigCaret(location, caret)[source]
add_ligatureCaretByPos_(location, glyphs, carets)[source]
add_name_record(location, nameID, platformID, platEncID, langID, string)[source]
add_os2_field(key, value)[source]
add_hhea_field(key, value)[source]
add_vhea_field(key, value)[source]
add_conditionset(location, key, value)[source]
makeVariablePos(location, varscalar)[source]
makeAnchorPos(varscalar, deviceTable, location)[source]
makeOpenTypeAnchor(location, anchor)[source]

ast.Anchor –> otTables.Anchor

makeOpenTypeValueRecord(location, v, pairPosContext)[source]

ast.ValueRecord –> otBase.ValueRecord

fontTools.feaLib.lookupDebugInfo

class fontTools.feaLib.lookupDebugInfo.LookupDebugInfo(location: str, name: str, feature: list)[source]

Bases: NamedTuple

Information about where a lookup came from, to be embedded in a font

location: str

Alias for field number 0

name: str

Alias for field number 1

feature: list

Alias for field number 2

fontTools.feaLib.error

exception fontTools.feaLib.error.FeatureLibError(message, location=None)[source]

Bases: Exception

exception fontTools.feaLib.error.IncludedFeaNotFound(message, location=None)[source]

Bases: FeatureLibError