ufo2otf Makes OTF’s, Webfonts and CSS From UFO’s

A greyish starry night with a baby blue ufo shining its purple light downwards, projecting an uppercase A, slab serif.

Introducing ufo2otf

ufo2otf is a command line utility that takes UFO font sources and generates OTF’s and webfonts. It helps you to translate as quickly as possible your font editor’s working files into fonts one can use and install, on one’s own system, and on the web.

Especially if you are following tellyou’s lead and releasing your fonts early and often, you can profit from automating this process. 


Installing ufo2otf is quite easy. Well, you have to use the command line, but since ufo2otf itself runs on the command line, that is fair game. It is a good idea to learn about the command line.

On a Mac, you can install it like this:

sudo easy_install ufo2otf


Then, you can run ufo2otf and have it tell you if you have got all the dependencies set up:

ufo2otf --diagnostics 

If everything works, and the folder in which you find yourself, you can create an otf as such:

ufo2otf NimbusSanL-Regu.ufo

Which will create NimbusSanL-Regu.otf. You can also create multiple otf’s by passing multiple arguments:

ufo2otf NimbusSanL-Regu.ufo NimbusSanL-ReguItal.ufo

Which creates NimbusSanL-Regu.otf and NimbusSanL-ReguItal.otf. To also generate webfonts we pass the option --webfonts:

ufo2otf NimbusSanL-Regu.ufo NimbusSanL-ReguItal.ufo --webfonts

Which will additionaly create a webfonts folder with ttf, eot and woff versions of the fonts, and a css stylesheet that links the different versions together.

From the command line there is even a way in which you can run it for all the ufos in the current folder. This is what I did when I created the webfonts and stylesheet for the article on the GhostScript fonts:

ufo2otf *.ufo --webfonts

Font compilers

Traditionally, computer programs are written in a language like C, which is readable to (some) humans, and then compiled to machine code, which is readable to the computer. The program that takes care of this step is called the compiler.

If you have a set of UFO source files, the same logic applies: the UFO is human-readable text (even if, in this case, you never really write it yourself), and it requires a compilation step to turn it into smaller, quicker font files that your operating system knows how to use.
 A program that is widely used in the font industry is the Adobe Font Development Kit for Opentype. It comes with the makeotf command line program which is able to create otf files from a specific layout of (PostScript) source files. Font editors like Fontlab use it to generate their Opentype/CFF fonts. To use AFDKO with UFO’s, Tal Leming has created a bridge called ufo2fdk. This is a python library. You first read in the UFO using another python library, Robofab: Robofab reads in the UFO, and ufo2fdk passes it on to the AFDKO, which generates the font. 

The AFDKO has some downsides when using it for a public project, where you might have a very heterogeneous working environment. It is closed source, which means there is no way that you can adapt it to new situations. For example, it is unavailable on Linux, which is not just a problem for those designers running on Linux, but also when embedding it into a web service.

The alternative comes in the form of the Open Source font editor FontForge. FontForge is able to read a large number of font formats, including UFO, and can generate fonts as well. FontForge is scriptable with python, and you can use FontForge in your own python scrips without launching the graphical user interface. This makes it especially suitable to be used in a compilation workflow.

To generate OTF’s, ufo2otf can use both the AFDKO and FontForge. By default, it will use whichever compiler is installed (with a preference for FontForge if both are present). You can also explicitly tell it which compiler to use. This can be quite handy because different compilers might interpret UFO differently, and finding out about such inconsistencies can help to fix implementation details, or to fix ambiguities in the UFO specification.

To generate webfonts, one needs to have FontForge installed. For the webfonts, ufo2otf will automatically perform a number of crude optimisations that are meant to make a typeface more suitable for the screen.

Why one needs a compiler for web fonts

Asides writing OTF’s, one might want to create other kind of typefaces that cater to the environment of the web. In the early days of @font-face support, serving typefaces on the web is an onerous endeavour. Only one browser, Safari, supports regular otf and ttf fonts. Internet Explorer supports an alternative format, yet it must be created from a desktop application that only runs onder Windows. Early versions of Mobile Safari require yet another format: SVG fonts. The conversions needed to create all these versions, and the CSS rules required to get them all to work together, is daunting.

It is at this point that FontSquirrel comes to the scene. This website offers you the possibility to create @font-face-kits: for a font you upload yourself, all the necessary versions are created, along with a CSS file. Running what probably is a headless version of Fontforge, together with a slew of other tools, the service proposes all kinds of useful modifications to your files to make them more fit to the web: automatic hinting, subsetting of the font to a defined character set (easier to download).

The ease of use offered by FontSquirrel is surely an important catalyst in the way in which @font-face ends up defining the face of the web. Using Fontsquirrel, however, does has its downsides, especially when setting up an automated workflow like you do in a larger organisation or in an open source project. As a website, it is not easy to automate. Its interface is made for humans ticking the boxes, not for hooking into scripts: there is no API or Application Programmatic Interface. FontSquirrel is also always changing: this means that you can not count on an option you used yesterday to be available today. This could be OK if it were Open Source, in which case you could choose a version to run on your own computer locally, but this is not the case.

Proper css for font families

A nice bonus when generating webfonts with ufo2otf is that it produces a more usable CSS than FontSquirrel. In CSS, one can group multiple @font-face declarations into one family. One can declare a font-file to use for bold, another one for regular and yet another for the italic. This is what you want, for example, if you use together NimbusSanL-Regu.otf, NimbusSanL-ReguItal.otf, NimbusSanL-Bold.otf and NimbusSanL-BoldItal.otf

Font Squirrel produces:

@font-face {
    font-family: 'nimbus_sans_lregular';
    src: url('nimbussanl-regu-webfont.eot');
    src: url('nimbussanl-regu-webfont.eot?#iefix') format('embedded-opentype'),
         url('nimbussanl-regu-webfont.woff') format('woff'),
         url('nimbussanl-regu-webfont.ttf') format('truetype'),
         url('nimbussanl-regu-webfont.svg#nimbus_sans_lregular') format('svg');
    font-weight: normal;
    font-style: normal;


@font-face {
    font-family: 'nimbus_sans_lreguital';
    src: url('nimbussanl-reguital-webfont.eot');
    src: url('nimbussanl-reguital-webfont.eot?#iefix') format('embedded-opentype'),
         url('nimbussanl-reguital-webfont.woff') format('woff'),
         url('nimbussanl-reguital-webfont.ttf') format('truetype'),
         url('nimbussanl-reguital-webfont.svg#nimbus_sans_lreguital') format('svg');
    font-weight: normal;
    font-style: normal;


@font-face {
    font-family: 'nimbus_sans_lbold';
    src: url('nimbussanl-bold-webfont.eot');
    src: url('nimbussanl-bold-webfont.eot?#iefix') format('embedded-opentype'),
         url('nimbussanl-bold-webfont.woff') format('woff'),
         url('nimbussanl-bold-webfont.ttf') format('truetype'),
         url('nimbussanl-bold-webfont.svg#nimbus_sans_lbold') format('svg');
    font-weight: normal;
    font-style: normal;

@font-face {
    font-family: 'nimbus_sans_lbolditalic';
    src: url('nimbussanl-boldital-webfont.eot');
    src: url('nimbussanl-boldital-webfont.eot?#iefix') format('embedded-opentype'),
         url('nimbussanl-boldital-webfont.woff') format('woff'),
         url('nimbussanl-boldital-webfont.ttf') format('truetype'),
         url('nimbussanl-boldital-webfont.svg#nimbus_sans_lbolditalic') format('svg');
    font-weight: normal;
    font-style: normal;

Instead of creating one font family, Font Squirrel uses four: nimbus_sans_lregular, nimbus_sans_lreguital, nimbus_sans_lbold and nimbus_sans_lbolditalic. Even if there are italics and bolds, they all have font-style: normal and font-weight: normal.
In ufo2otf we create just one font family, Nimbus Sans L, and change the font-weight and the font-style in accordance with the font variant:

@font-face {
    font-family: 'Nimbus Sans L';
    font-style: 'normal';
    font-weight: '400';
    src: url('NimbusSanL-Regu.eot'); /* IE9 Compat Modes */
    src: url('NimbusSanL-Regu.eot?#iefix') format('embedded-opentype'),
         url('NimbusSanL-Regu.woff') format('woff'),
         url('NimbusSanL-Regu.ttf')  format('truetype');

@font-face {
    font-family: 'Nimbus Sans L';
    font-style: 'italic';
    font-weight: '400';
    src: url('NimbusSanL-ReguItal.eot'); /* IE9 Compat Modes */
    src: url('NimbusSanL-ReguItal.eot?#iefix') format('embedded-opentype'),
         url('NimbusSanL-ReguItal.woff') format('woff'),
         url('NimbusSanL-ReguItal.ttf')  format('truetype');

@font-face {
    font-family: 'Nimbus Sans L';
    font-style: 'normal';
    font-weight: '700';
    src: url('NimbusSanL-Bold.eot'); /* IE9 Compat Modes */
    src: url('NimbusSanL-Bold.eot?#iefix') format('embedded-opentype'),
         url('NimbusSanL-Bold.woff') format('woff'),
         url('NimbusSanL-Bold.ttf')  format('truetype');

@font-face {
    font-family: 'Nimbus Sans L';
    font-style: 'italic';
    font-weight: '700';
    src: url('NimbusSanL-BoldItal.eot'); /* IE9 Compat Modes */
    src: url('NimbusSanL-BoldItal.eot?#iefix') format('embedded-opentype'),
         url('NimbusSanL-BoldItal.woff') format('woff'),
         url('NimbusSanL-BoldItal.ttf')  format('truetype');

This is easier to use: we can set the font-family Nimbus Sans L on the body, and bold text will automatically be rendered in the proper bold. With the Fontsquirrel CSS, you will need to explicitly assign a different font to the parts of the body that need to be rendered bold:

strong, b { 
font-style: normal;
font-family: 'nimbus_sans_lbold'

Note that ufo2otf’s approach is a lot more convenient (and more semantically correct), but less foolproof: it relies on the font providing proper metadata. Also, while providing support for quite some font weights, CSS does not allow for a lot of different font-styles: only normal and italic. So you can’t have, for example, a normal and a condensed version in the same family. ufo2otf tries to counter this by creating a new font family for such variants:

@font-face {
    font-family: 'Nimbus Sans L Condensed';
    font-style: 'normal';
    font-weight: '700';
    src: url('NimbusSanL-BoldCond.eot'); /* IE9 Compat Modes */
    src: url('NimbusSanL-BoldCond.eot?#iefix') format('embedded-opentype'),
         url('NimbusSanL-BoldCond.woff') format('woff'),
         url('NimbusSanL-BoldCond.ttf')  format('truetype');

If you are curious how ufo2otf goes about its font detection, it is a simple Python based program and it is in its source code that it tells the whole story.


For the webfonts, ufo2otf will automatically perform a number of crude optimisations that are meant to make a typeface more suitable for the screen.

According to what I learned at the ATypI session on web sessions, according to the SIL Open Font License, you have to rename a changed typeface to avoid confusion with the original. This also holds for the kind of modifications like hinting and subsetting you would normally use when repurposing fonts for the web.

Good call. So I should add a part to the script that changes the name in a random way?

By the way, a related project (that might make ufo2otf at some point) is Font Bakery by Mikhail Kashkin and Dave Crossland. Besides—I imagine—more fine grained control on the optimisations of your web fonts, it will run tests on your fonts to detect possible technical problems: 

You give it a font project git repository, tell it which license the project is under, which font source files you wish to build into binaries, and set some build options. It then runs tests on the sources, and if they pass, builds the fonts and runs further tests on the binaries.

I never opened a font for which FontForge did not find errors.

I would prefer it to tell me Everything is OK


Leave a comment