1 DesignSpaceDocument Python API

An object to read, write and edit interpolation systems for typefaces. Define sources, axes, rules, variable fonts and instances.

Get an overview of the available classes in the Class Diagram below:

UML class diagram of designspaceLib

UML class diagram of designspaceLib. Click to enlarge.

DesignSpaceDocument

class fontTools.designspaceLib.DesignSpaceDocument(readerClass=None, writerClass=None)[source]

Read, write data from the designspace file

filename

String, optional. When the document is read from the disk, this is its original file name, i.e. the last part of its path.

When the document is produced by a Python script and still only exists in memory, the producing script can write here an indication of a possible “good” filename, in case one wants to save the file somewhere.

lib

Custom data associated with the whole document.

classmethod fromfile(path, readerClass=None, writerClass=None)[source]
classmethod fromstring(string, readerClass=None, writerClass=None)[source]
tostring(encoding=None)[source]
read(path)[source]
write(path)[source]
updatePaths()[source]

Right before we save we need to identify and respond to the following situations: In each descriptor, we have to do the right thing for the filename attribute.

case 1. descriptor.filename == None descriptor.path == None

– action: write as is, descriptors will not have a filename attr. useless, but no reason to interfere.

case 2. descriptor.filename == “../something” descriptor.path == None

– action: write as is. The filename attr should not be touched.

case 3. descriptor.filename == None descriptor.path == “~/absolute/path/there”

– action: calculate the relative path for filename. We’re not overwriting some other value for filename, it should be fine

case 4. descriptor.filename == ‘../somewhere’ descriptor.path == “~/absolute/path/there”

– action: there is a conflict between the given filename, and the path. So we know where the file is relative to the document. Can’t guess why they’re different, we just choose for path to be correct and update filename.

addSource(sourceDescriptor)[source]
addSourceDescriptor(**kwargs)[source]
addInstance(instanceDescriptor)[source]
addInstanceDescriptor(**kwargs)[source]
addAxis(axisDescriptor)[source]
addAxisDescriptor(**kwargs)[source]
addRule(ruleDescriptor)[source]
addRuleDescriptor(**kwargs)[source]
asdict()
property log
newDefaultLocation()[source]

Return default location in design space.

updateFilenameFromPath(masters=True, instances=True, force=False)[source]
newAxisDescriptor()[source]
newSourceDescriptor()[source]
newInstanceDescriptor()[source]
getAxisOrder()[source]
getAxis(name)[source]
findDefault()[source]

Set and return SourceDescriptor at the default location or None.

The default location is the set of all default values in user space of all axes.

normalizeLocation(location)[source]
normalize()[source]
loadSourceFonts(opener, **kwargs)[source]

Ensure SourceDescriptor.font attributes are loaded, and return list of fonts.

Takes a callable which initializes a new font object (e.g. TTFont, or defcon.Font, etc.) from the SourceDescriptor.path, and sets the SourceDescriptor.font attribute. If the font attribute is already not None, it is not loaded again. Fonts with the same path are only loaded once and shared among SourceDescriptors.

For example, to load UFO sources using defcon:

designspace = DesignSpaceDocument.fromfile(“path/to/my.designspace”) designspace.loadSourceFonts(defcon.Font)

Or to load masters as FontTools binary fonts, including extra options:

designspace.loadSourceFonts(ttLib.TTFont, recalcBBoxes=False)

Parameters
  • opener (Callable) – takes one required positional argument, the source.path, and an optional list of keyword arguments, and returns a new font object loaded from the path.

  • **kwargs – extra options passed on to the opener function.

Returns

List of font objects in the order they appear in the sources list.

AxisDescriptor

class fontTools.designspaceLib.AxisDescriptor(*, tag=None, name=None, labelNames=None, minimum=None, default=None, maximum=None, hidden=False, map=None)[source]

Simple container for the axis data Add more localisations?

flavor = 'axis'
serialize()[source]
map_forward(v)[source]
map_backward(v)[source]
asdict()
compare(other)

DiscreteAxisDescriptor

AxisLabelDescriptor

LocationLabelDescriptor

RuleDescriptor

class fontTools.designspaceLib.RuleDescriptor(*, name=None, conditionSets=None, subs=None)[source]

Represents the rule descriptor element

<!-- optional: list of substitution rules -->
<rules>
    <rule name="vertical.bars">
        <conditionset>
            <condition minimum="250.000000" maximum="750.000000" name="weight"/>
            <condition minimum="100" name="width"/>
            <condition minimum="10" maximum="40" name="optical"/>
        </conditionset>
        <sub name="cent" with="cent.alt"/>
        <sub name="dollar" with="dollar.alt"/>
    </rule>
</rules>
asdict()
compare(other)

Evaluating rules

fontTools.designspaceLib.evaluateRule(rule, location)[source]

Return True if any of the rule’s conditionsets matches the given location.

fontTools.designspaceLib.evaluateConditions(conditions, location)[source]

Return True if all the conditions matches the given location. If a condition has no minimum, check for < maximum. If a condition has no maximum, check for > minimum.

fontTools.designspaceLib.processRules(rules, location, glyphNames)[source]

Apply these rules at this location to these glyphnames - rule order matters

SourceDescriptor

class fontTools.designspaceLib.SourceDescriptor(*, filename=None, path=None, font=None, name=None, location=None, layerName=None, familyName=None, styleName=None, copyLib=False, copyInfo=False, copyGroups=False, copyFeatures=False, muteKerning=False, muteInfo=False, mutedGlyphNames=None)[source]

Simple container for data related to the source

flavor = 'source'
font

Any Python object. Optional. Points to a representation of this source font that is loaded in memory, as a Python object (e.g. a defcon.Font or a fontTools.ttFont.TTFont).

The default document reader will not fill-in this attribute, and the default writer will not use this attribute. It is up to the user of designspaceLib to either load the resource identified by filename and store it in this field, or write the contents of this field to the disk and make `filename point to that.

property path

The absolute path, calculated from filename.

property filename

The original path as found in the document.

asdict()
compare(other)

VariableFontDescriptor

RangeAxisSubsetDescriptor

ValueAxisSubsetDescriptor

InstanceDescriptor

class fontTools.designspaceLib.InstanceDescriptor(*, filename=None, path=None, font=None, name=None, location=None, familyName=None, styleName=None, postScriptFontName=None, styleMapFamilyName=None, styleMapStyleName=None, localisedFamilyName=None, localisedStyleName=None, localisedStyleMapFamilyName=None, localisedStyleMapStyleName=None, glyphs=None, kerning=True, info=True, lib=None)[source]

Simple container for data related to the instance

flavor = 'instance'
lib

Custom data associated with this instance.

property path
property filename
setStyleName(styleName, languageCode='en')[source]
getStyleName(languageCode='en')[source]
setFamilyName(familyName, languageCode='en')[source]
getFamilyName(languageCode='en')[source]
setStyleMapStyleName(styleMapStyleName, languageCode='en')[source]
getStyleMapStyleName(languageCode='en')[source]
setStyleMapFamilyName(styleMapFamilyName, languageCode='en')[source]
getStyleMapFamilyName(languageCode='en')[source]
asdict()
compare(other)

Subclassing descriptors

The DesignSpaceDocument can take subclassed Reader and Writer objects. This allows you to work with your own descriptors. You could subclass the descriptors. But as long as they have the basic attributes the descriptor does not need to be a subclass.

class MyDocReader(BaseDocReader):
    axisDescriptorClass = MyAxisDescriptor
    discreteAxisDescriptorClass = MyDiscreteAxisDescriptor
    axisLabelDescriptorClass = MyAxisLabelDescriptor
    locationLabelDescriptorClass = MyLocationLabelDescriptor
    ruleDescriptorClass = MyRuleDescriptor
    sourceDescriptorClass = MySourceDescriptor
    variableFontsDescriptorClass = MyVariableFontDescriptor
    valueAxisSubsetDescriptorClass = MyValueAxisSubsetDescriptor
    rangeAxisSubsetDescriptorClass = MyRangeAxisSubsetDescriptor
    instanceDescriptorClass = MyInstanceDescriptor

class MyDocWriter(BaseDocWriter):
    axisDescriptorClass = MyAxisDescriptor
    discreteAxisDescriptorClass = MyDiscreteAxisDescriptor
    axisLabelDescriptorClass = MyAxisLabelDescriptor
    locationLabelDescriptorClass = MyLocationLabelDescriptor
    ruleDescriptorClass = MyRuleDescriptor
    sourceDescriptorClass = MySourceDescriptor
    variableFontsDescriptorClass = MyVariableFontDescriptor
    valueAxisSubsetDescriptorClass = MyValueAxisSubsetDescriptor
    rangeAxisSubsetDescriptorClass = MyRangeAxisSubsetDescriptor
    instanceDescriptorClass = MyInstanceDescriptor

myDoc = DesignSpaceDocument(MyDocReader, MyDocWriter)

Helper modules

fontTools.designspaceLib.split

See Scripting > Working with DesignSpace version 5 for more information.

fontTools.designspaceLib.stat

fontTools.designspaceLib.statNames