Introduction
Mkfont is a command line utility written in C to help create font textures. For example, if you want to display text in an OpenGL program, you can create a polygon for each character in a string and then map a texture of a character onto it. Mkfont can help you to create a font texture, but this program should be used in conjunction with a graphics program such as GIMP.
If you type mkfont at the command line without any parameters, it will show this:
mkfont for Win32 http://home.tiscali.be/zoetrope/
Syntax is: MKFONT [ options ] fontname fontsize infile outfile
-b Bold
-i Italic
-a No anti-aliasing
-w:N Image width (default = 256)
-h:N Image height (default = 256)
-x:N Offset x (default = 0)
-y:N Offset y (default = 0)
-m:N,N,N,N Cell margins (left, top, right, bottom) (default = 0,0,0,0)
And when you invoke mkfont like this:
mkfont times 20 chars.txt times
it will generate a font texture (a TGA file) with Times New Roman characters of point size 20.
The chars.txt file contains the characters you want to draw on the bitmap; in the example above:
ABCDEFGHIJKLM
NOPQRSTUVWXY
Z0123456897
`-=~
!@#$%^&*()
_+[]\\/{}<>
|;:,.'"?
Mkfont will produce two files: times.fnt and times.tga. Times.tga is a 32-bit TGA file which contains a bitmap with the text of chars.txt drawn on it:

Times.fnt contains the coordinates of the character cells:
A = 0 0 19 31
B = 19 0 18 31
C = 37 0 18 31
.
.
.
' = 33 186 4 31
" = 37 186 10 31
? = 47 186 12 31
Mkfont internals
Mkfont creates a new device context by calling CreateDC("DISPLAY", NULL, NULL, NULL).. CreateDC() returns the screen device context: if you draw on it, it will be displayed on the screen. Because we don't want that, we create a compatible DC. Then, we create a DIB section and receive a pointer to a piece of memory which contains an RGB bitmap. We select the bitmap into our device context and we can start drawing the characters. We use GetCharABCWidths() to measure the size of the characters: we must ensure that characters do not overlap each other because of underhang or overhang. It seems that it doesn't always work like it should: if the font is italic, it can happen that the width of the cell is 1 pixel too small.
Note that we draw black text on a white background. When we write the image to a file, we consider the black/gray pixels as the alpha channel. Then, the graphics artist/designer can do whatever he wants with it in a graphics program such as Photoshop or GIMP, e.g., add a shadow.
The ".fnt" file can be read easily by using sscanf(..., "%c = %d %d %d %d", ...).