CPAL — Color Palette Table (OpenType 1.8.3)
The palette table is a set of one or more palettes, each containing a predefined number of color records with BGRA values. It may also contain 'name' table IDs describing the palettes and their entries.
Palettes are defined by a set of color records. All palettes have the same number of color records, specified by numColorRecords. All color records for all palettes are arranged in a single array, and the color records for any given palette are a contiguous sequence of color records within that array. The first color record of each palette is provided in the colorRecordIndices array.
Multiple colorRecordIndices may refer to the same color record, in which case multiple palettes would use the same color records; hence the number of functionally-distinct palettes may be fewer than the numPalettes entry. Also, the sequence of color records for different palettes may overlap, with certain color records shared between multiple palettes. Thus, 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.
The first palette, palette index 0, is the default palette. A minimum of one palette must be provided in the CPAL table if the table is present. Palettes must have a minimum of one color record. An empty CPAL table, with no palettes and no color records is not permitted.
Colors within a palette are referenced by base-zero index. The number of colors in each palette is given by numPaletteEntries. The number of color records in the color records array (numColorRecords) must be greater than or equal to max(colorRecordIndices) + numPaletteEntries.
Palette Table Header
The CPAL table begins with a header that starts with a version number. Currently, only versions 0 and 1 are defined.
CPAL version 0
The CPAL header version 0 is organized as follows:
Type | Name | Description |
---|---|---|
uint16 | version | Table version number (=0). |
uint16 | numPaletteEntries | Number of palette entries in each palette. |
uint16 | numPalettes | 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. |
CPAL version 1
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 | numPaletteEntries | Number of palette entries in each palette. |
uint16 | numPalettes | 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 Entries and Color Records
Colors defined in the CPAL table are referenced by a palette index plus a palette-entry index. Indices are base zero. For a given palette index and palette-entry index, an entry within the color records array is derived: colorRecordIndex = colorRecordIndices[paletteIndex] + paletteEntryIndex.
The color records array is comprised of color records:
Type | Name | Description |
---|---|---|
ColorRecord | colorRecords[numColorRecords] | Color records for all palettes |
Each color record has BGRA values. 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). |
The colors in the Color Record should not be pre-multiplied, and the alpha value should be explicitly set for each palette entry.
When placing and registering overlapping elements, there is the possibility of “seaming”, where the edge rendering of one element interferes with the other element. This may be more or less visible based on the contrast of the colors used.
Palette Type Array
Type | Name | Description |
---|---|---|
uint32 | paletteTypes[numPalettes] | Array of 32-bit flag fields that describe properties of each palette. See below for details. |
The following flags are defined:
Mask | Name | Description |
---|---|---|
0x0001 | USABLE_WITH_LIGHT_BACKGROUND | Bit 0: palette is appropriate to use when displaying the font on a light background such as white. |
0x0002 | USABLE_WITH_DARK_BACKGROUND | Bit 1: palette is appropriate to use when displaying the font on a dark background such as black. |
0xFFFC | Reserved | Reserved for future use — set to 0. |
Note that the USABLE_WITH_LIGHT_BACKGROUND and USABLE_WITH_DARK_BACKGROUND flags are not mutually exclusive: they may both be set.
Palette Labels Array
Type | Name | Description |
---|---|---|
uint16 | paletteLabels[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 | paletteEntryLabels[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. |
Relationship to COLR and SVG Tables
Both the COLR and SVG tables can use CPAL to define their palettes.
COLR and CPAL
In fonts that have a COLR table, 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
In fonts that have an SVG table, the CPAL table can be used to contain the values of any color variables used by SVG glyph descriptions in the SVG table. SVG glyph descriptions can also include color specifications directly, however. Thus, the CPAL table is optional for fonts with an 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 specification for more details.