CPAL — Color Palette Table

The palette table is a set of one or more palettes, each containing a predefined number of RGBA values arranged consecutively by palette index value. It may also contain name table IDs describing the palettes and their entries.

The first palette, number 0, is the default palette. The palettes are referenced by colorRecordIndices, this is the index into the array of color records where the palette starts. Multiple colorRecordIndices may refer to the same palette, therefore the number of actual palettes in the table may be less than the numPalettes entry. A minimum of one palette, the default, must be provided in the table if the table is present. Each palette must have the same number of entries as defined by numPaletteEntries, which must be at least one entry. Any empty CPAL table, with no palettes and no color records is not permissible. It is permissible for palettes to overlap and share data; therefore, the total number of color records in the CPAL table may be less than the number of palette entries multiplied by the number of palettes.

For each of the palettes, the first color record is index zero. There can be no more than numPaletteEntries of RGBA values.

Palette Table Header

The CPAL table begins with a header that starts with a version number. Currently, only versions 0 and 1 are defined.

The CPAL header version 0 is organized as follows:

Type Name Description
uint16 version Table version number (=0).
uint16 numPalettesEntries Number of palette entries in each palette.
uint16 numPalette Number of palettes in the table.
uint16 numColorRecords Total number of color records, combined for all palettes.
Offset32 offsetFirstColorRecord Offset from the beginning of CPAL table to the first ColorRecord.
uint16 colorRecordIndices[numPalettes] Index of each palette’s first color record in the combined color record array.

The CPAL header version 1 adds three additional fields to the end of the table header and is organized as follows:

Type Name Description
uint16 version Table version number (=1).
uint16 numPalettesEntries Number of palette entries in each palette.
uint16 numPalette Number of palettes in the table.
uint16 numColorRecords Total number of color records, combined for all palettes.
Offset32 offsetFirstColorRecord Offset from the beginning of CPAL table to the first ColorRecord.
uint16 colorRecordIndices[numPalettes] Index of each palette’s first color record in the combined color record array.
Offset32 offsetPaletteTypeArray Offset from the beginning of CPAL table to the Palette Type Array. Set to 0 if no array is provided.
Offset32 offsetPaletteLabelArray Offset from the beginning of CPAL table to the Palette Labels Array. Set to 0 if no array is provided.
Offset32 offsetPaletteEntryLabelArray Offset from the beginning of CPAL table to the Palette Entry Label Array. Set to 0 if no array is provided.

Palette Table

The choice of individual color record in the selected palette for a given glyph layer is determined as the sum of the palette entry index (defined by COLR table Layer Record) and the offset to the first color record of the selected palette.

Type Name Description
ColorRecord colorRecords[numColorRecords] Color records for all palettes

Color Record

The colors in the Color Record should not be pre-multiplied and the alpha value should be explicitly set for each palette entry. The color space for these values is sRGB.

Type Name Description
uint8 blue Blue value (B0).
uint8 green Green value (B1).
uint8 red Red value (B2).
uint8 alpha Alpha value (B3).

When placing and registering glyphs for a layered color approach there is the possible issue of “seaming” where the edge rendering of one glyph interferes with another glyph. This may be more or less visible based on the contrast of the colors used.

Palette Type Array

Type Name Description
uint32 paletteType [numPalettes] Array of 32-bit flag fields that describe properties of each palette. Set a particular uint32 to 0 if no properties are specified for that palette. Property flags:
Bit 0: Palette is appropriate to use when displaying the font on a light background such as white.
Bit 1: Palette is appropriate to use when displaying the font on a dark background such as black. Bits 0 and 1 are not mutually exclusive: they may both be set.

Palette Labels Array

Type Name Description
uint16 paletteLabel [numPalettes] Array of name table IDs (typically in the font-specific name ID range) that specify user interface strings associated with each palette. Use 0xFFFF if no name ID is provided for a particular palette.

Palette Entry Label Array

Type Name Description
uint16 paletteEntryLabel [numPaletteEntries] Array of name table IDs (typically in the font-specific name ID range) that specify user interface strings associated with each palette entry, e.g. “Outline”, “Fill”. This set of palette entry labels applies to all palettes in the font. Use 0xFFFF if no name ID is provided for a particular palette entry.

Both the COLR and SVG tables can use CPAL to define their palettes.

COLR and CPAL

With COLR, the CPAL table is required, and contains all the font-specified colors used by multicolored glyphs

As noted in the COLR table description, the palette entry index of 0xFFFF if specified in the COLR table represents the foreground color used in the system. This special value does not change across multiple palettes. The maximum palette entry index is 65535 - 1, as the 65536th position is used in the COLR table to indicate the foreground font color.

SVG and CPAL

With SVG, the CPAL table is optional, and contains the values of any color variables used by the SVG glyph descriptions in the SVG table.

Foreground color and foreground color opacity are expressed by the context-fill and context-fill-opacity attributes in the SVG glyph descriptions.

When used with an SVG table, the default palette’s colors must be set to the same values as the default values for the color variables in the SVG glyph descriptions; this is for text engines that support the SVG table but not color palettes. The SVG glyph descriptions are able to express their own explicit or “hard-coded” colors as well. These are not related to color variables and thus do not vary by palette selection. See the SVG table’s specification for more details.