Scripting for interpolation


Interpolation
In this session we're going to look at scripting and interpolation. Building an interpolation system has 2 phases: preparing it and using it. Though this isn't necessarily a design / production difference. In the first phase you need to make sure all the data is set up properly, the compatible glyphs in each master, matching contours in each glyph, path directions, start point locations etc. This can be a lot of work, but RoboFab can assist by reporting the problems. The second phase, using the interpolation comes when everything works and rather than look for problems (there shouldn't be any) you just want to generate all the weights as fast as possible and get on with it proofing and other things.
Terminology
The glyphs (or whole fonts) that are used in an interpolation system are usually called masters. The interpolation factor is a number between 0 and 1. With factor = 0 the result will be identical to the first master (in this case glyph "A"), and as you can probably guess, with factor = 1 the result will match glyph "B". Factor =0.5 means the resulting shape will be exactly between the two masters. The factor can actually also be outside the 0, 1 range - in that case we speak of extrapolation. The particular change in a glyph when interpolating from one master to another is called an axis.
Why use RoboFab interpolation?
All the alternatives come with strings attached. FontLab's Blend tool forces points in contours which don't match. This is handy if you're looking for a quick fix, but it can more or less destroy your masters. Alternatively you can use the Multiple Master tools, but this requires all of your masters to be in the same file and drawing this way can be tricky. Since interpolation is a useful process in typedesign, and a good candidate for scripting we decided to include solid interpolation support in Robofab.
Interpolating glyphs
In the first example we're going to interpolate two glyphs in the same font. This can be useful in the design stage, for sketching or testing. The result is stored in a third glyph. Note: if you want to run this example in FontLab, open a new, empty font. Use the circle tool to draw one circle in "A", and again in "B". Make sure these are different enough to tell what's going on.
# robothon06
# interpolate two glyphs in the same font
from robofab.world import CurrentFont
f = CurrentFont()
factor = 0.5
f["C"].interpolate(factor, f["A"], f["B"])
f["C"].update()
You see there are 3 glyphs involved: the two masters ("A" and "B") and a new glyph which is used to store the results. In this case the new glyph is stored as "C", but it can be helpful to give it a more descriptive name. This is not very PostScript-like, but chances are these glyphs won't make it to production anyway, so it's not a problem. Notice that interpolate() is a method of the Glyph object. The Font object has an interpolate method as well, more about that later. The obligatory link to the relevant RoboFab documentation.
Here's the same script, but now it generates a range of interpolated glyphs, each with a better name which tells you which interpolation factor was used:
# robothon06
# interpolate two glyphs in the same font a bunch of times
from robofab.world import CurrentFont
f = CurrentFont()
for i in range(0, 10):
factor = i*.1
name = "result_%f"%factor
print "interpolating", name
f[name].interpolate(factor, f["A"], f["B"])
f.update()
interpolating result_0.000000
interpolating result_0.100000
interpolating result_0.200000
interpolating result_0.300000
interpolating result_0.400000
interpolating result_0.500000
interpolating result_0.600000
interpolating result_0.700000
interpolating result_0.800000
interpolating result_0.900000

Here you see a range of resulting glyphs as they could be generated by the script above.
Rounding errors
When you interpolate in FontLab you need to take into account that the results will be rounded off. Coordinates can only consist of whole numbers, i,e, "101" or "102" but not "101.3290" There is a nice solution for working with floating point precision glyphs using RoboFab. Here's a brief introduction:
# robothon06
from robofab.world import CurrentFont
# We need to import a class with a different
# implementation for the glyph object.
# It looks a bit odd, but this is how it is done
from robofab.objects.objectsRF import RGlyph as _RGlyph
f = CurrentFont()
# pick two compatible glyphs as masters
m1 = f["A"]
m2 = f["B"]
# make a new glyph object from this other glyph class
g = _RGlyph()
# interpolation factor which is bound to make floats
oddFactor = 0.2382345
# go!
g.interpolate(oddFactor, m1, m2)
# let's have a look at the raw results
for contour in g:
for pt in contour.points:
print "float", pt.x, pt.y
# a glyph can round itself off:
g.round()
# and then it looks like integers again
for contour in g:
for pt in contour.points:
print "integer", pt.x, pt.y