Skip to content

BitmapFonts

Gargaj edited this page Jan 4, 2022 · 7 revisions

How to convert 8x16 (or 8x8) bitmap fonts to TTF/webfont

Step 1: Find the font

Find and extract the font of the magazine from the .EXE - you can usually recognize them by being a N-byte aligned pattern (where N is the font height in pixels) with the first and last two bytes being 00, like so:

image

Most fonts don't redraw the block characters, so certain patterns like these have a good chance of being identical across the board:

image

For 8x16 fonts, you're looking for 8 (width) x 16 (height) x 8 (bits) = 4096 bytes of data

Step 2: Once extracted, turn it into a bitmap

This can be done with some simple scripting; a PHP example would be like this:

function fontToBitmap($font,$filename,$width=8,$height=16)
{
  $i = imagecreate($width*16,$height*16);
  imagefill($i,0,0,imagecolorallocate($i, 255, 255, 255));
  $black = imagecolorallocate($i, 0,0,0);
  $count = strlen($font) / $height;
  for($c=0;$c<$count;$c++)
  {
    $cx = (int)($c % 16) * $width;
    $cy = (int)($c / 16) * $height;
    for($y=0;$y<$height;$y++)
    {
      for($x=0;$x<$width;$x++)
      {
        if (ord($font[$c*$height+$y]) & (1<<$x))
        {
          imagesetpixel($i,$cx+$width-$x-1,$cy+$y,$black);
        }
      }
    }
  }
  imagepng($i,$filename);
}

...but of course you can use any language.

The result should look something like this:

image

Step 3: Bitmap font to TTF

This is both easy and arduous: open https://yal.cc/r/20/pixelfont/ in a browser, load in the image, and fill out the necessary parameters; the following settings are common for a "standard" 8x16 font:

"Output" Tab:

  • Pixel size = 128
  • Em size = 2048
  • Ascent = 1536
  • Descent = -512

"Input" Tab:

  • Tile width = 8
  • Tile height = 16
  • Offset X = 1
  • Baseline = 12
  • Monospace = checked

Everything else you should set to 0.

The common LATIN-1 character-/glyphset looks like this:

 ☺☻♥♦♣♠•◘○◙♂♀♪♫☼
►◄↕‼¶§▬↨↑↓→←∟↔▲▼
 !"#$%&'()*+,-./
0123456789:;<=>?
@ABCDEFGHIJKLMNO
PQRSTUVWXYZ[\]^_
`abcdefghijklmno
pqrstuvwxyz{|}~⌂
ÇüéâäàåçêëèïÍÍÄÅ
ÉæÆőöôûùÿÖÜ¢£¥₧ƒ
áíóúñѪº¿⌐¬½¼¡«»
░▒▓│┤╡╢╖╕╣║╗╝╜╛┐
└┴┬├─┼╞╟╚╔╩╦╠═╬╧
╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀
αßΓπΣσµτΦΘΩδ∞φε∩
≡±≥≤⌠⌡÷≈°∙·√ⁿ²■ 

...but there's a good chance that your magazine has swapped out some of the characters, so check manually and update the textbox when needed - you'll need this later. You can also go to the Meta tab to set a font name and author, if you want to.

Once you're good, make sure you press both Save TTF (top right) and Export (top left)

Step 4: Convert TTF to WOFF/WOFF2

Just use something like https://transfonter.org/ - you can do it locally if you have the tools.

Step 5: Retrieve the unicode values from the glyph tab

Not done yet - because your mag data will still be in ASCII, you need to convert back the above glyph tab (or the one you modified it to) into a look-up table. Again, once you've exported the JSON, you can script your way out of this:

$data = json_decode(file_get_contents("MyFont.json"),true);
if ($data)
{
  foreach($data["in-glyphs"] as $v2)
  {
    $v = substr(json_encode($v2),1,-1);
  
    for ($x = 0; $x<strlen($v); $x++)
    {
      if ($v[$x]=="\\")
      {
        if($v[$x+1]=="u")
        {
          $t = substr($v,$x+2,4);
          list($u) = sscanf($t,"%x");
          printf("%4d, ",$u);
          $x+=5;
        }
        else
        {
          printf("%4d, ",ord($v[$x+1]));
          $x++;
        }
      }
      else
      {
        printf("%4d, ",ord($v[$x]));
      }
    }
    echo "\n";
  }
}

This isn't pretty, but it'll work fine.