Bug 931040 - add access to hidden system fonts on OSX. r=jfkthame
authorJohn Daggett <jdaggett@mozilla.com>
Tue, 19 Aug 2014 21:46:17 +0900
changeset 200268 241f31c1ad62
parent 200267 bb91698edd20
child 200269 bd50eac73b51
push id47861
push userjdaggett@mozilla.com
push dateTue, 19 Aug 2014 12:46:45 +0000
treeherdermozilla-inbound@241f31c1ad62 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjfkthame
bugs931040
milestone34.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 931040 - add access to hidden system fonts on OSX. r=jfkthame
gfx/thebes/gfxDWriteFontList.cpp
gfx/thebes/gfxDWriteFontList.h
gfx/thebes/gfxFont.cpp
gfx/thebes/gfxGDIFontList.cpp
gfx/thebes/gfxGDIFontList.h
gfx/thebes/gfxMacPlatformFontList.mm
gfx/thebes/gfxPlatformFontList.cpp
gfx/thebes/gfxPlatformFontList.h
--- a/gfx/thebes/gfxDWriteFontList.cpp
+++ b/gfx/thebes/gfxDWriteFontList.cpp
@@ -1316,17 +1316,18 @@ gfxDWriteFontList::GetStandardFamilyName
     if (family) {
         family->LocalizedName(aFamilyName);
         return true;
     }
 
     return false;
 }
 
-gfxFontFamily* gfxDWriteFontList::FindFamily(const nsAString& aFamily)
+gfxFontFamily*
+gfxDWriteFontList::FindFamily(const nsAString& aFamily, bool aUseSystemFonts)
 {
     if (!mInitialized) {
         mInitialized = true;
         DelayedInitFontList();
     }
 
     nsAutoString keyName(aFamily);
     BuildKeyNameFromFontName(keyName);
--- a/gfx/thebes/gfxDWriteFontList.h
+++ b/gfx/thebes/gfxDWriteFontList.h
@@ -355,17 +355,18 @@ public:
                                            uint32_t aLength);
     
     bool GetStandardFamilyName(const nsAString& aFontName,
                                  nsAString& aFamilyName);
 
     IDWriteGdiInterop *GetGDIInterop() { return mGDIInterop; }
     bool UseGDIFontTableAccess() { return mGDIFontTableAccess; }
 
-    virtual gfxFontFamily* FindFamily(const nsAString& aFamily);
+    virtual gfxFontFamily* FindFamily(const nsAString& aFamily,
+                                      bool aUseSystemFonts = false);
 
     virtual void GetFontFamilyList(nsTArray<nsRefPtr<gfxFontFamily> >& aFamilyArray);
 
     gfxFloat GetForceGDIClassicMaxFontSize() { return mForceGDIClassicMaxFontSize; }
 
     virtual void AddSizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf,
                                         FontListSizes* aSizes) const;
     virtual void AddSizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf,
--- a/gfx/thebes/gfxFont.cpp
+++ b/gfx/thebes/gfxFont.cpp
@@ -5028,17 +5028,17 @@ gfxFontGroup::FindPlatformFont(const nsA
                 }
             }
         }
     }
 
     // Not known in the user font set ==> check system fonts
     if (!family) {
         gfxPlatformFontList *fontList = gfxPlatformFontList::PlatformFontList();
-        family = fontList->FindFamily(aName);
+        family = fontList->FindFamily(aName, mStyle.systemFont);
         if (family) {
             fe = family->FindFontForStyle(mStyle, needsBold);
         }
     }
 
     // add to the font group, unless it's already there
     if (fe && !HasFont(fe)) {
         nsRefPtr<gfxFont> font = fe->FindOrMakeFont(&mStyle, needsBold);
--- a/gfx/thebes/gfxGDIFontList.cpp
+++ b/gfx/thebes/gfxGDIFontList.cpp
@@ -834,17 +834,17 @@ gfxGDIFontList::MakePlatformFont(const g
     if (isCFF && !IsWin7OrLater()) {
         fe->mForceGDI = true;
     }
 
     return fe;
 }
 
 gfxFontFamily*
-gfxGDIFontList::FindFamily(const nsAString& aFamily)
+gfxGDIFontList::FindFamily(const nsAString& aFamily, bool aUseSystemFonts)
 {
     nsAutoString keyName(aFamily);
     BuildKeyNameFromFontName(keyName);
 
     gfxFontFamily *ff = mFontSubstitutes.GetWeak(keyName);
     if (ff) {
         return ff;
     }
--- a/gfx/thebes/gfxGDIFontList.h
+++ b/gfx/thebes/gfxGDIFontList.h
@@ -302,17 +302,18 @@ public:
         return static_cast<gfxGDIFontList*>(sPlatformFontList);
     }
 
     // initialize font lists
     virtual nsresult InitFontList();
 
     virtual gfxFontFamily* GetDefaultFont(const gfxFontStyle* aStyle);
 
-    virtual gfxFontFamily* FindFamily(const nsAString& aFamily);
+    virtual gfxFontFamily* FindFamily(const nsAString& aFamily,
+                                      bool aUseSystemFonts = false);
 
     virtual gfxFontEntry* LookupLocalFont(const gfxProxyFontEntry *aProxyEntry,
                                           const nsAString& aFontName);
 
     virtual gfxFontEntry* MakePlatformFont(const gfxProxyFontEntry *aProxyEntry,
                                            const uint8_t *aFontData, uint32_t aLength);
 
     virtual void AddSizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf,
--- a/gfx/thebes/gfxMacPlatformFontList.mm
+++ b/gfx/thebes/gfxMacPlatformFontList.mm
@@ -642,52 +642,61 @@ nsresult
 gfxMacPlatformFontList::InitFontList()
 {
     nsAutoreleasePool localPool;
 
     Telemetry::AutoTimer<Telemetry::MAC_INITFONTLIST_TOTAL> timer;
 
     // reset font lists
     gfxPlatformFontList::InitFontList();
+    mSystemFontFamilies.Clear();
     
     // iterate over available families
 
     CFArrayRef familyNames = CTFontManagerCopyAvailableFontFamilyNames();
 
     // iterate over families
     uint32_t i, numFamilies;
 
     numFamilies = CFArrayGetCount(familyNames);
     for (i = 0; i < numFamilies; i++) {
         CFStringRef family = (CFStringRef)CFArrayGetValueAtIndex(familyNames, i);
 
         // CTFontManager includes weird internal family names and
         // LastResort, skip over those
         if (!family ||
-            ::CFStringHasPrefix(family, CFSTR(".")) ||
             CFStringCompare(family, CFSTR("LastResort"),
                             kCFCompareCaseInsensitive) == kCFCompareEqualTo) {
             continue;
         }
 
+        bool hiddenSystemFont = false;
+        if (::CFStringHasPrefix(family, CFSTR("."))) {
+            hiddenSystemFont = true;
+        }
+
         nsAutoTArray<UniChar, 1024> buffer;
         CFIndex len = ::CFStringGetLength(family);
         buffer.SetLength(len+1);
         ::CFStringGetCharacters(family, ::CFRangeMake(0, len),
                                 buffer.Elements());
         buffer[len] = 0;
         nsAutoString familyName(reinterpret_cast<char16_t*>(buffer.Elements()), len);
 
         // create a family entry
         gfxFontFamily *familyEntry = new gfxMacFontFamily(familyName);
         if (!familyEntry) break;
 
         // add the family entry to the hash table
         ToLowerCase(familyName);
-        mFontFamilies.Put(familyName, familyEntry);
+        if (!hiddenSystemFont) {
+            mFontFamilies.Put(familyName, familyEntry);
+        } else {
+            mSystemFontFamilies.Put(familyName, familyEntry);
+        }
 
         // check the bad underline blacklist
         if (mBadUnderlineFamilyNames.Contains(familyName))
             familyEntry->SetBadUnderlineFamily();
     }
 
     CFRelease(familyNames);
 
--- a/gfx/thebes/gfxPlatformFontList.cpp
+++ b/gfx/thebes/gfxPlatformFontList.cpp
@@ -724,29 +724,38 @@ gfxPlatformFontList::CheckFamily(gfxFont
         mFontFamilies.Remove(key);
         return nullptr;
     }
 
     return aFamily;
 }
 
 gfxFontFamily* 
-gfxPlatformFontList::FindFamily(const nsAString& aFamily)
+gfxPlatformFontList::FindFamily(const nsAString& aFamily, bool aUseSystemFonts)
 {
     nsAutoString key;
     gfxFontFamily *familyEntry;
     GenerateFontListKey(aFamily, key);
 
     NS_ASSERTION(mFontFamilies.Count() != 0, "system font list was not initialized correctly");
 
     // lookup in canonical (i.e. English) family name list
     if ((familyEntry = mFontFamilies.GetWeak(key))) {
         return CheckFamily(familyEntry);
     }
 
+#if defined(XP_MACOSX)
+    // for system font types allow hidden system fonts to be referenced
+    if (aUseSystemFonts) {
+        if ((familyEntry = mSystemFontFamilies.GetWeak(key)) != nullptr) {
+            return CheckFamily(familyEntry);
+        }
+    }
+#endif
+
     // lookup in other family names list (mostly localized names)
     if ((familyEntry = mOtherFamilyNames.GetWeak(key)) != nullptr) {
         return CheckFamily(familyEntry);
     }
 
     // name not found and other family names not yet fully initialized so
     // initialize the rest of the list and try again.  this is done lazily
     // since reading name table entries is expensive.
--- a/gfx/thebes/gfxPlatformFontList.h
+++ b/gfx/thebes/gfxPlatformFontList.h
@@ -120,18 +120,18 @@ public:
 
     virtual void GetFontFamilyList(nsTArray<nsRefPtr<gfxFontFamily> >& aFamilyArray);
 
     virtual gfxFontEntry*
     SystemFindFontForChar(const uint32_t aCh,
                           int32_t aRunScript,
                           const gfxFontStyle* aStyle);
 
-    // TODO: make this virtual, for lazily adding to the font list
-    virtual gfxFontFamily* FindFamily(const nsAString& aFamily);
+    virtual gfxFontFamily* FindFamily(const nsAString& aFamily,
+                                      bool aUseSystemFonts = false);
 
     gfxFontEntry* FindFontForFamily(const nsAString& aFamily, const gfxFontStyle* aStyle, bool& aNeedsBold);
 
     bool GetPrefFontFamilyEntries(eFontPrefLang aLangGroup, nsTArray<nsRefPtr<gfxFontFamily> > *array);
     void SetPrefFontFamilyEntries(eFontPrefLang aLangGroup, nsTArray<nsRefPtr<gfxFontFamily> >& array);
 
     // name lookup table methods
 
@@ -287,16 +287,21 @@ protected:
     SizeOfFamilyNameEntryExcludingThis(const nsAString&               aKey,
                                        const nsRefPtr<gfxFontFamily>& aFamily,
                                        mozilla::MallocSizeOf          aMallocSizeOf,
                                        void*                          aUserArg);
 
     // canonical family name ==> family entry (unique, one name per family entry)
     nsRefPtrHashtable<nsStringHashKey, gfxFontFamily> mFontFamilies;
 
+#if defined(XP_MACOSX)
+    // hidden system fonts used within UI elements
+    nsRefPtrHashtable<nsStringHashKey, gfxFontFamily> mSystemFontFamilies;
+#endif
+
     // other family name ==> family entry (not unique, can have multiple names per
     // family entry, only names *other* than the canonical names are stored here)
     nsRefPtrHashtable<nsStringHashKey, gfxFontFamily> mOtherFamilyNames;
 
     // flag set after InitOtherFamilyNames is called upon first name lookup miss
     bool mOtherFamilyNamesInitialized;
 
     // flag set after fullname and Postcript name lists are populated