bug 663688 - prefer CGFont APIs to older ATS APIs on 10.6 or later. r=smichaud,roc
authorJonathan Kew <jfkthame@gmail.com>
Fri, 24 Jun 2011 18:55:27 +0100
changeset 72240 f1d138ffa159892dce3204e333c1955a54ff7899
parent 72239 de0a584b0c5498f78b575211d2259ec89f0dc29b
child 72241 11e15aabd2c136be61d99f45638d44fa65867a16
push idunknown
push userunknown
push dateunknown
reviewerssmichaud, roc
bugs663688
milestone7.0a1
bug 663688 - prefer CGFont APIs to older ATS APIs on 10.6 or later. r=smichaud,roc
gfx/thebes/gfxCoreTextShaper.cpp
gfx/thebes/gfxCoreTextShaper.h
gfx/thebes/gfxMacFont.cpp
gfx/thebes/gfxMacFont.h
gfx/thebes/gfxMacPlatformFontList.h
gfx/thebes/gfxMacPlatformFontList.mm
--- a/gfx/thebes/gfxCoreTextShaper.cpp
+++ b/gfx/thebes/gfxCoreTextShaper.cpp
@@ -66,20 +66,28 @@
 // standard font descriptors that we construct the first time they're needed
 CTFontDescriptorRef gfxCoreTextShaper::sDefaultFeaturesDescriptor = NULL;
 CTFontDescriptorRef gfxCoreTextShaper::sDisableLigaturesDescriptor = NULL;
 
 gfxCoreTextShaper::gfxCoreTextShaper(gfxMacFont *aFont)
     : gfxFontShaper(aFont)
 {
     // Create our CTFontRef
-    mCTFont = ::CTFontCreateWithPlatformFont(aFont->GetATSFontRef(),
-                                             aFont->GetAdjustedSize(),
-                                             NULL,
-                                             GetDefaultFeaturesDescriptor());
+    if (gfxMacPlatformFontList::UseATSFontEntry()) {
+        ATSFontEntry *fe = static_cast<ATSFontEntry*>(aFont->GetFontEntry());
+        mCTFont = ::CTFontCreateWithPlatformFont(fe->GetATSFontRef(),
+                                                 aFont->GetAdjustedSize(),
+                                                 NULL,
+                                                 GetDefaultFeaturesDescriptor());
+    } else {
+        mCTFont = ::CTFontCreateWithGraphicsFont(aFont->GetCGFontRef(),
+                                                 aFont->GetAdjustedSize(),
+                                                 NULL,
+                                                 GetDefaultFeaturesDescriptor());
+    }
 
     // Set up the default attribute dictionary that we will need each time we create a CFAttributedString
     mAttributesDict = ::CFDictionaryCreate(kCFAllocatorDefault,
                                            (const void**) &kCTFontAttributeName,
                                            (const void**) &mCTFont,
                                            1, // count of attributes
                                            &kCFTypeDictionaryKeyCallBacks,
                                            &kCFTypeDictionaryValueCallBacks);
@@ -156,20 +164,18 @@ gfxCoreTextShaper::InitTextRun(gfxContex
                                                          aRunLength,
                                                          kCFAllocatorNull);
     }
 
     CFDictionaryRef attrObj;
     if (disableLigatures) {
         // For letterspacing (or maybe other situations) we need to make a copy of the CTFont
         // with the ligature feature disabled
-        gfxMacFont *font = static_cast<gfxMacFont*>(mFont);
         CTFontRef ctFont =
-            CreateCTFontWithDisabledLigatures(font->GetATSFontRef(),
-                                              ::CTFontGetSize(mCTFont));
+            CreateCTFontWithDisabledLigatures(::CTFontGetSize(mCTFont));
 
         attrObj =
             ::CFDictionaryCreate(kCFAllocatorDefault,
                                  (const void**) &kCTFontAttributeName,
                                  (const void**) &ctFont,
                                  1, // count of attributes
                                  &kCFTypeDictionaryKeyCallBacks,
                                  &kCFTypeDictionaryValueCallBacks);
@@ -590,19 +596,19 @@ gfxCoreTextShaper::CreateDefaultFeatures
                              &kCFTypeDictionaryValueCallBacks);
     ::CFRelease(featuresArray);
 
     sDefaultFeaturesDescriptor =
         ::CTFontDescriptorCreateWithAttributes(attributesDict);
     ::CFRelease(attributesDict);
 }
 
-// Create a CTFontRef, with the Common Ligatures feature disabled [static]
+// Create a CTFontRef, with the Common Ligatures feature disabled
 CTFontRef
-gfxCoreTextShaper::CreateCTFontWithDisabledLigatures(ATSFontRef aFontRef, CGFloat aSize)
+gfxCoreTextShaper::CreateCTFontWithDisabledLigatures(CGFloat aSize)
 {
     if (sDisableLigaturesDescriptor == NULL) {
         // initialize cached descriptor to turn off the Common Ligatures feature
         SInt16 val = kLigaturesType;
         CFNumberRef ligaturesType =
             ::CFNumberCreate(kCFAllocatorDefault,
                              kCFNumberSInt16Type,
                              &val);
@@ -638,21 +644,30 @@ gfxCoreTextShaper::CreateCTFontWithDisab
                                  (const void **) &kCTFontFeatureSettingsAttribute,
                                  (const void **) &featuresArray,
                                  1, // count of keys & values
                                  &kCFTypeDictionaryKeyCallBacks,
                                  &kCFTypeDictionaryValueCallBacks);
         ::CFRelease(featuresArray);
 
         sDisableLigaturesDescriptor =
-            ::CTFontDescriptorCreateCopyWithAttributes(GetDefaultFeaturesDescriptor(), attributesDict);
+            ::CTFontDescriptorCreateCopyWithAttributes(GetDefaultFeaturesDescriptor(),
+                                                       attributesDict);
         ::CFRelease(attributesDict);
     }
-    
-    return ::CTFontCreateWithPlatformFont(aFontRef, aSize, NULL, sDisableLigaturesDescriptor);
+
+    if (gfxMacPlatformFontList::UseATSFontEntry()) {
+        ATSFontEntry *fe = static_cast<ATSFontEntry*>(mFont->GetFontEntry());
+        return ::CTFontCreateWithPlatformFont(fe->GetATSFontRef(), aSize, NULL,
+                                              sDisableLigaturesDescriptor);
+    }
+
+    gfxMacFont *f = static_cast<gfxMacFont*>(mFont);
+    return ::CTFontCreateWithGraphicsFont(f->GetCGFontRef(), aSize, NULL,
+                                          sDisableLigaturesDescriptor);
 }
 
 void
 gfxCoreTextShaper::Shutdown() // [static]
 {
     if (sDisableLigaturesDescriptor != NULL) {
         ::CFRelease(sDisableLigaturesDescriptor);
         sDisableLigaturesDescriptor = NULL;
--- a/gfx/thebes/gfxCoreTextShaper.h
+++ b/gfx/thebes/gfxCoreTextShaper.h
@@ -72,27 +72,27 @@ protected:
     CFDictionaryRef mAttributesDict;
 
     nsresult SetGlyphsFromRun(gfxTextRun *aTextRun,
                               CTRunRef aCTRun,
                               PRInt32 aStringOffset,
                               PRInt32 aLayoutStart,
                               PRInt32 aLayoutLength);
 
+    CTFontRef CreateCTFontWithDisabledLigatures(CGFloat aSize);
+
     static void CreateDefaultFeaturesDescriptor();
 
     static CTFontDescriptorRef GetDefaultFeaturesDescriptor() {
         if (sDefaultFeaturesDescriptor == NULL) {
             CreateDefaultFeaturesDescriptor();
         }
         return sDefaultFeaturesDescriptor;
     }
 
-    static CTFontRef CreateCTFontWithDisabledLigatures(ATSFontRef aFontRef, CGFloat aSize);
-
     // cached font descriptor, created the first time it's needed
     static CTFontDescriptorRef    sDefaultFeaturesDescriptor;
 
     // cached descriptor for adding disable-ligatures setting to a font
     static CTFontDescriptorRef    sDisableLigaturesDescriptor;
 };
 
 #endif /* GFX_CORETEXTSHAPER_H */
--- a/gfx/thebes/gfxMacFont.cpp
+++ b/gfx/thebes/gfxMacFont.cpp
@@ -48,26 +48,25 @@
 
 #include "cairo-quartz.h"
 
 using namespace mozilla;
 
 gfxMacFont::gfxMacFont(MacOSFontEntry *aFontEntry, const gfxFontStyle *aFontStyle,
                        PRBool aNeedsBold)
     : gfxFont(aFontEntry, aFontStyle),
-      mATSFont(aFontEntry->GetFontRef()),
       mCGFont(nsnull),
       mFontFace(nsnull),
       mScaledFont(nsnull)
 {
     if (aNeedsBold) {
         mSyntheticBoldOffset = 1;  // devunit offset when double-striking text to fake boldness
     }
 
-    mCGFont = ::CGFontCreateWithPlatformFont(&mATSFont);
+    mCGFont = aFontEntry->GetFontRef();
     if (!mCGFont) {
         mIsValid = PR_FALSE;
         return;
     }
 
     // InitMetrics will handle the sizeAdjust factor and set mAdjustedSize
     InitMetrics();
     if (!mIsValid) {
@@ -143,19 +142,16 @@ gfxMacFont::gfxMacFont(MacOSFontEntry *a
 gfxMacFont::~gfxMacFont()
 {
     if (mScaledFont) {
         cairo_scaled_font_destroy(mScaledFont);
     }
     if (mFontFace) {
         cairo_font_face_destroy(mFontFace);
     }
-
-    // this is documented to be safe if mCGFont is null
-    ::CGFontRelease(mCGFont);
 }
 
 PRBool
 gfxMacFont::InitTextRun(gfxContext *aContext,
                         gfxTextRun *aTextRun,
                         const PRUnichar *aString,
                         PRUint32 aRunStart,
                         PRUint32 aRunLength,
@@ -262,17 +258,17 @@ gfxMacFont::InitMetrics()
     } else {
         cgConvFactor = mFUnitsConvFactor;
     }
 
     // Try to read 'sfnt' metrics; for local, non-sfnt fonts ONLY, fall back to
     // platform APIs. The InitMetrics...() functions will set mIsValid on success.
     if (!InitMetricsFromSfntTables(mMetrics) &&
         (!mFontEntry->IsUserFont() || mFontEntry->IsLocalUserFont())) {
-        InitMetricsFromATSMetrics();
+        InitMetricsFromPlatform();
     }
     if (!mIsValid) {
         return;
     }
 
     if (mMetrics.xHeight == 0.0) {
         mMetrics.xHeight = ::CGFontGetXHeight(mCGFont) * cgConvFactor;
     }
@@ -286,17 +282,17 @@ gfxMacFont::InitMetrics()
         if (static_cast<MacOSFontEntry*>(mFontEntry.get())->IsCFF()) {
             cgConvFactor = mAdjustedSize / ::CGFontGetUnitsPerEm(mCGFont);
         } else {
             cgConvFactor = mFUnitsConvFactor;
         }
         mMetrics.xHeight = 0.0;
         if (!InitMetricsFromSfntTables(mMetrics) &&
             (!mFontEntry->IsUserFont() || mFontEntry->IsLocalUserFont())) {
-            InitMetricsFromATSMetrics();
+            InitMetricsFromPlatform();
         }
         if (!mIsValid) {
             // this shouldn't happen, as we succeeded earlier before applying
             // the size-adjust factor! But check anyway, for paranoia's sake.
             return;
         }
         if (mMetrics.xHeight == 0.0) {
             mMetrics.xHeight = ::CGFontGetXHeight(mCGFont) * cgConvFactor;
@@ -410,29 +406,75 @@ gfxMacFont::GetFontTable(PRUint32 aTag)
         if (mFontEntry->GetExistingFontTable(aTag, &blob)) {
             return blob;
         }
     }
 
     return nsnull;
 }
 
-// Try to initialize font metrics via ATS font metrics APIs,
+// Try to initialize font metrics via platform APIs (CG/CT),
 // and set mIsValid = TRUE on success.
 // We ONLY call this for local (platform) fonts that are not sfnt format;
-// for sfnts, including ALL downloadable fonts, use InitMetricsFromSfntTables
-// because ATSFontGetHorizontalMetrics() has been known to crash when
-// presented with bad fonts.
+// for sfnts, including ALL downloadable fonts, we prefer to use
+// InitMetricsFromSfntTables and avoid platform APIs.
 void
-gfxMacFont::InitMetricsFromATSMetrics()
+gfxMacFont::InitMetricsFromPlatform()
+{
+    if (gfxMacPlatformFontList::UseATSFontEntry()) {
+        ATSFontEntry *fe = static_cast<ATSFontEntry*>(GetFontEntry());
+        InitMetricsFromATSMetrics(fe->GetATSFontRef());
+        return;
+    }
+
+    CTFontRef ctFont = ::CTFontCreateWithGraphicsFont(mCGFont,
+                                                      mAdjustedSize,
+                                                      NULL, NULL);
+    if (!ctFont) {
+        return;
+    }
+
+    mMetrics.underlineOffset = ::CTFontGetUnderlinePosition(ctFont);
+    mMetrics.underlineSize = ::CTFontGetUnderlineThickness(ctFont);
+
+    mMetrics.externalLeading = ::CTFontGetLeading(ctFont);
+
+    mMetrics.maxAscent = ::CTFontGetAscent(ctFont);
+    mMetrics.maxDescent = ::CTFontGetDescent(ctFont);
+
+    // this is not strictly correct, but neither CTFont nor CGFont seems to
+    // provide maxAdvance, unless we were to iterate over all the glyphs
+    // (which isn't worth the cost here)
+    CGRect r = ::CTFontGetBoundingBox(ctFont);
+    mMetrics.maxAdvance = r.size.width;
+
+    // aveCharWidth is also not provided, so leave it at zero
+    // (fallback code in gfxMacFont::InitMetrics will then try measuring 'x');
+    // this could lead to less-than-"perfect" text field sizing when width is
+    // specified as a number of characters, and the font in use is a non-sfnt
+    // legacy font, but that's a sufficiently obscure edge case that we can
+    // ignore the potential discrepancy.
+    mMetrics.aveCharWidth = 0;
+
+    mMetrics.xHeight = ::CTFontGetXHeight(ctFont);
+
+    ::CFRelease(ctFont);
+
+    mIsValid = PR_TRUE;
+}
+
+// For OS X 10.5, try to initialize font metrics via ATS font metrics APIs,
+// and set mIsValid = TRUE on success.
+void
+gfxMacFont::InitMetricsFromATSMetrics(ATSFontRef aFontRef)
 {
     ATSFontMetrics atsMetrics;
     OSStatus err;
 
-    err = ::ATSFontGetHorizontalMetrics(mATSFont, kATSOptionFlagsDefault,
+    err = ::ATSFontGetHorizontalMetrics(aFontRef, kATSOptionFlagsDefault,
                                         &atsMetrics);
     if (err != noErr) {
 #ifdef DEBUG
         char warnBuf[1024];
         sprintf(warnBuf, "Bad font metrics for: %s err: %8.8x",
                 NS_ConvertUTF16toUTF8(mFontEntry->Name()).get(), PRUint32(err));
         NS_WARNING(warnBuf);
 #endif
--- a/gfx/thebes/gfxMacFont.h
+++ b/gfx/thebes/gfxMacFont.h
@@ -49,17 +49,16 @@
 class gfxMacFont : public gfxFont
 {
 public:
     gfxMacFont(MacOSFontEntry *aFontEntry, const gfxFontStyle *aFontStyle,
                PRBool aNeedsBold);
 
     virtual ~gfxMacFont();
 
-    ATSFontRef GetATSFontRef() const { return mATSFont; }
     CGFontRef GetCGFontRef() const { return mCGFont; }
 
     /* overrides for the pure virtual methods in gfxFont */
     virtual const gfxFont::Metrics& GetMetrics() {
         return mMetrics;
     }
 
     virtual PRUint32 GetSpaceGlyph() {
@@ -87,26 +86,28 @@ protected:
                                gfxTextRun *aTextRun,
                                const PRUnichar *aString,
                                PRUint32 aRunStart,
                                PRUint32 aRunLength,
                                PRInt32 aRunScript,
                                PRBool aPreferPlatformShaping = PR_FALSE);
 
     void InitMetrics();
-    void InitMetricsFromATSMetrics();
+    void InitMetricsFromPlatform();
+    void InitMetricsFromATSMetrics(ATSFontRef aFontRef);
 
     // Get width and glyph ID for a character; uses aConvFactor
     // to convert font units as returned by CG to actual dimensions
     gfxFloat GetCharWidth(CFDataRef aCmap, PRUnichar aUniChar,
                           PRUint32 *aGlyphID, gfxFloat aConvFactor);
 
     static void DestroyBlobFunc(void* aUserData);
 
-    ATSFontRef            mATSFont;
+    // a weak reference to the CoreGraphics font: this is owned by the
+    // MacOSFontEntry, it is not retained or released by gfxMacFont
     CGFontRef             mCGFont;
 
     cairo_font_face_t    *mFontFace;
     cairo_scaled_font_t  *mScaledFont;
 
     Metrics               mMetrics;
     PRUint32              mSpaceGlyph;
 };
--- a/gfx/thebes/gfxMacPlatformFontList.h
+++ b/gfx/thebes/gfxMacPlatformFontList.h
@@ -41,57 +41,108 @@
 #ifndef gfxMacPlatformFontList_H_
 #define gfxMacPlatformFontList_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
 {
 public:
     friend class gfxMacPlatformFontList;
 
-    MacOSFontEntry(const nsAString& aPostscriptName, PRInt32 aWeight,
-                   gfxFontFamily *aFamily, PRBool aIsStandardFace = PR_FALSE);
+    virtual ~MacOSFontEntry() {
+        ::CGFontRelease(mFontRef);
+    }
 
-    ATSFontRef GetFontRef();
+    virtual CGFontRef GetFontRef() = 0;
+
+    virtual nsresult GetFontTable(PRUint32 aTableTag,
+                                  FallibleTArray<PRUint8>& aBuffer) = 0;
+
     nsresult ReadCMAP();
 
     PRBool RequiresAATLayout() const { return mRequiresAAT; }
 
-    virtual nsresult GetFontTable(PRUint32 aTableTag, FallibleTArray<PRUint8>& aBuffer);
-
     PRBool IsCFF();
 
 protected:
-    // for use with data fonts
-    MacOSFontEntry(const nsAString& aPostscriptName, ATSFontRef aFontRef,
-                   PRUint16 aWeight, PRUint16 aStretch, PRUint32 aItalicStyle,
-                   gfxUserFontData *aUserFontData);
+    MacOSFontEntry(const nsAString& aPostscriptName, PRInt32 aWeight,
+                   gfxFontFamily *aFamily, PRBool aIsStandardFace = PR_FALSE);
 
     virtual gfxFont* CreateFontInstance(const gfxFontStyle *aFontStyle, PRBool aNeedsBold);
 
-    ATSFontRef mATSFontRef;
-    PRPackedBool mATSFontRefInitialized;
+    virtual PRBool HasFontTable(PRUint32 aTableTag) = 0;
+
+    CGFontRef mFontRef; // owning reference to the CGFont, released on destruction
+
+    PRPackedBool mFontRefInitialized;
     PRPackedBool mRequiresAAT;
     PRPackedBool mIsCFF;
     PRPackedBool mIsCFFInitialized;
 };
 
+// concrete subclasses of MacOSFontEntry: ATSFontEntry for 10.5, CGFontEntry for 10.6+
+class ATSFontEntry : public MacOSFontEntry
+{
+public:
+    ATSFontEntry(const nsAString& aPostscriptName, PRInt32 aWeight,
+                 gfxFontFamily *aFamily, PRBool aIsStandardFace = PR_FALSE);
+
+    // for use with data fonts
+    ATSFontEntry(const nsAString& aPostscriptName, ATSFontRef aFontRef,
+                 PRUint16 aWeight, PRUint16 aStretch, PRUint32 aItalicStyle,
+                 gfxUserFontData *aUserFontData, PRBool aIsLocal);
+
+    ATSFontRef GetATSFontRef();
+
+    virtual CGFontRef GetFontRef();
+
+    virtual nsresult GetFontTable(PRUint32 aTableTag,
+                                  FallibleTArray<PRUint8>& aBuffer);
+
+protected:
+    virtual PRBool HasFontTable(PRUint32 aTableTag);
+
+    ATSFontRef   mATSFontRef;
+    PRPackedBool mATSFontRefInitialized;
+};
+
+class CGFontEntry : public MacOSFontEntry
+{
+public:
+    CGFontEntry(const nsAString& aPostscriptName, PRInt32 aWeight,
+                gfxFontFamily *aFamily, PRBool aIsStandardFace = PR_FALSE);
+
+    // for use with data fonts
+    CGFontEntry(const nsAString& aPostscriptName, CGFontRef aFontRef,
+                PRUint16 aWeight, PRUint16 aStretch, PRUint32 aItalicStyle,
+                PRBool aIsUserFont, PRBool aIsLocal);
+
+    virtual CGFontRef GetFontRef();
+
+    virtual nsresult GetFontTable(PRUint32 aTableTag,
+                                  FallibleTArray<PRUint8>& aBuffer);
+
+protected:
+    virtual PRBool HasFontTable(PRUint32 aTableTag);
+};
+
 class gfxMacPlatformFontList : public gfxPlatformFontList {
 public:
     static gfxMacPlatformFontList* PlatformFontList() {
         return static_cast<gfxMacPlatformFontList*>(sPlatformFontList);
     }
 
     static PRInt32 AppleWeightToCSSWeight(PRInt32 aAppleWeight);
 
@@ -102,29 +153,36 @@ public:
     virtual gfxFontEntry* LookupLocalFont(const gfxProxyFontEntry *aProxyEntry,
                                           const nsAString& aFontName);
     
     virtual gfxFontEntry* MakePlatformFont(const gfxProxyFontEntry *aProxyEntry,
                                            const PRUint8 *aFontData, PRUint32 aLength);
 
     void ClearPrefFonts() { mPrefFonts.Clear(); }
 
+    static PRBool UseATSFontEntry() {
+        return gfxPlatformMac::GetPlatform()->OSXVersion() < MAC_OS_X_VERSION_10_6_HEX;
+    }
+
 private:
     friend class gfxPlatformMac;
 
     gfxMacPlatformFontList();
 
     // initialize font lists
     virtual nsresult InitFontList();
 
     // special case font faces treated as font families (set via prefs)
     void InitSingleFaceList();
 
-    // eliminate faces which have the same ATS font reference
-    void EliminateDuplicateFaces(const nsAString& aFamilyName);
+    gfxFontEntry* MakePlatformFontCG(const gfxProxyFontEntry *aProxyEntry,
+                                     const PRUint8 *aFontData, PRUint32 aLength);
+
+    gfxFontEntry* MakePlatformFontATS(const gfxProxyFontEntry *aProxyEntry,
+                                      const PRUint8 *aFontData, PRUint32 aLength);
 
     static void ATSNotification(ATSFontNotificationInfoRef aInfo, void* aUserArg);
 
     // keep track of ATS generation to prevent unneeded updates when loading downloaded fonts
     PRUint32 mATSGeneration;
 
     enum {
         kATSGenerationInitial = -1
--- a/gfx/thebes/gfxMacPlatformFontList.mm
+++ b/gfx/thebes/gfxMacPlatformFontList.mm
@@ -130,65 +130,33 @@ static NSString* GetNSStringForString(co
 #define LOG_FONTLIST(args) PR_LOG(gfxPlatform::GetLog(eGfxLog_fontlist), \
                                PR_LOG_DEBUG, args)
 #define LOG_FONTLIST_ENABLED() PR_LOG_TEST( \
                                    gfxPlatform::GetLog(eGfxLog_fontlist), \
                                    PR_LOG_DEBUG)
 
 #endif // PR_LOGGING
 
-/* MacOSFontEntry */
+/* MacOSFontEntry - abstract superclass for ATS and CG font entries */
 #pragma mark-
 
 MacOSFontEntry::MacOSFontEntry(const nsAString& aPostscriptName,
                                PRInt32 aWeight,
                                gfxFontFamily *aFamily,
                                PRBool aIsStandardFace)
     : gfxFontEntry(aPostscriptName, aFamily, aIsStandardFace),
-      mATSFontRef(0),
-      mATSFontRefInitialized(PR_FALSE),
+      mFontRef(NULL),
+      mFontRefInitialized(PR_FALSE),
       mRequiresAAT(PR_FALSE),
       mIsCFF(PR_FALSE),
       mIsCFFInitialized(PR_FALSE)
 {
     mWeight = aWeight;
 }
 
-MacOSFontEntry::MacOSFontEntry(const nsAString& aPostscriptName, ATSFontRef aFontRef,
-                               PRUint16 aWeight, PRUint16 aStretch, PRUint32 aItalicStyle,
-                               gfxUserFontData *aUserFontData)
-    : gfxFontEntry(aPostscriptName),
-      mATSFontRef(aFontRef),
-      mATSFontRefInitialized(PR_TRUE),
-      mRequiresAAT(PR_FALSE),
-      mIsCFF(PR_FALSE),
-      mIsCFFInitialized(PR_FALSE)
-{
-    // xxx - stretch is basically ignored for now
-
-    mUserFontData = aUserFontData;
-    mWeight = aWeight;
-    mStretch = aStretch;
-    mFixedPitch = PR_FALSE; // xxx - do we need this for downloaded fonts?
-    mItalic = (aItalicStyle & (FONT_STYLE_ITALIC | FONT_STYLE_OBLIQUE)) != 0;
-    mIsUserFont = aUserFontData != nsnull;
-}
-
-ATSFontRef
-MacOSFontEntry::GetFontRef()
-{
-    if (!mATSFontRefInitialized) {
-        mATSFontRefInitialized = PR_TRUE;
-        NSString *psname = GetNSStringForString(mName);
-        mATSFontRef = ::ATSFontFindFromPostScriptName(CFStringRef(psname),
-                                                      kATSOptionFlagsDefault);
-    }
-    return mATSFontRef;
-}
-
 // ATSUI requires AAT-enabled fonts to render complex scripts correctly.
 // For now, simple clear out the cmap codepoints for fonts that have
 // codepoints for complex scripts. (Bug 361986)
 // Core Text is similar, but can render Arabic using OpenType fonts as well.
 
 enum eComplexScript {
     eComplexScriptArabic,
     eComplexScriptIndic,
@@ -207,55 +175,50 @@ const ScriptRange gScriptsThatRequireSha
     { eComplexScriptTibetan, 0x0F00, 0x0FFF }     // Tibetan
     // Thai seems to be "renderable" without AAT morphing tables
     // xxx - Lao, Khmer?
 };
 
 nsresult
 MacOSFontEntry::ReadCMAP()
 {
-    ByteCount size;
-
     // attempt this once, if errors occur leave a blank cmap
-    if (mCmapInitialized)
+    if (mCmapInitialized) {
         return NS_OK;
+    }
     mCmapInitialized = PR_TRUE;
 
     PRUint32 kCMAP = TRUETYPE_TAG('c','m','a','p');
 
     AutoFallibleTArray<PRUint8,16384> cmap;
-    if (GetFontTable(kCMAP, cmap) != NS_OK)
+    if (GetFontTable(kCMAP, cmap) != NS_OK) {
         return NS_ERROR_FAILURE;
+    }
 
     PRPackedBool  unicodeFont, symbolFont; // currently ignored
     nsresult rv = gfxFontUtils::ReadCMAP(cmap.Elements(), cmap.Length(),
                                          mCharacterMap, mUVSOffset,
                                          unicodeFont, symbolFont);
     if (NS_FAILED(rv)) {
         mCharacterMap.reset();
         return rv;
     }
     mHasCmapTable = PR_TRUE;
 
-    ATSFontRef fontRef = GetFontRef();
+    CGFontRef fontRef = GetFontRef();
+    if (!fontRef) {
+        return NS_ERROR_FAILURE;
+    }
 
     // for layout support, check for the presence of mort/morx and/or
     // opentype layout tables
-    PRBool hasAATLayout =
-        (::ATSFontGetTable(fontRef, TRUETYPE_TAG('m','o','r','x'),
-                           0, 0, 0, &size) == noErr) ||
-        (::ATSFontGetTable(fontRef, TRUETYPE_TAG('m','o','r','t'),
-                           0, 0, 0, &size) == noErr);
-
-    PRBool hasGSUB =
-        (::ATSFontGetTable(fontRef, TRUETYPE_TAG('G','S','U','B'),
-                           0, 0, 0, &size) == noErr);
-    PRBool hasGPOS =
-        (::ATSFontGetTable(fontRef, TRUETYPE_TAG('G','P','O','S'),
-                           0, 0, 0, &size) == noErr);
+    PRBool hasAATLayout = HasFontTable(TRUETYPE_TAG('m','o','r','x')) ||
+                          HasFontTable(TRUETYPE_TAG('m','o','r','t'));
+    PRBool hasGSUB = HasFontTable(TRUETYPE_TAG('G','S','U','B'));
+    PRBool hasGPOS = HasFontTable(TRUETYPE_TAG('G','P','O','S'));
 
     if (hasAATLayout && !(hasGSUB || hasGPOS)) {
         mRequiresAAT = PR_TRUE; // prefer CoreText if font has no OTL tables
     }
 
     PRUint32 numScripts =
         sizeof(gScriptsThatRequireShaping) / sizeof(ScriptRange);
 
@@ -300,23 +263,103 @@ MacOSFontEntry::ReadCMAP()
     LOG_FONTLIST(("(fontlist-cmap) name: %s, size: %d\n",
                   NS_ConvertUTF16toUTF8(mName).get(),
                   mCharacterMap.GetSize()));
 #endif
 
     return rv;
 }
 
+gfxFont*
+MacOSFontEntry::CreateFontInstance(const gfxFontStyle *aFontStyle, PRBool aNeedsBold)
+{
+    return new gfxMacFont(this, aFontStyle, aNeedsBold);
+}
+
+PRBool
+MacOSFontEntry::IsCFF()
+{
+    if (!mIsCFFInitialized) {
+        mIsCFFInitialized = PR_TRUE;
+        mIsCFF = HasFontTable(TRUETYPE_TAG('C','F','F',' '));
+    }
+
+    return mIsCFF;
+}
+
+/* ATSFontEntry - used on Mac OS X 10.5.x */
+#pragma mark-
+
+ATSFontEntry::ATSFontEntry(const nsAString& aPostscriptName,
+                           PRInt32 aWeight,
+                           gfxFontFamily *aFamily,
+                           PRBool aIsStandardFace)
+    : MacOSFontEntry(aPostscriptName, aWeight, aFamily, aIsStandardFace),
+      mATSFontRef(kInvalidFont),
+      mATSFontRefInitialized(PR_FALSE)
+{
+}
+
+ATSFontEntry::ATSFontEntry(const nsAString& aPostscriptName,
+                           ATSFontRef aFontRef,
+                           PRUint16 aWeight, PRUint16 aStretch,
+                           PRUint32 aItalicStyle,
+                           gfxUserFontData *aUserFontData,
+                           PRBool aIsLocal)
+    : MacOSFontEntry(aPostscriptName, aWeight, nsnull, PR_FALSE)
+{
+    mATSFontRef = aFontRef;
+    mATSFontRefInitialized = PR_TRUE;
+
+    mWeight = aWeight;
+    mStretch = aStretch;
+    mFixedPitch = PR_FALSE; // xxx - do we need this for downloaded fonts?
+    mItalic = (aItalicStyle & (FONT_STYLE_ITALIC | FONT_STYLE_OBLIQUE)) != 0;
+    mUserFontData = aUserFontData;
+    mIsUserFont = (aUserFontData != nsnull) || aIsLocal;
+    mIsLocalUserFont = aIsLocal;
+}
+
+ATSFontRef
+ATSFontEntry::GetATSFontRef()
+{
+    if (!mATSFontRefInitialized) {
+        mATSFontRefInitialized = PR_TRUE;
+        NSString *psname = GetNSStringForString(mName);
+        mATSFontRef = ::ATSFontFindFromPostScriptName(CFStringRef(psname),
+                                                      kATSOptionFlagsDefault);
+    }
+    return mATSFontRef;
+}
+
+CGFontRef
+ATSFontEntry::GetFontRef()
+{
+    if (mFontRefInitialized) {
+        return mFontRef;
+    }
+
+    // GetATSFontRef will initialize mATSFontRef
+    if (GetATSFontRef() == kInvalidFont) {
+        return nsnull;
+    }
+    
+    mFontRef = ::CGFontCreateWithPlatformFont(&mATSFontRef);
+    mFontRefInitialized = PR_TRUE;
+
+    return mFontRef;
+}
+
 nsresult
-MacOSFontEntry::GetFontTable(PRUint32 aTableTag, FallibleTArray<PRUint8>& aBuffer)
+ATSFontEntry::GetFontTable(PRUint32 aTableTag, FallibleTArray<PRUint8>& aBuffer)
 {
     nsAutoreleasePool localPool;
 
-    ATSFontRef fontRef = GetFontRef();
-    if (fontRef == (ATSFontRef)kATSUInvalidFontID) {
+    ATSFontRef fontRef = GetATSFontRef();
+    if (fontRef == kInvalidFont) {
         return NS_ERROR_FAILURE;
     }
 
     ByteCount dataLength;
     OSStatus status = ::ATSFontGetTable(fontRef, aTableTag, 0, 0, 0, &dataLength);
     if (status != noErr) {
         return NS_ERROR_FAILURE;
     }
@@ -326,61 +369,129 @@ MacOSFontEntry::GetFontTable(PRUint32 aT
     }
     PRUint8 *dataPtr = aBuffer.Elements();
 
     status = ::ATSFontGetTable(fontRef, aTableTag, 0, dataLength, dataPtr, &dataLength);
     NS_ENSURE_TRUE(status == noErr, NS_ERROR_FAILURE);
 
     return NS_OK;
 }
+ 
+PRBool
+ATSFontEntry::HasFontTable(PRUint32 aTableTag)
+{
+    ATSFontRef fontRef = GetATSFontRef();
+    ByteCount size;
+    return fontRef != kInvalidFont &&
+        (::ATSFontGetTable(fontRef, aTableTag, 0, 0, 0, &size) == noErr);
+}
 
-gfxFont*
-MacOSFontEntry::CreateFontInstance(const gfxFontStyle *aFontStyle, PRBool aNeedsBold)
+/* CGFontEntry - used on Mac OS X 10.6+ */
+#pragma mark-
+
+CGFontEntry::CGFontEntry(const nsAString& aPostscriptName,
+                         PRInt32 aWeight,
+                         gfxFontFamily *aFamily,
+                         PRBool aIsStandardFace)
+    : MacOSFontEntry(aPostscriptName, aWeight, aFamily, aIsStandardFace)
+{
+}
+
+CGFontEntry::CGFontEntry(const nsAString& aPostscriptName,
+                         CGFontRef aFontRef,
+                         PRUint16 aWeight, PRUint16 aStretch,
+                         PRUint32 aItalicStyle,
+                         PRBool aIsUserFont, PRBool aIsLocal)
+    : MacOSFontEntry(aPostscriptName, aWeight, nsnull, PR_FALSE)
+{
+    mFontRef = aFontRef;
+    mFontRefInitialized = PR_TRUE;
+    ::CFRetain(mFontRef);
+
+    mWeight = aWeight;
+    mStretch = aStretch;
+    mFixedPitch = PR_FALSE; // xxx - do we need this for downloaded fonts?
+    mItalic = (aItalicStyle & (FONT_STYLE_ITALIC | FONT_STYLE_OBLIQUE)) != 0;
+    mIsUserFont = aIsUserFont;
+    mIsLocalUserFont = aIsLocal;
+}
+
+CGFontRef
+CGFontEntry::GetFontRef()
 {
-    return new gfxMacFont(this, aFontStyle, aNeedsBold);
+    if (!mFontRefInitialized) {
+        mFontRefInitialized = PR_TRUE;
+        NSString *psname = GetNSStringForString(mName);
+        mFontRef = ::CGFontCreateWithFontName(CFStringRef(psname));
+    }
+    return mFontRef;
+}
+
+nsresult
+CGFontEntry::GetFontTable(PRUint32 aTableTag, FallibleTArray<PRUint8>& aBuffer)
+{
+    nsAutoreleasePool localPool;
+
+    CGFontRef fontRef = GetFontRef();
+    if (!fontRef) {
+        return NS_ERROR_FAILURE;
+    }
+
+    CFDataRef tableData = ::CGFontCopyTableForTag(fontRef, aTableTag);
+    if (!tableData) {
+        return NS_ERROR_FAILURE;
+    }
+
+    nsresult rval = NS_OK;
+    CFIndex dataLength = ::CFDataGetLength(tableData);
+    if (aBuffer.AppendElements(dataLength)) {
+        ::CFDataGetBytes(tableData, ::CFRangeMake(0, dataLength),
+                         aBuffer.Elements());
+    } else {
+        rval = NS_ERROR_OUT_OF_MEMORY;
+    }
+    ::CFRelease(tableData);
+
+    return rval;
 }
 
 PRBool
-MacOSFontEntry::IsCFF()
+CGFontEntry::HasFontTable(PRUint32 aTableTag)
 {
-    if (!mIsCFFInitialized) {
-        mIsCFFInitialized = PR_TRUE;
-        ATSFontRef fontRef = GetFontRef();
-        if (fontRef != (ATSFontRef)kATSUInvalidFontID) {
-            ByteCount dataLength;
-            OSStatus status = ::ATSFontGetTable(fontRef,
-                                                TRUETYPE_TAG('C','F','F',' '),
-                                                0, 0, 0, &dataLength);
-            if (status == noErr && dataLength > 0) {
-                mIsCFF = PR_TRUE;
-            }
-        }
+    nsAutoreleasePool localPool;
+
+    CGFontRef fontRef = GetFontRef();
+    if (!fontRef) {
+        return PR_FALSE;
     }
 
-    return mIsCFF;
+    CFDataRef tableData = ::CGFontCopyTableForTag(fontRef, aTableTag);
+    if (!tableData) {
+        return PR_FALSE;
+    }
+
+    ::CFRelease(tableData);
+    return PR_TRUE;
 }
 
-
 /* gfxMacFontFamily */
 #pragma mark-
 
 class gfxMacFontFamily : public gfxFontFamily
 {
 public:
     gfxMacFontFamily(nsAString& aName) :
         gfxFontFamily(aName)
     {}
 
     virtual ~gfxMacFontFamily() {}
 
     virtual void LocalizedName(nsAString& aLocalizedName);
 
     virtual void FindStyleVariations();
-
-    void EliminateDuplicateFaces();
 };
 
 void
 gfxMacFontFamily::LocalizedName(nsAString& aLocalizedName)
 {
     nsAutoreleasePool localPool;
 
     if (!HasOtherFamilyNames()) {
@@ -450,19 +561,27 @@ gfxMacFontFamily::FindStyleVariations()
             [facename isEqualToString:@"Oblique"] ||
             [facename isEqualToString:@"Bold Italic"] ||
             [facename isEqualToString:@"Bold Oblique"])
         {
             isStandardFace = PR_TRUE;
         }
 
         // create a font entry
-        MacOSFontEntry *fontEntry = new MacOSFontEntry(postscriptFontName,
-                                                       cssWeight, this, isStandardFace);
-        if (!fontEntry) break;
+        MacOSFontEntry *fontEntry;
+        if (gfxMacPlatformFontList::UseATSFontEntry()) {
+            fontEntry = new ATSFontEntry(postscriptFontName,
+                                         cssWeight, this, isStandardFace);
+        } else {
+            fontEntry = new CGFontEntry(postscriptFontName,
+                                        cssWeight, this, isStandardFace);
+        }
+        if (!fontEntry) {
+            break;
+        }
 
         // set additional properties based on the traits reported by Cocoa
         if (macTraits & (NSCondensedFontMask | NSNarrowFontMask | NSCompressedFontMask)) {
             fontEntry->mStretch = NS_FONT_STRETCH_CONDENSED;
         } else if (macTraits & NSExpandedFontMask) {
             fontEntry->mStretch = NS_FONT_STRETCH_EXPANDED;
         }
         // Cocoa fails to set the Italic traits bit for HelveticaLightItalic,
@@ -497,64 +616,16 @@ gfxMacFontFamily::FindStyleVariations()
     SortAvailableFonts();
     SetHasStyles(PR_TRUE);
 
     if (mIsBadUnderlineFamily) {
         SetBadUnderlineFonts();
     }
 }
 
-void
-gfxMacFontFamily::EliminateDuplicateFaces()
-{
-    PRUint32 i, bold, numFonts, italicIndex;
-    MacOSFontEntry *italic, *nonitalic;
-
-    FindStyleVariations();
-
-    // if normal and italic have the same ATS font ref, delete italic
-    // if bold and bold-italic have the same ATS font ref, delete bold-italic
-
-    // two iterations, one for normal, one for bold
-    for (bold = 0; bold < 2; bold++) {
-        numFonts = mAvailableFonts.Length();
-
-        // find the non-italic face
-        nonitalic = nsnull;
-        for (i = 0; i < numFonts; i++) {
-            if ((mAvailableFonts[i]->IsBold() == (bold == 1)) &&
-                !mAvailableFonts[i]->IsItalic()) {
-                nonitalic = static_cast<MacOSFontEntry*>(mAvailableFonts[i].get());
-                break;
-            }
-        }
-
-        // find the italic face
-        if (nonitalic) {
-            italic = nsnull;
-            for (i = 0; i < numFonts; i++) {
-                if ((mAvailableFonts[i]->IsBold() == (bold == 1)) &&
-                     mAvailableFonts[i]->IsItalic()) {
-                    italic = static_cast<MacOSFontEntry*>(mAvailableFonts[i].get());
-                    italicIndex = i;
-                    break;
-                }
-            }
-
-            // if italic face and non-italic face have matching ATS refs,
-            // or if the italic returns 0 rather than an actual ATSFontRef,
-            // then the italic face is bogus so remove it
-            if (italic && (italic->GetFontRef() == 0 ||
-                           italic->GetFontRef() == nonitalic->GetFontRef())) {
-                mAvailableFonts.RemoveElementAt(italicIndex);
-            }
-        }
-    }
-}
-
 
 /* gfxSingleFaceMacFontFamily */
 #pragma mark-
 
 class gfxSingleFaceMacFontFamily : public gfxFontFamily
 {
 public:
     gfxSingleFaceMacFontFamily(nsAString& aName) :
@@ -681,29 +752,16 @@ gfxMacPlatformFontList::InitFontList()
 
     InitSingleFaceList();
 
     // to avoid full search of font name tables, seed the other names table with localized names from
     // some of the prefs fonts which are accessed via their localized names.  changes in the pref fonts will only cause
     // a font lookup miss earlier. this is a simple optimization, it's not required for correctness
     PreloadNamesList();
 
-    // clean up various minor 10.4 font problems for specific fonts
-    if (gfxPlatformMac::GetPlatform()->OSXVersion() < MAC_OS_X_VERSION_10_5_HEX) {
-        // Cocoa calls report that italic faces exist for Courier and Helvetica,
-        // even though only bold faces exist so test for this using ATS font refs (10.5 has proper faces)
-        EliminateDuplicateFaces(NS_LITERAL_STRING("Courier"));
-        EliminateDuplicateFaces(NS_LITERAL_STRING("Helvetica"));
-
-        // Cocoa reports that Courier and Monaco are not fixed-pitch fonts
-        // so explicitly tweak these settings
-        SetFixedPitch(NS_LITERAL_STRING("Courier"));
-        SetFixedPitch(NS_LITERAL_STRING("Monaco"));
-    }
-
     // start the delayed cmap loader
     StartLoader(kDelayBeforeLoadingCmaps, kIntervalBetweenLoadingCmaps);
 
 	return NS_OK;
 }
 
 void
 gfxMacPlatformFontList::InitSingleFaceList()
@@ -742,26 +800,16 @@ gfxMacPlatformFontList::InitSingleFaceLi
                               NS_ConvertUTF16toUTF8(familyName).get(),
                               NS_ConvertUTF16toUTF8(key).get()));
 #endif
             }
         }
     }
 }
 
-void
-gfxMacPlatformFontList::EliminateDuplicateFaces(const nsAString& aFamilyName)
-{
-    gfxMacFontFamily *family =
-        static_cast<gfxMacFontFamily*>(FindFamily(aFamilyName));
-
-    if (family)
-        family->EliminateDuplicateFaces();
-}
-
 PRBool
 gfxMacPlatformFontList::GetStandardFamilyName(const nsAString& aFontName, nsAString& aFamilyName)
 {
     gfxFontFamily *family = FindFamily(aFontName);
     if (family) {
         family->LocalizedName(aFamilyName);
         return PR_TRUE;
     }
@@ -836,80 +884,172 @@ gfxMacPlatformFontList::AppleWeightToCSS
 
 gfxFontEntry*
 gfxMacPlatformFontList::LookupLocalFont(const gfxProxyFontEntry *aProxyEntry,
                                         const nsAString& aFontName)
 {
     nsAutoreleasePool localPool;
 
     NSString *faceName = GetNSStringForString(aFontName);
+    MacOSFontEntry *newFontEntry;
 
-    // first lookup a single face based on postscript name
-    ATSFontRef fontRef = ::ATSFontFindFromPostScriptName(CFStringRef(faceName),
-                                                         kATSOptionFlagsDefault);
+    if (UseATSFontEntry()) {
+        // first lookup a single face based on postscript name
+        ATSFontRef fontRef = ::ATSFontFindFromPostScriptName(CFStringRef(faceName),
+                                                             kATSOptionFlagsDefault);
 
-    // if not found, lookup using full font name
-    if (fontRef == kInvalidFont)
-        fontRef = ::ATSFontFindFromName(CFStringRef(faceName),
-                                        kATSOptionFlagsDefault);
-
-    // not found
-    if (fontRef == kInvalidFont)
-        return nsnull;
+        // if not found, lookup using full font name
+        if (fontRef == kInvalidFont) {
+            fontRef = ::ATSFontFindFromName(CFStringRef(faceName),
+                                            kATSOptionFlagsDefault);
+            if (fontRef == kInvalidFont) {
+                return nsnull;
+            }
+        }
 
-    MacOSFontEntry *newFontEntry;
-    if (aProxyEntry) {
-        PRUint16 w = aProxyEntry->mWeight;
-        NS_ASSERTION(w >= 100 && w <= 900, "bogus font weight value!");
+        if (aProxyEntry) {
+            PRUint16 w = aProxyEntry->mWeight;
+            NS_ASSERTION(w >= 100 && w <= 900, "bogus font weight value!");
+ 
+            newFontEntry =
+                new ATSFontEntry(aFontName, fontRef,
+                                 w, aProxyEntry->mStretch,
+                                 aProxyEntry->mItalic ?
+                                     FONT_STYLE_ITALIC : FONT_STYLE_NORMAL,
+                                 nsnull, PR_TRUE);
+        } else {
+            newFontEntry =
+                new ATSFontEntry(aFontName, fontRef,
+                                 400, 0, FONT_STYLE_NORMAL, nsnull, PR_FALSE);
+        }
+    } else {
+        // lookup face based on postscript or full name
+        CGFontRef fontRef = ::CGFontCreateWithFontName(CFStringRef(faceName));
+        if (!fontRef) {
+            return nsnull;
+        }
 
-        newFontEntry =
-            new MacOSFontEntry(aFontName, fontRef,
-                               w, aProxyEntry->mStretch,
-                               aProxyEntry->mItalic ?
-                                   FONT_STYLE_ITALIC : FONT_STYLE_NORMAL,
-                               nsnull);
-        newFontEntry->mIsUserFont = newFontEntry->mIsLocalUserFont = PR_TRUE;
-    } else {
-        newFontEntry =
-            new MacOSFontEntry(aFontName, fontRef,
-                               400, 0, FONT_STYLE_NORMAL, nsnull);
+        if (aProxyEntry) {
+            PRUint16 w = aProxyEntry->mWeight;
+            NS_ASSERTION(w >= 100 && w <= 900, "bogus font weight value!");
+
+            newFontEntry =
+                new CGFontEntry(aFontName, fontRef,
+                                w, aProxyEntry->mStretch,
+                                aProxyEntry->mItalic ?
+                                    FONT_STYLE_ITALIC : FONT_STYLE_NORMAL,
+                                PR_TRUE, PR_TRUE);
+        } else {
+            newFontEntry =
+                new CGFontEntry(aFontName, fontRef,
+                                400, 0, FONT_STYLE_NORMAL,
+                                PR_FALSE, PR_FALSE);
+        }
+        ::CFRelease(fontRef);
     }
 
     return newFontEntry;
 }
 
+gfxFontEntry*
+gfxMacPlatformFontList::MakePlatformFont(const gfxProxyFontEntry *aProxyEntry,
+                                         const PRUint8 *aFontData,
+                                         PRUint32 aLength)
+{
+    return UseATSFontEntry()
+        ? MakePlatformFontATS(aProxyEntry, aFontData, aLength)
+        : MakePlatformFontCG(aProxyEntry, aFontData, aLength);
+}
+
+static void ReleaseData(void *info, const void *data, size_t size)
+{
+    NS_Free((void*)data);
+}
+
+gfxFontEntry*
+gfxMacPlatformFontList::MakePlatformFontCG(const gfxProxyFontEntry *aProxyEntry,
+                                           const PRUint8 *aFontData,
+                                           PRUint32 aLength)
+{
+    NS_ASSERTION(aFontData, "MakePlatformFont called with null data");
+
+    PRUint16 w = aProxyEntry->mWeight;
+    NS_ASSERTION(w >= 100 && w <= 900, "bogus font weight value!");
+
+    // create the font entry
+    nsAutoString uniqueName;
+
+    nsresult rv = gfxFontUtils::MakeUniqueUserFontName(uniqueName);
+    if (NS_FAILED(rv)) {
+        return nsnull;
+    }
+
+    CGDataProviderRef provider =
+        ::CGDataProviderCreateWithData(nsnull, aFontData, aLength,
+                                       &ReleaseData);
+    CGFontRef fontRef = ::CGFontCreateWithDataProvider(provider);
+    ::CGDataProviderRelease(provider);
+
+    if (!fontRef) {
+        return nsnull;
+    }
+
+    nsAutoPtr<CGFontEntry>
+        newFontEntry(new CGFontEntry(uniqueName, fontRef, w,
+                                     aProxyEntry->mStretch,
+                                     aProxyEntry->mItalic ?
+                                         FONT_STYLE_ITALIC : FONT_STYLE_NORMAL,
+                                     PR_TRUE, PR_FALSE));
+
+    // if succeeded and font cmap is good, return the new font
+    if (newFontEntry->mIsValid && NS_SUCCEEDED(newFontEntry->ReadCMAP())) {
+        return newFontEntry.forget();
+    }
+
+    // if something is funky about this font, delete immediately
+#if DEBUG
+    char warnBuf[1024];
+    sprintf(warnBuf, "downloaded font not loaded properly, removed face for (%s)",
+            NS_ConvertUTF16toUTF8(aProxyEntry->mFamily->Name()).get());
+    NS_WARNING(warnBuf);
+#endif
+
+    return nsnull;
+}
+
 // grumble, another non-publised Apple API dependency (found in Webkit code)
 // activated with this value, font will not be found via system lookup routines
 // it can only be used via the created ATSFontRef
 // needed to prevent one doc from finding a font used in a separate doc
 
 enum {
     kPrivateATSFontContextPrivate = 3
 };
 
-class MacOSUserFontData : public gfxUserFontData {
+class ATSUserFontData : public gfxUserFontData {
 public:
-    MacOSUserFontData(ATSFontContainerRef aContainerRef)
+    ATSUserFontData(ATSFontContainerRef aContainerRef)
         : mContainerRef(aContainerRef)
     { }
 
-    virtual ~MacOSUserFontData()
+    virtual ~ATSUserFontData()
     {
         // deactivate font
-        if (mContainerRef)
+        if (mContainerRef) {
             ::ATSFontDeactivate(mContainerRef, NULL, kATSOptionFlagsDefault);
+        }
     }
 
     ATSFontContainerRef     mContainerRef;
 };
 
 gfxFontEntry*
-gfxMacPlatformFontList::MakePlatformFont(const gfxProxyFontEntry *aProxyEntry,
-                                         const PRUint8 *aFontData,
-                                         PRUint32 aLength)
+gfxMacPlatformFontList::MakePlatformFontATS(const gfxProxyFontEntry *aProxyEntry,
+                                            const PRUint8 *aFontData,
+                                            PRUint32 aLength)
 {
     OSStatus err;
 
     NS_ASSERTION(aFontData, "MakePlatformFont called with null data");
 
     // MakePlatformFont is responsible for deleting the font data with NS_Free
     // so we set up a stack object to ensure it is freed even if we take an
     // early exit
@@ -977,52 +1117,40 @@ gfxMacPlatformFontList::MakePlatformFont
             NS_WARNING(warnBuf);
 #endif
             ::ATSFontDeactivate(containerRef, NULL, kATSOptionFlagsDefault);
             // retry the activation a couple of times if this fails
             // (may be a transient failure due to ATS font cache issues)
             continue;
         }
 
-        // font entry will own this
-        MacOSUserFontData *userFontData = new MacOSUserFontData(containerRef);
-
-        if (!userFontData) {
-            ::ATSFontDeactivate(containerRef, NULL, kATSOptionFlagsDefault);
-            return nsnull;
-        }
-
         PRUint16 w = aProxyEntry->mWeight;
         NS_ASSERTION(w >= 100 && w <= 900, "bogus font weight value!");
 
-        // create the font entry
         nsAutoString uniqueName;
-
         nsresult rv = gfxFontUtils::MakeUniqueUserFontName(uniqueName);
         if (NS_FAILED(rv)) {
-            delete userFontData;
             return nsnull;
         }
 
-        MacOSFontEntry *newFontEntry =
-            new MacOSFontEntry(uniqueName,
-                               fontRef,
-                               w, aProxyEntry->mStretch,
-                               aProxyEntry->mItalic ?
-                                   FONT_STYLE_ITALIC : FONT_STYLE_NORMAL,
-                               userFontData);
+        // font entry will own this
+        ATSUserFontData *userFontData = new ATSUserFontData(containerRef);
 
-        if (!newFontEntry) {
-            delete userFontData;
-            return nsnull;
-        }
+        ATSFontEntry *newFontEntry =
+            new ATSFontEntry(uniqueName,
+                             fontRef,
+                             w, aProxyEntry->mStretch,
+                             aProxyEntry->mItalic ?
+                                 FONT_STYLE_ITALIC : FONT_STYLE_NORMAL,
+                             userFontData, PR_FALSE);
 
         // if succeeded and font cmap is good, return the new font
-        if (newFontEntry->mIsValid && NS_SUCCEEDED(newFontEntry->ReadCMAP()))
+        if (newFontEntry->mIsValid && NS_SUCCEEDED(newFontEntry->ReadCMAP())) {
             return newFontEntry;
+        }
 
         // if something is funky about this font, delete immediately
 #if DEBUG
         char warnBuf[1024];
         sprintf(warnBuf, "downloaded font not loaded properly, removed face for (%s)",
                 NS_ConvertUTF16toUTF8(aProxyEntry->mFamily->Name()).get());
         NS_WARNING(warnBuf);
 #endif
@@ -1034,9 +1162,8 @@ gfxMacPlatformFontList::MakePlatformFont
         // except by memory allocation failure.
         NS_WARNING("invalid font entry for a newly activated font");
         break;
     }
 
     // if we get here, the activation failed (even with possible retries); can't use this font
     return nsnull;
 }
-