diff --git a/gfx/thebes/gfxPlatformFontList.cpp b/gfx/thebes/gfxPlatformFontList.cpp index 3128b88f75cf..82d82cd077d7 100644 --- a/gfx/thebes/gfxPlatformFontList.cpp +++ b/gfx/thebes/gfxPlatformFontList.cpp @@ -2470,131 +2470,8 @@ void gfxPlatformFontList::AppendCJKPrefLangs(eFontPrefLang aPrefLangs[], AppendPrefLang(aPrefLangs, aLen, aPageLang); } - // if not set up, set up the default CJK order, based on accept lang - // settings and locale - if (mCJKPrefLangs.Length() == 0) { - // temp array - eFontPrefLang tempPrefLangs[kMaxLenPrefLangList]; - uint32_t tempLen = 0; - - // Add the CJK pref fonts from accept languages, the order should be same - // order. We use gfxFontUtils::GetPrefsFontList to read the list even - // though it's not actually a list of fonts but of lang codes; the format - // is the same. - AutoTArray list; - gfxFontUtils::GetPrefsFontList("intl.accept_languages", list, true); - for (const auto& lang : list) { - eFontPrefLang fpl = GetFontPrefLangFor(lang.get()); - switch (fpl) { - case eFontPrefLang_Japanese: - case eFontPrefLang_Korean: - case eFontPrefLang_ChineseCN: - case eFontPrefLang_ChineseHK: - case eFontPrefLang_ChineseTW: - AppendPrefLang(tempPrefLangs, tempLen, fpl); - break; - default: - break; - } - } - - // Try using app's locale - nsAutoCString localeStr; - LocaleService::GetInstance()->GetAppLocaleAsBCP47(localeStr); - - { - Locale locale; - if (LocaleParser::TryParse(localeStr, locale).isOk() && - locale.Canonicalize().isOk()) { - if (locale.Language().EqualTo("ja")) { - AppendPrefLang(tempPrefLangs, tempLen, eFontPrefLang_Japanese); - } else if (locale.Language().EqualTo("zh")) { - if (locale.Region().EqualTo("CN")) { - AppendPrefLang(tempPrefLangs, tempLen, eFontPrefLang_ChineseCN); - } else if (locale.Region().EqualTo("TW")) { - AppendPrefLang(tempPrefLangs, tempLen, eFontPrefLang_ChineseTW); - } else if (locale.Region().EqualTo("HK")) { - AppendPrefLang(tempPrefLangs, tempLen, eFontPrefLang_ChineseHK); - } - } else if (locale.Language().EqualTo("ko")) { - AppendPrefLang(tempPrefLangs, tempLen, eFontPrefLang_Korean); - } - } - } - - // Then add the known CJK prefs in order of system preferred locales - AutoTArray prefLocales; - prefLocales.AppendElement("ja"_ns); - prefLocales.AppendElement("zh-CN"_ns); - prefLocales.AppendElement("zh-TW"_ns); - prefLocales.AppendElement("zh-HK"_ns); - prefLocales.AppendElement("ko"_ns); - - AutoTArray sysLocales; - AutoTArray negLocales; - if (NS_SUCCEEDED( - OSPreferences::GetInstance()->GetSystemLocales(sysLocales))) { - LocaleService::GetInstance()->NegotiateLanguages( - sysLocales, prefLocales, ""_ns, - LocaleService::kLangNegStrategyFiltering, negLocales); - for (const auto& localeStr : negLocales) { - Locale locale; - if (LocaleParser::TryParse(localeStr, locale).isOk() && - locale.Canonicalize().isOk()) { - if (locale.Language().EqualTo("ja")) { - AppendPrefLang(tempPrefLangs, tempLen, eFontPrefLang_Japanese); - } else if (locale.Language().EqualTo("zh")) { - if (locale.Region().EqualTo("CN")) { - AppendPrefLang(tempPrefLangs, tempLen, eFontPrefLang_ChineseCN); - } else if (locale.Region().EqualTo("TW")) { - AppendPrefLang(tempPrefLangs, tempLen, eFontPrefLang_ChineseTW); - } else if (locale.Region().EqualTo("HK")) { - AppendPrefLang(tempPrefLangs, tempLen, eFontPrefLang_ChineseHK); - } - } else if (locale.Language().EqualTo("ko")) { - AppendPrefLang(tempPrefLangs, tempLen, eFontPrefLang_Korean); - } - } - } - } - - // Last resort... set up CJK font prefs in the order listed by the user- - // configurable ordering pref. - gfxFontUtils::GetPrefsFontList(kCJKFallbackOrderPref, list); - for (const auto& item : list) { - eFontPrefLang fpl = GetFontPrefLangFor(item.get()); - switch (fpl) { - case eFontPrefLang_Japanese: - case eFontPrefLang_Korean: - case eFontPrefLang_ChineseCN: - case eFontPrefLang_ChineseHK: - case eFontPrefLang_ChineseTW: - AppendPrefLang(tempPrefLangs, tempLen, fpl); - break; - default: - break; - } - } - - // Truly-last resort... try Chinese font prefs before Japanese because - // they tend to have more complete character coverage, and therefore less - // risk of "ransom-note" effects. - // (If the kCJKFallbackOrderPref was fully populated, as it is by default, - // this will do nothing as all these values are already present.) - AppendPrefLang(tempPrefLangs, tempLen, eFontPrefLang_ChineseCN); - AppendPrefLang(tempPrefLangs, tempLen, eFontPrefLang_ChineseHK); - AppendPrefLang(tempPrefLangs, tempLen, eFontPrefLang_ChineseTW); - AppendPrefLang(tempPrefLangs, tempLen, eFontPrefLang_Japanese); - AppendPrefLang(tempPrefLangs, tempLen, eFontPrefLang_Korean); - - // copy into the cached array - for (const auto lang : Span(tempPrefLangs, tempLen)) { - mCJKPrefLangs.AppendElement(lang); - } - } - // append in cached CJK langs - for (const auto lang : mCJKPrefLangs) { + for (const auto lang : GetFontPrefs()->CJKPrefLangs()) { AppendPrefLang(aPrefLangs, aLen, eFontPrefLang(lang)); } } @@ -2934,7 +2811,6 @@ void gfxPlatformFontList::ClearLangGroupPrefFontsLocked() { pref = nullptr; } } - mCJKPrefLangs.Clear(); mEmojiPrefFont = nullptr; // Create a new FontPrefs and replace the existing one. @@ -3338,6 +3214,125 @@ void gfxPlatformFontList::FontPrefs::Init() { } } mEmojiHasUserValue = Preferences::HasUserValue("font.name-list.emoji"); + + // Record the default CJK order, based on accept-lang settings and locale. + eFontPrefLang tempPrefLangs[kMaxLenPrefLangList]; + uint32_t tempLen = 0; + + // Add the CJK pref fonts from accept languages, the order should be same + // order. We use gfxFontUtils::GetPrefsFontList to read the list even + // though it's not actually a list of fonts but of lang codes; the format + // is the same. + AutoTArray list; + gfxFontUtils::GetPrefsFontList("intl.accept_languages", list, true); + for (const auto& lang : list) { + eFontPrefLang fpl = GetFontPrefLangFor(lang.get()); + switch (fpl) { + case eFontPrefLang_Japanese: + case eFontPrefLang_Korean: + case eFontPrefLang_ChineseCN: + case eFontPrefLang_ChineseHK: + case eFontPrefLang_ChineseTW: + AppendPrefLang(tempPrefLangs, tempLen, fpl); + break; + default: + break; + } + } + + // Try using app's locale + nsAutoCString localeStr; + LocaleService::GetInstance()->GetAppLocaleAsBCP47(localeStr); + + { + Locale locale; + if (LocaleParser::TryParse(localeStr, locale).isOk() && + locale.Canonicalize().isOk()) { + if (locale.Language().EqualTo("ja")) { + AppendPrefLang(tempPrefLangs, tempLen, eFontPrefLang_Japanese); + } else if (locale.Language().EqualTo("zh")) { + if (locale.Region().EqualTo("CN")) { + AppendPrefLang(tempPrefLangs, tempLen, eFontPrefLang_ChineseCN); + } else if (locale.Region().EqualTo("TW")) { + AppendPrefLang(tempPrefLangs, tempLen, eFontPrefLang_ChineseTW); + } else if (locale.Region().EqualTo("HK")) { + AppendPrefLang(tempPrefLangs, tempLen, eFontPrefLang_ChineseHK); + } + } else if (locale.Language().EqualTo("ko")) { + AppendPrefLang(tempPrefLangs, tempLen, eFontPrefLang_Korean); + } + } + } + + // Then add the known CJK prefs in order of system preferred locales + AutoTArray prefLocales; + prefLocales.AppendElement("ja"_ns); + prefLocales.AppendElement("zh-CN"_ns); + prefLocales.AppendElement("zh-TW"_ns); + prefLocales.AppendElement("zh-HK"_ns); + prefLocales.AppendElement("ko"_ns); + + AutoTArray sysLocales; + AutoTArray negLocales; + if (NS_SUCCEEDED( + OSPreferences::GetInstance()->GetSystemLocales(sysLocales))) { + LocaleService::GetInstance()->NegotiateLanguages( + sysLocales, prefLocales, ""_ns, + LocaleService::kLangNegStrategyFiltering, negLocales); + for (const auto& localeStr : negLocales) { + Locale locale; + if (LocaleParser::TryParse(localeStr, locale).isOk() && + locale.Canonicalize().isOk()) { + if (locale.Language().EqualTo("ja")) { + AppendPrefLang(tempPrefLangs, tempLen, eFontPrefLang_Japanese); + } else if (locale.Language().EqualTo("zh")) { + if (locale.Region().EqualTo("CN")) { + AppendPrefLang(tempPrefLangs, tempLen, eFontPrefLang_ChineseCN); + } else if (locale.Region().EqualTo("TW")) { + AppendPrefLang(tempPrefLangs, tempLen, eFontPrefLang_ChineseTW); + } else if (locale.Region().EqualTo("HK")) { + AppendPrefLang(tempPrefLangs, tempLen, eFontPrefLang_ChineseHK); + } + } else if (locale.Language().EqualTo("ko")) { + AppendPrefLang(tempPrefLangs, tempLen, eFontPrefLang_Korean); + } + } + } + } + + // Last resort... set up CJK font prefs in the order listed by the user- + // configurable ordering pref. + gfxFontUtils::GetPrefsFontList(kCJKFallbackOrderPref, list); + for (const auto& item : list) { + eFontPrefLang fpl = GetFontPrefLangFor(item.get()); + switch (fpl) { + case eFontPrefLang_Japanese: + case eFontPrefLang_Korean: + case eFontPrefLang_ChineseCN: + case eFontPrefLang_ChineseHK: + case eFontPrefLang_ChineseTW: + AppendPrefLang(tempPrefLangs, tempLen, fpl); + break; + default: + break; + } + } + + // Truly-last resort... try Chinese font prefs before Japanese because + // they tend to have more complete character coverage, and therefore less + // risk of "ransom-note" effects. + // (If the kCJKFallbackOrderPref was fully populated, as it is by default, + // this will do nothing as all these values are already present.) + AppendPrefLang(tempPrefLangs, tempLen, eFontPrefLang_ChineseCN); + AppendPrefLang(tempPrefLangs, tempLen, eFontPrefLang_ChineseHK); + AppendPrefLang(tempPrefLangs, tempLen, eFontPrefLang_ChineseTW); + AppendPrefLang(tempPrefLangs, tempLen, eFontPrefLang_Japanese); + AppendPrefLang(tempPrefLangs, tempLen, eFontPrefLang_Korean); + + // copy into the cached array + for (const auto lang : Span(tempPrefLangs, tempLen)) { + mCJKPrefLangs.AppendElement(lang); + } } bool gfxPlatformFontList::FontPrefs::LookupName(const nsACString& aPref, diff --git a/gfx/thebes/gfxPlatformFontList.h b/gfx/thebes/gfxPlatformFontList.h index 51d6530e44c0..8b5a09b6b957 100644 --- a/gfx/thebes/gfxPlatformFontList.h +++ b/gfx/thebes/gfxPlatformFontList.h @@ -198,6 +198,8 @@ class gfxPlatformFontList : public gfxFontInfoLoader { return mFontNameList.ConstIter(); } + const nsTArray& CJKPrefLangs() const { return mCJKPrefLangs; } + private: static constexpr char kNamePrefix[] = "font.name."; static constexpr char kNameListPrefix[] = "font.name-list."; @@ -206,6 +208,7 @@ class gfxPlatformFontList : public gfxFontInfoLoader { HashMap mFontName; HashMap mFontNameList; + nsTArray mCJKPrefLangs; bool mEmojiHasUserValue = false; }; @@ -1055,7 +1058,6 @@ class gfxPlatformFontList : public gfxFontInfoLoader { nsLanguageAtomService* mLangService = nullptr; - nsTArray mCJKPrefLangs MOZ_GUARDED_BY(mLock); nsTArray mDefaultGenericsLangGroup MOZ_GUARDED_BY(mLock);