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 :)