4.9. Fonts

The font subsystem allows the definition of fonts that can then be used to render text in the HUD (§4.8) and, in future, in the game world (e.g., for signs, etc). Each font has a name in the directory hierarchy, so they should be referred to using the `` quotes. There are many examples in /common/fonts.

The font texture contains all the letters for a particular size. It commonly has an alpha channel to allow the text to be rendered on a background, and is typically white, so the text colour can be controlled with a mask at render time. However you can use colours if you wish. This can be useful in some cases, for big title text and so on.

A font binds from each unicode code point to a rectangle within the texture. Not every code point need be bound. If a code point is not bound in a font, then the font subsystem tries to find another character that is. First it tries the unicode replacement character "?", then space " " then finally the letter "E", before giving up and skipping the character.

To define a font, use the gfx_font_define function. This takes the name of the font being defined, the name of the texture to use, the line spacing (font height), and then a table giving the texture co-ordinates for each codepoint. Each code point defines a rectangle of texels, by giving the x, y of the bottom left corner of the rectangle, and also the width and height. The texture co-ordinates are relative to the bottom left of the texture. The following font defines codepoints for the letters A and B, and maps the same rectangles to a and b as well. This can be a useful way of making text appear in all capitals.

gfx_font_define(`MyFont`, `MyFont.jpg`, 12, {
    [0x0041] = {0, 0, 10, 12},  -- A
    [0x0042] = {0, 10, 10, 12},  -- B
    [0x0061] = {0, 0, 10, 12},  -- a
    [0x0062] = {0, 10, 10, 12},  -- b

In the above case, both letters are the same size, but this need not be the case. One can define variable width fonts, which are often more attractive than monospaced fonts. If the letters are different heights, they are aligned along the top of the rectangles as the text is rendered. This means you can clip unused texels at the bottom of character, saving texture space.