diff --git a/gfx/thebes/gfxFcPlatformFontList.cpp b/gfx/thebes/gfxFcPlatformFontList.cpp index 2f62de7c9573..04703e1284e8 100644 --- a/gfx/thebes/gfxFcPlatformFontList.cpp +++ b/gfx/thebes/gfxFcPlatformFontList.cpp @@ -2145,9 +2145,6 @@ bool gfxFcPlatformFontList::FindAndAddFamiliesLocked( // Because the FcConfigSubstitute call is quite expensive, we cache the // actual font families found via this process. - nsAutoCString lang; - GetSampleLangForGroup(aLanguage, lang); - ToLowerCase(lang); nsAutoCString cacheKey; // For languages that use CJK or Arabic script, we include the language as @@ -2157,13 +2154,21 @@ bool gfxFcPlatformFontList::FindAndAddFamiliesLocked( // and it gets really expensive to do separate lookups for 300+ distinct lang // tags e.g. on wikipedia.org, when they all end up mapping to the same font // list.) - Locale locale; - if (LocaleParser::TryParse(lang, locale).isOk() && - locale.AddLikelySubtags().isOk()) { - if (UseCustomFontconfigLookupsForLocale(locale)) { - cacheKey = lang; - cacheKey.Append(':'); - } + // We remember the most recently checked aLanguage atom so that when the same + // language is used in many successive calls, we can avoid repeating the + // locale code processing every time. + if (aLanguage != mPrevLanguage) { + GetSampleLangForGroup(aLanguage, mSampleLang); + ToLowerCase(mSampleLang); + Locale locale; + mUseCustomLookups = LocaleParser::TryParse(mSampleLang, locale).isOk() && + locale.AddLikelySubtags().isOk() && + UseCustomFontconfigLookupsForLocale(locale); + mPrevLanguage = aLanguage; + } + if (mUseCustomLookups) { + cacheKey = mSampleLang; + cacheKey.Append(':'); } cacheKey.Append(familyName); @@ -2180,8 +2185,8 @@ bool gfxFcPlatformFontList::FindAndAddFamiliesLocked( const FcChar8* terminator = nullptr; RefPtr sentinelSubst = dont_AddRef(FcPatternCreate()); FcPatternAddString(sentinelSubst, FC_FAMILY, kSentinelName); - if (!lang.IsEmpty()) { - FcPatternAddString(sentinelSubst, FC_LANG, ToFcChar8Ptr(lang.get())); + if (!mSampleLang.IsEmpty()) { + FcPatternAddString(sentinelSubst, FC_LANG, ToFcChar8Ptr(mSampleLang.get())); } FcConfigSubstitute(nullptr, sentinelSubst, FcMatchPattern); @@ -2209,8 +2214,8 @@ bool gfxFcPlatformFontList::FindAndAddFamiliesLocked( FcPatternAddString(fontWithSentinel, FC_FAMILY, ToFcChar8Ptr(familyName.get())); FcPatternAddString(fontWithSentinel, FC_FAMILY, kSentinelName); - if (!lang.IsEmpty()) { - FcPatternAddString(sentinelSubst, FC_LANG, ToFcChar8Ptr(lang.get())); + if (!mSampleLang.IsEmpty()) { + FcPatternAddString(sentinelSubst, FC_LANG, ToFcChar8Ptr(mSampleLang.get())); } FcConfigSubstitute(nullptr, fontWithSentinel, FcMatchPattern); diff --git a/gfx/thebes/gfxFcPlatformFontList.h b/gfx/thebes/gfxFcPlatformFontList.h index 2e622e0e456f..3becf45e4449 100644 --- a/gfx/thebes/gfxFcPlatformFontList.h +++ b/gfx/thebes/gfxFcPlatformFontList.h @@ -409,6 +409,12 @@ class gfxFcPlatformFontList final : public gfxPlatformFontList { private: #endif + // Cache for most recently used language code in FindAndAddFamiliesLocked, + // and the result of checking whether to use lang-specific lookups. + RefPtr mPrevLanguage; + nsCString mSampleLang; + bool mUseCustomLookups = false; + // By default, font prefs under Linux are set to simply lookup // via fontconfig the appropriate font for serif/sans-serif/monospace. // Rather than check each time a font pref is used, check them all at startup