The fontFeatures library¶
The FontFeatures class is a way of representing the transformations - substitutions and positionings - going on inside a font at a semantically high level. It aims to be independent of and unconstrained by the OpenType representation, with the assumption that these high-level objects can be either “compiled down” into AFDKO feature code or directly written to the GSUB/GPOS tables of a font.
FontFeatures aims to marshal data between OTF binary representations, AFDKO feature code, FontDame, and can power other representations such as the FEZ language (see the ‘fez’ library).
A FontFeatures representation of a font will make use of two other top-level concepts: Features and Routines. Routines are collections of rules; they play a similar function to the AFDKO concept of a lookup, but unlike lookups, Routines do not need to be comprised of rules of the same type. You can think of them as functions that are called on a glyph string.
Here is an example of constructing a simple feature file using fontFeatures:
ff = FontFeatures()
liga_ffi = Substitution( [ ["f"], ["f"], ["i"] ], replacement=[["f_f_i"]] )
liga_ffl = Substitution( [ ["f"], ["f"], ["l"] ], replacement=[["f_f_l"]] )
liga_fi = Substitution( [ ["f"], ["i"] ], replacement=[["fi"]] )
liga_ff = Substitution( [ ["f"], ["f"] ], replacement=[["f_f"]] )
liga_routine = Routine(rules=[liga_ffi, liga_ffl, liga_fi, liga_ff])
ff.addFeature("liga", [liga_routine])
# Export Adobe syntax
print(ff.asFea())
font = TTFont("Test.ttf")
ff.buildBinaryFeatures(font)
font.save("Test-liga.ttf")
-
class
fontFeatures.
FontFeatures
¶ An object representing the layout rules in a font.
The initializer has no parameters.
-
addFeature
(name, rs)¶ Add Routines to a named feature.
Parameters: - name – The feature name.
- rs – A sequence of
Routine
orRoutineReference
objects.
-
allRules
(ruletype=None)¶ Return all rules in the font, optionally filtered by type
Parameters: ruletype – A class ( Positioning
,Substitution
etc) to filter the results.Returns: Routines stored in the preamble and within features.
-
anchors
= None¶ A dictionary mapping glyph names to a dictionary of anchor names / positions.
-
asFeaAST
(do_gdef=True)¶ Returns this font’s features as a feaLib AST object, for later translation to AFDKO code.
-
buildBinaryFeatures
(font, axes=[])¶ Adds GDEF, GSUB and GPOS tables to a font object.
Parameters: - font – a fontTools
ttFont
object. - axes – an optional list of objects conforming to the
fontTools.designspaceLib.AxisDescriptor
protocol.
- font – a fontTools
-
ensureLookupsAreReferences
(lookuplist)¶ Ensures that all references are lookups.
Naughty people might put
Routine
objects directly intoChain
lookups. This tidies them up.
-
features
= None¶ An ordered dictionary mapping feature tags to a list of routine references.
-
classmethod
fromXML
(el)¶ Creates a FontFeatures object from a lxml Element object.
-
gensym
(category)¶ Generate a new unique symbol (used for labeling unlabeled data).
Parameters: category (str) – The category for this symbol Returns: a string representing a unique label.
-
getNamedClassFor
(glyphs, name)¶ Find and optionally stores a named class of glyphs
Parameters: - glyphs – A sequence of glyph names.
- name – A name for this glyph class if it does not exist.
Returns: The name of a glyph class. If the exact same set of glyphs was already stored as a glyph class, then the name of that class will be returned. If not, then the class will be stored and the name provided as the
name
argument will be returned.
-
glyphclasses
= None¶ A dictionary mapping glyph names to their categories.
-
hasScriptSupport
(script)¶ Check if the features object has support for a particular script.
Parameters: script (str) – A four-character OpenType script code. Returns: boolean
-
hoist_languages
()¶ Sort routines into scripts and languages and resolve wildcards.
-
markRoutineUseInChains
()¶ Annotate routines which are used in chaining rules.
Generally used when converting the fontFeatures object to another format; allows routines to know where they are being used by annotating them with the
.usedin
property for optimization purposes.
-
namedClasses
= None¶ A mapping of named classes to a list of glyph names which make up the class.
-
partitionRoutine
(routine, factor)¶ Splits a routine based on a predicate.
This method applies a function to each rule in the routine and creates distinct routines, each containing rules with the same return value from the function. This is useful, for example, when exporting to OpenType, to ensure that all rules in a routine must have the same type, same flags, etc.
Parameters: Returns: A list of
Routine
objects. Additionally, modifies the.routines
list of the FontFeatures object.
-
referenceRoutine
(r, do_usecount=True)¶ Store a routine and return a reference to it.
Parameters: r – A Routine
object.
-
resolveAllRoutines
()¶ Resolve reference use in chains.
Checks that all routines referenced in chain rules can actually be found within the object, and adds pointers to match named routine references with the relevant
Routine
object.
-
routineNamed
(name)¶ Finds a routine with the given name.
Parameters: name (str) – The name to find - Returns: a
Routine
object if the named routine was found - in the features object. Raises a
ValueError
if not.
- Returns: a
-
routines
= None¶ All of the layout routines used in this font.
-
scratch
= None¶ Space for items to communicate context to each other.
-
setGlyphClassesFromFont
(font)¶ Loads glyph classes from the font.
-
toXML
()¶ Serializes a FontFeatures object to a lxml Element object.
-
Routines: representing collections of layout rules¶
-
class
fontFeatures.
Routine
(name='', rules=None, address=None, inlined=False, languages=None, parent=None, flags=0, markFilteringSet=None, markAttachmentSet=None)¶ Represent a Routine (similar to OT Lookup).
A routine is a set of rules, sometimes but not always with an explicit name. It can apply to a set of language/script pairs.
-
addComment
(comment)¶ Adds a comment to a Routine.
Comments are emitted when the Routine is converted to text formats such as AFDKO.
Parameters: comment – A string comment.
-
addRule
(rule)¶ Adds a rule to a Routine.
Parameters: rule – A Substitution
,Positioning
, etc. object.
-
classmethod
fromXML
(el)¶ Creates a Routine from a lxml Element object.
-
involved_glyphs
¶ Returns the names of all of the glyphs involved in this Routine.
-
stage
¶ Returns which shaping stage this routine is used in.
Returns:
sub
for substitution stage,pos
for positioning stage.
-
toOTLookup
(font, ff)¶ Converts a fontFeatures.Routine object to binary.
Parameters: - font – A
TTFont
object. - ff – The parent
FontFeatures
object containing this routine.
Returns a list of
fontTools.otlLib.builder
Builder objects allowing this routine to be converted to binary layout format.- font – A
-
toXML
()¶ Serializes a Routine to a lxml Element object.
-
-
class
fontFeatures.
RoutineReference
(name=None, routine=None)¶ A reference to a Routine object, used in a lookup.
Routines can be referenced either by name (for example, when loaded from a textual representation), in which case they will be resolved at a later time, or by providing a pointer to the
Routine
object.-
asFea
()¶ Returns this Rule as a string of AFDKO feature text.
-
classmethod
fromXML
(el)¶ Creates a RoutineReference from a lxml Element object.
-
resolve
(ff)¶ Resolves the reference in the context of a
FontFeatures
object.Raises a
ValueError
if a named routine cannot be found.
-
stage
¶ Returns which shaping stage this routine is used in.
Returns:
sub
for substitution stage,pos
for positioning stage.
-
toXML
()¶ Serializes a RoutineReference to a lxml Element object.
-
-
class
fontFeatures.
ExtensionRoutine
(**kwargs)¶ OpenType-specific concept: A routine which contains other routines.
-
apply_to_buffer
(buf, stage=None, feature=None)¶ Applies shaping rules from this routine to a buffer.
Parameters: - buf – A
fontFeatures.shaperLib.Buffer
object. - stage (str) – Shaping stage -
sub
orpos
. - feature (str) – The feature being processed. (For debugging.)
Modifies the
buf
object.- buf – A
-
asFeaAST
()¶ Returns this extension routine as
fontTools.feaLib.ast
objects.
-
stage
¶ Returns which shaping stage this routine is used in.
Returns:
sub
for substitution stage,pos
for positioning stage.
-
Representing individual layout rules¶
-
class
fontFeatures.
Rule
¶ A base class for all rules.
-
asFea
()¶ Returns this Rule as a string of AFDKO feature text.
-
feaPreamble
(ff)¶ Computes any text that needs to go in the feature file header.
-
classmethod
fromXML
(el)¶ Creates a Rule from a lxml Element object.
-
has_context
¶ Does this rule have any pre- or post-context defined?
-
toXML
()¶ Serializes a Rule to a lxml Element object.
-
-
class
fontFeatures.
Substitution
(input_, replacement, precontext=None, postcontext=None, address=None, languages=None, lookups=None, reverse=False, flags=0, force_alt=False)¶ Represents a Substitution rule.
A substitution represents any kind of exchange of one set of glyphs for another: single substitutions, multiple substitutions and ligatures are all substitutions. Optionally, substitutions may be followed by precontext and postcontext.
Parameters: - input – A list of lists. The outer list represents the positions in the glyph stream to substitute, with the inner list representing the glyph names at each position.
- replacement – A list of glyph names.
- precontext – A list of list of glyphs which must appear before the input sequence.
- postcontext – A list of list of glyphs which must appear before the input sequence.
- lookups – A list of list of lookups to be applied to the glyph sequence. The outer list represents the positions in the input sequence, with the inner list containing Routines to apply.
- reverse – Boolean representing if the substitutions should take place from the end of the string.
- force_alt – Force this substitution to be interpreted as an alternate substitution.
Examples:
lig = Substitution( [ ["f"], ["i"] ], ["f_i"] ) # sub f i by f_i; contextual = Substitution( [ ["dotbelow"] ], [ ["dotbelow.post"] ], precontext = [["ra-myanmar", "ra-myanmar.bt1", "ra-myanmar.bt2"]] ) # sub [ra-myanmar ra-myanmar.bt1 ra-myanmar.bt2] dotbelow-myanmar' # by dotbelow-myanmar.post;
-
classmethod
fromXML
(el)¶ Creates a rule from a lxml Element object.
-
involved_glyphs
¶ Returns a set of all glyphs involved in this rule.
-
lookup_type
(forFea=False)¶ Mixin to determine the GSUB lookup type of a fontFeatures.Substitution object
Returns: integer GSUB lookup type.
-
class
fontFeatures.
Positioning
(glyphs, valuerecords, precontext=None, postcontext=None, address=None, languages=None, flags=0)¶ Represents a Positioning rule.
Parameters: - input – A list of lists. The outer list represents the positions in the glyph stream to position, with the inner list representing the glyph names at each glyph stream position.
- valuerecords – A list of
ValueRecord
objects to be applied at each glyph stream position. - precontext – A list of list of glyphs which must appear before the input sequence.
- postcontext – A list of list of glyphs which must appear before the input sequence.
Example:
open_up_behs = Positioning( [ ["BEi1", "BEi2"], ["sda", "sdb", "dda", "ddb"] ], [ ValueRecord(xAdvance=200), ValueRecord(xPlacement=50), ] postcontext = [ medis_finas ] ) # pos [BEi1 BEi2]' <0 0 200 0> [sda sdb dda ddb]' <0 50 0 0> @medis_finas;
-
classmethod
fromXML
(el)¶ Creates a rule from a lxml Element object.
-
involved_glyphs
¶ Returns a set of all glyphs involved in this rule.
-
lookup_type
()¶ Mixin to determine the GPOS lookup type of a fontFeatures.Positioning object
Returns: integer GPOS lookup type.
-
class
fontFeatures.
Attachment
(base_name, mark_name, bases=None, marks=None, fullname=None, flags=0, address=None, font=None, languages=None, force_markmark=False)¶ Represents an Attachment rule.
Parameters: - base_name – Name of the base class.
- mark_name – Name of the mark class.
- bases – Dictionary. They keys are names of glyphs to act as bases to the attachment (this may be categorized as mark glyphs if the attachment is a mark-to-mark operation); the associated values are a two-element tuple with the coordinates of the anchor.
- marks – Dictionary. They keys are names of glyphs to act as marks; the associated values are a two-element tuple with the coordinates of the anchor.
- force_markmark – boolean. If true, force this to be interpreted as a mark-to-mark operation
Whether this is a mark-to-base or mark-to-mark operation will be determined by the glyph category of the glyphs involved in the bases dictionary and the value of the force_markmark argument.
Examples:
ff.anchors = { "a": { "top": (250, 603) }, "acutecomb": { "_top": (56, 0) } } top_bases = {} top_marks = {} for glyphname, anchors in ff.anchors.items(): for anchorname, position in anchors.items(): if anchorname == "top": top_bases[glyphname] = position if anchorname == "_top": top_marks[glyphname] = position # top_bases = { "a": (260,603) } # top_marks = { "acutecomb": (56,0) } tops = Attachment("top", "_top", top_bases, top_marks)
-
classmethod
fromXML
(el)¶ Creates a rule from a lxml Element object.
-
involved_glyphs
¶ Returns a set of all glyphs involved in this rule.
-
is_cursive
¶ Returns true if this is a cursive attachment rule.
-
lookup_type
()¶ Mixin to determine the GPOS lookup type of a fontFeatures.Attachment object
Returns: integer GPOS lookup type.
-
shaper_inputs
()¶ Returns a list of potential glyphs to determine whether to test if this rule applies at a given point.
-
would_apply_at_position
(buf, ix, namedclasses={})¶ Tests to see if this rule would apply at position
ix
of the buffer.
-
class
fontFeatures.
Chaining
(input_, precontext=None, postcontext=None, address=None, languages=None, lookups=None, flags=0)¶ Represents a Chain rule.
A Chain rule represents the operation of calling another Routine when a particular input context is met.
Parameters: - input – A list of lists. The outer list represents the positions in the glyph stream to substitute, with the inner list representing the glyph names at each position.
- precontext – A list of list of glyphs which must appear before the input sequence.
- postcontext – A list of list of glyphs which must appear before the input sequence.
- lookups – A list of list of lookups to be applied to the glyph sequence. The outer list represents the positions in the input sequence, with the inner list containing Routines to apply.
Example:
sub_Qu = Routine(rules=[ Substitute([["Q"]], [["Q.beforeu"]]) ]) chain = Chain( [["Q"]], postcontext = [ ["u", "v", "u.sc", "v.sc"] ], lookups = [ [sub_Qu] ] ) # sub Q' lookup sub_Qu [u v u.sc v.sc];
-
classmethod
fromXML
(el)¶ Creates a rule from a lxml Element object.
-
involved_glyphs
¶ Returns a set of all glyphs involved in this rule.
-
lookup_type
()¶ Mixin to determine the GSUB/GPOS lookup type of a fontFeatures.Chaining object
Returns: integer GSUB/GPOS lookup type.
-
stage
¶ Returns which shaping stage this routine is used in.
Returns:
sub
for substitution stage,pos
for positioning stage.
Value Records¶
-
class
fontFeatures.
ValueRecord
(xPlacement=None, yPlacement=None, xAdvance=None, yAdvance=None, xPlaDevice=None, yPlaDevice=None, xAdvDevice=None, yAdvDevice=None, vertical=False, location=None)¶ A value record for representing positional changes in advance and placement.
See
fontTools.feaLib.ValueRecord
, from which this inherits.-
is_variable
¶ Returns true if any of the elements of the value record are a
fontTools.feaLib.VariableScalar
.
-
toOTValueRecord
(ff, pairPosContext=False)¶ Converts the ValueRecord to an
OTLValueRecord
object. If the value record contains any variable scalars, they are saved to the GDEF variation store.
-