Closed Bug 947654 Opened 10 years ago Closed 9 years ago

[meta] Default fonts for MathML

Categories

(Core :: MathML, enhancement)

enhancement
Not set
normal

Tracking

()

RESOLVED FIXED
mozilla41
Tracking Status
firefox41 --- fixed

People

(Reporter: fredw, Assigned: fredw)

References

(Depends on 3 open bugs, Blocks 3 open bugs, )

Details

(Keywords: dev-doc-complete, meta)

User Story

Mathematical formulas require special fonts. So far, these fonts were hardcoded in the mathml.css user agent stylesheet (setting the font-family on <math> tag) and in the preference option font.mathfont-family (setting the fallback fonts to use for stretchy and large operators). Here we introduce an internal x-math language that is automatically set on the <math> tag as well as corresponding preference options (e.g. font.name.serif.x-math). The user agent stylesheet now sets font-family to serif on the <math> tag and the preference option font.mathfont-family is replaced with font.name.serif.x-math. This will allow to configure the default/fallback fonts using standard per-language font preferences (see bug 1160455, bug 1160456 and bug 1170918 for the UI in SeaMonkey, Firefox and Thunderbird). Also, now that the line height bug is fixed on Windows (see bug 598900) all platforms can essentially use the same list of fallback fonts, with "Latin Modern Math" as first one.

Attachments

(1 file, 20 obsolete files)

20.73 KB, patch
Details | Diff | Splinter Review
This is a meta bug to keep track of some ideas for the default fonts for MathML, once we have a better support for Open Type MATH fonts.

1) Deprecate old fonts

   As discussed with Karl on IRC, the idea will be to progressively move our stretchy code from the old properties-based file to the new Open Type MATH support (this will in general be true for other parameters). As a first step, the two code paths will cohabitate but in the future in order to simplify the nsMathMLChar code and to really follow the Open Type MATH stretching rules, we want to keep the Open Type MATH versions only. Hence I suggest to:

   - Deprecate the MathJax fonts in favor of Latin Modern fonts. Both are based on Knuth's Computer Modern but the latter will allow better math layout via the Open Type MATH table.
   - Remove support for STIX 1.0 beta (bug 742273)
   - Deprecate the STIX General fonts in favor of the STIX Word fonts.
   - Remove the Asana .properties file ; and read the Open Type MATH table instead.

I think in the future only Unicode-based constructions will remain, but I guess they can just be hardcoded as an array instead of a properties file and the code can be adapted to follow the Open Type MATH rules.

2) Make the MathML font-family default to "inherit"

  After James' implementation of mathvariant, the only remaining place where we set explicit font names are on the <math> element. I suspect this was to avoid inconsistent font families and size, that is a situation where most of the math is rendered with the font inherited from the surrounding text but a couple of exotic math characters are picked from a totally different font like STIX.

  However this does not solve all the problems. For example in MathJax some users complain about the other direction: characters that are not always in the MathJax fonts like "é" will render badly in e.g. <mtext>. And more importantly, they complain about the inconsistency between the text and math fonts: the font of the surrounding text may be very different from the default MathJax or STIX fonts for MathML and in particular the font-size difference can be significant, which is especially bad for inline equations.

  MathJax's hack is to change the font-size of MathML to match the one of the surrounding text but this is bad because a) this adds additional computation we don't want (especially if this requires a third-party Javascript library) b) is in conflict with the CSS expectation of the user with respect to the default agent stylesheet c) is an unreliable calculation based on the height of the "x" in both fonts c) even when that calculation works and the font-size's match, the font-weight's no longer match...

  So my proposal is to set the default font-family to "inherit" so that:

- By default the text and math fonts will be consistent (I think e.g. ASCIIMath resets the font-family btw)

- If the user wants to use some specific characters, say Arabic, he can still use normal CSS rules like

   mtext { font-family: Amiri; }

- Authors who know what they do and who want to use "beautiful" math fonts could just use normal CSS rules to get consistent text and math fonts for example
   body { font-family: Latin Modern; }
   math { font-family: Latin Modern Math; }

- For users, it would still be possible to add options in the MathML-fonts add-on or in the user stylesheet to change the default font-family on the <math>.

3) Remove the ::-moz-math-stretchy pseudo element and font.mathfont-family property option from about:config.

  So that similarly, the fonts used for large and stretchy operators will be consistent with the font-family specified on the <math> that is one will only need to do

  math { font-family: Neo Euler; }

  to use Neo Euler for the math text, large operators and stretchy characters. However, this change may be problematic if the font used for the surrounding text do not have math constructions.
Not sure if it is a good thing, but may be we can check if the text font has companion math font available to Gecko and use it? E.g. if the text is set in font Foo, we check if there is a Foo Math font and use it. But even if we did that, still remain the case where we did not find a companion math font, just using a non-Math font does not seem right to me. May be we should add Math to the script categories in Preferences → Content → Fonts and colors → Advanced and have a sensible default and let the users override it.
Severity: normal → enhancement
Keywords: meta
We'll have to think about that but as a rule of thumb I think we want the default user agent stylesheet to do only minimum changes. Having the font-family magically changes to some arbitrary math fonts might not be expected by users. It seems that SVG does not do that and HTML only does that for the caption of a <video>.

I like the idea of a preference in the menu. The only problem I see is that we'll have to convince the Firefox UI reviewers about the usefulness of such an option.

Automatically finding a companion math could be a good idea, but we need a standard font mechanism way to do that association (appending "Math" to the name seems more a convention to me) and that must probably be standardized so that users won't be surprised (say with a new CSS rule font-mode: text; font-mode: math).
(In reply to Frédéric Wang (:fredw) from comment #2)
> I like the idea of a preference in the menu. The only problem I see is that
> we'll have to convince the Firefox UI reviewers about the usefulness of such
> an option.

That's not such a problem if it is just adding Math to the list of scripts.
I wonder whether we'd need separate options for LTR Math and RTL Math.
(In reply to Karl Tomlinson (:karlt) from comment #3)
> That's not such a problem if it is just adding Math to the list of scripts.
> I wonder whether we'd need separate options for LTR Math and RTL Math.

OK, I didn't see the "advanced" field with all the scripts. I guess you think e.g. Arabic fonts for RTL. However, Arabic equations written LTR also need the fonts. I believe Arabic is the only script to which we want an exception. All other countries use ascii letters only for math equations, except in <mtext>. Perhaps also when one uses word in variable like <mi>Énergie_Potentielle</mi> but that's very rare I think. So that would be three or four versions:

Math
Math Arabic
Math Text
Math Text Arabic?

I'm not sure if we can specify "inherit" or if the font size / min size menus are always relevant.

Our start page:
https://developer.mozilla.org/th/docs/Mozilla_MathML_Project/Start
https://developer.mozilla.org/he/docs/Mozilla_MathML_Project/Start
https://developer.mozilla.org/zh-CN/docs/Mozilla_MathML_Project/Start
https://developer.mozilla.org/ar/docs/Mozilla_MathML_Project/Start
I've created a version of the MathML torture test with Web fonts in order to test the ideal case where we only need to specify the MATH font to use on the <math> element:
http://www.maths-informatique-jeux.com/ulule/mathml_torture_test/

Another issue to address is 930504 (in particular to get the italic characters of single-char <mi>).
Depends on: 930504
Blocks: 775060
Assignee: nobody → fred.wang
Temporary patch to add new MATH fonts to the default stylesheet. Should be replaced with preference strings + add UI to let the users edit them.
More thoughts on font support and how we could move to Open Type MATH fonts:

=== CURRENT SITUATION ===

1) The default font-family on the <math> tag (mathml.css) is:

MathJax_Main, STIXGeneral, DejaVu Serif, DejaVu Sans, Cambria, Cambria Math, Times, Lucida Sans Unicode, OpenSymbol, Standard Symbols L, serif;

2) The private tables for stretchy operators are:

XP_WIN => MathJax_Main, STIXNonUnicode, STIXSizeOneSym, STIXSize1, Asana Math, Standard Symbols L, Symbol
other => MathJax_Main, STIXNonUnicode, STIXSizeOneSym, STIXSize1, Asana Math, Standard Symbols L

+ a table for Unicode constructions.

3) The default font.mathfont-family preference (used for stretchy operators) is:

XP_WIN => MathJax_Main, STIXNonUnicode, STIXSizeOneSym, STIXSize1, STIXGeneral, Asana Math, Symbol, DejaVu Sans, Cambria Math
XP_MACOSX => MathJax_Main, STIXNonUnicode, STIXSizeOneSym, STIXSize1, STIXGeneral, Asana Math, Symbol, DejaVu Sans, Cambria Math
XP_OS2 => MathJax_Main, STIXNonUnicode, STIXSizeOneSym, STIXSize1, STIXGeneral, Asana Math, DejaVu Sans
other => MathJax_Main, STIXNonUnicode, STIXSizeOneSym, STIXSize1, STIXGeneral, Asana Math, Standard Symbols L, DejaVu Sans, Cambria Math

4) Availability of Open Type MATH:

- Cambria Math:  Windows Vista, Windows 7, Microsoft Office 2007, Microsoft Office 2008 and 2011 for Mac, and Microsoft Office 2007.
- STIX Math: MAC OS X Lion.
- Asana Math, Latin Modern Math, TeX Gyre * Math, STIX Math, XITS Math are available as CTAN packages (http://ctan.org/topic/font-maths) and thus are very likely to be installed with TeX distributions like TeXLive or MiKTeX.
- For Firefox OS, we could bundle math fonts (bug 775060). I guess the same could be done for Android devices with Firefox pre-installed.
- In other cases, users will need to install fonts or to use the MathML-fonts add-on.

=== PROPOSAL ===

* Remove the font.mathfont-family* preferences and ::-moz-math-stretchy pseudo-element (see patches). The math font to use for the MathML elements (text, stretchy operators and Open Type MATH layout) will just be taken from the font-family of the style context and the user can set it with standard CSS.
* The default font-family on the <math> could be taken from a preference (ideally configurable from the browser UI).

* Deprecate the MathJax_Main in favor of Latin Modern Math.
* Remove STIX beta (STIXSize1) data. (bug 742273)
* Deprecate STIXGeneral in favor of STIX Math. We can merge the STIXNonUnicode and STIXSizeOneSym tables into a single "STIXGeneral" table, so one only need to specify "STIXGeneral" in the font-family.
* Remove the Asana private table and read the Open Type MATH table instead.

* Remove the Standard Symbols L table. IIUC, it was mostly added for Linux distributions (bug 236880) but has very limited support for stretchy operators. People would be better off installing Open Type MATH fonts, if they are not already available from their TeX distributions.
* Remove the Symbol table. This font is not needed when Cambria Math is available and thus should only be considered for Windows XP. Again, this font has very limited support for stretchy operators and people would be better off installing Open Type MATH fonts.

* TeX people prefer fonts that look like Computer Modern, so make Latin Modern Math the prefered font.
* STIX Math has many design bugs and lacking features. It's not clear when the STIX consortium will fix them, so prefer the XITS Math font.
* Order of preference: Open Type MATH fonts, deprecated fonts for which we have private tables for stretchy operators, other fonts for which we can use Unicode constructions for stretchy operators.

Proposal for a new default font-family:

Latin Modern Math, XITS Math, STIX Math, Cambria Math, Asana Math, TeX Gyre Bonum Math, TeX Gyre Pagella Math, TeX Gyre Termes Math, Neo Euler, Lucida Bright Math,

MathJax_Main, STIXGeneral,

DejaVu Serif, DejaVu Sans, Times, Lucida Sans Unicode, OpenSymbol, Standard Symbols L, serif;
Blocks: 923890
Depends on: 960115, 945183, 961365
Depends on: 961482
I've written new patches to do the proposal of comment 9 (https://github.com/fred-wang/MozillaCentralPatches/).

Finally what I have done is:

1) On the <math> element:

  - font-family is set to a new property -moz-use-math-font, which just picks the fonts from a font.name-list.mathml preference. The default list is the one mentioned in comment 9.

  - font-size is inherited since in general we want the MathML formulas to have the same size as the surrounding context. However, that may not be the case if the fonts are badly chosen by the Web author as explained in comment 1.

  - reset other font properties, so that the aspect of math fonts won't be changed by inherited properties. For example MATH fonts generally don't have a corresponding bold/italic fonts and we just use mathvariant to pick the appropriate Unicode char instead.

2) On the <mtext> element:

  - set font-family to "initial" so that we use the default font for the language of the document. This will avoid to get inconsistent glyphs when some characters in the text are not present in the math fonts.

Of course, to get consistent rendering/size between the surrounding context, the math formulas and the inner <mtext>, Web authors are encouraged to define the CSS of their pages appropriately e.g. using a font with its companion math.

I think this will give reasonable default and easy customization.
Attachment #8362155 - Attachment is obsolete: true
Depends on: 963079
Blocks: 963147
Keywords: dev-doc-needed
Blocks: 930504
No longer depends on: 930504
Attachment #8362151 - Attachment is obsolete: true
Comment on attachment 8408290 [details] [diff] [review]
Part 4 (version with -moz-use-math-font)

This is still block by other bugs, but I'm already asking feedback about this new -moz-use-math-font CSS property and preference for MATH fonts.
Attachment #8408290 - Flags: feedback?(karlt)
Attachment #8408290 - Flags: feedback?(cam)
I don't really like the idea of introducing a -moz-use-math-font keyword.  Can we instead update the UA style sheet to give the font-family property the right list of font families when the pref changes?
By the way, will there ever be a specification that defines the UA style sheet rules to use for MathML elements?  For things like resetting font-variant, font-weight, etc. to normal this is something that should work the same across browsers.
Attachment #8408290 - Flags: feedback?(cam) → feedback-
(In reply to Cameron McCormack (:heycam) (away 27 April - 1 June) from comment #16)
> I don't really like the idea of introducing a -moz-use-math-font keyword. 
> Can we instead update the UA style sheet to give the font-family property
> the right list of font families when the pref changes?

I'm not sure I understand your suggestion here. The point is to avoid such hardcoded list of fonts so that users can more easily configure it via a pref (and thus an UI). Or does Gecko have some C++ API to override the rules of a UA style from a pref? That's what I want to do with this -moz-use-math-font.

(In reply to Cameron McCormack (:heycam) (away 27 April - 1 June) from comment #17)
> By the way, will there ever be a specification that defines the UA style
> sheet rules to use for MathML elements?  For things like resetting
> font-variant, font-weight, etc. to normal this is something that should work
> the same across browsers.

Not to my knowledge.
It wouldn't be straightforward, but you could iterate over each nsIDOMWindow using the nsIWindowMediator service, get its document, and then if MathML is enabled in that document, find the nsIStyleSheet in its list of catalog style sheets that is the mathml.css one, and modify the rule that has the font-family declaration.  You'd also need to add that font-family declaration right after mathml.css is loaded in nsMathMLElement::BindToTree.

Or instead of modifying the mathml.css sheet, you could have a separate sheet just for the font-family rule.

That's all a bit complicated, but I would rather not expose a -moz-use-math-font keyword to content.

dbaron what do you think?
Flags: needinfo?(dbaron)
(In reply to Cameron McCormack (:heycam) (away 27 April - 1 June) from comment #19)
> It wouldn't be straightforward, but you could iterate over each nsIDOMWindow
> using the nsIWindowMediator service, get its document, and then if MathML is
> enabled in that document, find the nsIStyleSheet in its list of catalog
> style sheets that is the mathml.css one, and modify the rule that has the
> font-family declaration.  You'd also need to add that font-family
> declaration right after mathml.css is loaded in nsMathMLElement::BindToTree.

OK, I get the idea. It seems that this would even allow to have a "do not allow Websites to override my font preference" option by making the rule !important.

> That's all a bit complicated, but I would rather not expose a
> -moz-use-math-font keyword to content.

Yes, if we can avoid non-standard keyword, that's best.
(In reply to Cameron McCormack (:heycam) (away 27 April - 1 June) from comment #16)
> I don't really like the idea of introducing a -moz-use-math-font keyword. 
> Can we instead update the UA style sheet to give the font-family property
> the right list of font families when the pref changes?

We already dynamically build a style sheet from preferences, in PresShell::CreatePreferenceStyleSheet, so if we need to add UA style sheet rules based on prefs, we should probably use that.

(In reply to Cameron McCormack (:heycam) (away 27 April - 1 June) from comment #19)
> It wouldn't be straightforward, but you could iterate over each nsIDOMWindow
> using the nsIWindowMediator service, get its document, and then if MathML is
> enabled in that document, find the nsIStyleSheet in its list of catalog
> style sheets that is the mathml.css one, and modify the rule that has the
> font-family declaration.  You'd also need to add that font-family
> declaration right after mathml.css is loaded in nsMathMLElement::BindToTree.

That seems a bit complicated.  Does using the existing pref style sheet mechanism work?  (I don't quite follow the requirements right now.)
Flags: needinfo?(dbaron)
The requirement is just to make the default font-family on the <math> element configurable by a font.name-list.mathml preference. Contrary to other font preferences, this does not depend on the language of the page nor on the italic/bold/monospace/serif style (note: OpenType MATH families are only made of a single font file with the mathvariant characters in the Mathematical Alphanumeric Symbols Unicode block; we will use them for bold/italic too after bug 930504. That's also why I reset all the font properties in mathml.css).

So I think David's suggestion with pref style sheet is enough here. I attach a patch implementing this suggestion, which seems cleaner than the two other methods. Two differences I see (they don't sound too serious problems to me):

- When browser.display.use_document_fonts is false, the style in the preference style sheet seems to be ignored so the default user font is always used for <math> elements. Since this default font is unlikely to be a math font, the MathML equations might not render correctly. It seems that this is already the case in release, except that the ::-moz-math-stretchy pseudo-element forces the math fonts for at least the stretchy <mo>.

- As I understand, Gecko tries to avoid additional work when no MathML content is met. With this patch, the font-family rule on the <math> will always be created and the font.name-list.mathml preference will be read on all pages.
Attachment #8410268 - Flags: feedback?(cam)
Attachment #8408290 - Flags: feedback?(karlt)
Attachment #8408287 - Flags: review?(karlt)
Attachment #8408288 - Flags: review?(karlt)
Comment on attachment 8410268 [details] [diff] [review]
Part 4 - Make the font-family on <math> and <mtext> be font.name-list.mathml preference and 'initial' respectively.

Review of attachment 8410268 [details] [diff] [review]:
-----------------------------------------------------------------

Resetting feedback?; I'm happy with the pref style sheet changes, just not sure about the <mtext> stuff.

::: layout/base/nsPresShell.cpp
@@ +1609,5 @@
> +  NS_ASSERTION(mPrefStyleSheet, "prefstylesheet should not be null");
> +
> +  nsAutoString mathFontFamilyRule;
> +  mathFontFamilyRule.AppendLiteral("m|math { font-family: ");
> +  mathFontFamilyRule.Append(mPresContext->GetDefaultMathFont());

I'm concerned about escaping here.  I think the font family should be written as a CSS string (i.e. with surrounding quotes, and appropriate escapes within the string).  Otherwise the pref value might include ";" and break the style sheet.

This won't work for the default "serif" value that you use, though, which needs to be unquoted.

::: layout/mathml/mathml.css
@@ +64,5 @@
> +   language of the document and these characters may not be found in math fonts,
> +   so we reset font-family to use the default preference and get consistent
> +   glyphs. */
> +mtext {
> +  font-family: initial;

I don't know about this.  On every page except those with the most basic styling, this font isn't going to match what is used in the text surrounding the math.

We don't really have a good way to make <mtext> take the font family used outside the <math> by default.  So I'm inclined to think that the author just needs to set the font on <mtext> explicitly and not to set it to "initial".
Attachment #8410268 - Flags: feedback?(cam)
Comment on attachment 8408287 [details] [diff] [review]
Part 1 - Remove the font.mathfont-family* preferences

I'm keen to remove GetFontExtensionPref(), but is the fallback font.mathfont-family pref causing a problem?  It is only added after the CSS families.  It is useful if the author has specified a font family that is not installed.

An alternative might be to have a "math" language for the generic family preferences, so that sounds a little different to what you are proposing with font.name-list.mathml.
Attachment #8408287 - Flags: review?(karlt)
Attachment #8408288 - Flags: review?(karlt) → review+
(In reply to Karl Tomlinson (:karlt) from comment #24)
> I'm keen to remove GetFontExtensionPref(), but is the fallback
> font.mathfont-family pref causing a problem?  It is only added after the CSS
> families.  It is useful if the author has specified a font family that is
> not installed.

I'd like to avoid unexpected/complicated behavior. I think it's cleaner and more natural to say that the operators (and more generally the whole math layout, since future MATH parameters will be taken from the font) is just described by the font-family on the <math> (perhaps using the default pref values) and not on other pref or pseudo-elements. If the author intentionally specifies a font on the <math>, he must be sure that it is supported and provides a Web font fallback if necessary. Perhaps we can keep font.mathfont-family but then that will duplicate the font-family pref for the whole <math> tag.

I also have one concern with the current implementation: it seems that the font.mathfont-family pref is read for each call to the Stretch routine. The font.* families in nsPresContext instead caches that preference string, so I suspect this is a performance issue for the stretch code.

> 
> An alternative might be to have a "math" language for the generic family
> preferences, so that sounds a little different to what you are proposing
> with font.name-list.mathml.

If I remember how the other font pref are handled, the current language of the document is used for the initial value. But we don't have a "math" language and we only want to apply this to MathML elements (perhaps overriding the inherited value) so that didn't seem to work very well in that case...
In the non-math situations, font preferences don't set the initial value for font-family but describe fallback families for when there is no author-specified family or author-specified families are not available.

(In reply to Frédéric Wang (:fredw) |in vacation from 27/04 to 06/05 from comment #25)
> If the author
> intentionally specifies a font on the <math>, he must be sure that it is
> supported and provides a Web font fallback if necessary.

That's not how CSS font-family usually works.  font-family indicate preferred families, not that the author knows that the font is present.  The expectation is that the user agent will provide reasonable fallback.
As part of bug 280443, I'm going to try and eliminate the use of comma-separated strings for passing around font family lists.  Instead, I going to rework nsFont to include a struct that consists of an array of simple objects that are either a name or an enum for generics.  The tough part of this actually looks like it's going to be in MathML code which plays around a lot with font family lists.  Not sure yet what the right approach will be but I'm hoping we can simplify the font family name handling that takes place in MathML code.

Glancing quickly over your patches, I don't think it would be hard to implement a specific generic for math fonts (that would be resolved based on the pref).  It should probably just mimic -moz-fixed in behavior.  I think just -moz-math would be fine without the "use" portion.  Some of the font-related code in nsMathMLChar.cpp should probably be abstracted better and moved into gfx somewhere but I haven't fully grokked what it's doing.  Seeing lots of manipulation of the fontlist sort of concerns me...
Depends on: 1000745
(In reply to John Daggett (:jtd) away 25 - 29 april from comment #27)
> Seeing lots of manipulation of the fontlist sort of concerns me...

The patches of bug 1000745 should remove many of these font lists. After that, I think the only remaining issue is with the "font.mathfont-family" preference that calls the AddFallbackFonts function and EnumerateFamilies.

I believe if we find a better way to specify a preference for the default font-family on the <math> in the present bug, then this code in nsMathMLChar can be dropped (a complication is with the ::-moz-math-stretchy pseudo-element that sets the font-family on nsMathMLChar, that I'd like to remove too). I suspect that instead of doing this EnumerateFamilies on the font-family, we could just test each font in a gfxFontGroup.
Attachment #8408290 - Attachment description: Part 4: Make the font-family on <math> and <mtext> tags to be -moz-use-math-font (font.name-list.mathml preference) and 'initial' respectively. → Part 4 (version with -moz-use-math-font)
Attachment #8410268 - Attachment description: Make the font-family on <math> and <mtext> be font.name-list.mathml preference and 'initial' respectively. → Part 4 - Make the font-family on <math> and <mtext> be font.name-list.mathml preference and 'initial' respectively.
Attachment #8408287 - Attachment is obsolete: true
Depends on: 1000879
Depends on: 1001169
Comment on attachment 8408288 [details] [diff] [review]
Part 2: Remove the ::-moz-math-stretchy pseudo-element. b=947654, r=karlt.

This one is handled in bug 1000879.
Attachment #8408288 - Attachment is obsolete: true
Depends on: 1007093
Comment on attachment 8411784 [details] [diff] [review]
Part 3: Remove old glyph tables and merge the legacy tables for the STIXGeneral set.

Marking obsolete as these will be handled in bug 1007093 and bug 1007093.
Attachment #8411784 - Attachment is obsolete: true
(In reply to Karl Tomlinson (:karlt, back May 5) from comment #26)
> In the non-math situations, font preferences don't set the initial value for
> font-family but describe fallback families for when there is no
> author-specified family or author-specified families are not available.
> 
> That's not how CSS font-family usually works.  font-family indicate
> preferred families, not that the author knows that the font is present.  The
> expectation is that the user agent will provide reasonable fallback.

I think the fallback provided in the non-math case is to pick a glyph from a font corresponding to a "generic font-family". In the math case, we will also try a generic font-family at the end, using the Unicode table. So forcing the stretchy code to try a list of other known MATH fonts in a specific order before the final generic font-family seems to be a slight generalization of the normal fallback case.
(In reply to Karl Tomlinson (:karlt, back May 5) from comment #26)
> In the non-math situations, font preferences don't set the initial value for
> font-family but describe fallback families for when there is no
> author-specified family or author-specified families are not available.

So reading SetFont, I think the font preferences both set the initial values for font-family (when font-family = initial) and provide additional fallback to use as generic font-family. I'd like to do the same for the <math> element but I agree that the 2 patches I submitted don't really do that. The situation is slightly different here because

1) the <math> root does not do "font-family: initial" but has a default font-family in mathml.css (and otherwise would inherit the parent)
2) "math" is not a valid -x-lang

(In reply to Karl Tomlinson (:karlt, back May 5) from comment #24)
> An alternative might be to have a "math" language for the generic family
> preferences, so that sounds a little different to what you are proposing
> with font.name-list.mathml.

So that would be setting "font-family: initial; -x-lang: math;" for the <math>. But at the moment it's not clear whether we want -x-lang to accept the "math" language and to be usable in the mathml.css user agent stylesheet...
(In reply to John Daggett (:jtd) from comment #27)
> Glancing quickly over your patches, I don't think it would be hard to
> implement a specific generic for math fonts (that would be resolved based on
> the pref).  It should probably just mimic -moz-fixed in behavior.

That's almost what we want, but it is too easy for an author to specify font-family: Latin Modern, serif and so override the generic.

(In reply to Frédéric Wang (:fredw) from comment #35)
> But at the moment it's not clear whether we want -x-lang to accept
> the "math" language and to be usable in the mathml.css user agent
> stylesheet...

Yes, that may not be the best approach either.

I think what we want is to interpret generics differently within MathML, perhaps like a different lang but without exposing this to CSS/DOM.
So the other patches have been handled in separate bugs. Now the remaining issue is how to make the font-family configurable via a preference.

I think the easiest option that does not change too much the current setup is to take attachment 8410268 [details] [diff] [review] ; minus the <mtext> change and using the font.name-list.mathml list as a fallback for the nsMathMLChar <mo> operators. That won't make the font.name-list.mathml a real fallback for the whole MathML elements and that won't allow users to tell "don't allow the authors to override my preferences", but this could be refined in later bugs. (Note: I want to create an add-on that allows to easily configure the preferred default math fonts, so just doing that would be enough)

The main technical concern is how to handle font.name-list.mathml properly, in particular with quoting, escaping and list merging. I think this is essentially what bug 280443 is about so I suggest to focus on that if everybody agree about the intermediate step proposed in the previous paragraph.

@John: could you tell me what are the remaining issues to fix regarding the font-family in nsMathMLChar, about the status of bug 280443 and how I can rely on it to update my patches?
Flags: needinfo?(jdaggett)
Depends on: 280443
(In reply to Frédéric Wang (:fredw) from comment #37)
> So the other patches have been handled in separate bugs. Now the
> remaining issue is how to make the font-family configurable via a
> preference.
> 
> I think the easiest option that does not change too much the current
> setup is to take attachment 8410268 [details] [diff] [review] ; minus the <mtext> change and
> using the font.name-list.mathml list as a fallback for the
> nsMathMLChar <mo> operators. That won't make the
> font.name-list.mathml a real fallback for the whole MathML elements
> and that won't allow users to tell "don't allow the authors to
> override my preferences", but this could be refined in later bugs.
> (Note: I want to create an add-on that allows to easily configure
> the preferred default math fonts, so just doing that would be enough)

I'm not really keen on using the "font.name-list.mathml" prefname.  The distincition between "font.name.xxx" and "font.name-list.xxx" is really tied to UI considerations for font pref handling.  The fact that it's used for font fallback is largely for historical reasons.  I think the best way would be to have a pref 'font.mathml.fallback' with an added style bit in nsFont/gfxFontStyle to indicate the need for math font related fallback.  The mechanics of that fallback should live in gfx code I think, that's a much more logical place for it.  MathML code mucking about with fontlists complicates making changes to gfxFontGroup code.

> The main technical concern is how to handle font.name-list.mathml
> properly, in particular with quoting, escaping and list merging. I
> think this is essentially what bug 280443 is about so I suggest to
> focus on that if everybody agree about the intermediate step
> proposed in the previous paragraph.

Part of the work on bug 280443 is to get rid of all that.  There shouldn't be any need to worry about quotes, escaping, etc. for dealing with a list of fonts in a pref.  The gfxFontUtils::GetPrefsFontList is already basically what you want. I'm going to add a function that will turn that into a fontlist struct.

In the end, I'd like to kill off nsFont::EnumerateFamilies.  Additionally, I don't think code outside of gfx should be wandering the fontlist, mainly because the dynamic loading behavior managed by gfxFontGroup makes it so that gfxFontGroup::GetFontAt() really should be eliminated.  In it's place we should have higher-level abstractions, like a method to get the first valid font in the fontlist to pull font metrics. On bug 754215, you can see Jonathan starting to move to using something like GetValidFirstFont instead.  If MathML needs to be querying a font group, we should abstact that functionality and push it into gfxFontGroup.

I'll post some work-in-progress patches on bug 280443 so that you have an idea as to the where I'm heading with that bug.  Then we can discuss more what needs to happen for MathML.

Frédéric, thanks very much for your help with this, I'm happy to have help cleaning up fontlist handling. The MathML code is a bit of a stumbling block for me. ;)
Flags: needinfo?(jdaggett)
(In reply to Karl Tomlinson (needinfo?:karlt) from comment #36)
> (In reply to John Daggett (:jtd) from comment #27)
> > Glancing quickly over your patches, I don't think it would be hard to
> > implement a specific generic for math fonts (that would be resolved based on
> > the pref).  It should probably just mimic -moz-fixed in behavior.
> 
> That's almost what we want, but it is too easy for an author to specify
> font-family: Latin Modern, serif and so override the generic.

Hmmm, I don't quite understand the requirement here.  When performing font matching for MathML content, what's the precise definition of what you think is needed? The font matching code should use the MathML font list and ignore the 'font-family' value? Or it should interpret generics differently for MathML content? Or there should be an additional set of fonts tacked on at the end? As I described above, I think these special matching rules should live in gfxFontGroup rather than having MathML trying to perform fontlist ballet! ;)

Also, what's the precise definition of what you're looking for in a MathML fallback font? A font that supports stretchy characters with a 'math' table? Should those be prioritized over fonts that only support specific characters but lack a 'math' table (guessing yes here)?
Flags: needinfo?(karlt)
(In reply to Karl Tomlinson (needinfo?:karlt) from comment #36)
> (In reply to John Daggett (:jtd) from comment #27)
> > Glancing quickly over your patches, I don't think it would be hard to
> > implement a specific generic for math fonts (that would be resolved based on
> > the pref).  It should probably just mimic -moz-fixed in behavior.
> 
> That's almost what we want, but it is too easy for an author to specify
> font-family: Latin Modern, serif and so override the generic.

> I think what we want is to interpret generics differently within MathML,
> perhaps like a different lang but without exposing this to CSS/DOM.

(In reply to John Daggett (:jtd) from comment #39)
> Hmmm, I don't quite understand the requirement here.  When performing font
> matching for MathML content, what's the precise definition of what you think
> is needed? The font matching code should use the MathML font list and ignore
> the 'font-family' value?

No.

> Or it should interpret generics differently for MathML content?

Yes.  Currently the generic is interpreted differently by putting fonts in
font.mathfont-family before the generic for the language.  That's OK IMO.
What's not ideal currently though is that font.mathfont-family is applied only
to stretchy characters.

I don't know how necessary the generic for the language is, unless there is an
mtext element.  mtext doesn't need math fonts and should use the generic for
the host document language.  For mtext, It might be best to interpret generics
in the same way as in non-mathml elements.

> Or there should be an additional set of fonts tacked on at
> the end?

Possibly, but I'm guessing it would be better to try a math font before an
ordinary generic for the host document language.

> As I described above, I think these special matching rules should
> live in gfxFontGroup rather than having MathML trying to perform fontlist
> ballet! ;)

I'm neither for nor against that.

> Also, what's the precise definition of what you're looking for in a MathML
> fallback font? A font that supports stretchy characters with a 'math' table?

Ideally one font would support all mathematical characters in use and support
stretchy characters.  I assume this is what can be expected of modern fonts
with a 'math' table.  The math table also has other layout information, such
as the thickness of lines for fractions, subscript/superscript positioning
info, etc.

> Should those be prioritized over fonts that only support specific characters
> but lack a 'math' table (guessing yes here)?

I'm guessing yes here too.  The goal is to have all math drawn by the same
font so that stretchy characters are consistent with non-stretchy characters.

Currently there are some fonts which don't have a math table but do support
stretchy characters (through rules in Gecko), but these should eventually be
unnecessary.

Author specified fonts should still be prioritized, in author-specified order,
if provided.

(In reply to John Daggett (:jtd) from comment #38)
> In the end, I'd like to kill off nsFont::EnumerateFamilies.  Additionally, I
> don't think code outside of gfx should be wandering the fontlist, mainly
> because the dynamic loading behavior managed by gfxFontGroup makes it so
> that gfxFontGroup::GetFontAt() really should be eliminated.  In it's place
> we should have higher-level abstractions, like a method to get the first
> valid font in the fontlist to pull font metrics. On bug 754215, you can see
> Jonathan starting to move to using something like GetValidFirstFont instead.
> If MathML needs to be querying a font group, we should abstact that
> functionality and push it into gfxFontGroup.

If the author-specified font supports a character, but it doesn't support
stretching that character, then currently we look for another font to draw
stretched forms of that character.

Sometimes the size of braces or radicals, for example, can change the meaning
of the expression, so I think it is worth ensuring that we stretch such
characters.

Whether it is better to look for stretch support in fallback fonts or to
simply scale glyphs from the first font (without stretch support) may be up
for discussion.

If we still want to look for a font that supports stretching, then either
nsMathMLChar needs a way to enumerate fonts or families, or stretching code
needs to move into gfx.
Flags: needinfo?(karlt)
Discussing this a little bit more with Karl on IRC, it seems like what's needed is:

1. Font fallback that prioritizes math-table fonts for stretchy characters (as defined by a 'stretchy' attribute in the list in layout/mathml/mathfont.properties). So search once within <fontlist> + <mathml fallbacks> looking for math-table fonts that support a character, otherwise use first font that supports that character.

2. For non-stretchy characters, simply use normal font fallback

3. Not sure what to do with stretchy characters which can by synthesized via parts (e.g. { ( ] ). Like other stretchy characters search the entire list and use the first math-table font? Or use the first font that also supports the fallback parts when no math-table is present?

4. Karl thinks the 'serif' generic should be interpreted as pointing to or including the MathML fallback fonts. Other generics would remain as they are today.

Not so keen on (4), if we have (1) I'm not sure it's necessary. As for (3), I think it would be better to use the first math-font for { ( [ and only synthesize when necessary. But Karl seems to think we should follow the fontlist for these characters.

As I mentioned before, I think the fallback functionality can be pushed into gfx and enabled via a flag on gfxFontGroup, since that's the class that implements fallback and pref-font handling.  The only tricky part would be how to split the handling of fallback for the synthesized stretchy characters.
Not sure Jonathan will like this but I think in this case it might be worthwhile including a math-table font for just the stretchy characters, only activating it in situations where a math-table font wasn't available.  This is one case where I think were we could insure a decent level of support across all platforms without a huge cost.  There are only 224 stretchy characters so I think we could keep the size of the font fairly small.
(In reply to Karl Tomlinson (needinfo?:karlt) from comment #40)
> If we still want to look for a font that supports stretching, then either
> nsMathMLChar needs a way to enumerate fonts or families, or stretching code
> needs to move into gfx.

In general, I believe the stretching code should move to gfx as it's really just text layout (selecting glyph variants and building a bigger stretchy characters from several glyphs) not complex math layout. There are many issues with the nsMathMLChar code (for example bug 987028, bug 175850, bug 827039, bug 759462) and I think this would make it more consistent with normal text and would make easier to use the gfx code too (to pick glyph id, metrics etc). However, the nsMathMLChar code is complex, uses *.properties files for some non-MATH fonts and does some specific stuff for the font fallback. So a reasonable change in the short term would be to simplify the nsMathMLChar code, as I've tried to do so far. In the mid-term, we could do bug 1007090 when the users have migrated to MATH fonts (note: my main concern at the moment is the lack of good math italic with the new fonts, so I'd like to take bug 930504 ASAP). And in the long-term move the code to gfx, once it has been cleaned up.

In view of that, my answer to comment 41 would be to take the simplest approach and so:

- For 1), I would even remove the "otherwise use first font that supports that character" if that means using the *.properties files (i.e. instead just pick a glyph from the first font and apply the scale fallback)
- For 3), we should use the first math-table font, to be consistent with what we do for other stretchy characters in 1)
- 4) is not a good idea, because it would add some specific handling for the 'serif' generic.

Now, I understand Karl's approach is more pragmatic and we want to ensure that

a) we still have the *.properties file for backwards compatibility
b) we still have generic Unicode constructions for non-math fonts
c) we always have some fallback math fonts if the user changes the font-family.

In my opinion a), b) and c) could be ignored when MATH fonts become more available on user's systems, but I'm not exactly sure what to do for now.

(In reply to John Daggett (:jtd) from comment #42)
> Not sure Jonathan will like this but I think in this case it might be
> worthwhile including a math-table font for just the stretchy characters,

I'm not really font of packaging our own fonts within the product as I think this is better handled by the maintainer of the operating system. Also, there is the problem that these glyphs will render inconsistently with respect to the surrounding math... I see that it would help to address b) and c), though. But when MATH fonts are more available, I suspect this would become yet a special case to remove.

(In reply to John Daggett (:jtd) from comment #42)
> In the end, I'd like to kill off nsFont::EnumerateFamilies.

I believe this could be something we can do in the short term for MathML. It only remains one such call in nsMathMLChar to test all the fonts for the stretchy code. I suspect we could just search within the gfxFontGroup to do something like in comment 41. I'm not really sure how generic fonts will appear in the gfxFontGroup, though.
Logged bug 1009582 to cover whatever piece of font fallback functionality should move into gfx code.
> 03:44    nattokirai    are there sans-serif math fonts?
> 03:46    nattokirai    in other words, should *any* generic map to <math ml fallbacks> with mathml fallback?
> 03:46    nattokirai    or just serif?
> 03:46    karl    i don't expect any sans-serif math fonts; otherwise it would be hard to distinguish U+1D5BA MATHEMATICAL SANS-SERIF SMALL A from a
> 03:47    karl    sometimes, someone may specify sans-serif instead of using unicode to get such a character
> 03:47    nattokirai    maybe my question is really, for mathml elements what should sans-serif map to?
> 03:47    karl    because some tools are still 16-bit unicode
> 03:47    nattokirai    hmmm
> 03:48    nattokirai    what's that mean in the context of gecko code?
> 03:48    nattokirai    not sure what "someone may specify sans-serif instead of using unicode" means in terms of gecko

Just a comment on the sans-serif discussion. What Karl meant is that there are Unicode characters like U+1D5BA MATHEMATICAL SANS-SERIF SMALL A. So for example <math><mi>&#x1D5BA;</mi></math> will give a mathematical variable "a" with sans-serif style and this is supposed to provide some additional semantics per the MathML spec (just like bold variables are sometimes used to indicate a vector, double-struck variables some sets of numbers or fraktur variables some Lie algebras). I'm not really aware of concrete math usage for the serif style, though. There is an equivalent syntax <math><mi mathvariant="sans-serif">a</mi></math> where "someone may specify sans-serif instead of using unicode".

I don't think there is a sans-serif math font at the moment, but I don't believe that's something we should exclude either (in that case, I think mathvariant="sans-serif" will just have no effect and a fortiori authors won't try to use these characters for special semantics). Note that in bug 775060, we tried to find an appropriate math font to use with the default Firefox OS font (Fira Sans) and so it seems that it should ideally be a sans-serif font...
Depends on: 1014498
Depends on: 1014601
FYI, I've created a Firefox add-on to help configuring the math font to used:
https://addons.mozilla.org/en-US/firefox/addon/mathml-font-settings/
Attached patch default-math-font.patch (obsolete) — Splinter Review
So let's keep the font.mathfont-family preference for now and handle improvements to the fallback in bug 1009582.

This new patch applies on top of the patches of bug 280443 and only adds a new preference to set the default font-family on the <math> elements. However, it does not work at the moment because of bug 280443 comment 65 and bug 280443 comment 67.
Attachment #8408290 - Attachment is obsolete: true
Attachment #8410268 - Attachment is obsolete: true
Attachment #8411783 - Attachment is obsolete: true
Attachment #8434220 - Flags: feedback?(karlt)
Attachment #8434220 - Flags: feedback?(jdaggett)
Attachment #8434220 - Flags: feedback?(cam)
Comment on attachment 8434220 [details] [diff] [review]
default-math-font.patch

This adds a bit of configuration over the current situation, but it would be better if there was a way to make these fonts be used as fallback when the author fonts are not available, as if they were used for the generic font (or at least serif) within MathML.
Attachment #8434220 - Flags: feedback?(karlt) → feedback+
(In reply to Karl Tomlinson (needinfo?:karlt) from comment #48)
> Comment on attachment 8434220 [details] [diff] [review]
> default-math-font.patch
> 
> This adds a bit of configuration over the current situation, but it would be
> better if there was a way to make these fonts be used as fallback when the
> author fonts are not available, as if they were used for the generic font
> (or at least serif) within MathML.

The point of this bug was to make the default math fonts configurable, just like it is now possible to do with the default document fonts. As I see the difference between "default fonts" and "fallback fonts" does not really exist for the document fonts, since the fallback is used for the root of the HTML document, which does not inherit from any parent by definition.  Currently "fallback fonts" for nsMathMLChar are given by font.mathfont-family ; and the idea would be to extend this to the whole <math> element (by using frame flags or something). However, that will still not make the "default fonts" for the <math> configurable since the CSS spec says the font-family is inherited or taken from a user-agent stylesheet. So the only way is to make the user-agent stylesheet configurable or to extend the spec with a different behavior like introducing the CSS -moz-mathfont in my fist attempt or making the font-family: inherited + inventing a special "math" language. At this point, it's not clear what's best.
Attachment #8434220 - Flags: feedback?(jdaggett)
Attachment #8434220 - Flags: feedback?(cam)
@Karl:

So coming back to this, I think your proposal is to do

math {
  font-family: serif;
}

in mathml.css and have something for the MathML frames to magically insert the font.mathfont-family list before the first generic font.

Then this will make the default font-family customizable (as I wanted when I opened this bug) and provide math fonts to use as a fallback in MathML 
frames (as you suggest). This would actually supersede the code in nsMathMLChar to insert that fallback for the stretchy operators.

However, I don't see a clean way to insert this font.mathfont-family. One ugly & innefficient solution would be to do as in nsMathMLChar and call something like NormalizeDefaultFont each time nsStyleContext::StyleFont() is called...
Flags: needinfo?(karlt)
(In reply to Frédéric Wang (:fredw) from comment #50)
> @Karl:
> 
> So coming back to this, I think your proposal is to do
> 
> math {
>   font-family: serif;
> }
> 
> in mathml.css and have something for the MathML frames to magically insert
> the font.mathfont-family list before the first generic font.

Yes, but font.mathfont-family could replace "serif".

> However, I don't see a clean way to insert this font.mathfont-family

"serif" is currently always replaced by a list of families associated with a particular "language group".  I imagine that replacement would come instead from font.mathfont-family when in MathML elements.
Flags: needinfo?(karlt)
(In reply to Karl Tomlinson (:karlt) from comment #51)
> "serif" is currently always replaced by a list of families associated with a
> particular "language group".  I imagine that replacement would come instead
> from font.mathfont-family when in MathML elements.

Unfortunately, I think we don't have such "language group" available for math at the moment as said in previous comments. Who does know this code and how it could be adapted to work with MathML?
Depends on: 1069929
Keywords: helpwanted
Whiteboard: [see comment 50]
No longer blocks: 775060
Someone wrote to me today about that issue again, so I'll try to make this move forward...

To summarize, we need special fonts when writing mathematics. Essentially, we want this font selection to behave as normal text: use CSS font properties if they are specified and otherwise default to the "font.*" user preferences corresponding to the language of the current node. So by adding an "x-math" language for MathML nodes, users could configure their preferred font for MathML and we could fallback to known math fonts when necessary. My attempts with attachment 8408290 [details] [diff] [review] or attachment 8434220 [details] [diff] [review] makes the former possible, but not the latter.

Contrary to other languages, the "x-math" language is not something that could be determined as a "system language" or a "document language". Also, we don't want authors to specify an explicit lang="x-math" attribute but to automatically switch to the "x-math" language when encountering a <math> element.

So essentially, we want a behavior equivalent to setting "math { -x-lang: "x-math"; }" in our user agent stylesheet mathml.css and adding "font.*.x-math" preferences into our about:config. Of course -x-lang is not a real CSS property and the "x-math" language is probably not defined in any spec, so we need an equivalent way to switch to such "x-math" language.

Any suggestion?
Flags: needinfo?(roc)
Flags: needinfo?(jdaggett)
Flags: needinfo?(dbaron)
Flags: needinfo?(cam)
Seems to me that making nsIContent::GetLang return a magic "math" language for MathML nodes would be pretty easy!
Flags: needinfo?(roc)
Attached patch Add x-math language (obsolete) — Splinter Review
nsIContent::GetLang is not used to set the -x-lang "CSS property". However, it is used to implement the :lang pseudo class, so thanks for mentioning it.

Currently, the -x-lang "CSS property" is set in nsGenericHTMLElement::MapCommonAttributesIntoExceptHidden, but of course this only works when we have an explicit lang attribute...

I'm attaching a testcase as well as a patch showing what I want to do:

1) Move the hardcoded list from layout/mathml/mathml.css into the preference options, so that the default math font will become configurable.

2) Remove one FontFamilyList manipulation that John didn't like and the corresponding "font.mathfont-family" preference ; these fallbacks are now expected to be taken from the font.*.x-math.

3) Add the x-math language and set it into nsIContent::GetLang. This makes the :lang pseudo class works as expected in the testcase.

I now want to set -x-lang to x-math on MathML nodes, so that the font.*.x-math are really used. The obvious way is to make -x-lang an internal property usable from the mathml.css user agent stylesheet... However, perhaps there is a better option?
Attachment #8598124 - Flags: feedback?(roc)
Attached file Testcase for x-math language (obsolete) —
As you can see the :lang pseudo class is correctly used to make the text in green. However, the font style is only take with an explicit lang="x-math" not with the <math> tag.
(In reply to Frédéric Wang (:fredw) from comment #55)
> I now want to set -x-lang to x-math on MathML nodes, so that the
> font.*.x-math are really used. The obvious way is to make -x-lang an
> internal property usable from the mathml.css user agent stylesheet...
> However, perhaps there is a better option?

Can't you add logic to nsMathMLElement::MapMathMLAttributesInto, similar to what nsGenericHTMLElement::MapCommonAttributesIntoExceptHidden has for "lang", except that you do it unconditionally even if there's no attribute?

This is really a question for dbaron (or heycam, or bz) though.
(In reply to Robert O'Callahan (:roc) (Mozilla Corporation) from comment #58)
> Can't you add logic to nsMathMLElement::MapMathMLAttributesInto, similar to
> what nsGenericHTMLElement::MapCommonAttributesIntoExceptHidden has for
> "lang", except that you do it unconditionally even if there's no attribute?
> 
> This is really a question for dbaron (or heycam, or bz) though.

Well, I should have mention it, but I tried to do that... When inserted outside of any if statement, this make the application crash ; When inserted inside the if (aData->mSIDs & NS_STYLE_INHERIT_BIT(Font), this only works if an attribute mapped to a font property is attached to the node (e.g. mathsize).
(In reply to Frédéric Wang (:fredw) from comment #59)
> Well, I should have mention it, but I tried to do that... When inserted
> outside of any if statement, this make the application crash ; When inserted
> inside the if (aData->mSIDs & NS_STYLE_INHERIT_BIT(Font), this only works if
> an attribute mapped to a font property is attached to the node (e.g.
> mathsize).

Instead, you could do something in nsHTMLStyleSheet::RulesMatching right after:
  nsString lang;
  if (aData->mElement->GetAttr(kNameSpaceID_XML, nsGkAtoms::lang, lang)) {
    ruleWalker->Forward(LangRuleFor(lang));
  }
that does the equivalent, but with LangRuleFor(NS_LITERAL_STRING("x-math")) or whatever it is.

I expect that exposes it to the web less than changing nsIContent::GetLang (it's probably good not to expose custom names like "x-math"), although I haven't traced through the other callers of GetLang.
Flags: needinfo?(dbaron)
Flags: needinfo?(jdaggett)
Flags: needinfo?(cam)
This patch implements David's suggestion.

Some remarks:

1) The change in nsHTMLStyleSheet::RulesMatching makes x-math overrides the values of xml:lang and lang attributes on the <math> element ; I don't know whether we want that or not. In practice, I believe people really want to use math fonts for MathML but they may want to use language-specific scripts on the <mtext> elements (in that case they can use a lang attribute or special CSS on these elements).

2) I also removed the change from nsIContent::GetLang. This means in particular that one can no longer use the :lang(x-math) pseudo-element to match the <math> tag. Again, I don't know whether we want that or not, but this will probably not be useful in practice.

3) To continue the idea of comment 17, it would be good if some HTML spec could clarify this behavior for font on the <math> tag and the relationship with the lang attribute and :lang selector.

Any opinion?

@karl: do you remember why we used "DejaVu Sans" (maybe it has more math glyphs than Serif?). For now, I replaced it with DejaVu Serif in font.name.serif.x-math...
Attachment #8598124 - Attachment is obsolete: true
Attachment #8598124 - Flags: feedback?(roc)
Attachment #8599982 - Flags: feedback?(roc)
Attachment #8599982 - Flags: feedback?(karlt)
Comment on attachment 8599982 [details] [diff] [review]
Use font.*.x-math font preferences for MathML

Review of attachment 8599982 [details] [diff] [review]:
-----------------------------------------------------------------

Looks good to me.

I guess we should get this standardized so that in all browsers, authors need to set 'lang' on <mtext> to rather than inheriting language through <math>.
Attachment #8599982 - Flags: feedback?(roc) → feedback+
Unfortunately, we actually still need to insert the fallback fonts manually in nsMathMLChar :-(
Attachment #8434220 - Attachment is obsolete: true
Attachment #8598125 - Attachment is obsolete: true
Attachment #8598126 - Attachment is obsolete: true
Attachment #8599982 - Attachment is obsolete: true
Attachment #8599982 - Flags: feedback?(karlt)
Blocks: 1160455
Blocks: 1160456
Attachment #8602977 - Attachment is obsolete: true
Attachment #8603694 - Flags: review?(karlt)
User Story: (updated)
Whiteboard: [see comment 50]
Comment on attachment 8603694 [details] [diff] [review]
Use font.*.x-math font preferences for MathML

(In reply to Frédéric Wang (:fredw) from comment #61)
> 1) The change in nsHTMLStyleSheet::RulesMatching makes x-math overrides the
> values of xml:lang and lang attributes on the <math> element ; I don't know
> whether we want that or not. In practice, I believe people really want to
> use math fonts for MathML but they may want to use language-specific scripts
> on the <mtext> elements (in that case they can use a lang attribute or
> special CSS on these elements).

Yes.

> 2) I also removed the change from nsIContent::GetLang. This means in
> particular that one can no longer use the :lang(x-math) pseudo-element to
> match the <math> tag. Again, I don't know whether we want that or not, but
> this will probably not be useful in practice.

I think that was a good change.

> 3) To continue the idea of comment 17, it would be good if some HTML spec
> could clarify this behavior for font on the <math> tag and the relationship
> with the lang attribute and :lang selector.
> 
> Any opinion?

(In reply to Robert O'Callahan (:roc) (Mozilla Corporation) from comment #62)
> I guess we should get this standardized so that in all browsers, authors
> need to set 'lang' on <mtext> to rather than inheriting language through
> <math>.

I don't think we should be doing that.  Here we only want to select a
different font.  We don't want any other effects from :lang() selectors or
inheritance.  I don't know whether there are any non-font effects from the
language change here, but I assume the mechanism used here is assuming that
there are not.

>+  // Set the language to "x-math" on the <math> element, so that appropriate
>+  // font settings are used for MathML.
>+  if (aData->mElement->IsMathMLElement(nsGkAtoms::math)) {
>+    nsGkAtoms::x_math->ToString(lang);
>+    ruleWalker->Forward(LangRuleFor(lang));
>+  }

I don't know what this does, so please get a style reviewer to review this.

Can this be done only on non-mtext token elements?
Then there is no inheritance causing unwanted effects on descendants.

If this approach is exposed to content, then I wonder whether a layout
solution might be better here.  nsTextFrame might be the place to start
looking for such a solution.  gfxTextRunFactory::TEXT_USE_MATH_SCRIPT looks
very similar to what we want.  Perhaps something similar on the gfxFontGroup
might be able to be used for font selection and replace the existing
gfxTextRunFactory::TEXT_USE_MATH_SCRIPT.  Perhaps
nsLayoutUtils::GetFontMetricsForFrame() might be the place to do that, but it
needs to know but it is easier if the code is somewhere that
TEXT_IS_IN_TOKEN_MATHML can be tested.

However, I'm happy with this approach if a style reviewer is happy.

> # lang in (X)HTML/XML documents, which they shouldn't. (see bug 256257)
> #x-beng=x-beng
> #x-cans=x-cans
> #x-ethi=x-ethi
> #x-guru=x-guru
> #x-gujr=x-gujr
> #x-khmr=x-khmr
> #x-mlym=x-mlym
>+x-math=x-math

Please move the new line to above the comment, so that it is clear the comment
doesn't apply to this line.

>-== stretchy-largeop-1.html stretchy-largeop-1-ref.html
>+random-if(gtk2Widget) == stretchy-largeop-1.html stretchy-largeop-1-ref.html

Please don't mark the tests random unless the results are non-deterministic.
If tests are marked random, then we won't notice when the start to work again.

I assume there is nothing in this patch to make the results non-deterministic,
but what is causing the change in behavior?

>+    <math style="font-family: serif; font-size: 40px;">
>+      <mtext>x-math language</mtext>
>+    </math>

Please use a different token element in the test, because mtext would be better
rendered using fonts for the document language.

>-  font-family: MathJax_Main, STIXGeneral, Cambria, Cambria Math, XITS, Latin Modern Math, DejaVu Serif, DejaVu Sans, Times, Lucida Sans Unicode, OpenSymbol, Standard Symbols L, serif;

Please note in the commit message that the preferred font is changing to Latin
Modern Math (or Cambria).

>+pref("font.name.serif.x-math", "Latin Modern Math, XITS Math, STIX Math, Asana Math, TeX Gyre Bonum Math, TeX Gyre Pagella Math, TeX Gyre Termes Math, Neo Euler, Lucida Bright Math, MathJax_Main, STIXNonUnicode, STIXSizeOneSym, STIXGeneral, Standard Symbols L, DejaVu Serif, serif");
>+pref("font.name.sans-serif.x-math", "DejaVu Sans, sans-serif");
>+pref("font.name.monospace.x-math", "monospace");

STIXSizeOneSym should not be before other families because it will render
characters in the wrong size.

I think it and STIXNonUnicode can be removed because the associated
mathfont*.properties files no longer exist.

The UI may only be able to set one family here.  The simplest solution I think
would be to set the font.name-list.serif.x-math to the full version, and have
only one family font.name.serif.x-math, which for editing in the UI and
preferred.  Maybe font.name.serif.x-math can be empty even.  I don't know how
the UI might behave in that case.

(In reply to Frédéric Wang (:fredw) from comment #61)
> @karl: do you remember why we used "DejaVu Sans" (maybe it has more math
> glyphs than Serif?). For now, I replaced it with DejaVu Serif in
> font.name.serif.x-math...

I think DejaVu Sans had more maths characters.
DejaVu Serif was used first for basic/common characters and DejaVu Sans for
fallback.  Sans may have had better looking stretchy parentheses than Serif -
I don't recall clearly.

DejaVu Sans has some Mathematical Alphanumeric Symbols coverage not in DejaVu
Serif so I expect it is worth keeping DejaVu Sans as a fallback.

>+// mathml.css sets font-size to "inherit" and font-family to "serif" so only
>+// font.name.*.x-math and font.minimum-size.x-math are really relevant.
>+pref("font.default.x-math", "serif");
>+pref("font.minimum-size.x-math", 0);
>+pref("font.size.variable.x-math", 16);
>+pref("font.size.fixed.x-math", 13);

Would it make sense to remove these prefs then?

>+pref("font.name.serif.x-math", "Cambria, Cambria Math, MathJax_Main, STIXNonUnicode, STIXSizeOneSym, STIXGeneral, Asana Math, Symbol, DejaVu Serif, Times New Roman");

Are you intentionally preferring Cambria over the Latin Modern Math used on
other platforms?

If so, please note in the commit message.

The relative order of MathJax_Main and STIXGeneral is also different here from what is is on other platforms.
Is there a reason for that?
Attachment #8603694 - Flags: review?(karlt) → review-
(In reply to Karl Tomlinson (ni?:karlt) from comment #67)
> Can this be done only on non-mtext token elements?
> Perhaps nsLayoutUtils::GetFontMetricsForFrame() might be the place to do that, but it
> needs to know but it is easier if the code is somewhere that
> TEXT_IS_IN_TOKEN_MATHML can be tested.
> 
> However, I'm happy with this approach if a style reviewer is happy.

I haven't checked the details, but if I understand you are proposing to only apply the font style on the non-mtext token elements. Note that here we want the whole formula to be styled with a specific font, not just the token elements. In particular, the values from the MathConstants are already used for spacing, line thickness etc and we may add more MATH features later. So a content approach would essentially have to reimplement what the style systems does (and will potentially be more error-prone, less efficient, inconsistent with CSS for page authors...)

Now that bug 1014498 is fixed, I think we will be able to get more or less the same list for all platforms. I'll give it a try later.
Attachment #8603694 - Attachment is obsolete: true
@karl: So it now looks much better:

https://treeherder.mozilla.org/#/jobs?repo=try&revision=6c1ef2435ae1

mfenced-11.html now passes on Windows with Direct Write and mpadded-7.html, mpadded-8.html, mpadded-9.html still passes on B2G (although I'll need to check exactly which config). No more problems on Linux. However, Windows XP has still new failures (I'm not sure if it's specific to the GDI backend or to the fact that they don't have Cambria). So maybe we can mark them as failing for now?
Flags: needinfo?(karlt)
Comment on attachment 8609372 [details] [diff] [review]
Use font.*.x-math font preferences for MathML

(In reply to Karl Tomlinson (ni?:karlt) from comment #67)
> >+  // Set the language to "x-math" on the <math> element, so that appropriate
> >+  // font settings are used for MathML.
> >+  if (aData->mElement->IsMathMLElement(nsGkAtoms::math)) {
> >+    nsGkAtoms::x_math->ToString(lang);
> >+    ruleWalker->Forward(LangRuleFor(lang));
> >+  }
> 
> I don't know what this does, so please get a style reviewer to review this.

Cameron: can you please review the change in layout/style/nsHTMLStyleSheet.cpp?
Attachment #8609372 - Flags: review?(cam)
Comment on attachment 8609372 [details] [diff] [review]
Use font.*.x-math font preferences for MathML

r=me on the -x-lang setting, but could you update the comment on LangRule in nsHTMLStyleSheet to mention that we also create one extra rule for this on <math> elements?
Flags: needinfo?(karlt)
Attachment #8609372 - Flags: review?(cam) → review+
(In reply to Cameron McCormack (:heycam) from comment #73)
> r=me on the -x-lang setting, but could you update the comment on LangRule in
> nsHTMLStyleSheet to mention that we also create one extra rule for this on
> <math> elements?

in nsHTMLStyleSheet.h
Comment on attachment 8609743 [details] [diff] [review]
Use font.*.x-math font preferences for MathML

(In reply to Karl Tomlinson (ni?:karlt) from comment #67)
> >-  font-family: MathJax_Main, STIXGeneral, Cambria, Cambria Math, XITS, Latin Modern Math, DejaVu Serif, DejaVu Sans, Times, Lucida Sans Unicode, OpenSymbol, Standard Symbols L, serif;
> 
> Please note in the commit message that the preferred font is changing to
> Latin Modern Math (or Cambria).

Please add a line to the commit message for this.

(In reply to Frédéric Wang (:fredw) from comment #70)
> However, Windows XP
> has still new failures (I'm not sure if it's specific to the GDI backend or
> to the fact that they don't have Cambria). So maybe we can mark them as
> failing for now?

I suspect the mmultiscripts-1.html change is more likely an issue with the
mmultiscripts implementation or the test, so yes, marking as failing is good.

The mfrac results are not obviously affected by changes here, so changing the annotation from random to fails is good thanks.

>     nsAutoTArray<nsString, 10> mathFallbacks;
>-    gfxFontUtils::GetPrefsFontList("font.mathfont-family", mathFallbacks);
>+    gfxFontUtils::GetPrefsFontList("font.name.serif.x-math", mathFallbacks);
>+    gfxFontUtils::AppendPrefsFontList("font.name-list.serif.x-math",
>+                                      mathFallbacks);

The auto array is not long enough to hold all the pref fonts.  It's auto
length should probably be increased from 10 to at least the length of the
longest default list (including the extra one from font.name.)"
Attachment #8609743 - Flags: review?(karlt) → review+
User Story: (updated)
https://hg.mozilla.org/mozilla-central/rev/ac4d26019611
Status: NEW → RESOLVED
Closed: 9 years ago
Resolution: --- → FIXED
Target Milestone: --- → mozilla41
Blocks: 1170918
User Story: (updated)
I have added the user story of this bug (I guess it summarizes it wonderfully) to the release notes for Firefox 41.
https://developer.mozilla.org/en-US/Firefox/Releases/41#MathML
Depends on: 1205570
Depends on: 1219068
Blocks: 1788937
Summary: Default fonts for MathML → [meta] Default fonts for MathML
You need to log in before you can comment on or make changes to this bug.