kern - Kerning
Note: Apple has extended the definition of the 'kern' table to provide additional functionality. The Apple extensions are not supported on Windows. Fonts intended for cross-platform use or for the Windows platform in general should conform to the 'kern' table format specified here.
The kerning table contains the values that control the inter-character spacing for the glyphs in a font. There is currently no system level support for kerning (other than returning the kern pairs and kern values). OpenType™ fonts containing CFF outlines are not supported by the 'kern' table and must use the GPOS OpenType Layout table.
Each subtable varies in format, and can contain information for vertical or horizontal text, and can contain kerning values or minimum values. Kerning values are used to adjust inter-character spacing, and minimum values are used to limit the amount of adjustment that the scaler applies by the combination of kerning and tracking. Because the adjustments are additive, the order of the subtables containing kerning values is not important. However, tables containing minimum values should usually be placed last, so that they can be used to limit the total effect of other subtables.
The kerning table in the OpenType font file has a header, which contains the format number and the number of subtables present, and the subtables themselves.
|uint16||version||Table version number (0)|
|uint16||nTables||Number of subtables in the kerning table.|
Kerning subtables will share the same header format. This header is used to identify the format of the subtable and the kind of information it contains:
|uint16||version||Kern subtable version number|
|uint16||length||Length of the subtable, in bytes (including this header).|
|uint16||coverage||What type of information is contained in this table.|
The coverage field is divided into the following sub-fields, with sizes given in bits:
|horizontal||0||1||1 if table has horizontal data, 0 if vertical.|
|minimum||1||1||If this bit is set to 1, the table has minimum values. If set to 0, the table has kerning values.|
|cross-stream||2||1||If set to 1, kerning is perpendicular to the flow of the text.
If the text is normally written horizontally, kerning will be done in the up and down directions. If kerning values are positive, the text will be kerned upwards; if they are negative, the text will be kerned downwards.
If the text is normally written vertically, kerning will be done in the left and right directions. If kerning values are positive, the text will be kerned to the right; if they are negative, the text will be kerned to the left.
The value 0x8000 in the kerning data resets the cross-stream kerning back to 0.
|override||3||1||If this bit is set to 1 the value in this table should replace the value currently being accumulated.|
|reserved1||4-7||4||Reserved. This should be set to zero.|
|format||8-15||8||Format of the subtable. Only formats 0 and 2 have been defined. Formats 1 and 3 through 255 are reserved for future use.|
Format 0 is the only subtable format supported by Windows.
This subtable is a sorted list of kerning pairs and values. The list is preceded by information which makes it possible to make an efficient binary search of the list:
|uint16||nPairs||This gives the number of kerning pairs in the table.|
|uint16||searchRange||The largest power of two less than or equal to the value of nPairs, multiplied by the size in bytes of an entry in the table.|
|uint16||entrySelector||This is calculated as log2 of the largest power of two less than or equal to the value of nPairs. This value indicates how many iterations of the search loop will have to be made. (For example, in a list of eight items, there would have to be three iterations of the loop).|
|uint16||rangeShift||The value of nPairs minus the largest power of two less than or equal to nPairs, and then multiplied by the size in bytes of an entry in the table.|
This is followed by the list of kerning pairs and values. Each has the following format:
|uint16||left||The glyph index for the left-hand glyph in the kerning pair.|
|uint16||right||The glyph index for the right-hand glyph in the kerning pair.|
|FWORD||value||The kerning value for the above pair, in FUnits. If this value is greater than zero, the characters will be moved apart. If this value is less than zero, the character will be moved closer together.|
The left and right halves of the kerning pair make an unsigned 32-bit number, which is then used to order the kerning pairs numerically.
A binary search is most efficiently coded if the search range is a power of two. The search range can be reduced by half by shifting instead of dividing. In general, the number of kerning pairs, nPairs, will not be a power of two. The value of the search range, searchRange, should be the largest power of two less than or equal to nPairs. The number of pairs not covered by searchRange (that is, nPairs - searchRange) is the value rangeShift.
Windows v3.1 does not make use of the 'kern' data other than to expose it to applications through the GetFontData() API.Format 2
This subtable is a two-dimensional array of kerning values. The glyphs are mapped to classes, using a different mapping for left- and right-hand glyphs. This allows glyphs that have similar right- or left-side shapes to be handled together. Each similar right- or left-hand shape is said to be single class.
Each row in the kerning array represents one left-hand glyph class, each column represents one right-hand glyph class, and each cell contains a kerning value. Row and column 0 always represent glyphs that do not kern and contain all zeros.
The values in the right class table are stored pre-multiplied by the number of bytes in a single kerning value, and the values in the left class table are stored pre-multiplied by the number of bytes in one row. This eliminates needing to multiply the row and column values together to determine the location of the kerning value. The array can be indexed by doing the right- and left-hand class mappings, adding the class values to the address of the array, and fetching the kerning value to which the new address points.
The header for the simple array has the following format:
|uint16||rowWidth||The width, in bytes, of a row in the table.|
|Offset16||leftClassTable||Offset from beginning of this subtable to left-hand class table.|
|Offset16||rightClassTable||Offset from beginning of this subtable to right-hand class table.|
|Offset16||array||Offset from beginning of this subtable to the start of the kerning array.|
Each class table has the following header:
|uint16||firstGlyph||First glyph in class range.|
|uint16||nGlyphs||Number of glyph in class range.|
This header is followed by nGlyphs number of class values, which are in uint16 format. Entries for glyphs that don’t participate in kerning should point to the row or column at position zero.
The array itself is a left by right array of kerning values, which are FWords, where left is the number of left-hand classes and R is the number of right-hand classes. The array is stored by row.
Note that this format is the quickest to process since each lookup requires only a few index operations. The table can be quite large since it will contain the number of cells equal to the product of the number of right-hand classes and the number of left-hand classes, even though many of these classes do not kern with each other.
Would you like to provide feedback?
Our feedback system is built on GitHub Issues. Read more on our blog.