WARNING
The 'mort'
table is deprecated. It is supported on OS X but not iOS, and Apple font tools no longer will generate 'mort'
. New and udpated fonts should use 'morx'
tables.
Introduction
The 'mort'
) allows you to specify a set of transformations that can apply to the glyphs of your font. These transformations, called
Apple has defined a standard set of text features. You may include one or more of these or create your own text features. Font features that will be supported by your font must be part of the Font Feature Registry maintained by Apple Computer, Inc. Some of the feature types that have been registered follow:
- Ligatures
- Cursive connection
- Letter case
- Vertical substitution
- Linguistic rearrangement
- Number spacing
- Smart swashes
- Diacritics
- Vertical Position
- Fractions
- Overlapping characters
- Typographic extras
- Mathematical extras
- Ornament sets
- Character alternatives
- Design complexity
- Style options
- Character shape
- Number case
- Letter spacing
Glyph Metamorphosis Table Format
The glyph metamorphosis table consists of a header followed by one or more metamorphosis chains. Each
The glyph metamorphosis table header specifies the current version and the number of metamorphosis chains provided in the table. The format of the glyph metamorphosis table header is:
Type
|
Name
|
Description
|
---|---|---|
fixed32 | version | Version number of the glyph metamorphosis table (0x00010000 for the current version). |
uint32 | nChains | Number of metamorphosis chains contained in this table. |
One or more glyph metamorphosis chains follow the table header. Each metamorphosis chain starts on a longword boundary. Padding must be added between chains to ensure that the next chain starts at a byte offset evenly divisible by 4. Each chain contains a chain header, feature table arrays, and metamorphosis subtables. The metamorphosis subtables specify a set of atomic transformations. When these transformations are applied to the glyph array in proper order, the text is processed to provide the specified text features.
The format of the chain header is:
Type
|
Name
|
Description
|
---|---|---|
uint32 | defaultFlags | The default sub-feature flags for this chain. |
uint32 | chainLength | The length of the chain in bytes, including this header. |
uint16 | nFeatureEntries | The number of entries in the chain's feature subtable. |
uint16 | nSubtables | The number of subtables in the chain. |
A single metamorphosis chain is usually sufficient, unless the font's features cannot be specified with 32 sub-features. The chain's header is followed by the feature table, which is an array of feature entries. The number of entries in the feature table is given by the value of the nFeatureEntries
field in the chain's header.
Feature Table
The
The format of the feature table is:
Type
|
Name
|
Description
|
---|---|---|
uint16 | featureType | The type of feature. |
uint16 | featureSetting | The feature's setting. |
uint32 | enableFlags | Flags for the settings that this feature and setting enables. |
uint32 | disableFlags | Complement of flags for the settings that this feature and setting disable. |
During text processing, the following sequence takes place.
- The result is initialized to the chain's
defaultFlags
. - The entries in the feature table are processed in order. If the setting is in the requested list, the result is ANDed with the entry's
disableFlags
and ORed with the entry'senableFlags
. If the setting is not in the requested list, the result will be the chain'sdefaultFlags
. ThedefaultFlags
specify sub-features that will happen in the absence of any user specification. - When the request is finished, the result contains the sub-feature flags corresponding to the list of requested features.
The order of entries in the requested feature list is arbitrary. However, the order of entries in the feature table is important. Entries that are located later in the feature table take precedence over earlier entries. This is necessary because only the font designer knows the relationship between the features and the subfeatures.
Each feature table must end with an entry for the Enable Glyph Effects feature with the setting enableEffectOffSelector
. This turns off all subfeature flags for the chain. Enable and disable flags for the last entry in the feature table are:
Enable flag
|
Disable flag
|
---|---|
0x00000000 | 0x00000000 (complement of 0xFFFFFFFF) |
Metamorphosis Subtables
After the feature table come the metamorphosis subtables. These chain subtables describe the atomic transformations that make up the chain's sub-features. These transformations are the heart of the glyph metamorphosis table. Each metamorphosis chain subtable consists of a subtable header followed by one or more metamorphosis subtables. The subtable types are given in the following table:
Subtable type
|
Description
|
---|---|
0 | Indic-style rearrangement. |
1 | Contextual glyph substitution. |
2 | Ligature substitution. |
3 | (Reserved) |
4 | Non-contextual glyph substitution. |
5 | Contextual glyph insertion |
The common subtable header is followed by a subheader. The format of the subheader varies according to the subtable type.
A chain's subtables must have lengths that are multiples of 4 bytes. If subtable lengths are not multiples of 4 bytes, you should add padding spaces at the end.
Although each atomic transformation has its own format, each subtable begins with a common header, called a MorphSubtableHeader
, which has this format:
Type
|
Name
|
Description
|
---|---|---|
uint16 | length | Length of subtable in bytes, including this header. |
uint16 | coverage | Coverage flags and atomic transformation type. |
uint32 | subFeatureFlags | Flags for the settings that this subtable describes. |
The bits in the coverage field have the interpretation shown in the following table and figure:
Mask value
|
Interpretation
|
---|---|
0x8000 | If set to 1, this subtable should be applied only to vertical text. If set to 0, this subtable should be applied only to horizontal text. Note that the 0x2000 bit can change how this bit gets interpreted. |
0x4000 | If set to 1, this subtable should process the glyph array in descending order. If set to 0, this subtable should process the glyph array in ascending order. |
0x2000 | If set to 1, this subtable should be applied irrespective of the state of the 0x8000 bit. This allows you to make subtables that will be executed irrespective of the orientation of the text. If this bit is 0, the 0x8000 bit is interpreted as described above. Support for this bit is available starting with GX 1.1; earlier versions of the software will ignore it. |
0x1FF8 | These bits are reserved and must be set to 0. |
0x0007 | These bits specify the subtable type (using the constants listed above). |
The subFeatureFlags
field of the chain subtable header has a bit set for each sub-feature whose transformation requires the atomic transformation specified by the subtable. After a user request, feature subtables are searched to determine which tables are needed. Then, the result is compared with this field. If any bits are common and are non-zero, the table is enabled.
For example, if the result is 0x00010001 and the subFeatureFlags
field of this subtable contains 0x00000001, this table is enabled.
Indic Rearrangement Subtable
An Indic-style rearrangement action specifies a rearrangement of the order of a contiguous range of glyphs in the glyph array.
The format of the Indic rearrangement subtable is shown in the following figure. Note that the whole subtable is just a state table.
Type
|
Name
|
Description
|
---|---|---|
StateHeader | stHeader | The Indic rearrangement state table header. |
The actions in an Indic rearrangement subtable use no per-glyph tables. The table-specific flags in the flags field of the entry subtable have the following format:
Mask value
|
Name
|
Interpretation
|
---|---|---|
0x8000 | markFirst | If set, make the current glyph the first glyph to be rearranged. |
0x4000 | dontAdvance | If set, don't advance to the next glyph before going to the new state. |
0x2000 | markLast | If set, make the current glyph the last glyph to be rearranged. |
0x1FF0 | reserved | These bits are reserved and should be set to 0. |
0x000F | verb | The type of rearrangement specified. |
The positions of the bits in the flags binary field are shown in the following figure:
The following table shows the rearrangement verb atomic transformations. The uppercase letters 'A', 'B', 'C', and 'D' represent individual glyphs, and 'x' represents an arbitrary sequence of glyphs. You use the markFirst
and markLast
flags to remember the array of glyphs to be rearranged. The first and last glyph values are set before the rearrangement specified by the value of the verb field is applied.
Verb
|
Results
|
---|---|
0 | no change |
1 | Ax => xA |
2 | xD => Dx |
3 | AxD => DxA |
4 | ABx => xAB |
5 | ABx => xBA |
6 | xCD => CDx |
7 | xCD => DCx |
8 | AxCD => CDxA |
9 | AxCD => DCxA |
10 | ABxD => DxAB |
11 | ABxD => DxBA |
12 | ABxCD => CDxAB |
13 | ABxCD => CDxBA |
14 | ABxCD => DCxAB |
15 | ABxCD => DCxBA |
Contextual Glyph Substitution Subtable
Contextual glyph substitution is the substitution of other glyphs for both the glyph at the current position in the glyph array and an earlier glyph in the glyph array, called thesetMark
flag is set, the current glyph is made the marked glyph after the substitutions are made.
You could use the contextual glyph substitution subtable to create simple ligatures, such as 'fi' and 'Æ,' or for unusual substitutions such as: % + zero = per-mille. If you want to create ligatures that are more complex than two-character ligatures from the separate characters, you should use the ligature substitution subtable. However, if the font contains component ligatures with glyph indices, then more complex ligatures can be formed using contextual glyph substitution. For example, if the 'ff' ligature is in the font, then the 'ffi' ligature can be formed using a contextual substitution subtable.
The format of the contextual glyph substitution subtable is as follows.
Type
|
Name
|
Description
|
---|---|---|
StateHeader | stHeader | The contextual glyph substitution state table header |
uint16 | substitutionTable | Byte offset from the beginning of the state subtable to the beginning of the substitution tables. |
The actions in a contextual glyph substitution subtable have table- specific flags and two offsets to per-glyph tables (for a total of 4 16-bit words). The format of these actions is as follows:
Type
|
Name
|
Description
|
---|---|---|
uint16 | newState | Byte offset from the beginning of the state table to the new state. |
uint16 | flags | Table-specific flags. |
uint16 | markOffset | Word offset from the beginning of the state subtable to the substitution table for the marked glyph. |
uint16 | currentOffset | Word offset from the beginning of the state subtable to the substitution table for the current glyph. |
The following figure shows the positions of the bits in the flags binary field of the contextual glyph substitution subtable.
The format of the table-specific flags
field is as follows:
Mask value
|
Name
|
Interpretation
|
---|---|---|
0x8000 | setMark | If set, make the current glyph the marked glyph. |
0x4000 | dontAdvance | If set, don't advance to the next glyph before going to the new state. |
0x3FFF | reserved | These bits are reserved and should be set to 0. |
Ligature Substitution Subtable
The ligature substitution subtable specifies the substitution of a ligature glyph for a set of component glyphs. For example, you can specify that when the glyphs 'f,' 'f,' and 'i' are placed next to one another, the separate glyphs will be replaced by the ligature glyph 'ffi.' If you want to create simple two-character ligatures, you should use the contextual substitution subtable rather than the ligature substitution table, which is designed for more complex ligature formations (although you may certainly use the ligature substitution subtable for two-glyph ligatures, if you wish).
The format of the ligature substitution subtable is as follows:
Type
|
Name
|
Description
|
---|---|---|
StateHeader | stHeader | The ligature substitution state table header. |
uint16 | ligActionTable | Byte offset from the beginning of the state table to the ligature action lists. |
uint16 | componentTable | Byte offset from the beginning of the state table to the component offset tables. |
uint16 | ligatureTable | Byte offset from the beginning of the state table to the beginning of the ligature tables. |
The format of the flag field of the ligature substitution subtable actions is shown in the following figure. There are no per-glyph substitutions.
The ligature action list specifies how to use the component glyphs to construct a word offset into a table of ligature glyph indices. The table is sorted by components; that is, first by the first component, then by the second component, and so on.
The ligature component stack is 16 deep. This means that a ligature can be formed using a maximum of 16 components. If the value of the offset
field is non-zero, it gives the offset to a list of 32-bit ligature actions. The offset
field, which is the offset to the ligature action list, is a table-specific flag field. Its format is shown in the following table (and the above illustration):
Mask value
|
Name
|
Interpretation
|
---|---|---|
0x8000 | setComponent | If set, AAT should make the current glyph a ligature component. |
0x4000 | dontAdvance | If set, AAT should not advance to the next glyph before moving to the new state. |
0x3FFF | offset | Byte offset from beginning of subtable to the ligature action list. This value must be a multiple of 4. |
The ligature action list must be long aligned. One entry in this list is shown in the following figure:
The mask values of the ligature action list are given in the following table:
Mask value
|
Name
|
Interpretation
|
---|---|---|
0x80000000 | last | If set, this is the last action in the list and implies store. |
0x40000000 | store | If set, substitute the ligature for the marked glyph. |
0x3FFFFFFF | offset | Word offset from beginning of state table to component offset table. |
Usually a ligature action list forms only one ligature, so the store
flag is not set for any entry. Multiple ligatures may be formed by setting the store
flag on intermediate entries in the action list. The only limit is that the component stack can hold only 16 components.
The offset into the ligature table is computed as the sum of the offsets for each component. One offset needs to include the offset to the ligature table.
Each entry in the ligature action list contains the offset to a per-glyph table that gives the offset for the corresponding component. Given an offset to the first ligature in the table starting with a particular set of components, the component offset table for the next component would contain the relative offsets to the first ligature containing the particular component.
As each entry in the action list is processed, the corresponding component is popped from the stack. If the store
and last
flags in the entry are clear, the component glyph is replaced by the deleted glyph index; if the store
or last
flag is set, the accumulated offset is used to fetch the glyph index for the ligature, which replaces the component glyph. You can form an n-component ligature by replacing the component glyphs with the ligature glyph followed by n-1 deleted glyphs. For example, if you use the ligature substitution subtable to form the 'ffi' ligature, you begin with 'f', 'f', and 'i' and end up with 'ffi' and two deleted glyphs.
When the entire ligature action list has been processed, the position of each ligature glyph in the glyph array is pushed onto the component stack again so that the ligatures can be used as components of other ligatures. For example, an 'ff' ligature can be used in an 'ffi' ligature.
For example, the next figure shows a ligature table for a fictional set of ligatures composed of 'a,' 'b,' or 'c' followed by 'd,' 'e,' or 'f' followed by 'g,' 'h,' or 'i'. Keep in mind that what you should actually store in the ligature table at the various offsets is the glyph index for the ligature, and not the data for the ligature itself.
The offset into the ligature table is computed as the sum of the offsets for each component. Each entry in the ligature action list contains the offset to a per-glyph table that gives the offset in bytes for the corresponding component.
Once you know the glyphs that make up a particular ligature, you can construct a component offset table for calculating the offsets to the glyph index for that ligature. Using the ligature table in the previous figure, you can construct the table for the offsets for the components of the various ligatures.
Given an offset to the first ligature in the table starting with a particular set of components, the component offset table for the next component would contain the relative offsets to the first ligature containing the particular component. The offset into the ligature table is computed as the sum of the offsets for each component. Each entry in the ligature action list contains the offset to a per-glyph table which gives the offset for the corresponding component. The glyph offsets for this example are shown in the following table:
Glyph
|
Offset
|
---|---|
a | 1000 |
b | 1018 |
c | 1036 |
d | 0 |
e | 6 |
f | 12 |
g | 0 |
h | 2 |
i | 4 |
Using this table, you find that the relative offsets for 'bfh' is 1018 + 12 + 2 = 1032, and the relative offset for 'aei' is 1000 + 6 + 4 = 1010. This byte offset is relative to the beginning of the ligature table.
To produce an offset relative to the beginning of the state subtable, you need to add the offset of the ligature table to the values of one of the component offset tables.
Non-contextual Glyph Substitution Subtable
The non-contextual glyph substitution subtable is a lookup table that maps a single glyph index into another glyph index. The format of the non-contextual glyph substitution subtable is given in the following table:
Type
|
Name
|
Description
|
---|---|---|
LookupTable | table | The noncontextual glyph substitution table |
Glyph Insertion Subtable
A new kind of metamorphosis subtable, one that implements insertion actions, is available starting with GX 1.1. This subtable permits extra glyphs (which have no corresponding characters in the backing store) to be inserted into a layout shape. There are two kinds of insertion actions available:
Kashida-like insertion actions, where one or more glyphs are appended to a particular glyph, and are selected with that glyph. An example is Pig Latin, where the "ay" or "way" are inserted after the relevant letters. During justification, the width of the "baseform" will be augmented by the width of the all the insertions, and the caret split will encompass the whole grouping. This is very similar to how kashidas currently work (hence the name).
Split-vowel-like insertion actions, where glyphs are appended to a given glyph (as in the kashida-like case), but where the inserted glyph(s) do not select with that glyph, but rather with some other glyph. Burmese split vowels are an example of this kind of insertion.
A single subtable can mix and match these kinds of actions as needed.
The subtable consists solely of a state table (similar to the Indic rearrangement subtable). The actions are 8 bytes long, as follows:
Type
|
Name
|
Description
|
---|---|---|
uint16 | newState | Byte offset from the beginning of the state table to the new state. |
uint16 | flags | The action flags (defined below). |
uint16 | currentInsertList | Byte offset from the beginning of the state table to the list of 16-bit glyphcodes to be inserted at the current glyph (or none if zero). The number of glyphs to be inserted is contained in the currentInsertCount field in the flags (see below). |
uint16 | markedInsertList | Byte offset from the beginning of the state table to the list of 16-bit glyphcodes to be inserted at the marked glyph (or none if zero). The number of glyphs to be inserted is contained in the markedInsertCount field in the flags (see below). |
The flag bits are interpreted as follows:
Mask value
|
Name
|
Interpretation
|
---|---|---|
0x8000 | setMark | If set, mark the current glyph. |
0x4000 | dontAdvance | If set, don't advance to the next glyph before going to the new state. |
0x2000 | currentIsKashidaLike | If set, and the currentInsertList is nonzero, then the specified glyph list will be inserted as a kashida-like insertion, either before or after the current glyph (depending on the state of the currentInsertBefore flag). If clear, and the currentInsertList is nonzero, then the specified glyph list will be inserted as a split-vowel-like insertion, either before or after the current glyph (depending on the state of the currentInsertBefore flag). |
0x1000 | markedIsKashidaLike | If set, and the markedInsertList is nonzero, then the specified glyph list will be inserted as a kashida-like insertion, either before or after the marked glyph (depending on the state of the markedInsertBefore flag). If clear, and the markedInsertList is nonzero, then the specified glyph list will be inserted as a split-vowel-like insertion, either before or after the marked glyph (depending on the state of the markedInsertBefore flag). |
0x0800 | currentInsertBefore | If set, specifies that insertions are to be made to the left of the current glyph. If clear, they're made to the right of the current glyph. |
0x0400 | markedInsertBefore | If set, specifies that insertions are to be made to the left of the marked glyph. If clear, they're made to the right of the marked glyph. |
0x03E0 | currentInsertCount | This 5-bit field is treated as a count of the number of glyphs to insert at the current position. Since zero means no insertions, the largest number of insertions at any given current location is 31 glyphs. |
0x001F | markedInsertCount | This 5-bit field is treated as a count of the number of glyphs to insert at the marked position. Since zero means no insertions, the largest number of insertions at any given marked location is 31 glyphs. |
Special split-vowel considerations
The connection between the two pieces of a split vowel is established via the distance from the current to the marked glyph. For example, say a split vowel character occurs after a consonant, and once encountered, the first part of the split vowel should be inserted before that consonant. In building the insertion subtable to do this, you would set a mark at every candidate consonant. Then, if a split vowel is indeed encountered after the consonant, it would have the markedIsKashidaLike
flag off and the markedInsertBefore
flag on. The split vowel piece would then be inserted before the consonant, and AAT will establish the connection between the two pieces, such that a selection of one piece, say, will result in both pieces being highlighted (because they are both associated with the same character offset, namely the offset of the vowel character that came after the consonant).
Alternatively, in this example, you could set the subtable to process in reverse order (using the appropriate bit in the coverage
field), and then the vowel would be the first thing encountered, so your subtable would be set up to mark the vowel, and then after moving to the consonant, do the insertion before the current glyph (i.e. before the consonant). Either of these methods works; the choice of which is most suited for a given font is left to the font designer.
Glyph Metamorphosis Table Examples
Example: Non-contextual Glyph Substitution
Let's create a Roman font that accommodates horizontal and vertical text. We will specifically address the problem that occurs when horizontal text with opening and closing parentheses is used vertically. When the text is horizontal, our font should use the horizontal opening and closing parentheses (glyph indices 11 and 12, respectively). When the text is vertical, our font should use the vertical opening and closing parentheses (glyph indices 135 and 136, respectively).
This figure shows a sample of text produced with this example font.
To accommodate this design, our font must contain the features and settings given in the following table. This will require one glyph metamorphosis chain composed of three feature subtables and a metamorphosis subtable. The constants associated with particular feature types and selectors (such as 4 for vertical substitution) are located in the current edition of the Font Feature Registry.
Feature
|
Setting
|
Enable flag
|
Disable flag
|
---|---|---|---|
Vertical substitution | On | 0x00000001 | 0xFFFFFFFF |
Vertical substitution | Off | 0x00000000 | 0xFFFFFFFE |
Glyph effects | Off | 0x00000000 | 0x00000000 |
The glyph metamorphosis table for this example font is this:
Offset/
length |
Value
|
Name
|
Comment
|
---|---|---|---|
0/4 | 0x00010000 | version | Version number of the glyph metamorphosis table, in fixed- point format. |
4/4 | 1 | nChains | Number of metamorphosis chains contained in this table is 1. |
(The single metamorphosis chain follows) | |||
8/4 | 1 | defaultFlags | Default setting flag for this chain is 1. |
12/4 | 80 | chainLength | Chain length is 88 - 8 = 80 bytes. |
16/2 | 3 | nFeatureEntries | Number of entries in the chain's feature subtable is 3. |
18/2 | 1 | nSubtables | The number of feature subtables in this chain is 1. |
(The first of three entries in the feature subtable array follows) | |||
20/2 | 4 | featureType | Feature type is vertical substitution. |
22/2 | 0 | featureSetting | Feature setting is on. |
24/4 | 0x00000001 | enableFlags | Enable flag. |
28/4 | 0xFFFFFFFF | disableFlags | Disable flag. |
(The second of three entries in the feature subtable array follows) | |||
32/2 | 4 | featureType | Feature type is vertical substitution. |
34/2 | 1 | featureSetting | Feature setting is off. |
36/4 | 0x00000000 | enableFlags | Enable flag. |
40/4 | 0xFFFFFFFE | disableFlags | Disable flag. |
(The third of three entries in the feature subtable array follows) | |||
44/2 | 0 | featureType | Feature type is glyph effects. |
46/2 | 1 | featureSetting | Feature setting is off. |
48/4 | 0x00000000 | enableFlags | Last enableFlags field of the feature subtable must contain 0x00000000. |
52/4 | 0x00000000 | disableFlags | Last disableFlags field of the feature subtable must contain 0x00000000. |
(The chain subtable follows) | |||
56/2 | 32 | length | Length of the chain subtable is 88 - 56 = 32 bytes. |
58/2 | 0x8004 | coverage | 0x8000 value indicates that this subtable should be applied only to horizontal text. The 0x0004 value indicates that the chain subtable type is for non-contextual glyph substitution. |
60/4 | 0x00000001 | subFeatureFlags | Subfeature type is contextual glyph substitution. |
(The non-contextual glyph substitution lookup table follows) | |||
64/2 | 6 | format | Lookup table format 6 (single table format). |
66/2 | 4 | unitSize | Size of a LookupSingle record (2 bytes for the glyph index, and 2 bytes for the offset from the start of this ligature caret table). |
68/2 | 2 | nUnits | Number of units of the preceding unitSize to be searched. There are two glyphs to be included in the table. |
70/2 | 8 | searchRange | The unitSize times the largest power of two that is less than or equal to nUnits. |
72/2 | 1 | entrySelector | The log base 2 of the largest power of two less than or equal to nUnits. |
74/2 | 0 | rangeShift | The unitSize times the difference of nUnits minus the largest power of two less than or equal to nUnits. |
(The LookupSingle record entries start here) | |||
76/2 | 11 | glyphIndex | Glyph index for the opening horizontal parenthesis '(' is 11. |
78/2 | 135 | glyphIndex | Glyph index for the opening vertical parenthesis is 135. |
80/2 | 12 | glyphIndex | Glyph index for the closing horizontal parenthesis ')' is 12. |
82/2 | 136 | glyphIndex | Glyph index for the closing vertical parenthesis is 136. |
(This is the special guardian LookupSingle record) | |||
84/2 | 0xFFFF | glyph | Guardian value. |
86/2 | 0 | value | Guardian value. |
Example: Hierarchical Ligature Tables
Suppose you want to set up a font with all four settings of the ligature formation text feature: mandatory, normal, optional, and suppress. Because this text feature shares subfeatures, you can describe these subfeatures on the same chain.
When a subtable is enabled, it activates the subtables beneath it in the hierarchy. Therefore, you can have each subtable describe a different set of ligatures. For example, in this font the Mandatory subtable describes the 'fi' and 'fl' ligatures, the normal subtable describes the 'æ' and 'œ' ligatures, and the optional subtable describes the 'Æ' and 'Œ' ligatures. Whenever the user selects the normal ligatures of this font, the ligatures of the mandatory and normal subtables are available. When the user selects optional ligatures, the ligatures of the mandatory, normal, and optional subtables are available. The suppress subtable cancels the use of all ligatures.
This table describes the feature subtable entries for these subtables:
Setting
|
Enable flags
|
Disable flags
|
---|---|---|
Mandatory | 0x00000001 | 0xFFFFFFF9 (complement of 0x00000006) |
Normal | 0x00000003 | 0xFFFFFFFB (complement of 0x00000004) |
Optional | 0x00000007 | 0xFFFFFFFF (complement of 0x00000000) |
Suppress | 0x00000000 | 0xFFFFFFF8 (complement of 0x00000007) |
The enable flags of the mandatory setting are only for that subtable, and its disable flags deactivate the normal and optional tables. The enable flags of the normal setting activate both the normal and mandatory tables, and its disable flags disable only the optional table. The enable flags of the optional table activate all tables, and its disable flags do not disable any table. The enable flags of the suppress table do not enable any table, and its disable flags deactivate all tables.
For example, if you use the feature table in the above table, there are three subtables: one with subFeatureFlags
set to 0x00000001 for the mandatory ligatures, one with subFeatureFlags
set to 0x00000002 for the normal ligatures that aren't mandatory, and one with subFeatureFlags
set to 0x00000004 for optional ligatures that are neither mandatory or normal. Thus, the mandatory subtable is applied if the ligature formation setting is mandatory, normal, or optional; the normal subtable is applied if the ligature formation setting is normal or optional, and the optional subtable is applied if the ligature formation setting is optional.
Example: Stand-Alone Ligature Tables
In the previous example, each setting of the ligature formation text feature builds on the contents of the previous ligature subtable. A request for optional ligatures means that three subtables are applied.
However, if you make each ligature subtable independent of the others, only one subtable is applied when the user requests a particular type of ligature. Although you have to duplicate the ligature information (putting the glyph codes to create the 'fi' ligature into every table, for instance), table access is faster because only one table is used. You can setup the feature subtable so that a request for one ligature formation subtable disables all other ligature subtables, such as in the following table:
Setting
|
Enable flags
|
Disable flags
|
---|---|---|
Mandatory | 0x00000001 | 0xFFFFFFF9 (complement of 0x00000006) |
Normal | 0x00000002 | 0xFFFFFFFA (complement of 0x00000005) |
Optional | 0x00000004 | 0xFFFFFFFC (complement of 0x00000003) |
Suppress | 0x00000000 | 0xFFFFFFF8 (complement of 0x00000007) |
Any ligature formation request results in the setting of a single subfeature flag for the requested setting with the highest precedence.
Again, there are three subtables: one with the subFeatureFlags
field of its subtable header set to 0x00000001 for the mandatory ligatures; one with subFeatureFlags
set to 0x00000002 for the mandatory and normal ligatures; and one with subFeatureFlags
set to 0x00000004 for mandatory, normal, and optional ligatures.
The normal and optional subtables are more complex (because the normal subtable duplicates the ligatures in the mandatory subtable and the optional subtable duplicates the ligatures in the normal subtable), but at most one subtable is applied to the glyph array, which takes less time than applying three subtables.
You can also use this feature table with the subtables from the example by changing their subFeatureFlags
to 0x00000007, 0x00000006, and 0x00000004, respectively.
Platform-specific Information
The 'mort'
table is not supported on any version of iOS. It is supported on all versions of OS X, but its use is strongly discouraged. If a font has both a 'mort'
table and a 'morx'
(extended metamorphosis) table, the 'mort'
table is ignored.
Tools
'mort'
tables are dumped (but not fused) by ftxdumperfuser. Dumping to both MIF and ATIF is supported. ftxenhancer does not generate 'mort'
tables.