The glyf table holds the outlines, one glyph description after another
with no header, and loca says where each one starts. An outline is made of
closed contours of points, each on or off the curve; two on-curve points make a
straight line, and an off-curve point between them is the control point of a quadratic
Bézier curve. Two off-curve points in a row imply an on-curve point midway between
them. A composite glyph is built from other glyphs instead, such as é from e and the
acute accent.
loca: index to location
numGlyphs + 1 offsets from the start of glyf, one per glyph
and one more for the end of the last. Glyph n runs from
loca[n] to loca[n + 1], so glyph descriptions must be in
glyph ID order, and the offsets must not decrease.
indexToLocFormat in head | Format | Each entry |
|---|---|---|
| 0 | Short | Offset16: the offset divided by 2. Glyphs must start at even offsets, and the last offset can be at most 65,535 × 2 = 131,070. |
| 1 | Long | Offset32: the offset itself. |
A glyph with no outline and no instructions, such as the space, has
loca[n] = loca[n + 1]: it takes no bytes in glyf.
Glyph header
| Offset | Type | Name | Description |
|---|---|---|---|
0 | int16 | numberOfContours | 0 or more: a simple glyph. Negative, normally −1: a composite glyph. |
2 | int16 | xMin | The smallest x of the glyph’s points, on- and off-curve. |
4 | int16 | yMin | The smallest y. |
6 | int16 | xMax | The largest x. |
8 | int16 | yMax | The largest y. |
The box contains the outline but may not be tight to it, as it is taken from the
control points. There are no side bearings here; they come from hmtx,
and the rasteriser adds four “phantom points” after the last point for the origin,
advance width, top and bottom, which instructions can move.
Simple glyph
| Type | Name | Description |
|---|---|---|
uint16 × numberOfContours | endPtsOfContours | The number of the last point of each contour, increasing. Points are numbered from 0 across all contours; the last entry + 1 is the number of points. |
uint16 | instructionLength | Bytes of instructions; may be 0. |
uint8 × instructionLength | instructions | The glyph’s hinting program. |
uint8[ ] | flags | One flag per point, packed with REPEAT_FLAG. |
uint8 or int16[ ] | xCoordinates | The change in x from the previous point (the first point’s from 0), 0, 1 or 2 bytes each as its flag says. |
uint8 or int16[ ] | yCoordinates | The change in y, the same way. All x values come before all y values. |
A glyph with 0 contours may still have instructions, which then work on the phantom points. The flag and coordinate arrays have no stored length: a reader expands the flags until it has one per point, then reads the x and y bytes the flags call for.
Point flags
| Bit | Mask | Name | Meaning |
|---|---|---|---|
| 0 | 0x01 | ON_CURVE_POINT | The point is on the curve; clear for an off-curve control point. |
| 1 | 0x02 | X_SHORT_VECTOR | The x change is one unsigned byte, with its sign in bit 4. |
| 2 | 0x04 | Y_SHORT_VECTOR | The y change is one unsigned byte, with its sign in bit 5. |
| 3 | 0x08 | REPEAT_FLAG | The next byte is a count of how many more times this flag repeats for the following points. |
| 4 | 0x10 | X_IS_SAME_OR_POSITIVE_X_SHORT_VECTOR | With bit 1 set: the byte is positive (clear: negative). With bit 1 clear: set means x is the same as the previous point and no bytes are stored; clear means a signed 16-bit change follows. |
| 5 | 0x20 | Y_IS_SAME_OR_POSITIVE_Y_SHORT_VECTOR | The same for y, with bit 2. |
| 6 | 0x40 | OVERLAP_SIMPLE | Contours may overlap. Optional; when used, set on the first flag of the glyph. Some rasterisers need it to fill overlaps correctly, which matters for instances taken from variable fonts. |
| 7 | 0x80 | reserved | 0. |
| Bit 1 (or 2) | Bit 4 (or 5) | Stored | Change |
|---|---|---|---|
| 0 | 0 | 2 bytes | signed 16-bit value |
| 0 | 1 | nothing | 0, same as the previous point |
| 1 | 0 | 1 byte | −byte (0 to −255) |
| 1 | 1 | 1 byte | +byte (0 to 255) |
Composite glyph
After the header come component records, one per component glyph, until one without
MORE_COMPONENTS. Components can themselves be composites, but the graph
must have no loops and end in simple glyphs; maxComponentDepth in
maxp gives the deepest nesting, and some PostScript devices cannot draw
nested composites. As each component is added, its points are renumbered to follow the
points already in the glyph.
| Type | Name | Description |
|---|---|---|
uint16 | flags | See component flags. |
uint16 | glyphIndex | The component glyph. |
| 1 or 2 bytes | argument1 | x offset, or a point number in the composite so far. |
| 1 or 2 bytes | argument2 | y offset, or a point number in the component. |
| 0, 2, 4 or 8 bytes | transform | F2DOT14 values: one scale; or xscale, yscale; or xscale, scale01, scale10, yscale. |
After the last component, if any component had WE_HAVE_INSTRUCTIONS,
come a uint16 instruction length and the instructions for the whole
glyph, run after each component’s own.
Component flags
| Bit | Mask | Name | Meaning |
|---|---|---|---|
| 0 | 0x0001 | ARG_1_AND_2_ARE_WORDS | The arguments are 16-bit; otherwise 8-bit. |
| 1 | 0x0002 | ARGS_ARE_XY_VALUES | The arguments are a signed x, y offset; otherwise unsigned point numbers. Must be set on the first component. |
| 2 | 0x0004 | ROUND_XY_TO_GRID | Round the offset, after any transform and variation, to the pixel grid. Only with bit 1. |
| 3 | 0x0008 | WE_HAVE_A_SCALE | One F2DOT14 scale for both directions. |
| 4 | 0x0010 | reserved | 0. |
| 5 | 0x0020 | MORE_COMPONENTS | Another component follows. |
| 6 | 0x0040 | WE_HAVE_AN_X_AND_Y_SCALE | Separate x and y scales. |
| 7 | 0x0080 | WE_HAVE_A_TWO_BY_TWO | A full 2 × 2 matrix. |
| 8 | 0x0100 | WE_HAVE_INSTRUCTIONS | Instructions for the composite follow the last component. |
| 9 | 0x0200 | USE_MY_METRICS | The composite takes its advance width and side bearings from this component, as ï does from its dotless i. Undefined for rotated components. |
| 10 | 0x0400 | OVERLAP_COMPOUND | The components overlap. Optional; when used, set on the first component. |
| 11 | 0x0800 | SCALED_COMPONENT_OFFSET | The offset is in the component’s coordinates, so the transform applies to it too. |
| 12 | 0x1000 | UNSCALED_COMPONENT_OFFSET | The offset is in the composite’s coordinates and is not transformed. |
| 13 to 15 | 0xE000 | reserved | 0. |
Bits 3, 6 and 7 are exclusive: at most one may be set. With neither bit 11 nor bit 12 set, Microsoft and Apple rasterisers behave as if bit 12 were set, which is the recommended default; both set is invalid and also gets the default.
Arguments and transform
| Bit 0 | Bit 1 | argument1, argument2 |
|---|---|---|
| 0 | 0 | uint8 point numbers |
| 0 | 1 | int8 x and y offsets |
| 1 | 0 | uint16 point numbers |
| 1 | 1 | int16 (FWORD) x and y offsets |
With offsets, (argument1, argument2) is added to every point of the component. With point numbers, the component is moved so that its point argument2 lands on the composite’s point argument1; phantom points may be used, and any transform is applied to the component first.
A point (x, y) of the component becomes
x′ = xscale × x + scale10 × y
and y′ = scale01 × x + yscale × y.
With WE_HAVE_AN_X_AND_Y_SCALE, scale01 and
scale10 are 0; with WE_HAVE_A_SCALE, xscale
and yscale are both the one scale. A mirror image of a component is
xscale = −1, stored as 0xC000.
Example
The loca of KaTeX’s Size2 Regular font is short format (41 entries,
82 bytes). It starts 0000 0012 0012 0012 0012 003E: glyph 0 runs from 0 to
36, glyphs 1 to 3 (.null, nonmarkingreturn,
space) are empty at 36, and glyph 4 runs from 36 to 124. The last entry,
0A87, is 5,390, the length of glyf.
Glyph 0, .notdef, the 36 bytes at the start of glyf:
00 02 numberOfContours 2
00 32 00 00 00 C8 02 15 xMin 50, yMin 0, xMax 200, yMax 533
00 03 00 07 endPtsOfContours 3, 7: 8 points
00 00 instructionLength 0
33 11 33 11 27 33 11 23 flags, one per point
32 96 64 32 32 x changes
02 15 FD EB 32 01 B1 y changes
| Point | Flag | x | y |
|---|---|---|---|
| 0 | 33: on curve, x +byte, y same | +50 = 50 | 0 |
| 1 | 11: on curve, x same, y 16-bit | 50 | +533 = 533 |
| 2 | 33 | +150 = 200 | 533 |
| 3 | 11 | 200 | −533 (FDEB) = 0 |
| 4 | 27: on curve, x −byte, y +byte | −100 = 100 | +50 = 50 |
| 5 | 33 | +50 = 150 | 50 |
| 6 | 11 | 150 | +433 = 483 |
| 7 | 23: on curve, x −byte, y same | −50 = 100 | 483 |
Two rectangles, all points on the curve: (50, 0) to (200, 533) and, inside it, (100, 50) to (150, 483). Drawn in opposite directions, the inner one cuts a hole, making the usual hollow box of a missing character.