CPAL - Color Palette Table (OpenType 1.7)

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
USHORT version Table version number (=0).
USHORT numPalettesEntries Number of palette entries in each palette.
USHORT numPalette Number of palettes in the table.
USHORT numColorRecords Total number of color records, combined for all palettes.
ULONG offsetFirstColorRecord Offset from the beginning of CPAL table to the first ColorRecord.
USHORT 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
USHORT version Table version number (=1).
USHORT numPalettesEntries Number of palette entries in each palette.
USHORT numPalette Number of palettes in the table.
USHORT numColorRecords Total number of color records, combined for all palettes.
ULONG offsetFirstColorRecord Offset from the beginning of CPAL table to the first ColorRecord.
USHORT colorRecordIndices[numPalettes] Index of each palette’s first color record in the combined color record array.
ULONG offsetPaletteTypeArray Offset from the beginning of CPAL table to the Palette Type Array. Set to 0 if no array is provided.
ULONG offsetPaletteLabelArray Offset from the beginning of CPAL table to the Palette Labels Array. Set to 0 if no array is provided.
ULONG 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
BYTE blue Blue value (B0).
BYTE green Green value (B1).
BYTE red Red value (B2).
BYTE 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
ULONG paletteType [numPalettes] Array of 32-bit flag fields that describe properties of each palette. Set a particular ULONG 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
USHORT 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
USHORT 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.