A TrueType font is a set of tables, each identified by a four-character tag, and a
directory at the start of the file that says where each table is. Apple calls this
container the sfnt, and OpenType kept it unchanged. This page covers the
directory, the data types every table uses, checksums, and the list of tables. All
numbers are big-endian.
Data types
The names the OpenType specification uses, and that the pages for each table use too.
| Type | Size | Meaning |
|---|---|---|
uint8, int8 | 1 | Unsigned and signed 8-bit integers. |
uint16, int16 | 2 | Unsigned and signed 16-bit integers. |
uint24 | 3 | Unsigned 24-bit integer. |
uint32, int32 | 4 | Unsigned and signed 32-bit integers. |
Fixed | 4 | Signed 16.16 fixed-point number: 0x00018000 is 1.5. |
FWORD | 2 | int16 in font design units (see unitsPerEm in head). |
UFWORD | 2 | uint16 in font design units. |
F2DOT14 | 2 | Signed 2.14 fixed-point number: a two’s complement integer in the top 2 bits plus an unsigned fraction of 14 bits. 0x7FFF is 1.999939, 0x7000 1.75, 0x0001 0.000061, 0xFFFF −0.000061, 0x8000 −2.0. |
LONGDATETIME | 8 | Signed 64-bit count of seconds since midnight, 1 January 1904, UTC (the classic Mac OS epoch). |
Tag | 4 | Four bytes from 0x20 to 0x7E, read as characters: one to four non-space characters, padded at the end with spaces, so cvt is 63 76 74 20. Case matters. A space may not be followed by another character. |
Offset8, Offset16, Offset24, Offset32 | 1, 2, 3, 4 | Offsets to a subtable; 0 means there is none. |
Version16Dot16 | 4 | A version with the major number in the top 16 bits and the minor number as a digit in the next 4: version 0.5 is 0x00005000, 2.5 is 0x00025000. Only maxp, post and vhea use it. |
Table directory
The directory starts at byte 0 of a .ttf file. In a
font collection each font has its own directory,
wherever the collection header says.
| Offset | Type | Name | Description |
|---|---|---|---|
0 | uint32 | sfntVersion | What kind of font this is: see below. |
4 | uint16 | numTables | The number of tables. |
6 | uint16 | searchRange | The largest power of 2 not above numTables, times 16. |
8 | uint16 | entrySelector | The base-2 logarithm of that power of 2: floor(log2(numTables)). |
10 | uint16 | rangeShift | numTables × 16 − searchRange. |
12 | record × numTables | tableRecords | One 16-byte table record per table, sorted by tag. |
The three search fields once sped up a binary search of the records. They can always
be worked out from numTables, and the specification recommends that
readers do so rather than trust them, since wrong values have been used to attack
font parsers. Writers should still fill them in correctly.
sfntVersion
| Value | As text | Meaning |
|---|---|---|
0x00010000 | – | TrueType outlines. The value OpenType requires for TrueType fonts, and the one fonts for Windows and Adobe software must use. |
0x74727565 | true | TrueType outlines, recognised by macOS and iOS. Apple encourages it for fonts made only for its systems; OpenType says not to use it. |
0x4F54544F | OTTO | CFF outlines: an OpenType CFF font, usually .otf. |
0x74797031 | typ1 | Apple: an old-style PostScript Type 1 font in an sfnt wrapper. Not for OpenType. |
A collection file starts with ttcf instead, the tag of its
collection header.
Table record
| Offset | Type | Name | Description |
|---|---|---|---|
0 | Tag | tableTag | The table’s tag. |
4 | uint32 | checksum | The table’s checksum. |
8 | Offset32 | offset | Where the table starts, from the start of the file. |
12 | uint32 | length | The table’s length in bytes, without padding. |
- Records are sorted by tag in ascending order, comparing the bytes as unsigned
numbers, so upper-case tags (
OS/2) sort before lower-case ones (cmap). - A font should have at most one table with any given tag; with two, what happens is up to the software.
- Every table starts on a four-byte boundary, and the gaps are filled with zeros. Only top-level tables are aligned this way, not the subtables inside them.
- Tables can be in any order in the file, and there is no fixed number of them.
- Apple reserves tags made only of lower-case letters for its own tables; anyone else defining a table should register its tag.
Checksums
A table’s checksum is the sum of its bytes taken as big-endian uint32
words, ignoring overflow. A table whose length is not a multiple of 4 is summed as if
it were padded with zero bytes. In C, from the specification:
uint32 CalcTableChecksum(uint32 *Table, uint32 Length)
{
uint32 Sum = 0L;
uint32 *EndPtr = Table + ((Length + 3) & ~3) / sizeof(uint32);
while (Table < EndPtr)
Sum += *Table++;
return Sum;
}
The head table holds a second check, checksumAdjustment,
for the whole file. A font maker computes it last:
- Set
checksumAdjustmentto 0. - Compute the checksum of every table,
headincluded, and write each into its table record. - Compute the checksum of the whole file, as if it were one table.
- Subtract that from
0xB1B0AFBAand store the result inchecksumAdjustment.
Writing checksumAdjustment changes the head table, so to
check head against its record a reader takes
checksumAdjustment as 0. Once checksumAdjustment is in
place, the checksum of the whole file is 0xB1B0AFBA. In a collection, checksumAdjustment is
not used and may be 0.
For example, the 8-byte gasp table 00 01 00 01 FF FF 00 0F
is two words, 0x00010001 + 0xFFFF000F =
0x100000010; dropping the overflow leaves the checksum
0x00000010.
Tables
OpenType groups the tables it defines as follows. A TrueType font must have the
required tables and glyf and loca; the rest are optional.
The tables a TrueType font cannot use, because they belong to CFF outlines, are
CFF , CFF2 and VORG.
| Group | Tag | Name |
|---|---|---|
| Required in every font | cmap | Character to glyph mapping |
head | Font header | |
hhea | Horizontal header | |
hmtx | Horizontal metrics | |
maxp | Maximum profile | |
name | Naming table | |
OS/2 | OS/2 and Windows metrics (optional in Apple’s specification) | |
post | PostScript information | |
| TrueType outlines | glyf | Glyph data |
loca | Index to location | |
cvt | Control value table (optional) | |
fpgm | Font program (optional) | |
prep | Control value program (optional) | |
gasp | Grid-fitting and scan-conversion procedure (optional) | |
| Bitmap glyphs | EBDT | Embedded bitmap data |
EBLC | Embedded bitmap location data | |
EBSC | Embedded bitmap scaling data | |
CBDT | Colour bitmap data | |
CBLC | Colour bitmap location data | |
sbix | Standard bitmap graphics | |
| SVG glyphs | SVG | Scalable Vector Graphics |
| Colour | COLR | Colour table (also uses CBDT, CBLC, sbix, SVG ) |
CPAL | Colour palette table | |
| Advanced typography | BASE | Baseline data |
GDEF | Glyph definition data | |
GPOS | Glyph positioning data | |
GSUB | Glyph substitution data | |
JSTF | Justification data | |
MATH | Math layout data | |
| Variations | avar | Axis variations |
cvar | CVT variations (TrueType outlines only) | |
fvar | Font variations | |
gvar | Glyph variations (TrueType outlines only) | |
HVAR | Horizontal metrics variations | |
MVAR | Metrics variations | |
STAT | Style attributes (required in variable fonts) | |
VVAR | Vertical metrics variations | |
| Other | DSIG | Digital signature |
hdmx | Horizontal device metrics | |
kern | Kerning | |
LTSH | Linear threshold data | |
MERG | Merge | |
meta | Metadata | |
PCLT | PCL 5 data | |
VDMX | Vertical device metrics | |
vhea | Vertical metrics header | |
vmtx | Vertical metrics |
The tables that TrueType and OpenType fonts share beyond those on these TTF pages are
documented on the OTF pages: vhea,
vmtx and VORG; the
bitmap tables (EBDT,
EBLC, EBSC, CBDT, CBLC,
sbix); COLR,
CPAL and SVG ; the layout tables
GDEF,
GSUB,
GPOS,
BASE and JSTF and
MATH, built on the
layout common tables; the variation
tables fvar, avar
and STAT and gvar,
cvar, HVAR, VVAR and MVAR; and
DSIG and
PCLT, meta and
MERG.
Apple’s TrueType Reference Manual defines further tables that macOS and iOS use, not
part of OpenType: acnt, ankr, bdat,
bhed, bloc, bsln, fdsc,
feat, fmtx, fond, gcid,
hvgl, hvpm, just, kerx,
lcar, ltag, mort, morx,
opbd, prop, trak, xref and
Zapf. Its avar, cvar, fvar,
gvar, kern and meta tables share their tags
with OpenType’s, but Apple’s versions of some of them differ in detail.
Example
The start of KaTeX’s Size2 Regular font, an 11,508-byte TrueType font with 14 tables: the 12-byte header and the first table record.
00000000 00 01 00 00 00 0E 00 80 00 03 00 60 4F 53 2F 32 ...........`OS/2
00000010 45 61 95 F5 00 00 17 6C 00 00 00 60 Ea.....l...`
sfntVersion is 0x00010000, TrueType; 14 tables; the largest
power of 2 not above 14 is 8, so searchRange is 128,
entrySelector 3 and rangeShift 224 − 128 = 96. All 14
records, in their sorted order:
| Tag | Checksum | Offset | Length |
|---|---|---|---|
OS/2 | 456195F5 | 5,996 | 96 |
cmap | 9E88C148 | 6,092 | 196 |
cvt | 00000000 | 10,040 | 14 |
fpgm | 622EF97A | 6,288 | 3,596 |
gasp | 00000010 | 11,500 | 8 |
glyf | 8522CEC5 | 236 | 5,390 |
head | 62F242D7 | 5,744 | 54 |
hhea | 097C017E | 5,960 | 36 |
hmtx | 76ED01CD | 5,800 | 158 |
loca | 59455413 | 5,660 | 82 |
maxp | 00BB0ECB | 5,628 | 32 |
name | 5FD37EB2 | 10,056 | 1,152 |
post | 70A69C6C | 11,208 | 292 |
prep | 7EB63BB6 | 9,884 | 156 |
The first table, glyf, starts at 236, straight after the 12 + 14 × 16
bytes of the directory. Its length, 5,390, is not a multiple of 4, so two zero bytes
follow it and maxp starts at 5,628. The last table, gasp,
ends at 11,508, the end of the file. The cvt table is 14 zero bytes,
hence its checksum of 0.