TrueType font file format
A TrueType outline font.
- MIME type
- font/ttf
- Extensions
- .ttf
- Category
- Fonts
Magic-number signature
| 0x00000000 | 00010000 | ···· | sfnt version 1.0 |
About the TrueType font format
TrueType, designed by Apple in the late 1980s and adopted by Microsoft, describes each glyph as a set of quadratic Bezier curves plus a bytecode hinting program that tells the rasteriser how to snap those curves onto a pixel grid at small sizes. The file itself is an sfnt container: a short directory at the front lists every table in the font by a four-character tag, and each table is an independent blob addressed by an absolute file offset, so tables can be added, removed or reordered without touching anything else. The version tag 00 01 00 00 at offset 0 is what marks the outlines as TrueType rather than PostScript.
Header layout, byte by byte
| Offset | Length | Field | Meaning |
|---|---|---|---|
| 0 | 4 | sfntVersion | 00 01 00 00 for TrueType outlines. Three other values are legal in the same slot and each means a different kind of file: 4F 54 54 4F (OTTO) is an OpenType font with PostScript outlines, 74 74 63 66 (ttcf) is a collection holding several faces at once, and 74 72 75 65 (true) is the older Apple tag that some Mac-authored fonts still carry. A detector keyed only on 00 01 00 00 silently misses the last of those. |
| 4 | 2 | numTables | How many table records follow the directory. Big-endian, like every multi-byte number in an sfnt file no matter which processor wrote it, which makes this one of the few formats a little-endian reader gets wrong in an immediately obvious way. |
| 6 | 2 | searchRange | The largest power of two not greater than numTables, multiplied by 16. It exists only as a hint for a binary search over the records, and shipping fonts get it wrong often enough - Apple system faces among them - that parsers ignore it and walk the records linearly instead. |
| 8 | 2 | entrySelector | The base-two logarithm of that same power of two. Another vestige of the binary-search hint, and equally safe to ignore; no rasteriser has depended on it in decades. |
| 10 | 2 | rangeShift | numTables times 16, minus searchRange. Wrong in a surprising share of real fonts, which is the plainest evidence available that these three fields are dead weight kept for backward compatibility. |
| 12 | variable | Table records | Sixteen bytes each: a four-character tag, a checksum, an absolute file offset and a length, all big-endian. Records are sorted alphabetically by tag, so the first one in the directory is whatever sorts first rather than whatever comes first in the file; the tables themselves may sit in any order, which makes the offsets the only reliable way to find them. |
| variable | 54 | head table | Reached through its directory record rather than from a fixed position. Twelve bytes into it sits the magic number 5F 0F 3C F5, the single surest check that a file really is an sfnt; unitsPerEm is at plus 18, and indexToLocFormat, which decides whether the loca table holds 16-bit or 32-bit offsets, is at plus 50. |
| variable | variable | glyf and loca tables | loca is an array of offsets into glyf, one per glyph plus a terminator, and glyf holds the contours themselves. Because the width of a loca entry is decided by a single field back in head, a font with a mismatched indexToLocFormat produces garbage outlines while every other part of the file validates cleanly. |
Telling it apart from its neighbours
| Easily confused with | How to tell |
|---|---|
| OpenType font | Both are sfnt files and both are OpenType in every sense that matters; the difference is the outline flavour, and it is announced by the four bytes at offset 0. 00 01 00 00 means quadratic TrueType outlines living in a glyf table, 4F 54 54 4F (OTTO) means cubic PostScript outlines packed into a CFF table. The extension is not evidence either way - plenty of files named .otf hold TrueType outlines. |
| TrueType Collection (.ttc) | A collection starts with 74 74 63 66 (ttcf), a version at offset 4 and a font count at offset 8, followed by an array of offsets each pointing at an ordinary table directory. Several faces then share one copy of the glyph data. macOS ships most of its system families this way, so a .ttc handed to a tool that insists on 00 01 00 00 at offset 0 is rejected as corrupt when nothing whatsoever is wrong with it. |
| WOFF font | The same font, wrapped for the web. The wrapper puts 77 4F 46 46 (wOFF) at offset 0 and moves the original sfntVersion to offset 4 as the flavor field, so a WOFF carrying a TrueType font reads 00 01 00 00 at offset 4 rather than 0. Renaming the file to .ttf changes nothing; the tables are still zlib streams. |
| WOFF2 font | The same relationship one generation on: 77 4F 46 32 (wOF2) at offset 0 and the flavour again at offset 4. Because the entire font body is a single Brotli stream, a WOFF2 saved out of a browser network panel and renamed .ttf cannot be rescued by renaming it back - it has to be decompressed by a tool that understands the wrapper. |
How these files break
- Truncated download. The directory at the front survives, so a hex viewer shows a plausible table count and a full set of tags, but the offsets and lengths in the later records point past the end of the file. Comparing the largest offset-plus-length in the directory against the real file size catches it in one pass without decoding anything.
- Text-mode transfer. An FTP client or a build step that translates line endings turns every 0D 0A inside the hinting bytecode and the glyph data into a bare 0A. The directory itself rarely contains that pair, so it still parses, and the font opens, reports the right glyph count and renders nonsense.
- A stale checkSumAdjustment. Subsetting and patching tools frequently rewrite tables without recomputing the value eight bytes into the head table. Rasterisers ignore it, so the font works everywhere it is used, but validators flag the file and a DSIG signature table that was valid before the edit is now meaningless.
- A renamed web font. Saving a .woff2 out of a browser and calling it .ttf is the single most common reason a font refuses to install: the bytes are Brotli-compressed and begin wOF2, and the operating system reports the file as damaged rather than as the wrong format, which sends people looking for the wrong problem.
- Prepended junk. A font fetched through a proxy that injects an error page, or downloaded after the session expired, arrives with an HTML doctype at offset 0 and not one byte of font data anywhere in it. The file size is often plausible, so nothing looks wrong until the first four bytes are read.
Where the format stands today
TrueType is still the workhorse of desktop typography. Windows and macOS both ship the overwhelming majority of their system faces as TrueType outlines, usually bundled into collections, and the hinting bytecode that made the format famous still matters wherever text is rendered small on a low-density screen. On the web it has been almost entirely displaced: browsers do accept a bare .ttf through an @font-face rule, but serving one wastes bandwidth, since WOFF2 delivers exactly the same tables for roughly a third fewer bytes. Where TrueType remains the first choice is anything that has to be installed rather than downloaded - a face going into a design tool, an embedded device, a print workflow or a PDF - and anything that will be edited again, because the tables are stored plainly and every font editor reads and writes them directly. The variable-font extension added in OpenType 1.8 is built on the same quadratic outlines, so a modern variable font is still a TrueType file underneath.
Open TrueType font files on this site
Every one of these runs in your browser — the file never leaves your machine.
Related formats
Formats that are easy to confuse with TrueType font — compare their leading bytes.
| Format | First bytes | Extension |
|---|---|---|
| OpenType font | 4F 54 54 4F | .otf |
| WOFF font | 77 4F 46 46 | .woff |
| WOFF2 font | 77 4F 46 32 | .woff2 |