COLR — Color Table
The COLR table adds support for multi-colored glyphs in a manner that is compatible with existing text engines and easy to support with current OpenType font files.
The COLR table defines a list of base glyphs — which are regular glyphs, typically associated with a 'cmap' entry. Each base glyph is associated by the COLR table to a list of glyphs, each corresponding to layers that can be combined, creating a colored representation of the base glyph. The layered glyphs are explicitly defined in bottom-up z-order and each of their advance widths must match those of the base glyph. If the font has vertical metrics, the associated layer glyphs must also have the same advance height and vertical Y origin as the base glyph.
The COLR table works together with the CPAL table which holds the color palettes used by the color layers.
Fonts using COLR and CPAL tables must implement glyph ID 1 as the .null glyph. If the COLR table is present in a font but no CPAL table exists, then the COLR table will not be supported for this font.
The table starts with a fixed portion describing the overall setup for the color font records. All offsets, unless otherwise noted, will be from the beginning of the table
|uint16||version||Table version number (starts at 0).|
|uint16||numBaseGlyphRecords||Number of Base Glyph Records.|
|Offset32||baseGlyphRecordsOffset||Offset (from beginning of COLR table) to Base Glyph records.|
|Offset32||layerRecordsOffset||Offset (from beginning of COLR table) to Layer Records.|
|uint16||numLayerRecords||Number of Layer Records.|
Base Glyph Record
The header of the COLR table points to the base glyph record. This record is used to match the base glyph to the layered glyphs. Each base glyph record contains a base glyph index. This is usually the glyph index that is referenced in the 'cmap' table. The number of layers is used to indicate how many color layers will be used for this base glyph. Each record then has an index to a glyph layer record. There will be numLayers of layer records for each base glyph. The firstLayerIndex refers to the lowest z-order, or bottom, glyph id for the colored glyph. The next layer record will represent the next highest glyph in the z-order, and this continues bottom-up until it reaches the numLayers glyph at the top of the z-order. The index is relative to the start of the Layer Records. The index does not have to be unique for each base glyph ID. If two base glyphs need to share the color glyphs and palette indices, this is acceptable. Likewise a Base Glyph Record could point partway into a z-order of another base glyph.
The base glyph records are sorted by glyph id. It is assumed that a binary search can be used to efficiently access the glyph IDs that have color values. Any use scenario that attempts to map glyphs to character codes must be aware of the mapping done by the COLR table.
|uint16||gID||Glyph ID of reference glyph. This glyph is for reference only and is not rendered for color.|
|uint16||firstLayerIndex||Index (from beginning of the Layer Records) to the layer record. There will be numLayers consecutive entries for this base glyph.|
|uint16||numLayers||Number of color layers associated with this glyph.|
|uint16||gID||Glyph ID of layer glyph (must be in z-order from bottom to top).|
|uint16||paletteIndex||Index value to use with a selected color palette. This value must be less than numPaletteEntries in the CPAL table. A palette entry index value of 0xFFFF is a special case indicating that the text foreground color (defined by a higher-level client) should be used and shall not be treated as actual index into CPAL ColorRecord array.|
The selection of color palette to be used for a given layer record is the responsibility of a higher-level client. With CPAL version 0 – the palette selection needs to be made based on the information distributed with a font. CPAL version 1 offers user-selectable color palettes based on a textual descriptions of palette entries and palette labels.
Would you like to provide feedback?
Our feedback system is built on GitHub Issues. Read more on our blog.