The 'morx' Table

General table information

The format for the metamorphosis (‘mort’) table was first designed in 1988. At that time, 680x0 processors were the design center, and memory was comparatively expensive. Because of these constraints, the table format was designed to take as little space as possible, and to use “tricks” which sped up processing. An example of this is the use of even numbers for ‘cmap’ formats: because they were even, the format could be added to a base address directly to compute a jump address.

In a world of hundred-megabyte machines running gigahertz RISC processors, however, this design is anachronistic—and worse, an impediment. Developers wished to create fonts which required more than the original 'mort' table could supply. To this end, an extended glyph metamorphosis table, the 'morx' table, has been introduced.


Table Format

The 'morx' table structure is related to the 'mort' table structure; developers should be familiar with the latter. Because so much is changed within a 'morx' table, however, this new table bumps to version 2.0. However, in order to allow the essentially limitless expansion supported by the current format, we keep the notion of chains.

Unfortunately, Apple's AAT metamorphosis shaping code neglected to check the version in the morph code. This means we could not rely solely on the version, since older versions of ATSUI presented with fonts using version 2 morph tables would choke. This was solved by introducing the new table format. Version checking has been added for the ‘morx’ table, so future versions past version 2 can be dealt with gracefully in older software. Eventually Apple will deprecate the ‘mort’ table.

Table header:

Type
Name
Description
fixed32 version Version number of the extended glyph metamorphosis table (0x00020000 for the current version)
uint32 nChains Number of metamorphosis chains contained in this table.

As with version 1.0 'mort' tables, this header is followed by the chains. Each chain starts with the chain header:

Type
Name
Description
uint32 defaultFlags The default specification for subtables.
uint32 chainLength Total byte count, including this header; must be a multiple of 4.
uint32 nFeatureEntries Number of feature subtable entries.
uint32 nSubtables The number of subtables in the chain.

The feature subtable immediately follows the chain header. It is an array of nFeatureEntries of the following structures:

Type
Name
Description
uint16 featureType The feature type.
uint16 featureSetting The feature selector.
uint32 enableFlags The OR’ed enable flags.
uint32 disableFlags The AND’ed disable flags.

After the feature subtable come the actual subtables, a total of nSubtables of them. Each one starts with a subtable header in this format:

Type
Name
Description
uint32 length Total subtable length, including this header.
uint32 coverage Coverage flags and subtable type.
uint32 subFeatureFlags The 32-bit mask identifying which subtable this is (the subtable being executed if the AND of this value and the processed defaultFlags is nonzero)

The coverage value is interpreted in the following way:

Mask value
Interpretation
0x80000000 If set, this subtable will only be applied to vertical text. If clear, this subtable will only be applied to horizontal text.
0x40000000 If set, this subtable will process glyphs in descending order. If clear, it will process the glyphs in ascending order.
0x20000000 If set, this subtable will be applied to both horizontal and vertical text (i.e. the state of bit 0x80000000 is ignored).
0x1FFFFF00 Reserved, set to zero.
0x000000FF Subtable type; see following table.

The subtable types are defined as follows:

Subtable type
Description
0 Rearrangement subtable.
1 Contextual subtable.
2 Ligature subtable.
3 (Reserved)
4 Noncontextual (“swash”) subtable.
5 Insertion subtable


State tables:

The principal difference in a version 2.0 ‘morx’ table is in the expanded range of the state table and its defining fields. Here is the new definition of the state table header:

Type Name Description
uint32 nClasses Number of classes, which is the number of 16-bit entry indices in a single line in the state array.
uint32 classTableOffset Offset from the start of this state table header to the start of the class table.
uint32 stateArrayOffset Offset from the start of this state table header to the start of the state array.
uint32 entryTableOffset Offset from the start of this state table header to the start of the entry table.

Historically the class table has been a tight array of 8-bit values. However, in certain cases (such as Asian fonts) the potential wide separation between glyph indices covered by the same class table has led to much wasted space in the table. Therefore, the class tables in version 2 ‘morx’ tables are now simply LookupTables, where the looked-up value is a 16-bit class value. Note that a format 8 LookupTable (trimmed array) yields the same results as class array defined in the version 1 ‘mort’ table.

See Apple Advanced Typography Font Tables for a full description of a LookupTable. Note that the current LookupTable definition limits us to 16-bit lookup results (i.e. classes); at some point this may be revised, but 32-bit support is not needed for the scope of the initial ‘morx’ definition.

Another important difference between the old-style and new-style state table is that the entries in the state array are now 16-bit zero-based indices into the entry table, instead of being 8-bit indices. This enormously increases the range and power of state tables using this new format.

The remainder of this section discusses changes to each of the specific subtable types. As a general note, the entries in the entry table here refer to new states not by byte offset but rather by a zero-based 16-bit index. This allows full coverage of even the largest state array we might imagine, subject to the current 16-bit glyph index limitation.

Rearrangement subtables

The rearrangement subtable starts with a new-style state table header, as defined above. There are no additional offset, nor any per-glyph tables.

The interpretation of the rearrangement subtable’s action flags is unchanged. As mentioned above, the reference to the new state is now a zero-based index instead of a byte offset. No additional verbs are defined.

Contextual subtables

The contextual subtable starts with a new-style state table header, as defined above. Immediately after the entryTableOffset is a UInt32 byte offset from the start of the state table header to the start of the per-glyph lookup tables (which are new, and replace the old substitution tables).

Type
Name
Description
uint16 newState Zero-based index to the new state.
uint16 flags Table-specific flags.
uint16 markIndex Index of the substitution table for the marked glyph.
uint16 currentIndex Index of the substitution table for the current glyph.

There are still four 16-bit fields in the entry table’s entry, but their interpretation is somewhat different. As mentioned above, the reference to the new state is now a zero-based index instead of a byte offset. Similarly, what used to be the markOffset and currentOffset fields are now zero-based indices into the set of per-glyph LookupTables whose base offset is the UInt32 following the entryTableOffset, as described above. Since they are no longer offsets they have been renamed to markIndex and currentIndex. If no substitution is to be done, use the value –1.

Replacing the old per-glyph substitution table is a set of LookupTables. A glyph whose action indicates a substitution should happen will specify the index of one of these LookupTables. That glyphcode will be put through the specified LookupTable in order to ascertain the new glyphcode.

In order to speed up the process of locating the LookupTable being indexed, the very start of the per-glyph lookup tables is an array of UInt32 offsets from the start of the per-glyph lookup table space (whose offset itself is the UInt32 after the entryTableOffset, as described above). The markIndex or currentIndex is thus used to first look up the offset in this table, and that offset then allows immediate access to the LookupTable, which is then used to look up the glyphcode.

Note that nowhere is there specified the number of LookupTables. Since this number is an artifact of the font production process, and is not needed by the runtime metamorphosis software, there was no need to include it explicitly.

An example of a ‘morx’ contextual substitution table is included in the Examples section, later in this document.

Ligature subtables

Because the changes to the ligature subtable are a little more extensive, this section will be a little more thorough in documenting the data structures. It will also help the reader to see the examples section at the end of this document.

After the standard subtable header, the ligature subtable starts off with an extended state table header:

Type
Name
Description
STXHeader stateHeader New-style state table header, as described above.
UInt32 ligActionOffset Byte offset from stateHeader to the start of the ligature action table.
UInt32 componentOffset Byte offset from stateHeader to the start of the component table.
UInt32 ligatureOffset Byte offset from stateHeader to the start of the actual ligature lists.

Unlike old-style ‘mort’ tables, the ligature subtable in a ‘morx’ table makes use of the three extra offsets listed here.

The state header is then followed by each of the 7 state table pieces, as specified by their offsets. They may be in any order; for discussion here and in the examples section, we will assume the pieces are in the same order as their offset fields in the state table header.

The class table is just a LookupTable, as described above.

The state array is a two dimensional array of UInt16 indices into the entry table. The rows of the state array correspond to states, and the columns to the classes (the four fixed classes plus the ones specific to this table, for a total of nClasses).

The entry table for a new-style ligature subtable has three UInt16s per entry, instead of two in the old-style subtable:

Type
Name
Description
UInt16 nextStateIndex Row index in the state array for the state which will be used by the next glyph.
UInt16 entryFlags Flags; see below (note a new flag).
UInt16 ligActionIndex Index to the first ligActionTable entry for processing this group, if indicated by the flags.

The flags use the following bits:

Mask value
Name
Interpretation
0x8000 setComponent Push this glyph onto the component stack for eventual processing.
0x4000 dontAdvance Leave the glyph pointer at this glyph for the next iteration.
0x2000 performAction use the ligActionIndex to process a ligature group. Note this flag is new; it was not present in the old-style ‘mort’ table’s ligature subtable
0x3FFF N/A Reserved; set to zero. Note this interpretation is different too; the byte offset which used to be here has been replaced with a full UInt16 index, the ligActionIndex

The ligature action table is next. A key difference between this new ligature subtable format and the old-style one is that the choice of where to start in the table is made by index, not offset, as described above. However, the processing is overall the same: the glyphs which were pushed onto the stack by the entry table flags are now popped off (in reverse order, remember) and acted upon as indicated by the ligature action value. The format of a ligature action is a UInt32, broken up as follows:

Mask value
Name
Interpretation
0x80000000 last This is the last action in the list. This also implies storage.
0x40000000 store Store the ligature at the current cumulated index in the ligature table in place of the marked (i.e. currently-popped) glyph.
0x3FFFFFFF offset A 30-bit value which is sign-extended to 32-bits and added to the glyph ID, resulting in an index into the component table.

If this seems confusing, please see the examples section for an illustration of how this all works.

The component table is an array of UInt16 values which, once looked up as described above, are added together to obtain an index (not an offset!) into the final piece, the actual ligature list.

The ligature list itself is unchanged: an array of output UInt16 ligatures.

Noncontextual subtables

Since no state tables are involved here, there is no change in this format.

Insertion subtables

The insertion subtable starts with a new-style state table header, as defined above. Immediately after the entryTableOffset is a new UInt32 byte offset from the start of the state table header to the start of the insertion glyph table.

There are still four 16-bit fields in the entry table’s entry, but their interpretation is somewhat different. As mentioned above, the reference to the new state is now a zero-based index instead of a byte offset. Similarly, what used to be the markInsertList and currentInsertList fields are now zero-based indices into the insertion glyph table. A value of -1 means no insert list is used.

The interpretation of the insertion subtable’s action flags is unchanged.


Examples

In order to help clarify how the new subtables look, here are some examples.

1. A contextual substitution table

Suppose I have some swash glyphs which I wish to encode in a feature. For input glyphs 50, 51, 201 and 202 I wish to map to swash glyphs 600, 601, 602 and 900, provided the input glyph is preceded by glyph 80. This contextual table would look like this; note that this table is far more compact than an equivalent ‘mort’ table would be, because of the use of LookupTables in two key places:

Offset Value Description
0 5 Number of classes
4 20 Byte offset to class lookup table
8 56 Byte offset to state array
12 92 Byte offset to entry table
16 xxx 16 xxx Byte offset to per-glyph table

*** The class lookup table starts here ***

Offset Value Description
20 6 Lookup table format 6 (single)
22 4 Unit size (4 bytes)
24 5 Number of units
26 16 Search range
28 2 Entry selector
30 4 Range shift
32 50,4 Input glyph 50 maps to class 4
36 51,4 Input glyph 51 maps to class 4
40 80,5 Input glyph 80 maps to class 5
44 201,4 Input glyph 201 maps to class 4
48 202,4 Input glyph 202 maps to class 4
52 -1,1 Guard at end (not counted in nUnits)

*** The state array starts here ***

Offset Value Description
56 0 0 0 0 0 1 The entry table indices for the first row of the state array (start of text), indexed by class
68 0 0 0 0 0 1 The entry table indices for the second row of the state array (start of line), indexed by class
80 0 0 0 0 2 1 The entry table indices for the final row of the state array (saw80 state)

*** The entry table starts here ***

Offset Value Description
92 0 Entry 0: goto state row 0
94 0 Entry 0: no flags
96 -1 Entry 0: no mark substitution
98 -1 Entry 0: no current substitution
100 2 Entry 1: goto state row 2 (saw 80)
102 0 Entry 1: no flags
104 -1 Entry 1: no mark substitution
106 -1 Entry 1: no current substitution
108 0 Entry 2: goto state row 0
110 0 Entry 2: no flags
112 -1 Entry 2: no mark substitution
114 0 Entry 2: Use per-glyph lookup 0

*** The per-glyph lookup tables start here, pad to UInt32 if needed ***

Offset Value Description
116 4 Offset from this point to start of per-glyph lookup 0

*** Per-glyph lookup 0 starts here ***

Offset Value Description
120 6 Lookup table format 6 (single)
122 4 Unit size (4 bytes)
124 4 Number of units
126 16 Search range
128 2 Entry selector
130 0 Range shift
132 50, 600 Input glyph 50 maps to glyph 600
136 51, 601 Input glyph 51 maps to glyph 601
144 201, 602 Input glyph 201 maps to glyph 602
148 202, 900 Input glyph 202 maps to 900
152 -1, 1 Guard at end (not counted in nUnits)


2. A ligature table

Suppose I have this group of ligatures in a font:

adf, adg, adh, adi, aef, aeg, aeh, aei glyphs 1000 – 1007

bdf, bdg, bdh, bdi, bef, beg, beh, bei glyphs 1008 – 1015

cdf, cdg, cdh, cdi, cef, ceg, ceh, cei glyphs 1500 – 1506 and 1511

Notice that the ligatures have ‘a’, ‘b’ or ‘c’ as their first elements, ‘d’ or ‘e’ as their second, and ‘f’, ‘g’, ‘h’ or ‘i’ as their third. Let’s suppose that ‘a’ is glyph 20, ‘b’ glyph 21, and so on through ‘i’ at glyph 28. Let’s see what a ligature subtable to encode these ligatures would look like, starting with the state table header:

Offset Value Description
0 7 Number of classes
4 28 Byte offset to class lookup table
8 64 Byte offset to state array
12 120 Byte offset to entry table
16 144 Byte offset to ligature actions
20 156 Byte offset to component base
24 174 Byte offset to ligature list base

*** The class lookup table starts here ***

Offset Value Description
28 2 Lookup table format 2 (segment single)
30 6 Unit size (6 bytes)
32 3 Number of units
34 12 Search range
36 1 Entry selector
38 6 Range shift
40 22, 20, 4 First segment, mapping glyphs 20 through 22 (‘a’ through ‘c’) to class 4
46 24, 23, 5 Second segment, mapping glyph 23 and 24 (‘d’ and ‘e’) to class 5
52 24, 23, 5 Third segment, mapping glyphs 25 through 28 (‘f’ through ‘i’) to class 6
58 -1, -1, 1 Special guard segment (not counted in nUnits above, note!)

*** The state array starts here ***

Offset Value Description
64 0 0 0 0 1 0 0 The entry table indices for the first row of the state array (start of text), indexed by class
78 0 0 0 0 1 0 0 The entry table indices for the second row of the state array (start of line), indexed by class
92 0 0 0 0 1 2 0 The entry table indices for the third row of the state array (the “saw a, b, or c” state), indexed by class
106 0 0 0 0 1 2 3 The entry table indices for the last row of the state array (the “saw a, b, or c followed by d or e” state), indexed by class

*** The entry table starts here ***

Offset Value Description
120 0 Entry 0: goto state row 0
122 0 Entry 0: no flags
124 0 Entry 0: no 0x2000 flag, so ignore
126 2 Entry 1: goto state row 2
128 0x8000 Entry 1: set a component
130 0 Entry 1: no 0x2000 flag, so ignore
132 3 Entry 2: goto state row 3
134 0x8000 Entry 2: set a component
136 0 Entry 2: no 0x2000 flag, so ignore
138 0 Entry 3: goto state row 0
140 0xA000 Entry 3: set component and act
142 0 Entry 3: Start at ligActions[0]

*** The ligature actions table starts here ***

Offset Value Description
144 0x3FFFFFE7 Action 0, part 1: since ‘f’, ‘g’, ‘h’ or ‘i’ are first popped, add their glyph indices to sign extended lower 30 bits, which is -25. So ‘f’ (glyph 25) plus -25 yields component entry 0; ‘g’ yields 1; ‘h’ yields 2; and ‘i’ yields 3
148 0x3FFFFFED Action 0, part 2: since ‘d’ or ‘e’ are second popped, add their glyph indices to sign-extended lower 30 bits, which is -19. So ‘d’ (glyph 23) plus -19 yields component entry 4; and ‘e’ yields 5
152 0xBFFFFFF2 Action 0, part 3 (last part): since ‘a’, ‘b’ or ‘c’ are last popped, add their glyph indices to sign-extended lower 30 bits, which is -14. So ‘a’ (glyph 20) plus -14 yields component entry 6; ‘b’ yields 7; and ‘c’ yields 8

*** The component table starts here ***

Offset Value Description
156 0 component entry 0
158 1 component entry 1
160 2 component entry 2
162 3 component entry 3
164 0 component entry 4
166 4 component entry 5
168 0 component entry 6
170 8 component entry 7
172 16 component entry 8

*** The ligature table starts here ***

Offset Value Description
174 1000 ligature list[0] -- ‘adf’
176 1001 ligature list[1] -- ‘adg’
178 1002 ligature list[2] -- ‘adh’
180 1003 ligature list[3] -- ‘adi’
182 1004 ligature list[4] -- ‘aef’
184 1005 ligature list[5] -- ‘aeg’
186 1006 ligature list[6] -- ‘aeh’
188 1007 ligature list[7] -- ‘aei’
190 1008 ligature list[8] -- ‘bdf’
192 1009 ligature list[9] -- ‘bdg’
194 1010 ligature list[10] -- ‘bdh’
196 1011 ligature list[11] -- ‘bdi’
198 1012 ligature list[12] -- ‘bef’
200 1013 ligature list[13] -- ‘beg’
202 1014 ligature list[14] -- ‘beh’
204 1015 ligature list[15] -- ‘bei’
206 1500 ligature list[16] -- ‘cdf’
208 1501 ligature list[17] -- ‘cdg’
210 1502 ligature list[18] -- ‘cdh’
212 1503 ligature list[19] -- ‘cdi’
214 1504 ligature list[20] -- ‘cef’
216 1505 ligature list[21] -- ‘ceg’
218 1506 ligature list[22] -- ‘ceh’
220 1511 ligature list[23] -- ‘cei’

174 1000 ligature list[0] -- ‘adf’

176 1001 ligature list[1] -- ‘adg’

178 1002 ligature list[2] -- ‘adh’

180 1003 ligature list[3] -- ‘adi’

182 1004 ligature list[4] -- ‘aef’

184 1005 ligature list[5] -- ‘aeg’

186 1006 ligature list[6] -- ‘aeh’

188 1007 ligature list[7] -- ‘aei’

190 1008 ligature list[8] -- ‘bdf’

192 1009 ligature list[9] -- ‘bdg’

194 1010 ligature list[10] -- ‘bdh’

196 1011 ligature list[11] -- ‘bdi’

198 1012 ligature list[12] -- ‘bef’

200 1013 ligature list[13] -- ‘beg’

202 1014 ligature list[14] -- ‘beh’

204 1015 ligature list[15] -- ‘bei’

206 1500 ligature list[16] -- ‘cdf’

208 1501 ligature list[17] -- ‘cdg’

210 1502 ligature list[18] -- ‘cdh’

212 1503 ligature list[19] -- ‘cdi’

214 1504 ligature list[20] -- ‘cef’

216 1505 ligature list[21] -- ‘ceg’

218 1506 ligature list[22] -- ‘ceh’

220 1511 ligature list[23] -- ‘cei’


Mac OS-specific information

The 'morx' is supported on Mac OS X from its initial release onwards. It is not supported on pre-Mac OS X versions of the Mac OS.

Newton-specific information

The 'morx' table is not used by the Newton OS.

Dependencies

The 'morx' table references to glyph indices; these may need to be updated whenever the glyph count recorded in the 'maxp' table drops.

Tools

Hex editing of the 'morx' table is possible using TrueEdit. There are currently no other tools available to create or edit 'morx' tables.


Change Log

7 November 2000
Initial public version.
applefonts@apple.com

[Table of Contents]

Last updated: JHJ