MathML Operator Mirroring Explainer

HTML RTL mirroring

Modern browsers support two mirroring techniques when rendering RTL text:

  1. Character-level via Unicode. For example LEFT PARENTHESIS U+0028 becomes RIGHT PARENTHESIS U+0029.
  2. Glyph-level mirroring via the rtlm OpenType feature. This requires special font such as the xits-math.otf font used in this page. For example SQUARE ROOT U+221A has glyph name uni221A in that font, for which the rtlm mirrored form is the glyph called uni221A.rtlm.
Description Mirroring English (LTR) Arabic (RTL)
HTML character-level via Unicode (1, 2] (١، ٢]
glyph-level mirroring via rtlm 3÷4 ٣÷٤

MathML operator stretching

Modern browsers support two special rendering modes for MathML operators. This requires special fonts with an OpenType MATH table such as the xits-math.otf font used in this page.

Description Attributes English (LTR)
Normal text layout <mo stretchy="false" largeop="false"> ( C ]
Stretchy operator <mo stretchy="true"> ( 1 2 3 4 ]
Large operator <mo largeop="true"> C

RTL math mirroring (issue #67)

Arabic mathematical notations require rendering math operator in right-to-left mode. This works when operators uses normal text layout. But when shaping a stretchy glyph or drawing a large operator, MathML Core does not define how to perform the mirroring. Some browsers (e.g. Firefox) are able to perform glyph-level/character-level mirroring of MathML operators.

Firefox can even mirror via a "negative" scale transform (reflection with respect to a vertical axis). This provides a fallback technique for math fonts that don't provide rtlm variants, but does not work for things like clockwise integrals where the semantic would be modified by such a transform.

Description Mirroring English (LTR) Arabic (RTL)
MathML <mo stretchy="false"> character-level mirroring via Unicode ( 1 , 2 ] ( ١ ، ٢ ]
MathML <mo stretchy="true"> { 5 6 ) { ٥ ٦ )
MathML <mo largeop="true"> glyph-level mirroring via rtlm C ج
MathML msqrt 3 4 ٣ ٤

MathML Core amendment

Currently for <mo> element is made of a single character c, steps 2 and 3 of layout of operators determine the glyph corresponding to a given character c, and uses that glyph as an input to the MathVariant tables in order to obtain a larger glyph or a glyph assembly. The same is done for the radical symbol of the <msqrt> and <mroot> elements, using character U+221A SQUARE ROOT.

The proposal is simply to amend these steps, so that the input glyph is instead obtain by one of the HTML RTL mirroring techniques (Character-level via Unicode or Glyph-level mirroring) from the character c.

The proposed approach should work with the XITS fonts and is equivalent to what is implemented by Firefox. Internally, Firefox actually shapes the character c in RTL mode and then extracts the glyph from the output shape buffer.

Harry Chen's pull request: Add support for character-level and glyph-level mirroring of RTL operators #277