commit 5be0dfe31a547aaf8a492927ad1e98fff03340c4
parent e7efe8e2d1b972ed4a073065bc99cfb08f6c31e9
Author: Frédéric Wang <fwang@igalia.com>
Date: Tue, 6 Jan 2026 15:11:02 +0000
Bug 1993425 - gfxFcPlatformFontList: Handle "math" as a generic family name. r=jfkthame
When `mathml.font_family_math.enabled` is set to true, we do the
following changes:
- If the preference look in `font.name.serif.x-math` or
`font.name-list.serif.x-math` result in "math" being returned, then
resolve the font list via fontconfig, using "und-zmth" lang.
- Make `gfxFcPlatformFontList::GetFontList` handle "math" the same
as generic names "serif", "sans-serif" or "monospace".
Differential Revision: https://phabricator.services.mozilla.com/D276968
Diffstat:
1 file changed, 55 insertions(+), 28 deletions(-)
diff --git a/gfx/thebes/gfxFcPlatformFontList.cpp b/gfx/thebes/gfxFcPlatformFontList.cpp
@@ -2188,29 +2188,33 @@ void gfxFcPlatformFontList::GetFontList(nsAtom* aLangGroup,
// Get the list of font family names using fontconfig
GetSystemFontList(aListOfFonts, aLangGroup);
- // Under Linux, the generics "serif", "sans-serif" and "monospace"
+ // Under Linux, the generics "serif", "sans-serif", "monospace" and "math"
// are included in the pref fontlist. These map to whatever fontconfig
// decides they should be for a given language, rather than one of the
// fonts listed in the prefs font lists (e.g. font.name.*, font.name-list.*)
- bool serif = false, sansSerif = false, monospace = false;
- if (aGenericFamily.IsEmpty())
- serif = sansSerif = monospace = true;
- else if (aGenericFamily.LowerCaseEqualsLiteral("serif"))
+ bool serif = false, sansSerif = false, monospace = false, math = false;
+ if (aGenericFamily.IsEmpty()) {
+ serif = sansSerif = monospace = math = true;
+ } else if (aGenericFamily.LowerCaseEqualsLiteral("serif")) {
serif = true;
- else if (aGenericFamily.LowerCaseEqualsLiteral("sans-serif"))
+ } else if (aGenericFamily.LowerCaseEqualsLiteral("sans-serif")) {
sansSerif = true;
- else if (aGenericFamily.LowerCaseEqualsLiteral("monospace"))
+ } else if (aGenericFamily.LowerCaseEqualsLiteral("monospace")) {
monospace = true;
- else if (aGenericFamily.LowerCaseEqualsLiteral("cursive") ||
- aGenericFamily.LowerCaseEqualsLiteral("fantasy") ||
- aGenericFamily.LowerCaseEqualsLiteral("math"))
+ } else if (StaticPrefs::mathml_font_family_math_enabled() &&
+ aGenericFamily.LowerCaseEqualsLiteral("math")) {
+ math = true;
+ } else if (aGenericFamily.LowerCaseEqualsLiteral("cursive") ||
+ aGenericFamily.LowerCaseEqualsLiteral("fantasy")) {
serif = sansSerif = true;
- else
+ } else {
MOZ_ASSERT_UNREACHABLE("unexpected CSS generic font family");
+ }
// The first in the list becomes the default in
// FontBuilder.readFontSelection() if the preference-selected font is not
// available, so put system configured defaults first.
+ if (math) aListOfFonts.InsertElementAt(0, u"math"_ns);
if (monospace) aListOfFonts.InsertElementAt(0, u"monospace"_ns);
if (sansSerif) aListOfFonts.InsertElementAt(0, u"sans-serif"_ns);
if (serif) aListOfFonts.InsertElementAt(0, u"serif"_ns);
@@ -2567,10 +2571,12 @@ void gfxFcPlatformFontList::AddGenericFonts(
if (!fontlistValue.IsEmpty()) {
if (!fontlistValue.EqualsLiteral("serif") &&
!fontlistValue.EqualsLiteral("sans-serif") &&
- !fontlistValue.EqualsLiteral("monospace")) {
+ !fontlistValue.EqualsLiteral("monospace") &&
+ !(StaticPrefs::mathml_font_family_math_enabled() &&
+ fontlistValue.EqualsLiteral("math"))) {
usePrefFontList = true;
} else {
- // serif, sans-serif or monospace was specified
+ // serif, sans-serif, monospace or math was specified
genericToLookup = fontlistValue;
}
}
@@ -2779,16 +2785,34 @@ struct MozLangGroupData {
};
const MozLangGroupData MozLangGroups[] = {
- {nsGkAtoms::x_western, "en"}, {nsGkAtoms::x_cyrillic, "ru"},
- {nsGkAtoms::x_devanagari, "hi"}, {nsGkAtoms::x_tamil, "ta"},
- {nsGkAtoms::x_armn, "hy"}, {nsGkAtoms::x_beng, "bn"},
- {nsGkAtoms::x_cans, "iu"}, {nsGkAtoms::x_ethi, "am"},
- {nsGkAtoms::x_geor, "ka"}, {nsGkAtoms::x_gujr, "gu"},
- {nsGkAtoms::x_guru, "pa"}, {nsGkAtoms::x_khmr, "km"},
- {nsGkAtoms::x_knda, "kn"}, {nsGkAtoms::x_mlym, "ml"},
- {nsGkAtoms::x_orya, "or"}, {nsGkAtoms::x_sinh, "si"},
- {nsGkAtoms::x_tamil, "ta"}, {nsGkAtoms::x_telu, "te"},
- {nsGkAtoms::x_tibt, "bo"}, {nsGkAtoms::Unicode, 0}};
+ // clang-format off
+ {nsGkAtoms::x_western, "en"},
+ {nsGkAtoms::x_cyrillic, "ru"},
+ {nsGkAtoms::x_devanagari, "hi"},
+ {nsGkAtoms::x_tamil, "ta"},
+ {nsGkAtoms::x_armn, "hy"},
+ {nsGkAtoms::x_beng, "bn"},
+ {nsGkAtoms::x_cans, "iu"},
+ {nsGkAtoms::x_ethi, "am"},
+ {nsGkAtoms::x_geor, "ka"},
+ {nsGkAtoms::x_gujr, "gu"},
+ {nsGkAtoms::x_guru, "pa"},
+ {nsGkAtoms::x_khmr, "km"},
+ {nsGkAtoms::x_knda, "kn"},
+ // Zmth is a script subtag for mathematical notation. fontconfig uses
+ // "und-zmth" to select math fonts:
+ // https://www.iana.org/assignments/language-subtag-registry/language-subtag-registry
+ // https://gitlab.freedesktop.org/fontconfig/fontconfig/-/blob/main/fc-lang/und_zmth.orth
+ {nsGkAtoms::x_math, "und-zmth"},
+ {nsGkAtoms::x_mlym, "ml"},
+ {nsGkAtoms::x_orya, "or"},
+ {nsGkAtoms::x_sinh, "si"},
+ {nsGkAtoms::x_tamil, "ta"},
+ {nsGkAtoms::x_telu, "te"},
+ {nsGkAtoms::x_tibt, "bo"},
+ {nsGkAtoms::Unicode, 0}
+ // clang-format on
+};
bool gfxFcPlatformFontList::TryLangForGroup(const nsACString& aOSLang,
nsAtom* aLangGroup,
@@ -2832,11 +2856,14 @@ void gfxFcPlatformFontList::GetSampleLangForGroup(nsAtom* aLanguage,
// set up lang string
const MozLangGroupData* mozLangGroup = nullptr;
- // -- look it up in the list of moz lang groups
- for (unsigned int i = 0; i < std::size(MozLangGroups); ++i) {
- if (aLanguage == MozLangGroups[i].mozLangGroup) {
- mozLangGroup = &MozLangGroups[i];
- break;
+ if (aLanguage != nsGkAtoms::x_math ||
+ StaticPrefs::mathml_font_family_math_enabled()) {
+ // -- look it up in the list of moz lang groups
+ for (unsigned int i = 0; i < std::size(MozLangGroups); ++i) {
+ if (aLanguage == MozLangGroups[i].mozLangGroup) {
+ mozLangGroup = &MozLangGroups[i];
+ break;
+ }
}
}