Deathshadow's Madness
Madness and you, perfect together

The Image

demo font image thumbnail Click for Full 1152x180 Image

History aside, we need an image to pull that information from. Easiest way I've always found is to just make a 32x16 grid of characters for the printable members of the 7 bit ASCII set (character codes 32..127). You'll notice the example font is quite large, each glyph being 36x60 for a whopping 1152x180 total image size. I did this because there's an old saying in media - garbage in, garbage out. The higher resolution your source image, the better it will look when rendered - even when sampling to smaller sizes. I'm convinced most of the times fonts look like ass when upsized or downsized is that you aren't using big enough a source image!

The 'test_36x60' font is Arial Bold, rendered in Paint Shop Pro with "stroke" turned of so it's just a fill at "size 28" - whatever the **** paint program sizes have to do with anything (which near as I can tell is nothing). I tweaked the sizes of a few elements to make them fit our 36x60 box, and rounded off a few of the square corners to tweak Microsofts 'for screen' font design to work better with openGL. I used two thirds of the height as the baseline to leave plenty of room for complex descenders, and allowed the top at that "28" size fall where it may, which gave a little bit of extra space for ascenders. This works out really nice for the parenthesis as I tweaked them to go above the capsline and below the baseline by the same amount.

To make the spacing simple, I set up a grid of 12x20, which divided the character into a 3x3 block, letting me see the baseline as well as have a general impression of width. I manually placed each letter into the grid justified left, simplifying calculating the kerning.

For a save format to get it into Pascal, I choose PCX for a variety of reasons.

  1. As useful as image libraries like SDL_Image and Vampyre are, I really dislike the idea of using anywhere from 200-300k in DLL's just so my images don't take 100k apiece. We just don't need anything that complex.
  2. All we care about making is an alpha channel - we don't need to dick with luminance or colors so why not just make a 8 bit greyscale and convert it to GL_LUMINANCE_ALPHA in software? Makes drawing our fonts easy too, just make 'em black and white letting our program do the gruntwork of transparency. Any opportunity to make it so we don't have to dick with layers is welcome in my book.
  3. Given that in a font you usually have long runs of black and long runs of white, and even with anti-aliasing only have a handful of pixels in-between the two extremes PCX's variation of RLE can deliver pretty darned good compression.

Originally I was thinking just use .pcx with a .kerning file and say "close enough", but after looking at the data we're dealing with I thought maybe we could do better/simpler/faster. Since in PCX colors 192..255 take two bytes, and our long runs are only compressed 63:2 max, it doesn't quite fit our data set where all we really need to spend time on compressing is 0 and 255 (black and white).