Font & Info objects


So now then, you should have your editor fired up. Your RoboFab installed. Locate the output window as well.


If that runs without problems you're good to go. If a new window pops up with a traceback like this it means there's something wrong with the installation.

Traceback (most recent call last):
File "<string>", line 1, in ?
ImportError: No module named

In this documentation, stuff in the output window is indicated with a tinted background. Whenever something is printed in Python code it will end up in the output window.

Huh, import ?

Python can do a lot of different things. Some of its functionality is always available (the built-in things) but most of it is stored in seperate modules. When you want to use code from a different module, you need to import it first so that Python knows it needs to look somewhere else for objects, functions and stuff. Most of the Robofab stuff is stored in the module. Notice that dot there? The dot syntax also works for modules and modules within modules. If you want to import a module and Python can't find it, you will get a traceback with an ImportError. You can also import specific things from another module, then you write:

from someModule import oneSpecificThing
from someModule.subModule import oneSpecificThing
from someModule import anotherSpecificThing, andAnotherThing

# and these:
import someModule
import someModule.subModule

We'll need to import a couple of useful functions from the robofab module to get started. To begin with, we'll look at CurrentFont and CurrentGlyph.


So, suppose you have FontLab, and a font file open. Make sure it is a font you can trash if you have to, and not the single copy of the production master of your newest bestseller. How do you get started talking to that font in Python? Use the CurrentFont() function. This is a special function which will return an object which represents the front most font. When there are no fonts it will return None.

This is how you import CurrentFont:

from import CurrentFont
print CurrentFont()
<RFont font for DemoFont Italic>

A Font object! We'll be using CurrentFont and the font object it returns shortly, but first let's have a look at CurrentFont's siblings: CurrentGlyph and AllFonts.

# open a glyph in FL first!
from import CurrentGlyph
print CurrentGlyph()
<RGlyph for DemoFont.ograve>

CurrentGlyph() returns a Glyph object for the glyph which is at the front. Usually this is the glyph that's open in the current edit window. If there is no edit window, it will be the first glyph of the selection in the font window. If there is no selection, and no edit window, CurrentGlyph will return None. So this is a useful place to start if you want to write a script which manipulates a single glyph and you want an object for that glyph.

# open a couple of fonts in FL first!
from import AllFonts
print AllFonts()
[<RFont font for MyDemoFont>,
<RFont font for AnotherFont Plain>,
<RFont font for AnotherFont Italic>]

AllFonts() returns a list with Font objects, one object for each open font. CurrentFont, CurrentGlyph and AllFonts live in the module. They're useful for writing small scripts in FontLab.

Some attributes of the Font object

So what are the things we can ask the Font object about? What attributes do font objects have? Let's have a look (at the documentation!).

# open a couple of fonts in FL first!
from import CurrentFont
font = CurrentFont()
print font.path
print font.kerning
<RKerning for MyFont Plain>
<RInfo for MyFont Plain>

Hang on! that didn't print anything that looks like kerning, and what's that thing? Remember that objects can contain objects? The object model splits all font related data into smaller, easier to manage pieces. So a Font object has one single Info object which in turn stores all of the naming and dimensions. Same for font.kerning, it's an object which represents all kerning data of the font. We'll get back to the kerning object later.

Some Info attributes

The Info object stores all of the font's names, key dimensions etc.

# robothon 2009
# getting data from the info object

from import CurrentFont

font = CurrentFont()
# naming attributes
# dimension attributes
➔ Download this.
MyDemo Plain

Almost all attributes can also be set to new values. This is when it starts getting interesting.

# robothon 2009
# setting data in the info object

from import CurrentFont

font = CurrentFont()
# naming attributes = "MyFamily"
print = "Roman"
print = + '-' +
# dimension attributes = 600
print = -400

➔ Download this.

A useful method of the Info object is autoNaming(). It assumes you have entered correct data for familyName and styleName. Based on these 2 values, a bunch of variations and permutations are generated and stored in the appropriate fields. These are the basic names, no fancy OpenType stuff.

# robothon 2009
# get a particular glyph

from import CurrentFont
font = CurrentFont() = "myFamilyName" = "myStyleName"

➔ Download this.
myFamilyName myStyleName

Getting to glyphs

We've seen CurrentGlyph and CurrentFont, but how do you we get to other glyphs in a font? A Font object contains glyphs and this is what you do to get to them:

# robothon 2009
# get a particular glyph

from import CurrentFont
font = CurrentFont()
print font['A']
print font['Adieresis']
print font['two']
print font['afii12934']

➔ Download this.
<RGlyph for MyFamily-Roman.A>
<RGlyph for MyFamily-Roman.Adieresis>
<RGlyph for MyFamily-Roman.two>
<RGlyph for MyFamily-Roman.afii12934>

The Font object in this case behaves like a Python dictionary object. Between the [ square brackets ] you can ask for a glyph by its (postscript) name. In Python speak:

value = dictionary[key]

If you want to look at all glyphs in a font, one at a time, you can loop or iterate through the font. It's written like this:

# robothon 2009
# iteration through glyphs in a font

from import CurrentFont

font = CurrentFont()
print "font has %d glyphs" % len(font)
for glyph in font:
    print glyph

➔ Download this.
font has 201 glyphs
<RGlyph for MyFamily-Roman.aring>
<RGlyph for MyFamily-Roman.ordfeminine>
<RGlyph for MyFamily-Roman.less>
<RGlyph for MyFamily-Roman.ograve>
<RGlyph for MyFamily-Roman.V>
<RGlyph for MyFamily-Roman.dollar>
<RGlyph for MyFamily-Roman.circumflex>

A couple of things to look for in the example above:

When you want to be sure about the order in which the glyphs are looked at, you need to sort them first. Example:

# iteration through alphabetically sorted glyphnames
from import CurrentFont

font = CurrentFont()
print "font has %d glyphs" % len(font)

# names is now a list of strings, the names of the glyphs
# not the glyphs themselves!
names = font.keys()

# the list of names is sorted

# now we iterate through the list of names
for glyphName in names:
    # now we ask for the glyph with glyphName
    print font[glyphName]
font has 201 glyphs
<RGlyph for MyFamily-Roman.A>
<RGlyph for MyFamily-Roman.AE>
<RGlyph for MyFamily-Roman.Aacute>
<RGlyph for MyFamily-Roman.Acircumflex>
<RGlyph for MyFamily-Roman.Adieresis>
<RGlyph for MyFamily-Roman.Agrave>
<RGlyph for MyFamily-Roman.Aring>
<RGlyph for MyFamily-Roman.Atilde>
<RGlyph for MyFamily-Roman.B>

Step by Step

  • Basic Python: Some rules, syntax.
  • Font object, Info object: Introduction to Font and Info objects, with examples.
  • Glyph object and Pen object: Introduction to Glyph and Pen objects
  • Kerning object and glyph building: Introduction to the Kerning object, and a closer look at building glyphs from parts.
  • Interpolation: Scripting for interpolation
  • Production: Scripting for production
  • NoneLab: Adventures in NoneLab, scripting outside the box