Filter:

and

Most common tags
By artist
Show fonts begining with…
0 1 2 3 4 5 6 7 8 9 A B C D E F G H I J K L M N O P Q R S T U V W X Y Z

BMF – ByteMap font format

Version 1.1

offset size meaning
04magic header (0xE1E6D51A)
41version (0x11 for v1.1)
51line-height
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
124reserved
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 * …
offsetsizemeaning
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 both its size (width, height) and shift being zero is considered empty/unused and as such not stored. Characters with empty bitmaps are also valid. For example, space usually has no bitmap but its shift parameter is important to store in the font.

Example

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

 Fj:Q
width44110
height8949
relx0–210
rely0220
shift4238

Working with the format

Pseudocode for loading a font

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);
    }
}
fclose(file);

Pseudocode for layout

text = "EXAMPLE ABC";
cursorX = 30;
cursorY = 20;
originalX = cursorX;
for (index = 0; index < strlen(text); index++) {
    whichChar = ord(text[index]);
    if (breakingLinesEnabled && (whichChar == 13)) {
        cursorY += lineHeight;
        cursorX = originalX;
        continue;
    }
    charWidth = tablo[whichChar][0];
    charHeight = tablo[whichChar][1];
    charRelX = tablo[whichChar][2];
    charRelY = tablo[whichChar][3];
    charShift = tablo[whichChar][4];
    charBitmap = tablo[whichChar][5];
    for (bitmapY = 0; bitmapY < charHeight; bitmapY++) {
        for (bitmapX = 0; bitmapX < charWidth; bitmapX++) {
            colorAttribute = charBitmap[bitmapY * charWidth + bitmapX];
            if (colorAttribute) {
                setPixel(
                    cursorX + charRelX + bitmapX,
                    cursorY + sizeOver + charRelY + bitmapY,
                    palette[colorAttribute]
                );
            }
        }
    }
    cursorX += charShift + addSpace;
}