XMLGameEngine

An engine for describing games built around Xerces, exprtk, and SFML.

View the Project on GitHub beefviper/XMLGameEngine

36. Built-in font

Status: built (lib/source/builtin_font.cpp, lib/include/builtin_font.h, tests/test_builtin_font.cpp)

Why

Text is drawn with a font file, assets/tuffy.ttf, found relative to the directory the program is run from. Run XGECLI from anywhere but a directory that has assets/ next to it and the font is not found. The engine printed a line about it and then drew nothing, so a game loaded and played with every label invisible, which is easy to miss. A game should still be readable when its font is missing, so the engine carries a font inside itself.

Decision

An 8 by 8 pixel glyph for each printable ASCII character (32 to 126) is stored in the program as a constant table, 760 bytes: eight bytes a character, one per row, with the lowest bit of a row the leftmost pixel. The glyphs are the public-domain font8x8 set by Daniel Hepper, itself from the IBM VGA font, with the credit kept in the source.

rasterizeText(text, size, color) draws a string into a Bitmap (34), the same picture type a sprite of <line>s becomes. Each backend, when its font load fails, prints the error once (error: failed to load font: assets/tuffy.ttf - drawing text with the built-in 8x8 font instead) and from then on draws every text from that bitmap instead of from the font. So the fallback is one function and one branch in each backend (the three there were then; the OpenGL backend and XGEGUI’s Qt renderer, added later, do the same), and the same code can be tested without a window.

Options considered

Approximations

Only ASCII, one style, no kerning, and the line height is the cell height (each glyph leaves its last row empty, except for tails, so lines are one row apart); the width and height of a letter cannot be chosen separately from a game file, only from <size>. The real font’s letters are proportional and the fallback’s are not, so a title can be wider or narrower. Checked in the tests and by drawing a sample to a picture; the three window backends were compile-checked only, not run.