Bug 1561600 - Support the special Osaka-mono font (family) for Japanese on macOS, by hooking up the font.single-face-list pref to the shared font-list's alias table. r=jwatt
authorJonathan Kew <jkew@mozilla.com>
Wed, 26 Jun 2019 18:58:48 +0000
changeset 543061 7bc807167dc9580c7a0581d3380498f3feee0619
parent 543060 0581a4a4bdf3d445727ed432256f39082ad5f794
child 543062 0a18aa212ee6c1013d9069d2142dbbe8d1fb3715
push id2131
push userffxbld-merge
push dateMon, 26 Aug 2019 18:30:20 +0000
treeherdermozilla-release@b19ffb3ca153 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjwatt
bugs1561600
milestone69.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1561600 - Support the special Osaka-mono font (family) for Japanese on macOS, by hooking up the font.single-face-list pref to the shared font-list's alias table. r=jwatt Differential Revision: https://phabricator.services.mozilla.com/D36023
gfx/thebes/gfxMacPlatformFontList.h
gfx/thebes/gfxMacPlatformFontList.mm
--- a/gfx/thebes/gfxMacPlatformFontList.h
+++ b/gfx/thebes/gfxMacPlatformFontList.h
@@ -159,16 +159,17 @@ class gfxMacPlatformFontList : public gf
   virtual ~gfxMacPlatformFontList();
 
   // initialize font lists
   nsresult InitFontListForPlatform() override;
   void InitSharedFontListForPlatform() override;
 
   // special case font faces treated as font families (set via prefs)
   void InitSingleFaceList();
+  void InitAliasesForSingleFaceList();
 
   // initialize system fonts
   void InitSystemFontNames();
 
   // helper function to lookup in both hidden system fonts and normal fonts
   gfxFontFamily* FindSystemFontFamily(const nsACString& aFamily);
 
   static void RegisteredFontsChangedNotificationCallback(
--- a/gfx/thebes/gfxMacPlatformFontList.mm
+++ b/gfx/thebes/gfxMacPlatformFontList.mm
@@ -1005,20 +1005,85 @@ void gfxMacPlatformFontList::InitSharedF
       GenerateFontListKey(name, key);
       bool isHidden = key.EqualsLiteral("lastresort") || key[0] == '.';
       families.AppendElement(fontlist::Family::InitData(key, name, 0, isHidden));
     }
     CFRelease(familyNames);
     ApplyWhitelist(families);
     families.Sort();
     SharedFontList()->SetFamilyNames(families);
+    InitAliasesForSingleFaceList();
     GetPrefsAndStartLoader();
   }
 }
 
+void gfxMacPlatformFontList::InitAliasesForSingleFaceList() {
+  AutoTArray<nsCString, 10> singleFaceFonts;
+  gfxFontUtils::GetPrefsFontList("font.single-face-list", singleFaceFonts);
+
+  for (auto& familyName : singleFaceFonts) {
+    LOG_FONTLIST(("(fontlist-singleface) face name: %s\n", familyName.get()));
+    // Each entry in the "single face families" list is expected to be a
+    // colon-separated pair of FaceName:Family,
+    // where FaceName is the individual face name (psname) of a font
+    // that should be exposed as a separate family name,
+    // and Family is the standard family to which that face belongs.
+    // The only such face listed by default is
+    //    Osaka-Mono:Osaka
+    auto colon = familyName.FindChar(':');
+    if (colon == kNotFound) {
+      continue;
+    }
+
+    // Look for the parent family in the main font family list,
+    // and ensure we have loaded its list of available faces.
+    nsAutoCString key;
+    GenerateFontListKey(Substring(familyName, colon + 1), key);
+    fontlist::Family* family = SharedFontList()->FindFamily(key);
+    if (!family) {
+      // The parent family is not present, so just ignore this entry.
+      continue;
+    }
+    if (!family->IsInitialized()) {
+      if (!gfxPlatformFontList::InitializeFamily(family)) {
+        // This shouldn't ever fail, but if it does, we can safely ignore it.
+        MOZ_ASSERT(false, "failed to initialize font family");
+        continue;
+      }
+    }
+
+    // Truncate the entry from prefs at the colon, so now it is just the
+    // desired single-face-family name.
+    familyName.Truncate(colon);
+
+    // Look through the family's faces to see if this one is present.
+    fontlist::FontList* list = SharedFontList();
+    const fontlist::Pointer* facePtrs = family->Faces(list);
+    for (size_t i = 0; i < family->NumFaces(); i++) {
+      if (facePtrs[i].IsNull()) {
+        continue;
+      }
+      auto face = static_cast<const fontlist::Face*>(facePtrs[i].ToPtr(list));
+      if (face->mDescriptor.AsString(list).Equals(familyName)) {
+        // Found it! Create an entry in the Alias table.
+        GenerateFontListKey(familyName, key);
+        if (SharedFontList()->FindFamily(key) || mAliasTable.Get(familyName)) {
+          // If the family name is already known, something's misconfigured;
+          // just ignore it.
+          MOZ_ASSERT(false, "single-face family already known");
+          break;
+        }
+        auto af = mAliasTable.LookupOrAdd(familyName);
+        af->AppendElement(facePtrs[i]);
+        break;
+      }
+    }
+  }
+}
+
 void gfxMacPlatformFontList::InitSingleFaceList() {
   AutoTArray<nsCString, 10> singleFaceFonts;
   gfxFontUtils::GetPrefsFontList("font.single-face-list", singleFaceFonts);
 
   for (auto& familyName : singleFaceFonts) {
     LOG_FONTLIST(("(fontlist-singleface) face name: %s\n", familyName.get()));
     // Each entry in the "single face families" list is expected to be a
     // colon-separated pair of FaceName:Family,