Draft
edit

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:

axes
name, tag, mininum/maximum/default values, labels
masters
UFO path, familyName, styleName, layer, location
instances
UFO path, familyName, styleName, location
rules
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"
doc.addAxis(a1)

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

#---------
# 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
doc.addSource(s0)

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)
doc.addSource(s1)

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)
doc.addSource(s2)

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)
doc.addSource(s3)

#-----------
# 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
doc.addInstance(i0)

#-------
# 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")
doc.write(path)

Last edited on 09/10/2018