Fork us on GitHub Follow us on Facebook Follow us on Twitter

Version 1 (modified by Jiri Svoboda, 3 months ago) (diff)

TPF file format

HelenOS Typeface File Format (TPF)

HelenOS proportional fonts are stored in TPF format. TPF format can store an entire typeface (font family), i.e. a set of fonts of different sizes and attributes. At present the fonts are in the form of monochrome bitmaps, in future they could be extended to support e.g. ASCII art / ANSI art, outline or stroke fonts, as required. Other possible future extensions include the specification of fallback fonts. Reading and writing TPF files (as well as text rendering) is performed by libgfxfont. Font Editor is a HelenOS application that can be used to edit TPF typefaces.

The file format is considered evolving at this stage and not set in stone. It is based on Microsoft RIFF structure, which makes it easier to evolve the format, because incremental changes can be more easily made in a backward compatible manner (i.e. new version of software can still read older version of file format). The RIFF structure was also chosen because the library for reading/writing RIFF files has more uses in HelenOS (e.g. reading WAV files).

TPF fourcc codes overview

Here's an overview of fourcc codes used (at the risk of becoming out of sync with the code):

FourCC code Comment
TPFC Typeface (RIFF format ID)
font Font (list type)
fprp Font properties (CKID)
fmtr Font metrics (CKID)
fbmp Font bitmap (CKID)
glph Glyph (list type)
gmtr Glyph metrics (CKID)
gpat Glyph patterns (CKID)
gror Glyph rectangle/origin (CKID)

TPF file structure

   RIFF(TPFC)
       LIST(font)
           fprp
           fmtr
           fbmp
           LIST(glph)
               gmtr
               gpat
               gror
           LIST(glph)
               ...
           ...
       LIST(font)
           ...
       ...

A TPF file is a RIFF file with TPFC format ID. It consists of a number of LIST(font) chunks (one per font).

Each LIST(font) chunk contains three chunks, in order, fprp, fmtr and fbmp, followed by zero or more LIST(glph) chunks (one for each glyph). fprp contains the basic font properties (used to index the fonts), fmtr contains the font metrics and fbmp contains the bitmap of the entire font.

Each LIST(glph) chunk contains exactly three chunks, in order, gmtr, gpat, gror. gmtr contains the glyph metrics. gpat contains a list of string patterns that the glyph matches. gror contains the glyph rectangle/origin within the font bitmap (i.e. which rectangle inside bitmap contains the glyph and where its origin point is).

For backward compatibility, whenever the reader expects a particular chunk to appear, they will silently skip over any other chunk. That means new, optional, chunks can be introduced and the older file will still be readable by newer software.

fprp chunk

        uint16_t size;
        uint16_t flags;

size is the height (in pixels) of the font.

Flags:

Bit number Description
0 Bold
1 Italic

fmtr chunk

        uint16_t ascent;
        uint16_t descent;
        uint16_t leading;

ascent is the number of pixels the capital characters extend above the baseline. descent is the number of pixels the descenders descend below the baseline. leading is the number of additional pixels of spacing added between two successive lines of text.

fbmp chunk

This chunk contains a header, immediately followed by the actual bitmap data. The format of the header is as follows:

        /** Width in pixels */
        uint32_t width;
        /** Height in pixels */
        uint32_t height;
        /** Format (0) */
        uint16_t fmt;
        /** Depth (bits/pixel) */
        uint16_t depth;

The font bitmap is stored as individual lines (each padded to an entire byte), top to bottom. Each line is packed into bytes, left to right. The first pixel is stored into the most significant bit.

gmtr chunk

        uint16_t advance;

advance is the number of pixels the pen advances to the right when this glyph is set.

gpat chunk

This chunk contains a series of null-terminated UTF-8 strings that the glyph should match. For example, the glyph "Č" could match either a single pre-composed character or the letter "C" follwed by a combining hook, so it would have two strings. In another example, there could be a ligature "iff" matching a single string consisting of three characters. In the simplest case there will be just one string containing a single Unicode code point.

gror chunk

        /** Rectangle p0.x */
        uint32_t p0x;
        /** Rectangle p0.y */
        uint32_t p0y;
        /** Rectangle p1.x */
        uint32_t p1x;
        /** Rectangle p1.y */
        uint32_t p1y;
        /** Origin X */
        uint32_t orig_x;
        /** Origin Y */
        uint32_t orig_y;

The rectangle [p0x, p1x) x [p0y, p1y) (i.e. excluding p1x,p1y) contains the glyph and its origin point is [orig_x, orig_y] (coordinates in the font bitmap). The origin point is placed at the current pen position when the glyph is set.