Bug 1056479 p6 - handle font updates. r=jfkthame
☠☠ backed out by 6127b1d28cb5 ☠ ☠
authorJohn Daggett <jdaggett@mozilla.com>
Tue, 12 May 2015 14:51:17 +0900
changeset 243461 0b35e8a463d2bef4a311ed4847571cda7123ddbe
parent 243460 0933391809c952884b1d65b0b7bcd2044a2ea7c8
child 243462 bcc65b714dd694ccf8d016be7f2cc48698532c9b
push id28738
push usercbook@mozilla.com
push dateTue, 12 May 2015 14:11:31 +0000
treeherderautoland@bedce1b405a3 [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_ */