cmap — Character to Glyph Index Mapping Table (OpenType 1.8.3)
This table defines the mapping of character codes to the glyph index values used in the font. It may contain more than one subtable, in order to support more than one character encoding scheme.
Overview
This table defines mapping of character codes to a default glyph index. Different subtables may be defined that each contain mappings for different character encoding schemes. The table header indicates the character encodings for which subtables are present.
Regardless of the encoding scheme, character codes that do not correspond to any glyph in the font should be mapped to glyph index 0. The glyph at this location must be a special glyph representing a missing character, commonly known as .notdef.
Each subtable is in one of seven possible formats and begins with a format field indicating the format used. The first four formats — formats 0, 2, 4 and 6 — were originally defined prior to Unicode 2.0. These formats allow for 8-bit single-byte, 8-bit multi-byte, and 16-bit encodings. With the introduction of supplementary planes in Unicode 2.0, the Unicode addressable code space extends beyond 16 bits. To accommodate this, three additional formats were added — formats 8, 10 and 12 — that allow for 32-bit encoding schemes.
Other enhancements in Unicode led to the addition of other subtable formats. Subtable format 13 allows for an efficient mapping of many characters to a single glyph; this is useful for “last-resort” fonts that provide fallback rendering for all possible Unicode characters with a distinct fallback glyph for different Unicode ranges. Subtable format 14 provides a unified mechanism for supporting Unicode variation sequences.
Note: The 'cmap' table version number remains at 0x0000 for fonts that make use of the newer subtable formats.
'cmap' Header
The Character To Glyph Index Mapping Table is organized as follows:
Type | Name | Description |
---|---|---|
uint16 | version | Table version number (0). |
uint16 | numTables | Number of encoding tables that follow. |
EncodingRecord | encodingRecords[numTables] |
Encoding records and encodings
The array of encoding records specifies particular encodings and the offset to the subtable for each encoding.
EncodingRecord:
Type | Name | Description |
---|---|---|
uint16 | platformID | Platform ID. |
uint16 | encodingID | Platform-specific encoding ID. |
Offset32 | offset | Byte offset from beginning of table to the subtable for this encoding. |
The platform ID and platform-specific encoding ID in the encoding record are used to specify a particular character encoding. In the case of the Macintosh platform, a language field within the mapping subtable is also used for this purpose.
The encoding record entries in the 'cmap' header must be sorted first by platform ID, then by platform-specific encoding ID, and then by the language field in the corresponding subtable. Each platform ID, platform-specific encoding ID, and subtable language combination may appear only once in the 'cmap' table.
Complete details on platform IDs and platform-specific encoding and language IDs are provided in the 'name' table chapter. Some specific details applicable to the 'cmap' table are provided here.
Unicode platform (platform ID = 0)
Unicode Variation Sequences supported by the font should be specified in the 'cmap' table using a format 14 subtable. A format 14 subtable must only be used under platform ID 0 and encoding ID 5.
Macintosh platform (platform ID = 1)
When building a font that will be used on the Macintosh, the platform ID should be 1 and the encoding ID should be 0.
Windows platform (platform ID = 3)
When building a Unicode font for Windows, the platform ID should be 3 and the encoding ID should be 1. When building a symbol font for Windows, the platform ID should be 3 and the encoding ID should be 0.
Microsoft strongly recommends using Unicode 'cmap' subtables for all fonts. However, other non-Unicode encodings are also used in existing fonts with the Windows platform. The following are encoding IDs defined for the Windows platform:
Windows Encodings
Platform ID | Encoding ID | Description |
---|---|---|
3 | 0 | Symbol |
3 | 1 | Unicode BMP |
3 | 2 | ShiftJIS |
3 | 3 | PRC |
3 | 4 | Big5 |
3 | 5 | Wansung |
3 | 6 | Johab |
3 | 7 | Reserved |
3 | 8 | Reserved |
3 | 9 | Reserved |
3 | 10 | Unicode full repertoire |
When building a symbol font for Windows, the platform ID should be 3 and the encoding ID should be 0.
Fonts that support Unicode BMP characters (U+0000 to U+FFFF) on the Windows platform must have a format 4 'cmap' subtable for platform ID 3, platform-specific encoding 1.
Fonts that support Unicode supplementary-plane characters (U+10000 to U+10FFFF) on the Windows platform must have a format 12 subtable for platform ID 3, encoding ID 10. To ensure backward compatibility with older software and devices, a format 4 subtable for platform ID 3, encoding ID 1 is also required. The characters supported in the format 4 subtable must be a subset of the characters in the format 12 subtable and should include all of the Unicode BMP characters supported by the font.
Custom platform (platform ID = 4) and OTF Windows NT compatibility mapping
If a platform ID 4 (custom), encoding ID 0-255 (OTF Windows NT compatibility mapping) 'cmap' encoding is present in an OpenType font with CFF outlines, then the OTF font driver in Windows NT will: (a) superimpose the glyphs encoded at character codes 0-255 in the encoding on the corresponding Windows ANSI (code page 1252) Unicode values in the Unicode encoding it reports to the system; (b) add Windows ANSI (CharSet 0) to the list of CharSets supported by the font; and (c) consider the value of the encoding ID to be a Windows CharSet value and add it to the list of CharSets supported by the font. Note: The 'cmap' subtable must use Format 0 or 6 for its subtable, and the encoding must be identical to the CFF’s encoding.
This 'cmap' encoding is not required. It provides a compatibility mechanism for non-Unicode applications that use the font as if it were Windows ANSI encoded. Non-Windows ANSI Type 1 fonts, such as Cyrillic and Central European fonts, that Adobe shipped in the past had “0” (Windows ANSI) recorded in the CharSet field of the .PFM file; ATM for Windows 9x ignores the CharSet altogether. Adobe provides this compatibility 'cmap' encoding in every OTF converted from a Type1 font in which the Encoding is not StandardEncoding.
Use of the language field in 'cmap' subtables
The language field must be set to zero for all 'cmap' subtables whose platform IDs are other than Macintosh (platform ID 1). For 'cmap' subtables whose platform IDs are Macintosh, set this field to the Macintosh language ID of the 'cmap' subtable plus one, or to zero if the 'cmap' subtable is not language-specific. For example, a Mac OS Turkish 'cmap' subtable must set this field to 18, since the Macintosh language ID for Turkish is 17. A Mac OS Roman 'cmap' subtable must set this field to 0, since Mac OS Roman is not a language-specific encoding.
Format 0: Byte encoding table
This is the Apple standard character to glyph index mapping table.
'cmap' Subtable Format 0:
Type | Name | Description |
---|---|---|
uint16 | format | Format number is set to 0. |
uint16 | length | This is the length in bytes of the subtable. |
uint16 | language | For requirements on use of the language field, see “Use of the language field in 'cmap' subtables” in this document. |
uint8 | glyphIdArray[256] | An array that maps character codes to glyph index values. |
This is a simple 1 to 1 mapping of character codes to glyph indices. The glyph set is limited to 256. Note that if this format is used to index into a larger glyph set, only the first 256 glyphs will be accessible.
Format 2: High-byte mapping through table
This subtable is useful for the national character code standards used for Japanese, Chinese, and Korean characters. These code standards use a mixed 8-/16-bit encoding, in which certain byte values signal the first byte of a 2-byte character (but these values are also legal as the second byte of a 2-byte character).
In addition, even for the 2-byte characters, the mapping of character codes to glyph index values depends heavily on the first byte. Consequently, the table begins with an array that maps the first byte to a SubHeader record. For 2-byte character codes, the SubHeader is used to map the second byte’s value through a subArray, as described below. When processing mixed 8-/16-bit text, SubHeader 0 is special: it is used for single-byte character codes. When SubHeader 0 is used, a second byte is not needed; the single byte value is mapped through the subArray.
'cmap' Subtable Format 2:
Type | Name | Description |
---|---|---|
uint16 | format | Format number is set to 2. |
uint16 | length | This is the length in bytes of the subtable. |
uint16 | language | For requirements on use of the language field, see “Use of the language field in 'cmap' subtables” in this document. |
uint16 | subHeaderKeys[256] | Array that maps high bytes to subHeaders: value is subHeader index × 8. |
SubHeader | subHeaders[ ] | Variable-length array of SubHeader records. |
uint16 | glyphIndexArray[ ] | Variable-length array containing subarrays used for mapping the low byte of 2-byte characters. |
A SubHeader is structured as follows:
SubHeader Record:
Type | Name | Description |
---|---|---|
uint16 | firstCode | First valid low byte for this SubHeader. |
uint16 | entryCount | Number of valid low bytes for this SubHeader. |
int16 | idDelta | See text below. |
uint16 | idRangeOffset | See text below. |
The firstCode and entryCount values specify a subrange that begins at firstCode and has a length equal to the value of entryCount. This subrange stays within the 0-255 range of the byte being mapped. Bytes outside of this subrange are mapped to glyph index 0 (missing glyph).The offset of the byte within this subrange is then used as index into a corresponding subarray of glyphIndexArray. This subarray is also of length entryCount. The value of the idRangeOffset is the number of bytes past the actual location of the idRangeOffset word where the glyphIndexArray element corresponding to firstCode appears.
Finally, if the value obtained from the subarray is not 0 (which indicates the missing glyph), you should add idDelta to it in order to get the glyphIndex. The value idDelta permits the same subarray to be used for several different subheaders. The idDelta arithmetic is modulo 65536.
Format 4: Segment mapping to delta values
This is the standard character-to-glyph-index mapping table for the Windows platform for fonts that support Unicode BMP characters. See Windows platform (platform ID = 3) above for additional details regarding subtable formats for Unicode encoding on the Windows platform.
This format is used when the character codes for the characters represented by a font fall into several contiguous ranges, possibly with holes in some or all of the ranges (that is, some of the codes in a range may not have a representation in the font). The format-dependent data is divided into three parts, which must occur in the following order:
- A four-word header gives parameters for an optimized search of the segment list;
- Four parallel arrays describe the segments (one segment for each contiguous range of codes);
- A variable-length array of glyph IDs (unsigned words).
'cmap' Subtable Format 4:
Type | Name | Description |
---|---|---|
uint16 | format | Format number is set to 4. |
uint16 | length | This is the length in bytes of the subtable. |
uint16 | language | For requirements on use of the language field, see “Use of the language field in 'cmap' subtables” in this document. |
uint16 | segCountX2 | 2 × segCount. |
uint16 | searchRange | 2 × (2**floor(log2(segCount))) |
uint16 | entrySelector | log2(searchRange/2) |
uint16 | rangeShift | 2 × segCount - searchRange |
uint16 | endCode[segCount] | End characterCode for each segment, last=0xFFFF. |
uint16 | reservedPad | Set to 0. |
uint16 | startCode[segCount] | Start character code for each segment. |
int16 | idDelta[segCount] | Delta for all character codes in segment. |
uint16 | idRangeOffset[segCount] | Offsets into glyphIdArray or 0 |
uint16 | glyphIdArray[ ] | Glyph index array (arbitrary length) |
The number of segments is specified by segCount, which is not explicitly in the header; however, all of the header parameters are derived from it. The searchRange value is twice the largest power of 2 that is less than or equal to segCount. For example, if segCount=39, we have the following:
segCountX2 | 78 | |||||
searchRange | 64 (= 2 × largest power of 2 <=39) | |||||
entrySelector | 5 (= log232) | |||||
rangeShift | 14 (= 2 × 39 - 64) |
Each segment is described by a startCode and endCode, along with an idDelta and an idRangeOffset, which are used for mapping the character codes in the segment. The segments are sorted in order of increasing endCode values, and the segment values are specified in four parallel arrays. You search for the first endCode that is greater than or equal to the character code you want to map. If the corresponding startCode is less than or equal to the character code, then you use the corresponding idDelta and idRangeOffset to map the character code to a glyph index (otherwise, the missingGlyph is returned). For the search to terminate, the final start code and endCode values must be 0xFFFF. This segment need not contain any valid mappings. (It can just map the single character code 0xFFFF to missingGlyph). However, the segment must be present.
If the idRangeOffset value for the segment is not 0, the mapping of character codes relies on glyphIdArray. The character code offset from startCode is added to the idRangeOffset value. This sum is used as an offset from the current location within idRangeOffset itself to index out the correct glyphIdArray value. This obscure indexing trick works because glyphIdArray immediately follows idRangeOffset in the font file. The C expression that yields the glyph index is:
glyphId = *(idRangeOffset[i]/2
+ (c - startCode[i])
+ &idRangeOffset[i])
The value c is the character code in question, and i is the segment index in which c appears. If the value obtained from the indexing operation is not 0 (which indicates missingGlyph), idDelta[i] is added to it to get the glyph index. The idDelta arithmetic is modulo 65536.
If the idRangeOffset is 0, the idDelta value is added directly to the character code offset (i.e. idDelta[i] + c
) to get the corresponding glyph index. Again, the idDelta arithmetic is modulo 65536.
As an example, the variant part of the table to map characters 10-20, 30-90, and 153-480 onto a contiguous range of glyph indices may look like this:
segCountX2: | 8 | |||||
searchRange: | 8 | |||||
entrySelector: | 4 | |||||
rangeShift: | 0 | |||||
endCode: | 20 90 480 0xffff | |||||
reservedPad: | 0 | |||||
startCode: | 10 30 153 0xffff | |||||
idDelta: | -9 -18 -27 1 | |||||
idRangeOffset: | 0 0 0 0 |
This table performs the following mappings:
10 ⇒ 10 - 9 = 1
20 ⇒ 20 - 9 = 11
30 ⇒ 30 - 18 = 12
90 ⇒ 90 - 18 = 72
...
Note that the delta values could be reworked so as to reorder the segments.
Format 6: Trimmed table mapping
'cmap' Subtable Format 6:
Type | Name | Description |
---|---|---|
uint16 | format | Format number is set to 6. |
uint16 | length | This is the length in bytes of the subtable. |
uint16 | language | For requirements on use of the language field, see “Use of the language field in 'cmap' subtables” in this document. |
uint16 | firstCode | First character code of subrange. |
uint16 | entryCount | Number of character codes in subrange. |
uint16 | glyphIdArray[entryCount] | Array of glyph index values for character codes in the range. |
The firstCode and entryCount values specify a subrange (beginning at firstCode, length = entryCount) within the range of possible character codes. Codes outside of this subrange are mapped to glyph index 0. The offset of the code (from the first code) within this subrange is used as index to the glyphIdArray, which provides the glyph index value.
Format 8: mixed 16-bit and 32-bit coverage
Format 8 is similar to format 2, in that it provides for mixed-length character codes. Instead of allowing for 8- and 16-bit character codes, however, it allows for 16- and 32-bit character codes.
If a font contains Unicode supplementary-plane characters (U+10000 to U+10FFFF), then it’s likely that it will also include Unicode BMP characters (U+0000 to U+FFFF) as well. Hence, there is a need to map a mixture of 16-bit and 32-bit character codes. A simplifying assumption is made: namely, that there are no 32-bit character codes which share the same first 16 bits as any 16-bit character code. (Since the Unicode code space extends only to U+1FFFFF, a potential conflict exists only for characters U+0000 to U+001F, which are non-printing control characters.) This means that the determination as to whether a particular 16-bit value is a standalone character code or the start of a 32-bit character code can be made by looking at the 16-bit value directly, with no further information required.
'cmap' Subtable Format 8:
Type | Name | Description |
---|---|---|
uint16 | format | Subtable format; set to 8. |
uint16 | reserved | Reserved; set to 0 |
uint32 | length | Byte length of this subtable (including the header) |
uint32 | language | For requirements on use of the language field, see “Use of the language field in 'cmap' subtables” in this document. |
uint8 | is32[8192] | Tightly packed array of bits (8K bytes total) indicating whether the particular 16-bit (index) value is the start of a 32-bit character code |
uint32 | numGroups | Number of groupings which follow |
SequentialMapGroup | groups[numGroups] | Array of SequentialMapGroup records. |
Each sequential map group record specifies a character range and the starting glyph ID mapped from the first character. Glyph IDs for subsequent characters follow in sequence.
SequentialMapGroup Record:
Type | Name | Description |
---|---|---|
uint32 | startCharCode | First character code in this group; note that if this group is for one or more 16-bit character codes (which is determined from the is32 array), this 32-bit value will have the high 16-bits set to zero |
uint32 | endCharCode | Last character code in this group; same condition as listed above for the startCharCode |
uint32 | startGlyphID | Glyph index corresponding to the starting character code |
A few notes here. The endCharCode is used, rather than a count, because comparisons for group matching are usually done on an existing character code, and having the endCharCode be there explicitly saves the necessity of an addition per group. Groups must be sorted by increasing startCharCode. A group’s endCharCode must be less than the startCharCode of the following group, if any.
To determine if a particular word (cp) is the first half of 32-bit code points, one can use an expression such as ( is32[ cp / 8 ] & ( 1 << ( 7 - ( cp % 8 ) ) ) ). If this is non-zero, then the word is the first half of a 32-bit code point.
0 is not a special value for the high word of a 32-bit code point. A font may not have both a glyph for the code point 0x0000 and glyphs for code points with a high word of 0x0000.
The presence of the packed array of bits indicating whether a particular 16-bit value is the start of a 32-bit character code is useful even when the font contains no glyphs for a particular 16-bit start value. This is because the system software often needs to know how many bytes ahead the next character begins, even if the current character maps to the missing glyph. By including this information explicitly in this table, no “secret” knowledge needs to be encoded into the OS.
Although this format was created to support Unicode supplementary-plane characters, it is not widely supported or used. Also, no character encoding other than Unicode uses mixed 16-/32-bit characters. The use of this format is discouraged.
Format 10: Trimmed array
Format 10 is similar to format 6, in that it defines a trimmed array for a tight range of character codes. It differs, however, in that is uses 32-bit character codes:
'cmap' Subtable Format 10:
Type | Name | Description |
---|---|---|
uint16 | format | Subtable format; set to 10. |
uint16 | reserved | Reserved; set to 0 |
uint32 | length | Byte length of this subtable (including the header) |
uint32 | language | For requirements on use of the language field, see “Use of the language field in 'cmap' subtables” in this document. |
uint32 | startCharCode | First character code covered |
uint32 | numChars | Number of character codes covered |
uint16 | glyphs[] | Array of glyph indices for the character codes covered |
This format is not widely used and is not supported by Microsoft. It would be most suitable for fonts that support only a contiguous range of Unicode supplementary-plane characters, but such fonts are rare.
Format 12: Segmented coverage
This is the standard character-to-glyph-index mapping table for the Windows platform for fonts supporting Unicode supplementary-plane characters (U+10000 to U+10FFFF). See Windows platform (platform ID = 3) above for additional details regarding subtable formats for Unicode encoding on the Windows platform.
Format 12 is similar to format 4 in that it defines segments for sparse representation. It differs, however, in that it uses 32-bit character codes.
'cmap' Subtable Format 12:
Type | Name | Description |
---|---|---|
uint16 | format | Subtable format; set to 12. |
uint16 | reserved | Reserved; set to 0 |
uint32 | length | Byte length of this subtable (including the header) |
uint32 | language | For requirements on use of the language field, see “Use of the language field in 'cmap' subtables” in this document. |
uint32 | numGroups | Number of groupings which follow |
SequentialMapGroup | groups[numGroups] | Array of SequentialMapGroup records. |
The sequential map group record is the same format as is used for the format 8 subtable. The qualifications regarding 16-bit character codes does not apply here, however, since characters codes are uniformly 32-bit.
SequentialMapGroup Record:
Type | Name | Description |
---|---|---|
uint32 | startCharCode | First character code in this group |
uint32 | endCharCode | Last character code in this group |
uint32 | startGlyphID | Glyph index corresponding to the starting character code |
Groups must be sorted by increasing startCharCode. A group’s endCharCode must be less than the startCharCode of the following group, if any. The endCharCode is used, rather than a count, because comparisons for group matching are usually done on an existing character code, and having the endCharCode be there explicitly saves the necessity of an addition per group.
Format 13: Many-to-one range mappings
This subtable provides for situations in which the same glyph is used for hundreds or even thousands of consecutive characters spanning across multiple ranges of the code space. This subtable format may be useful for “last resort” fonts, although these fonts may use other suitable subtable formats as well. (For “last-resort” fonts, see also the 'head' table flags, bit 14.)
Note: Subtable format 13 has the same structure as format 12; it differs only in the interpretation of the startGlyphID/glyphID fields.
'cmap' Subtable Format 13:
Type | Name | Description |
---|---|---|
uint16 | format | Subtable format; set to 13. |
uint16 | reserved | Reserved; set to 0 |
uint32 | length | Byte length of this subtable (including the header) |
uint32 | language | For requirements on use of the language field, see “Use of the language field in 'cmap' subtables” in this document. |
uint32 | numGroups | Number of groupings which follow |
ConstantMapGroup | groups[numGroups] | Array of ConstantMapGroup records. |
The constant map group record has the same structure as the sequential map group record, with start and end character codes and a mapped glyph ID. However, the same glyph ID applies to all characters in the specified range rather than sequential glyph IDs.
ConstantMapGroup Record:
Type | Name | Description |
---|---|---|
uint32 | startCharCode | First character code in this group |
uint32 | endCharCode | Last character code in this group |
uint32 | glyphID | Glyph index to be used for all the characters in the group’s range. |
Format 14: Unicode Variation Sequences
Subtable format 14 specifies the Unicode Variation Sequences (UVSes) supported by the font. A Variation Sequence, according to the Unicode Standard, comprises a base character followed by a variation selector. For example, <U+82A6, U+E0101>.
The subtable partitions the UVSes supported by the font into two categories: “default” and “non-default” UVSes. Given a UVS, if the glyph obtained by looking up the base character of that sequence in the Unicode 'cmap' subtable (i.e. the BMP subtable or the BMP + supplementary-planes subtable) is the glyph to use for that sequence, then the sequence is a default UVS; otherwise it is a non-default UVS, and the glyph to use for that sequence is specified in the format 14 subtable itself.
The example at the bottom of the page shows how a font vendor can use format 14 for a JIS-2004-aware font.
'cmap' Subtable Format 14:
Type | Name | Description |
---|---|---|
uint16 | format | Subtable format. Set to 14. |
uint32 | length | Byte length of this subtable (including this header) |
uint32 | numVarSelectorRecords | Number of variation Selector Records |
VariationSelector | varSelector[numVarSelectorRecords] | Array of VariationSelector records. |
Each variation selector records specifies a variation selector character, and offsets to default and non-default tables used to map variation sequences using that variation selector.
VariationSelector Record:
Type | Name | Description |
---|---|---|
uint24 | varSelector | Variation selector |
Offset32 | defaultUVSOffset | Offset from the start of the format 14 subtable to Default UVS Table. May be 0. |
Offset32 | nonDefaultUVSOffset | Offset from the start of the format 14 subtable to Non-Default UVS Table. May be 0. |
The Variation Selector Records are sorted in increasing order of varSelector. No two records may have the same varSelector.
A Variation Selector Record and the data its offsets point to specify those UVSes supported by the font for which the variation selector is the varSelector value of the record. The base characters of the UVSes are stored in the tables pointed to by the offsets. The UVSes are partitioned by whether they are default or non-default UVSes.
Glyph IDs to be used for non-default UVSes are specified in the Non-Default UVS table.
Default UVS table
A Default UVS Table is simply a range-compressed list of Unicode scalar values, representing the base characters of the default UVSes which use the varSelector of the associated Variation Selector Record.
DefaultUVS Table:
Type | Name | Description |
---|---|---|
uint32 | numUnicodeValueRanges | Number of Unicode character ranges. |
UnicodeRange | ranges[numUnicodeValueRanges] | Array of UnicodeRange records. |
Each Unicode range record specifies a contiguous range of Unicode values.
UnicodeRange Record:
Type | Name | Description |
---|---|---|
uint24 | startUnicodeValue | First value in this range |
uint8 | additionalCount | Number of additional values in this range |
For example, the range U+4E4D – U+4E4F (3 values) will set startUnicodeValue to 0x004E4D and additionalCount to 2. A singleton range will set additionalCount to 0.
The sum (startUnicodeValue + additionalCount) must not exceed 0xFFFFFF.
The Unicode Value Ranges are sorted in increasing order of startUnicodeValue. The ranges must not overlap; i.e., (startUnicodeValue + additionalCount) must be less than the startUnicodeValue of the following range (if any).
Non-Default UVS table
A Non-Default UVS Table is a list of pairs of Unicode scalar values and glyph IDs. The Unicode values represent the base characters of all non-default UVSes which use the varSelector of the associated Variation Selector Record, and the glyph IDs specify the glyph IDs to use for the UVSes.
NonDefaultUVS Table:
Type | Name | Description |
---|---|---|
uint32 | numUVSMappings | Number of UVS Mappings that follow |
UVSMapping | uvsMappings[numUVSMappings] | Array of UVSMapping records. |
Each UVSMapping record provides a glyph ID mapping for one base Unicode character, when that base character is used in a variation sequence with the current variation selector.
UVSMapping Record:
Type | Name | Description |
---|---|---|
uint24 | unicodeValue | Base Unicode value of the UVS |
uint16 | glyphID | Glyph ID of the UVS |
The UVS Mappings are sorted in increasing order of unicodeValue. No two mappings in this table may have the same ‘unicodeValue’ values.
Example
Here is an example of how a format 14 'cmap' subtable may be used in a font that is aware of JIS-2004 variant glyphs. The CIDs (character IDs) in this example refer to those in the Adobe Character Collection “Adobe-Japan1”, and may be assumed to be identical to the glyph IDs in the font in our example.
JIS-2004 changed the default glyph variants for some of its code points. For example:
JIS-90: U+82A6 ⇒ CID 1142
JIS-2004: U+82A6 ⇒ CID 7961
Both of these glyph variants are supported through the use of UVSes, as the following examples from Unicode’s UVS registry show:
U+82A6 U+E0100 ⇒ CID 1142
U+82A6 U+E0101 ⇒ CID 7961
If the font wants to support the JIS-2004 variants by default, it will:
- encode glyph ID 7961 at U+82A6 in the Unicode 'cmap' subtable,
- specify <U+82A6, U+E0101> in the UVS 'cmap' subtable’s Default UVS Table (varSelector will be 0x0E0101 and defaultUVSOffset will point to data containing a 0x0082A6 Unicode value)
- specify <U+82A6, U+E0100> ⇒ glyph ID 1142 in the UVS 'cmap' subtable’s Non-Default UVS Table (varSelector will be 0x0E0100 and nonDefaultBaseUVOffset will point to data containing a unicodeValue 0x0082A6 and glyphID 1142).
If, however, the font wants to support the JIS-90 variants by default, it will:
- encode glyph ID 1142 at U+82A6 in the Unicode 'cmap' subtable,
- specify <U+82A6, U+E0100> in the UVS 'cmap' subtable’s Default UVS Table
- specify <U+82A6, U+E0101> ⇒ glyph ID 7961 in the UVS 'cmap' subtable’s Non-Default UVS Table