The hmtx table gives each glyph’s advance width and left side bearing,
the gap between the glyph’s origin and the left edge of its outline. In most TrueType
fonts the left side bearing equals the xMin already stored in the glyph’s
bounding box in glyf, so WOFF2 can leave the bearings out. This is
transformation version 1 of hmtx in the
table directory; version 0
stores the table as it is. It is optional.
The original table
An OpenType hmtx table has numberOfHMetrics pairs (from the
hhea table) of a UInt16 advance width and an Int16 left side bearing, then
one more Int16 left side bearing for each remaining glyph, up to
numGlyphs (from maxp). The glyphs after the pairs all have
the last pair’s advance width.
Transformed structure
| Type | Name | Count | Present | Description |
|---|---|---|---|---|
| UInt8 | flags | 1 | always | Which arrays are left out: see flags. |
| UInt16 | advanceWidth | numberOfHMetrics | always | The advance widths, as in the original pairs. |
| Int16 | lsb | numberOfHMetrics | when bit 0 is clear | The left side bearings of the first numberOfHMetrics glyphs. |
| Int16 | leftSideBearing | numGlyphs − numberOfHMetrics | when bit 1 is clear | The left side bearings of the remaining glyphs. |
Even an array that is kept is stored apart from the advance widths, so like values sit together for the compressor.
Flags
| Bit | Mask | Meaning when set |
|---|---|---|
| 0 | 0x01 | The lsb array is absent; rebuild it from the glyphs’ xMin. |
| 1 | 0x02 | The leftSideBearing array is absent; rebuild it from the glyphs’ xMin. |
| 2 to 7 | 0xFC | Reserved: must be 0. |
At least one of bits 0 and 1 must be set; a transformation that leaves out nothing is not allowed. A decoder must reject the font when the flags break either rule.
When it may be used
- Only in fonts with TrueType outlines, since the bearings come from
glyf. A CFF font’shmtxis always stored as it is. - Only when every bearing left out equals its glyph’s
xMin, or is 0 for a glyph with no outline. An encoder must check this. - In a collection, only when
that holds for every combination of
hmtxandglyfthe fonts share.
Rebuilding the table
The decoder needs the glyphs’ bounding boxes first, so it decodes
glyf before hmtx. It then writes the original layout: for
each of the first numberOfHMetrics glyphs, the advance width and either
the stored lsb or the glyph’s xMin; then for each remaining
glyph the stored leftSideBearing or its xMin. A glyph with no
outline gets 0.