2009-12-15

New Font Utilities

I’ve extended the font creation utility I discussed a few posts ago so that it now creates Font subclasses in addition to the other three. The bmp2font utility is now capable of producing any of the official Woopsi font classes.

This is great, except actually creating one of the bitmaps is a real pain. I have no intention of mucking about with glyph maps unless I really have to, so I set about creating a utility that would convert a Windows font to a bitmap.

Doing so was slightly tricky. Requesting a particular font size in .NET doesn’t guarantee you a font of that size. Due to the spacing around fonts (which .NET doesn’t provide a way of changing) and the way it calculates font sizes, what you get if you use the built-in APIs is a bitmap with a lot of empty space and not a lot of font. This is clearly no use.

Instead, I came up with a solution in which I render each glyph to its own bitmap, calculate the exact size of each glyph and the overall size of the font, then blit all of the bitmaps to a single master bitmap. Each of the glyphs is left-aligned and no space is wasted. This new “font2bmp” utility can turn any Windows font into BMP file with the minimum of hassle and dimensions.

At this point, I realised that I had a utility to convert from a Windows font to a bitmap, and from a bitmap to a Woopsi font, and that it would probably be a good idea to have a utility that could cut out the middleman and go straight from one font format to the other. Refactoring the two projects produced two DLLs that could be used to achieve this.

A short time later and I’ve got the third utility in the font trilogy, “font2font”. This will convert straight from a Windows font to a Woopsi font.

All three utilities are available in the Subversion repository, and will be in the next release. One minor bugfix - Lakedaemon spotted Woopsi allocating heap memory for no real reason when it converted single chars to strings when setting string values. This was rather wasteful. Woopsi now uses the stack instead.