Bitmap Font Generator - Documentation

The Bitmap Font Generator is a free program to generate bitmap fonts from true type fonts. The bitmaps are generated in such a way as to leave as little unused space as possible. The position of the characters in the bitmap is not regular so you'll need the generated font descriptor file to determine how to draw each character.


top

Font settings

You can open the font settings dialog by going to the Options menu and choosing Font settings, or you can just press F on the keyboard.

The left half of this dialog controls the properties of the font, i.e. the character set, and looks. The right half controls how the font will be stored, i.e. texture layout, file format, etc. The left half is pretty self explanatory, so I'll explain only the right half.

Padding

Padding is useful when you want to add some post processing effects in another paint program. For example, if you want to add a blurring effect that uses a 5x5 kernel, you would add a padding of 2 on all sides. Similarly if you want to add a drop shadow, you would add a bit of padding below and to the right of the characters (assuming that's the direction of the drop shadow that you want).

Spacing

The spacing controls how much minimum space is left between characters in the font texture. If you're using mipmapping to scale the font texture when drawing the font, you'll need to add spacing to avoid bleeding when the texture is downscaled. The more mipmap levels you use the more spacing you need.

Bilinear filtering may also cause bleeding, so unless you use pixel perfect drawing, where each texel is perfectly mapped to a pixel on the screen with a 1-to-1 releation ship you'll want to use at least 1 for vertical and horizontal spacing.

Texture

BMFont supports several different texture layouts. The width and height, of course control the size of the texture. You'll want to keep the texture as small as possible, while still allowing all characters to fit in one texture.

If you're importing colored icons, or planning on using post processing to add colors to the characters, then you'll want to choose the 32bit format, otherwise the 8bit format may be sufficient.

If you choose the 32bit format, you may still optimize the usage of the texture memory if you choose to pack characters in each channel, though that will require a special pixel shader to decode during drawing. In this mode you can still import colored icons, the characters will be properly packed around them.

The font outline can also be encoded together with the character in 8 bits, allowing you to store many more characters in the same space than if you had stored the outlined characters as colored images. This too require a special pixel shader to decode during drawing.

File format

Finally you can choose the file format for both the font descriptor and textures. This is mostly a matter of choice, rather than one having more benefits than the other. Though if you want to save disc space, you may want to choose binary file descriptor with png textures.


top

Command line parameters

The application can be used from the command line, to performed automated generation of font files. The prerequisite is a font configuration file, that you can save from the application, or even generate yourself. The command line parameters are:


top

File tags

info

This tag holds information on how the font was generated.

faceThis is the name of the true type font.
sizeThe size of the true type font.
boldThe font is bold.
italicThe font is italic.
charsetThe name of the OEM charset used (when not unicode).
unicodeSet to 1 if it is the unicode charset.
stretchHThe font height stretch in percentage. 100% means no stretch.
smoothSet to 1 if smoothing was turned on.
aaThe supersampling level used. 1 means no supersampling was used.
paddingThe padding for each character (up, right, down, left).
spacingThe spacing for each character (horizontal, vertical).
outlineThe outline thickness for the characters.

common

This tag holds information common to all characters.

lineHeightThis is the distance in pixels between each line of text.
baseThe number of pixels from the absolute top of the line to the base of the characters.
scaleWThe width of the texture, normally used to scale the x pos of the character image.
scaleHThe height of the texture, normally used to scale the y pos of the character image.
pagesThe number of texture pages included in the font.
packedSet to 1 if the monochrome characters have been packed into each of the texture channels.
encodedSet to 1 if the black outline is encoded together with the white char in the alpha channel.

page

This tag gives the name of a texture file. There is one for each page in the font.

idThe page id.
fileThe texture file name.

char

This tag describes on character in the font. There is one for each included character in the font.

idThe character id.
xThe left position of the character image in the texture.
yThe top position of the character image in the texture.
widthThe width of the character image in the texture.
heightThe height of the character image in the texture.
xoffsetHow much the current position should be offset when copying the image from the texture to the screen.
yoffsetHow much the current position should be offset when copying the image from the texture to the screen.
xadvanceHow much the current position should be advanced after drawing the character.
pageThe texture page where the character image is found.
chnlThe texture channel where the character image is found (1 = blue, 2 = green, 4 = red, 8 = alpha, 15 = all channels).

kerning

The kerning information is used to adjust the distance between certain characters, e.g. some characters should be placed closer to each other than others.

firstThe first character id.
secondThe second character id.
amountHow much the x position should be adjusted when drawing the second character immediately following the first.

top

Binary file layout

This section describes the layout of the tags in the binary file format. To understand what each tag means refer to the file tags section.

The first three bytes are the file identifier and must always be 66, 77, 70, or "BMF". The fourth byte gives the format version, currently it must be the binary 1 or 2. Version 2 sees the addition of outline in the infoBlock and encoded in the commonBlock.

Following the first four bytes is a series of blocks with information. Each block starts with a one byte block type identifier, followed by a 4 byte integer that gives the size of the block, including the 4 byte size value, but not the block type identifier.

Block type 1: info

#pragma pack(1)
struct infoBlock
{
    int  blockSize;
    WORD fontSize;
    BYTE reserved:4;
    BYTE bold    :1;
    BYTE italic  :1;
    BYTE unicode :1;
    BYTE smooth  :1;
    BYTE charSet;
    WORD stretchH;
    BYTE aa;
    BYTE paddingUp;
    BYTE paddingRight;
    BYTE paddingDown;
    BYTE paddingLeft;
    BYTE spacingHoriz;
    BYTE spacingVert;
    BYTE outline;         // Added with version 2
    char fontName[1];
};

This structure gives the layout of the fields. Remember that there should be no padding between members. Allocate the size of the block using the blockSize, as following the block comes the font name, including the terminating null char. Most of the time this block can simply be ignored.

Block type 2: common

#pragma pack(1)
struct commonBlock
{
    int  blockSize;
    WORD lineHeight;
    WORD base;
    WORD scaleW;
    WORD scaleH;
    WORD pages;
    BYTE packed  :1;
    BYTE encoded :1;      // Added with version 2
    BYTE reserved:6;
}; 

Block type 3: pages

#pragma pack(1)
struct pagesBlock
{
    int  blockSize;
    char pageNames[1];
};

This block gives the name of each texture file with the image data for the characters. The string pageNames holds the names separated and terminated by null chars. Each filename has the same length, so once you know the size of the first name, you can easily determine the position of each of the names. The id of each page is the zero-based index of the string name.

Block type 4: chars

#pragma pack(1)
struct charsBlock
{
    int blockSize;
    struct charInfo
    {
        WORD  id;
        WORD  x;
        WORD  y;
        WORD  width;
        WORD  height;
        short xoffset;
        short yoffset;
        short xadvance;
        BYTE  page;
        BYTE  chnl;
    } chars[1];
};

The number of characters in the file can be computed by taking the size of the block and dividing with the size of the charInfo structure, i.e.: numChars = (charsBlock.blockSize - 4)/18.

Block type 5: kerning pairs

#pragma pack(1)
struct kerningPairsBlock
{
    int blockSize;
    struct kerningPair
    {
        WORD  first;
        WORD  second;
        short amount;
    } kerningPairs[1];
};

This block is only in the file if there are any kerning pairs with amount differing from 0.


top

Pixel shader sample

This pixel shader shows how to decode the color from a font texture with characters packed into all 4 channels, and each channel using special encoding to store the character with the outline. The texture is also allowed to store full 32bit images for some characters.

// DirectX 9 pixel shader
float4 PixScene( float4 color : COLOR0,
                 int4   chnl  : TEXCOORD1,
                 float2 tex0  : TEXCOORD0 ) : COLOR0
{
  float4 pixel = tex2D(g_samScene, tex0);
    
  if( dot(vector(1,1,1,1), chnl) )
  {
    float val = dot(pixel, chnl);
		
    pixel.rgb = val > 0.5 ? 2*val-1 : 0;
    pixel.a   = val > 0.5 ? 1 : 2*val;
  }
    
  return pixel * color;
}

The chnl texture coordinate is a 4D vector that shows which channel the character should be read from. If this is (0,0,0,0) the character is interpreted as a 32 bit image. The texture coordinate can be stored in a UBYTE4 type, so it doesn't require much bandwidth when being sent to the video card.


top

Known issues

Cropped characters

With some fonts, some characters are cropped. An example is Bitstream's Cyberbit font, where the bottom of the square bracket characters are cropped off in some font sizes.

This is a compatibility problem between the font and GDI, not a problem in this application by itself. You get the same problem in WordPad for example. I will however try out other font rasterizers, to see if I can fix this problem in a future version.

Characters are disabled, yet they have images

Depending on your Windows configuration you may see that with some fonts characters are disabled, yet have a character image. Especially with the asian character sets. This is because Windows automatically fills in the missing characters by taking them from another font when the international language pack is installed.

I do not consider this an error in BMFont, but it may be fixed in a future version, especially if I end up using another font rasterizer.

Rotated characters

Some font files have some but not all subsets with characters rotated by 90 degrees. For example @Arial Unicode MS, with subset Enclosed Alphanumerics. This is not an error, but a feature of that font file. With the font rotated like this it permits writing texts in normal text editors as if they were in vertical lines.


top