| 1 | = HelenOS Typeface File Format (TPF) = |
| 2 | |
| 3 | 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. |
| 4 | |
| 5 | 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. |
| 6 | |
| 7 | 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). |
| 8 | The RIFF structure was also chosen because the library for reading/writing RIFF files has more uses in HelenOS (e.g. reading WAV files). |
| 9 | |
| 10 | |
| 11 | == TPF fourcc codes overview == |
| 12 | Here's an overview of fourcc codes used (at the risk of becoming out of sync with the code): |
| 13 | |
| 14 | || '''FourCC code'''|| '''Comment''' || |
| 15 | || TPFC || Typeface (RIFF format ID) || |
| 16 | || font || Font (list type) || |
| 17 | || fprp || Font properties (CKID) || |
| 18 | || fmtr || Font metrics (CKID) || |
| 19 | || fbmp || Font bitmap (CKID) || |
| 20 | || glph || Glyph (list type) || |
| 21 | || gmtr || Glyph metrics (CKID) || |
| 22 | || gpat || Glyph patterns (CKID) || |
| 23 | || gror || Glyph rectangle/origin (CKID) || |
| 24 | |
| 25 | == TPF file structure == |
| 26 | |
| 27 | {{{ |
| 28 | RIFF(TPFC) |
| 29 | LIST(font) |
| 30 | fprp |
| 31 | fmtr |
| 32 | fbmp |
| 33 | LIST(glph) |
| 34 | gmtr |
| 35 | gpat |
| 36 | gror |
| 37 | LIST(glph) |
| 38 | ... |
| 39 | ... |
| 40 | LIST(font) |
| 41 | ... |
| 42 | ... |
| 43 | }}} |
| 44 | |
| 45 | A TPF file is a RIFF file with ''TPFC'' format ID. It consists of a number of ''LIST(font)'' chunks (one per font). |
| 46 | |
| 47 | 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. |
| 48 | |
| 49 | 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). |
| 50 | |
| 51 | 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. |
| 52 | |
| 53 | == fprp chunk == |
| 54 | |
| 55 | {{{ |
| 56 | uint16_t size; |
| 57 | uint16_t flags; |
| 58 | }}} |
| 59 | |
| 60 | ''size'' is the height (in pixels) of the font. |
| 61 | |
| 62 | Flags: |
| 63 | |
| 64 | || '''Bit number'' || '''Description''' || |
| 65 | || 0 || Bold || |
| 66 | || 1 || Italic || |
| 67 | |
| 68 | |
| 69 | == fmtr chunk == |
| 70 | |
| 71 | {{{ |
| 72 | uint16_t ascent; |
| 73 | uint16_t descent; |
| 74 | uint16_t leading; |
| 75 | }}} |
| 76 | |
| 77 | ''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. |
| 78 | |
| 79 | == fbmp chunk == |
| 80 | |
| 81 | This chunk contains a header, immediately followed by the actual bitmap data. The format of the header is as follows: |
| 82 | |
| 83 | {{{ |
| 84 | /** Width in pixels */ |
| 85 | uint32_t width; |
| 86 | /** Height in pixels */ |
| 87 | uint32_t height; |
| 88 | /** Format (0) */ |
| 89 | uint16_t fmt; |
| 90 | /** Depth (bits/pixel) */ |
| 91 | uint16_t depth; |
| 92 | }}} |
| 93 | |
| 94 | 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. |
| 95 | |
| 96 | |
| 97 | == gmtr chunk == |
| 98 | {{{ |
| 99 | uint16_t advance; |
| 100 | }}} |
| 101 | |
| 102 | ''advance'' is the number of pixels the pen advances to the right when this glyph is set. |
| 103 | |
| 104 | == gpat chunk == |
| 105 | |
| 106 | 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. |
| 107 | |
| 108 | == gror chunk == |
| 109 | |
| 110 | {{{ |
| 111 | /** Rectangle p0.x */ |
| 112 | uint32_t p0x; |
| 113 | /** Rectangle p0.y */ |
| 114 | uint32_t p0y; |
| 115 | /** Rectangle p1.x */ |
| 116 | uint32_t p1x; |
| 117 | /** Rectangle p1.y */ |
| 118 | uint32_t p1y; |
| 119 | /** Origin X */ |
| 120 | uint32_t orig_x; |
| 121 | /** Origin Y */ |
| 122 | uint32_t orig_y; |
| 123 | }}} |
| 124 | |
| 125 | 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. |