Intermediates Interpolation Helper Script

I want to write a script to automatically generate extra intermediate masters orthogonal to an intermediate inside the design space, so that there is always a stable rectangular design space – to make sure a variable font works properly.

Currently if we have an intermediate like such (in this case the intermediate corrects the contrast of the letter ‘o’ slightly and moves the overshoots a bit):

The interpolation get’s all wonky (it’s not meant to scale the entire glyph like such):
Jul-05-2021 16-12-04

That’s because the VF doesn’t have masters at the edges of the designspace like so – since the interpolator requres stable rectangular designspaces:

Keeping in mind if I have multiple intermediates, they always needs to be rectangular spaces (I’m fairly sure the pink ones are necessary to keep the static exports and VF instances consistent):

Right now I have to manually go through a font and work out where along the edges and inside of the designspace I need to generate intermediates. Can someone point me to the maths I need to find where I need to calculate how to ensure rectangular spaces for any number of axes?

1 Like

In the latest version, the first image should work. I implement that only very recently, so it probably needs some improvements. Can you send me your file?

I might have made a mistake, but I think I got the setup from the first picture and it get still all messed up.

Any clues how I can make it work properly? The manual explains how to set up an intermediate, but I cannot find anything about the rules (e.g. do all masters need a matching intermediate). (1.0 MB)

  • screencast of the variable font going haywire,
  • glyphs file
  • v-font
  • test html

Another thing: In G2 one could disable a brace layer as written in the tutorial (e.g. remove one brace or add the word “off”). In G3 that’s not possible anymore. One can check off the “intermediate” layer type, but enabling it afterwards does require re-setting the values).


The algorithm to detect “free” masters is not very robust, yet. It should not sit on a line between two masters. I’ll have a look.

So the setup of my sample is kind of as it should be? Or do I need to change something as well?
In this example, I try to get the TR terminal to be not squished (due to the rotation) in a certain width range.

I’m running into a similar situation. Ended up adding matching intermediates all over which doesn’t feel like it’s the best way.

If this is a way (temporarily, at least) does anyone know of a script that makes it easier to add intermediates on select masters?

+1 for adding a feature to quickly enable and disable intermediates without having to reset values.

1 Like

@Mark the first two images are what you mean by “matching intermediates”, right? Adding these seems to make the v-font work but I guess the question is if they are actually necessary to add.

Also, does it matter under which masters the intermediates are added?


I’m on it. Just need to fish something else.


+1 on being able to disable the intermediates and alternates without losing their last values.

+1 to all of this, those extra brace layers are annoying. I had scripted them for max two axes in glyphs 2 but never generalized it

I would also like to know that. The manual says, that if you leave one field empty, it will then presume it belongs to the master it is added to. That imples that otherwise it doesn’t.

If you’re looking for a function to calculate missing master coordinates:

import itertools

axes_coords = [[] for axis in Font.axes]

for i, axis in enumerate(Font.axes):
	for master in Font.masters:
		if master.axes[i] in axes_coords[i]:

necessary_masters = list(itertools.product(*axes_coords))
missing_masters = []

for master in necessary_masters:
	if master not in [master.axes for master in Font.masters]:
		if master not in missing_masters:
			print("Missing coordinate", master)

You can then use something like this to add the missing masters:

for missing_master in missing_masters:
	missing_master_instance = GSInstance() = "Extreme " + str(missing_master)
	Font.instances[-1].axes = missing_master
	Font.masters[-1].axes = missing_master

Hope this is what you’re looking for.