The .designspace file format

A .designspace file is an XML-based description of a multi-dimensional interpolation space. It contains information about several objects which make up the designspace:

name, tag, mininum/maximum/default values, labels
UFO path, familyName, styleName, layer, location
UFO path, familyName, styleName, location
name, substitutions, conditionSets, conditions

Designspace files were introduced by MutatorMath, and are now used by varLib too.

Creating designspaces with Superpolator

Superpolator is a stand-alone application to design interpolation spaces. It provides an interactive UI with a designspace map, interpolation preview, location editor, rules editor etc.

Superpolator’s native data format is .sp3, but it can also read and write .designspace files.

  1. Define your design space using Superpolator’s interface.
  2. Choose File > Export DesignSpace… to export the data to a .designspace file.

Superpolator requires a paid license for continuous use. A fully functional demo version is also available, and expires after 30 days.

Creating designspaces with DesignSpaceEditor

DesignSpaceEditor is a RoboFont extension which provides a simple interface to create and edit designspace data – without any interactive preview, map etc.

  1. Design your designspace using DesignSpaceEditor’s interface.
  2. Click on the Save button to save the data to a .designspace file.

DesignSpaceEditor is open-source and can be installed with Mechanic 2.

Creating designspaces with designSpaceLib

Designspace files can also be created with code: FontToolsAn open-source library for manipulating font files with Python. supports reading & writing .designspace files using the designSpaceLib.

DesignspaceLib started as DesignSpaceDocument, a separate library, and was recently incorporated into fontTools.

The script below will create a .designspace file for MutatorSans. To try it out, save it in the MutatorSans folder next to the UFOs.

import os

from fontTools.designspaceLib import DesignSpaceDocument, AxisDescriptor, SourceDescriptor, InstanceDescriptor

root = os.getcwd()
doc = DesignSpaceDocument()

familyName = "MutatorMathTest"

# axes

a1 = AxisDescriptor()
a1.maximum = 1000
a1.minimum = 0
a1.default = 0
a1.name = "width"
a1.tag = "wdth"

a2 = AxisDescriptor()
a2.maximum = 1000
a2.minimum = 0
a2.default = 0
a2.name = "weight"
a2.tag = "wght"

# masters

s0 = SourceDescriptor()
s0.path = "MutatorSansLightCondensed.ufo"
s0.name = "master.MutatorMathTest.LightCondensed.0"
s0.familyName = familyName
s0.styleName = "LightCondensed"
s0.location = dict(weight=0, width=0)
s0.copyLib = True
s0.copyInfo = True
s0.copyGroups = True
s0.copyFeatures = True

s1 = SourceDescriptor()
s1.path = "MutatorSansBoldCondensed.ufo"
s1.name = "master.MutatorMathTest.BoldCondensed.1"
s1.familyName = familyName
s1.styleName = "BoldCondensed"
s1.location = dict(weight=1000, width=0)

s2 = SourceDescriptor()
s2.path = "MutatorSansLightWide.ufo"
s2.name = "master.MutatorMathTest.LightWide.2"
s2.familyName = familyName
s2.styleName = "LightWide"
s2.location = dict(weight=0, width=1000)

s3 = SourceDescriptor()
s3.path = "MutatorSansBoldWide.ufo"
s3.name = "master.MutatorMathTest.BoldWide.3"
s3.familyName = familyName
s3.styleName = "BoldWide"
s3.location = dict(weight=1000, width=1000)

# instances

i0 = InstanceDescriptor()
i0.name = 'instance_LightCondensed'
i0.familyName = familyName
i0.styleName = "Medium"
i0.path = os.path.join(root, "instances", "MutatorSansTest-Medium.ufo")
i0.location = dict(weight=500, width=327)
i0.kerning = True
i0.info = True

# rules

# TODO: add rules to match the contents of `MutatorSans.designspace`
# http://github.com/LettError/mutatorSans/blob/master/MutatorSans.designspace

# saving

path = os.path.join(root, "MutatorSans__test123__.designspace")
Last edited on 02/06/2020