Bug 1224965 p2 - tweak the handling of generic substitutions. r=karlt a=ritu
authorJohn Daggett <jdaggett@mozilla.com>
Tue, 01 Dec 2015 09:48:05 +0900
changeset 305676 5ac27957690f76110f2eb3666b5f9599506265c3
parent 305675 f4892b39b7311837cbf49a6f20cacc8e105a01ae
child 305677 f6ecc28fba3dda2cb62312b51ca1e305abacd442
push id1001
push userraliiev@mozilla.com
push dateMon, 18 Jan 2016 19:06:03 +0000
treeherdermozilla-release@8b89261f3ac4 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskarlt, ritu
bugs1224965
milestone44.0a2
Bug 1224965 p2 - tweak the handling of generic substitutions. r=karlt a=ritu
gfx/thebes/gfxFcPlatformFontList.cpp
--- a/gfx/thebes/gfxFcPlatformFontList.cpp
+++ b/gfx/thebes/gfxFcPlatformFontList.cpp
@@ -396,41 +396,47 @@ gfxFontconfigFontEntry::gfxFontconfigFon
     mStretch = aStretch;
     mIsLocalUserFont = true;
 }
 
 gfxFontconfigFontEntry::~gfxFontconfigFontEntry()
 {
 }
 
+static bool
+PatternHasLang(const FcPattern *aPattern, const FcChar8 *aLang)
+{
+    FcLangSet *langset;
+
+    if (FcPatternGetLangSet(aPattern, FC_LANG, 0, &langset) != FcResultMatch) {
+        return false;
+    }
+
+    if (FcLangSetHasLang(langset, aLang) != FcLangDifferentLang) {
+        return true;
+    }
+    return false;
+}
+
 bool
 gfxFontconfigFontEntry::SupportsLangGroup(nsIAtom *aLangGroup) const
 {
     if (!aLangGroup || aLangGroup == nsGkAtoms::Unicode) {
         return true;
     }
 
     nsAutoCString fcLang;
     gfxFcPlatformFontList* pfl = gfxFcPlatformFontList::PlatformFontList();
     pfl->GetSampleLangForGroup(aLangGroup, fcLang);
     if (fcLang.IsEmpty()) {
         return true;
     }
 
     // is lang included in the underlying pattern?
-    FcLangSet *langset;
-    if (FcPatternGetLangSet(mFontPattern, FC_LANG, 0, &langset) != FcResultMatch) {
-        return false;
-    }
-
-    if (FcLangSetHasLang(langset, (FcChar8 *)fcLang.get()) != FcLangDifferentLang) {
-        return true;
-    }
-
-    return false;
+    return PatternHasLang(mFontPattern, ToFcChar8Ptr(fcLang.get()));
 }
 
 nsresult
 gfxFontconfigFontEntry::ReadCMAP(FontInfoData *aFontInfoData)
 {
     // attempt this once, if errors occur leave a blank cmap
     if (mCharacterMap) {
         return NS_OK;
@@ -1645,16 +1651,17 @@ gfxFcPlatformFontList::FindGenericFamili
 
     if (!faces) {
       return nullptr;
     }
 
     // -- select the fonts to be used for the generic
     prefFonts = new PrefFontList; // can be empty but in practice won't happen
     uint32_t limit = gfxPlatformGtk::GetPlatform()->MaxGenericSubstitions();
+    bool foundFontWithLang = false;
     for (int i = 0; i < faces->nfont; i++) {
         FcPattern* font = faces->fonts[i];
         FcChar8* mappedGeneric = nullptr;
 
         // not scalable? skip...
         FcBool scalable;
         if (FcPatternGetBool(font, FC_SCALABLE, 0, &scalable) != FcResultMatch ||
             !scalable) {
@@ -1662,24 +1669,35 @@ gfxFcPlatformFontList::FindGenericFamili
         }
 
         FcPatternGetString(font, FC_FAMILY, 0, &mappedGeneric);
         if (mappedGeneric) {
             NS_ConvertUTF8toUTF16 mappedGenericName(ToCharPtr(mappedGeneric));
             gfxFontFamily* genericFamily =
                 gfxPlatformFontList::FindFamily(mappedGenericName);
             if (genericFamily && !prefFonts->Contains(genericFamily)) {
-                //printf("generic %s ==> %s\n", genericLang.get(), (const char*)mappedGeneric);
                 prefFonts->AppendElement(genericFamily);
-                if (prefFonts->Length() >= limit) {
+                bool foundLang = !fcLang.IsEmpty() &&
+                                 PatternHasLang(font, ToFcChar8Ptr(fcLang.get()));
+                foundFontWithLang = foundFontWithLang || foundLang;
+                // stop at the first family for which the lang matches (or
+                // when there is no lang)
+                if (fcLang.IsEmpty() ||
+                    prefFonts->Length() >= limit || foundLang) {
                     break;
                 }
             }
         }
     }
+
+    // if no font in the list matches the lang, trim all but the first one
+    if (!prefFonts->IsEmpty() && !foundFontWithLang) {
+        prefFonts->TruncateLength(1);
+    }
+
     mGenericMappings.Put(genericLang, prefFonts);
     return prefFonts;
 }
 
 bool
 gfxFcPlatformFontList::PrefFontListsUseOnlyGenerics()
 {
     bool prefFontsUseOnlyGenerics = true;