Bug 869762: Use Core Foundation notifications instead of ATS for font changes on OS X. r=jdaggett
authorJosh Aas <joshmoz@gmail.com>
Tue, 15 Oct 2013 23:53:52 -0500
changeset 164692 c62ad7dd57cdd08b7bdb888173a5c1057ff4fa1b
parent 164691 53c610770178a15e0754b1f214c2d35ec07f9323
child 164693 afae5911a1e04d6eb72b231f954fb75806b66d95
push id3066
push userakeybl@mozilla.com
push dateMon, 09 Dec 2013 19:58:46 +0000
treeherdermozilla-beta@a31a0dce83aa [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjdaggett
bugs869762
milestone27.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 869762: Use Core Foundation notifications instead of ATS for font changes on OS X. r=jdaggett
gfx/thebes/gfxMacPlatformFontList.h
gfx/thebes/gfxMacPlatformFontList.mm
--- a/gfx/thebes/gfxMacPlatformFontList.h
+++ b/gfx/thebes/gfxMacPlatformFontList.h
@@ -1,26 +1,26 @@
 /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef gfxMacPlatformFontList_H_
 #define gfxMacPlatformFontList_H_
 
+#include <CoreFoundation/CoreFoundation.h>
+
 #include "mozilla/MemoryReporting.h"
 #include "nsDataHashtable.h"
 #include "nsRefPtrHashtable.h"
 
 #include "gfxPlatformFontList.h"
 #include "gfxPlatform.h"
 #include "gfxPlatformMac.h"
 
-#include <Carbon/Carbon.h>
-
 #include "nsUnicharUtils.h"
 #include "nsTArray.h"
 
 class gfxMacPlatformFontList;
 
 // a single member of a font family (i.e. a single face, such as Times Italic)
 class MacOSFontEntry : public gfxFontEntry
 {
@@ -96,30 +96,31 @@ private:
     virtual ~gfxMacPlatformFontList();
 
     // initialize font lists
     virtual nsresult InitFontList();
 
     // special case font faces treated as font families (set via prefs)
     void InitSingleFaceList();
 
-    static void ATSNotification(ATSFontNotificationInfoRef aInfo, void* aUserArg);
+    static void RegisteredFontsChangedNotificationCallback(CFNotificationCenterRef center,
+                                                           void *observer,
+                                                           CFStringRef name,
+                                                           const void *object,
+                                                           CFDictionaryRef userInfo);
 
     // search fonts system-wide for a given character, null otherwise
     virtual gfxFontEntry* GlobalFontFallback(const uint32_t aCh,
                                              int32_t aRunScript,
                                              const gfxFontStyle* aMatchStyle,
                                              uint32_t& aCmapCount,
                                              gfxFontFamily** aMatchedFamily);
 
     virtual bool UsesSystemFallback() { return true; }
 
-    // keep track of ATS generation to prevent unneeded updates when loading downloaded fonts
-    uint32_t mATSGeneration;
-
     enum {
         kATSGenerationInitial = -1
     };
 
     // default font for use with system-wide font fallback
     CTFontRef mDefaultFont;
 };
 
--- a/gfx/thebes/gfxMacPlatformFontList.mm
+++ b/gfx/thebes/gfxMacPlatformFontList.mm
@@ -38,17 +38,16 @@
  *
  * ***** END LICENSE BLOCK ***** */
 
 #ifdef MOZ_LOGGING
 #define FORCE_PR_LOG /* Allow logging in the release build */
 #endif
 #include "prlog.h"
 
-#include <Carbon/Carbon.h>
 #include <algorithm>
 
 #import <AppKit/AppKit.h>
 
 #include "gfxPlatformMac.h"
 #include "gfxMacPlatformFontList.h"
 #include "gfxMacFont.h"
 #include "gfxUserFontSet.h"
@@ -641,22 +640,25 @@ gfxSingleFaceMacFontFamily::ReadOtherFam
     mOtherFamilyNamesInitialized = true;
 }
 
 
 /* gfxMacPlatformFontList */
 #pragma mark-
 
 gfxMacPlatformFontList::gfxMacPlatformFontList() :
-    gfxPlatformFontList(false), mATSGeneration(uint32_t(kATSGenerationInitial)),
+    gfxPlatformFontList(false),
     mDefaultFont(nullptr)
 {
-    ::ATSFontNotificationSubscribe(ATSNotification,
-                                   kATSFontNotifyOptionDefault,
-                                   (void*)this, nullptr);
+    ::CFNotificationCenterAddObserver(::CFNotificationCenterGetLocalCenter(),
+                                      this,
+                                      RegisteredFontsChangedNotificationCallback,
+                                      kCTFontManagerRegisteredFontsChangedNotification,
+                                      0,
+                                      CFNotificationSuspensionBehaviorDeliverImmediately);
 
     // cache this in a static variable so that MacOSFontFamily objects
     // don't have to repeatedly look it up
     sFontManager = [NSFontManager sharedFontManager];
 }
 
 gfxMacPlatformFontList::~gfxMacPlatformFontList()
 {
@@ -665,29 +667,18 @@ gfxMacPlatformFontList::~gfxMacPlatformF
     }
 }
 
 nsresult
 gfxMacPlatformFontList::InitFontList()
 {
     nsAutoreleasePool localPool;
 
-    ATSGeneration currentGeneration = ::ATSGetGeneration();
-
-    // need to ignore notifications after adding each font
-    if (mATSGeneration == currentGeneration)
-        return NS_OK;
-
     Telemetry::AutoTimer<Telemetry::MAC_INITFONTLIST_TOTAL> timer;
 
-    mATSGeneration = currentGeneration;
-#ifdef PR_LOGGING
-    LOG_FONTLIST(("(fontlist) updating to generation: %d", mATSGeneration));
-#endif
-
     // reset font lists
     gfxPlatformFontList::InitFontList();
     
     // iterate over available families
     NSEnumerator *families = [[sFontManager availableFontFamilies]
                               objectEnumerator];  // returns "canonical", non-localized family name
 
     nsAutoString availableFamilyName;
@@ -772,21 +763,28 @@ gfxMacPlatformFontList::GetStandardFamil
         family->LocalizedName(aFamilyName);
         return true;
     }
 
     return false;
 }
 
 void
-gfxMacPlatformFontList::ATSNotification(ATSFontNotificationInfoRef aInfo,
-                                        void* aUserArg)
+gfxMacPlatformFontList::RegisteredFontsChangedNotificationCallback(CFNotificationCenterRef center,
+                                                                   void *observer,
+                                                                   CFStringRef name,
+                                                                   const void *object,
+                                                                   CFDictionaryRef userInfo)
 {
+    if (!::CFEqual(name, kCTFontManagerRegisteredFontsChangedNotification)) {
+        return;
+    }
+
     // xxx - should be carefully pruning the list of fonts, not rebuilding it from scratch
-    static_cast<gfxMacPlatformFontList*>(aUserArg)->UpdateFontList();
+    static_cast<gfxMacPlatformFontList*>(observer)->UpdateFontList();
 
     // modify a preference that will trigger reflow everywhere
     static const char kPrefName[] = "font.internaluseonly.changed";
     bool fontInternalChange = Preferences::GetBool(kPrefName, false);
     Preferences::SetBool(kPrefName, !fontInternalChange);
 }
 
 gfxFontEntry*