How to Create EOT Files without WEFT

CSS3's fonts module contains @font-face, an easy-to-use mechanism for using custom fonts on web pages. It's ready to use in all major browsers, except for their differences in font file format support. Linking directly to OpenType or TrueType fonts in your @font-face rules only works in non-IE browsers. You have to serve Microsoft's proprietary EOT format to IE.

Microsoft provides a tool called WEFT for creating such files. While WEFT might be sufficient for many users, Windows plays no role in my web development toolchain (with the exception of VMs for IE testing, of course). And, frankly, I've found WEFT's GUI to be confusing and unusable. I need to be able to create EOT files under sensible operating systems like, say, FreeBSD.

If you have TrueType (.ttf) files for your desired font, you can use ttf2eot'a simple command-line tool, whose code was extracted from Google Chrome'to generate EOT files. Kudos to Truex for alerting me to this tool. A simple make in the ttf2eot directory will generate the ttf2eot executable, which can be used like so:

$ ttf2eot < Foo.ttf > Foo.eot

Things are a bit more complicated if you have OpenType (.otf), not TrueType files. You'll first have to convert them to TrueType. Fortunately, FontForge can do this. On FreeBSD, this is a simple install from ports:

$ cd /usr/ports/print/fontforge ; sudo make install clean

On Mac OS X, you can install it from MacPorts like so (or at least you will be able to, when bug #20085 is fixed):

$ sudo port install fontforge

Once you've got FontForge installed, create the following script (happily borrowed from the FontForge Scripting Tutorial). Call it convert.pe, make it executable, and drop it in your PATH somewhere.

#!/usr/bin/env fontforge
Open($1)
Generate($1:r + ".ttf")

Now, to create Foo.ttf, you should be able to run the following command:

$ convert.pe Foo.otf

You can automate all of the above steps with GNU Make like so:

%.eot: %.ttf
	ttf2eot < $< > $@

%.ttf: %.otf
	convert.pe $<

You're now equipped to use any font (whose license permits embedding with @font-face) on your website, in an automated fashion, in all major browsers.

Well, that's slightly overstating it. There's a catch. Actually, there are two catches. As describd in beautiful fonts with @font-face, Internet Explorer only recognizes the font-family and src descriptors within @font-face rules, so each family can only contain a single face. So you won't be able to simultaneously use the regular, bold, and italic variants of the same face on the same page, like you can with WEFT. Also, you can't just put a url(foo.eot) rule in your existing src setting. It doesn't understand format() hints and will ignore any @font-face rule containing these hints. (Emphasis mine.) You have to use a separate @font-face rule for IE. At the end of the day, your CSS will look something like this:

/* For IE */

@font-face {
  font-family: "Foo";
  src: url(Foo.eot);
}

/* Other browsers */

@font-face {
  font-family: "Foo";
  src: local('Foo'),
       url(Foo.otf) format("opentype");
}

@font-face {
  font-family: "Foo";
  src: local('Foo Bold'),
       url(FooBold.otf) format("opentype");
  font-weight: bold;
}


@font-face {
  font-family: "Foo";
  src: local('Foo Italic'),
       url(FooItalic.otf) format("opentype");
  font-style: italic;
}

@font-face {
  font-family: "Foo";
  src: local('Foo Bold Italic'),
       url(FooBoldItalic.otf) format("opentype");
  font-weight: bold;
  font-style: italic;
}