Font

Note

This section needs to contain the following:

  • description of what this is ✓

  • sub-object with basic usage ✓

  • bridge to default layer for glyphs for backwards compatibility ✗

  • glyph interaction with basic usage ✗

Description

The Font object is the central part that connects all glyphs with font information like names, key dimensions etc.

Font objects behave like dictionaries: the glyph name is the key and the returned value is a Glyph object for that glyph. If the glyph does not exist, Font will raise an IndexError.

Font has a couple of important sub-objects which are worth checking out. The font’s kerning is stored in a Kerning object and can be reached as an attribute at Font.kerning. Fontnames, key dimensions, flags etc are stored in a Info object which is available through Font.info. The Font.lib is a Lib object which behaves as a dictionary.

Overview

Copy

BaseFont.copy

Copy data from the current font into a new font.

File Operations

BaseFont.path

Get the path to the font file.

BaseFont.save

Save the font to the specified path.

BaseFont.generate

Generate the font in another format.

Sub-Objects

BaseFont.info

Get the font's info object.

BaseFont.groups

Get the font's groups object.

BaseFont.kerning

Get the font's kerning object.

BaseFont.features

Get the font's features object.

BaseFont.lib

Get the font's lib object.

BaseFont.tempLib

Get the font's temporary lib object.

Layers

BaseFont.layers

Get the font's layer objects.

BaseFont.layerOrder

Get or set the order of the layers in the font.

BaseFont.defaultLayer

Get or set the font's default layer.

BaseFont.getLayer

Get the named layer from the font.

BaseFont.newLayer

Create a new layer in the font.

BaseFont.removeLayer

Remove the specified layer from the font.

BaseFont.insertLayer

Insert a specified layer into the font.

BaseFont.duplicateLayer

Duplicate the specified layer in the font.

Glyphs

BaseFont.__len__

Return the number of glyphs in the layer.

BaseFont.keys

Get the names of all glyphs in the layer.

BaseFont.glyphOrder

Get or set the order of the glyphs in the font.

BaseFont.__iter__

Iterate through the glyphs in the layer.

BaseFont.__contains__

Check if the layer contains the specified glyph.

BaseFont.__getitem__

Get the specified glyph from the layer.

BaseFont.newGlyph

Create a new glyph in the layer.

BaseFont.insertGlyph

Insert a specified glyph into the layer.

BaseFont.removeGlyph

Remove the specified glyph from the layer.

Guidelines

BaseFont.guidelines

Get the font-level guideline objects.

BaseFont.appendGuideline

Append a new guideline to the font.

BaseFont.removeGuideline

Remove a guideline from the font.

BaseFont.clearGuidelines

Clear all guidelines in the font.

Interpolation

BaseFont.isCompatible

Evaluate interpolation compatibility with another font.

BaseFont.interpolate

Interpolate all possible data in the font.

Kerning

BaseFont.getFlatKerning

Get the font's kerning as a flat dictionary.

Mapping

BaseFont.getCharacterMapping

Get the font's character mapping.

BaseFont.getReverseComponentMapping

Get a reversed map of all component references in the font.

Selection

BaseFont.selectedLayers

Get or set the selected glyph layers in the default font layer.

BaseFont.selectedLayerNames

Get or set the selected glyph layer names in the default font layer.

BaseFont.selectedGuidelines

Get or set the selected guidelines in the font.

Normalization

BaseFont.round

Round all appropriate font data to integers.

BaseFont.autoUnicodes

Use heuristics to set Unicode values in all font glyphs.

Environment

BaseFont.naked

Return the environment's native object wrapped by the current object.

BaseFont.changed

Tell the environment that something has changed in the object.

Reference

class fontParts.base.BaseFont(pathOrObject: str | BaseFont | None = None, showInterface: bool = True)[source]

Represent the basis for a font object.

Instances of this class are almost always created with one of the font functions in fontParts.world.

This class will be instantiated in different ways depending on the value type of the pathOrObject parameter.

Parameters:
  • pathOrObject – The source for initializing the font. If None, a new, empty font will be created. If a str representing the path to an existing file, the class will open and read the file at this path. If an instance of the environment’s unwrapped native font object, it will be wrapped with FontParts. Defaults to None.

  • showInterface – Whether to display the graphical interface. Defaults to True.

Copy

BaseFont.copy() BaseFont[source]

Copy data from the current font into a new font.

This will copy:

Returns:

A new BaseFont instance with the same attributes as the current instance.

Example:

>>> copiedFont = font.copy()

File Operations

BaseFont.path: dynamicProperty

Get the path to the font file.

This property is read-only.

Returns:

A str defining the location of the file or None to indicate that the font does not have a file representation.

Example:

>>> print(font.path)
"/path/to/my/font.ufo"
BaseFont.save(path: str | None = None, showProgress: bool = False, formatVersion: int | None = None, fileStructure: str | None = None) None[source]

Save the font to the specified path.

Parameters:
  • path – The path to which the font should be saved. If None, the font is saved to its original location. The file type is inferred from the file extension of the path. If no extension is given, the environment may use a default format. Defaults to None.

  • showProgress – Whether to display a progress bar during the operation. Environments may or may not implement this behavior. Defaults to False.

  • formatVersion – The format version to use when saving the file. For example, a formatVersion of 2 will save the file in UFO 2 format. If None, the original format version will be preserved, or the latest version supported by the environment will be used if no original version exists. Defaults to None.

  • fileStructure – The file structure for saving UFO formats. Can be None, which uses the existing file structure or the default structure for unsaved fonts; 'package', which is the default structure; or 'zip', which saves the font as a .ufoz file. Defaults to None.

Raises:

IOError – If no file location is given in either the path parameter or the BaseFont.path attribute.

Note

Environments may define their own rules regarding when a file should be saved to its original location versus a new location. For example, a font opened from a compiled OpenType font may not be saved back into the original OpenType file.

Example:

>>> font.save()
>>> font.save("/path/to/my/font-2.ufo")
BaseFont.close(save: bool = False) None[source]

Close the font.

Parameters:

save – Whether to save the font before closing. Defaults to False

Example:

>>> font.close()
>>> font.close(save=True)
BaseFont.generate(format: str, path: str | None = None, **environmentOptions: Any) None[source]

Generate the font in another format.

This method converts the font to the specified format and saves it to the specified path. Standard format identifiers can be found in BaseFont.generateFormatToExtension.

Environments may support additional keyword arguments in this method. For example, if the tool allows decomposing components during generation, this can be specified with an additional keyword argument.

Parameters:
  • format – The file format identifier for the output.

  • path – The location to save the generated file. If not provided, the file will be saved in the same directory as the source font, with the current file name and the appropriate suffix for the format. If a directory is specified, the file will be saved with the current file name and the appropriate suffix for the format. If a file already exists at that location, it will be overwritten.

  • **environmentOptions – Additional keyword arguments for environment-specific options.

Raises:
  • ValueError – If format is not defined.

  • TypeError – If format is not a str.

  • UserWarning – If an unsupported environment option is passed.

  • IOError – If the output path is not defined and the source font does not have a path.

Example:

>>> font.generate("otfcff")
>>> font.generate("otfcff", "/path/to/my/font.otf")

Sub-Objects

BaseFont.info: dynamicProperty

Get the font’s info object.

This property is read-only.

Returns:

An instance of the BaseInfo class.

Example:

>>> font.info.familyName
"My Family"
BaseFont.groups: dynamicProperty

Get the font’s groups object.

This property is read-only.

Returns:

An instance of the BaseGroups class.

Example:

>>> font.groups["myGroup"]
["A", "B", "C"]
BaseFont.kerning: dynamicProperty

Get the font’s kerning object.

This property is read-only.

Returns:

An instance of the BaseKerning class.

Example:

>>> font.kerning["A", "B"]
-100
BaseFont.features: dynamicProperty

Get the font’s features object.

This property is read-only.

Returns:

An instance of the BaseFeatures class.

Example:

>>> font.features.text
"include(features/substitutions.fea);"
BaseFont.lib: dynamicProperty

Get the font’s lib object.

This property is read-only.

Returns:

An instance of the BaseLib class.

Example:

>>> font.lib["org.robofab.hello"]
"world"
BaseFont.tempLib: dynamicProperty

Get the font’s temporary lib object.

This property is read-only.

This property provides access to a temporary instance of the BaseLib class, used for storing data that should not be persisted. It is similar to BaseFont.lib, except that its contents will not be saved when calling the BaseFont.save method.

Returns:

A temporary instance of the BaseLib class.

Example:

>>> font.tempLib["org.robofab.hello"]
"world"

Layers

BaseFont.layers: dynamicProperty

Get the font’s layer objects.

This property is read-only.

Returns:

A tuple containing instances of the BaseLayer class.

Example:

>>> for layer in font.layers:
...     layer.name
"My Layer 1"
"My Layer 2"
BaseFont.layerOrder: dynamicProperty

Get or set the order of the layers in the font.

The value must be a list or tuple of layer names as str reflecting the desired order of the font’s BaseLayer objects.

Returns:

A tuple of layer names as str in their defined order.

Example:

>>> font.layerOrder = ["My Layer 2", "My Layer 1"]
>>> font.layerOrder
("My Layer 2", "My Layer 1")
BaseFont.defaultLayer: dynamicProperty

Get or set the font’s default layer.

The value must be the desired default BaseLayer instance.

Returns:

The current default BaseLayer instance.

Example:

>>> layer = font.defaultLayer
>>> font.defaultLayer = otherLayer
BaseFont.defaultLayerName: dynamicProperty

Get or set the name of the font’s default layer.

The value must be name of the desired default :class`BaseLayer` instance as a str.

Returns:

The name of the current default :class`BaseLayer` instance.

Example:

>>> font.defaultLayerName = "My Layer 2"
>>> font.defaultLayerName
"My Layer 2"
BaseFont.getLayer(name: str) BaseLayer[source]

Get the named layer from the font.

Parameters:

name – The name of the BaseLayer instance to retrieve.

Returns:

The specified BaseLayer instance.

Raises:

ValueError – If no layer with the given name exists in the font.

Example:

>>> font.getLayer("My Layer 2")
<Layer 'My Layer 2' at 0x...>
BaseFont.newLayer(name: str, color: RGBALike | None = None) BaseLayer[source]

Create a new layer in the font.

Parameters:
  • name – The name of the new layer to create.

  • color – The color value to assign to the new layer. Defaults to None.

Returns:

A newly created BaseLayer instance.

Example:

>>> layer = font.newLayer("My Layer 3")
BaseFont.removeLayer(name: str) None[source]

Remove the specified layer from the font.

Parameters:

name – The name of the layer to remove.

Raises:

ValueError – If no layer with the given name exists in the font.

Example:

>>> font.removeLayer("My Layer 3")
BaseFont.insertLayer(layer: BaseLayer, name: str | None = None) BaseLayer[source]

Insert a specified layer into the font.

This method will not insert a layer directly, but rather create a new BaseLayer instance containing the data from layer. The data inserted from layer is the same data as documented in BaseLayer.copy.

Parameters:
  • layer – The BaseLayer instance to insert.

  • name – The name to assign to the new layer after insertion. If value is None, the origninal name will be used. Defaults to None.

Returns:

The newly inserted BaseLayer instance.

Example:

>>> layer = font.insertLayer(otherLayer, name="layer 2")
BaseFont.duplicateLayer(layerName: str, newLayerName: str) BaseLayer[source]

Duplicate the specified layer in the font.

This method creates a new BaseLayer instance. It copies data from the layer named layerName into this new instance, assigns it the name specified by newLayerName, and then inserts the new layer into the font.

Parameters:
  • layerName – The name of the layer to duplicate.

  • newLayerName – The new name to assign to the duplicated layer.

Returns:

The newly duplicated BaseLayer instance.

Raises:

ValueError – If no layer with the given name exists in the font.

Example:

>>> layer = font.duplicateLayer("layer 1", "layer 2")
BaseFont.swapLayerNames(layerName: str, otherLayerName: str) None[source]

Swap the names of two specific layers in the font.

This method assigns the name layerName to the layer currently named otherLayerName and assigns the name otherLayerName to the layer currently named layerName.

Parameters:
  • layerName – The name of one layer.

  • otherNAme – The name of the other layer.

Raises:

ValueError – If no layer with the given layerName or otherLayerName exists in the font.

Example:

>>> font.swapLayerNames("before drawing revisions",
...                     "after drawing revisions")

Glyphs

Interacting with glyphs at the font level is a shortcut for interacting with glyphs in the default layer.

>>> glyph = font.newGlyph("A")

Does the same thing as:

>>> glyph = font.getLayer(font.defaultLayerName).newGlyph("A")
BaseFont.__len__() int

Return the number of glyphs in the layer.

Returns:

The number of BaseGlyph instances in the layer as an int.

Example:

>>> len(layer)
256
BaseFont.keys() tuple[str, ...]

Get the names of all glyphs in the layer.

This method returns an unordered tuple of glyph names representing all the BaseGlyph instances in the active layer. If called from a BaseFont instance, it returns the glyphs from the default layer. If called from a BaseLayer instance, it returns the glyphs from the current layer.

Returns:

A tuple of glyph names representing the glyphs in the current or default BaseLayer instance.

Example:

>>> layer.keys()
["B", "C", "A"]
BaseFont.glyphOrder: dynamicProperty

Get or set the order of the glyphs in the font.

The value must be a list or tuple of glyph names reflecting the desired order of the font’s BaseGlyph objects.

Returns:

A tuple of glyph names in their defined order.

Example:

>>> font.glyphOrder
["C", "B", "A"]
>>> font.glyphOrder = ("A", "B", "C")
BaseFont.__iter__() Iterator[BaseGlyph]

Iterate through the glyphs in the layer.

Returns:

An iterator over BaseGlyph instances.

Example:

>>> for glyph in layer:
...     glyph.name
"A"
"B"
"C"
BaseFont.__contains__(name: str) bool

Check if the layer contains the specified glyph.

This method checks whether a glyph with the given name exists in the layer. When called from a BaseFont instance, it checks the default layer. When called from a BaseLayer instance, it checks the current layer.

Parameters:

name – The name of the glyph to check for.

Returns:

True if the glyph exists in the layer, False otherwise.

Note

has_key is provided as an alias for this method for backward compatibility but may be deprecated in the future. It is advisable to use __contains__ instead.

Example:

>>> "A" in layer
True
BaseFont.__getitem__(name: str) BaseGlyph

Get the specified glyph from the layer.

Parameters:

name – The name representing the glyph to retrieve.

Returns:

a BaseGlyph instance with the specified name.

Raises:

KeyError – If no glyph with the given name exists in the layer.

Example:

>>> glyph = layer["A"]
BaseFont.newGlyph(name: str, clear: bool = True, rename: bool = False) BaseGlyph

Create a new glyph in the layer.

This method creates a new glyph with the given name in the layer.

If no glyph with the specified name exists, a new glyph is created and returned.

If a glyph with the specified name already exists:

  • If clear is True, the existing glyph is removed before creating and returning a new glyph with the same name.

  • If clear is False and rename is False, the existing glyph is returned unchanged.

  • If clear is False and rename is True, the existing glyph is renamed to a unique replacement name and a new glyph with the original name is created and returned.

Replacement names are generated by appending a numeric suffix such as .1 or .2 to the original glyph name.

When called from a BaseFont instance, the glyph is created in the default layer. When called from a BaseLayer instance, the glyph is created in the current layer.

Parameters:
  • name – The name of the glyph to create.

  • clear – Whether to remove an existing glyph with the same name before creating a new glyph. Defaults to True.

  • rename – Whether to rename an existing glyph to a unique replacement name when clear is False. Defaults to False.

Returns:

The newly created or existing BaseGlyph instance.

Example:

>>> glyph = layer.newGlyph("A")
BaseFont.insertGlyph(glyph: BaseGlyph, name: str | None = None) BaseGlyph

Insert a specified glyph into the layer.

This method will not insert a glyph directly, but rather create a new BaseGlyph instance containing the data from glyph. The data inserted from glyph is the same data as documented in BaseGlyph.copy.

Parameters:
  • glyph – The BaseGlyph instance to insert.

  • name – The name to assign to the new layer after insertion. If value is None, the origninal name will be used. Defaults to None.

Returns:

The newly inserted BaseGlyph instance.

Example:

>>> glyph = font.insertGlyph(otherGlyph, name="glyph2")
BaseFont.removeGlyph(name: str) None

Remove the specified glyph from the layer.

This method removes the glyph with the given name from the layer. When called from a BaseFont instance, it removes the glyph from the default layer. When called from a BaseLayer instance, it removes the glyph from the current layer.

Parameters:

name – The name of the glyph to remove.

Example:

>>> layer.removeGlyph("A")

Guidelines

BaseFont.guidelines: dynamicProperty

Get the font-level guideline objects.

This property is read-only.

Returns:

A tuple containing instances of the BaseGuideline class.

>>> for guideline in font.guidelines:
...     guideline.angle
0
45
90

BaseFont.appendGuideline(position: CoordinateLike | None = None, angle: IntFloatType | None = None, name: str | None = None, color: RGBALike | None = None, guideline: BaseGuideline | None = None) BaseGuideline[source]

Append a new guideline to the font.

This method will create a new BaseGuideline with the provided values. Values may be copied from the specified guideline or passed individually to the appropriate parameters.

Parameters:
  • position – The optional position for the guideline as a Coordinate. Defaults to None.

  • angle – The optional angle for the guideline as a float. Defaults to None.

  • name – The optional name for the guideline as a str. Defaults to None.

  • color – The optional color for the guideline as a Color. Defaults to None.

  • guideline – The optional BaseGuideline instance from which to copy values. If position, angle, name, or color are specified, those values will be used instead. Defaults to None.

Returns:

The newly appended instance of the BaseGuideline class.

Example:

>>> guideline = font.appendGuideline((50, 0), 90)
>>> guideline = font.appendGuideline((0, 540), 0, name="overshoot",
... color=(0, 0, 0, 0.2))
BaseFont.removeGuideline(guideline: int | BaseGuideline) None[source]

Remove a guideline from the font.

Parameters:

guideline – A BaseGuideline object or an integer representing a BaseGuideline.index.

Raises:

ValueError if no guideline is found at the given index.

Example:

>>> font.removeGuideline(guideline)
>>> font.removeGuideline(2)
BaseFont.clearGuidelines() None[source]

Clear all guidelines in the font.

Example:

>>> font.clearGuidelines()

Interpolation

BaseFont.isCompatible(other: BaseFont, cls=None) tuple[bool, FontCompatibilityReporter][source]

Evaluate interpolation compatibility with another font.

This method will return a bool indicating if the font is compatible for interpolation with other, and a str containing compatibility notes.

Parameters:

other – The other BaseFont instance to check compatibility with.

Returns:

A tuple where the first element is a bool indicating compatibility, and the second element is a fontParts.base.compatibility.FontCompatibilityReporter instance.

Example:

>>> compatible, report = self.isCompatible(otherFont)
>>> compatible
False
>>> report
[Fatal] Glyph: "test1" + "test2"
[Fatal] Glyph: "test1" contains 1 contours | "test2" contains 2 contours
BaseFont.interpolate(factor: int | float | list[int | float] | tuple[float, float], minFont: BaseFont, maxFont: BaseFont, round: bool = True, suppressError: bool = True) None[source]

Interpolate all possible data in the font.

The interpolation occurs on a 0 to 1.0 range between minFont and maxFont, using the specified factor.

Parameters:
  • factor – The interpolation value as a single int or float or a tuple of two int or float values representing the factors (x, y).

  • minFont – The BaseFont instance corresponding to the 0.0 position in the interpolation.

  • maxFont – The BaseFont instance corresponding to the 1.0 position in the interpolation.

  • round – A bool indicating whether the result should be rounded to integers. Defaults to True.

  • suppressError – A bool indicating whether to ignore incompatible data or raise an error when such incompatibilities are found. Defaults to True.

Raises:

TypeError – If minFont or maxFont are not instances of BaseFont.

Example:

>>> font.interpolate(0.5, otherFont1, otherFont2)
>>> font.interpolate((0.5, 2.0), otherFont1, otherFont2, round=False)

Kerning

BaseFont.getFlatKerning() dict[tuple[str, str], tuple[str, str]][source]

Get the font’s kerning as a flat dictionary.

Returns:

A dict of the font’s BaseKerning keys mapped to their respective values.

Mapping

BaseFont.getCharacterMapping() dict[int, tuple[str, ...]][source]

Get the font’s character mapping.

This method creates a dict mapping Unicode values to tuples of glyph names. Each Unicode value corresponds to one or more glyphs, and the glyph names represent these glyphs in the mapping.

Note

One glyph can have multiple unicode values, and a unicode value can have multiple glyphs pointing to it.

Returns:

A dict mapping Unicode values to tuple of glyph names.

Example:

>>> mapping = font.getCharacterMapping()
>>> mapping
{65: ('A', 'A.alt'), 66: ('B',),
67: ('C', 'C.alt', 'C.swash') , ...}
BaseFont.getReverseComponentMapping() dict[str, tuple[str, ...]][source]

Get a reversed map of all component references in the font.

This method creates a dict mapping each component glyph name in the font to a tuple containing the composite glyph names that include the comoponent.

Returns:

A dict of component glyph names mapped to tuples of composite glyph names.

Example:

>>> mapping = font.getReverseComponentMapping()
>>> mapping
{'A': ('Aacute', 'Aring'), 'acute': ('Aacute',),
'ring': ('Aring',)  , ...}

Selection

BaseFont.selectedLayers: dynamicProperty

Get or set the selected glyph layers in the default font layer.

Parameters:

value – The list of BaseLayer instances to select.

Returns:

A tuple of currently selected BaseLayer instances.

Getting selected layer objects:

>>> for layer in layer.selectedLayers:
...     layer.color = (1, 0, 0, 0.5)

Setting selected layer objects:

>>> layer.selectedLayers = someLayers
BaseFont.selectedLayerNames: dynamicProperty

Get or set the selected glyph layer names in the default font layer.

Parameters:

value – The list of layer names representing the BaseLayer instances to select.

Returns:

A tuple of layer names representing the currently selected BaseLayer instances.

Getting selected layer names:

>>> for name in layer.selectedLayerNames:
...     print(name)

Setting selected layer names:

>>> layer.selectedLayerNames = ["A", "B", "C"]
BaseFont.selectedGuidelines: dynamicProperty

Get or set the selected guidelines in the font.

Parameters:

value – The list of either BaseGuideline instances to select or their corresponding indexes.

Returns:

A tuple of currently selected BaseGuideline instances.

Getting selected guideline objects:

>>> for guideline in font.selectedGuidelines:
...     guideline.color = (1, 0, 0, 0.5)

Setting selected guideline objects:

>>> font.selectedGuidelines = someGuidelines

Setting also supports guideline indexes:

>>> font.selectedGuidelines = [0, 2]

Normalization

BaseFont.round() None[source]

Round all appropriate font data to integers.

This method applies only to the glyphs in the default layer of the font. It is the equivalent of calling the round method on:

Example:

>>> font.round()
BaseFont.autoUnicodes() None[source]

Use heuristics to set Unicode values in all font glyphs.

This method applies only to the glyphs in the default layer of the font. Environments will define their own heuristics for automatically determining values.

Example:

>>> font.autoUnicodes()

Environment

BaseFont.naked() Any

Return the environment’s native object wrapped by the current object.

Raises:

NotImplementedError – If the method has not been overridden by a subclass.

Example:

>>> loweLevelObj = obj.naked()
BaseFont.changed(*args: Any, **kwargs: Any) None

Tell the environment that something has changed in the object.

The behavior of this method will vary from environment to environment.

Parameters:
  • *args – Any positional arguments.

  • **kwargs – Any keyword arguments.

Example:

>>> obj.changed()