This is a short explanation of how I got my OS X fonts working in ImageMagick. I won’t guarantee that it’s the best way — leave me a comment if you know better — but it’s what I did.
This worked for me on OS X Leopard 10.5.2, with ImageMagick 6.3.3. I used MacPorts to grab one bit of software I needed, but you can get away without it, I reckon.
This explanation is intended for the more Unix‐geeky Mac user, but frankly, the kind of person who wants to draw graphics using ImageMagick will naturally lean towards Unix geekhood, won’t they?
My problem started when I wanted to use my favourite Mac font, American Typewriter, with ImageMagick. I tried something like this:
convert -background lightblue -fill blue -font AmericanTypewriter \
-pointsize 72 label:"No luck" output.png
…and ended up with this:
convert: unable to read font ‘AmericanTypewriter’.
The fundamental problem is that ImageMagick doesn’t understand the OS X font format, dfont. Dfont files are resource files, effectively directories, which wrap up different varieties of font in a single bundle.
You can check what fonts ImageMagick can see with an IM command like:
identify -list Type
On my system the output was a pretty paltry list.
So, helped by a hint from Peter’s Projects, here’s what I did.
First I found out where my fonts were, by using OS X’s standard Font Book application. If you right‐click on a font in Font Book, you can choose “Reveal In Finder” and it’ll show you where the font file is. Unsurprisingly, American Typewriter and the rest of my fonts were in /Libarary/Fonts.
Then I installed fondu. Fondu extracts the fonts from .dfont files, effectively sucking out all the standard font goodness from these “pay no attention to the man behind the curtain” bundles.
I installed my fondu using MacPorts, which was as easy as typing:
sudo port install fondu
If you’re lucky, you’ll already be a MacPorts user, as that may well be how you got ImageMagick in the first place. On the other hand, it looks like there’s a pre‐built package containing fondu available from the fondu site on SourceForge, so it shouldn’t be too much trouble either way.
Then I figured I’d put my fonts in a nice, MacPorts‐friendly location, carefully not putting them in the /Library/Fonts folder. As root, I created /usr/local/share/fonts to hold my extracted fonts, then let fondu work its magic:
matt-gibsons-computer:~ root# cd /usr/local/share/fonts/ matt-gibsons-computer:fonts root# fondu /Library/Fonts/*.dfont
I got prompted a couple of times whether I wanted to overwrite some files — I figure that some of the extracted fonts had a name clash — but it didn’t seem to be anything I cared about, so I just overwrote them. At some point I may figure out what I lost, but it was a small percentage of the total fonts, and it hasn’t done me any harm so far.
This left me with a load of shiny new extracted fonts, including Amercian Typewriter:
matt-gibsons-computer:fonts root# ls *American* AmericanTypewriter.ttf AmericanTypewriterBold.ttf AmericanTypewriterCondensed.ttf AmericanTypewriterCondensedBold.ttf AmericanTypewriterCondensedLight.ttf AmericanTypewriterLight.ttf
Then I grabbed the imagick_type_gen script from ImageMagick. This generates an ImageMagick font configuration file automagically, by searching your system for fonts that ImageMagick can use.
The locate Database
One problem, though: imagick_type_gen uses the locate database to do its searching. The locate database isn’t live — it’s only updated every now and again (on Leopard it’s updated weekly, for example.)
Rather than waiting a week for the database to be updated so that imagick_type_gen could find the fonts I’d just extracted, I updated the database manually, using the scheduled script that normally kicks it off:
matt-gibsons-computer:~ root# /etc/periodic/weekly/310.locate
That can take a while, as it effectively does a find across your whole disk. I went for a coffee.
Okay, so now imagick_type_gen will actually find some fonts. Try running it; it won’t hurt. You don’t have to be root at this point, or at any point from here on, in fact.
matt-gibsons-computer:~ matt$ imagick_type_gen.pl <?xml version="1.0"?> <typemap> Doing TTF fonts AScore - AScore - AScore <type format="ttf" name="AScore" ...
As you can see, this generates an XML file, which is what ImageMagick uses to figure out what fonts you’ve got. ImageMagick has a system (i.e. all‐users) version of this file in its config directory — on my installation this is /usr/local/lib/ImageMagick-6.3.3/config/type.xml — but you don’t have to overwrite that one if you don’t want to. Personally I took the coward’s way out and just installed a user version of the file.
The user version of the type.xml file goes in $HOME/.magick/type.xml, so (having shoved imagick_type_gen into /usr/local/bin and made it executable, on the grounds it may come in handy in the future) I created my type.xml file:
matt-gibsons-computer:~ matt$ mkdir ~/.magick matt-gibsons-computer:~ matt$ imagick_type_gen > ~/.magick/type.xml
Okay, so I’ve got my fonts extracted, and I have a configuration file that ImageMagick should be able to use to find them. The first thing I did was have another go at listing my available fonts, to see if American Typewriter was among them:
matt-gibsons-computer:~ matt$ identify -list Type | grep American AmericanTypewriter American Typewriter ... AmericanTypewriterB American Typewriter ... AmericanTypewriterC American Typewriter ... AmericanTypewriterCB American Typewriter ... AmericanTypewriterCL American Typewriter ... AmericanTypewriterL American Typewriter ... matt-gibsons-computer:~ matt$
Yay! So, now it was time to have another try at generating my image:
matt-gibsons-computer:~ matt$ convert -background \ lightblue -fill blue -font "AmericanTypewriter" \ -pointsize 72 label:'Hurrah!' doyoufeellucky.png
And there it was, in all its glory.
As with a lot of things ImageMagick related, I’m left with the feeling that there’s probably an easier way of doing this. But if there is, I couldn’t find instructions for it on the web, which is of course the first place I looked. Hopefully this has helped you out, but if you know of a better way of doing this, like I said, please drop me a line :)