Clean up SkFontHost_Mac ownership.

This clarifies ownership rules throughout SkFontHost_Mac.cpp, as well as
tidying up various bits of code. Clarifying ownership means replacing 
AutoCFRelease with UniqueCFRef which is based on std::unique_ptr. Most of
the cleanup is removing now dead code and properly indenting.

Change-Id: I6d3a225d62b5d0f2f48a9e70c1a24317faa06747
Reviewed-on: https://skia-review.googlesource.com/6297
Reviewed-by: Ben Wagner <bungeman@google.com>
Commit-Queue: Ben Wagner <bungeman@google.com>
diff --git a/src/ports/SkFontHost_mac.cpp b/src/ports/SkFontHost_mac.cpp
index 8168cd4..65200e4 100644
--- a/src/ports/SkFontHost_mac.cpp
+++ b/src/ports/SkFontHost_mac.cpp
@@ -60,80 +60,20 @@
 
 class SkScalerContext_Mac;
 
-// CTFontManagerCopyAvailableFontFamilyNames() is not always available, so we
-// provide a wrapper here that will return an empty array if need be.
-static CFArrayRef SkCTFontManagerCopyAvailableFontFamilyNames() {
-#ifdef SK_BUILD_FOR_IOS
-    return CFArrayCreate(nullptr, nullptr, 0, nullptr);
-#else
-    return CTFontManagerCopyAvailableFontFamilyNames();
-#endif
-}
-
-
-// Being templated and taking const T* prevents calling
-// CFSafeRelease(autoCFRelease) through implicit conversion.
-template <typename T> static void CFSafeRelease(/*CFTypeRef*/const T* cfTypeRef) {
-    if (cfTypeRef) {
-        CFRelease(cfTypeRef);
+struct CFSafeRelease {
+    void operator()(CFTypeRef cfTypeRef) {
+      if (cfTypeRef) {
+          CFRelease(cfTypeRef);
+      }
     }
-}
-
-// Being templated and taking const T* prevents calling
-// CFSafeRetain(autoCFRelease) through implicit conversion.
-template <typename T> static void CFSafeRetain(/*CFTypeRef*/const T* cfTypeRef) {
-    if (cfTypeRef) {
-        CFRetain(cfTypeRef);
-    }
-}
-
-/** Acts like a CFRef, but calls CFSafeRelease when it goes out of scope. */
-template<typename CFRef> class AutoCFRelease : private SkNoncopyable {
-public:
-    explicit AutoCFRelease(CFRef cfRef = nullptr) : fCFRef(cfRef) { }
-    ~AutoCFRelease() { CFSafeRelease(fCFRef); }
-
-    void reset(CFRef that = nullptr) {
-        if (that != fCFRef) {
-            CFSafeRelease(fCFRef);
-            fCFRef = that;
-        }
-    }
-
-    CFRef release() {
-        CFRef self = fCFRef;
-        fCFRef = nullptr;
-        return self;
-    }
-
-    operator CFRef() const { return fCFRef; }
-    CFRef get() const { return fCFRef; }
-
-    CFRef* operator&() { SkASSERT(fCFRef == nullptr); return &fCFRef; }
-private:
-    CFRef fCFRef;
 };
+template <typename CFRef> using UniqueCFRef =
+        std::unique_ptr<skstd::remove_pointer_t<CFRef>, CFSafeRelease>;
 
-static CFStringRef make_CFString(const char str[]) {
-    return CFStringCreateWithCString(nullptr, str, kCFStringEncodingUTF8);
+static UniqueCFRef<CFStringRef> make_CFString(const char str[]) {
+    return UniqueCFRef<CFStringRef>(CFStringCreateWithCString(nullptr, str, kCFStringEncodingUTF8));
 }
 
-template<typename T> class AutoCGTable : SkNoncopyable {
-public:
-    AutoCGTable(CGFontRef font)
-    //Undocumented: the tag parameter in this call is expected in machine order and not BE order.
-    : fCFData(CGFontCopyTableForTag(font, SkSetFourByteTag(T::TAG0, T::TAG1, T::TAG2, T::TAG3)))
-    , fData(fCFData ? reinterpret_cast<const T*>(CFDataGetBytePtr(fCFData)) : nullptr)
-    { }
-
-    const T* operator->() const { return fData; }
-
-private:
-    AutoCFRelease<CFDataRef> fCFData;
-public:
-    const T* fData;
-};
-
 // inline versions of these rect helpers
 
 static bool CGRectIsEmpty_inline(const CGRect& rect) {
@@ -212,12 +152,6 @@
     return pixel & 0xFF;
 }
 
-static const char FONT_DEFAULT_NAME[] = "Lucida Sans";
-
-static bool isLCDFormat(unsigned format) {
-    return SkMask::kLCD16_Format == format;
-}
-
 static CGFloat ScalarToCG(SkScalar scalar) {
     if (sizeof(CGFloat) == sizeof(float)) {
         return SkScalarToFloat(scalar);
@@ -245,15 +179,13 @@
     }
 }
 
-static CGAffineTransform MatrixToCGAffineTransform(const SkMatrix& matrix,
-                                                   SkScalar sx = SK_Scalar1,
-                                                   SkScalar sy = SK_Scalar1) {
-    return CGAffineTransformMake( ScalarToCG(matrix[SkMatrix::kMScaleX] * sx),
-                                 -ScalarToCG(matrix[SkMatrix::kMSkewY]  * sy),
-                                 -ScalarToCG(matrix[SkMatrix::kMSkewX]  * sx),
-                                  ScalarToCG(matrix[SkMatrix::kMScaleY] * sy),
-                                  ScalarToCG(matrix[SkMatrix::kMTransX] * sx),
-                                  ScalarToCG(matrix[SkMatrix::kMTransY] * sy));
+static CGAffineTransform MatrixToCGAffineTransform(const SkMatrix& matrix) {
+    return CGAffineTransformMake( ScalarToCG(matrix[SkMatrix::kMScaleX]),
+                                 -ScalarToCG(matrix[SkMatrix::kMSkewY] ),
+                                 -ScalarToCG(matrix[SkMatrix::kMSkewX] ),
+                                  ScalarToCG(matrix[SkMatrix::kMScaleY]),
+                                  ScalarToCG(matrix[SkMatrix::kMTransX]),
+                                  ScalarToCG(matrix[SkMatrix::kMTransY]));
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -271,19 +203,19 @@
         return (bool) gSupportsLCD;
     }
     uint32_t rgb = 0;
-    AutoCFRelease<CGColorSpaceRef> colorspace(CGColorSpaceCreateDeviceRGB());
-    AutoCFRelease<CGContextRef> cgContext(CGBitmapContextCreate(&rgb, 1, 1, 8, 4,
-                                                                colorspace, BITMAP_INFO_RGB));
-    AutoCFRelease<CTFontRef> ctFont(CTFontCreateWithName(CFSTR("Helvetica"), 16, nullptr));
-    CGContextSetShouldSmoothFonts(cgContext, true);
-    CGContextSetShouldAntialias(cgContext, true);
-    CGContextSetTextDrawingMode(cgContext, kCGTextFill);
-    CGContextSetGrayFillColor(cgContext, 1, 1);
+    UniqueCFRef<CGColorSpaceRef> colorspace(CGColorSpaceCreateDeviceRGB());
+    UniqueCFRef<CGContextRef> cgContext(
+            CGBitmapContextCreate(&rgb, 1, 1, 8, 4, colorspace.get(), BITMAP_INFO_RGB));
+    UniqueCFRef<CTFontRef> ctFont(CTFontCreateWithName(CFSTR("Helvetica"), 16, nullptr));
+    CGContextSetShouldSmoothFonts(cgContext.get(), true);
+    CGContextSetShouldAntialias(cgContext.get(), true);
+    CGContextSetTextDrawingMode(cgContext.get(), kCGTextFill);
+    CGContextSetGrayFillColor(cgContext.get(), 1, 1);
     CGPoint point = CGPointMake(-1, 0);
     static const UniChar pipeChar = '|';
     CGGlyph pipeGlyph;
-    CTFontGetGlyphsForCharacters(ctFont, &pipeChar, &pipeGlyph, 1);
-    CTFontDrawGlyphs(ctFont, &pipeGlyph, &point, 1, cgContext);
+    CTFontGetGlyphsForCharacters(ctFont.get(), &pipeChar, &pipeGlyph, 1);
+    CTFontDrawGlyphs(ctFont.get(), &pipeGlyph, &point, 1, cgContext.get());
 
     uint32_t r = (rgb >> 16) & 0xFF;
     uint32_t g = (rgb >>  8) & 0xFF;
@@ -304,18 +236,17 @@
     }
 
     CGRGBPixel* getCG(const SkScalerContext_Mac& context, const SkGlyph& glyph,
-                      CGGlyph glyphID, size_t* rowBytesPtr,
-                      bool generateA8FromLCD);
+                      CGGlyph glyphID, size_t* rowBytesPtr, bool generateA8FromLCD);
 
 private:
     enum {
         kSize = 32 * 32 * sizeof(CGRGBPixel)
     };
     SkAutoSMalloc<kSize> fImageStorage;
-    AutoCFRelease<CGColorSpaceRef> fRGBSpace;
+    UniqueCFRef<CGColorSpaceRef> fRGBSpace;
 
     // cached state
-    AutoCFRelease<CGContextRef> fCG;
+    UniqueCFRef<CGContextRef> fCG;
     SkISize fSize;
     bool fDoAA;
     bool fDoLCD;
@@ -330,8 +261,8 @@
 static bool find_dict_CGFloat(CFDictionaryRef dict, CFStringRef name, CGFloat* value) {
     CFNumberRef num;
     return CFDictionaryGetValueIfPresent(dict, name, (const void**)&num)
-    && CFNumberIsFloatType(num)
-    && CFNumberGetValue(num, kCFNumberCGFloatType, value);
+        && CFNumberIsFloatType(num)
+        && CFNumberGetValue(num, kCFNumberCGFloatType, value);
 }
 
 template <typename S, typename D, typename C> struct LinearInterpolater {
@@ -414,20 +345,20 @@
 }
 
 static SkFontStyle fontstyle_from_descriptor(CTFontDescriptorRef desc) {
-    AutoCFRelease<CFDictionaryRef> dict(
-            (CFDictionaryRef)CTFontDescriptorCopyAttribute(desc, kCTFontTraitsAttribute));
-    if (nullptr == dict.get()) {
+    UniqueCFRef<CFTypeRef> fontTraits(CTFontDescriptorCopyAttribute(desc, kCTFontTraitsAttribute));
+    if (!fontTraits || CFDictionaryGetTypeID() != CFGetTypeID(fontTraits.get())) {
         return SkFontStyle();
     }
+    UniqueCFRef<CFDictionaryRef> fontTraitsDict(static_cast<CFDictionaryRef>(fontTraits.release()));
 
     CGFloat weight, width, slant;
-    if (!find_dict_CGFloat(dict, kCTFontWeightTrait, &weight)) {
+    if (!find_dict_CGFloat(fontTraitsDict.get(), kCTFontWeightTrait, &weight)) {
         weight = 0;
     }
-    if (!find_dict_CGFloat(dict, kCTFontWidthTrait, &width)) {
+    if (!find_dict_CGFloat(fontTraitsDict.get(), kCTFontWidthTrait, &width)) {
         width = 0;
     }
-    if (!find_dict_CGFloat(dict, kCTFontSlantTrait, &slant)) {
+    if (!find_dict_CGFloat(fontTraitsDict.get(), kCTFontSlantTrait, &slant)) {
         slant = 0;
     }
 
@@ -439,20 +370,21 @@
 
 class SkTypeface_Mac : public SkTypeface {
 public:
-    SkTypeface_Mac(CTFontRef fontRef, CFTypeRef resourceRef,
+    SkTypeface_Mac(UniqueCFRef<CTFontRef> fontRef, UniqueCFRef<CFTypeRef> resourceRef,
                    const SkFontStyle& fs, bool isFixedPitch,
                    bool isLocalStream)
         : SkTypeface(fs, isFixedPitch)
-        , fFontRef(fontRef) // caller has already called CFRetain for us
-        , fOriginatingCFTypeRef(resourceRef) // caller has already called CFRetain for us
-        , fHasColorGlyphs(SkToBool(CTFontGetSymbolicTraits(fFontRef) & kCTFontColorGlyphsTrait))
+        , fFontRef(std::move(fontRef))
+        , fOriginatingCFTypeRef(std::move(resourceRef))
+        , fHasColorGlyphs(
+                SkToBool(CTFontGetSymbolicTraits(fFontRef.get()) & kCTFontColorGlyphsTrait))
         , fIsLocalStream(isLocalStream)
     {
-        SkASSERT(fontRef);
+        SkASSERT(fFontRef);
     }
 
-    AutoCFRelease<CTFontRef> fFontRef;
-    AutoCFRelease<CFTypeRef> fOriginatingCFTypeRef;
+    UniqueCFRef<CTFontRef> fFontRef;
+    UniqueCFRef<CFTypeRef> fOriginatingCFTypeRef;
     const bool fHasColorGlyphs;
 
 protected:
@@ -462,17 +394,15 @@
     void onGetFamilyName(SkString* familyName) const override;
     SkTypeface::LocalizedStrings* onCreateFamilyNameIterator() const override;
     int onGetTableTags(SkFontTableTag tags[]) const override;
-    virtual size_t onGetTableData(SkFontTableTag, size_t offset,
-                                  size_t length, void* data) const override;
+    size_t onGetTableData(SkFontTableTag, size_t offset, size_t length, void* data) const override;
     SkScalerContext* onCreateScalerContext(const SkScalerContextEffects&,
                                            const SkDescriptor*) const override;
     void onFilterRec(SkScalerContextRec*) const override;
     void onGetFontDescriptor(SkFontDescriptor*, bool*) const override;
-    virtual SkAdvancedTypefaceMetrics* onGetAdvancedTypefaceMetrics(
-                                PerGlyphInfo,
-                                const uint32_t*, uint32_t) const override;
-    virtual int onCharsToGlyphs(const void* chars, Encoding, uint16_t glyphs[],
-                                int glyphCount) const override;
+    SkAdvancedTypefaceMetrics* onGetAdvancedTypefaceMetrics(
+            PerGlyphInfo, const uint32_t* glyphIDs, uint32_t glyphIDsCount) const override;
+    int onCharsToGlyphs(const void* chars, Encoding,
+                        uint16_t glyphs[], int glyphCount) const override;
     int onCountGlyphs() const override;
 
 private:
@@ -483,18 +413,16 @@
 
 static bool find_by_CTFontRef(SkTypeface* cached, void* context) {
     CTFontRef self = (CTFontRef)context;
-    CTFontRef other = ((SkTypeface_Mac*)cached)->fFontRef;
+    CTFontRef other = ((SkTypeface_Mac*)cached)->fFontRef.get();
 
     return CFEqual(self, other);
 }
 
-/** Creates a typeface, searching the cache if isLocalStream is false.
- *  Takes ownership of the CTFontRef and CFTypeRef.
- */
-static SkTypeface* create_from_CTFontRef(CTFontRef f, CFTypeRef r, bool isLocalStream) {
-    SkASSERT(f);
-    AutoCFRelease<CTFontRef> font(f);
-    AutoCFRelease<CFTypeRef> resource(r);
+/** Creates a typeface, searching the cache if isLocalStream is false. */
+static SkTypeface* create_from_CTFontRef(UniqueCFRef<CTFontRef> font,
+                                         UniqueCFRef<CFTypeRef> resource,
+                                         bool isLocalStream) {
+    SkASSERT(font);
 
     if (!isLocalStream) {
         SkTypeface* face = SkTypefaceCache::FindByProcAndRef(find_by_CTFontRef, (void*)font.get());
@@ -503,12 +431,12 @@
         }
     }
 
-    AutoCFRelease<CTFontDescriptorRef> desc(CTFontCopyFontDescriptor(font));
-    SkFontStyle style = fontstyle_from_descriptor(desc);
-    CTFontSymbolicTraits traits = CTFontGetSymbolicTraits(font);
+    UniqueCFRef<CTFontDescriptorRef> desc(CTFontCopyFontDescriptor(font.get()));
+    SkFontStyle style = fontstyle_from_descriptor(desc.get());
+    CTFontSymbolicTraits traits = CTFontGetSymbolicTraits(font.get());
     bool isFixedPitch = SkToBool(traits & kCTFontMonoSpaceTrait);
 
-    SkTypeface* face = new SkTypeface_Mac(font.release(), resource.release(),
+    SkTypeface* face = new SkTypeface_Mac(std::move(font), std::move(resource),
                                           style, isFixedPitch, isLocalStream);
     if (!isLocalStream) {
         SkTypefaceCache::Add(face);
@@ -518,15 +446,16 @@
 
 /** Creates a typeface from a descriptor, searching the cache. */
 static SkTypeface* create_from_desc(CTFontDescriptorRef desc) {
-    AutoCFRelease<CTFontRef> ctFont(CTFontCreateWithFontDescriptor(desc, 0, nullptr));
+    UniqueCFRef<CTFontRef> ctFont(CTFontCreateWithFontDescriptor(desc, 0, nullptr));
     if (!ctFont) {
         return nullptr;
     }
 
-    return create_from_CTFontRef(ctFont.release(), nullptr, false);
+    return create_from_CTFontRef(std::move(ctFont), nullptr, false);
 }
 
-static CTFontDescriptorRef create_descriptor(const char familyName[], const SkFontStyle& style) {
+static UniqueCFRef<CTFontDescriptorRef> create_descriptor(const char familyName[],
+                                                          const SkFontStyle& style) {
     CTFontSymbolicTraits ctFontTraits = 0;
     if (style.weight() >= SkFontStyle::kBold_Weight) {
         ctFontTraits |= kCTFontBoldTrait;
@@ -538,17 +467,17 @@
     //TODO: add weight width slant
 
     // Create the font info
-    AutoCFRelease<CFStringRef> cfFontName(make_CFString(familyName));
+    UniqueCFRef<CFStringRef> cfFontName = make_CFString(familyName);
 
-    AutoCFRelease<CFNumberRef> cfFontTraits(
+    UniqueCFRef<CFNumberRef> cfFontTraits(
             CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &ctFontTraits));
 
-    AutoCFRelease<CFMutableDictionaryRef> cfAttributes(
+    UniqueCFRef<CFMutableDictionaryRef> cfAttributes(
             CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
                                       &kCFTypeDictionaryKeyCallBacks,
                                       &kCFTypeDictionaryValueCallBacks));
 
-    AutoCFRelease<CFMutableDictionaryRef> cfTraits(
+    UniqueCFRef<CFMutableDictionaryRef> cfTraits(
             CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
                                       &kCFTypeDictionaryKeyCallBacks,
                                       &kCFTypeDictionaryValueCallBacks));
@@ -557,33 +486,22 @@
         return nullptr;
     }
 
-    CFDictionaryAddValue(cfTraits, kCTFontSymbolicTrait, cfFontTraits);
+    CFDictionaryAddValue(cfTraits.get(), kCTFontSymbolicTrait, cfFontTraits.get());
 
-    CFDictionaryAddValue(cfAttributes, kCTFontFamilyNameAttribute, cfFontName);
-    CFDictionaryAddValue(cfAttributes, kCTFontTraitsAttribute, cfTraits);
+    CFDictionaryAddValue(cfAttributes.get(), kCTFontFamilyNameAttribute, cfFontName.get());
+    CFDictionaryAddValue(cfAttributes.get(), kCTFontTraitsAttribute, cfTraits.get());
 
-    return CTFontDescriptorCreateWithAttributes(cfAttributes);
+    return UniqueCFRef<CTFontDescriptorRef>(
+            CTFontDescriptorCreateWithAttributes(cfAttributes.get()));
 }
 
 /** Creates a typeface from a name, searching the cache. */
 static SkTypeface* create_from_name(const char familyName[], const SkFontStyle& style) {
-    AutoCFRelease<CTFontDescriptorRef> desc(create_descriptor(familyName, style));
+    UniqueCFRef<CTFontDescriptorRef> desc = create_descriptor(familyName, style);
     if (!desc) {
         return nullptr;
     }
-    return create_from_desc(desc);
-}
-
-SK_DECLARE_STATIC_MUTEX(gGetDefaultFaceMutex);
-static SkTypeface* GetDefaultFace() {
-    SkAutoMutexAcquire ma(gGetDefaultFaceMutex);
-
-    static SkTypeface* gDefaultFace;
-
-    if (nullptr == gDefaultFace) {
-        gDefaultFace = create_from_name(FONT_DEFAULT_NAME, SkFontStyle());
-    }
-    return gDefaultFace;
+    return create_from_desc(desc.get());
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -597,12 +515,14 @@
 /*  This function is visible on the outside. It first searches the cache, and if
  *  not found, returns a new entry (after adding it to the cache).
  */
-SkTypeface* SkCreateTypefaceFromCTFont(CTFontRef fontRef, CFTypeRef resourceRef) {
-    CFRetain(fontRef);
-    if (resourceRef) {
-        CFRetain(resourceRef);
+SkTypeface* SkCreateTypefaceFromCTFont(CTFontRef font, CFTypeRef resource) {
+    CFRetain(font);
+    if (resource) {
+        CFRetain(resource);
     }
-    return create_from_CTFontRef(fontRef, resourceRef, false);
+    return create_from_CTFontRef(UniqueCFRef<CTFontRef>(font),
+                                 UniqueCFRef<CFTypeRef>(resource),
+                                 false);
 }
 
 static const char* map_css_names(const char* name) {
@@ -672,13 +592,13 @@
      *  As a result of the above (and other constraints) this font contains the size, but not the
      *  transform. The transform must always be applied separately.
      */
-    AutoCFRelease<CTFontRef> fCTFont;
+    UniqueCFRef<CTFontRef> fCTFont;
 
     /** The transform without the font size. */
     CGAffineTransform fTransform;
     CGAffineTransform fInvTransform;
 
-    AutoCFRelease<CGFontRef> fCGFont;
+    UniqueCFRef<CGFontRef> fCGFont;
     uint16_t fGlyphCount;
     const bool fDoSubPosition;
     const bool fVertical;
@@ -693,10 +613,10 @@
 // It is not possible to use descriptors with CTFontCreateWithFontDescriptor, since that does not
 // work with non-system fonts. As a result, create the strike specific CTFonts from the underlying
 // CGFont.
-static CTFontRef ctfont_create_exact_copy(CTFontRef baseFont, CGFloat textSize,
-                                          const CGAffineTransform* transform)
+static UniqueCFRef<CTFontRef> ctfont_create_exact_copy(CTFontRef baseFont, CGFloat textSize,
+                                                       const CGAffineTransform* transform)
 {
-    AutoCFRelease<CGFontRef> baseCGFont(CTFontCopyGraphicsFont(baseFont, nullptr));
+    UniqueCFRef<CGFontRef> baseCGFont(CTFontCopyGraphicsFont(baseFont, nullptr));
 
     // The last parameter (CTFontDescriptorRef attributes) *must* be nullptr.
     // If non-nullptr then with fonts with variation axes, the copy will fail in
@@ -706,7 +626,8 @@
     // Because we cannot setup the CTFont descriptor to match, the same restriction applies here
     // as other uses of CTFontCreateWithGraphicsFont which is that such CTFonts should not escape
     // the scaler context, since they aren't 'normal'.
-    return CTFontCreateWithGraphicsFont(baseCGFont, textSize, transform, nullptr);
+    return UniqueCFRef<CTFontRef>(
+            CTFontCreateWithGraphicsFont(baseCGFont.get(), textSize, transform, nullptr));
 }
 
 SkScalerContext_Mac::SkScalerContext_Mac(sk_sp<SkTypeface_Mac> typeface,
@@ -742,11 +663,11 @@
     // The transform contains everything except the requested text size.
     // Some properties, like 'trak', are based on the text size (before applying the matrix).
     CGFloat textSize = ScalarToCG(scale.y());
-    fCTFont.reset(ctfont_create_exact_copy(ctFont, textSize, nullptr));
-    fCGFont.reset(CTFontCopyGraphicsFont(fCTFont, nullptr));
+    fCTFont = ctfont_create_exact_copy(ctFont, textSize, nullptr);
+    fCGFont.reset(CTFontCopyGraphicsFont(fCTFont.get(), nullptr));
 
     // The fUnitMatrix includes the text size (and em) as it is used to scale the raw font data.
-    SkScalar emPerFUnit = SkScalarInvert(SkIntToScalar(CGFontGetUnitsPerEm(fCGFont)));
+    SkScalar emPerFUnit = SkScalarInvert(SkIntToScalar(CGFontGetUnitsPerEm(fCGFont.get())));
     fFUnitMatrix.preScale(emPerFUnit, -emPerFUnit);
 }
 
@@ -798,37 +719,37 @@
                                      : kCGImageAlphaNoneSkipFirst;
         const CGBitmapInfo bitmapInfo = kCGBitmapByteOrder32Host | alpha;
         fCG.reset(CGBitmapContextCreate(image, fSize.fWidth, fSize.fHeight, 8,
-                                        rowBytes, fRGBSpace, bitmapInfo));
+                                        rowBytes, fRGBSpace.get(), bitmapInfo));
 
         // Skia handles quantization and subpixel positioning,
         // so disable quantization and enabe subpixel positioning in CG.
-        CGContextSetAllowsFontSubpixelQuantization(fCG, false);
-        CGContextSetShouldSubpixelQuantizeFonts(fCG, false);
+        CGContextSetAllowsFontSubpixelQuantization(fCG.get(), false);
+        CGContextSetShouldSubpixelQuantizeFonts(fCG.get(), false);
 
         // Because CG always draws from the horizontal baseline,
         // if there is a non-integral translation from the horizontal origin to the vertical origin,
         // then CG cannot draw the glyph in the correct location without subpixel positioning.
-        CGContextSetAllowsFontSubpixelPositioning(fCG, true);
-        CGContextSetShouldSubpixelPositionFonts(fCG, true);
+        CGContextSetAllowsFontSubpixelPositioning(fCG.get(), true);
+        CGContextSetShouldSubpixelPositionFonts(fCG.get(), true);
 
-        CGContextSetTextDrawingMode(fCG, kCGTextFill);
+        CGContextSetTextDrawingMode(fCG.get(), kCGTextFill);
 
         // Draw black on white to create mask. (Special path exists to speed this up in CG.)
-        CGContextSetGrayFillColor(fCG, 0.0f, 1.0f);
+        CGContextSetGrayFillColor(fCG.get(), 0.0f, 1.0f);
 
         // force our checks below to happen
         fDoAA = !doAA;
         fDoLCD = !doLCD;
 
-        CGContextSetTextMatrix(fCG, context.fTransform);
+        CGContextSetTextMatrix(fCG.get(), context.fTransform);
     }
 
     if (fDoAA != doAA) {
-        CGContextSetShouldAntialias(fCG, doAA);
+        CGContextSetShouldAntialias(fCG.get(), doAA);
         fDoAA = doAA;
     }
     if (fDoLCD != doLCD) {
-        CGContextSetShouldSmoothFonts(fCG, doLCD);
+        CGContextSetShouldSmoothFonts(fCG.get(), doLCD);
         fDoLCD = doLCD;
     }
 
@@ -865,7 +786,7 @@
     // So always make the font transform identity and place the transform on the context.
     point = CGPointApplyAffineTransform(point, context.fInvTransform);
 
-    CTFontDrawGlyphs(context.fCTFont, &glyphID, &point, 1, fCG);
+    CTFontDrawGlyphs(context.fCTFont.get(), &glyphID, &point, 1, fCG.get());
 
     SkASSERT(rowBytesPtr);
     *rowBytesPtr = rowBytes;
@@ -875,7 +796,7 @@
 void SkScalerContext_Mac::getVerticalOffset(CGGlyph glyphID, SkPoint* offset) const {
     // CTFontGetVerticalTranslationsForGlyphs produces cgVertOffset in CG units (pixels, y up).
     CGSize cgVertOffset;
-    CTFontGetVerticalTranslationsForGlyphs(fCTFont, &glyphID, &cgVertOffset, 1);
+    CTFontGetVerticalTranslationsForGlyphs(fCTFont.get(), &glyphID, &cgVertOffset, 1);
     cgVertOffset = CGSizeApplyAffineTransform(cgVertOffset, fTransform);
     SkPoint skVertOffset = { CGToScalar(cgVertOffset.width), CGToScalar(cgVertOffset.height) };
     // From CG units (pixels, y up) to SkGlyph units (pixels, y down).
@@ -900,7 +821,7 @@
     // Undocumented behavior of CTFontGetGlyphsForCharacters with non-bmp code points:
     // When a surrogate pair is detected, the glyph index used is the index of the high surrogate.
     // It is documented that if a mapping is unavailable, the glyph will be set to 0.
-    CTFontGetGlyphsForCharacters(fCTFont, theChar, cgGlyph, numUniChar);
+    CTFontGetGlyphsForCharacters(fCTFont.get(), theChar, cgGlyph, numUniChar);
     return cgGlyph[0];
 }
 
@@ -917,13 +838,13 @@
     // The following block produces cgAdvance in CG units (pixels, y up).
     CGSize cgAdvance;
     if (fVertical) {
-        CTFontGetAdvancesForGlyphs(fCTFont, kCTFontVerticalOrientation,
+        CTFontGetAdvancesForGlyphs(fCTFont.get(), kCTFontVerticalOrientation,
                                    &cgGlyph, &cgAdvance, 1);
         // Vertical advances are returned as widths instead of heights.
         SkTSwap(cgAdvance.height, cgAdvance.width);
         cgAdvance.height = -cgAdvance.height;
     } else {
-        CTFontGetAdvancesForGlyphs(fCTFont, kCTFontHorizontalOrientation,
+        CTFontGetAdvancesForGlyphs(fCTFont.get(), kCTFontHorizontalOrientation,
                                    &cgGlyph, &cgAdvance, 1);
     }
     cgAdvance = CGSizeApplyAffineTransform(cgAdvance, fTransform);
@@ -942,7 +863,7 @@
     {
         // CTFontGetBoundingRectsForGlyphs produces cgBounds in CG units (pixels, y up).
         CGRect cgBounds;
-        CTFontGetBoundingRectsForGlyphs(fCTFont, kCTFontHorizontalOrientation,
+        CTFontGetBoundingRectsForGlyphs(fCTFont.get(), kCTFontHorizontalOrientation,
                                         &cgGlyph, &cgBounds, 1);
         cgBounds = CGRectApplyAffineTransform(cgBounds, fTransform);
 
@@ -952,8 +873,8 @@
         // empty path or not, and if so, we jam the bounds to 0. Hopefully a zero-advance
         // is rare, so we won't incur a big performance cost for this extra check.
         if (0 == cgAdvance.width && 0 == cgAdvance.height) {
-            AutoCFRelease<CGPathRef> path(CTFontCreatePathForGlyph(fCTFont, cgGlyph, nullptr));
-            if (nullptr == path || CGPathIsEmpty(path)) {
+            UniqueCFRef<CGPathRef> path(CTFontCreatePathForGlyph(fCTFont.get(), cgGlyph, nullptr));
+            if (!path || CGPathIsEmpty(path.get())) {
                 return;
             }
         }
@@ -1057,8 +978,8 @@
         for (int i = 0; i < width; ++i) {
             dst[i] = rgb_to_a8<APPLY_PREBLEND>(cgPixels[i], table8);
         }
-        cgPixels = (CGRGBPixel*)((char*)cgPixels + cgRowBytes);
-        dst += dstRB;
+        cgPixels = SkTAddOffset<const CGRGBPixel>(cgPixels, cgRowBytes);
+        dst = SkTAddOffset<uint8_t>(dst, dstRB);
     }
 }
 
@@ -1087,8 +1008,8 @@
         for (int i = 0; i < width; i++) {
             dst[i] = rgb_to_lcd16<APPLY_PREBLEND>(cgPixels[i], tableR, tableG, tableB);
         }
-        cgPixels = (CGRGBPixel*)((char*)cgPixels + cgRowBytes);
-        dst = (uint16_t*)((char*)dst + dstRB);
+        cgPixels = SkTAddOffset<const CGRGBPixel>(cgPixels, cgRowBytes);
+        dst = SkTAddOffset<uint16_t>(dst, dstRB);
     }
 }
 
@@ -1104,7 +1025,7 @@
 }
 
 void SkScalerContext_Mac::generateImage(const SkGlyph& glyph) {
-    CGGlyph cgGlyph = (CGGlyph) glyph.getGlyphID();
+    CGGlyph cgGlyph = SkTo<CGGlyph>(glyph.getGlyphID());
 
     // FIXME: lcd smoothed un-hinted rasterization unsupported.
     bool generateA8FromLCD = fRec.getHinting() != SkPaint::kNo_Hinting;
@@ -1117,8 +1038,9 @@
     }
 
     // Fix the glyph
-    const bool isLCD = isLCDFormat(glyph.fMaskFormat);
-    if (isLCD || (glyph.fMaskFormat == SkMask::kA8_Format && supports_LCD() && generateA8FromLCD)) {
+    if ((glyph.fMaskFormat == SkMask::kLCD16_Format) ||
+        (glyph.fMaskFormat == SkMask::kA8_Format && supports_LCD() && generateA8FromLCD))
+    {
         const uint8_t* table = getInverseGammaTableCoreGraphicSmoothing();
 
         //Note that the following cannot really be integrated into the
@@ -1162,8 +1084,8 @@
             uint8_t* dst = (uint8_t*)glyph.fImage;
             for (int y = 0; y < glyph.fHeight; y++) {
                 cgpixels_to_bits(dst, cgPixels, width);
-                cgPixels = (CGRGBPixel*)((char*)cgPixels + cgRowBytes);
-                dst += dstRB;
+                cgPixels = SkTAddOffset<CGRGBPixel>(cgPixels, cgRowBytes);
+                dst = SkTAddOffset<uint8_t>(dst, dstRB);
             }
         } break;
         case SkMask::kARGB32_Format: {
@@ -1174,8 +1096,8 @@
                 for (int x = 0; x < width; ++x) {
                     dst[x] = cgpixels_to_pmcolor(cgPixels[x]);
                 }
-                cgPixels = (CGRGBPixel*)((char*)cgPixels + cgRowBytes);
-                dst = (SkPMColor*)((char*)dst + dstRB);
+                cgPixels = SkTAddOffset<CGRGBPixel>(cgPixels, cgRowBytes);
+                dst = SkTAddOffset<SkPMColor>(dst, dstRB);
             }
         } break;
         default:
@@ -1227,11 +1149,11 @@
     }
 
     CGGlyph cgGlyph = SkTo<CGGlyph>(glyph);
-    AutoCFRelease<CGPathRef> cgPath(CTFontCreatePathForGlyph(fCTFont, cgGlyph, &xform));
+    UniqueCFRef<CGPathRef> cgPath(CTFontCreatePathForGlyph(fCTFont.get(), cgGlyph, &xform));
 
     path->reset();
     if (cgPath != nullptr) {
-        CGPathApply(cgPath, path, SkScalerContext_Mac::CTPathElement);
+        CGPathApply(cgPath.get(), path, SkScalerContext_Mac::CTPathElement);
     }
 
     if (fDoSubPosition) {
@@ -1253,21 +1175,21 @@
 
     AUTO_CG_LOCK();
 
-    CGRect theBounds = CTFontGetBoundingBox(fCTFont);
+    CGRect theBounds = CTFontGetBoundingBox(fCTFont.get());
 
     metrics->fTop          = CGToScalar(-CGRectGetMaxY_inline(theBounds));
-    metrics->fAscent       = CGToScalar(-CTFontGetAscent(fCTFont));
-    metrics->fDescent      = CGToScalar( CTFontGetDescent(fCTFont));
+    metrics->fAscent       = CGToScalar(-CTFontGetAscent(fCTFont.get()));
+    metrics->fDescent      = CGToScalar( CTFontGetDescent(fCTFont.get()));
     metrics->fBottom       = CGToScalar(-CGRectGetMinY_inline(theBounds));
-    metrics->fLeading      = CGToScalar( CTFontGetLeading(fCTFont));
+    metrics->fLeading      = CGToScalar( CTFontGetLeading(fCTFont.get()));
     metrics->fAvgCharWidth = CGToScalar( CGRectGetWidth_inline(theBounds));
     metrics->fXMin         = CGToScalar( CGRectGetMinX_inline(theBounds));
     metrics->fXMax         = CGToScalar( CGRectGetMaxX_inline(theBounds));
     metrics->fMaxCharWidth = metrics->fXMax - metrics->fXMin;
-    metrics->fXHeight      = CGToScalar( CTFontGetXHeight(fCTFont));
-    metrics->fCapHeight    = CGToScalar( CTFontGetCapHeight(fCTFont));
-    metrics->fUnderlineThickness = CGToScalar( CTFontGetUnderlineThickness(fCTFont));
-    metrics->fUnderlinePosition = -CGToScalar( CTFontGetUnderlinePosition(fCTFont));
+    metrics->fXHeight      = CGToScalar( CTFontGetXHeight(fCTFont.get()));
+    metrics->fCapHeight    = CGToScalar( CTFontGetCapHeight(fCTFont.get()));
+    metrics->fUnderlineThickness = CGToScalar( CTFontGetUnderlineThickness(fCTFont.get()));
+    metrics->fUnderlinePosition = -CGToScalar( CTFontGetUnderlinePosition(fCTFont.get()));
 
     metrics->fFlags |= SkPaint::FontMetrics::kUnderlineThinknessIsValid_Flag;
     metrics->fFlags |= SkPaint::FontMetrics::kUnderlinePositionIsValid_Flag;
@@ -1312,16 +1234,19 @@
 
 // Returns nullptr on failure
 // Call must still manage its ownership of provider
-static SkTypeface* create_from_dataProvider(CGDataProviderRef provider) {
-    AutoCFRelease<CGFontRef> cg(CGFontCreateWithDataProvider(provider));
-    if (nullptr == cg) {
+static SkTypeface* create_from_dataProvider(UniqueCFRef<CGDataProviderRef> provider) {
+    UniqueCFRef<CGFontRef> cg(CGFontCreateWithDataProvider(provider.get()));
+    if (!cg) {
         return nullptr;
     }
-    CTFontRef ct = CTFontCreateWithGraphicsFont(cg, 0, nullptr, nullptr);
-    return ct ? create_from_CTFontRef(ct, nullptr, true) : nullptr;
+    UniqueCFRef<CTFontRef> ct(CTFontCreateWithGraphicsFont(cg.get(), 0, nullptr, nullptr));
+    if (!ct) {
+        return nullptr;
+    }
+    return create_from_CTFontRef(std::move(ct), nullptr, true);
 }
 
-// Web fonts added to the the CTFont registry do not return their character set.
+// Web fonts added to the CTFont registry do not return their character set.
 // Iterate through the font in this case. The existing caller caches the result,
 // so the performance impact isn't too bad.
 static void populate_glyph_to_unicode_slow(CTFontRef ctFont, CFIndex glyphCount,
@@ -1347,18 +1272,17 @@
 // supported.
 static void populate_glyph_to_unicode(CTFontRef ctFont, CFIndex glyphCount,
                                       SkTDArray<SkUnichar>* glyphToUnicode) {
-    AutoCFRelease<CFCharacterSetRef> charSet(CTFontCopyCharacterSet(ctFont));
+    UniqueCFRef<CFCharacterSetRef> charSet(CTFontCopyCharacterSet(ctFont));
     if (!charSet) {
         populate_glyph_to_unicode_slow(ctFont, glyphCount, glyphToUnicode);
         return;
     }
 
-    AutoCFRelease<CFDataRef> bitmap(CFCharacterSetCreateBitmapRepresentation(kCFAllocatorDefault,
-                                                                             charSet));
+    UniqueCFRef<CFDataRef> bitmap(CFCharacterSetCreateBitmapRepresentation(nullptr, charSet.get()));
     if (!bitmap) {
         return;
     }
-    CFIndex length = CFDataGetLength(bitmap);
+    CFIndex length = CFDataGetLength(bitmap.get());
     if (!length) {
         return;
     }
@@ -1369,7 +1293,7 @@
         // See http://developer.apple.com/library/ios/#documentation/CoreFoundation/Reference/CFCharacterSetRef/Reference/reference.html
         length = 8192;
     }
-    const UInt8* bits = CFDataGetBytePtr(bitmap);
+    const UInt8* bits = CFDataGetBytePtr(bitmap.get());
     glyphToUnicode->setCount(SkToInt(glyphCount));
     SkUnichar* out = glyphToUnicode->begin();
     sk_bzero(out, glyphCount * sizeof(SkUnichar));
@@ -1407,25 +1331,24 @@
 
     AUTO_CG_LOCK();
 
-    CTFontRef originalCTFont = fFontRef.get();
-    AutoCFRelease<CTFontRef> ctFont(ctfont_create_exact_copy(
-            originalCTFont, CTFontGetUnitsPerEm(originalCTFont), nullptr));
+    UniqueCFRef<CTFontRef> ctFont =
+            ctfont_create_exact_copy(fFontRef.get(), CTFontGetUnitsPerEm(fFontRef.get()), nullptr);
 
     SkAdvancedTypefaceMetrics* info = new SkAdvancedTypefaceMetrics;
 
     {
-        AutoCFRelease<CFStringRef> fontName(CTFontCopyPostScriptName(ctFont));
+        UniqueCFRef<CFStringRef> fontName(CTFontCopyPostScriptName(ctFont.get()));
         if (fontName.get()) {
-            CFStringToSkString(fontName, &info->fFontName);
+            CFStringToSkString(fontName.get(), &info->fFontName);
         }
     }
 
-    CFIndex glyphCount = CTFontGetGlyphCount(ctFont);
+    CFIndex glyphCount = CTFontGetGlyphCount(ctFont.get());
     info->fLastGlyphID = SkToU16(glyphCount - 1);
-    info->fEmSize = CTFontGetUnitsPerEm(ctFont);
+    info->fEmSize = CTFontGetUnitsPerEm(ctFont.get());
 
     if (perGlyphInfo & kToUnicode_PerGlyphInfo) {
-        populate_glyph_to_unicode(ctFont, glyphCount, &info->fGlyphToUnicode);
+        populate_glyph_to_unicode(ctFont.get(), glyphCount, &info->fGlyphToUnicode);
     }
 
     // If it's not a truetype font, mark it as 'other'. Assume that TrueType
@@ -1437,7 +1360,7 @@
     }
 
     info->fType = SkAdvancedTypefaceMetrics::kTrueType_Font;
-    CTFontSymbolicTraits symbolicTraits = CTFontGetSymbolicTraits(ctFont);
+    CTFontSymbolicTraits symbolicTraits = CTFontGetSymbolicTraits(ctFont.get());
     if (symbolicTraits & kCTFontMonoSpaceTrait) {
         info->fStyle |= SkAdvancedTypefaceMetrics::kFixedPitch_Style;
     }
@@ -1450,11 +1373,11 @@
     } else if (stylisticClass & kCTFontScriptsClass) {
         info->fStyle |= SkAdvancedTypefaceMetrics::kScript_Style;
     }
-    info->fItalicAngle = (int16_t) CTFontGetSlantAngle(ctFont);
-    info->fAscent = (int16_t) CTFontGetAscent(ctFont);
-    info->fDescent = (int16_t) CTFontGetDescent(ctFont);
-    info->fCapHeight = (int16_t) CTFontGetCapHeight(ctFont);
-    CGRect bbox = CTFontGetBoundingBox(ctFont);
+    info->fItalicAngle = (int16_t) CTFontGetSlantAngle(ctFont.get());
+    info->fAscent = (int16_t) CTFontGetAscent(ctFont.get());
+    info->fDescent = (int16_t) CTFontGetDescent(ctFont.get());
+    info->fCapHeight = (int16_t) CTFontGetCapHeight(ctFont.get());
+    CGRect bbox = CTFontGetBoundingBox(ctFont.get());
 
     SkRect r;
     r.set( CGToScalar(CGRectGetMinX_inline(bbox)),   // Left
@@ -1472,8 +1395,8 @@
     const size_t count = sizeof(stem_chars) / sizeof(stem_chars[0]);
     CGGlyph glyphs[count];
     CGRect boundingRects[count];
-    if (CTFontGetGlyphsForCharacters(ctFont, stem_chars, glyphs, count)) {
-        CTFontGetBoundingRectsForGlyphs(ctFont, kCTFontHorizontalOrientation,
+    if (CTFontGetGlyphsForCharacters(ctFont.get(), stem_chars, glyphs, count)) {
+        CTFontGetBoundingRectsForGlyphs(ctFont.get(), kCTFontHorizontalOrientation,
                                         glyphs, boundingRects, count);
         for (size_t i = 0; i < count; i++) {
             int16_t width = (int16_t) boundingRects[i].size.width;
@@ -1490,14 +1413,14 @@
 
 static SK_SFNT_ULONG get_font_type_tag(const SkTypeface_Mac* typeface) {
     CTFontRef ctFont = typeface->fFontRef.get();
-    AutoCFRelease<CFNumberRef> fontFormatRef(
+    UniqueCFRef<CFNumberRef> fontFormatRef(
             static_cast<CFNumberRef>(CTFontCopyAttribute(ctFont, kCTFontFormatAttribute)));
     if (!fontFormatRef) {
         return 0;
     }
 
     SInt32 fontFormatValue;
-    if (!CFNumberGetValue(fontFormatRef, kCFNumberSInt32Type, &fontFormatValue)) {
+    if (!CFNumberGetValue(fontFormatRef.get(), kCFNumberSInt32Type, &fontFormatValue)) {
         return 0;
     }
 
@@ -1638,22 +1561,28 @@
     // CTFontCopyVariationAxes and CTFontCopyVariation do not work when applied to fonts which
     // started life with CGFontCreateWithDataProvider (they simply always return nullptr).
     // As a result, we are limited to CGFontCopyVariationAxes and CGFontCopyVariations.
-    AutoCFRelease<CGFontRef> cgFont(CTFontCopyGraphicsFont(fFontRef, nullptr));
-
-    AutoCFRelease<CFDictionaryRef> cgVariations(CGFontCopyVariations(cgFont));
-    // If a font has no variations CGFontCopyVariations returns nullptr (instead of an empty dict).
-    if (!cgVariations.get()) {
+    UniqueCFRef<CGFontRef> cgFont(CTFontCopyGraphicsFont(fFontRef, nullptr));
+    if (!cgFont) {
         return false;
     }
 
-    AutoCFRelease<CFArrayRef> cgAxes(CGFontCopyVariationAxes(cgFont));
-    *cgAxisCount = CFArrayGetCount(cgAxes);
+    UniqueCFRef<CFDictionaryRef> cgVariations(CGFontCopyVariations(cgFont.get()));
+    // If a font has no variations CGFontCopyVariations returns nullptr (instead of an empty dict).
+    if (!cgVariations) {
+        return false;
+    }
+
+    UniqueCFRef<CFArrayRef> cgAxes(CGFontCopyVariationAxes(cgFont.get()));
+    if (!cgAxes) {
+        return false;
+    }
+    *cgAxisCount = CFArrayGetCount(cgAxes.get());
     axisValues->reset(*cgAxisCount);
 
     // Set all of the axes to their default values.
     // Fail if any default value cannot be determined.
     for (CFIndex i = 0; i < *cgAxisCount; ++i) {
-        CFTypeRef cgAxis = CFArrayGetValueAtIndex(cgAxes, i);
+        CFTypeRef cgAxis = CFArrayGetValueAtIndex(cgAxes.get(), i);
         if (CFGetTypeID(cgAxis) != CFDictionaryGetTypeID()) {
             return false;
         }
@@ -1680,7 +1609,7 @@
 
     // Override the default values with the given font's stated axis values.
     NonDefaultAxesContext c = { axisValues->get(), cgAxes.get() };
-    CFDictionaryApplyFunction(cgVariations, set_non_default_axes, &c);
+    CFDictionaryApplyFunction(cgVariations.get(), set_non_default_axes, &c);
 
     return true;
 }
@@ -1690,7 +1619,7 @@
 
     CFIndex cgAxisCount;
     SkAutoSTMalloc<4, SkFixed> axisValues;
-    if (get_variations(fFontRef, &cgAxisCount, &axisValues)) {
+    if (get_variations(fFontRef.get(), &cgAxisCount, &axisValues)) {
         return skstd::make_unique<SkFontData>(std::move(stream), index,
                                               axisValues.get(), cgAxisCount);
     }
@@ -1701,26 +1630,27 @@
 ///////////////////////////////////////////////////////////////////////////////
 
 int SkTypeface_Mac::onGetUPEM() const {
-    AutoCFRelease<CGFontRef> cgFont(CTFontCopyGraphicsFont(fFontRef, nullptr));
-    return CGFontGetUnitsPerEm(cgFont);
+    UniqueCFRef<CGFontRef> cgFont(CTFontCopyGraphicsFont(fFontRef.get(), nullptr));
+    return CGFontGetUnitsPerEm(cgFont.get());
 }
 
 SkTypeface::LocalizedStrings* SkTypeface_Mac::onCreateFamilyNameIterator() const {
     SkTypeface::LocalizedStrings* nameIter =
-        SkOTUtils::LocalizedStrings_NameTable::CreateForFamilyNames(*this);
+            SkOTUtils::LocalizedStrings_NameTable::CreateForFamilyNames(*this);
     if (nullptr == nameIter) {
-        AutoCFRelease<CFStringRef> cfLanguage;
-        AutoCFRelease<CFStringRef> cfFamilyName(
-            CTFontCopyLocalizedName(fFontRef, kCTFontFamilyNameKey, &cfLanguage));
+        CFStringRef cfLanguageRaw;
+        UniqueCFRef<CFStringRef> cfFamilyName(
+                CTFontCopyLocalizedName(fFontRef.get(), kCTFontFamilyNameKey, &cfLanguageRaw));
+        UniqueCFRef<CFStringRef> cfLanguage(cfLanguageRaw);
 
         SkString skLanguage;
         SkString skFamilyName;
-        if (cfLanguage.get()) {
+        if (cfLanguage) {
             CFStringToSkString(cfLanguage.get(), &skLanguage);
         } else {
             skLanguage = "und"; //undetermined
         }
-        if (cfFamilyName.get()) {
+        if (cfFamilyName) {
             CFStringToSkString(cfFamilyName.get(), &skFamilyName);
         }
 
@@ -1729,43 +1659,44 @@
     return nameIter;
 }
 
-// If, as is the case with web fonts, the CTFont data isn't available,
-// the CGFont data may work. While the CGFont may always provide the
-// right result, leave the CTFont code path to minimize disruption.
-static CFDataRef copyTableFromFont(CTFontRef ctFont, SkFontTableTag tag) {
-    CFDataRef data = CTFontCopyTable(ctFont, (CTFontTableTag) tag,
-                                     kCTFontTableOptionNoOptions);
-    if (nullptr == data) {
-        AutoCFRelease<CGFontRef> cgFont(CTFontCopyGraphicsFont(ctFont, nullptr));
-        data = CGFontCopyTableForTag(cgFont, tag);
-    }
-    return data;
-}
-
 int SkTypeface_Mac::onGetTableTags(SkFontTableTag tags[]) const {
-    AutoCFRelease<CFArrayRef> cfArray(CTFontCopyAvailableTables(fFontRef,
-                                                kCTFontTableOptionNoOptions));
-    if (nullptr == cfArray) {
+    UniqueCFRef<CFArrayRef> cfArray(
+            CTFontCopyAvailableTables(fFontRef.get(), kCTFontTableOptionNoOptions));
+    if (!cfArray) {
         return 0;
     }
-    int count = SkToInt(CFArrayGetCount(cfArray));
+    int count = SkToInt(CFArrayGetCount(cfArray.get()));
     if (tags) {
         for (int i = 0; i < count; ++i) {
-            uintptr_t fontTag = reinterpret_cast<uintptr_t>(CFArrayGetValueAtIndex(cfArray, i));
+            uintptr_t fontTag = reinterpret_cast<uintptr_t>(
+                CFArrayGetValueAtIndex(cfArray.get(), i));
             tags[i] = static_cast<SkFontTableTag>(fontTag);
         }
     }
     return count;
 }
 
+// If, as is the case with web fonts, the CTFont data isn't available,
+// the CGFont data may work. While the CGFont may always provide the
+// right result, leave the CTFont code path to minimize disruption.
+static UniqueCFRef<CFDataRef> copy_table_from_font(CTFontRef ctFont, SkFontTableTag tag) {
+    UniqueCFRef<CFDataRef> data(CTFontCopyTable(ctFont, (CTFontTableTag) tag,
+                                                kCTFontTableOptionNoOptions));
+    if (!data) {
+        UniqueCFRef<CGFontRef> cgFont(CTFontCopyGraphicsFont(ctFont, nullptr));
+        data.reset(CGFontCopyTableForTag(cgFont.get(), tag));
+    }
+    return data;
+}
+
 size_t SkTypeface_Mac::onGetTableData(SkFontTableTag tag, size_t offset,
                                       size_t length, void* dstData) const {
-    AutoCFRelease<CFDataRef> srcData(copyTableFromFont(fFontRef, tag));
-    if (nullptr == srcData) {
+    UniqueCFRef<CFDataRef> srcData = copy_table_from_font(fFontRef.get(), tag);
+    if (!srcData) {
         return 0;
     }
 
-    size_t srcSize = CFDataGetLength(srcData);
+    size_t srcSize = CFDataGetLength(srcData.get());
     if (offset >= srcSize) {
         return 0;
     }
@@ -1773,7 +1704,7 @@
         length = srcSize - offset;
     }
     if (dstData) {
-        memcpy(dstData, CFDataGetBytePtr(srcData) + offset, length);
+        memcpy(dstData, CFDataGetBytePtr(srcData.get()) + offset, length);
     }
     return length;
 }
@@ -1835,7 +1766,7 @@
     // Currenly side with LCD, effectively ignoring the hinting setting.
     // [LCD][yes-hint]: generate LCD using CoreGraphic's LCD output.
 
-    if (isLCDFormat(rec->fMaskFormat)) {
+    if (rec->fMaskFormat == SkMask::kLCD16_Format) {
         if (lcdSupport) {
             //CoreGraphics creates 555 masks for smoothed text anyway.
             rec->fMaskFormat = SkMask::kLCD16_Format;
@@ -1865,27 +1796,27 @@
     }
 }
 
-// we take ownership of the ref
+/** Takes ownership of the CFStringRef. */
 static const char* get_str(CFStringRef ref, SkString* str) {
     if (nullptr == ref) {
         return nullptr;
     }
     CFStringToSkString(ref, str);
-    CFSafeRelease(ref);
+    CFRelease(ref);
     return str->c_str();
 }
 
 void SkTypeface_Mac::onGetFamilyName(SkString* familyName) const {
-    get_str(CTFontCopyFamilyName(fFontRef), familyName);
+    get_str(CTFontCopyFamilyName(fFontRef.get()), familyName);
 }
 
 void SkTypeface_Mac::onGetFontDescriptor(SkFontDescriptor* desc,
                                          bool* isLocalStream) const {
     SkString tmpStr;
 
-    desc->setFamilyName(get_str(CTFontCopyFamilyName(fFontRef), &tmpStr));
-    desc->setFullName(get_str(CTFontCopyFullName(fFontRef), &tmpStr));
-    desc->setPostscriptName(get_str(CTFontCopyPostScriptName(fFontRef), &tmpStr));
+    desc->setFamilyName(get_str(CTFontCopyFamilyName(fFontRef.get()), &tmpStr));
+    desc->setFullName(get_str(CTFontCopyFullName(fFontRef.get()), &tmpStr));
+    desc->setPostscriptName(get_str(CTFontCopyPostScriptName(fFontRef.get()), &tmpStr));
     desc->setStyle(this->fontStyle());
     *isLocalStream = fIsLocalStream;
 }
@@ -1943,7 +1874,7 @@
         macGlyphs = glyphStorage.reset(srcCount);
     }
 
-    bool allEncoded = CTFontGetGlyphsForCharacters(fFontRef, src, macGlyphs, srcCount);
+    bool allEncoded = CTFontGetGlyphsForCharacters(fFontRef.get(), src, macGlyphs, srcCount);
 
     // If there were any non-bmp, then copy and compact.
     // If 'glyphs' is nullptr, then compact glyphStorage in-place.
@@ -1978,18 +1909,18 @@
 }
 
 int SkTypeface_Mac::onCountGlyphs() const {
-    return SkToInt(CTFontGetGlyphCount(fFontRef));
+    return SkToInt(CTFontGetGlyphCount(fFontRef.get()));
 }
 
 ///////////////////////////////////////////////////////////////////////////////
 ///////////////////////////////////////////////////////////////////////////////
 
 static bool find_desc_str(CTFontDescriptorRef desc, CFStringRef name, SkString* value) {
-    AutoCFRelease<CFStringRef> ref((CFStringRef)CTFontDescriptorCopyAttribute(desc, name));
-    if (nullptr == ref.get()) {
+    UniqueCFRef<CFStringRef> ref((CFStringRef)CTFontDescriptorCopyAttribute(desc, name));
+    if (!ref) {
         return false;
     }
-    CFStringToSkString(ref, value);
+    CFStringToSkString(ref.get(), value);
     return true;
 }
 
@@ -2011,15 +1942,12 @@
 public:
     SkFontStyleSet_Mac(CTFontDescriptorRef desc)
         : fArray(CTFontDescriptorCreateMatchingFontDescriptors(desc, nullptr))
-        , fCount(0) {
-        if (nullptr == fArray) {
-            fArray = CFArrayCreate(nullptr, nullptr, 0, nullptr);
+        , fCount(0)
+    {
+        if (!fArray) {
+            fArray.reset(CFArrayCreate(nullptr, nullptr, 0, nullptr));
         }
-        fCount = SkToInt(CFArrayGetCount(fArray));
-    }
-
-    virtual ~SkFontStyleSet_Mac() {
-        CFRelease(fArray);
+        fCount = SkToInt(CFArrayGetCount(fArray.get()));
     }
 
     int count() override {
@@ -2028,7 +1956,7 @@
 
     void getStyle(int index, SkFontStyle* style, SkString* name) override {
         SkASSERT((unsigned)index < (unsigned)fCount);
-        CTFontDescriptorRef desc = (CTFontDescriptorRef)CFArrayGetValueAtIndex(fArray, index);
+        CTFontDescriptorRef desc = (CTFontDescriptorRef)CFArrayGetValueAtIndex(fArray.get(), index);
         if (style) {
             *style = fontstyle_from_descriptor(desc);
         }
@@ -2040,8 +1968,8 @@
     }
 
     SkTypeface* createTypeface(int index) override {
-        SkASSERT((unsigned)index < (unsigned)CFArrayGetCount(fArray));
-        CTFontDescriptorRef desc = (CTFontDescriptorRef)CFArrayGetValueAtIndex(fArray, index);
+        SkASSERT((unsigned)index < (unsigned)CFArrayGetCount(fArray.get()));
+        CTFontDescriptorRef desc = (CTFontDescriptorRef)CFArrayGetValueAtIndex(fArray.get(), index);
 
         return create_from_desc(desc);
     }
@@ -2054,15 +1982,15 @@
     }
 
 private:
-    CFArrayRef  fArray;
-    int         fCount;
+    UniqueCFRef<CFArrayRef> fArray;
+    int fCount;
 
     CTFontDescriptorRef findMatchingDesc(const SkFontStyle& pattern) const {
         int bestMetric = SK_MaxS32;
         CTFontDescriptorRef bestDesc = nullptr;
 
         for (int i = 0; i < fCount; ++i) {
-            CTFontDescriptorRef desc = (CTFontDescriptorRef)CFArrayGetValueAtIndex(fArray, i);
+            CTFontDescriptorRef desc = (CTFontDescriptorRef)CFArrayGetValueAtIndex(fArray.get(), i);
             int metric = compute_metric(pattern, fontstyle_from_descriptor(desc));
             if (0 == metric) {
                 return desc;
@@ -2078,35 +2006,42 @@
 };
 
 class SkFontMgr_Mac : public SkFontMgr {
-    CFArrayRef  fNames;
-    int         fCount;
+    UniqueCFRef<CFArrayRef> fNames;
+    int fCount;
 
-    CFStringRef stringAt(int index) const {
+    CFStringRef getFamilyNameAt(int index) const {
         SkASSERT((unsigned)index < (unsigned)fCount);
-        return (CFStringRef)CFArrayGetValueAtIndex(fNames, index);
+        return (CFStringRef)CFArrayGetValueAtIndex(fNames.get(), index);
     }
 
     static SkFontStyleSet* CreateSet(CFStringRef cfFamilyName) {
-        AutoCFRelease<CFMutableDictionaryRef> cfAttr(
+        UniqueCFRef<CFMutableDictionaryRef> cfAttr(
                  CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
                                            &kCFTypeDictionaryKeyCallBacks,
                                            &kCFTypeDictionaryValueCallBacks));
 
-        CFDictionaryAddValue(cfAttr, kCTFontFamilyNameAttribute, cfFamilyName);
+        CFDictionaryAddValue(cfAttr.get(), kCTFontFamilyNameAttribute, cfFamilyName);
 
-        AutoCFRelease<CTFontDescriptorRef> desc(
-                                CTFontDescriptorCreateWithAttributes(cfAttr));
-        return new SkFontStyleSet_Mac(desc);
+        UniqueCFRef<CTFontDescriptorRef> desc(
+                CTFontDescriptorCreateWithAttributes(cfAttr.get()));
+        return new SkFontStyleSet_Mac(desc.get());
+    }
+
+    /** CTFontManagerCopyAvailableFontFamilyNames() is not always available, so we
+     *  provide a wrapper here that will return an empty array if need be.
+     */
+    static UniqueCFRef<CFArrayRef> CopyAvailableFontFamilyNames() {
+#ifdef SK_BUILD_FOR_IOS
+        return UniqueCFRef<CFArrayRef>(CFArrayCreate(nullptr, nullptr, 0, nullptr));
+#else
+        return UniqueCFRef<CFArrayRef>(CTFontManagerCopyAvailableFontFamilyNames());
+#endif
     }
 
 public:
     SkFontMgr_Mac()
-        : fNames(SkCTFontManagerCopyAvailableFontFamilyNames())
-        , fCount(fNames ? SkToInt(CFArrayGetCount(fNames)) : 0) {}
-
-    virtual ~SkFontMgr_Mac() {
-        CFSafeRelease(fNames);
-    }
+        : fNames(CopyAvailableFontFamilyNames())
+        , fCount(fNames ? SkToInt(CFArrayGetCount(fNames.get())) : 0) {}
 
 protected:
     int onCountFamilies() const override {
@@ -2115,7 +2050,7 @@
 
     void onGetFamilyName(int index, SkString* familyName) const override {
         if ((unsigned)index < (unsigned)fCount) {
-            CFStringToSkString(this->stringAt(index), familyName);
+            CFStringToSkString(this->getFamilyNameAt(index), familyName);
         } else {
             familyName->reset();
         }
@@ -2125,26 +2060,26 @@
         if ((unsigned)index >= (unsigned)fCount) {
             return nullptr;
         }
-        return CreateSet(this->stringAt(index));
+        return CreateSet(this->getFamilyNameAt(index));
     }
 
     SkFontStyleSet* onMatchFamily(const char familyName[]) const override {
-        AutoCFRelease<CFStringRef> cfName(make_CFString(familyName));
-        return CreateSet(cfName);
+        UniqueCFRef<CFStringRef> cfName = make_CFString(familyName);
+        return CreateSet(cfName.get());
     }
 
-    virtual SkTypeface* onMatchFamilyStyle(const char familyName[],
-                                           const SkFontStyle& fontStyle) const override {
+    SkTypeface* onMatchFamilyStyle(const char familyName[],
+                                   const SkFontStyle& fontStyle) const override {
         sk_sp<SkFontStyleSet> sset(this->matchFamily(familyName));
         return sset->matchStyle(fontStyle);
     }
 
-    virtual SkTypeface* onMatchFamilyStyleCharacter(const char familyName[],
-                                                    const SkFontStyle& style,
-                                                    const char* bcp47[], int bcp47Count,
-                                                    SkUnichar character) const override {
-        AutoCFRelease<CTFontDescriptorRef> desc(create_descriptor(familyName, style));
-        AutoCFRelease<CTFontRef> currentFont(CTFontCreateWithFontDescriptor(desc, 0, nullptr));
+    SkTypeface* onMatchFamilyStyleCharacter(const char familyName[],
+                                            const SkFontStyle& style,
+                                            const char* bcp47[], int bcp47Count,
+                                            SkUnichar character) const override {
+        UniqueCFRef<CTFontDescriptorRef> desc = create_descriptor(familyName, style);
+        UniqueCFRef<CTFontRef> currentFont(CTFontCreateWithFontDescriptor(desc.get(), 0, nullptr));
 
         // kCFStringEncodingUTF32 is BE unless there is a BOM.
         // Since there is no machine endian option, explicitly state machine endian.
@@ -2153,34 +2088,35 @@
 #else
         constexpr CFStringEncoding encoding = kCFStringEncodingUTF32BE;
 #endif
-        AutoCFRelease<CFStringRef> string(CFStringCreateWithBytes(
+        UniqueCFRef<CFStringRef> string(CFStringCreateWithBytes(
                 kCFAllocatorDefault, reinterpret_cast<const UInt8 *>(&character), sizeof(character),
                 encoding, false));
-        CFRange range = CFRangeMake(0, CFStringGetLength(string));  // in UniChar units.
-        AutoCFRelease<CTFontRef> fallbackFont(CTFontCreateForString(currentFont, string, range));
-        return create_from_CTFontRef(fallbackFont.release(), nullptr, false);
+        CFRange range = CFRangeMake(0, CFStringGetLength(string.get()));  // in UniChar units.
+        UniqueCFRef<CTFontRef> fallbackFont(
+                CTFontCreateForString(currentFont.get(), string.get(), range));
+        return create_from_CTFontRef(std::move(fallbackFont), nullptr, false);
     }
 
-    virtual SkTypeface* onMatchFaceStyle(const SkTypeface* familyMember,
-                                         const SkFontStyle&) const override {
+    SkTypeface* onMatchFaceStyle(const SkTypeface* familyMember,
+                                 const SkFontStyle&) const override {
         return nullptr;
     }
 
     SkTypeface* onCreateFromData(SkData* data, int ttcIndex) const override {
-        AutoCFRelease<CGDataProviderRef> pr(SkCreateDataProviderFromData(sk_ref_sp(data)));
-        if (nullptr == pr) {
+        UniqueCFRef<CGDataProviderRef> pr(SkCreateDataProviderFromData(sk_ref_sp(data)));
+        if (!pr) {
             return nullptr;
         }
-        return create_from_dataProvider(pr);
+        return create_from_dataProvider(std::move(pr));
     }
 
     SkTypeface* onCreateFromStream(SkStreamAsset* bareStream, int ttcIndex) const override {
         std::unique_ptr<SkStreamAsset> stream(bareStream);
-        AutoCFRelease<CGDataProviderRef> pr(SkCreateDataProviderFromStream(std::move(stream)));
-        if (nullptr == pr) {
+        UniqueCFRef<CGDataProviderRef> pr(SkCreateDataProviderFromStream(std::move(stream)));
+        if (!pr) {
             return nullptr;
         }
-        return create_from_dataProvider(pr);
+        return create_from_dataProvider(std::move(pr));
     }
 
     static CFNumberRef get_tag_for_name(CFStringRef name, CFArrayRef ctAxes) {
@@ -2209,32 +2145,34 @@
         }
         return nullptr;
     }
-    static CFDictionaryRef get_axes(CGFontRef cg, const FontParameters& params) {
-        AutoCFRelease<CFArrayRef> cgAxes(CGFontCopyVariationAxes(cg));
+    static UniqueCFRef<CFDictionaryRef> copy_axes(CGFontRef cg, const FontParameters& params) {
+        UniqueCFRef<CFArrayRef> cgAxes(CGFontCopyVariationAxes(cg));
         if (!cgAxes) {
             return nullptr;
         }
-        CFIndex axisCount = CFArrayGetCount(cgAxes);
+        CFIndex axisCount = CFArrayGetCount(cgAxes.get());
 
         // The CGFont variation data is keyed by name, and lacks the tag.
         // The CTFont variation data is keyed by tag, and also has the name.
         // We would like to work with CTFont variaitons, but creating a CTFont font with
         // CTFont variation dictionary runs into bugs. So use the CTFont variation data
         // to match names to tags to create the appropriate CGFont.
-        AutoCFRelease<CTFontRef> ct(CTFontCreateWithGraphicsFont(cg, 0, nullptr, nullptr));
-        AutoCFRelease<CFArrayRef> ctAxes(CTFontCopyVariationAxes(ct));
-        if (!ctAxes || CFArrayGetCount(ctAxes) != axisCount) {
+        UniqueCFRef<CTFontRef> ct(CTFontCreateWithGraphicsFont(cg, 0, nullptr, nullptr));
+        UniqueCFRef<CFArrayRef> ctAxes(CTFontCopyVariationAxes(ct.get()));
+        if (!ctAxes || CFArrayGetCount(ctAxes.get()) != axisCount) {
             return nullptr;
         }
 
         int paramAxisCount;
         const FontParameters::Axis* paramAxes = params.getAxes(&paramAxisCount);
 
-        CFMutableDictionaryRef dict = CFDictionaryCreateMutable(kCFAllocatorDefault, axisCount,
-                                                                &kCFTypeDictionaryKeyCallBacks,
-                                                                &kCFTypeDictionaryValueCallBacks);
+        UniqueCFRef<CFMutableDictionaryRef> dict(
+                CFDictionaryCreateMutable(kCFAllocatorDefault, axisCount,
+                                          &kCFTypeDictionaryKeyCallBacks,
+                                          &kCFTypeDictionaryValueCallBacks));
+
         for (int i = 0; i < axisCount; ++i) {
-            CFTypeRef axisInfo = CFArrayGetValueAtIndex(cgAxes, i);
+            CFTypeRef axisInfo = CFArrayGetValueAtIndex(cgAxes.get(), i);
             if (CFDictionaryGetTypeID() != CFGetTypeID(axisInfo)) {
                 return nullptr;
             }
@@ -2245,7 +2183,8 @@
                 return nullptr;
             }
 
-            CFNumberRef tagNumber = get_tag_for_name(static_cast<CFStringRef>(axisName), ctAxes);
+            CFNumberRef tagNumber =
+                    get_tag_for_name(static_cast<CFStringRef>(axisName), ctAxes.get());
             if (!tagNumber) {
                 // Could not find a tag to go with the name of this index.
                 // This would be a bug in CG/CT.
@@ -2287,58 +2226,60 @@
                     break;
                 }
             }
-            CFNumberRef valueNumber = CFNumberCreate(kCFAllocatorDefault, kCFNumberDoubleType,
-                                                     &value);
-            CFDictionaryAddValue(dict, axisName, valueNumber);
-            CFRelease(valueNumber);
+            UniqueCFRef<CFNumberRef> valueNumber(
+                CFNumberCreate(kCFAllocatorDefault, kCFNumberDoubleType, &value));
+            CFDictionaryAddValue(dict.get(), axisName, valueNumber.get());
         }
-        return dict;
+        return std::move(dict);
     }
     SkTypeface* onCreateFromStream(SkStreamAsset* bs, const FontParameters& params) const override {
         std::unique_ptr<SkStreamAsset> s(bs);
-        AutoCFRelease<CGDataProviderRef> provider(SkCreateDataProviderFromStream(std::move(s)));
-        if (nullptr == provider) {
+        UniqueCFRef<CGDataProviderRef> provider(SkCreateDataProviderFromStream(std::move(s)));
+        if (!provider) {
             return nullptr;
         }
-        AutoCFRelease<CGFontRef> cg(CGFontCreateWithDataProvider(provider));
-        if (nullptr == cg) {
+        UniqueCFRef<CGFontRef> cg(CGFontCreateWithDataProvider(provider.get()));
+        if (!cg) {
             return nullptr;
         }
 
-        AutoCFRelease<CFDictionaryRef> cgVariations(get_axes(cg, params));
+        UniqueCFRef<CFDictionaryRef> cgVariations = copy_axes(cg.get(), params);
         // The CGFontRef returned by CGFontCreateCopyWithVariations when the passed CGFontRef was
         // created from a data provider does not appear to have any ownership of the underlying
         // data. The original CGFontRef must be kept alive until the copy will no longer be used.
-        AutoCFRelease<CGFontRef> cgVariant;
+        UniqueCFRef<CGFontRef> cgVariant;
         if (cgVariations) {
-            cgVariant.reset(CGFontCreateCopyWithVariations(cg, cgVariations));
+            cgVariant.reset(CGFontCreateCopyWithVariations(cg.get(), cgVariations.get()));
         } else {
             cgVariant.reset(cg.release());
         }
 
-        AutoCFRelease<CTFontRef> ct(CTFontCreateWithGraphicsFont(cgVariant, 0, nullptr, nullptr));
+        UniqueCFRef<CTFontRef> ct(
+                CTFontCreateWithGraphicsFont(cgVariant.get(), 0, nullptr, nullptr));
         if (!ct) {
             return nullptr;
         }
-        return create_from_CTFontRef(ct.release(), cg.release(), true);
+        return create_from_CTFontRef(std::move(ct), std::move(cg), true);
     }
 
-    static CFDictionaryRef get_axes(CGFontRef cg, SkFontData* fontData) {
-        AutoCFRelease<CFArrayRef> cgAxes(CGFontCopyVariationAxes(cg));
+    static UniqueCFRef<CFDictionaryRef> copy_axes(CGFontRef cg, SkFontData* fontData) {
+        UniqueCFRef<CFArrayRef> cgAxes(CGFontCopyVariationAxes(cg));
         if (!cgAxes) {
             return nullptr;
         }
 
-        CFIndex axisCount = CFArrayGetCount(cgAxes);
+        CFIndex axisCount = CFArrayGetCount(cgAxes.get());
         if (0 == axisCount || axisCount != fontData->getAxisCount()) {
             return nullptr;
         }
 
-        CFMutableDictionaryRef dict = CFDictionaryCreateMutable(kCFAllocatorDefault, axisCount,
-                                                                &kCFTypeDictionaryKeyCallBacks,
-                                                                &kCFTypeDictionaryValueCallBacks);
+        UniqueCFRef<CFMutableDictionaryRef> dict(
+                CFDictionaryCreateMutable(kCFAllocatorDefault, axisCount,
+                                          &kCFTypeDictionaryKeyCallBacks,
+                                          &kCFTypeDictionaryValueCallBacks));
+
         for (int i = 0; i < fontData->getAxisCount(); ++i) {
-            CFTypeRef axisInfo = CFArrayGetValueAtIndex(cgAxes, i);
+            CFTypeRef axisInfo = CFArrayGetValueAtIndex(cgAxes.get(), i);
             if (CFDictionaryGetTypeID() != CFGetTypeID(axisInfo)) {
                 return nullptr;
             }
@@ -2368,49 +2309,48 @@
                 return nullptr;
             }
             double value = SkTPin(SkFixedToDouble(fontData->getAxis()[i]), minDouble, maxDouble);
-            CFNumberRef valueNumber = CFNumberCreate(kCFAllocatorDefault, kCFNumberDoubleType,
-                                                     &value);
-
-            CFDictionaryAddValue(dict, axisName, valueNumber);
-            CFRelease(valueNumber);
+            UniqueCFRef<CFNumberRef> valueNumber(
+                    CFNumberCreate(kCFAllocatorDefault, kCFNumberDoubleType, &value));
+            CFDictionaryAddValue(dict.get(), axisName, valueNumber.get());
         }
-        return dict;
+        return std::move(dict);
     }
     SkTypeface* onCreateFromFontData(std::unique_ptr<SkFontData> fontData) const override {
-        AutoCFRelease<CGDataProviderRef> provider(
+        UniqueCFRef<CGDataProviderRef> provider(
                 SkCreateDataProviderFromStream(fontData->detachStream()));
-        if (nullptr == provider) {
+        if (!provider) {
             return nullptr;
         }
-        AutoCFRelease<CGFontRef> cg(CGFontCreateWithDataProvider(provider));
-        if (nullptr == cg) {
+        UniqueCFRef<CGFontRef> cg(CGFontCreateWithDataProvider(provider.get()));
+        if (!cg) {
             return nullptr;
         }
 
-        AutoCFRelease<CFDictionaryRef> cgVariations(get_axes(cg, fontData.get()));
+        UniqueCFRef<CFDictionaryRef> cgVariations = copy_axes(cg.get(), fontData.get());
         // The CGFontRef returned by CGFontCreateCopyWithVariations when the passed CGFontRef was
         // created from a data provider does not appear to have any ownership of the underlying
         // data. The original CGFontRef must be kept alive until the copy will no longer be used.
-        AutoCFRelease<CGFontRef> cgVariant;
+        UniqueCFRef<CGFontRef> cgVariant;
         if (cgVariations) {
-            cgVariant.reset(CGFontCreateCopyWithVariations(cg, cgVariations));
+            cgVariant.reset(CGFontCreateCopyWithVariations(cg.get(), cgVariations.get()));
         } else {
             cgVariant.reset(cg.release());
         }
 
-        AutoCFRelease<CTFontRef> ct(CTFontCreateWithGraphicsFont(cgVariant, 0, nullptr, nullptr));
+        UniqueCFRef<CTFontRef> ct(
+                CTFontCreateWithGraphicsFont(cgVariant.get(), 0, nullptr, nullptr));
         if (!ct) {
             return nullptr;
         }
-        return create_from_CTFontRef(ct.release(), cg.release(), true);
+        return create_from_CTFontRef(std::move(ct), std::move(cg), true);
     }
 
     SkTypeface* onCreateFromFile(const char path[], int ttcIndex) const override {
-        AutoCFRelease<CGDataProviderRef> pr(CGDataProviderCreateWithFilename(path));
-        if (nullptr == pr) {
+        UniqueCFRef<CGDataProviderRef> pr(CGDataProviderCreateWithFilename(path));
+        if (!pr) {
             return nullptr;
         }
-        return create_from_dataProvider(pr);
+        return create_from_dataProvider(std::move(pr));
     }
 
     SkTypeface* onLegacyCreateTypeface(const char familyName[], SkFontStyle style) const override {
@@ -2418,6 +2358,7 @@
             familyName = map_css_names(familyName);
         }
 
+        static const char FONT_DEFAULT_NAME[] = "Lucida Sans";
         if (!familyName || !*familyName) {
             familyName = FONT_DEFAULT_NAME;
         }
@@ -2427,7 +2368,12 @@
             return face;
         }
 
-        return SkSafeRef(GetDefaultFace());
+        static SkTypeface* gDefaultFace;
+        static SkOnce lookupDefault;
+        lookupDefault([]{
+            gDefaultFace = create_from_name(FONT_DEFAULT_NAME, SkFontStyle());
+        });
+        return SkSafeRef(gDefaultFace);
     }
 };