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¶
Copy data from the current font into a new font. |
File Operations¶
Get the path to the font file. |
|
Save the font to the specified path. |
|
Generate the font in another format. |
Sub-Objects¶
Get the font's info object. |
|
Get the font's groups object. |
|
Get the font's kerning object. |
|
Get the font's features object. |
|
Get the font's lib object. |
|
Get the font's temporary lib object. |
Layers¶
Get the font's layer objects. |
|
Get or set the order of the layers in the font. |
|
Get or set the font's default layer. |
|
Get the named layer from the font. |
|
Create a new layer in the font. |
|
Remove the specified layer from the font. |
|
Insert a specified layer into the font. |
|
Duplicate the specified layer in the font. |
Glyphs¶
Return the number of glyphs in the layer. |
|
Get the names of all glyphs in the layer. |
|
Get or set the order of the glyphs in the font. |
|
Iterate through the glyphs in the layer. |
|
Check if the layer contains the specified glyph. |
|
Get the specified glyph from the layer. |
|
Create a new glyph in the layer. |
|
Insert a specified glyph into the layer. |
|
Remove the specified glyph from the layer. |
Guidelines¶
Get the font-level guideline objects. |
|
Append a new guideline to the font. |
|
Remove a guideline from the font. |
|
Clear all guidelines in the font. |
Interpolation¶
Evaluate interpolation compatibility with another font. |
|
Interpolate all possible data in the font. |
Kerning¶
Get the font's kerning as a flat dictionary. |
Mapping¶
Get the font's character mapping. |
|
Get a reversed map of all component references in the font. |
Selection¶
Get or set the selected glyph layers in the default font layer. |
|
Get or set the selected glyph layer names in the default font layer. |
|
Get or set the selected guidelines in the font. |
Normalization¶
Round all appropriate font data to integers. |
|
Use heuristics to set Unicode values in all font glyphs. |
Environment¶
Return the environment's native object wrapped by the current object. |
|
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 astrrepresenting 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 toNone.showInterface – Whether to display the graphical interface. Defaults to
True.
Copy¶
File Operations¶
- BaseFont.path: dynamicProperty¶
Get the path to the font file.
This property is read-only.
- Returns:
A
strdefining the location of the file orNoneto 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 toNone.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 toNone.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.ufozfile. Defaults toNone.
- Raises:
IOError – If no file location is given in either the path parameter or the
BaseFont.pathattribute.
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.
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
BaseInfoclass.
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
BaseGroupsclass.
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
BaseKerningclass.
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
BaseFeaturesclass.
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
BaseLibclass.
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
BaseLibclass, used for storing data that should not be persisted. It is similar toBaseFont.lib, except that its contents will not be saved when calling theBaseFont.savemethod.- Returns:
A temporary instance of the
BaseLibclass.
Example:
>>> font.tempLib["org.robofab.hello"] "world"
Layers¶
- BaseFont.layers: dynamicProperty¶
Get the font’s layer objects.
This property is read-only.
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
listortupleof layer names asstrreflecting the desired order of the font’sBaseLayerobjects.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
BaseLayerinstance.- Returns:
The current default
BaseLayerinstance.
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
BaseLayerinstance to retrieve.- Returns:
The specified
BaseLayerinstance.- 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
BaseLayerinstance.
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
BaseLayerinstance containing the data from layer. The data inserted from layer is the same data as documented inBaseLayer.copy.- Parameters:
- Returns:
The newly inserted
BaseLayerinstance.
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
BaseLayerinstance. 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
BaseLayerinstance.- 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.keys() tuple[str, ...]¶
Get the names of all glyphs in the layer.
This method returns an unordered
tupleof glyph names representing all theBaseGlyphinstances in the active layer. If called from aBaseFontinstance, it returns the glyphs from the default layer. If called from aBaseLayerinstance, it returns the glyphs from the current layer.- Returns:
A
tupleof glyph names representing the glyphs in the current or defaultBaseLayerinstance.
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
listortupleof glyph names reflecting the desired order of the font’sBaseGlyphobjects.- Returns:
A
tupleof 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
BaseGlyphinstances.
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
BaseFontinstance, it checks the default layer. When called from aBaseLayerinstance, it checks the current layer.- Parameters:
name – The name of the glyph to check for.
- Returns:
Note
has_keyis 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
BaseGlyphinstance 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
Falseand rename isFalse, the existing glyph is returned unchanged.If clear is
Falseand rename isTrue, 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
.1or.2to the original glyph name.When called from a
BaseFontinstance, the glyph is created in the default layer. When called from aBaseLayerinstance, the glyph is created in the current layer.- Parameters:
- Returns:
The newly created or existing
BaseGlyphinstance.
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
BaseGlyphinstance containing the data from glyph. The data inserted from glyph is the same data as documented inBaseGlyph.copy.- Parameters:
- Returns:
The newly inserted
BaseGlyphinstance.
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
BaseFontinstance, it removes the glyph from the default layer. When called from aBaseLayerinstance, 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
tuplecontaining instances of theBaseGuidelineclass.>>> 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
BaseGuidelinewith 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 toNone.name – The optional name for the guideline as a
str. Defaults toNone.color – The optional color for the guideline as a Color. Defaults to
None.guideline – The optional
BaseGuidelineinstance from which to copy values. If position, angle, name, or color are specified, those values will be used instead. Defaults toNone.
- Returns:
The newly appended instance of the
BaseGuidelineclass.
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
BaseGuidelineobject or an integer representing aBaseGuideline.index.- Raises:
ValueError if no guideline is found at the given index.
Example:
>>> font.removeGuideline(guideline) >>> font.removeGuideline(2)
Interpolation¶
- BaseFont.isCompatible(other: BaseFont, cls=None) tuple[bool, FontCompatibilityReporter][source]¶
Evaluate interpolation compatibility with another font.
This method will return a
boolindicating if the font is compatible for interpolation with other, and astrcontaining compatibility notes.- Parameters:
other – The other
BaseFontinstance to check compatibility with.- Returns:
A
tuplewhere the first element is aboolindicating compatibility, and the second element is afontParts.base.compatibility.FontCompatibilityReporterinstance.
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
intorfloator atupleof twointorfloatvalues representing the factors(x, y).minFont – The
BaseFontinstance corresponding to the 0.0 position in the interpolation.maxFont – The
BaseFontinstance corresponding to the 1.0 position in the interpolation.round – A
boolindicating whether the result should be rounded to integers. Defaults toTrue.suppressError – A
boolindicating whether to ignore incompatible data or raise an error when such incompatibilities are found. Defaults toTrue.
- 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¶
Mapping¶
- BaseFont.getCharacterMapping() dict[int, tuple[str, ...]][source]¶
Get the font’s character mapping.
This method creates a
dictmapping 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.
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
dictmapping each component glyph name in the font to atuplecontaining the composite glyph names that include the comoponent.- Returns:
A
dictof 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:
- Returns:
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
listof layer names representing theBaseLayerinstances to select.- Returns:
A
tupleof layer names representing the currently selectedBaseLayerinstances.
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
listof eitherBaseGuidelineinstances to select or their corresponding indexes.- Returns:
A
tupleof currently selectedBaseGuidelineinstances.
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¶
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()