Mathematical formulas are complex text objects in which multiple elements with various metric, style or positioning attributes are combined. In order for a math handling engine to support layout of mathematical formulas, several types of font-specific information particular to the layout of formulas are required. The MATH table format defines data structures for font-specific information necessary for math formula layout.
General structure of math formulas is hierarchical, with formulas composed of smaller sub-formula components, where each sub-formula may be composed of even simpler sub-formulas, and so on down to individual characters, e.g. letters or numbers.
Example of a complex hierarchical math formula and the diagram showing the pieces of metal type and spacing materials used in a traditional printing application
Likewise, process of math formula layout is also recursive. Child components are formatted first and then arranged to form their parent’s layout with this process repeated on every level starting from simplest blocks up to the whole formula. Each sub-formula has its own component structure and rules for how to perform layout. For example, fraction consists of nominator and denominator sub-formulas, which will be placed on top one another with fraction rule separating them. Integral contains integral sign, optional upper and lower limits, and following integral expression (which are all sub-formulas).
Math formula layout rules are quite different from text substitution and positioning rules expressed in tables like GSUB and GPOS. Regular glyph runs have full context font layout tables can operate on, so actions like contextual substitution or kerning can be expressed in terms of known glyph sequences. For math formula, virtually any component can be a complex formula as well.
Math handling engine works with boxes representing individual formula components as units of layout. During layout process individual boxes can be arranged relative to each other, stretched depending on sizes of sibling boxes, or use different glyph variants based on box size and position in the formula.
MATH table provides font-specific information about font and individual glyphs that math handling engine uses to produce formula layout that matches font design and realizes full font potential by using available glyph stylistic alternates and stretching variants.
Shared Table: MathValueRecord
MATH subtables use MathValueRecord to describe values, in font design units, that place or adjust elements of math formulas. A MathValueRecord may also specify an offset to a device table which provides corrections to this value at particular display resolutions.
When designing a MATH table, device tables may be specified for many values used for positioning elements of a formula, suggesting many device corrections. However, a math handling engine may not permit those corrections to accumulate. This accumulation will result in formula dimensions that are significantly different from scaled-down dimensions of the same formula rendered on a high-resolution device. Therefore, accumulation is undesirable and leads to inconsistencies between screen and print versions, as well as possible clipping.
To maintain consistency across devices with different resolutions, only limited device corrections are permitted. When too many device corrections are called for, some of these corrections may be cancelled by a math handling engine. Because of that, it is suggested that the format 1 is used for the device table referenced by a MathValueRecord. This format allows the font designer to specify corrections of -2, -1, 0, and 1 pixels. The recommended values to use in MathValueRecords are -1, 0, or 1.
|int16||Value||The X or Y value in design units|
|Offset16||DeviceTable||Offset to the device table – from the beginning of parent table. May be NULL. Suggested format for device table is 1.|
MATH Table Header
The MATH table begins with a header that consists of a version number for the table (Version), which is currently set to 1.0 (0x00010000), and specified offsets to the following tables that store information on positioning of math formula elements:
Math Header Table
|uint16||MajorVersion||Major version of the MATH table, = 1.|
|uint16||MinorVersion||Minor version of the MATH table, = 0.|
|Offset16||MathConstants||Offset to MathConstants table - from the beginning of MATH table.|
|Offset16||MathGlyphInfo||Offset to MathGlyphInfo table - from the beginning of MATH table.|
|Offset16||MathVariants||Offset to MathVariants table - from the beginning of MATH table.|
The MathConstants table defines miscellaneous constants required to properly position elements of mathematical formulas. These constants belong to several groups of semantically related values such as values needed to properly position accents, values for positioning superscripts and subscripts, and values for positioning elements of fractions. The table also contains general use constants that may affect all parts of the formula, such as axis height and math leading. Note that most of the constants deal with the vertical positioning.
In most cases, values in the MathConstants table are assumed to be positive. For example, for descenders and shift down values a positive constant signifies movement in a downwards direction. Most values in the MathConstants table are represented by a MathValueRecord, which allows the font designer to supply device corrections to those values when necessary. For values involving base and dependent elements (e.g. superscripts or limits) value is defined in the font size of the base.
When selecting names for values in the MathConstants table, the following naming convention should be used:
|int16||ScriptPercentScaleDown||Percentage of scaling down for script level 1. Suggested value: 80%.|
|int16||ScriptScriptPercentScaleDown||Percentage of scaling down for script level 2 (ScriptScript). Suggested value: 60%.|
|uint16||DelimitedSubFormulaMinHeight||Minimum height required for a delimited expression to be treated as a sub-formula. Suggested value: normal line height ×1.5.|
|uint16||DisplayOperatorMinHeight||Minimum height of n-ary operators (such as integral and summation) for formulas in display mode.|
|MathValueRecord||MathLeading||White space to be left between math formulas to ensure proper line spacing. For example, for applications that treat line gap as a part of line ascender, formulas with ink going above (os2.sTypoAscender + os2.sTypoLineGap - MathLeading) or with ink going below os2.sTypoDescender will result in increasing line height.|
|MathValueRecord||AxisHeight||Axis height of the font.|
|MathValueRecord||AccentBaseHeight||Maximum (ink) height of accent base that does not require raising the accents. Suggested: x‑height of the font (os2.sxHeight) plus any possible overshots.|
|MathValueRecord||FlattenedAccentBaseHeight||Maximum (ink) height of accent base that does not require flattening the accents. Suggested: cap height of the font (os2.sCapHeight).|
|MathValueRecord||SubscriptShiftDown||The standard shift down applied to subscript elements. Positive for moving in the downward direction. Suggested: os2.ySubscriptYOffset.|
|MathValueRecord||SubscriptTopMax||Maximum allowed height of the (ink) top of subscripts that does not require moving subscripts further down. Suggested: 4/5 x- height.|
|MathValueRecord||SubscriptBaselineDropMin||Minimum allowed drop of the baseline of subscripts relative to the (ink) bottom of the base. Checked for bases that are treated as a box or extended shape. Positive for subscript baseline dropped below the base bottom.|
|MathValueRecord||SuperscriptShiftUp||Standard shift up applied to superscript elements. Suggested: os2.ySuperscriptYOffset.|
|MathValueRecord||SuperscriptShiftUpCramped||Standard shift of superscripts relative to the base, in cramped style.|
|MathValueRecord||SuperscriptBottomMin||Minimum allowed height of the (ink) bottom of superscripts that does not require moving subscripts further up. Suggested: ¼ x-height.|
|MathValueRecord||SuperscriptBaselineDropMax||Maximum allowed drop of the baseline of superscripts relative to the (ink) top of the base. Checked for bases that are treated as a box or extended shape. Positive for superscript baseline below the base top.|
|MathValueRecord||SubSuperscriptGapMin||Minimum gap between the superscript and subscript ink. Suggested: 4×default rule thickness.|
|MathValueRecord||SuperscriptBottomMaxWith Subscript||The maximum level to which the (ink) bottom of superscript can be pushed to increase the gap between superscript and subscript, before subscript starts being moved down. Suggested: 4/5 x-height.|
|MathValueRecord||SpaceAfterScript||Extra white space to be added after each subscript and superscript. Suggested: 0.5pt for a 12 pt font.|
|MathValueRecord||UpperLimitGapMin||Minimum gap between the (ink) bottom of the upper limit, and the (ink) top of the base operator.|
|MathValueRecord||UpperLimitBaselineRiseMin||Minimum distance between baseline of upper limit and (ink) top of the base operator.|
|MathValueRecord||LowerLimitGapMin||Minimum gap between (ink) top of the lower limit, and (ink) bottom of the base operator.|
|MathValueRecord||LowerLimitBaselineDropMin||Minimum distance between baseline of the lower limit and (ink) bottom of the base operator.|
|MathValueRecord||StackTopShiftUp||Standard shift up applied to the top element of a stack.|
|MathValueRecord||StackTopDisplayStyleShiftUp||Standard shift up applied to the top element of a stack in display style.|
|MathValueRecord||StackBottomShiftDown||Standard shift down applied to the bottom element of a stack. Positive for moving in the downward direction.|
|MathValueRecord||StackBottomDisplayStyleShiftDown||Standard shift down applied to the bottom element of a stack in display style. Positive for moving in the downward direction.|
|MathValueRecord||StackGapMin||Minimum gap between (ink) bottom of the top element of a stack, and the (ink) top of the bottom element. Suggested: 3×default rule thickness.|
|MathValueRecord||StackDisplayStyleGapMin||Minimum gap between (ink) bottom of the top element of a stack, and the (ink) top of the bottom element in display style. Suggested: 7×default rule thickness.|
|MathValueRecord||StretchStackTopShiftUp||Standard shift up applied to the top element of the stretch stack.|
|MathValueRecord||StretchStackBottomShiftDown||Standard shift down applied to the bottom element of the stretch stack. Positive for moving in the downward direction.|
|MathValueRecord||StretchStackGapAboveMin||Minimum gap between the ink of the stretched element, and the (ink) bottom of the element above. Suggested: UpperLimitGapMin.|
|MathValueRecord||StretchStackGapBelowMin||Minimum gap between the ink of the stretched element, and the (ink) top of the element below. Suggested: LowerLimitGapMin.|
|MathValueRecord||FractionNumeratorShiftUp||Standard shift up applied to the numerator.|
|MathValueRecord||FractionNumeratorDisplayStyle ShiftUp||Standard shift up applied to the numerator in display style. Suggested: StackTopDisplayStyleShiftUp.|
|MathValueRecord||FractionDenominatorShiftDown||Standard shift down applied to the denominator. Positive for moving in the downward direction.|
|MathValueRecord||FractionDenominatorDisplay StyleShiftDown||Standard shift down applied to the denominator in display style. Positive for moving in the downward direction. Suggested: StackBottomDisplayStyleShiftDown.|
|MathValueRecord||FractionNumeratorGapMin||Minimum tolerated gap between the (ink) bottom of the numerator and the ink of the fraction bar. Suggested: default rule thickness.|
|MathValueRecord||FractionNumDisplayStyle GapMin||Minimum tolerated gap between the (ink) bottom of the numerator and the ink of the fraction bar in display style. Suggested: 3×default rule thickness.|
|MathValueRecord||FractionRuleThickness||Thickness of the fraction bar. Suggested: default rule thickness.|
|MathValueRecord||FractionDenominatorGapMin||Minimum tolerated gap between the (ink) top of the denominator and the ink of the fraction bar. Suggested: default rule thickness.|
|MathValueRecord||FractionDenomDisplayStyleGap Min||Minimum tolerated gap between the (ink) top of the denominator and the ink of the fraction bar in display style. Suggested: 3×default rule thickness.|
|MathValueRecord||SkewedFractionHorizontalGap||Horizontal distance between the top and bottom elements of a skewed fraction.|
|MathValueRecord||SkewedFractionVerticalGap||Vertical distance between the ink of the top and bottom elements of a skewed fraction.|
|MathValueRecord||OverbarVerticalGap||Distance between the overbar and the (ink) top of he base. Suggested: 3×default rule thickness.|
|MathValueRecord||OverbarRuleThickness||Thickness of overbar. Suggested: default rule thickness.|
|MathValueRecord||OverbarExtraAscender||Extra white space reserved above the overbar. Suggested: default rule thickness.|
|MathValueRecord||UnderbarVerticalGap||Distance between underbar and (ink) bottom of the base. Suggested: 3×default rule thickness.|
|MathValueRecord||UnderbarRuleThickness||Thickness of underbar. Suggested: default rule thickness.|
|MathValueRecord||UnderbarExtraDescender||Extra white space reserved below the underbar. Always positive. Suggested: default rule thickness.|
|MathValueRecord||RadicalVerticalGap||Space between the (ink) top of the expression and the bar over it. Suggested: 1¼ default rule thickness.|
|MathValueRecord||RadicalDisplayStyleVerticalGap||Space between the (ink) top of the expression and the bar over it. Suggested: default rule thickness + ¼ x-height.|
|MathValueRecord||RadicalRuleThickness||Thickness of the radical rule. This is the thickness of the rule in designed or constructed radical signs. Suggested: default rule thickness.|
|MathValueRecord||RadicalExtraAscender||Extra white space reserved above the radical. Suggested: RadicalRuleThickness.|
|MathValueRecord||RadicalKernBeforeDegree||Extra horizontal kern before the degree of a radical, if such is present.|
|MathValueRecord||RadicalKernAfterDegree||Negative kern after the degree of a radical, if such is present. Suggested: −10/18 of em.|
|int16||RadicalDegreeBottomRaise Percent||Height of the bottom of the radical degree, if such is present, in proportion to the ascender of the radical sign. Suggested: 60%.|
The MathGlyphInfo table contains positioning information that is defined on per-glyph basis. The table consists of the following parts:
NOTE: Here, and elsewhere in the subclause – please refer to subclause 6.2.4 "Features and Lookups" for description of the coverage table formats.
|Offset16||MathItalicsCorrectionInfo||Offset to MathItalicsCorrectionInfo table - from the beginning of MathGlyphInfo table.|
|Offset16||MathTopAccentAttachment||Offset to MathTopAccentAttachment table - from the beginning of MathGlyphInfo table.|
|Offset16||ExtendedShapeCoverage||Offset to coverage table for Extended Shape glyphs - from the beginning of MathGlyphInfo table. When the left or right glyph of a box is an extended shape variant, the (ink) box (and not the default position defined by values in MathConstants table) should be used for vertical positioning purposes. May be NULL..|
|Offset16||MathKernInfo||Offset to MathKernInfo table - from the beginning of MathGlyphInfo table.|
The MathItalicsCorrectionInfo table contains italics correction values for slanted glyphs used in math typesetting. The table consists of the following parts:
Italics correction can be used in the following situations:
|Offset16||Coverage||Offset to Coverage table - from the beginning of MathItalicsCorrectionInfo table.|
|uint16||ItalicsCorrectionCount||Number of italics correction values. Should coincide with the number of covered glyphs.|
|MathValueRecord||ItalicsCorrection [ItalicsCorrectionCount]||Array of MathValueRecords defining italics correction values for each covered glyph.|
The MathTopAccentAttachment table contains information on horizontal positioning of top math accents. The table consists of the following parts:
|Offset16||TopAccentCoverage||Offset to Coverage table - from the beginning of MathTopAccentAttachment table.|
|uint16||TopAccentAttachmentCount||Number of top accent attachment point values. Should coincide with the number of covered glyphs.|
|MathValueRecord||TopAccentAttachment [TopAccentAttachmentCount]||Array of MathValueRecords defining top accent attachment points for each covered glyph.|
The glyphs covered by this table are to be considered extended shapes. These glyphs are variants extended in the vertical direction, e.g., to match height of another part of the formula. Because their dimensions may be very large in comparison with normal glyphs in the glyph set, the standard positioning algorithms will not produce the best results when applied to them. In the vertical direction, other formula elements will be positioned not relative to those glyphs, but instead to the ink box of the subexpression containing them.
For example, consider a fraction enclosed in parentheses with a superscript. Notice how the superscripts on ‘z’ and ‘Z’ are also aligned vertically, although they have different heights. If the right parenthesis was not considered an extended shape, the superscript would be put in position aligned with any other superscript on the line, like this:
Because this is undesirable, the right parenthesis in this case should be considered an extended shape, resulting in superscript positioned relative to the whole subexpression:
The MathKernInfo table provides information on glyphs for which mathematical (height-dependent) kerning values are defined. It consists of the following fields:
|Offset16||MathKernCoverage||Offset to Coverage table - from the beginning of the MathKernInfo table.|
|uint16||MathKernCount||Number of MathKernInfoRecords.|
|MathKernInfoRecord||MathKernInfoRecords [MathKernCount]||Array of MathKernInfoRecords, per-glyph information for mathematical positioning of subscripts and superscripts.|
Each MathKernInfoRecord points to up to four kern tables for each of the corners around the glyph.
|Offset16||TopRightMathKern||Offset to MathKern table for top right corner - from the beginning of MathKernInfo table. May be NULL.|
|Offset16||TopLeftMathKern||Offset to MathKern table for the top left corner - from the beginning of MathKernInfo table. May be NULL.|
|Offset16||BottomRightMathKern||Offset to MathKern table for bottom right corner - from the beginning of MathKernInfo table. May be NULL.|
|Offset16||BottomLeftMathKern||Offset to MathKern table for bottom left corner - from the beginning of MathKernInfo table. May be NULL.|
The MathKern table contains adjustments to horizontal positions of subscripts and superscripts. The purpose of this table is to improve spacing in situations such as or . The kerning algorithm consists of the following steps:
Example of horizontal and vertical kerning adjustments for superscript positioning.
Kern value corresponding to a particular height from the MathKern table is determined by finding two consecutive indexes in the CorrectionHeight array so that the value of the correction height at hand falls between the two heights found at those indexes. The KernValue array entry corresponding to the larger index gives the sought value. If the correction height is less than all heights in the table, the first value (index 0) should be used. For a height that is greater than all heights in the table, the last entry should be used.
|uint16||HeightCount||Number of heights on which the kern value changes.|
|MathValueRecord||CorrectionHeight[HeightCount]||Array of correction heights at which the kern value changes. Sorted by the height value in design units.|
|MathValueRecord||KernValue[HeightCount+1]||Array of kern values corresponding to heights.
First value is the kern value for all heights less or equal than the first height in this table.
Last value is the value to be applied for all heights greater than the last height in this table.
Negative values are interpreted as "move glyphs closer to each other".
The MathVariants table solves the following problem: given a particular default glyph shape and a certain width or height, find a variant shape glyph (or construct created by putting several glyph together) that has the required measurement. This functionality is needed for growing the parentheses to match the height of the expression within, growing the radical sign to match the height of the expression under the radical, stretching accents like tilde when they are put over several characters, for stretching arrows, horizontal curly braces, and so forth.
The MathVariants table consists of the following fields:
|uint16||MinConnectorOverlap||Minimum overlap of connecting glyphs during glyph construction, in design units.|
|Offset16||VertGlyphCoverage||Offset to Coverage table - from the beginning of MathVariants table.|
|Offset16||HorizGlyphCoverage||Offset to Coverage table - from the beginning of MathVariants table.|
|uint16||VertGlyphCount||Number of glyphs for which information is provided for vertically growing variants.|
|uint16||HorizGlyphCount||Number of glyphs for which information is provided for horizontally growing variants.|
|Offset16||VertGlyphConstruction [VertGlyphCount]||Array of offsets to MathGlyphConstruction tables - from the beginning of the MathVariants table, for shapes growing in vertical direction.|
|Offset16||HorizGlyphConstruction [HorizGlyphCount]||Array of offsets to MathGlyphConstruction tables - from the beginning of the MathVariants table, for shapes growing in horizontal direction.|
The MathGlyphConstruction table provides information on finding or assembling extended variants for one particular glyph. It can be used for shapes that grow in both horizontal and vertical directions.
The first entry is the offset to the GlyphAssembly table that specifies how the shape for this glyph can be assembled from parts found in the glyph set of the font. If no such assembly exists, this offset will be set to NULL.
The MathGlyphConstruction table also contains the count and array of ready-made glyph variants for the specified glyph. Each variant consists of the glyph index and this glyph’s measurement in the direction of extension (vertical or horizontal).
Note that it is quite possible that both the GlyphAssembly table and some variants are defined for a particular glyph. For example, the font may specify several variants for curly braces of different sizes, and a general mechanism of how larger versions of curly braces can be constructed by stacking parts found in the glyph set. First attempt is made to find glyph among provided variants. However, if the required size is bigger than all glyph variants provided, the general mechanism can be employed to typeset the curly braces as a glyph assembly.
|Offset16||GlyphAssembly||Offset to GlyphAssembly table for this shape - from the beginning of MathGlyphConstruction table. May be NULL.|
|uint16||VariantCount||Count of glyph growing variants for this glyph.|
|MathGlyphVariantRecord||MathGlyphVariantRecord [VariantCount]||MathGlyphVariantRecords for alternative variants of the glyphs.|
|uint16||VariantGlyph||Glyph ID for the variant.|
|uint16||AdvanceMeasurement||Advance width/height, in design units, of the variant, in the direction of requested glyph extension.|
The GlyphAssembly table specifies how the shape for a particular glyph can be constructed from parts found in the glyph set. The table defines the italics correction of the resulting assembly, and a number of parts that have to be put together to form the required shape.
|MathValueRecord||ItalicsCorrection||Italics correction of this GlyphAssembly. Should not depend on the assembly size.|
|uint16||PartCount||Number of parts in this assembly.|
|GlyphPartRecord||PartRecords[PartCount]||Array of part records, from left to right and bottom to top.|
The result of the assembly process is an array of glyphs with an offset specified for each of those glyphs. When drawn consecutively at those offsets, the glyphs should combine correctly and produce the required shape.
The offsets in the direction of growth (advance offsets), as well as the number of parts labeled as extenders, are determined based on the size requirement for the resulting assembly.
Note that the glyphs comprising the assembly should be designed so that they align properly in the direction that is orthogonal to the direction of growth.
Thus, a GlyphPartRecord consists of the following fields:
Size of Assembly = Offset of the Last Part + Full Advance of the Last Part
To ensure that the width/height is distributed equally and the symmetry of the shape is preserved, following steps can be used by math handling client.
Note that for assemblies growing in vertical direction, the distribution of height or the result between ascent and descent is not defined. The math handling client is responsible for positioning the resulting assembly relative to the baseline.
|uint16||Glyph||Glyph ID for the part.|
|uint16||StartConnectorLength||Advance width/ height of the straight bar connector material, in design units, is at the beginning of the glyph, in the direction of the extension.|
|uint16||EndConnectorLength||Advance width/ height of the straight bar connector material, in design units, is at the end of the glyph, in the direction of the extension.|
|uint16||FullAdvance||Full advance width/height for this part, in the direction of the extension. In design units.|
|uint16||PartFlags||Part qualifiers. PartFlags enumeration currently uses only one bit:
0x0001 fExtender If set, the part can be skipped or repeated.
The following tags are being used by math handling engine to access a particular set of glyph varioants. For detailed description of the feature tags see subclause 220.127.116.11.
OpenType tags for math processing
|math||Script tag to be used with the MATH table features. The only language system supported with this tag is the default.|
This feature provides glyph variants adjusted to be more suitable for use in subscripts and superscripts.
These script style forms should not be scaled or moved in the font; scaling and moving them is done by the math handling client. Instead, the ssty feature should provide glyph forms that result in shapes that look good as superscripts and subscripts when scaled and positioned by the Math engine. When designing the script forms, the font developer may assume that MATH.MathConstants.ScriptPercentScaleDown and MATH.MathConstants.ScriptScriptPercentScaleDown will be the scaling factors used by the Math engine.
This feature can have a parameter indicating the script level: 1 for simple subscripts and superscripts, 2 for second level subscripts and superscripts (that is, scripts on scripts), and so on. (Currently, only the first two alternates are used).
For glyphs that are not covered by this feature, the original glyph is used in subscripts and superscripts.
Recommended format: Alternate Substitution table (Single Substitution if there are no second level forms). There should be no context.
|flac||Flattened Accents over Capitals
This feature provides flattened forms of accents to be used over high-rise bases such as capitals.
This feature should only change the shape of the accent and should not move it in the vertical or horizontal direction. Moving of the accents is done by the math handling client.
Accents are flattened by the Math engine if their base is higher than MATH.MathConstants. FlattenedAccentBaseHeight.
Recommended format: Single Substitution table. There should be no context.
This feature provides dotless forms for Math Alphanumeric characters, such as U+1D422 MATHEMATICAL BOLD SMALL I, U+1D423 MATHEMATICAL BOLD SMALL J, U+1D456 U+MATHEMATICAL ITALIC SMALL I, U+1D457 MATHEMATICAL ITALIC SMALL J, and so on.
The dotless forms are to be used as base forms for placing mathematical accents over them.
Recommended format: Single Substitution table. There should be no context.
This page was last updated 22 April 2017.
Comments to the MST group: how to contact us.