Shared Tables:
ValueRecord, Anchor Table, and MarkArray

Several lookup subtables described earlier in this chapter refer to one or more of the same tables for positioning data: ValueRecord, Anchor table, and MarkArray. For easy reference, those shared tables are described here.

Example 14 at the end of the chapter uses a ValueFormat table and ValueRecord to specify positioning values in GPOS.

ValueRecord

GPOS subtables use ValueRecords to describe all the variables and values used to adjust the position of a glyph or set of glyphs. A ValueRecord may define any combination of X and Y values (in design units) to add to (positive values) or subtract from (negative values) the placement and advance values provided in the font. A ValueRecord also may contain an offset to a Device table for each of the specified values. If a ValueRecord specifies more than one value, the values should be listed in the order shown in the ValueRecord definition.

The text-processing client must be aware of the flexible and multi-dimensional nature of ValueRecords in the GPOS table. Because the GPOS table uses ValueRecords for many purposes, the sizes and contents of ValueRecords may vary from subtable to subtable.

ValueRecord (all fields are optional)

Type

Name

Description

int16

XPlacement

Horizontal adjustment for placement

  

—in design units

int16

YPlacement

Vertical adjustment for placement

  

—in design units

int16

XAdvance

Horizontal adjustment for advance

  

—in design units

int16

YAdvance

Vertical adjustment for advance

  

—in design units

Offset

XPlaDevice

Offset to Device table for horizontal placement

  

—measured from beginning of PosTable

Offset

YPlaDevice

Offset to Device table for vertical placement

  

—measured from beginning of PosTable

Offset

XAdvDevice

Offset to Device table for horizontal advance

  

—measured from beginning of PosTable

Offset

YAdvDevice

Offset to Device table for vertical advance

  

—measured from beginning of PosTable


A data format (ValueFormat), usually declared at the beginning of each GPOS subtable, defines the types of positioning adjustment data that ValueRecords specify. Usually, the same ValueFormat applies to every ValueRecord defined in the particular GPOS subtable.

The ValueFormat determines whether the ValueRecords:

Apply to placement, advance, or both.

Apply to the horizontal position (X coordinate), the vertical position (Y coordinate), or both.

May refer to one or more Device tables for any of the specified values.

Each one-bit in the ValueFormat corresponds to a field in the ValueRecord and increases the size of the ValueRecord by 2 bytes. A ValueFormat of 0x0000 corresponds to an empty ValueRecord, which indicates no positioning changes.

To identify the fields in each ValueRecord, the ValueFormat uses the bit settings shown below. To specify multiple fields with a ValueFormat, the bit settings of the relevant fields are added with a logical OR operation.

For example, to adjust the left-side bearing of a glyph, the ValueFormat will be 0x0001, and the ValueRecord will define the XPlacement value. To adjust the advance width of a different glyph, the ValueFormat will be 0x0004, and the ValueRecord will describe the XAdvance value. To adjust both the XPlacement and XAdvance of a set of glyphs, the ValueFormat will be 0x0005, and the ValueRecord will specify both values in the order they are listed in the ValueRecord definition.

ValueFormat bit enumeration (indicates which fields are present)

Mask

Name

Description

0x0001

XPlacement

Includes horizontal adjustment for placement

0x0002

YPlacement

Includes vertical adjustment for placement

0x0004

XAdvance

Includes horizontal adjustment for advance

0x0008

YAdvance

Includes vertical adjustment for advance

0x0010

XPlaDevice

Includes horizontal Device table for placement

0x0020

YPlaDevice

Includes vertical Device table for placement

0x0040

XAdvDevice

Includes horizontal Device table for advance

0x0080

YAdvDevice

Includes vertical Device table for advance

0xFF00

Reserved

For future use


Anchor Table

A GPOS table uses anchor points to position one glyph with respect to another. Each glyph defines an anchor point, and the text-processing client attaches the glyphs by aligning their corresponding anchor points.

To describe an anchor point, an Anchor table can use one of three formats. The first format uses design units to specify a location for the anchor point. The other two formats refine the location of the anchor point using contour points (Format 2) or Device tables (Format 3).

Anchor Table: Format 1

AnchorFormat1 consists of a format identifier (AnchorFormat) and a pair of design unit coordinates (XCoordinate and YCoordinate) that specify the location of the anchor point. This format has the benefits of small size and simplicity, but the anchor point cannot be hinted to adjust its position for different device resolutions.

Example 15 at the end of this chapter uses AnchorFormat1.

AnchorFormat1 table: Design units only

Type

Name

Description

uint16

AnchorFormat

Format identifier

  

—format = 1

int16

XCoordinate

Horizontal value

  

—in design units

int16

YCoordinate

Vertical value

  

—in design units


Anchor Table: Format 2

Like AnchorFormat1, AnchorFormat2 specifies a format identifier (AnchorFormat) and a pair of design unit coordinates for the anchor point (Xcoordinate and Ycoordinate).

For fine-tuning the location of the anchor point, AnchorFormat2 also provides an index to a glyph contour point (AnchorPoint) that is on the outline of a glyph (AnchorPoint). Hinting can be used to move the AnchorPoint. In the rendered text, the AnchorPoint will provide the final positioning data for a given ppem size.

Example 16 at the end of this chapter uses AnchorFormat2.

AnchorFormat2 table: Design units plus contour point

Type

Name

Description

uint16

AnchorFormat

Format identifier

  

—format = 2

int16

XCoordinate

Horizontal value

  

—in design units

int16

YCoordinate

Vertical value

  

—in design units

uint16

AnchorPoint

Index to glyph contour point


Anchor Table: Format 3

Like AnchorFormat1, AnchorFormat3 specifies a format identifier (AnchorFormat) and locates an anchor point (Xcoordinate and Ycoordinate). And, like AnchorFormat 2, it permits fine adjustments to the coordinate values. However, AnchorFormat3 uses Device tables, rather than a contour point, for this adjustment.

With a Device table, a client can adjust the position of the anchor point for any font size and device resolution. AnchorFormat3 can specify offsets to Device tables for the the X coordinate (XDeviceTable) and the Y coordinate (YDeviceTable). If only one coordinate requires adjustment, the offset to the Device table may be set to NULL for the other coordinate.

Example 17 at the end of the chapter shows an AnchorFormat3 table.

AnchorFormat3 table: Design units plus Device tables

Type

Name

Description

uint16

AnchorFormat

Format identifier

  

—format = 3

int16

XCoordinate

Horizontal value

  

—in design units

int16

YCoordinate

Vertical value

  

—in design units

Offset

XDeviceTable

Offset to Device table for X coordinate

  

—from beginning of Anchor table

  

— may be NULL

Offset

YDeviceTable

Offset to Device table for Y coordinate

  

— from beginning of Anchor table

  

— may be NULL


Mark Array

The MarkArray table defines the class and the anchor point for a mark glyph. Three GPOS subtables—MarkToBase, MarkToLigature, and MarkToMark Attachment—use the MarkArray table to specify data for attaching marks.

The MarkArray table contains a count of the number of mark records (MarkCount) and an array of those records (MarkRecord). Each mark record defines the class of the mark and an offset to the Anchor table that contains data for the mark.

A class value can be 0 (zero), but the MarkRecord must explicitly assign that class value (this differs from the ClassDef table, in which all glyphs not assigned class values automatically belong to Class 0). The GPOS subtables that refer to MarkArray tables use the class assignments for indexing zero-based arrays that contain data for each mark class.

In Example 18 at the end of the chapter, a MarkArray table and two MarkRecords define two mark classes.

MarkArray table

Type

Name

Description

uint16

MarkCount

Number of MarkRecords

struct

MarkRecord[MarkCount]

Array of MarkRecords

  

—in Coverage order


MarkRecord

Type

Name

Description

uint16

Class

Class defined for this mark

Offset

MarkAnchor

Offset to Anchor table

  

—from beginning of MarkArray table