The 'gvar' table

General table information

Apple Advanced Typography style variations allow the font designer to build high quality styles into the typeface itself. This reduces the dependence on algorithmic styling in the graphics system. To include font variations in your font, you must also include the font variations table.

The glyph variations table (tag name: 'gvar') allows you to include all of the data required for stylizing the glyphs in your font.

Conceptually, variation fonts define axes over which font characteristics can vary. Thus, in the figure below, we see the Q glyph from Skia drawn at various points along the 'wght' axis. Since the minimum and maximum values have been defined as +0.7 and +1.3, respectively, the specification of a style coordinate of 1.0 refers to the style of the center 'Q.'

Multiple axes can be combined within a single font. For example, you may want to create a 'wght' axis and a 'wdth' axis. The user can then select any combination of weight and width, such as 75% bold and 50% condensed. The next figure shows an example of a two-axis font variation in which the weight axis has a minimum value of 1.0 and maximum of 1.5 and the width axis has a minimum of 0.6 and a maximum of 1.0.

Data for how these axes are presented to the user is contained in the font variations table. The glyph variations table contains data which is used to determine the outline for a glyph given a combination of settings for the various axes.

This is done by using tuples. The terminology is derived from mathematics, where an n-tuple is defined as an ordered list of n numbers. For a variation font, a tuple is an ordered list of deltas which are applied to a font at one point within the possible coordinate space defined by the axes. These deltas are added to the coordinates of the points found in the 'glyf' table to determine the actual coordinates of the points on the outline for the glyph as it is to be rendered. Hinting can then be applied to this modified outline. The hints themselves can vary for the glyph; this is controlled by the 'cvar' table.

So that a glyph can vary in its dimensions as well as its shape, tuples have entries for each point in the glyph plus entries for four "phantom points," which represent the glyph's side-bearings. These phantom points are, in order, the left-side phantom point, the right-side phantom point, the top phantom point, and the bottom phantom point.

Structure of the 'gvar' table

The glyph variations table consists of a glyph variations table header, glyph offset array, glyph style coordinate array, and glyph variations array. The overall structure of the glyph variations table is shown in the following figure:

The glyph variations table header format is shown in this table:

Type

Name

Description

fixed32 version Version number of the glyph variations table (0x00010000 for the current version).
uint16 axisCount The number of style axes for this font. This must be the same number as axisCount in the 'fvar' table.
uint16 globalCoordCount The number of shared coordinates.
uint32 offsetToCoord Byte offset from the beginning of this table to the list of shared style coordinates.
uint16 glyphCount The number of glyphs in this font.
uint16 flags Bit-field that gives the format of the offset array that follows. If the flag is 0, the type is uint16. If the flag is 1, the type is unit 32.
uint32 offsetToData Byte offset from the beginning of this table to the first glyph variation.
uint16 or uint32 offset[glyphCount+1] Byte offsets from the beginning of the glyph variation array to the data for each glyph in the font. The format of this field is set by the flags field.
variable variation[glyphCount] The glyph variation array.

The shared coordinates of the globalCoordCount are referenced by the glyph tuples rather than storing the coordinates in each glyph tuple.

The number of bytes occupied by the global coordinates can be found using the expression offsetToData - offsetToCoord. This size should be equal to globalCoordCount * axisCount * sizeof(shortFrac). That is, there are globalCoord shortFrac&s for each axis in the font.

If the flag bitfield is set to 1, the offsets are type uint32. If the flag bit-field is set to 0, the offsets are type uint16.

The offset array follows the glyph variation header. The offset array gives the offset from the beginning of the glyph variation array. This data specifies where each glyph variation begins. The variation data is the same order as the glyph order. This allows the length of a particular glyph variation to be computed by subtracting the offset of the next variation from the current one. This means that there must be glyphCount + 1 entries in the offset array.

The glyph variation array follows the glyph variation offset array. Each glyph variation array is padded to ensure that it start at an even bytes. Each glyph variation begins with a glyph variation array header. The format of the glyph variation array header is as follows:

Type

Name

Description

uint16 tupleCount A packed field. The high 4 bits are flags and the low 12 bits are the number of tuples for this glyph. The number of tuples can be any number between 1 and 4095.
uint16 offsetToData Byte offset from the beginning of the glyph variation header to the first byte of either the shared packed point numbers or the first packed tuple data (that is, the offset to either the pointNumbers array or the tuple variation data).
tupleVariation tuple[tupleCount] The tuple variation array.
char pointNumbers[] The shared point numbers array.
char tupleData[] The tuple variation data.

The tupleCount is a packed field comprising a flag and the number of tuples. The format of the tupleCount field is shown here:

Value

Name

Description

0x8000 tuples_share_point_numbers Flag indicating that some or all tuples reference a common set of packed point numbers that follow.
0x7000 reserved_tuple_count_flags Flags reserved for future use.
0x0FFF tuple_count_mask Mask using the low bits to give the tuple count.

Currently, the only flag bit supported is 0x8000, tuples_share_point_numbers. This means that all of the tuples reference a common set of packed point numbers that follow immediately after the tuple array.

The glyph variation header is followed by a list of tuple variations. Each tuple variation begins with a tuple variation header. The format of the tuple variation header is as follows:

Type

Name

Description

uint16 tupleSize The size in bytes of variation data for this tuple.
uint16 tupleIndex A packed field. The high 4 bits are flags. The interpretation of these flags is provided in Table 14-5. The low 12 bits are an index into the global tuple coordinates.
shortFrac embeddedCoord[] Embedded coordinate tuples, if any.
shortFrac intermediateCoord[] Intermediate coordinate tuples, if any.

The tupleSize field is not the size of the full tuple variation data for this tuple. Rather, it refers to the number of bytes within the tupleData for the entire glyph variation which are used by this tuple. The next tuple data can actually be calculated using code something like the following:

const tupleVariation* 
NextTupleVariation( const tupleVariation* iTupleVar, int iAxisCount )
{
	int tBump = sizeof( tupleVariation ); /* four bytes == two * sizeof( UInt16 ) */
	int tTupleIndex = iTupleVar->tupleIndex;

	if ( tTupleIndex & embedded_tuple_coord )
		tBump += iAxisCount * sizeof( shortFrac );
	if ( tTupleIndex & intermediate_tuple )
		tBump += 2 * iAxisCount * sizeof( shortFrac );
	return (const tupleVariation*)((char*)iTupleVar + tBump);
}

The tupleIndex is a packed field consisting of a flag and an index mask into the array of global tuple coordinates. The tupleIndex field format is described in the following table:

Value

Name

Description

0x8000 embedded_tuple_coord Flag indicating that the coordinate for this tuple follows immediately after the tupleIndex. The low 12 bits of the tupleIndex are ignored.
0x4000 intermediate_tuple Flag indicating that this is an intermediate tuple. The two coordinates following the tupleIndex (and the optional embedded coordinate) specify the domain for this tuple.
0x2000 private_point_numbers Flag indicating that the preceding tuple data for this tuple is a set of packed point numbers that this tuple operates on. If this bit is clear, this tuple uses shared point numbers.
0x1000 reserved_tuple_index_flag Flag reserved for future use.
0x0FFF tuple_index_mask Mask using the low bits to give the tuple index.

Point Numbers for Simple Glyph Variations

Point numbers are stored as a count followed by the first point number. Each subsequent point is stored as the difference between it and the previous point number. The data is packed into runs of bytes and words.

If the count will fit in 7 bits, the point count is packed into a byte. If the count will not fit in 7 bits, it is stored in 2 bytes, with the high bit of the first byte set. If count = 0, every point on the glyph is used and no data follows. If count is nonzero, a series of runs of bytes and words follows. In this case each run begins with a control byte. The control byte's high bit specifies whether the run is bytes or words and the low 7 bits specify the number of elements in the run minus 1.

The packed point count flag format is as follows:

Mask

Name

Description

0x80 points_are_words Flag indicating that the point number run is a word.
0x7F point_run_count_mask Mask indicating that the low 7 bits are the number of elements minus 1.

Deltas for Glyph Variations

Deltas for a tuple are stored as an array of x-deltas followed by an array of y-deltas. Each delta corresponds to a point in the glyph outline specified in the point numbers array for this tuple. The X and Y arrays are packed similar to the point numbers. Each array is a series of runs, where each run is a control byte followed by deltas. The control byte specifies the size of the data in the run in the high two bits, and the number of deltas in the low six bits.

The packed tuple delta field formats are shown in the following table. Note that if neither the 0x80 or 0x40 flags are set, then the run contains signed byte deltas.

Mask

Name

Description

0x80 deltas_are_zero Flag indicating that this run contains no data. This means that all of the deltas are zero, so no data is actually stored.
0x40 deltas_are_words Flag indicating that the run contains 16-bit signed deltas.
0x3F delta_run_count_mask Flag and mask using the low 6 bits to provide the number of deltas in the run minus 1.

Point Numbers for Component Glyph Variations

Component glyph variations are structured very similar to glyph variations for simple glyphs. The difference is that simple glyphs are defined by points and component glyphs are defined by other glyphs. Component glyph variations describe how the position of each component specified by offsets changes and how the metrics of the parent composite glyph change. These changes are represented by fake point numbers. One fake point number is assigned to each component and then 4 more are assigned for the final glyph's metrics.

Consider the component glyph 'é'. If the accent was specified using anchor points, then there would be no use for variation data. The accent can be repositioned by moving the attachment points in either the base glyph or the accent. However, if the accent was specified by an offset, the variation data could be used to describe how its position changes.

The fake point number assignment and the delta assignments for the example component glyph are as follows:

Fake point number

Delta assignments

0 Base glyph.
1 Accent glyph.
2 Left side bearing metric point.
3 Right side bearing metric point.
4 Top side bearing metric point.
5 Bottom side bearing metric point.

Mac OS-specific information

The 'gvar' table is supported on Mac OS only via QuickDraw GX or ATSUI. Applications which do not take advantage of these technologies directly or indirectly may not use style variations within fonts.

Newton-specific information

The 'gvar' table is not supported on the Newton OS.

Dependencies

The 'fvar' table should have the same number of axes as the 'fvar' table. The glyph and glyph point indices should be the same as in the 'glyf' table.

Tools

The only tool currently supported for editing 'gvar' tables is ftxdumperfuser. Note that ftxdumperfuser does not have a specific XML format for 'fvar' tables; you must use the generic table format.


Change Log

16 December 2002
General update and clarification.
30 September 1996
Switched to use the <TABLE> tag.
29 April 1995
Initial conversion to HTML format.
applefonts@apple.com

[Table of Contents]