CFF2 — Compact Font Format (CFF) Version 2 (OpenType 1.8.3)

1. Introduction

This document describes the CFF2 format. Like the CFF 1.0 format, CFF2 allows efficient storage of glyph outlines and metadata. The CFF2 format differs from CFF version 1.0 in that it cannot be used as a stand-alone font program: it is intended for use only in the context of an OpenType font as an 'sfnt' table with the tag CFF2, and depends on data in other OpenType tables. All the data from the 1.0 format that is duplicated by data in other tables, or which is not used in the context of an OpenType font, is removed.

Another important difference is that the CFF2 format adds new operators which allows CFF2 to represent the data for a variable font: a font that includes representations for several different variants of each glyph, which can be blended to produce an intermediate instance. See the chapter OpenType Font Variations Overview for a general overview of variable fonts and for a complete list of the tables required to support a variable font.

Finally, the CFF2 format requires the use of CFF2 CharStrings rather than Type 2 CharStrings. This CharString format, like the CFF2 format itself, has removed operators to reduce file size, and added new operators to support variable fonts. See section 8, CharStrings INDEX, for additional information on CFF2 CharStrings.

For a complete description of the differences between CFF format version 1.0 and CFF2, see Appendix D, Changes From CFF 1.0.

2. Data Layout

Conceptually, the binary data is organized as a number of separate data structures. The overall layout within the binary data is shown in Table 1. The first three structures occupy fixed locations. The remainder are reached via offsets, and their ordering can be changed.

Table 1 CFF2 Data Layout

Entry Comments
Header Fixed location
Top DICT Fixed location
Global Subr INDEX Fixed location
VariationStore
FDSelect Present only if there is more than one Font DICT in the Font DICT INDEX.
Font DICT INDEX
Array of Font DICT Included in Font DICT INDEX.
Private DICT One per Font DICT.

Appendix A, Example CFF2 Font, shows an annotated example of a CFF2 table.

3. Data Types

This section describes data representation and types used by the CFF2 format.

All multi-byte numeric data and offset fields are stored in big-endian byte order (high byte low offset) and do not honor any alignment restrictions. This leads to a format that is free from padding bytes.

Data objects are often specified by byte offsets that are relative to some reference point within the CFF2 data. These offsets are 1 to 4 bytes in length. The reference position for the offset is indicated in each case.

The data types used in the CFF2 table are shown in Table 2.

Table 2 CFF2 Data Types

Name Range Description
uint8 0 to 255 8-bit unsigned number
uint16 0 to 65535 16-bit unsigned number
uint32 0 to 4294967295 32-bit unsigned number
Offset varies 1, 2, 3, or 4 byte offsets (specified by OffSize field in an Index table)
OffSize 1 to 4 1-byte unsigned number specifies the size of an Offset field or fields

This document describes data structures by listing field types, names, and descriptions. Data structures may be given a type name and subsequently described. Arrays of objects are indicated by the usual square bracket convention enclosing the array length.

The majority of CFF2 data is contained by either of two data structures called DICT and INDEX which are described in subsequent sections.

4. DICT Data

Font dictionary data comprising key-value pairs is represented in a compact tokenized format that is similar to that used to represent CharStrings. Dictionary keys are encoded as 1- or 2-byte operators and dictionary values are encoded as variable-size numeric operands. An operator is preceded by the operand(s) that specify its value. A DICT is simply a sequence of operand(s)/operator bytes concatenated together. There are three structures that use the DICT Data format: Top DICT, Font DICT and Private DICT. A list of DICT operators for each of these may be found in section 7, Top DICT, section 10, Font DICT, and section 11, Private DICT. A summary of all DICT operators is provided in Appendix C CFF2 DICT Encoding.

A number of integer operand types of varying sizes are defined and are encoded as shown in Table 3 (first byte of operand is b0, second is b1, and so on).

Table 3 Operand Encoding

Size b0 range Value range Value calculation
1 32 to 246 -107 to +107 b0 - 139
2 247 to 250 +108 to +1131 (b0 - 247) * 256 + b1 + 108
2 251 to 254 -1131 to -108 -(b0 - 251) * 256 - b1 - 108
3 28 -32768 to +32767 b1 << 8 | b2
5 29 -(2^31) to +(2^31 - 1) b1 << 24 | b2 << 16 | b3 << 8 | b4

Note: The 1- , 2-, and 3- byte integer formats are identical to those used by CFF2 CharStrings.

Examples of the integer formats are shown in Table 4.

Table 4 Integer Format Examples

Value Encoding
0 8b
100 ef
-100 27
1000 fa 7c
10000 1c 27 10
-10000 1c d8 f0
100000 1d 00 01 86 a0
-100000 1d ff fe 79 60

A real number operand is provided in addition to integer operands. This operand begins with a byte value of 30 followed by a variable-length sequence of bytes. Each byte is composed of two 4-bit nibbles as defined in Table 5. The first nibble of a pair is stored in the most significant 4 bits of a byte and the second nibble of a pair is stored in the least significant 4 bits of a byte.

Table 5 Nibble Definitions

Nibble value Represents
0 to 9 0 to 9
a . (decimal point)
b E
c E-
d <reserved>
e - (minus)
f end of number

A real number is terminated by one (or two) 0xf nibbles so that it is always padded to a full byte. Thus, the value -2.25 is encoded by the byte sequence (1e e2 a2 5f) and the value 0.140541E-3 by the sequence (1e 0a 14 05 41 c3 ff).

Operators and operands may be distinguished by inspection of their first byte. Values 28, 29, 30, and 32 to 254 specify operands (numbers). All other values either specify an operator or are reserved. The maximum number of operands which may precede an operator is set by the current stack limit.

An operator may have one or more operands of the types shown in Table 6.

Table 6 Operand Types

Type Description
number Integer or real number
array One or more numbers
delta A number or a delta-encoded array of numbers (see below)

The length of array or delta types is determined by counting the operands preceding the operator. The second and subsequent numbers in a delta are encoded as the difference between successive values. For example, an array a0, a1, a2, ..., an would be encoded as: a0 (a1 - a0) (a2 - a1) ..., (an - an-1).

Two-byte operators have an initial escape byte of 12.

Further compaction of dictionary data is achieved by establishing default values for various DICT keys. For those keys that have a default value, the absence of the corresponding operator in a DICT implies a key should take its default value.

5. INDEX Data

An INDEX is an array of variable-sized objects. It comprises a header, an offset array, and object data. The offset array specifies offsets within the object data. An object is retrieved by indexing the offset array and fetching the object at the specified offset. The object’s length can be determined by subtracting its offset from the next offset in the offset array. An additional offset is added at the end of the offset array so the length of the last object may be determined. The INDEX format is shown in Table 7.

Table 7 INDEX Format

Type Name Description
uint32 count Number of objects stored in INDEX
OffSize offSize Offset array element size
Offset offset [count+1] Offset array — offsets are from byte preceding object data.
uint8 data [<varies>] Object data

Offsets in the offset array are relative to the byte that precedes the object data. Therefore the first element of the offset array is always 1. (This ensures that every object has a corresponding offset which is always nonzero and permits the efficient implementation of dynamic object loading.)

An empty INDEX is represented by a count field with a 0 value and no additional fields. Thus, the total size of an empty INDEX is 4 bytes.

Note: An INDEX may be skipped by jumping to the offset specified by the last element of the offset array.

6. Header

The binary data begins with a header having the format shown in Table 8.

Table 8 Header Format

Type Name Description
uint8 majorVersion Format major version. Set to 2.
uint8 minorVersion Format minor version. Set to zero.
uint8 headerSize Header size (bytes).
uint16 topDictLength Length of Top DICT structure in bytes.

The headerSize field must be used when locating the start of the Top DICT data. It is provided so that future versions of the format may introduce additional data between the topDictLength field and the Top DICT data in a manner that is compatible with older implementations.

7. Top DICT Data

This is the top-level DICT of the CFF2 table.

The names of the Top DICT operators and default values (where applicable) are shown in Table 9.

Table 9 Top DICT Operator Entries

Name Value Operand(s) Default Notes
FontMatrix 12 7 array 0.001 0 0 0.001 0 0
CharStrings 17 number CharStrings INDEX offset, from start of the CFF2 table.
FDArray 12 36 number Font DICT (FD) INDEX offset, from start of the CFF2 table.
FDSelect 12 37 number FDSelect structure offset, from start of the CFF2 table.
vstore 24 number VariationStore structure offset, from start of the CFF2 table.

The Top DICT FontMatrix operator is required if the unitsPerEm value in the 'head' table is other than 1000. If unitsPerEm is 1000, then the FontMatrix operator may be omitted. When included, the FontMatrix operand array must be 1/unitsPerEm 0 0 1/unitsPerEm 0 0. The default values shown above assume that unitsPerEm is 1000.

The FDSelect operator and the structure it points to are required if the Font DICT INDEX contains more than one Font DICT, else it must be omitted.

The vstore operator and the data it points to are required if variation data is present, and must be omitted if there is no varation data.

Operators in Top DICT, Font DICTs, Private DICTs and CharStrings may be preceded by up to a maximum of 513 operands.

8. CharStrings INDEX

The CharStrings INDEX is an INDEX structure that contains all of the CFF2 glyphs in the font. Each CharString provides the definition of a glyph and is accessed by glyph index (“GID”). The first CharString (GID 0) must be the .notdef glyph. The number of glyphs defined in the CFF2 table may be determined from the CharString INDEX count field. The value of this field must match the value of the numGlyphs field in the 'maxp' table.

The format of the CharString data for CFF2 data, and therefore the method of interpretation, is the CFF2 CharString format. This is based on the Type 2 CharString format, and differs only in that some operators are added, and many are removed. See the chapter The CFF2 CharString Format for details. The major changes are as follows:

  • CFF2 CharStrings do not contain a value for advance width.
  • For CFF2 tables, the fill rule for CharStrings must always be the nonzero winding number rule, rather than the even-odd rule. This is required in order to support variable font data, in which it is not practical to enforce removal of overlaps between paths.
  • The stack depth is increased from 48 to 513.
  • The CharString operator set is extended in CFF2 to include the blend (16) and vsindex (15) operators. These operators work as described below, in relation to equivalent CFF2 Private DICT operators, in section 12, Extensions for OpenType Font Variations. Note, however, that the operator codes for these operators when used in CharStrings are different from the operator codes for the equivalent CFF2 Private DICT operators.
  • The Type 2 operators endchar and return are removed.
  • The Type 2 logic, storage, and math operators are removed.

The CFF2 format does not contain glyph names or CID values for glyph tags. Glyph tags that provide some semantic content can be useful for debugging, however, and can also be used as a last resort for deriving encoding information. Glyph tags for CFF2 tables can be represented by PostScript glyph names in a version 2.0 'post' table. Glyph names add to the size of a font and are optional. Alternatively, the font can use a version 3.0 'post' table, which omits glyph names.

9. Local and Global Subr INDEXes

A subroutine (“subr”) is typically a sequence of CharString bytes representing a sub-program that is used in more than one place in a font’s CharString data. A subr may be stored once but referenced many times from within one or more CharStrings by the use of a call-subroutine operator that takes as an operand the number of the subr to be called.

Some subrs are local; that is, they are contained within a Private DICT and accessible by the set of CharStrings associated with the Private Dict. Local subrs are contained within an INDEX structure; the offset of the INDEX within the Private DICT is specified using the Subrs operator. A CharString references a local subr in its Private DICT by means of the callsubr operator.

Subrs can also be global, accessible to any CharString within the font. Global subrs are stored in the Global Subrs INDEX, which follows the Top DICT data. A font might not have any global subrs, in which case the Global Subrs INDEX is empty. A CharString references a global subr by means of the callgsubr operator.

Subr numbers are skewed by a number called the “subr number bias” that is calculated from the count of the subroutines in either the local or global subr INDEXes. The bias is calculated as follows:

uint16 bias;
uint16 nSubrs = subrINDEX.count;
if (nSubrs < 1240)
    bias = 107;
else if (nSubrs < 33900)
    bias = 1131;
else
    bias = 32768;

For correct subr selection, the calculated bias must be added to the subr number operand before accessing the appropriate subr INDEX. This technique allows subr numbers to be specified using negative as well as positive numbers, thereby fully utilizing the available number ranges and thus saving space.

10. Font DICT INDEX, Font DICTs and FDSelect.

The Font DICT INDEX contains one or more FontDICT structures. Unlike CID-keyed Type 1 fonts, the Font DICT INDEX may contain more than 256 Font DICTs.

A Font DICT is used for hinting, variation or subroutine (subr) data used by CharStrings. A font can have one Font DICT, which would apply to all CharStrings, or it can have multiple Font DICTs, each applicable to some set of CharStrings. The actual hinting or other data is contained in a Private DICT. Each Font DICT structure provides a reference to a Private DICT.

Table 10 Font DICT Operator Entries

Name Value Operand(s) Default Notes
Private 18 number number Private DICT size and offset, from start of the CFF2 table.

Earlier versions of this specification documented a Font DICT FontMatrix operator using the two-byte operator code 12 7. Use of a Font DICT FontMatrix operator is not required in CFF2 fonts, and is now deprecated.

If there are multiple Font DICTs, an FDSelect table is used to provide information about which Font DICT (“FD”) is used for which glyphs. An FDSelect is used only if there are multiple Font DICTS.

The location of the FDSelect table is given as the operand of the FDSelect operator in the Top DICT. An FDSelect table associates a Font DICT with a glyph by specifying an FD index for that glyph. The FD index is used to access one of the Font DICTs stored in the Font DICT INDEX. Three formats for the FDSelect table are currently defined, as shown in the following tables.

Table 11 FDSelect Format 0

Type Name Description
uint8 format Set to 0
uint8 fds [nGlyphs] FD selector array

Each element of the fds array represents the FD index of a Font DICT in the FDArray. This format should be used when the FD indices are in a fairly random order. The number of glyphs (nGlyphs) is the value of the count field in the CharStrings INDEX.

Table 12 FDSelect Format 3

Type Name Description
uint8 format Set to 3
uint16 nRanges Number of ranges
Range3 range3 [nRanges] Array of Range3 records (see below)
uint16 sentinel Sentinel GID

The format of a Range3 record is as follows:

Table 13 Range3 Record Format

Type Name Description
uint16 first First glyph index in range
uint8 fd FD index for all glyphs in range

Each Range3 describes a group of sequential GIDs that have the same FD index. Each range includes GIDs from the first GID in the range record up to, but not including, the first GID of the next range record. Records in the Range3 array must be in increasing order of first GIDs. The first range must have a first GID of 0. A sentinel GID follows the last range element and serves to delimit the last range in the array. The sentinel GID is set equal to the number of glyphs in the font. That is, its value is 1 greater than the last GID in the font. This format is particularly suited to FD indexes that are well ordered (the usual case).

Table 14 FDSelect Format 4

Type Name Description
uint8 format Set to 4
uint32 nRanges Number of ranges
Range4 range4 [nRanges] Array of Range4 records (see below)
uint32 sentinel Sentinel GID

Format 4 differs from Format 3 only in that it accommodates more than 65535 glyphs by using a uint32 type for the nRanges and sentinel fields, and a Range4 record array.

The format of a Range4 record is as follows:

Table 15 Range4 Record Format

Type Name Description
uint32 first First glyph index in range
uint16 fd FD index for all glyphs in range

The Range4 format differs from the Range3 only in that it accommodates more than 65535 glyphs by using a uint32 for the first GID field and a uint16 field for the FD index.

Note: While FDSelect format 4 allows for more than 65535 glyphs, other parts of the OpenType format, such as the numGlyphs field of the 'maxp' table, are still constrained to 65535 glyphs.

11. Private DICT Data

The names of the Private DICT operators shown in Table 16 are, where possible, the same as the corresponding Type 1 dict keys. Operators that have no corresponding Type 1 dict key are indicated with a note in Table 16.

Table 16 Private DICT Operators

Name Value Operand(s) Default Notes
BlueValues 6 delta
OtherBlues 7 delta
FamilyBlues 8 delta
FamilyOtherBlues 9 delta
BlueScale 12 9 number 0.039625
BlueShift 12 10 number 7
BlueFuzz 12 11 number 1
StdHW 10 number
StdVW 11 number
StemSnapH 12 12 delta
StemSnapV 12 13 delta
LanguageGroup 12 17 number 0
ExpansionFactor 12 18 number 0.06
vsindex 22 number 0 itemVariationData index in the VariationStore structure table.
blend 23 delta, numberOfBlends Leaves numberOfBlends values on the operand stack.
Subrs 19 number Offset to local subrs INDEX, from start of the Private DICT.

The local subrs offset is relative to the beginning of the Private DICT data.

The OtherBlues and FamilyOtherBlues operators must occur after the BlueValues and FamilyBlues operators, respectively.

A Private DICT is required, but may be specified as having a size of 0 if there are no non-default values to be stored.

12. Extensions for OpenType Font Variations

In order to support glyph variation data in CFF2 tables, three new operators are added in CFF2 format: vsindex, blend, and vstore.

A variable font holds data representing the equivalent of several distinct design variations, and uses algorithms for interpolation — or blending — between these designs to derive a continuous range of design instances. This allows an entire family of fonts to be represented by a single variable font. For example, a variable font may contain data equivalent to Light and Heavy designs from a family, which can then be interpolated to derive instances for any weight in a continuous range between Light and Heavy.

See the chapter, OpenType Font Variations Overview for general background on OpenType Font Variations, details on the tables used to support a variable font, terminology, and a specification of the interpolation algorithm used to blend values to derive specific design instances.

Outline data for a variable font in the CFF2 format are built much like a non-variable CFF2 table would be built, with exactly the same structure and operators as would be used for the default design representation. However, wherever a value occurs in the default design, the single value for the one design is supplemented with a set of delta values, followed by the blend operator. (For efficiency, a single blend operator may follow a series of such delta sets, rather than after each individual set.) Unlike other DICT operators, blend does not clear the stack when it is processed. The result of the blend operator remains on the stack to be processed by the following operator.

Within a variable font, different glyphs can use different sets of regions and associated delta values for the blending operation. When processing a given glyph, the interpreter must determine which set to use. These sets are stored in the CFF2 table in an ItemVariationStore structure. The ItemVariationStore contains one or more ItemVariationData subtables, each of which contains a list of Variation Regions. The first ItemVariationData subtable (index 0) is used by default when no other subtable has been specified. When an ItemVariationData subtable other than the default is needed for a set of delta values, the vsindex operator is used. When this operator is used in a Private DICT to set a non-default itemVariationData index, this then becomes the default Item Variation Data index for not only the Private DICT, but also for all CharStrings that reference that Private DICT. When the vsindex operator is used in a CharString, it supersedes any vsindex from the private DICT. All private DICTs and CharStrings in a CFF2 table share the same ItemVariationStore.

Syntax for Font Variations support operators.

vsindex
|- ivs vsindex (22) |-

Selects the ItemVariationData subtable to be used for blending; the ivs argument is the ItemVariationData index. When used, vsindex must precede the blend operator.

Note that the operator code, 22, is different from the equivalent CharStrings operator. This operator may be used only in a Private DICT.


blend
num(0)…num(n-1), delta(0,0)…delta(k-1,0), 
delta(0,1)…delta(k-1,1) … delta(0,n-1)…delta(k-1,n-1)
n blend (23) val(0)…val(n-1)

For k regions, produces n interpolated result value(s) from n*(k + 1) operands. For more information and examples, see the description of the equivalent CharString operator in section 4.5, Variation Data Operators, in the CFF2 CharString Format chapter.

Note that the operator code, 23, is different from the equivalent CharStrings operator. This operator may only be used in a Private DICT.


vstore
|- offset vstore (24) |-

Provides the offset to the VariationStore data in the CFF2 table. This operator may only be used in the Top DICT.


VariationStore Data Contents

The VariationStore data is comprised of two parts: a uint16 field that specifies a length, followed by an Item Variation Store structure of the specified length. The Item Variation Store format is specified in the chapter OpenType Font Variations Common Table Formats. A brief description of the format as used within the CFF2 table follows.

To support variation of glyphs or other font data, the information used is comprised of default values for the particular data item, a set of delta adjustment values used to modify the default value, and a set of regions within the font’s variation space over which the different delta values apply. The Item Variation Store format is designed to accommodate both the set of regions and the delta values. Within the CFF2 table, the Item Variation Store is used to represent the different regions, but the delta values are interleaved within the CharStrings where they are used.

An Item Variation Store contains two important lists. The first list is data that describes the region of influence in variation space for each design that is used in the variable font. Each of these is called a Variation Region. The entire list of Variation Regions is called a Variation Region List.

The second list is an array of ItemVariationData structures that each specify a set of Variation Regions, as a list of indices into the Variation Region List. This allows different glyphs to have delta values that apply to different sets of regions. There is often only one itemVariationData structure, and hence only one set of regions that is used by all glyphs. If more than one set of regions are needed, then an itemVariationData structure is added to define each set. The vsindex operator may be used in a Private DICT to set the itemVariationData index for all glyphs which reference the Private DICT, or it may be used in specific CFF2 CharStrings when a CharString needs to use a different ItemVariationData structure than is specified in the Private DICT.

An example of a Variation Store structure in a CFF2 table can be seen in Appendix A. Example CFF2 Font.

Appendix A Example CFF2 Font

This appendix illustrates the CFF2 format with an example CFF2 table.

Binary dump (226 bytes):

0000: 02 00 05 00 07 CF 0C 24 C3 11 9B 18 00 00 00 00
0010: 00 26 00 01 00 00 00 0C 00 01 00 00 00 1C 00 01
0020: 00 02 C0 00 E0 00 00 00 C0 00 C0 00 E0 00 00 00
0030: 00 00 00 02 00 00 00 01 00 00 00 02 01 01 03 05
0040: 20 0A 20 0A 00 00 00 01 01 01 05 F7 06 DA 12 77
0050: 9F F8 6C 9D AE 9A F4 9A 95 9F B3 9F 8B 8B 8B 8B
0060: 85 9A 8B 8B 97 73 8B 8B 8C 80 8B 8B 8B 8D 8B 8B
0070: 8C 8A 8B 8B 97 17 06 FB 8E 95 86 9D 8B 8B 8D 17
0080: 07 77 9F F8 6D 9D AD 9A F3 9A 95 9F B3 9F 08 FB
0090: 8D 95 09 1E A0 37 5F 0C 09 8B 0C 0B C2 6E 9E 8C
00A0: 17 0A DB 57 F7 02 8C 17 0B B3 9A 77 9F 82 8A 8D
00B0: 17 0C 0C DB 95 57 F7 02 85 8B 8D 17 0C 0D F7 06
00C0: 13 00 00 00 01 01 01 1B BD BD EF 8C 10 8B 15 F8
00D0: 88 27 FB 5C 8C 10 06 F8 88 07 FC 88 EF F7 5C 8C
00E0: 10 06

Analysis:

Hex data Source Comments
Header CFF2 offsets: 0000 to 0004
02 majorVersion = 2
00 minorVersion = 0
05 headerSize = 5
00 07 topDictSize = 7
Top DICT Data CFF2 offsets: 0005 to 000B
CF 0C 24 |- offset FDArray |- = 68 FDArray
The bytes 0C 24 represent the FDArray operator. The operand byte is hex CF = decimal 207, which is decoded using the rule for byte values from 32 to 246 (see Table 3, Operand Encoding): b0 - 139.
This gives the offset of the Font DICT INDEX: decimal 68 = hex 44.
C3 11 |- offset CharStrings |- = 56 CharStrings
The byte 11 represents the CharStrings operator. The operand byte is hex C3, which is the encoded representation of the value 56.
This gives the offset of the CharStrings INDEX: decimal 56 = hex 38.
9B 18 |- offset vstore |- = 16 vstore
The byte 18 represents the vstore operator. The operand byte is hex 9B, which is the encoded representation of the value 16.
This gives the offset of the VariationStore Data: decimal 16 = hex 10.
Global Subr INDEX CFF2 offsets: 000C to 000F
00 00 00 00 count = empty INDEX; no additional fields represented.
VariationStore Data CFF2 offsets: 0010 to 0037
00 26 length = 38 — length in bytes of the Item Variation Store structure that follows.
ItemVariationStore CFF2 offsets: 0012 to 0037
00 01 format = 1
00 00 00 0C variationRegionListOffset = 12 — offset in bytes from the start of the ItemVariationStore.
00 01 itemVariationDataCount = 1 — number of ItemVariationData subtables.
00 00 00 1C itemVariationDataOffsets[0] = 28 — offset in bytes from start of the ItemVariationStore to ItemVariationData subtable 0.
VariationRegionList CFF2 offsets: 001E to 002D
00 01 axisCount = 1
00 02 regionCount = 2
variationRegions[0] CFF2 offsets: 0022 to 0027
regionAxes[0] CFF2 offsets: 0022 to 0027
C0 00 startCoord = -1.0 (F2DOT14 value)
E0 00 peakCoord = -0.5 (F2DOT14 value)
00 00 endCoord = 0.0 (F2DOT14 value)
variationRegions[1] CFF2 offsets: 0028 to 002D
regionAxes[0] CFF2 offsets: 0028 to 002D
C0 00 startCoord = -1.0 (F2DOT14 value)
C0 00 peakCoord = -1.0 (F2DOT14 value)
E0 00 endCoord = -0.5 (F2DOT14 value)
ItemVariationData subtable 0 CFF2 offsets: 002E to 0037
00 00 itemCount = 0
00 00 shortDeltaCount = 0
00 02 regionIndexCount = 2
00 00 00 01 regionIndexes[] = {0, 1}
CharStrings INDEX CFF2 offsets: 0038 to 0043
00 00 00 02 count = 2
01 offSize = 1
01 03 05 offset[] = {1, 3, 5} (number of elements is count + 1)
CharString 0 CFF2 offsets: 0040 to 0041
20 0A |- subr# callsubr |- = -107 callsubr
The byte 0A represents the callsubr operator. The operand byte is 20, which is the encoded representation of the value -107.
CharString 1 CFF2 offsets: 0042 to 0043
20 0A |- subr# callsubr |- = -107 callsubr
The byte 0A represents the callsubr operator. The operand byte is 20, which is the encoded representation of the value -107.
Font DICT INDEX CFF2 offsets: 0044 to 004E
00 00 00 01 count = 1
01 offSize = 1
01 05 offset[] = {1, 5} (number of elements is count + 1)
Font DICT 0 CFF2 offsets: 004B to 004E
F7 06 DA 12 |- size offset Private |- = 114 79 Private
The byte 12 represents the Private operator. The operand bytes F7 06 are the encoded representation of the value 114. The operand byte DA is the encoded representation of the value 79.
This gives the size and offset of a Private DICT: size is 114 bytes, offset (from start of CFF2 table) is 79 bytes (hex 4F).
Private DICT CFF2 offset: 004F to 00C0
77 9F F8 6C 9D AE 9A F4 9A 95 9F B3 9F 8B 8B 8B 8B 85 9A 8B 8B 97 73 8B 8B 8C 80 8B 8B 8B 8D 8B 8B 8C 8A 8B 8B 97 17 06 |- num* blend BlueValues |- = -20 20 472 18 35 15 105 15 10 20 40 20 0 0 0 0 -6 15 0 0 12 -24 0 0 1 -11 0 0 0 2 0 0 1 -1 0 0 12 blend BlueValues
The byte 06 represents the BlueValues operator. The byte 17 represents the blend operator. The operand bytes 77.. 97 are the encoded representation of the values -20... 12.
FB 8E 95 86 9D 8B 8B 8D 17 07 |- num* blend OtherBlues |- = -250 10 -5 18 0 0 2 blend OtherBlues
The byte 07 represents the OtherBlues operator. The byte 17 represents the blend operator. The operand bytes FB.. 8D are the encoded representation of the values -250... 2.
77 9F F8 6D 9D AD 9A F3 9A 95 9F B3 9F 08 |- num* FamilyBlues |- = -20 20 473 18 34 15 104 15 10 20 40 20 FamilyBlues
The byte 08 represents the operator FamilyBlues. The operand bytes 77... 9F are the encoded representation of the values -20... 20.
FB 8D 95 09 |- num* FamilyOtherBlues |- = -249 10 FamilyOtherBlues
The byte 09 represents the FamilyOtherBlues operator. The operand bytes FB 8D are the encoded representation of the value -249. The operand byte 95 is the encoded representation of the value 10.
1E A0 37 5F 0C 09 |- num BlueScale |- = 0.0375 BlueScale
The bytes 0C 09 represent the BlueScale operator. The operand bytes 1E A0 37 5F are the encoded representation of the value 0.0375.
8B 0C 0B |- num BlueFuzz |- = 0 BlueFuzz.
The bytes 0C 0B represents the BlueFuzz operator. The operand byte 8B is the encoded representation of the value 0.
C2 6E 9E 8C 17 0A |- num* blend StdHW |- = 55 -29 19 1 blend StdHW
The byte 0A represents the StdHW operator. The byte 17 represents the blend operator. The operand bytes C2 6E 9E 8C are the encoded representation of the values 55 -29 19 1.
DB 57 F7 02 8C 17 0B |- num* blend StdVW |- = 80 -52 110 1 blend StdVW
The byte 0B represents the StdVW operator. The byte 17 represents the blend operator. The operand bytes DB 57 F7 02 8C are the encoded representation of the values 80 -52 110 1.
B3 9A 77 9F 82 8A 8D 17 0C 0C |- num* blend StemSnapH |- = 40 15 -20 20 -9 -1 2 blend StemSnapH
The bytes 0C 0C represent the StemSnapH operator. The byte 17 represents the blend operator. The operand bytes B3 9A 77 9F 82 8A 8D are the encoded representation of the values 40 15 -20 20 -9 -1 2.
DB 95 57 F7 02 85 8B 8D 17 0C 0D |- num* blend StemSnapV |- = 80 10 -52 110 -6 0 2 blend StemSnapV
The bytes 0C 0D represent the StemSnapV operator. The byte 17 represents the blend operator. The operand bytes DB 95 57 F7 02 85 8B 8D are the encoded representation of the values 80 10 -52 110 -6 0 2.
F7 06 13 |- num Subrs |- = 114 Subrs
The byte 13 represents the Subrs operator. The operand bytes F7 06 are the encoded representation of the value 114.
This gives the offset (from the start of the Private DICT) to the local Subr INDEX: 114 bytes (hex 72).
Local Subr INDEX CFF2 offsets: 00C1 to 00E1
00 00 00 01 count = 1
01 offSize = 1
01 1B offset[] = {1, 27} (number of elements is count + 1)
subr 0 CFF2 offsets: 00C8 to 00E1
BD BD EF 8C 10 8B 15 |- num* blend num rmoveto |- = 50 50 100 1 blend 0 rmoveto
The byte 15 represents the rmoveto CharString operator. The byte 10 represents the blend CharString operator. The operand bytes BD BD EF 8C are the encoded representation of the values 50 50 100 1. The operand byte 8B is the encoded representation of the value 0.
F8 88 27 FB 5C 8C 10 06 |- num* blend hlineto |- = 500 -100 -200 1 blend hlineto
The byte 06 represents the hlineto CharString operator. The byte 10 represents the blend CharString operator. The operand bytes F8 88 27 FB 5C 8C are the encoded representation of the values 500 -100 -200 1.
F8 88 07 |- num vlineto |- = 500 vlineto
The byte 07 represents the vlineto CharString operator. The operand bytes F8 88 are the encoded representation of the value 500.
FC 88 EF F7 5C 8C 10 06 |- num* blend hlineto |- = -500 100 200 1 blend hlineto The byte 06 represents the hlineto CharString operator. The byte 10 represents the blend CharString operator. The operand bytes FC 88 EF F7 5C 8C are the encoded representation of the values -500 100 200 1.

The following documents may be consulted for further information on Adobe font technology. All are available at Adobe Font Technical Notes.

  • The Compact Font Format Specification #5176
  • The Type 2 CharString format #5177
  • Generating PostScript Names for Fonts Using OpenType Font Variations #5902

Appendix C CFF2 DICT Encoding

Table 17 One-byte CFF2 DICT Operators

Dec Hex Operator Note
0 to 5 00 to 05 <reserved>
6 06 BlueValues
7 07 OtherBlues
8 08 FamilyBlues
9 09 FamilyOtherBlues
10 0a StdHW
11 0b StdVW
12 0c escape First byte of a 2-byte operator.
13 to 16 0d to 10 <reserved>
17 11 CharStrings
18 12 Private
19 13 Subrs
20 to 21 14 to 15 <reserved>
22 16 vsindex
23 17 blend
24 18 vstore
25 to 27 19 to 1b <reserved>
28 1c <numbers> First byte of a 3-byte sequence specifying a signed integer value (following two bytes are an int16).
29 1d <numbers> First byte of a 5-byte sequence specifying a signed integer value (following four bytes are an int32).
30 1e BCD
31 1f <reserved>
32 to 246 20 to f6 <numbers>
247 to 254 f7 to fe <numbers> First byte of a 2-byte sequence specifying a number.
255 ff <reserved>

Note: Operator code 25 (0x19) was previously assigned as a maxstack operator. This was never required in CFF2 fonts and is no longer supported.

Table 18 Two-byte CFF2 DICT Operators

Dec Hex Operator
12 0 to 12 6 0c 00 to 0c 06 <reserved>
12 7 0c 07 FontMatrix
12 8 0c 08 <reserved>
12 9 0c 09 BlueScale
12 10 0c 0a BlueShift
12 11 0c 0b BlueFuzz
12 12 0c 0c StemSnapH
12 13 0c 0d StemSnapV
12 14 to 12 16 0c 0e to 0c 10 <reserved>
12 17 0c 11 LanguageGroup
12 18 0c 12 ExpansionFactor
12 19 to 12 35 0c 13 to 0c 23 <reserved>
12 36 0c 24 FDArray
12 37 0c 25 FDSelect
12 38 to 12 255 0c 26 to 0c ff <reserved>

Note: The FontMatrix operator is valid for use in a Top DICT, but use in a Font DICT is deprecated.

Appendix D Changes From CFF 1.0

D1. Table Name and Version

A font with CFF2 font data must use the table tag 'CFF2', and the table major version must be set to 2.

D2. DICT Layout

The following CFF 1.0 tables are removed from the CFF2 table:

  • Name INDEX. CFF2 tables do not contain PostScript names. Also, FontSets are not supported in the CFF2 format. When making a CFF 1.0 instance snapshot from a CFF2 table, the PostScript font name can be copied from the name ID 6 value in the 'name' table. For variable fonts, it must be derived via the heuristics specified for variable fonts and the information in the 'fvar' and STAT tables. See Adobe Technical Note 5902, PostScript Name Generation for Fonts Using OpenType Font Variations #5902.
  • Top DICT INDEX. Since FontSets are not supported in the CFF2 format, there can be only one Top DICT.
  • String Table. Glyph names, if needed, can be provided in the 'post' table.
  • Encoding Table. CFF2 tables derive encoding information only from the 'cmap' table.
  • Charset Table. No longer used. Glyph identifiers are derived from the 'post' table.

The count field of an INDEX is uint32 instead of uint16.

The CFF2 header differs from the CFF 1.0 header in that the 4th field now represents the length of the Top DICT data structure. See section 6, Header, for details.

The Top DICT data starts immediately after the header data. The fixed data layout order in the CFF2 format is:

  • Header
  • Top DICT Data
  • Global Subr INDEX

The following INDEX tables are accessed by offsets specified in the TopDICT or Private DICT:

  • FDSelect
  • CharStrings INDEX
  • VariationStore Data
  • Font DICT INDEX
  • Private DICT
  • Local Subrs INDEX

D3. Top DICT Data

The Top DICT does not reference a Private DICT directly. Instead, it uses the FDArray operator to reference a Font DICT INDEX, which is always present. The Font DICT INDEX will always contain at least one Font DICT. If the Font DICT INDEX contains more than one Font DICT, then the Top DICT must also reference an FDSelect structure.

One new Top DICT operator has been added: vstore. See section 12, Extensions for OpenType Font Variations for details.

Top DICT operators that can be derived from other OpenType tables or that are no longer used have all been removed from the CFF2 format specification. Use of these operators in a CFF2 table is invalid; if encountered, they must be ignored.

The only CFF 1 Top DICT operators that are permitted in a CFF2 table are the following:

  • FontMatrix (12 7) array
  • CharStrings (17) offset
  • FDArray (12 36) offset
  • FDSelect (12 37) offset

The following table lists CFF 1 Top DICT operators that are not supported in CFF2, along with details on alternative mechanisms within a CFF2 font:

Table 19 CFF 1 Top DICT Operators Not Used in CFF2

Name Code (decimal) CFF2 equivalent
version 0 Equivalent to the fontRevision field in the 'head' table. A CFF 1 version operand can be derived from the fontRevision field, which is a 16.16 Fixed value, and formatting it as a decimal number with three decimal places of precision.
Notice 1 Equivalent to the concatenation of strings from the 'name' table: the Copyright string (name ID 0), a space, followed by the Trademark string (name ID 7).
FullName 2 Equivalent to the Full Name string (name ID 4) in the 'name' table.
FamilyName 3 Equivalent to the Typographic Family Name string (name ID 16) in the 'name' table, if present, else the Famly Name string (name ID 1).
Weight 4 Equivalent to the usWeightClass field in the OS/2 table.
FontBBox 5 Approximately equivalent to the combination of the xMin, xMax, yMin and yMax fields in the 'head' table. These will be only approximate, as they will be for the default value only, but are accurate enough if deriving values for CFF 1 interpreters. Some interpreters use these values to influence the hints for global coloring, and some use this to set flattening parameters.
Copyright 12 0 Equivalent to the Copyright string (name ID 0) in the 'name' table.
IsFixedPitch 12 1 Equivalent to the isFixedPitch field in the 'post' table.
ItalicAngle 12 2 Equivalent to the italicAngle field in the 'post' table.
UnderlinePosition 12 3 Equivalent to the underlinePosition field in the 'post' table.
UnderlineThickness 12 4 Equivalent to the underlineThickness field in the 'post' table.
PaintType 12 5 There is no equivalent in a CFF2 font. If deriving CFF 1-compatible data, use the CFF 1 default value of zero.
StrokeWidth 12 8 There is no equivalent in a CFF2 font. In a CFF 1 font, it is used only for PaintType 2. If deriving CFF 1-compatible data, PaintType 0 should be used.
SyntheticBase 12 20 There is no equivalent in a CFF2 font.
PostScript 12 21 There is no equivalent in a CFF2 font. CFF 1 allowed for embedded PostScript code, but this was only ever used in CFF 1 OpenType fonts to provide an FSType key in the Top DICT, to carry the font embedding permissions from the fsType field of the OS/2 table. If deriving CFF 1-compatible data, the value can be copied from the OS/2 table.
BaseFontName 12 22 There is no equivalent in a CFF2 font.
BaseFontBlend 12 23 There is no equivalent in a CFF2 font.
ROS 12 30 There is no equivalent in a CFF2 font. If generating CFF 1-compatible font instance from a CFF2 variable font that has more than one Font DICT in the Font DICT INDEX, the CFF 1 font must be written as a CID-keyed font. The ROS used should be Adobe-Identity-0. This maps all glyph IDs to a CID of the same value and carries no semantic content.
CIDFontVersion 12 31 There is no equivalent in a CFF2 font. If deriving CFF 1-compatible data, use the CFF 1 default value of zero.
CIFFontRevision 12 32 There is no equivalent in a CFF2 font. If deriving CFF 1-compatible data, use the CFF 1 default value of zero.
CIDFontType 12 33 There is no equivalent in a CFF2 font. If deriving CFF 1-compatible data, use the CFF 1 default value of zero.
CIDCount 12 34 Equivalent to the numGlyphs field in the 'maxp' table.
UIDBase 12 35 No longer required — see comments on UniqueID.
UniqueID 13 No longer required: This was originally used for caching fonts in printers. However, many third-party fonts with conflicting UnicodeID values have made it unreliable. More importantly, performance tests have shown that font caching no longer provides significant performance improvements when printing.
XUID 14 No longer required — see comments on UniqueID.
charset 15 If required, glyph names can be represented in a version 2.0 'post' table.
Encoding 16 Equivalent to the 'cmap' table.
Private 18 No longer required: In a CFF2 font, a Private DICT is always referenced from a Font DICT in the Font DICT INDEX.

D4. Private DICT Data

Two new operators are added that can be used in Private DICTs: vsindex and blend. See section 12, Extensions for OpenType Font Variations Extensions, for more information.

Private DICT operators that are no longer used or that have existing equivalents in other OpenType tables are not used in CFF2. Use of these operators in a CFF2 table is invalid; if encountered, they must be ignored. The following table lists CFF 1 Private DICT operators that are not supported in CFF2, along with details on alternative mechanisms within a CFF2 font:

Table 20 CFF 1 Private DICT Operators Not Used in CFF2

Name Code (decimal) CFF2 equivalent
defaultWidthX (20) Horizontal glyph metrics for CharStrings in a CFF2 table are obtained from the 'hmtx' and HVAR tables
nominalWidthX (21) Horizontal glyph metrics for CharStrings in a CFF2 table are obtained from the 'hmtx' and HVAR tables

Appendix E Changes Since Earlier Versions

The following changes and revisions have been made since the initial publication in OpenType 1.8.

  • Initial publication: OpenType 1.8 (September 2016). See Appendix D, Changes From CFF 1.0.
  • OpenType 1.8.1 (January 2017):
    • Data types Card8, Card16 and Card32 were replaced by uint8, uint16 and uint32 to match usage with the rest of the OpenType specification.
    • All references to FontSets were removed or reworded (FontSets are not supported in CFF2).
    • In Table 2, CFF2 Data Types, an entry was added for uint32.
    • In section 4, DICT Data, descriptions of operands and operators were revised, and table references were corrected.
    • In Table 6 of section 4, Operand Types, the boolean type was deleted (not used in CFF2).
    • In section 5, INDEX Data, the size of an empty INDEX was corrected to 4 bytes.
    • In section 7, Top DICT Data, the allowable range for maximum stack depth was added, as well as clarification that it affects stack depth for Private DICT and CFF2 CharString operators only.
    • Section 8, Glyph Organization, was merged into the following section.
    • In section 8 (previously section 9), CharStrings INDEX, text was reworded for better clarity, and a paragraph on glyph names and glyph IDs was added.
    • In section 9 (previously section 10), Local and Global Subr INDEXes, text was reworded for better clarity, and the detailed discussion of space savings from subr number bias was removed.
    • In section 10 (previously section 11), Font DICT INDEX, Font DICTs and FDSelect, text was reworded for better clarity; a note was added that a Font DICT INDEX can contain more than 256 Font DICTs; the description of sentinel glyph ID was restored; and the reference to FontName was removed (this CFF 1 operator is not used in CFF2).
    • In section 11 (previously section 12), Private DICT Data, the paragraph about advance widths was removed.
    • In section 12 (previously section 13), the blend operator example was replaced with a reference to the example provided in section 4.5 of “The CFF2 CharString Format” chapter.
    • In appendix A, Example CFF2 Font, an example of CFF2 font data was added.
    • In appendix C, CFF2 DICT Encoding, formatting changes were made.
    • In appendix D, Changes from CFF 1.0, text was reworded in various places.
    • In section D2 of appendix D, DICT Layout, a note about the type for the INDEX count field was added, and table references were corrected.
    • In section D3 of appendix D, Top DICT Data, CharStringType was removed from the list of supported operators, and details about the supported operators were added. Also, in the description of the CFF 1 ROS operator, “Adobe-Identity-1” was changed to “Adobe-Identity-0”. Other formatting changes were also made.
    • In section D4 of appendix D, ForceBold and initialRandomSeed were removed from the list of CFF 1 operators not used in CFF2, and other formatting changes were made.
    • Section D5 of appendix D, CharString Data, and also section D6, External Tables, were removed.
    • Many changes were made for consistency of terminology, such as consistent capitalization and spelling of “CharString”, “VariationStore”, “CFF2”, and use of “Font DICT INDEX” where that is more appropriate than “FDArray”.
  • OpenType 1.8.2 (July 2017):
    • Limited use of Top DICT FontMatrix operator (section 7), and deprecated use of Font DICT FontMatrix operator (section 10, Appendix C).
    • Corrected error in numeric range of reserved two-byte DICT operators (Appendix C).
    • Removed the maxstack operator. (Inadvertently introduced in the first CFF2 specification but was never required.)
    • Editorial revisions.