fvar — Font Variations Table (OpenType 1.8)
OpenType Font Variations allow a font designer to incorporate multiple faces within a font family into a single font resource. Variable fonts can provide great flexibility for content authors and designers while also allowing the font data to be represented in an efficient format.
A variable font allows for continuous variation along some given design axis, such as weight:
Conceptually, variable fonts define one or more axes over which design characteristics can vary. Weight is one possible axis of variation, but many different kinds of variation are possible. Variable fonts are not limited to a single axis of variation, but can combine two or more different axes of variation. For example, the following illustrates a combination of weight and width variation:
The set of axes supported by a font define a variation space for that font, supporting a potentially-vast number of design-variation instances at positions across that space.
The font variations table ('fvar') provides the global definition of variations supported within the font. It specifies the axes of variation that are used and the ranges of variation for each axis. It also allows the font designer to specify certain coordinate positions within the font’s variation space as named instances. Named instances have designer-provided names, effectively equivalent to sub-family names, that applications can use as a short list of “pre-chosen” design variants they can offer to users.
For a general introduction to OpenType Font Variations, see OpenType Font Variations Overview.
All variable fonts must include a font variations table, as well as other required or optional tables used in variable fonts. For more information on other tables used in variable fonts, see Variation Data Tables and Miscellaneous Requirements in the Overview chapter.
Note that some of the information in the font variations table also needs to be reflected in the style attributes ('STAT') table, which is also required in all variable fonts. In particular, each axis and each named instance specified in the font variations table must have matching axis records and axis value tables in the style attributes table.
Table Formats
The font variations table consists of a table header, followed by an array of variation axis records, followed by an array of named-instance records:
The format of the font variations table header is as follows.
Font variations header:
Type | Name | Description |
---|---|---|
USHORT | majorVersion | Major version number of the font variations table — set to 1. |
USHORT | minorVersion | Minor version number of the font variations table — set to 0. |
USHORT | offsetToAxesArray | Offset in bytes from the beginning of the table to the start of the variation axis array — set to 16 (0x0010) for this version. |
USHORT | countSizePairs | The number of count + size field pairs that follow — set to 2 (for axis count/size plus instance count/size). |
USHORT | axisCount | The number of variation axes in the font (the number of records in the axes array). |
USHORT | axisSize | The size in bytes of each VariationAxisRecord — set to 20 (0x0014) for this version. |
USHORT | instanceCount | The number of named instances defined in the font (the number of records in the instances array). |
USHORT | instanceSize | The size in bytes of each InstanceRecord — set to either axisCount * sizeof(Fixed) + 4, or to axisCount * sizeof(Fixed) + 6. |
The header is immediately followed by axes and instances arrays.
VariationAxisRecord | axes[axisCount] | The variation axis array. |
InstanceRecord | instances[instanceCount] | The named instance array. |
Note: The countSizePairs field is currently set to 2 to indicate that two count/size field pairs follow: the axis count/size pair, and the instance count/size pair. This number may increase in future versions of the 'fvar' table. The axes and instances arrays will always follow the last count/size field pair. To ensure forward compatibility, the offsetToAxesArray must be read to determine the start of the axes array.
Note: The axisSize and instanceSize fields indicate the size of the VariationAxisRecord and InstanceRecord structures. In this version of the 'fvar' table, the InstanceRecord structure has an optional field, and so two different size formulations are possible. The size of variation axis records or instance records may increase in future versions of the 'fvar' table. In minor-version revisions of the 'fvar' table, any increase in the size of records will be to extend the records with additional fields following the currently-defined fields.
The format of the variation axis record is as follows:
VariationAxisRecord
Type | Name | Description |
---|---|---|
Tag | axisTag | Tag identifying the design variation for the axis. |
Fixed | minValue | The minimum coordinate value for the axis. |
Fixed | defaultValue | The default coordinate value for the axis. |
Fixed | maxValue | The maximum coordinate value for the axis. |
USHORT | flags | Reserved for future use — set to 0. |
USHORT | axisNameID | The name ID for entries in the 'name' table that provide a display name for this axis. |
Each axis has a tag that identifies the design variation for the axis. For example, the tag 'wght' designates a weight variation. Tags are registered for commonly-used design axes, but foundry-defined tags may also be used. Registered tags define valid ranges of coordinate values for the axis across all fonts. The variation axis record defines minimum and maximum values supported by the font, which may be more limited that the valid ranges defined for a registered tag.
Note: Axis values given in the variation axis record use user scale coordinates that are specific to each axis tag. The user scale for each registered tag is described with the definition of each tag. In most other font tables that contain variations-related data, axis coordinate values are expressed using normalized coordinate scales. For more information regarding user scales and normalized scales, and a specification of the normalization process, see the Coordinate Scales and Normalization section in the OpenType Font Variations Overview chapter.
For more details on axis tags, see Variation Axis Tags below.
The default value interacts with the glyph and glyph variations tables in a particular way: the variation instance that has the default coordinate value for each axis will use glyph outlines as defined in the glyph table, without any variations from the glyph variations table applied. This instance is referred to as the default instance.
The axisNameID field provides a name ID that can be used to obtain strings from the 'name' table that can be used to refer to the axis in application user interfaces. The name ID must be greater than 255 and less than 32768. For registered axis tags, a conventional US English axis name is provided; it is recommended that that name, or localized derivative names, be used in application user interfaces to provide greater consistency in user experience between different fonts.
The instance record format includes an array of n-tuple coordinate arrays that define position within the font’s variation space. The n-tuple array has the following format:
Tuple Record (Fixed):
Type | Name | Description |
---|---|---|
Fixed | coordinates[axisCount] | Coordinate array specifying a position within the font’s variation space. |
The format of the instance record is as follows.
InstanceRecord:
Type | Name | Description |
---|---|---|
USHORT | subfamilyNameID | The name ID for entries in the 'name' table that provide subfamily names for this instance. |
USHORT | flags | Reserved for future use — set to 0. |
Tuple | coordinates | The coordinates array for this instance. |
USHORT | postScriptNameID | Optional. The name ID for entries in the 'name' table that provide PostScript names for this instance. |
The postScriptNameID field is optional, but should be included in all variable fonts, and may be required in some platforms. Note that all of the instance records in a given font must be the same size, with all either including or omitting the postScriptNameID field.
The subfamilyNameID field provides a name ID that can be used to obtain strings from the 'name' table that can be treated as equivalent to name ID 17 (typographic subfamily) strings for the given instance. Values of 2 or 17 can be used; otherwise, values must be greater than 255 and less than 32768. The values 2 or 17 should only be used if the named instance corresponds to the font’s default instance.
The postScriptNameID field provides a name ID that can be used to obtain strings from the 'name' table that can be treated as equivalent to name ID 6 (PostScript name) strings for the given instance. Values of 6 and 0xFFFF can be used; otherwise, values must be greater than 255 and less than 32768. If the value is 0xFFFF, then the value is ignored, and no PostScript name equivalent is provided for the instance. The value 6 should only be used if the named instance corresponds to the font’s default instance.
All of the instance records in a font should have distinct coordinates and distinct subfamilyNameID and postScriptName ID values. If two or more records share the same coordinates, the same nameID values or the same postScriptNameID values, then all but the first can be ignored.
The default instance of a font is that instance for which the coordinate value of each axis is the defaultValue specified in the corresponding variation axis record. An instance record is not required for the default instance, though an instance record can be provided. When enumerating named instances, the default instance should be enumerated even if there is no corresponding instance record. If an instance record is included for the default instance (that is, an instance record has coordinates set to default values), then the nameID value should be set to either 2 or 17, and the postScriptNameID value should be set to 6.
Variation Instance Selection
When formatting text using a variable font, applications must select a particular variation instance; that is, specific, in-range values must be specified for each of the axes defined in the font variation table. An instance may be selected by reference to a named instanced defined in an instance record, or by using a set of arbitrary axis values for the various axes. If a value is not specified for any particular axis, the default value for that axis defined in the font is used. If an application specifies a value for an axis that is less than the minValue defined in the font, then minValue must be used. Similarly, if an application specifies a value greater than the maxValue defined in the font, then maxValue must be used.
Variation Axis Tags
Axis tags identify the design variation for a given axis. Axis tags are also used in the style attributes ('STAT') table, and can be used in a style attributes table in non-variable fonts. A registry of commonly-used axis tags is maintained, but private, foundry-determined tags can also be used.
Like other OpenType tags, axis tags are four unsigned bytes that can equivalently be interpreted as a string of four ASCII characters. Axis tags must begin with a letter (0x41 to 0x5A, 0x61 to 0x7A) and must use only letters, digits (0x30 to 0x39) or space (0x20). Space characters must only occur as trailing characters in tags that have fewer than four letters or digits.
Privately-defined axis tags must begin with an uppercase letter (0x41 to 0x5A), and must use only uppercase letters or digits. Registered axis tags must not use that pattern, but can be any other valid pattern.
Every registered tag provides a US English name for the axis that can be used as a display string in user interfaces to refer to the axis, or as the basis of localized display strings.
Every registered tag also provides information regarding the range of valid values for that axis. Depending on the axis, this may or may not be a bounded range. Every registered tag must also provide information regarding the scale for those values, specifying either some objective measure or some convention by which values can be interpreted. This is required to provide some means if interoperability between different fonts and between OpenType Font Variations and other specifications, such as font-weight values in CSS.
The specification of a scale interpretation for a registered axis tag may include some value that is considered “normal” for that axis. For font implementations that support a given axis, this “normal” value will usually be a good choice for the default value of that axis in the 'fvar' variation axis record. Fonts are not required to use this “normal” value as their default, however.
Five registered tags are defined as part of this version of OpenType:
Tag | Name | Description | Scale | “Normal” value |
---|---|---|---|---|
'ital' | Italic | Used to vary between non-italic and italic. | Values must be in the range 0 to 1. A value of 0 can be interpreted as “Roman” (non-italic); a value of 1 can be interpreted as (fully) italic. | 0 |
'opsz' | Optical size | Used to vary design to suit different text sizes. | Values can be interpreted as text size, in points. (Text size can be as determined in an application and is not necessarily physical size on a display surface.) Values must be strictly greater than zero. | 12 |
'slnt' | Slant | Used to vary between upright and slanted text. | Values can be interpreted as the angle, in counter-clockwise degrees, of oblique slant from whatever the designer considers to be upright for that font design. Values must be greater than -90 and less than +90. | 0 |
'wdth' | Width | Used to vary width of text from narrower to wider. | Values can be interpreted as a percentage of whatever the font designer considers “normal” for that font design. Values must be strictly greater than zero. | 100 |
'wght' | Weight | Used to vary stroke thicknesses to give variation from lighter to blacker. | Values must be in the range 1 to 1000. Values can be interpreted in direct comparison to values for usWeightClass (in the 'OS/2' table), or the CSS font-weight property — see the note below. | 400 |
In a variable font that implements 'slnt' variations, the value in the italicAngle field of the 'post' table must match the default 'slnt' value specified in the 'fvar' table.
In a variable font that implements 'wght' variations, the value in the usWeightClass field of the 'OS/2' table must match the default 'wght' value specified in the 'fvar' table.
In a variable font that implements 'wdth' variations, the value in the usWidthClass field of the 'OS/2' table must correspond to the default 'wdth' value specified in the 'fvar' table.
Note: The italic and slant axes are distinct. Fonts may use one or the other, depending on the nature of the design. Although italic designs typically have some slant, use of the italic axis does not require use of the slant axis.
Note: The post.italicAngle field uses the same scale as the 'slnt' axis. For non-default instances of a variable font, the 'slnt' axis value can be used as the post.italicAngle value for the instance.
Note: The OS/2.usWeightClass field uses the same scale as the 'wght' design axis. For non-default instances of a variable font, the 'wght' axis value can be used as the OS/2.usWeightClass value for the instance.
Note: The OS/2.usWidthClass field (and also the CSS font-stretch property) use a scale that is different from the 'wdth' axis scale, but for which there is a defined correspondence using mappings provided with the description of usWidthClass in the OS/2 table documentation. For non-default instances of a variable font, the 'wdth' axis value can be used to derive the OS/2.usWidthClass value for that instance. When mapping from 'wdth' values to usWidthClass, interpolate values between the mapped values and round, and clamp to the range 1 to 9.
Example
This example is for a hypothetical font with family name “SelawikV” that has two axes of variation, for weight and width. This table summarizes the description of the axes for the font:
Axis tag | Minimum value | Default value | Maximum value | Axis name ID |
---|---|---|---|---|
'wght' | 300 | 400 | 700 | 256 |
'wdth' | 62.5 | 100 | 150 | 257 |
This font also has the following named instances:
Instance subfamily name | Subfamily name ID | PostScript name | PostScript name ID | 'wght' value | 'wdth' value |
---|---|---|---|---|---|
Regular | 258 | SelawikV-Regular | 262 | 400 | 100 |
Bold | 259 | SelawikV-Bold | 263 | 700 | 100 |
Condensed | 260 | SelawikV-Condensed | 264 | 400 | 75 |
Condensed Bold | 261 | SelawikV-CondensedBold | 265 | 700 | 75 |
The 'fvar' table is constructed as follows:
Hex data | Field | Comment |
---|---|---|
Header | ||
0001 | majorVersion | |
0000 | minorVersion | |
0010 | offsetToAxesArray | 16 bytes — combined size of fields before the axes array. |
0002 | countSizePairs | 2 count/size pairs: axis, instance |
0002 | axisCount | 2 axes ('wght', 'wdth') |
0014 | axisCount | Size of each variation axis record is 20 bytes. |
0004 | instanceCount | 4 named instances |
000E | instanceSize | Size of instance records is 14 bytes. |
First variation axis record | ||
77676874 | axisTag | Axis tag 'wght'. |
012C0000 | minValue | Minimum 'wght' value is 300 (Fixed format). |
01900000 | defaultValue | Default 'wght' value is 400. |
02BC0000 | maxValue | Maximum 'wght' value is 700. |
0000 | flags | |
0100 | axisNameID | Display name “Weight” uses name ID 256. |
Second variation axis record | ||
77647468 | axisTag | Axis tag 'wdth'. |
003E8000 | minValue | Minimum 'wdth' value is 62.5 (Fixed format). |
00640000 | defaultValue | Default 'wdth' value is 100. |
00960000 | maxValue | Maximum 'wdth' value is 150. |
0000 | flags | |
0101 | axisNameID | Display name “Width” uses name ID 257. |
First instance record | ||
0102 | subfamilyNameID | Instance subfamily name “Regular” uses name ID 258. |
0000 | flags | |
01900000 | coordinates[0] | 'wght' coordinate is 400. |
00640000 | coordinates[1] | 'wdth' coordinate is 100. |
0106 | postScriptNameID | Instance PostScript name “SelawikV-Regular” uses name ID 262. |
Second instance record | ||
0103 | subfamilyNameID | Instance subfamily name “Bold” uses name ID 259. |
0000 | flags | |
02BC0000 | coordinates[0] | 'wght' coordinate is 700. |
00640000 | coordinates[1] | 'wdth' coordinate is 100. |
0107 | postScriptNameID | Instance PostScript name “SelawikV-Bold” uses name ID 263. |
Third instance record | ||
0104 | subfamilyNameID | Instance subfamily name “Condensed” uses name ID 260. |
0000 | flags | |
01900000 | coordinates[0] | 'wght' coordinate is 400. |
004B0000 | coordinates[1] | 'wdth' coordinate is 75. |
0108 | postScriptNameID | Instance PostScript name “SelawikV-Condensed” uses name ID 264. |
Fourth instance record | ||
0105 | subfamilyNameID | Instance subfamily name “Condensed Bold” uses name ID 261. |
0000 | flags | |
02BC0000 | coordinates[0] | 'wght' coordinate is 700. |
004B0000 | coordinates[1] | 'wdth' coordinate is 75. |
0109 | postScriptNameID | Instance PostScript name “SelawikV-CondensedBold” uses name ID 265. |
The total size of the table is 112 bytes.