Bug 1056479 p6 - handle font updates. r=jfkthame
authorJohn Daggett <jdaggett@mozilla.com>
Wed, 13 May 2015 14:11:26 +0900
changeset 243645 1bc9ce0ef5bba1d12a2976f04fd3a366330b5bc1
parent 243644 ea4df703d98aa5f5fd43858367223a38a5f05da5
child 243646 5a747351d2e1290cb09a095e78603184b2e4b136
push id28744
push userkwierso@gmail.com
push dateWed, 13 May 2015 18:12:16 +0000
treeherdermozilla-central@324c3423deaf [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjfkthame
bugs1056479
milestone41.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_ */