Yeah! A designspace is file that contains the plans for an interpolation system for a typeface. It describes how the source fonts relate and how they should interpolate. It defines the dimensions in which the typeface developes, for instance “weight”, “width”, or other things. A designspace also stores information about the instances, specific locations in the designspace that are interesting and what they need to be called.
Designspaces can be used to build variable fonts, but you can also use them to generate fixed UFOs.
This text is an introduction to designspace construction. It does not go into detail how to design letterforms for interpolation, or things like family planning. That is for other chapters. To avoid getting tangled in typographic terminology, the dimensions in this text are named after colors.
Tools can interpret designspaces in different ways depending on what they’re trying to make. For a variable font the requirements are different from making a couple of UFOs. This text won’t go into implementation differences. But for instance MutatorMath does not handle non-aligned off-axis masters so well, but it is great for extrapolation and anisotropic experiments. The FontTools / varlib interpreter will try to fold everything into a variable font. This is complex and varlib will be much stricter. So, it can happen that you construct a designspace for a simple interpolation and then later discover that it needs adjustments. That is ok. The designspace, the decisions where to put masters and how to draw them is as much a part of the design process as drawing the letterforms themselves.
We can draw masters as dots and their interpolations as lines between them.
But how do you know which master goes where and where do you start? Also: how to make sure we don’t have to write new interpolation code whenever a new master is added, or for every possible constellation of masters that might be necessary in the future?
In designspace construction there is an elegant solution for this. It allows the system to be assembled one step at a time by adding masters and placing them in a coordinate system. It starts with a default master, here in red and labeled
default. The default is always on the default value of all axes.
We can now add a new master next to the default and by doing so create a new axis. Let’s call it
blue. When we observe the interpolation at coordinate
blue=0 the result is identical to the default. But when we observe the interpolation at
blue=1 it looks like the new master. You can imagine that at
blue=0.5 the interpolation will look a bit like both. We can extend the blue axis by placing a third master at
blue=-1. The blue axis now runs between
1, three masters on a single axis. In typographic terms, this could be light to regular to bold. Or compressed to regular to wide.
Let’s add another axis give it a different color
purple. Again, we add a master but now we say it has value
1 along the
purple axis. This creates a miniature coordinate system. Every point in the rectangle can be addressed as a pair of
purple values. For instance, in fig. 3 the diagram on the left: the purple master is at
purple=1, blue=0, the blue master is at
purple=0, blue=1 and the point marked
a is located at
blue=1. The default sits at
Figure 3, center: this system also has 2 axes, but now with 4 masters and here the blue axis runs between
b is at
The system on the right also has 4 masters, but now they are placed on three axes rather than two. So, point
c is located at
c do not have a master. And yet, the location has coordinates in the designspace. So we should be able to make an interpolation for it: it would show something. This is a form of extrapolation in which all the differences between the default and each master are superimposed. Interesting to explore (for instance with Skateboard). And maybe your designspace does not need a master at every corner, it depends on how you draw the masters.
It’s ok to leave corners open during the design process. But keep in mind that variable fonts can dial up any combination of axes. So you need to make sure the shapes you get at these open corners make sense. In figure 4 the open locations are populated with new masters. Often it is possible to generate an instance for an open location, then clean it up and re-insert it as a new master.
More terminology. If a master can be placed with just one value on a single axis, it is called on-axis. It has a direct line to the default. If it needs more than one value then it is called off-axis. Then it doesn’t have a direct line to the default. In this chapter, on-axis masters are marked blue, the off-axis masters are marked gray.
In figure 4, the cube on the left has 3 axes and 4 open corners (marked as dark gray dots). It is constructed from one default and 3 on-axis masters. Such a system will show a lot of extrapolation. Good for exploring, but maybe not so good for final work.
In the center cube, two of the open corners are populated with master. Depending on the masters, and the goals the designspace has to achieve, some corners can be left open. During the design or even in a final structure. The right cube has all positions filled: a default, 3 on-axis masters, 4 off-axis masters.
Desinspace construction allows a lot of freedom. But not all constructions make sense and not everything will produce results.
On the left in fig. 5: two axes, three masters. But the blue axis doesn’t have a on-axis master. The gray off-axis master is just floating around. This can be solved by changing the default value of the blue axis so that the blue master becomes the default. That will make the gray master on-axis as the system works.
The diagram in the middle has no default, even though the axes expect one there. No default, no interpolation.
The diagram on the right has no masters on the axes and one off-axis master that can’t align with anything. In this case, perhaps the system is better as a single axis with these two masters at the extremes.
A comprehensive list of designspace problems and code to analyse at Github
So far all the off-axis masters lined up nicely with on-axis masters. That means that at each value of an off-axis lication is matched by one from an on-axis master. But.. it can be a lot messier.
In figure 5, we add a master
F somewhere in the middle (top right). Its effects can be noticed everywhere inside the square, but these effects reduce closer to the edges and towards the other masters. Adding master
E (bottom left) has similar effects. But when both
F masters are added (bottom right), there is no easy way to determine how far the effects of each master will be visible. FontTools has an algorithm that sorts the masters. For instance, it prioritizes based on how close they are to the default.
So in this case
E is closest to
D, therefor it it first in line. Its effects will be available to the whole designspace. Master
F is further out, the FontTools algorithm assigns the next largest available space. The effects of
F are limited by
That means that for each non-aligned master you add, the designspace splits and the effective range of each new master is smaller than the previous one. This also happens in higher dimensions, so a bit of care has to be taken with adding such intermediates because it becomes complicated very quickly.
Back to the example above. Suppose you drew the
F master first and were happy to see its effects spread to all the corners of the designspace. And then you add master
E to fix another problem. Then you would notice that adding
E the influence of
F has changed and is no longer visible everywhere. Or, worse, you may not notice and only later discover that some of the problems that
F was intended to remedy are visible again.
This can lead to a sequence of steps in which you observe a problem and try to fix it by adding masters. With each additional master the designspace fractures more and reduces the effectivity of existing masters.
The animation in fig. 6: a two axis system, 4 masters on the corners marked in gray. Then there are 3 off-axis masters, marked
G is static, marked in blue.
F is static as well. Master
E is moving around, orbiting
F. This would of course never happen in a real designspace. But it moves around so you can see how the designspace resolves the influence of these three masters with
E in different places.
Casually adding a new off-axis master might reduce the effects of the masters already in the system. This is not necessarily a bad thing. The code that interprets the designspace needs to create a logical, deterministic order. On the other hand, in type design, these masters represent solid units of time to draw and proof so it is necessary to understand what happens as not to reduce the investment.