# Support for MathJax fonts in Mozilla

131 views

### Frédéric WANG

Nov 11, 2011, 9:44:44 AM11/11/11
Hi,

I'm trying to add support for MathJax fonts in Mozilla native MathML. I've tried to guess how the fonts are picked and I've added the general CSS rules:

math {
font-family: MathJax_Math;
}
mn, mo, mtext, ms {
font-family: MathJax_Main;
}
[mathvariant="normal"] {
font-family: MathJax_Math;
}
[mathvariant="double-struck"] {
font-family: MathJax_AMS;
}
[mathvariant="script"],
[mathvariant="bold-script"] {
font-family: MathJax_Script;
}
[mathvariant="fraktur"],
[mathvariant="bold-fraktur"] {
font-family: MathJax_Fraktur;
}
[mathvariant="sans-serif"],
[mathvariant="bold-sans-serif"],
[mathvariant="sans-serif-italic"],
[mathvariant="sans-serif-bold-italic"] {
font-family: MathJax_SansSerif;
}
[mathvariant="monospace"] {
font-family: MathJax_Typewriter;
}

(note that ms is not "monospace" in Mozilla)

I don't know what is the purpose of MathJax_Caligraphic, MathJax_WinChrome, MathJax_WinIE6?

I suppose MathJax_Size* fonts are used to construct stretchy characters. Mozilla can not currently read Open type MATH tables (and I can't find them in the MathJax fonts anyway), so I have to write (or hopefully generate) some tables in Mozilla's own format. Can you please indicate me where those tables are stored in MathJax and which format is used? Thanks.

--
Frédéric Wang.
Website - Weblog

### Frédéric WANG

Nov 11, 2011, 11:47:28 AM11/11/11

> Can you please indicate me where those tables are stored in MathJax
Probably MathJax/jax/output/HTML-CSS/fonts/TeX/

### Davide P. Cervone

Nov 15, 2011, 6:26:54 PM11/15/11
If I understand you correctly, this is for Firefox to use MathJax
fonts for its native MathML renderer without the use of MathJax, right?

> I don't know what is the purpose of MathJax_Caligraphic,
> MathJax_WinChrome, MathJax_WinIE6?

MathJax_Caligraphic is for the TeX \cal font (for which there is no
equivalent in MathML).

MathJax_WinChrome and MathJax_WinIE6 include characters that were not
accessible in those browsers. I should look at Chrome again and see
if that has been improved since I first set up the fonts (there were
only five or six anyway). IE6 had quite a few that it couldn't access.

> I suppose MathJax_Size* fonts are used to construct stretchy
> characters.

MathJax_Size4 contains the partial characters for making stretchy
delimiters (e.g., U+239B through U+23A0). MathJax_Size1 contains the
first size (larger than standard text) of the delimiters,
MathJax_Size2 contains the next larger size, and so on.

> Mozilla can not currently read Open type MATH tables (and I can't
> find them in the MathJax fonts anyway),

MathJax can't access any of the internal font data (JavaScript doesn't
have access to that), so the fonts fon't contain anything like that.
(In any case, I am not a font expert and don't know how to make them
anyway).

> so I have to write (or hopefully generate) some tables in Mozilla's
> own format. Can you please indicate me where those tables are stored
> in MathJax and which format is used? Thanks.

The only data about the fonts is in the unpacked/jax/output/HTML-CSS/
fonts/TeX/fontdata.js file It is in JavaScript objects that are not
in any standard format (they are MathJax internal data). There is a
delimiter array that lists the various sizes available for the
stretchy characters, together with the parts to mark arbitrary sized
ones, when available. You might be able to use that, though it may
not be immediately obvious what everything is. If you want to go that
route, I can try to map it out better for you.

Davide

### Frédéric WANG

Nov 16, 2011, 5:16:23 PM11/16/11
Le 16/11/2011 00:26, Davide P. Cervone a �crit :

> If I understand you correctly, this is for Firefox to use MathJax
> fonts for its native MathML renderer without the use of MathJax, right?
>
Yes, exactly.

> MathJax_Caligraphic is for the TeX \cal font (for which there is no
> equivalent in MathML).
>
> MathJax_WinChrome and MathJax_WinIE6 include characters that were not
> accessible in those browsers. I should look at Chrome again and see
> if that has been improved since I first set up the fonts (there were
> only five or six anyway). IE6 had quite a few that it couldn't access.

OK, so they are probably not needed for my purpose.

> The only data about the fonts is in the

> unpacked/jax/output/HTML-CSS/fonts/TeX/fontdata.js file It is in

> JavaScript objects that are not in any standard format (they are
> MathJax internal data). There is a delimiter array that lists the
> various sizes available for the stretchy characters, together with the
> parts to mark arbitrary sized ones, when available. You might be able
> to use that, though it may not be immediately obvious what everything
> is. If you want to go that route, I can try to map it out better for
> you.

Thank you. In Mozilla the stretchy characters are described that way:

- Top/Left glyph
- Middle glyph
- Bottom Right glyph
- Glue glyph: the one which is repeated to connect the three other
components.
- size0
- size1
- ...
- sizeN

So if I'm trying to guess what the DELIMITERS array is:

- dir is the direction vertical/horizontal (in Mozilla, this is already
stored in the operator dictionary)
- HW: I guess it is some kind of factor to decide which font should be
used with respect to the size we want to stretch? (in Mozilla we can
measure directly the size of the glyphs in fonts, so this is probably
not needed)
- stretch: I can see what are top, bot, mid, left and right. What about
ext/sep? Are they "glue" glyphs in Mozilla's terminology?

### Frédéric WANG

Nov 16, 2011, 5:30:17 PM11/16/11

> Thank you. In Mozilla the stretchy characters are described that way:
>
> - Top/Left glyph
> - Middle glyph
> - Bottom Right glyph
> - Glue glyph: the one which is repeated to connect the three other
> components.
> - size0
> - size1
> - ...
> - sizeN
>
> So if I'm trying to guess what the DELIMITERS array is:
>
> - dir is the direction vertical/horizontal (in Mozilla, this is
> already stored in the operator dictionary)
> - HW: I guess it is some kind of factor to decide which font should be
> used with respect to the size we want to stretch? (in Mozilla we can
> measure directly the size of the glyphs in fonts, so this is probably
> not needed)
> - stretch: I can see what are top, bot, mid, left and right. What
> about ext/sep? Are they "glue" glyphs in Mozilla's terminology?
>
>
I would also like to know where are described the size variants for
large operators, integral symbols etc. I guess I have to pick the
character at the corresponding unicode point in MathJax_Size1,
MathJax_Size2 ... MathJax_Size4. But how do I know which sizes are
available for a given character ? Is it encoded in a table somewhere or
are there always four sizes for each character ?

### Davide P. Cervone

Nov 17, 2011, 7:56:10 PM11/17/11
>> MathJax_Caligraphic is for the TeX \cal font (for which there is no
>> equivalent in MathML).
>>
>> MathJax_WinChrome and MathJax_WinIE6 include characters that were
>> not accessible in those browsers. I should look at Chrome again
>> and see if that has been improved since I first set up the fonts
>> (there were only five or six anyway). IE6 had quite a few that it
>> couldn't access.
>
> OK, so they are probably not needed for my purpose.

Right.

>> The only data about the fonts is in the unpacked/jax/output/HTML-
>> CSS/fonts/TeX/fontdata.js file It is in JavaScript objects that
>> are not in any standard format (they are MathJax internal data).
>> There is a delimiter array that lists the various sizes available
>> for the stretchy characters, together with the parts to mark
>> arbitrary sized ones, when available. You might be able to use
>> that, though it may not be immediately obvious what everything is.
>> If you want to go that route, I can try to map it out better for you.
> Thank you. In Mozilla the stretchy characters are described that way:
>
> - Top/Left glyph
> - Middle glyph
> - Bottom Right glyph
> - Glue glyph: the one which is repeated to connect the three other
> components.
> - size0
> - size1
> - ...
> - sizeN
>
> So if I'm trying to guess what the DELIMITERS array is:
>
> - dir is the direction vertical/horizontal (in Mozilla, this is
> already stored in the operator dictionary)

right.

> - HW: I guess it is some kind of factor to decide which font should
> be used with respect to the size we want to stretch? (in Mozilla we
> can measure directly the size of the glyphs in fonts, so this is
> probably not needed)

Actually, this is the list corresponding to the size0,size1,...,sizeN
list at the end of your data. This is an array of arrays, with the
inner arrays having two elements: the height or width of the character
(depending on whether it is stretching vertically or horizontally) and
the font in which the character appears. The fonts are often listed
as variable names (which are defined at the top of the file) to reduce
the size of the file. The character in that font is assumed to be at
the same unicode code point as the delimiter being stretched. In rare
cases, the array has three or four entries, in which case the third is
a scaling factor to be applied to the character, and the fourth is a
unicode position where the character is to be found (in those cases
where it is not at the same location as the delimiter being stretched).

> - stretch: I can see what are top, bot, mid, left and right. What
> about ext/sep? Are they "glue" glyphs in Mozilla's terminology?

Yes, ext is the "extender" for vertical delimiters, and sep is the
"separator" for horizontal ones. They are your glue characters.
These are given by an array that includes the unicode location of the
character and the font in which it is found. Note that in the case of
braces, the mid character is actually made of two separate characters;
Firefox may not be set up do deal with that.

Note that there are more stretchy characters listed in the fontdata-
extra.js file in the v2.0-candidate branch.

Davide

### Davide P. Cervone

Nov 17, 2011, 8:00:12 PM11/17/11

There are actaully only two sizes for these characters in most cases.
When an operator is in displaystyle, MathJax looks first in
MathJax_Size2, then in MathJax_Size1, then in MathJax_Main for the
operator. If it is not in displaystyle, then it only looks in
MathJax_Size1 and MathJax_Main. The fonts searched are listed in the
VARIANTS array in the "-largeop" and "-smallop" entries.

Davide

### Frédéric WANG

Nov 17, 2011, 9:20:29 PM11/17/11
Is there a way to know which characters have variants in MathJax_Size1 /
MathJax_Size2?
Is it enough to consider those which are listed in
HTMLCSS.FONTDATA.FONTS['MathJax_Size1'] and
HTMLCSS.FONTDATA.FONTS['MathJax_Size2'] ?

### Davide P. Cervone

Nov 17, 2011, 9:24:42 PM11/17/11
Yes, the FONTDATA.FONTS['MathJax_Size1'] and
FONTDATA.FONTS['MathJax_Size2'] arrays should include everything in
those fonts (that's not the case for every font, but is for those two).

Davide

### Frédéric WANG

Nov 17, 2011, 9:29:09 PM11/17/11

Actually, this is the list corresponding to the size0,size1,...,sizeN list at the end of your data.  This is an array of arrays, with the inner arrays having two elements: the height or width of the character (depending on whether it is stretching vertically or horizontally) and the font in which the character appears.  The fonts are often listed as variable names (which are defined at the top of the file) to reduce the size of the file.  The character in that font is assumed to be at the same unicode code point as the delimiter being stretched.  In rare cases, the array has three or four entries, in which case the third is a scaling factor to be applied to the character, and the fourth is a unicode position where the character is to be found (in those cases where it is not at the same location as the delimiter being stretched).

OK, I can use these lists to get the variants size0, ... sizeN. As I said, I don't need the height/width param, which can be measured directly. The scaling factor won't be usable in Mozilla unless I modify the C++ source, though. Just a question: why aren't the characters already scaled in the font file?

Note that in the case of braces, the mid character is actually made of two separate characters; Firefox may not be set up do deal with that.
Yes, not without modifying the C++ source. I'll have to ignore constructions for these characters too (fortunately, they are already well supported using other unicode fonts).

Note that there are more stretchy characters listed in the fontdata-extra.js file in the v2.0-candidate branch.
Yes, I noticed this.

### Frédéric WANG

Nov 17, 2011, 9:30:49 PM11/17/11
OK, great that makes things easier for me.

Le 18/11/2011 03:24, Davide P. Cervone a écrit :
Yes, the FONTDATA.FONTS['MathJax_Size1'] and FONTDATA.FONTS['MathJax_Size2'] arrays should include everything in those fonts (that's not the case for every font, but is for those two).

Davide

### Davide P. Cervone

Nov 17, 2011, 9:35:46 PM11/17/11
> OK, I can use these lists to get the variants size0, ... sizeN. As I
> said, I don't need the height/width param, which can be measured
> directly. The scaling factor won't be usable in Mozilla unless I
> modify the C++ source, though. Just a question: why aren't the
> characters already scaled in the font file?

This is only rarely used, and I think it is not used in the MathJax
fonts. It was used in the STIX fonts when there were not characters
in sizes that TeX needed. But as I said, it was rare. I just wanted
you to know what it meant if you saw it.

Davide

### Frédéric WANG

Nov 21, 2011, 7:39:50 AM11/21/11

>> Note that in the case of braces, the mid character is actually made
>> of two separate characters; Firefox may not be set up do deal with that.
> Yes, not without modifying the C++ source. I'll have to ignore
> constructions for these characters too (fortunately, they are already
> well supported using other unicode fonts).
Actually, there is some code to do that work. It was used in old version
of Mozilla for the CMEX10 fonts. I'll have to try whether it is still
working...

### Frédéric WANG

Nov 23, 2011, 6:03:10 PM11/23/11

> I'm trying to add support for MathJax fonts in Mozilla native MathML.

Just for the record:
https://bugzilla.mozilla.org/show_bug.cgi?id=701758

### Davide P. Cervone

Nov 24, 2011, 12:49:49 PM11/24/11
Looks cool. GLad it worked out for you.

Davide

### Frédéric WANG

Dec 7, 2011, 2:26:07 PM12/7/11
I've just made a complete test for Mozilla, based on its operator dictionary:

https://bug708072.bugzilla.mozilla.org/attachment.cgi?id=579435

It turns out that some scale factors are also used for some operators in fontdata-extra.js, so you I won't be able to use those characters in Mozilla either (without modifying the C++ source).

BTW, I also found a typo for the operator 0x21A0 in the v2.0-candidate branch (I have to verify if I used the last version, though).

### Frédéric WANG

Dec 7, 2011, 2:31:00 PM12/7/11

> BTW, I also found a typo for the operator 0x21A0 in the v2.0-candidate
> branch (I have to verify if I used the last version, though).
OK, both on SVG and v2.0-candidate, in
jax/output/HTML-CSS/fonts/TeX/fontdata-extra.js:

{
dir: H, HW: [[1,AMS]], stretch: {right:[0x221A0,AMS], rep:[0x2212,MAIN]}
},

Here, right should contain 0x21A0 instead of 0x221A0.

### Davide P. Cervone

Dec 17, 2011, 10:55:11 AM12/17/11
Thanks. I've taken care of it, and the corresponding error in the SVG
font extras, and the STIX font extras, as well.

Davide

### Frédéric WANG

Mar 7, 2012, 6:31:44 PM3/7/12
So use of MathJax fonts for stretchy symbols (except horizontal braces) is integrated in Firefox Nightly builds. Now, I'm wondering what are exactly the rules to determine the font-family to apply on mathematical text? Particularly for MathJax_Math and MathJax_Main...

https://bugzilla.mozilla.org/show_bug.cgi?id=732834

### Davide P. Cervone

Mar 8, 2012, 3:34:54 PM3/8/12
Fred:

MathJax's font handling is kind of a mess, and it has evolved as needs arose, making it even more complicated.

The MathJax_Main font is the largest one, containing the upright roman alphabet, and all the math symbols from the basic TeX CM fonts (the characters from the AMS fonts are in MathJax_AMS).
The MathJax_Math font contains the math italic alphabet and the italic Greek letters (whereas MathJax_Main-Italic is the text italic characters, which are almost the same, but have different spacing).  MathML doesn't really make a distinction between these, but MathJax used MathJax_Main-Italic for <mtext mathvariant="italic"> but MathJax_Math for <mi mathvariant="italic">.

The MathJax fontdata.js files contain the mappings of mathvariants to the actual fonts in the VARIANT object, so for example VARIANT.normal.fonts is an array containing "MathJax_Main","MathJax_Size1","MathJax_AMS", and MathJax will look through these fonts in that order for a given character in that variant.  So I guess that would correspond to the CSS rule

[mathvariant="normal"] {
font-family: MathJax_Main,MathJax_Size1,MathJax_AMS;
}

Note that mathJax_Main comes in normal, italic, bold, and bold-italic, and many of the others have bold versions (and sometimes italic ones) as well.  So, for example,

[mathvariant="script"] {
font-family: MathJax_Script;
}
[mathvariant="bold-script"] {
font-family: MathJax_Script;
font-weight: bold;
}

might be better than assigning both bold and bold-script to the same thing.  Of course, MathJax includes several other fonts to look through if the character isn't in this font, so you might want to do something like the example for mathvariant="normal" in this case as well.  The reason that MathJax includes other fonts is so that if you use mathvariant on a character that isn't in that font, it will still display those characters somehow.  For example, <mstyle mathvariant="script"><mi>A</mi><mo>+</mo><mi>B</mi></mstyle> would still be able to display the + even though there is no script variant of that character.  Because VARIANT.script.fonts = ["MathJax_Script","MathJax_Main","MathJax_Size1","MathJax_AMS"], it would find the "+" in the MathJax_Main font and use that.  I'm not sure what Firefox would do in this case with the CSS for mathvariant="script" above.

If you do try to use MathJax's font arrays and turn them into font-family specifications, you may run into trouble, because the lists can include mixes of italic and non-italic or normal and bold fonts, and that is harder to handle in CSS.  You could use @font-face to specify the individual names with their styles and weights so that you can then list them intermixed in a font-family declaration.

There is one more complication, however, which involves remapping of characters from one variant to another.  For example, the full definition of VARIANT.normal is

normal: {
fonts: [MathJax_Main,MathJax_Size1,MathJax__AMS],
offsetG: 0x03B1, variantG: "italic",
remap: {
0x391:0x41, 0x392:0x42, 0x395:0x45, 0x396:0x5A, 0x397:0x48, 0x399:0x49, 0x39A:0x4B,
0x39C:0x4D, 0x39D:0x4E, 0x39F:0x4F, 0x3A1:0x50, 0x3A4:0x54, 0x3A7:0x58,
0x29F8:[0x002F,"italic"]
}
}

which includes two different forms of remapping.  The offsetG and variantG is used to remap the lower-case Greek letters to the italic variant (since there are no upright greek in the basic TeX CM fonts), and it is tied to the RANGES object which tells the range of characters that are remapped (in this case, it corresponds to {name: "greek", low: 0x03B1, high: 0x03F6, offset: "G"} which maps U+03B1 through U+03F6 to the italic variant).

The remap object gives single-character remapping within the font.  In this case, it remaps the capital Greek letters to the corresponding capital letters in the standard ASCII range.  This maps the MathJax_Main font appear to have a Greek capital Alpha (that looks just like capital A).  The final entry in the remap object remaps U+29F8 (large solidus) to U+002F (the / character) in the italic variant (MathJax_Math) which includes the glyph for that character.  (The MathJax fonts were created fairly early in the MathJAx development process, and I learned a lot about unicode working with MathJax after that, so some glyphs are not in the best locations -- these remappings allow me to use the original fonts as though everything was were it should be.)

There are some other remappings as well, but those are the basics.  Hope that tells you what you are after.

Davide

### Frédéric WANG

Mar 11, 2012, 7:23:03 AM3/11/12
FYI, Firefox 13 will use MathJax fonts for operator stretching and mathematical text (of course it will still use other fallback/alternative fonts such as STIX or Asana Mathfonts). I didn't add all the rules for mathematical text, just those in the user agent style sheet:

http://mxr.mozilla.org/mozilla-central/source/layout/mathml/mathml.css#51
http://mxr.mozilla.org/mozilla-central/source/layout/mathml/mathml.css#157

(probably, there will be duplicate rules with what MathJax is adding for the Firefox native MathML)

I didn't use MathJax_Math since you say it is nearly the same as MathJax_Main italic.
--
Frédéric Wang
maths-informatique-jeux.com/blog/frederic