Bug 1056479 p6 - handle font updates. r=jfkthame
☠☠ backed out by b243afafbb75 ☠ ☠
authorJohn Daggett <jdaggett@mozilla.com>
Tue, 12 May 2015 17:44:30 +0900
changeset 243510 f630169085c1d4904ed849d146b0eee5bcf6dd41
parent 243509 51287191cc06a4db53ec10f7948033a4a4a2346c
child 243511 f18546e7f271caa2ea09bac6ebd8a7f36be25c58
push id28741
push userkwierso@gmail.com
push dateTue, 12 May 2015 23:24:40 +0000
treeherdermozilla-central@d476776d920d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjfkthame
bugs1056479
milestone40.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 1056479 p6 - handle font updates. r=jfkthame
gfx/thebes/gfxFcPlatformFontList.cpp
gfx/thebes/gfxFcPlatformFontList.h
--- a/gfx/thebes/gfxFcPlatformFontList.cpp
+++ b/gfx/thebes/gfxFcPlatformFontList.cpp
@@ -915,18 +915,45 @@ gfxFontConfigFont::GetGlyphRenderingOpti
       break;
   }
 
   // We don't want to force the use of the autohinter over the font's built in hints
   return mozilla::gfx::Factory::CreateCairoGlyphRenderingOptions(hinting, false);
 }
 #endif
 
+gfxFcPlatformFontList::gfxFcPlatformFontList()
+    : mLocalNames(64), mGenericMappings(32), mLastConfig(nullptr)
+{
+    // if the rescan interval is set, start the timer
+    int rescanInterval = FcConfigGetRescanInterval(nullptr);
+    if (rescanInterval) {
+        mLastConfig = FcConfigGetCurrent();
+        mCheckFontUpdatesTimer = do_CreateInstance("@mozilla.org/timer;1");
+        if (mCheckFontUpdatesTimer) {
+            mCheckFontUpdatesTimer->
+                InitWithFuncCallback(CheckFontUpdates, this,
+                                     (rescanInterval + 1) * 1000,
+                                     nsITimer::TYPE_REPEATING_SLACK);
+        } else {
+            NS_WARNING("Failure to create font updates timer");
+        }
+    }
+
+#ifdef MOZ_BUNDLED_FONTS
+    mBundledFontsInitialized = false;
+#endif
+}
+
 gfxFcPlatformFontList::~gfxFcPlatformFontList()
 {
+    if (mCheckFontUpdatesTimer) {
+        mCheckFontUpdatesTimer->Cancel();
+        mCheckFontUpdatesTimer = nullptr;
+    }
 }
 
 void
 gfxFcPlatformFontList::AddFontSetFamilies(FcFontSet* aFontSet)
 {
     // This iterates over the fonts in a font set and adds in gfxFontFamily
     // objects for each family. The patterns for individual fonts are not
     // copied here. When a family is actually used, the fonts in the family
@@ -1003,16 +1030,18 @@ gfxFcPlatformFontList::AddFontSetFamilie
             mLocalNames.Put(fullname, fontFamily);
         }
     }
 }
 
 nsresult
 gfxFcPlatformFontList::InitFontList()
 {
+    mLastConfig = FcConfigGetCurrent();
+
     // reset font lists
     gfxPlatformFontList::InitFontList();
 
     mLocalNames.Clear();
     mGenericMappings.Clear();
 
     // iterate over available fonts
     FcFontSet* systemFonts = FcConfigGetFonts(nullptr, FcSetSystem);
@@ -1389,16 +1418,31 @@ gfxFcPlatformFontList::FindGenericFamily
                 break;
             }
         }
     }
 
     return genericFamily;
 }
 
+/* static */ void
+gfxFcPlatformFontList::CheckFontUpdates(nsITimer *aTimer, void *aThis)
+{
+    // check for font updates
+    FcInitBringUptoDate();
+
+    // update fontlist if current config changed
+    gfxFcPlatformFontList *pfl = static_cast<gfxFcPlatformFontList*>(aThis);
+    FcConfig* current = FcConfigGetCurrent();
+    if (current != pfl->GetLastConfig()) {
+        pfl->UpdateFontList();
+        pfl->ForceGlobalReflow();
+    }
+}
+
 #ifdef MOZ_BUNDLED_FONTS
 void
 gfxFcPlatformFontList::ActivateBundledFonts()
 {
     if (!mBundledFontsInitialized) {
         mBundledFontsInitialized = true;
         nsCOMPtr<nsIFile> localDir;
         nsresult rv = NS_GetSpecialDirectory(NS_GRE_DIR, getter_AddRefs(localDir));
--- a/gfx/thebes/gfxFcPlatformFontList.h
+++ b/gfx/thebes/gfxFcPlatformFontList.h
@@ -23,16 +23,23 @@
 
 template <>
 class nsAutoRefTraits<FcObjectSet> : public nsPointerRefTraits<FcObjectSet>
 {
 public:
     static void Release(FcObjectSet *ptr) { FcObjectSetDestroy(ptr); }
 };
 
+template <>
+class nsAutoRefTraits<FcConfig> : public nsPointerRefTraits<FcConfig>
+{
+public:
+    static void Release(FcConfig *ptr) { FcConfigDestroy(ptr); }
+    static void AddRef(FcConfig *ptr) { FcConfigReference(ptr); }
+};
 
 // Helper classes used for clearning out user font data when cairo font
 // face is destroyed. Since multiple faces may use the same data, be
 // careful to assure that the data is only cleared out when all uses
 // expire. The font entry object contains a refptr to FTUserFontData and
 // each cairo font created from that font entry contains a
 // FTUserFontDataRef with a refptr to that same FTUserFontData object.
 
@@ -182,23 +189,17 @@ public:
 #endif
 
 protected:
     virtual ~gfxFontConfigFont();
 };
 
 class gfxFcPlatformFontList : public gfxPlatformFontList {
 public:
-    gfxFcPlatformFontList()
-        : mLocalNames(64), mGenericMappings(32)
-    {
-#ifdef MOZ_BUNDLED_FONTS
-        mBundledFontsInitialized = false;
-#endif
-    }
+    gfxFcPlatformFontList();
 
     // initialize font lists
     nsresult InitFontList() override;
 
     void GetFontList(nsIAtom *aLangGroup,
                      const nsACString& aGenericFamily,
                      nsTArray<nsString>& aListOfFonts) override;
 
@@ -218,38 +219,45 @@ public:
 
     gfxFontFamily* FindFamily(const nsAString& aFamily,
                               nsIAtom* aLanguage = nullptr,
                               bool aUseSystemFonts = false) override;
 
     bool GetStandardFamilyName(const nsAString& aFontName,
                                nsAString& aFamilyName) override;
 
+    FcConfig* GetLastConfig() const { return mLastConfig; }
+
     static FT_Library GetFTLibrary();
 
 protected:
     virtual ~gfxFcPlatformFontList();
 
     // add all the font families found in a font set
     void AddFontSetFamilies(FcFontSet* aFontSet);
 
     // figure out which family fontconfig maps a generic to
     // (aGeneric assumed already lowercase)
     gfxFontFamily* FindGenericFamily(const nsAString& aGeneric,
                                      nsIAtom* aLanguage);
 
+    static void CheckFontUpdates(nsITimer *aTimer, void *aThis);
+
 #ifdef MOZ_BUNDLED_FONTS
     void ActivateBundledFonts();
     nsCString mBundledFontsPath;
     bool mBundledFontsInitialized;
 #endif
 
     // to avoid enumerating all fonts, maintain a mapping of local font
     // names to family
     nsRefPtrHashtable<nsStringHashKey, gfxFontFamily> mLocalNames;
 
     // caching generic/lang ==> font family
     nsRefPtrHashtable<nsCStringHashKey, gfxFontFamily> mGenericMappings;
 
+    nsCOMPtr<nsITimer> mCheckFontUpdatesTimer;
+    nsCountedRef<FcConfig> mLastConfig;
+
     static FT_Library sCairoFTLibrary;
 };
 
 #endif /* GFXPLATFORMFONTLIST_H_ */