Deathshadow's Madness
Madness and you, perfect together

glKernedFont - A kerned texture font library for Free Pascal/OpenGL

When working in OpenGL one of the biggest problems is how to render text. There is no built in mechanism for handling it, leaving you to choose one of three methods for implementing it; Raster, vector and texture. Each of these has it's own advantages and drawbacks - Raster means you need individual images for each 'size' of font and does not usually provide any anti-aliasing to smooth the edges, texture often gets blurry if you scale it up/down, and vector consumes a good deal of processing time that could usually be better spent elsewhere.

Of the three, texture usually ends up the best choice - it's scaleable, to make your custom font all you need to do is draw each character onto a grid, but it has one pretty big shortcoming - just like Raster fonts it uses 'fixed kerning' - kerning is the space between characters. Usually when people talk about kerning, they are referring to how the horizontal line at the top of a capital "T" can overhang lowercase letters like "g"... or how the descender on a lowercase "j" can underhang the edge of a square letter like "H" - or how the letter "I" is narrower than the letter "M". Fixed width fonts are not capable of any of that, so they often end up oddly spaced on screen. In the early days of computing that was fine - today, we expect better.

So what can be done about it? Rather than using just a flat bitmap, we can create kerning information for each character. It's actually pretty simple to just store the values by which the fonts should overlap and add them up as you write to the screen. If you want the technical details on how it works, you can find that on my How it Works page.

The API is pretty simple. For the end user it's all wrapped up in a nice little object - all you need is a .glkfont file (typicallly generated from a .PCX and a .kerning textfile by the fontconvert program)

var
	demoFont:tglKernedFont;

The tGLKernedFont.init constructor takes two parameters, first the font name (used as the prefix to the file, the extension is automatically added. The second parameter is the glFloat height range you want the font glyph to be rendered as.

demoFont.init('test_36x60',1);

tglKernedFont.setPosition - tglKernedFont has it's own internal positioning code separate from openGL. I did this so I didn't have to spend time pushing/popping a transform matrix on each and every character, speeding things up greatly. If you want to position each string you output with glTransform then you should call this before each writeString command.

demoFont.setPosition(0,0,0);

There's also the tglKernedFont.scale command you can call, so if you don't want to mess with glScale you can handle it in the unit.

demoFont.scale(2); { make twice as large as normal }

tglKernedFont.writeString shouldn't need too much explanation. I'm amazed looking at some other implementations how convoluted they make something this simple.

demoFont.writeString('Kerned OpenGL Texture Fonts Demo');

... and of course, when you're done, don't forget to clean up.

demoFont.term;

The fontdemo.pp enclosed in the distribution shows pretty much the full capabilities of the library in it's current state. For more infomration read the How it Works section and browse the API Documentation

As mentioned multiple times on this site, the code is released to the public domain. You find it useful, go ahead and use it, just toss in a "glKernedFont unit by Jason M. Knight" somewhere in your credits or accompanying readme/license/documentation.