Planning the designspace

Before we start, it’s a good idea to make a sketch of the designspace we’re going to build:

  • How many sources will it contain? Along how many axes?
  • Where will the sources be positioned?
  • Are there any named instances? Where?
  • Will there be any special rules? (for example shape substitutions)

We’ll be using the MutatorSans family as an example. Its designspace contains:

  • 4 sources along two axes, width and weight
  • 1 glyph substitution rule
  • 1 instance named Medium

Notice how the interpolation space does not include a Regular source, only extreme styles – this is a design decision. There are other ways to setup a weight/width designspace, give it a try!

Designing the sources

Having a blueprint of the designspace, we can now focus on designing the sources.

These are the 4 sources in MutatorSans, each one stored as a separate UFO font.

It’s also possible to store all sources as layers of a single font. If you choose to work this way, keep in mind that these layers do not have their own kerning.

The usual rules and recommendations about drawing for interpolation apply:

  • glyphs must be compatible across all sources (see next section)
  • use overlapping paths to have more control over the shapes

It’s usually a good idea to draw the sources and build the designspace iteratively: draw, preview interpolations, adjust the drawings and/or parameters, preview again etc.

Useful tools

Skateboard
help users to navigate complex design spaces and to keep outlines under control
Delorean: Interpolation Preview, Interpolation Slider
preview interpolation result while drawing
Overlay UFOs
view other sources in the background layer
ShowSparks
view one-to-one relations between points in all open fonts
EditThatNextMaster
easily switch between sources in glyph, space or font windows

Making sure all sources are compatible

Interpolation requires all source fonts to be compatible. This means that:

  1. all sources must have the same glyphs as the neutral
  2. in each glyph in all sources, the following must match:
    1. number of contours
    2. direction of each contour
    3. number of on-curve and off-curve points

Older interpolation tools may interpolate a straight segment with a curve by assuming there are off-curve points on top of the on-curves. In variable fonts this is not possible, and it is a good design practice to have all the points in the sources.

Useful tools

Prepolator
an extension to detect and fix compatibility problems between fonts
Checking interpolation compatibility
some examples of how to check interpolation compatibility with code

Creating the designspace

The .designspace file is where all information required to build a family of fonts or a variable font is stored.

  • each axis is given a name and a range of values
  • together, all axes define a coordinate space
  • sources are inserted into specific locations of this coordinate space
  • instances are defined as new locations with names

These are the axes and locations in the example MutatorSans designspace:

Useful tools

Different tools can be used to create .designspace files:

DesignSpaceEditor
an open-source extension to edit raw designspace data
DesignSpaceDocument
a Python library to read & write .designspace files with code

Adding glyph substitution rules

Interpolation produces continuous variation between sources. Glyph substitution rules allow us to introduce local discontinuous changes to areas of the designspace, switching one set of glyph contours for another.

MutatorSans includes a glyph substitution rule to ‘fold’ the serifs of the I if the width parameter is below a certain value:

Defining instances

Variable fonts provide a continuous gradient of variations called instances. Instances are designated by a location (for example width=500, weight=250) in the design space, but designers can pre-define some of these variations to have names, like Regular, Bold, or Ultra Wide Thin.

You can set named instances using the DesignSpace Editor extension. Switch to the “Instances” pane, hit + and fill out the new cells in the table:

You can also use the FontTools designspaceLib, check this section of Creating designspace files.

These named instances will be accessible to users in typesetting software. You can list the available named instances of a font using the DrawBot .listNamedInstances() method.

Generating variable fonts

The recommended way of building variable fonts in RoboFont is using the Batch extension. Besides generating static fonts, Batch can also generate a variable font from a .designspace file (and a set of compatible UFO sources).

The Batch extension is open-source and can be installed with Mechanic 2.

The requirements for building variable fonts are stricter than those for building static fonts. Batch does a lot of work behind the scenes to fix compatibility issues between the sources. See the Batch documentation for more details.

Generating variable fonts with the Batch extension

Use the menu File > Batch to open the Batch window:

  1. drag the .designspace file into the list (or use the Open button)
  2. open the section Variable Fonts, and select the desired options
  3. click on the Generate button to generate the variable font

Generating variable fonts with code

The variable font generator included inside the Batch extension can also be used programmatically: you can import it into your scripts, and use it to generate variable fonts from .designspace files – without opening the Batch window.

The lib folder of every installed extension is added to the sys.path – so code from one extension can be accessed by another extension or by a script.

The example script below generates a variable font from the MutatorSans .designspace file and linked UFO sources.

import variableFontGenerator

desingSpacePath = 'myMutatorSansFolder/MutatorSans.designspace'
varFontPath = 'myMutatorSansFolder/MutatorSans.ttf'

p = variableFontGenerator.BatchDesignSpaceProcessor(desingSpacePath)
p.generateVariationFont(varFontPath)

Last edited on 01/09/2021