Partager via


OpenType™ Layout Common Table Formats (OpenType 1.8.1)

OpenType Layout consists of five tables: the Glyph Substitution table (GSUB), the Glyph Positioning table (GPOS), the Baseline table (BASE), the Justification table (JSTF), and the Glyph Definition table (GDEF). These tables use some of the same data formats.

This chapter explains the conventions used in all OpenType Layout tables, and it describes the common table formats. Separate chapters provide complete details about the GSUB, GPOS, BASE, JSTF, and GDEF tables.

Overview

The OpenType Layout tables provide typographic information for properly positioning and substituting glyphs, operations that are required for accurate typography in many language environments. OpenType Layout data is organized by script, language system, typographic feature, and lookup.

Scripts are defined at the top level. A script is a collection of glyphs used to represent one or more languages in written form (see Figure 2a). For instance, a single script-Latin-is used to write English, French, German, and many other languages. In contrast, three scripts-Hiragana, Katakana, and Kanji-are used to write Japanese. With OpenType Layout, multiple scripts may be supported by a single font.

Latin, Kanji and Arabic glyphs
Figure 2a. Glyphs in the Latin, Kanji, and Arabic scripts

A language system may modify the functions or appearance of glyphs in a script to represent a particular language. For example, the eszet ligature is used in the German language system, but not in French or English (see Figure 2b). And the Arabic script contains different glyphs for writing the Farsi and Urdu languages. In OpenType Layout, language systems are defined within scripts.

Differences between English, French and German typography
Figure 2b. Differences in the English, French, and German language systems

A language system defines features, which are typographic rules for using glyphs to represent a language. Sample features are a “vert” feature that substitutes vertical glyphs in Japanese, a “liga” feature for using ligatures in place of separate glyphs, and a “mark” feature that positions diacritical marks with respect to base glyphs in Arabic (see Figure 2c). In the absence of language-specific rules, default language system features apply to the entire script. For instance, a default language system feature for the Arabic script substitutes initial, medial, and final glyph forms based on a glyph’s position in a word.

Ligature formation and mark positioning
Figure 2c. A ligature glyph feature substitutes the <etc> ligature for individual glyphs, and a mark feature positions diacritical marks above an Arabic ligature glyph.

Features are implemented with lookup data that the text-processing client uses to substitute and position glyphs. Lookups describe the glyphs affected by an operation, the type of operation to be applied to these glyphs, and the resulting glyph output.

A font may also include FeatureVariations data within a GPOS or GSUB table that allows the default lookup data associated with a feature to be substituted by alternate lookup data when particular conditions apply. Currently, this mechanism is used only for variable fonts using OpenType Font Variations.

OpenType Layout and Font Variations

OpenType Font Variations allow a single font to support many design variations along one or more axes of design variation. For example, a font with weight and width variations might support weights from thin to black, and widths from ultra-condensed to ultra-expanded. For general information on OpenType Font Variations, see the chapter, OpenType Font Variations Overview.

When different variation instances are selected, the design and metrics of individual glyphs changes. This can impact font-unit values given in GPOS, BASE, JSTF or GDEF tables, such as the X and Y coordinates of an attachment anchor position. The font-unit values given in these tables apply to the default instance of a variable font. If adjustments are needed for different variation instances, this is done using variation data with processes similar to those used for glyph outlines and other font data, as described in the chapter, OpenType Font Variations Overview. The variation data for GPOS, JSTF or GDEF values is contained in an ItemVariationStore table which, in turn, is contained within the GDEF table; variation data for BASE values is contained in an ItemVariationStore table within the BASE table itself. The format of the ItemVariationStore is described in detail in the chapter, OpenType Font Variations Common Table Formats. For font-unit values within the GPOS, BASE, JSTF or GDEF tables that require variation, references to specific variation data within the ItemVariationStore are provided in VariationIndex tables, described below.

In some variable fonts, it may be desirable to have different glyph-substitution or glyph-positioning actions used for different regions within the font’s variation space. For example, for narrow or heavy instances in which counters become small, it may be desirable to make certain glyph substitutions to use alternate glyphs with certain strokes removed or outlines simplified to allow for larger counters. Such effects can be achieved using a FeatureVariations table within either the GSUB or GPOS table. The FeatureVariations table is described below.

Table Organization

Two OpenType Layout tables, GSUB and GPOS, use the same data formats to describe the typographic functions of glyphs and the languages and scripts that they support: a ScriptList table, a FeatureList table, a LookupList table, and a FeatureVariations table. In GSUB, the tables define glyph substitution data. In GPOS, they define glyph positioning data. This chapter describes these common table formats.

The ScriptList identifies the scripts in a font, each of which is represented by a Script table that contains script and language-system data. Language system tables reference features, which are defined in the FeatureList. Each feature table references the lookup data defined in the LookupList that describes how, when, and where to implement the feature.

block diagram showing script, language system and feature table organization
Figure 2d. The relationship of scripts, language systems, features, and lookups for substitution and positioning tables

Note: The data in the BASE and JSTF tables also is organized by script and language system. However, the data formats differ from those in GSUB and GPOS, and they do not include a FeatureList or LookupList. The BASE and JSTF data formats are described in the BASE and JSTF chapters.

The information used to substitute and position glyphs is defined in Lookup subtables. Each subtable supplies one type of information, depending upon whether the lookup is part of a GSUB or GPOS table. For instance, a GSUB lookup might specify the glyphs to be substituted and the context in which a substitution occurs, and a GPOS lookup might specify glyph position adjustments for kerning. OpenType Layout has seven types of GSUB lookups (described in the GSUB chapter) and nine types of GPOS lookups (described in the GPOS chapter).

Each subtable (except for an Extension LookupType subtable) includes a Coverage table that lists the “covered” glyphs that will result in a glyph substitution or positioning operation. The Coverage table formats are described in this chapter.

Some substitution or positioning operations may apply to groups, or classes, of glyphs. GSUB and GPOS Lookup subtables use the Class Definition table to assign glyphs to classes. This chapter includes a description of the Class Definition table formats.

In non-variable fonts, GPOS Lookup subtables may also contain Device tables to adjust scaled contour glyph coordinates for particular output sizes and resolutions. Device tables can also be used for similar adjustments to baseline metric or caret offset values in the BASE and GDEF tables. Similarly, in variable fonts, GPOS lookup subtables, BaseCoord tables and CaretValue tables may contain VariationIndex tables that reference variation data to adjust font-unit values as may be needed for different variation instances within a font’s design variation space. Device and VariationIndex tables are described in this chapter.

As mentioned above, a feature table references a set of lookups in the lookup list. The FeatureVariations table allows the default set of lookups used for a given feature to be substituted by a different set of lookups under particular conditions. This can be used in variable fonts to provide different substitution or positioning actions for different variation instances. For example, for narrow or heavy instances in which counters become small, it may be desirable to make certain glyph substitutions to use alternate glyphs with certain strokes removed or outlines simplified to allow for larger counters.

This chapter describes the common data types used in OpenType Layout. Sample tables and lists that illustrate the common data formats are supplied at the end of this chapter.

Scripts and Languages

Three tables and their associated records apply to scripts and languages: the Script List table (ScriptList) and its script record (ScriptRecord), the Script table and its language system record (LangSysRecord), and the Language System table (LangSys).

Script List Table and Script Record

OpenType Layout fonts may contain one or more groups of glyphs used to render various scripts, which are enumerated in a ScriptList table. Both the GSUB and GPOS tables define Script List tables (ScriptList):

  • The GSUB table uses the ScriptList table to access the glyph substitution features that apply to a script. For details, see the chapter, The Glyph Substitution Table (GSUB).
  • The GPOS table uses the ScriptList table to access the glyph positioning features that apply to a script. For details, see the chapter, The Glyph Positioning Table (GPOS).

A ScriptList table consists of a count of the scripts represented by the glyphs in the font (ScriptCount) and an array of records (ScriptRecord), one for each script for which the font defines script-specific features (a script without script-specific features does not need a ScriptRecord).

If a Script table with the script tag 'DFLT' (default) is present in the ScriptList table, it must have a non-NULL DefaultLangSys and LangSysCount must be equal to 0. The 'DFLT' Script table should be used if there is not an explicit entry for the script being formatted.

The ScriptRecord array stores the records alphabetically by a ScriptTag that identifies the script. Each ScriptRecord consists of a ScriptTag and an offset to a Script table.

Example 1 at the end of this chapter shows a ScriptList table and ScriptRecords for a Japanese font that uses three scripts.

ScriptList table

Type Name Description
uint16 ScriptCount Number of ScriptRecords
struct ScriptRecord
[ScriptCount]
Array of ScriptRecords
-listed alphabetically by ScriptTag

ScriptRecord

Type Name Description
Tag ScriptTag 4-byte ScriptTag identifier
Offset16 Script Offset to Script table-from beginning of ScriptList

Script Table and Language System Record

A Script table identifies each language system that defines how to use the glyphs in a script for a particular language. It also references a default language system that defines how to use the script’s glyphs in the absence of language-specific knowledge.

A Script table begins with an offset to the Default Language System table (DefaultLangSys), which defines the set of features that regulate the default behavior of the script. Next, Language System Count (LangSysCount) defines the number of language systems (excluding the DefaultLangSys) that use the script. In addition, an array of Language System Records (LangSysRecord) defines each language system (excluding the default) with an identification tag (LangSysTag) and an offset to a Language System table (LangSys). The LangSysRecord array stores the records alphabetically by LangSysTag.

If no language-specific script behavior is defined, the LangSysCount is set to zero (0), and no LangSysRecords are allocated.

Script table

Type Name Description
Offset16 DefaultLangSys Offset to DefaultLangSys table-from beginning of Script table-may be NULL
uint16 LangSysCount Number of LangSysRecords for this script-excluding the DefaultLangSys
struct LangSysRecord
[LangSysCount]
Array of LangSysRecords-listed alphabetically by LangSysTag

LangSysRecord

Type Name Description
Tag LangSysTag 4-byte LangSysTag identifier
Offset16 LangSys Offset to LangSys table-from beginning of Script table

Language System Table

The Language System table (LangSys) identifies language-system features used to render the glyphs in a script. (The LookupOrder offset is reserved for future use.)

Optionally, a LangSys table may define a Required Feature Index (ReqFeatureIndex) to specify one feature as required within the context of a particular language system. For example, in the Cyrillic script, the Serbian language system always renders certain glyphs differently than the Russian language system.

Only one feature index value can be tagged as the ReqFeatureIndex. This is not a functional limitation, however, because the feature and lookup definitions in OpenType Layout are structured so that one feature table can reference many glyph substitution and positioning lookups. When no required features are defined, then the ReqFeatureIndex is set to 0xFFFF.

All other features are optional. For each optional feature, a zero-based index value references a record (FeatureRecord) in the FeatureRecord array, which is stored in a Feature List table (FeatureList). The feature indices themselves (excluding the ReqFeatureIndex) are stored in arbitrary order in the FeatureIndex array. The FeatureCount specifies the total number of features listed in the FeatureIndex array.

Features are specified in full in the FeatureList table, FeatureRecord, and Feature table, which are described later in this chapter. Example 2 at the end of this chapter shows a Script table, LangSysRecord, and LangSys table used for contextual positioning in the Arabic script.

LangSys table

Type Name Description
Offset16 LookupOrder = NULL (reserved for an offset to a reordering table)
uint16 ReqFeatureIndex Index of a feature required for this language system- if no required features = 0xFFFF
uint16 FeatureCount Number of FeatureIndex values for this language system-excludes the required feature
uint16 FeatureIndex[FeatureCount] Array of indices into the FeatureList-in arbitrary order

Features and Lookups

Features define the functionality of an OpenType Layout font and they are named to convey meaning to the text-processing client. Consider a feature named “liga” to create ligatures. Because of its name, the client knows what the feature does and can decide whether to apply it. For more information, see the “OpenType Layout Registered Features” chapter. Font developers can use these features, as well as create their own.

After choosing which features to use, the client assembles all lookups from the selected features. Multiple lookups may be needed to define the data required for different substitution and positioning actions, as well as to control the sequencing and effects of those actions.

To implement features, a client applies the lookups in the order the lookup definitions occur in the LookupList. As a result, within the GSUB or GPOS table, lookups from several different features may be interleaved during text processing. A lookup is finished when the client locates a target glyph or glyph context and performs a substitution (if specified) or a positioning (if specified).

Note: The substitution (GSUB) lookups always occur before the positioning (GPOS) lookups. The lookup sequencing mechanism in TrueType relies on the font to determine the proper order of text-processing operations.

Lookup data is defined in one or more subtables that contain information about specific glyphs and the operations to be performed on them. Each type of lookup has one or more corresponding subtable definitions. The choice of a subtable format depends upon two factors: the precise content of the information being applied to an operation, and the required storage efficiency. (For complete definitions of all lookup types and subtables, see the the GSUB and GPOS chapters of this document.)

OpenType Layout features define information that is specific to the layout of the glyphs in a font. They do not encode information that is constant within the conventions of a particular language or the typography of a particular script. Information that would be replicated across all fonts in a given language belongs in the text-processing application for that language, not in the fonts.

Feature List Table

The headers of the GSUB and GPOS tables contain offsets to Feature List tables (FeatureList) that enumerate all the features in a font. Features in a particular FeatureList are not limited to any single script. A FeatureList contains the entire list of either the GSUB or GPOS features that are used to render the glyphs in all the scripts in the font.

The FeatureList table enumerates features in an array of records (FeatureRecord) and specifies the total number of features (FeatureCount). Every feature must have a FeatureRecord, which consists of a FeatureTag that identifies the feature and an offset to a Feature table (described next). The FeatureRecord array is arranged alphabetically by FeatureTag names.

Note: The values stored in the FeatureIndex array of a LangSys table are used to locate records in the FeatureRecord array of a FeatureList table.

FeatureList table

Type Name Description
uint16 FeatureCount Number of FeatureRecords in this table
struct FeatureRecord[FeatureCount] Array of FeatureRecords-zero-based (first feature has FeatureIndex = 0)-listed alphabetically by FeatureTag

FeatureRecord

Type Name Description
Tag FeatureTag 4-byte feature identification tag
Offset16 Feature Offset to Feature table-from beginning of FeatureList

Feature Table

A Feature table defines a feature with one or more lookups. The client uses the lookups to substitute or position glyphs.

Feature tables defined within the GSUB table contain references to glyph substitution lookups, and feature tables defined within the GPOS table contain references to glyph positioning lookups. If a text-processing operation requires both glyph substitution and positioning, then both the GSUB and GPOS tables must each define a Feature table, and the tables must use the same FeatureTags.

A Feature table consists of an offset to a Feature Parameters (FeatureParams) table (if one has been defined for this feature - see note in the following paragraph), a count of the lookups listed for the feature (LookupCount), and an arbitrarily ordered array of indices into a LookupList (LookupListIndex). The LookupList indices are references into an array of offsets to Lookup tables.

The format of the Feature Parameters table is specific to a particular feature, and must be specified in the feature’s entry in the Feature Tags section of the OpenType Layout Tag Registry. The length of the Feature Parameters table must be implicitly or explicitly specified in the Feature Parameters table itself. The FeatureParams field in the Feature Table records the offset relative to the beginning of the Feature Table. If a Feature Parameters table is not needed, the FeatureParams field must be set to NULL.

To identify the features in a GSUB or GPOS table, a text-processing client reads the FeatureTag of each FeatureRecord referenced in a given LangSys table. Then the client selects the features it wants to implement and uses the LookupList to retrieve the Lookup indices of the chosen features. Next, the client arranges the indices in the LookupList order. Finally, the client applies the lookup data to substitute or position glyphs.

Example 3 at the end of this chapter shows the FeatureList and Feature tables used to substitute ligatures in two languages.

Feature table

Type Name Description
Offset16 FeatureParams = NULL (reserved for offset to FeatureParams)
uint16 LookupCount Number of LookupList indices for this feature
uint16 LookupListIndex
[LookupCount]
Array of LookupList indices for this feature -zero-based (first lookup is LookupListIndex = 0)

Lookup List Table

The headers of the GSUB and GPOS tables contain offsets to Lookup List tables (LookupList) for glyph substitution (GSUB table) and glyph positioning (GPOS table). The LookupList table contains an array of offsets to Lookup tables (Lookup). The font developer defines the Lookup sequence in the Lookup array to control the order in which a text-processing client applies lookup data to glyph substitution and positioning operations. LookupCount specifies the total number of Lookup table offsets in the array.

Example 4 at the end of this chapter shows three ligature lookups in the LookupList table.

LookupList table

Type Name Description
uint16 LookupCount Number of lookups in this table
Offset16 Lookup[LookupCount] Array of offsets to Lookup tables-from beginning of LookupList -zero based (first lookup is Lookup index = 0)

Lookup Table

A Lookup table (Lookup) defines the specific conditions, type, and results of a substitution or positioning action that is used to implement a feature. For example, a substitution operation requires a list of target glyph indices to be replaced, a list of replacement glyph indices, and a description of the type of substitution action.

Each Lookup table may contain only one type of information (LookupType), determined by whether the lookup is part of a GSUB or GPOS table. GSUB supports eight LookupTypes, and GPOS supports nine LookupTypes (for details about LookupTypes, see the GSUB and GPOS chapters of the document).

Each LookupType is defined with one or more subtables, and each subtable definition provides a different representation format. The format is determined by the content of the information required for an operation and by required storage efficiency. When glyph information is best presented in more than one format, a single lookup may contain more than one subtable, as long as all the subtables are the same LookupType. For example, within a given lookup, a glyph index array format may best represent one set of target glyphs, whereas a glyph index range format may be better for another set of target glyphs.

During text processing, a client applies a lookup to each glyph in the string before moving to the next lookup. A lookup is finished for a glyph after the client makes the substitution/positioning operation. To move to the “next” glyph, the client will typically skip all the glyphs that participated in the lookup operation: glyphs that were substituted/positioned as well as any other glyphs that formed a context for the operation. However, in the case of pair positioning operations (i.e., kerning), the “next” glyph in a sequence may be the second glyph of the positioned pair (see pair positioning lookup for details).

A Lookup table contains a LookupType, specified as an integer, that defines the type of information stored in the lookup. The LookupFlag specifies lookup qualifiers that assist a text-processing client in substituting or positioning glyphs. The SubTableCount specifies the total number of SubTables. The SubTable array specifies offsets, measured from the beginning of the Lookup table, to each SubTable enumerated in the SubTable array.

Lookup table

Type Name Description
uint16 LookupType Different enumerations for GSUB and GPOS
uint16 LookupFlag Lookup qualifiers
uint16 SubTableCount Number of SubTables for this lookup
Offset16 SubTable
[SubTableCount]
Array of offsets to SubTables-from beginning of Lookup table
uint16 MarkFilteringSet Index (base 0) into GDEF mark glyph sets structure. This field is only present if bit UseMarkFilteringSet of lookup flags is set.

The LookupFlag uses two bytes of data:

  • Each of the first four bits can be set in order to specify additional instructions for applying a lookup to a glyph string. The LookUpFlag bit enumeration table provides details about the use of these bits.
  • The fifth bit indicates the presence of a MarkFilteringSet field in the Lookup table.
  • The next three bits are reserved for future use.
  • The high byte is set to specify the type of mark attachment.

LookupFlag bit enumeration

Type Name Description
0x0001 RightToLeft This bit relates only to the correct processing of the cursive attachment lookup type (GPOS lookup type 3). When this bit is set, the last glyph in a given sequence to which the cursive attachment lookup is applied, will be positioned on the baseline.
Note: Setting of this bit is not intended to be used by operating systems or applications to determine text direction.
0x0002 IgnoreBaseGlyphs If set, skips over base glyphs
0x0004 IgnoreLigatures If set, skips over ligatures
0x0008 IgnoreMarks If set, skips over all combining marks
0x0010 UseMarkFilteringSet If set, indicates that the lookup table structure is followed by a MarkFilteringSet field. The layout engine skips over all mark glyphs not in the mark filtering set indicated.
0x00E0 Reserved For future use (Set to zero)
0xFF00 MarkAttachmentType If not zero, skips over all marks of attachment type different from specified.

IgnoreBaseGlyphs, IgnoreLigatures, or IgnoreMarks refer to base glyphs, ligatures and marks as defined in the Glyph Class Definition Table in the GDEF table. If any of these flags are set, a Glyph Class Definition Table must be present. If any of these bits is set, then lookups must ignore glyphs of the respective type; that is, the other glyphs must be processed just as though these glyphs were not present.

If MarkAttachmentType is non-zero, then mark attachment classes must be defined in the Mark Attachment Class Definition Table in the GDEF table. When processing glyph sequences, a lookup must ignore any mark glyphs that are not in the specified mark attachment class; only marks of the specified type are processed.

If any lookup has the UseMarkFilteringSet flag set, then the Lookup header must include the MarkFilteringSet field and a MarkGlyphSetsTable must be present in GDEF table. The lookup must ignore any mark glyphs that are not in the specified mark glyph set; only glyphs in the specified mark glyph set are processed.

If a mark filtering set is specified, this supersedes any mark attachment type indication in the lookup flag. If the IgnoreMarks bit is set, this supersedes any mark filtering set or mark attachment type indications.

For example, in Arabic text, a character string might have the pattern base mark base. That string could be converted into a ligature composed of two components, one for each base character, with the combining mark glyph over the first component. To produce this ligature, the font developer would set the IgnoreMarks bit of the ligature substitution lookup to tell the client to ignore the mark, substitute the ligature glyph first, and then position the mark glyph over the in a subsequent GPOS lookup. Alternatively, a lookup which did not set the IgnoreMarks bit could be used to describe a three-component ligature glyph, composed of the first base glyph, the mark glyph, and the second base glyph.

For another example, a lookup which creates a ligature of a base glyph with a top mark could skip over all bottom marks by specifying the mark attachment type as a class that includes only top marks.

Coverage Table

Each subtable (except an Extension LookupType subtable) in a lookup references a Coverage table (Coverage), which specifies all the glyphs affected by a substitution or positioning operation described in the subtable. The GSUB, GPOS, and GDEF tables rely on this notion of coverage. If a glyph does not appear in a Coverage table, the client can skip that subtable and move immediately to the next subtable.

A Coverage table identifies glyphs by glyph indices (glyph IDs) either of two ways:

  • As a list of individual glyph indices in the glyph set.
  • As ranges of consecutive indices. The range format gives a number of start-glyph and end-glyph index pairs to denote the consecutive glyphs covered by the table.

In a Coverage table, a format code (CoverageFormat) specifies the format as an integer: 1 = lists, and 2 = ranges.

A Coverage table defines a unique index value (Coverage Index) for each covered glyph. This unique value specifies the position of the covered glyph in the Coverage table. The client uses the Coverage Index to look up values in the subtable for each glyph.

Coverage Format 1

Coverage Format 1 consists of a format code (CoverageFormat) and a count of covered glyphs (GlyphCount), followed by an array of glyph indices (GlyphArray). The glyph indices must be in numerical order for binary searching of the list. When a glyph is found in the Coverage table, its position in the GlyphArray determines the Coverage Index that is returned-the first glyph has a Coverage Index = 0, and the last glyph has a Coverage Index = GlyphCount -1.

Example 5 at the end of this chapter shows a Coverage table that uses Format 1 to list the glyph IDs of all lowercase descender glyphs in a font.

CoverageFormat1 table: Individual glyph indices

Type Name Description
uint16 CoverageFormat Format identifier-format = 1
uint16 GlyphCount Number of glyphs in the GlyphArray
uint16 GlyphArray[GlyphCount] Array of glyph IDs — in numerical order

Coverage Format 2

Format 2 consists of a format code (CoverageFormat) and a count of glyph index ranges (RangeCount), followed by an array of records (RangeRecords). Each RangeRecord consists of a start glyph index (StartGlyphID) an end glyph index (EndGlyphID) and the Coverage Index associated with the range’s Start glyph. Ranges must be in glyph ID order, and they must be distinct, with no overlapping.

The Coverage Indexes for the first range begin with zero (0), and the Start Coverage Indexes for each succeeding range are determined by adding the length of the preceding range (EndGlyphID - StartGlyphID + 1) to the array Index. This allows for a quick calculation of the Coverage Index for any glyph in any range using the formula: Coverage Index (GlyphID) = StartCoverageIndex + GlyphID - StartGlyphID.

Example 6 at the end of this chapter shows a Coverage table that uses Format 2 to identify a range of numeral glyphs in a font.

CoverageFormat2 table: Range of glyphs

Type Name Description
uint16 CoverageFormat Format identifier-format = 2
uint16 RangeCount Number of RangeRecords
struct RangeRecord
[RangeCount]
Array of glyph ranges — ordered by StartGlyphID.

RangeRecord

Type Name Description
uint16 StartGlyphID First glyph ID in the range
uint16 EndGlyphID Last glyph ID in the range
uint16 StartCoverageIndex Coverage Index of first glyph ID in range

Class Definition Table

In OpenType Layout, index values identify glyphs. For efficiency and ease of representation, a font developer can group glyph indices to form glyph classes. Class assignments vary in meaning from one lookup subtable to another. For example, in the GSUB and GPOS tables, classes are used to describe glyph contexts. GDEF tables also use the idea of glyph classes.

Consider a substitution action that replaces only the lowercase ascender glyphs in a glyph string. To more easily describe the appropriate context for the substitution, the font developer might divide the font’s lowercase glyphs into two classes, one that contains the ascenders and one that contains the glyphs without ascenders.

A font developer can assign any glyph to any class, each identified with an integer called a class value. A Class Definition table (ClassDef) groups glyph indices by class, beginning with Class 1, then Class 2, and so on. All glyphs not assigned to a class fall into Class 0. Within a given class definition table, each glyph in the font belongs to exactly one class.

The ClassDef table can have either of two formats: one that assigns a range of consecutive glyph indices to different classes, or one that puts groups of consecutive glyph indices into the same class.

Class Definition Table Format 1

The first class definition format (ClassDefFormat1) specifies a range of consecutive glyph indices and a list of corresponding glyph class values. This table is useful for assigning each glyph to a different class because the glyph indices in each class are not grouped together.

A ClassDef Format 1 table begins with a format identifier (ClassFormat). The range of glyph IDs covered by the table is identified by two values: the glyph ID of the first glyph (StartGlyphID) and the number of consecutive glyph IDs (including the first one) that will be assigned class values (GlyphCount). The ClassValueArray lists the class value assigned to each glyph ID, starting with the class value for StartGlyphID and following the same order as the glyph IDs. Any glyph not included in the range of covered glyph IDs automatically belongs to Class 0.

Example 7 at the end of this chapter uses Format 1 to assign class values to the lowercase, x-height, ascender, and descender glyphs in a font.

ClassDefFormat1 table: Class array

Type Name Description
uint16 ClassFormat Format identifier-format = 1
uint16 StartGlyphID First glyph ID of the ClassValueArray
uint16 GlyphCount Size of the ClassValueArray
uint16 ClassValueArray[GlyphCount] Array of Class Values-one per glyph ID

Class Definition Table Format 2

The second class definition format (ClassDefFormat2) defines multiple groups of glyph indices that belong to the same class. Each group consists of a discrete range of glyph indices in consecutive order (ranges cannot overlap).

The ClassDef Format 2 table contains a format identifier (ClassFormat), a count of ClassRangeRecords that define the groups and assign class values (ClassRangeCount), and an array of ClassRangeRecords ordered by the glyph ID of the first glyph in each record (ClassRangeRecord).

Each ClassRangeRecord consists of a Start glyph index, an End glyph index, and a Class value. All glyph IDs in a range, from Start to End inclusive, constitute the class identified by the Class value. Any glyph not covered by a ClassRangeRecord is assumed to belong to Class 0.

Example 8 at the end of this chapter uses Format 2 to assign class values to four types of glyphs in the Arabic script.

ClassDefFormat2 table: Class ranges

Type Name Description
uint16 ClassFormat Format identifier-format = 2
uint16 ClassRangeCount Number of ClassRangeRecords
struct ClassRangeRecord
[ClassRangeCount]
Array of ClassRangeRecords — ordered by StartGlyphID

ClassRangeRecord

Type Name Description
uint16 StartGlyphID First glyph ID in the range
uint16 EndGlyphID Last glyph ID in the range
uint16 Class Applied to all glyphs in the range

Device and VariationIndex Tables

Device tables and VariationIndex tables are used to provide adjustments to font-unit values in GPOS, JSTF, GDEF or BASE tables, such as the X and Y coordinates of an attachment anchor position. Device tables are used only in non-variable fonts. VariationIndex tables are used only in variable fonts and are a variant format of the Device table. When values require adjustment data, the table containing that value will also include an offset to a Device table or VariationIndex table.

Note: Because the same fields are used to provide an offset to a Device table or an offset to a VariationIndex table, Device tables and VariationIndex tables cannot both be used for a given positioning value. Device tables should only be used in non-variable fonts; VariationIndex tables can only be used in variable fonts.

Glyphs in a font are defined in design units specified by the font developer. Font scaling increases or decreases a glyph’s size and rounds it to the nearest whole pixel. However, precise glyph positioning often requires adjustment of these scaled and rounded values, particularly at small PPEM sizes. Hinting, applied to points in the glyph outline, is an effective solution to this problem, but it may require the font developer to redesign or re-hint glyphs.

Another solution, used by the GPOS, BASE, JSTF, and GDEF tables in non-variable fonts, is to use a Device table to specify correction values to adjust the scaled design units. A Device table applies the correction values to the range of sizes identified by StartSize and EndSize, which specify the smallest and largest pixel-per-em (ppem) sizes needing adjustment.

Because Device table adjustments often are very small (a pixel or two), the correction can be compressed into a 2-, 4-, or 8-bit representation per size. Two bits can represent a number in the range {-2, -1, 0, or 1}, four bits can represent a number in the range {-8 to 7}, and eight bits can represent a number in the range {-128 to 127}.

In variable fonts, X or Y font-unit values in GPOS, JSTF, or GDEF data may require adjustment for different variation instances within a font’s variation space. The variation data for this is contained in an ItemVariationStore table contained within the GDEF table. Similarly, values in a BASE table may require adjustment, and the variation data for this is contained in an ItemVariationStore table within the BASE table. The format of the ItemVariationStore is described in detail in the chapter, OpenType Font Variations Common Table Formats. It contains a number of delta values organized into sets that are referenced using a delta-set index. Data stored outside the ItemVariationStore provides delta-set indices for each of target items requiring variation. Within the GPOS, JSTF, GDEF and BASE tables, delta-set indices are stored in VariationIndex tables.

The Device and VariationIndex tables contain a DeltaFormat field that identifies the format of data contained. Format values 0x0001 to 0x0003 are used for Device tables, and indicate the format of delta adjustment values contained directly within the device table: signed 2-, 4,- or 8-bit values. A format value of 0x8000 is used for the VariationIndex table, and indicates that a delta-set index is used to reference delta data in an ItemVariationStore table.

DeltaFormat values:

Type Name Description
0x0001 local2BitDeltas Signed 2-bit value, 8 values per uint16
0x0002 local4BitDeltas Signed 4-bit value, 4 values per uint16
0x0003 local8BitDeltas Signed 8-bit value, 2 values per uint16
0x8000 variationIndex VariationIndex table, contains a delta-set index pair.

The Device table includes an array of uint16 values (DeltaValue) that stores the adjustment delta values in a packed representation. The 2-, 4-, or 8-bit signed values are packed into uint16 values starting with the most significant bits first. For example, using a DeltaFormat of 2 (4-bit values), an array of values equal to {1, 2, 3, -1} would be represented by the DeltaValue 0x123F.

A single Device table provides delta information for one target value at a range of sizes. The DeltaValue array lists the number of pixels to adjust specified X or Y values at each ppem size in the targeted range. In the array, the first index position specifies the number of pixels to add or subtract from the coordinate at the smallest ppem size that needs correction, the second index position specifies the number of pixels to add or subtract from the coordinate at the next ppem size, and so on for each ppem size in the range.

Device table

Type Name Description
uint16 StartSize Smallest size to correct, in ppem
uint16 EndSize Largest size to correct, in ppem
uint16 DeltaFormat Format of DeltaValue array data: 0x0001, 0x0002, or 0x0003
uint16 DeltaValue[ ] Array of compressed data

Example 9 at the end of this chapter uses a Device table to define the minimum extent value for a math script.

In a variable font, the ItemVariationStore table uses a two-level organization for variation data: a store can have multiple Item Variation Data subtables, and each subtable has multiple delta-set rows. A delta-set index is a two-part index: an outer index that selects a particular item variation data subtable, and an inner index that selects a particular delta-set row within that subtable. A VariationIndex table specifies both the outer and inner portions of the delta-set index.

VariationIndex table

Type Name Description
uint16 DeltaSetOuterIndex A delta-set outer index — used to select an item variation data subtable within the item variation store.
uint16 DeltaSetInnerIndex A delta-set inner index — used to select a delta-set row within an item variation data subtable.
uint16 DeltaFormat Format, = 0x8000

Note that the VariationIndex table is shorter than the Device table since it does not directly contain an array of delta data. Its format is similar to a Device table with an empty delta array. When applications get an offset to a Device or VariationIndex table, they should begin by reading the first three fields and then testing the DeltaFormat field to determine the interpretation of the first two fields and whether there is additional data to read.

FeatureVariations Table

A feature variations table describes variations on the effects of features based on various conditions. That is, it allows the default set of lookups for a given feature to be substituted with alternates of lookups under particular conditions.

The feature list provides an array of feature tables and associated feature tags, and a LangSys table identifies a particular set of the feature-table/tag pairs that will be supported for a given script and language system. The feature tables specified in a LangSys table are used by default when current conditions do not match any of the conditions for variation defined in the feature variations table. Those defaults will also be used under all conditions in implementations that do not support the feature variations table.

The feature variations table has an array of condition records, each of which references a set of conditions (a condition set table), and a set of alternate feature tables to use when a runtime context matches the condition set.

The substitutions given are replacements of one feature table for another. The alternate feature tables are appended at the end of the feature variations table, and are not included in the feature list table. Hence, there are no feature records in the feature list table that correspond to the alternate feature tables. An alternate feature table maintains the same feature tag association as the default feature table. Also, whereas the default feature tables in the feature list table are referenced using 16-bit offsets, the alternate feature tables are referenced using 32-bit offsets within the feature variations table.

When processing text, a default set of feature tables, each with an associated feature tag, is obtained from a LangSys table for a given script and language system. Condition sets are evaluated in order, testing for a condition set that matches the current runtime context. When the first match is found, the corresponding feature table substitution table is used to revise the set of feature tables obtained by default via the LangSys table, as described below (see FeatureTableSubstitution table).

The format of the feature variations table is as follows.

FeatureVariations Table

Type Name Description
uint16 MajorVersion Major version of the FeatureVariations table — set to 1.
uint16 MinorVersion Minor version of the FeatureVariations table — set to 0.
uint32 FeatureVariationRecordCount Number of feature variation records.
FeatureVariationRecord FeatureVariationRecords[FeatureVariationRecordCount] Array of feature variation records.

A feature variation record has offsets to a condition set table and to a feature table substitution table.

If the ConditionSet offset is 0, there is no condition set table. This is treated as the universal condition: all contexts are matched.

If the FeatureTableSubstitution offset is 0, there is no feature table substitution table, and no substitutions are made.

Feature variation records must be ordered in the order of precedence for the condition sets. During processing, the feature variation records will be read, and the corresponding condition sets tested, in the order in which they occur. If the condition set for a given record does not match the runtime context, then the next record is checked. The first feature variation record for which the condition set matches the runtime context will be considered as a candidate: if the version of the FeatureTableSubstitution table is supported, then this feature variation record will be used, and no additional feature variation records will be considered. If the version of the FeatureTableSubtitution table is not supported, then this feature variation record is rejected and processing will move to the next feature variation record.

FeatureVariationRecord

Type Name Description
Offset32 ConditionSet Offset to a condition set table, from beginning of FeatureVariations table.
Offset32 FeatureTableSubstitution Offset to a feature table substitution table, from beginning of the FeatureVariations table.

ConditionSet Table

A condition set table specifies a set of conditions under which a feature table substitution is to be applied. A condition set may specify conditions related to various factors; currently, one type of factor is supported: the variation instance of a variable font. Individual conditions are represented in subtables, which may use different formats according to the nature of the factor defining the condition.

For a given condition set, conditions are conjunctively related (boolean AND): all of the specified conditions must be met in order for the associated feature table substitution to be applied. A condition set does not need to specify conditional values for all possible factors. If no values are specified for some factor, then the condition set matches all runtime values for that factor.

If a given condition set contains no conditions, then it matches all contexts, and the associated feature table substitution is always applied, unless there was a FeatureVariation record earlier in the array with a condition set matching the current context.

ConditionSet Table

Type Name Description
uint16 ConditionCount Number of conditions for this condition set.
Offset32 ConditionTable[ConditionCount] Array of offsets to condition tables, from beginning of the ConditionSet table.

Condition Table

The condition table describes a particular condition. Different formats for the condition table may be defined, with each format used for a particular kind of condition qualifier. Currently, one format is defined: ConditionTableFormat1, which is used to specify a value range for a variation axis value in a variable font.

New condition table formats for other condition qualifiers may be added in the future. If a layout engine encounters a condition table with an unrecognized format, it should fail to match the condition set, but continue to test other condition sets. In this way, new condition formats can be defined and used in fonts that can work in a backward-compatible way in existing implementations.

Condition Table Format 1: Font Variation Axis Range

A font variation axis range condition refers to a range of values for a design variation axis in a variable font. The axes of variation are specified in the font variations ('fvar') table of a font. If a format 1 condition table is used, there must be an fvar table in the font, and the AxisIndex value (which is zero-based) must be less than the axisCount value in the fvar table. If the AxisIndex is invalid, the feature variation record containing this condition table is ignored.

A format 1 condition table specifies a matching range of variation instance values along a single axis. Absence of a format 1 condition for a given variation axis implies that that axis is not a factor in determining applicability of the condition set.

The fvar table defines a range of valid values for each variation axis. During processing for a particular variation instance, a normalization process is applied that maps user values in the range defined within the fvar table to a normalized scale with a range from -1 to 1. The values specified in a format 1 condition table are expressed in terms of the normalized scale, and so can be any value from -1 to 1.

A font variation axis range condition is met if the currently-selected variation instance has a value for the given axis that is greater than or equal to the FilterRangeMinValue, and that is less than or equal to the FilterRangeMaxValue.

ConditionTableFormat1

Type Name Description
uint16 Format Format, = 1
uint16 AxisIndex Index (zero-based) for the variation axis within the 'fvar' table.
F2DOT14 FilterRangeMinValue Minimum value of the font variation instances that satisfy this condition.
F2DOT14 FilterRangeMaxValue Maximum value of the font variation instances that satisfy this condition.

FeatureTableSubstitution Table

A feature table substitution table describes a set of feature table substitutions to be applied when the corresponding condition set matches the current runtime context. These substitutions are represented using an array of feature table substitution records. Each record gives a simple substitution of one feature table for another. When checking for a particular feature index, the first record having that index is matched, and searching ends if a record is encountered with a higher index value.

Note that the records must be ordered in increasing order of the FeatureIndex values, and no two records may have the same FeatureIndex value.

FeatureTableSubstitution table:

Type Name Description
uint16 MajorVersion Major version of the feature table substitution table — set to 1
uint16 MinorVersion Minor version of the feature table substitution table — set to 0.
uint16 SubstitutionCount Number of feature table substitution records.
FeatureTableSubstitutionRecord Substitutions[SubstitutionCount] Array of feature table substitution records.

FeatureTableSubstitutionRecord:

Type Name Description
uint16 FeatureIndex The feature table index to match.
Offset32 AlternateFeatureTable Offset to an alternate feature table, from start of the FeatureTableSubstitution table.

As described above, condition sets are evaluated and may be selected for processing of the associated feature table substitution table to replace a default feature table obtained from a LangSys table with an alternate feature table. Given a default array of feature tables for selected features obtained from the LangSys table, substitution of alternate feature tables can be done as follows:

  1. For each feature index, evaluate the FeatureTableSubstitutionRecords in order.
  2. If a matching record is encountered (FeatureIndex = the current feature index), then replace the feature table for that feature index using the alternate feature table at the offset given in the record. Stop processing for that feature index.
  3. If a record is encountered with a higher feature index value, stop searching for that feature index; no substitution is made.

Common Table Examples

The rest of this chapter describes and illustrates examples of all the common table formats. All the examples reflect unique parameters, but the samples provide a useful reference for building tables specific to other situations.

The examples have three columns showing hex data, source, and comments.

Example 1: ScriptList Table and ScriptRecords

Example 1 illustrates a ScriptList table and ScriptRecord definitions for a Japanese font with multiple scripts: Han Ideographic, Kana, and Latin. Each script has script-specific behavior.

Example 1

Hex Data Source Comment
  ScriptList
TheScriptList
ScriptList table definintion
0003 3 ScriptCount
ScriptRecord[0],in alphabetical order by ScriptTag
68616E69 “hani” ScriptTag, Han Ideographic script
0014 HanIScriptTable offset to Script table
ScriptRecord[1]
6B616E61 “kana” ScriptTag, Hiragana and Katakana scripts
0018 KanaScriptTable offset to Script table
ScriptRecord[2]
6C61746E “latn” ScriptTag, Latin script
001C LatinScriptTable offset to Script table

Example 2: Script Table, LangSysRecord, and LangSys Table

Example 2 illustrates the Script table, LangSysRecord, and LangSys table definitions for the Arabic script and the Urdu language system. The default LangSys table defines three default Arabic script features used to replace certain glyphs in words with their proper initial, medial, and final glyph forms. These contextual substitutions are invariant and occur in all language systems that use the Arabic script.

Many alternative glyphs in the Arabic script have language-specific uses. For instance, the Arabic, Farsi, and Urdu language systems use different glyphs for numerals. To maintain character-set compatibility, the Unicode standard includes separate character codes for the Arabic and Farsi numeral glyphs. However, the standard uses the same character codes for Farsi and Urdu numerals, even though three of the Urdu glyphs (4, 6, and 7) differ from the Farsi glyphs. To access and display the proper glyphs for the Urdu numerals, users of the text-processing client must enter the character codes for the Farsi numerals. Then the text-processing client uses a required OpenType Layout glyph substitution feature, defined in the Urdu LangSys table, to access the correct Urdu glyphs for the 4, 6, and 7 numerals.

Note that the Urdu LangSys table repeats the default script features. This repetition is necessary because the Urdu language system also uses alternative glyphs in the initial, medial, and final glyph positions in words.

Example 2

Hex Data Source Comment
  Script
ArabicScriptTable
Script table definition
000A DefLangSys offset to DefaultLangSys table
0001 1 LangSysCount LangSysRecord[0], in alphabetical order by LangSysTag
55524420 “URD ” LangSysTag, Urdu language
0016 UrduLangSys offset to LangSys table for Urdu
  LangSys
DefLangSys
default LangSys table definition
0000 NULL LookupOrder, reserved, null
FFFF 0xFFFF ReqFeatureIndex, no required features
0003 3 FeatureCount
0000 0 FeatureIndex[0], in arbitrary order
“init” feature (initial glyph)
0001 1 FeatureIndex[1], “fina” feature (final glyph)
0002 2 FeatureIndex[2], for “medi” feature (medial glyph)
  LangSys
UrduLangSys
LangSys table definition
0000 NULL LookupOrder, reserved, null
0003 3 ReqFeatureIndex, numeral subsitution in Urdu
0003 3 FeatureCount
0000 0 FeatureIndex[0], in arbitrary order
“init” feature (initial glyph)
0001 1 FeatureIndex[1], “fina” feature (final glyph)
0002 2 FeatureIndex[2], “medi” feature (medial glyph)

Example 3: FeatureList Table and Feature Table

Example 3 shows the FeatureList and Feature table definitions for ligatures in the Latin script. The FeatureList has three features, all optional and named “liga.” One feature, also a default, implements ligatures in Latin if no language-specific feature specifies other ligatures. Two other features implement ligatures in the Turkish and German languages, respectively.

Three lookups define glyph substitutions for rendering ligatures in this font. The first lookup produces the “ffi” and “fi” ligatures; the second produces the “ffl,” “fl,” and “ff” ligatures; and the third produces the eszet ligature.

The ligatures that begin with an “f” are separated into two sets because Turkish has a dotless “i” glyph and so does not use “ffi” and “fi” ligatures. However, Turkish does use the “ffl,” “fl,” and “ff” ligatures, and the TurkishLigatures feature table lists this one lookup.

Only the German language system uses the eszet ligature, so the GermanLigatures feature table includes a lookup for rendering that ligature.

Because the Latin script can use both sets of ligatures, the DefaultLigatures feature table defines two LookupList indices: one for the “ffi” and “fi” ligatures, and one for the “ffl,” “fl,” and “ff” ligatures. If the text-processing client selects this feature, then the font applies both lookups.

Note that the TurkishLigatures and DefaultLigatures feature tables both list a LookupListIndex of one (1) for the “ffl,” “fl,” and “ff” ligatures lookup. This is because language-specific lookups override all default language-system lookups, and a language-system feature table must explicitly list all lookups that apply to the language.

Example 3

Hex Data Source Comment
  FeatureList
TheFeatureList
FeatureList table definition
0003 3 FeatureCount
FeatureRecord[0]
6C696761 “liga” FeatureTag
0014 TurkishLigatures offset to Feature table, FflFfFlLiga FeatureRecord[1]
6C696761 “liga” FeatureTag
001A DefaultLigatures offset to Feature table, FfiFiLiga, FflFfFlLiga FeatureRecord[2]
6C696761 “liga” FeatureTag
0022 GermanLigatures offset to Feature table, EszetLiga
  Feature
TurkishLigatures
Feature table definition
0000 NULL FeatureParams, reserved, null
0001 1 LookupCount
0000 1 LookupListIndex[1], ffl, fl, ff ligature substitution Lookup
  Feature
DefaultLigatures
Feature table definition
0000 NULL FeatureParams - reserved, null
0002 2 LookupCount
0000 0 LookupListIndex[0], in arbitrary order, ffi, fi ligatures
0001 1 LookupListIndex[1], ffl, fl, ff ligature substitution Lookup
  Feature
GermanLigatures
Feature table definition
0000 NULL FeatureParams - reserved, null
0001 3 LookupCount
0000 0 LookupListIndex[0], in arbitrary order, ffi, fi ligatures
0001 1 LookupListIndex[1], ffl, fl, ff ligature substitution Lookup
0002 2 LookupListIndex[2], eszet ligature substitution Lookup

Example 4: LookupList Table and Lookup Table

A continuation of Example 3, Example 4 shows three ligature lookups in the LookupList table. The first generates the “ffi” and “fi” ligatures; the second produces the “ffl,” “fl,” and “ff” ligatures; and the third generates the eszet ligature. Each lookup table defines an offset to a subtable that contains data for the ligature substitution.

Example 4

Hex Data Source Comment
  LookupList
TheLookupList
LookupList table definition
0003 3 LookupCount
0008 FfiFiLookup offset to Lookup[0] table, in design order
0010 FflFlFfLookup offset to Lookup[1] table
0018 EszetLookup offset to Lookup[2] table
  Lookup
FfiFiLookup
Lookup[0] table definition
0004 4 LookupType, ligature subst
000C 0x000C LookupFlag, IgnoreLigatures, IgnoreMarks
0001 1 SubTableCount
0018 FfiFiSubtable offset to FfiFi ligature substitution subtable
  Lookup
FflFlFfLookup
Lookup[1] table definition
0004 4 LookupType
ligature subst
000C 0x000C LookupFlag- IgnoreLigatures, IgnoreMarks
0001 1 SubTableCount
0028 FflFlFfSubtable offset to FflFlFf ligature substitution subtable
  Lookup
EszetLookup
Lookup[2] table definition
0004 4 LookupType- ligature subst
000C 0x000C LookupFlag- IgnoreLigatures, IgnoreMarks
0001 1 SubTableCount
0038 EszetSubtable offset to Eszet ligature substitution subtable

Example 5: CoverageFormat1 Table (glyph ID List)

Example 5 illustrates a Coverage table that lists the glyph IDs of all lowercase descender glyphs in a font. The table uses the list format instead of the range format because the glyph IDs for the descender glyphs are not consecutively ordered.

Example 5

Hex Data Source Comment
  CoverageFormat1
DescenderCoverage
Coverage table definition
0001 1 CoverageFormat lists
0005 5 GlyphCount
0038 gGlyphID GlyphArray[0], in glyph ID order
003B jGlyphID GlyphArray[1]
0041 pGlyphID GlyphArray[2]
0042 qGlyphID GlyphArray[3]
004A yGlyphID GlyphArray[4]

Example 6: CoverageFormat2 Table (glyph ID Ranges)

Example 6 shows a Coverage table that defines ten numeral glyphs (0 through 9). The table uses the range format instead of the list format because the glyph IDs are ordered consecutively in the font. The StartCoverageIndex of zero (0) indicates that the first glyph ID, for the zero glyph, returns a Coverage Index of 0. The second glyph ID, for the numeral one (1) glyph, returns a Coverage Index of 1, and so on.

Example 6

Hex Data Source Comment
  CoverageFormat2
NumeralCoverage
Coverage table definition
0002 2 CoverageFormat, glyph ID ranges
0001 1 RangeCount
RangeRecord[0]
004E 0glyphID StartGlyphID
0057 9glyphID EndGlyphID
0000 0 StartCoverageIndex, first CoverageIndex = 0

Example 7: ClassDefFormat1 Table (Class Array)

The ClassDef table in Example 7 assigns class values to the lowercase glyphs in a font. The x-height glyphs are in Class 0, the ascender glyphs are in Class 1, and the descender glyphs are in Class 2. The array begins with the index for the lowercase “a” glyph.

Example 7

Hex Data Source Comment
  ClassDefFormat1
LowercaseClassDef
ClassDef table definition
0001 1 ClassFormat
0032 aGlyphID StartGlyph
001A 26 GlyphCount
0000 0 aGlyph, Xheight Class 0
0001 1 bGlyph, Ascender Class 1
0000 0 cGlyph, Xheight Class 0
0001 1 dGlyph, Ascender Class 1
0000 0 eGlyph, Xheight Class 0
0001 1 fGlyph, Ascender Class 1
0002 2 gGlyph, Descender Class 2
0001 1 hGlyph, Ascender Class 1
0000 0 iGlyph, Ascender Class 1
0002 2 jGlyph, Descender Class 2
0001 1 kGlyph, Ascender Class 1
0001 1 lGlyph, Ascender Class 1
0000 0 mGlyph, Xheight Class 0
0000 0 nGlyph, Xheight Class 0
0000 0 oGlyph, Xheight Class 0
0002 2 pGlyph, Descender Class 2
0002 2 qGlyph, Descender Class 2
0000 0 rGlyph, Xheight Class 0
0000 0 sGlyph, Xheight Class 0
0001 1 tGlyph, Ascender Class 1
0000 0 uGlyph, Xheight Class 0
0000 0 vGlyph, Xheight Class 0
0000 0 wGlyph, Xheight Class 0
0000 0 xGlyph, Xheight Class 0
0002 2 yGlyph, Descender Class 2
0000 0 zGlyph, Xheight Class 0

Example 8: ClassDefFormat2 Table (Class Ranges)

In Example 8, the ClassDef table assigns class values to four types of glyphs in the Arabic script: medium-height base glyphs, high base glyphs, very high base glyphs, and default mark glyphs. The table lists only Class 1, Class 2, and Class 3; all glyphs not explicitly assigned a class fall into Class 0.

The table uses the range format because the glyph IDs in each class are ordered consecutively in the font. In the ClassRange array, ClassRange definitions are ordered by the Start glyph index in each range. The indices of the high base glyphs, defined in ClassRange[0], are first in the font and have a class value of 2. ClassRange[1] defines all the very high base glyphs and assigns a class value of 3. ClassRange[2] contains all default mark glyphs; the class value is 1. Class 0 consists of all the medium-height base glyphs, which are not explicitly assigned a class value.

Example 8

Hex Data Source Comment
  ClassDefFormat2
GlyphHeightClassDef
Class table definition
0002 2 Class Format ranges
0003 3 ClassRangeCount
ClassRange[0], ordered by StartGlyphID
0030 tahGlyphID Start
first glyph ID in the range
0031 dhahGlyphID End
Last glyph ID in the range
0002 2 Class, high base glyphs, ClassRange[1]
0040 cafGlyphID Start, first glyph ID in the range
0041 gafGlyphID End, Last glyph ID in the range
0003 3 Class, very high base glyphs, ClassRange[2]
00D2 fathatanDefaultGlyphID Start, first glyph ID in the range
00D3 dammatanDefaultGlyphID End, Last glyph ID in the range
0001 1 Class
default marks

Example 9: Device Table

Example 9 defines the minimum extent value for a math script, using a Device table to adjust the value according to the size of the output font. Here, the Device table defines single-pixel adjustments for font sizes from 11 ppem to 15 ppem. The DeltaFormat is 1, which signifies a packed array of signed 2-bit values, eight values per uint16.

Example 9

Hex Data Source Comment
  DeviceTableFormat1
MinCoordDeviceTable
Device Table definition
000B 11 StartSize, 11 ppem
000F 15 EndSize, 15 ppem
0001 1 DeltaFormat
signed 2 bit value, 8 values
per uint16
  1 increase 11ppem by 1 pixel
  1 increase 12ppem by 1 pixel
  1 increase 13ppem by 1 pixel
  1 increase 14ppem by 1 pixel
5540 1 increase 15ppem by 1 pixel