and sort by:

BMF – ByteMap font format

Version 1.1

offset size meaning
04magic header (0xE1E6D51A)
41version (0x11 for v1.1)
should be equal to or greater than size-under – size-over
61size-over the base line (–128…127)
measure from base line to top of capital letters, in pixels; should be negative
71size-under the base line (–128…127)
measure from base line to lowest extends (of letters like "y", "g"), in pixels; usually positive
81add-space after each char (–128…127)
how many pixels to add after plotting each character
91size-inner (small letters height) (–128…127)
measure from base line to top of small letters; should be negative
101count of used colors
111highest used color attribute
161number of colors in palette (P)
17P*3font palette (RGB, 0…63 per component)
17+P*31title length (T)
18+P*3Ttitle string
19+P*3+T2number of characters in font i.e. having non-zero size or shift (N)
20+P*3+T?’tablo‘ - character bitmap definitions
N * …
01which character
11character width (W)
21character height (H)
31relx – X offset from cursor position (–128…127)
41rely – Y offset from cursor position (–128…127)
51horizontal cursor shift after drawing the character
6W * Hcharacter bitmap (uncompressed, 8 bits per pixel)

Character with zero size (width and height) and zero shift is considered empty/unused and as such is not stored. In addition, zero is a valid size of bitmap; in that case definition of the next character follows right after.


Let addspace = 1 for this example. The red arrow (being size-over) is cursor position during outputing each character in the text.


Pseudocode for loading

file = fopen("font.bmf", "rb");
buffer = fread(file, 18);
if (substr(buffer, 0, 5) != "\xE1\xE6\xD5\x1A\x11") {
    return false; // not a BMF version 1.1
lineHeight = buffer[5];
sizeOver = buffer[6];
sizeUnder = buffer[7];
addSpace = buffer[8];
sizeInner = buffer[9];
usedColors = buffer[10];
highestColor = buffer[11];
colors = buffer[16];
palette = fread(file, colors * 3);
for (i = 0; i < colors * 3; i++) {
    palette[i] *= 4; // stretch 0..63 values to 0..255
buffer = fread(file, 1); // title length
title = fread(file, buffer);
numChars = fread(file, 1);
for (i = 0; i < numChars; i++) {
    whichChar = fread(file, 1);
    tablo[whichChar] = fread(file, 5);
    if (bitmapSize = tablo[whichChar][0] * tablo[whichChar][1]) {
        bitmaps[whichChar] = fread(file, bitmapSize);