FNT file format

Applies to:
BGEE, BG2EE, IWDEE, PSTEE (Enhanced Edition games prior to patch 2.0)

General Description
This file format describes a bitmap (texture-atlas) font. It is the proprietary font format introduced by the Enhanced Edition engine and used for in-game text before the 2.0 patch switched to TTF fonts.

A FNT file holds no pixel data of its own. Instead it stores, for every glyph, a rectangle into a companion bitmap that shares the same basename (e.g. DIALOG.FNT describes glyphs drawn from DIALOG.BMP). A single FNT/BMP pair may contain several point sizes of the same typeface; the glyphs for every size are packed into the one bitmap and indexed separately.

Detailed Description
All values are little-endian. The file is a fixed sequence of sections with no internal offsets; each section is located by computing the size of the preceding ones from the header counts.

Let G = glyph count and S = size count.

Overall structure:
  • Header (16 bytes)
  • Character code table (G × 4 bytes)
  • Size metrics (S × 16 bytes)
  • Glyph metrics (S × G × 16 bytes)
  • Kerning table (kerning count × 8 bytes)
  • Glyph coordinate table (S × G × 14 bytes)
  • Companion bitmap (separate .BMP file)


  • The file has no signature or version string; it begins directly with the header.

    Offset Size (data type) Description
    0x0000 4 (dword) Glyph count (G) - the number of glyphs defined for each point size
    0x0004 2 (word) Size count (S) - the number of point sizes bundled in this font
    0x0006 2 (word) Unknown (usu. 1)
    0x0008 4 (dword) Unknown (usu. 1)
    0x000c 4 (dword) Count of kerning entries


    An array of G dwords, each a Unicode code point. The entry at index i gives the character represented by glyph i; that same index i is used to look the glyph up in the glyph metrics and coordinate tables. Code points are stored in ascending order and typically begin with the control codes 0x09 (tab), 0x0A (line feed) and 0x0D (carriage return), followed by 0x20 (space) and the printable characters.

    Offset Size (data type) Description
    0x0000 4 (dword) Unicode code point of this glyph


    An array of S records, one per bundled point size, in ascending size order. These give the typeface-wide metrics for each size; the corresponding glyph rectangles for size s are found in block s of the coordinate table. All four values are IEEE 32-bit floats.

    Offset Size (data type) Description
    0x0000 4 (float) Point size of this entry (em size)
    0x0004 4 (float) Line height, in pixels
    0x0008 4 (float) Baseline / ascent, in pixels
    0x000c 4 (float) Descent, in pixels (height below the baseline)


    This section contains S blocks of G records (one block per point size, each block ordered by glyph index). Each record is four 32-bit floats describing the layout metrics of a glyph. Non-printing glyphs (tab, line feed, carriage return) are all-zero. The authoritative placement and dimensions for rendering are given separately in the coordinate table; the values here are layout metrics expressed in pixels.

    Offset Size (data type) Description
    0x0000 4 (float) Left side bearing
    0x0004 4 (float) Advance width
    0x0008 4 (float) Top side bearing / vertical offset
    0x000c 4 (float) Unknown (usually 0)


    An array of kerning count (header field at 0x000c) records, present only for fonts that define kerning. Each record adjusts the spacing of a character pair.

    Offset Size (data type) Description
    0x0000 4 (dword) Code point of the neighbouring character in the pair
    0x0004 4 (float) Horizontal kerning adjustment, in pixels (commonly negative)

    The mechanism that associates a run of kerning records with its owning glyph (i.e. the left-hand character of the pair) has not been fully determined.


    This section contains S blocks of G records (one block per point size, each block ordered by glyph index). Each 14-byte record locates the glyph within the companion bitmap and describes how to place it. The rectangle (x, y, width, height) addresses the bitmap using its native bottom-up orientation, so y is measured from the bottom edge of the image. Whitespace glyphs use a zero (or 1×1) rectangle.

    Offset Size (data type) Description
    0x0000 2 (word) Unknown (always observed as 0; possibly a bitmap page index)
    0x0002 2 (signed word) Vertical placement offset of the glyph
    0x0004 2 (word) Horizontal placement offset of the glyph
    0x0006 2 (word) X position of the glyph rectangle in the bitmap, in pixels
    0x0008 2 (word) Y position of the glyph rectangle in the bitmap, in pixels (measured from the bottom)
    0x000a 2 (word) Width of the glyph rectangle, in pixels
    0x000c 2 (word) Height of the glyph rectangle, in pixels


    The glyph pixels live in a standard Windows BMP file with the same basename as the FNT (e.g. SUBTITLE.FNTSUBTITLE.BMP). All point sizes of the font share this single atlas; the coordinate table rectangles index into it. Because the bitmap is stored bottom-up, the y coordinate is measured from the bottom of the image.

    Several bitmap encodings are used in practice:
  • 8 bits-per-pixel, RLE8-compressed (BI_RLE8) or uncompressed, with a 256-entry grayscale palette. The palette value is the glyph's coverage (alpha); the colour is applied by the engine.
  • 24 bits-per-pixel, uncompressed BGR.
  • 32 bits-per-pixel, BI_BITFIELDS, carrying a real alpha channel.

  • The atlas background is black / zero coverage and is treated as transparent.