Filter:

and

Most common tags
By artist
Spaz Cupid Daniel Guldkrans Agent -t- Sense Imperator Pandafox Zone Tanis Xerud Samurai Redzone Krazy Rex Le Sergeant Compyx Carnera Antor Ice ES Jou-Nan Chen Deekay Made Helrizer Dim mOdmate Fade One Flotsam Sim1 Elf Marc Rosocha Grazey Ozymandias Manikin Pursy Igor Jacky Speedlight Lowlife Desire Spiral Vic Shadowmaster Mic Ray Larabie Nobody Magnum Mark Coleman FAA MacDos Senser Facet Lancelot Ccr Aleksi Eeben Jerom Moondog Procyon Matt Dominion Slime phygorax Miguel Hernandez Walt John Cumming The Speed Demon Mick Lord North Star Equinox THUG Inc. Buch Codex 2005 Tuf Ludug Master Matt Sephton Cougar Jovis Kim Buker Chansler Rack Duel Connor Smiley Fieserwolf ST Survivor Skywalker Black Sky TRS Offset Yolan MoN Nik Blade Mo Warden Axelsoft Woz MC Laser dynaCore Raist Vixen Slaine Homeboy Wayne Xenit Uno Navy Chrome Zebra Ace Stingray JSF Crit Polux Source Lanch Seen Cobra Groxy Anders Ekstrom Roy Zaborak Spy Phalanx Marvel Frodo Monopoly Sector 9 The Speed Demon\ Slash Renker Hof Mad Butcher Red Zappy Johnny Turbo The Pride Viper Phan Alta Manar Nick23 Deus Triatian Time Thrust Pippin Sonic JMS Bugbear Rick Stigels Oxar Bod Paranoid Denthor Clasch Dan Striper Dust Israel Prrak PMA Agro Zin Rock Lobster Lucifer Fraxion Inquisitor Bizox Panic Apollyon Bridgeclaw Deflector Cmr Tai-Pan Designer Ratman Asia Inc. Daryl Orcslayer Turbo Violence Defcon 5 Galdor Darry Booper Human Double Trouble Uncle Evil Stick The Master Dieu Mat Mad Epsilon Ioda MR40 TPD Megadeth Diesel Nic Blagger Charon Spike Headhunter Goldevil Aces Xytar Dr. Death Zanac Raven Griff Phygorax
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

The format

Version 1.2 is in preparations, soon to be released.

BMF version 1.1

offset size meaning
04magic header (0xE1E6D51A)
41version (0x11)
51lineHeight – measure from lowest to highest reach
(0…255) should be equal to or greater than size-under – size-over
61sizeOver (–128…127)
measure from baseline to top of capital letters, in pixels; should be negative
71sizeUnder (–128…127)
measure from baseline to lowest extends (of letters like "y", "g"), in pixels; should be positive or zero
81addSpace after each char (–128…127)
how many pixels to add after plotting each character
91sizeInner (height of small letters) (–128…127)
measure from baseline to top of small letters (e.g. "m"); should be negative
101usedColors – count of used colors
111highest used color attribute
124reserved (0)
161number of colors in palette (P)
17P*3font palette (array of RGB triplets, 6 bits/0…63 per component)
17+P*31title length (T)
18+P*3Ttitle or description of the font (string)
19+P*3+T2numChars – number of characters in font i.e. having non-zero size or shift (N)
20+P*3+T?bitmap definitions

N * (which character (its ASCII code 0…255), followed by its tablo entry)
E.g. "A", <tablo entry for "A">, "B", <tablo entry for "B">, "C", <tablo entry for "C">, …

Tablo entry has the following structure:

offsetsizemeaning
01character width (W)
11character height (H)
21relX – X offset from cursor position (–128…127)
31relY – Y offset from cursor position (–128…127)
41shift – horizontal cursor shift after drawing the character
5W * Hcharacter bitmap (uncompressed, row-major, 8 bits per pixel)

Each character with its width * height and shift equal to zero is considered empty (unused) and as such its entry is not stored. Characters with empty bitmaps but non-zero shift are valid, i.e. its entry follows. Bitmaps of 0×0 pixels are to be treated as empty string. For example, space usually has no bitmap but its shift parameter is important to store in the font.

BMF version 1.2

Quick overview of changes from version 1.1:

  • Unicode support
  • alpha channel option
  • multiple palettes
  • kerning pairs

Basic backward compatibility maintained.

offsetsizemeaning
04magic header (0xE1E6D51A Little-Endian)
41version (0x12)
51lineHeight – measure from lowest to highest reach
(0…255) should be equal to or greater than size-under – size-over
61sizeOver (–128…127)
measure from baseline to top of capital letters, in pixels; should be negative
71sizeUnder (–128…127)
measure from baseline to lowest extends (of letters like "y", "g"), in pixels; should be positive or zero
81addSpace after each char (–128…127)
how many pixels to add after plotting each character
91sizeInner (height of small letters) (–128…127)
measure from baseline to top of small letters (e.g. "m"); should be negative
101usedColors – count of used colors
111highest used color attribute
121alphaBits – how many bits of each bitmap byte the alpha channel occupy? (0…8)
131extraPalettes – how many additional palettes there are (all palettes must fit into the 255-entry field)
142reserved (0)
161number of colors in palette (P)
17P*3font palette (array of RGB triplets, 6 bits/0…63 per component)
17+P*31title length (T)
18+P*3Ttitle or description of the font (string)
19+P*3+T2asciiChars – number of characters in font of codes under 256 (N)
20+P*3+T?bitmap definitions

N * (which character (its ASCII code 0…255), followed by its tablo entry)
E.g. "A", <tablo entry for "A">, "B", <tablo entry for "B">, "C", <tablo entry for "C">, …

Tablo entry has the following structure:

offsetsizemeaning
01character width (W)
11character height (H)
21relX – X offset from cursor position (–128…127)
31relY – Y offset from cursor position (–128…127)
41shift – horizontal cursor shift after drawing the character
5W * Hcharacter bitmap (uncompressed, row-major, 8 bits per pixel)
after that follows
sizemeaning
4unicodeChars (32-bit unsigned int) – how many characters of Unicode code greater than 255 follow (U)

U * (which character (32-bit unsigned int), followed by its tablo entry (same format as above)

after that follows
sizemeaning
4kerningPairs (32-bit unsigned int) – how many kerning pairs are defined (K)

K * kerning pair definition

offsetsizemeaning
04first character (its Unicode code, 32-bit unsigned int)
44second character
82correction (16-bit signed int), positive=shift right, negative=shift left

Example

For this example, let addSpace = 1, sizeOver = –8. The blue line is the base line, the blue cursor is the initial position to plot the text, the red cursor, being sizeOver pixels down from the base line, indicate cursor position before outputing each character of the text. Finally, to get to the actual top-left corners of each bitmap, we need to add the (relX, relY) vector from each character's tablo.

Fj:Q
width44110
height8949
relX0–210
relY0220
shift4238

Working with the format

Pseudocode for loading a font

filename = "font.bmf";
file = fopen(filename, "rb");
buffer = fread(file, 18);
version = buffer[4];
if (substr(buffer, 0, 4) != "\xE1\xE6\xD5\x1A" || (version != 0x11 && version != 0x12)) {
  return false; // not a BMF, version 1.1 or 1.2
}
lineHeight = buffer[5];
sizeOver = buffer[6];
sizeUnder = buffer[7];
addSpace = buffer[8];
sizeInner = buffer[9];
usedColors = buffer[10];
highestColor = buffer[11];
alphaBits = buffer[12];
extraPalettes = buffer[13];
reserved = buffer[14];
numColors = buffer[16];
palette = fread(file, numColors * 3);
for (i = 0; i < numColors * 3; i++) {
  palette[i] *= 4; // stretch 0..63 values to 0..255
}
buffer = fread(file, 1); // title length
title = fread(file, buffer);
asciiChars = fread(file, 2);
for (i = 0; i < asciiChars; i++) {
  whichChar = fread(file, 1);
  tablo[whichChar] = fread(file, 5);
  if (bitmapSize = tablo[whichChar][0] * tablo[whichChar][1]) {
    bitmaps[whichChar] = fread(file, bitmapSize);
  }
}
// next goes for version 1.2 only
unicodeChars = fread(file, 4);
for (i = 0; i < unicodeChars; i++) {
  whichChar = fread(file, 4);
  tablo[whichChar] = fread(file, 5);
  if (bitmapSize = tablo[whichChar][0] * tablo[whichChar][1]) {
    bitmaps[whichChar] = fread(file, bitmapSize);
  }
}
numKerningPairs = fread(file, 4);
kerningPairs = [];
for (i = 0; i < numKerningPairs; i++) {
  fread(file, buffer, 10);
  kerningPairs []= buffer;
}
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 += font.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++) {
      if (colorAttribute = charBitmap[bitmapY * charWidth + bitmapX]) {
        setPixel(
          cursorX + charRelX + bitmapX,
          cursorY + font.sizeOver + charRelY + bitmapY,
          font.palette[colorAttribute]
        );
      }
    }
  }
  cursorX += charShift + font.addSpace;
}