Reland "Replace CGFontCreate with CTFontManagerCreate."

This is a reland of f1d4f00fda5ca6ce8cd609d5a335ee27f1b75d72

Original change's description:
> Replace CGFontCreate with CTFontManagerCreate.
>
> Replaces calls to CGFontCreateWithDataProvider with calls to
> CTFontManagerCreateFontDescriptorFromData. Note that this means Skia will
> not create CTFonts based on CGFonts, however SkCreateTypefaceFromCTFont
> allows the user to create CTFonts from CGFonts and introduce them to Skia.
>
> Bug: skia:4043,skia:9627
>
> Change-Id: I8eb72c0e4eb257149f1f6a78ca34da4fbfafccab
> TBR: reed@google.com
> Reviewed-on: https://skia-review.googlesource.com/c/skia/+/254181
> Commit-Queue: Ben Wagner <bungeman@google.com>
> Reviewed-by: Dominik Röttsches <drott@google.com>

Bug: skia:4043, skia:9627
Change-Id: Ic265f2ce52b816831e6402c5ffd21dac065049dd
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/257052
Reviewed-by: Dominik Röttsches <drott@chromium.org>
Commit-Queue: Ben Wagner <bungeman@google.com>
diff --git a/BUILD.gn b/BUILD.gn
index 66f7849..bcbe6eb 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -924,7 +924,6 @@
     "src/ports/SkOSFile_stdio.cpp",
     "src/sfnt/SkOTTable_name.cpp",
     "src/sfnt/SkOTUtils.cpp",
-    "src/utils/mac/SkStream_mac.cpp",
   ]
 
   defines = []
diff --git a/include/utils/mac/SkCGUtils.h b/include/utils/mac/SkCGUtils.h
index a8bde99..43cd59f 100644
--- a/include/utils/mac/SkCGUtils.h
+++ b/include/utils/mac/SkCGUtils.h
@@ -74,13 +74,5 @@
  */
 void SkCGDrawBitmap(CGContextRef, const SkBitmap&, float x, float y);
 
-/**
- *  Return a provider that wraps the specified stream.
- *  When the provider is finally deleted, it will delete the stream.
- */
-CGDataProviderRef SkCreateDataProviderFromStream(std::unique_ptr<SkStreamRewindable>);
-
-CGDataProviderRef SkCreateDataProviderFromData(sk_sp<SkData>);
-
 #endif  // defined(SK_BUILD_FOR_MAC) || defined(SK_BUILD_FOR_IOS)
 #endif  // SkCGUtils_DEFINED
diff --git a/src/ports/SkFontHost_mac.cpp b/src/ports/SkFontHost_mac.cpp
index bddbf65..3a997ec 100644
--- a/src/ports/SkFontHost_mac.cpp
+++ b/src/ports/SkFontHost_mac.cpp
@@ -386,13 +386,12 @@
                 CGBitmapContextCreate(&smoothBitmap, 16, 16, 8, 16*4,
                                       colorspace.get(), BITMAP_INFO_RGB));
 
-        SkUniqueCFRef<CGDataProviderRef> data(
-                CGDataProviderCreateWithData(nullptr, kSpiderSymbol_ttf,
-                                             SK_ARRAY_COUNT(kSpiderSymbol_ttf), nullptr));
-        SkUniqueCFRef<CGFontRef> cgFont(CGFontCreateWithDataProvider(data.get()));
-        SkASSERT(cgFont);
-        SkUniqueCFRef<CTFontRef> ctFont(
-                CTFontCreateWithGraphicsFont(cgFont.get(), 16, nullptr, nullptr));
+        SkUniqueCFRef<CFDataRef> data(CFDataCreateWithBytesNoCopy(
+                kCFAllocatorDefault, kSpiderSymbol_ttf, SK_ARRAY_COUNT(kSpiderSymbol_ttf),
+                kCFAllocatorNull));
+        SkUniqueCFRef<CTFontDescriptorRef> desc(
+                CTFontManagerCreateFontDescriptorFromData(data.get()));
+        SkUniqueCFRef<CTFontRef> ctFont(CTFontCreateWithFontDescriptor(desc.get(), 16, nullptr));
         SkASSERT(ctFont);
 
         CGContextSetShouldSmoothFonts(noSmoothContext.get(), false);
@@ -1617,24 +1616,6 @@
 
 ///////////////////////////////////////////////////////////////////////////////
 
-// Returns nullptr on failure
-static sk_sp<SkTypeface> create_from_dataProvider(SkUniqueCFRef<CGDataProviderRef> provider,
-                                                  std::unique_ptr<SkStreamAsset> providedData,
-                                                  int ttcIndex) {
-    if (ttcIndex != 0) {
-        return nullptr;
-    }
-    SkUniqueCFRef<CGFontRef> cg(CGFontCreateWithDataProvider(provider.get()));
-    if (!cg) {
-        return nullptr;
-    }
-    SkUniqueCFRef<CTFontRef> ct(CTFontCreateWithGraphicsFont(cg.get(), 0, nullptr, nullptr));
-    if (!ct) {
-        return nullptr;
-    }
-    return create_from_CTFontRef(std::move(ct), nullptr, OpszVariation(), std::move(providedData));
-}
-
 // 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.
@@ -2115,7 +2096,7 @@
 static SkUniqueCFRef<CFDictionaryRef> ct_variation_from_cg_variation(CFDictionaryRef cgVariations,
                                                                      CFArrayRef ctAxes) {
 
-    SkUniqueCFRef<CFMutableDictionaryRef> ctVariations(
+    SkUniqueCFRef<CFMutableDictionaryRef> ctVariation(
             CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
                                       &kCFTypeDictionaryKeyCallBacks,
                                       &kCFTypeDictionaryValueCallBacks));
@@ -2145,9 +2126,9 @@
             return nullptr;
         }
 
-        CFDictionaryAddValue(ctVariations.get(), axisTag, axisValue);
+        CFDictionaryAddValue(ctVariation.get(), axisTag, axisValue);
     }
-    return ctVariations;
+    return ctVariation;
 }
 
 int SkTypeface_Mac::onGetVariationDesignPosition(
@@ -2169,8 +2150,8 @@
     // This call always returns nullptr on 10.11 and under for CGFontCreateWithDataProvider fonts.
     // When this happens, try converting the CG variation to a CT variation.
     // On 10.12 and later, this only returns non-default variations.
-    SkUniqueCFRef<CFDictionaryRef> ctVariations(CTFontCopyVariation(fFontRef.get()));
-    if (!ctVariations) {
+    SkUniqueCFRef<CFDictionaryRef> ctVariation(CTFontCopyVariation(fFontRef.get()));
+    if (!ctVariation) {
         // When 10.11 and earlier are no longer supported, the following code can be replaced with
         // return -1 and ct_variation_from_cg_variation can be removed.
         SkUniqueCFRef<CGFontRef> cgFont(CTFontCopyGraphicsFont(fFontRef.get(), nullptr));
@@ -2181,8 +2162,8 @@
         if (!cgVariations) {
             return -1;
         }
-        ctVariations = ct_variation_from_cg_variation(cgVariations.get(), ctAxes.get());
-        if (!ctVariations) {
+        ctVariation = ct_variation_from_cg_variation(cgVariations.get(), ctAxes.get());
+        if (!ctVariation) {
             return -1;
         }
     }
@@ -2206,7 +2187,7 @@
         coordinates[i].axis = tagLong;
 
         CGFloat variationCGFloat;
-        CFTypeRef variationValue = CFDictionaryGetValue(ctVariations.get(), tagNumber);
+        CFTypeRef variationValue = CFDictionaryGetValue(ctVariation.get(), tagNumber);
         if (variationValue) {
             if (CFGetTypeID(variationValue) != CFNumberGetTypeID()) {
                 return -1;
@@ -2696,45 +2677,52 @@
     }
 
     sk_sp<SkTypeface> onMakeFromData(sk_sp<SkData> data, int ttcIndex) const override {
-        SkUniqueCFRef<CGDataProviderRef> pr(SkCreateDataProviderFromData(data));
-        if (!pr) {
+        if (ttcIndex != 0) {
             return nullptr;
         }
-        return create_from_dataProvider(std::move(pr), SkMemoryStream::Make(std::move(data)),
-                                        ttcIndex);
+
+        SkUniqueCFRef<CTFontRef> ct = ctfont_from_skdata(data, ttcIndex);
+        if (!ct) {
+            return nullptr;
+        }
+
+        return create_from_CTFontRef(std::move(ct), nullptr, OpszVariation(),
+                                     SkMemoryStream::Make(std::move(data)));
     }
 
     sk_sp<SkTypeface> onMakeFromStreamIndex(std::unique_ptr<SkStreamAsset> stream,
                                             int ttcIndex) const override {
-        SkUniqueCFRef<CGDataProviderRef> pr(SkCreateDataProviderFromStream(stream->duplicate()));
-        if (!pr) {
+        if (ttcIndex != 0) {
             return nullptr;
         }
-        return create_from_dataProvider(std::move(pr), std::move(stream), ttcIndex);
+
+        sk_sp<SkData> data = skdata_from_skstreamasset(stream->duplicate());
+        if (!data) {
+            return nullptr;
+        }
+        SkUniqueCFRef<CTFontRef> ct = ctfont_from_skdata(std::move(data), ttcIndex);
+        if (!ct) {
+            return nullptr;
+        }
+
+        return create_from_CTFontRef(std::move(ct), nullptr, OpszVariation(), std::move(stream));
     }
 
-    /** Creates a dictionary suitable for setting the axes on a CGFont. */
-    struct CGFontVariations {
+    struct CTFontVariation {
         SkUniqueCFRef<CFDictionaryRef> dict;
         OpszVariation opsz;
     };
-    static CGFontVariations copy_axes(CGFontRef cg, const SkFontArguments& args) {
-        // In macOS 10.15 CTFontCreate* overrides any 'opsz' variation with the 'size'.
-        // Track the 'opsz' and return it, since it is an out of band axis.
+
+    /** Creates a dictionary suitable for setting the axes on a CTFont. */
+    static CTFontVariation ctvariation_from_skfontarguments(CTFontRef ct,
+                                                            const SkFontArguments& args)
+    {
         OpszVariation opsz;
         constexpr const SkFourByteTag opszTag = SkSetFourByteTag('o','p','s','z');
 
-        // The CGFont variation data is keyed by name, but lacks the tag.
-        // The CTFont variation data is keyed by tag, and also has the name.
-        // We would like to work with CTFont variations, 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.
-        SkUniqueCFRef<CTFontRef> ct(CTFontCreateWithGraphicsFont(cg, 0, nullptr, nullptr));
-        // CTFontCopyVariationAxes returns nullptr for CGFontCreateWithDataProvider fonts with
-        // macOS 10.10 and iOS 9 or earlier. When this happens, there is no API to provide the tag.
-        SkUniqueCFRef<CFArrayRef> ctAxes(CTFontCopyVariationAxes(ct.get()));
+        SkUniqueCFRef<CFArrayRef> ctAxes(CTFontCopyVariationAxes(ct));
         if (!ctAxes) {
-            return CGFontVariations();
+            return CTFontVariation();
         }
         CFIndex axisCount = CFArrayGetCount(ctAxes.get());
 
@@ -2748,26 +2736,18 @@
         for (int i = 0; i < axisCount; ++i) {
             CFTypeRef axisInfo = CFArrayGetValueAtIndex(ctAxes.get(), i);
             if (CFDictionaryGetTypeID() != CFGetTypeID(axisInfo)) {
-                return CGFontVariations();
+                return CTFontVariation();
             }
             CFDictionaryRef axisInfoDict = static_cast<CFDictionaryRef>(axisInfo);
 
-            // The assumption is that values produced by kCTFontVariationAxisNameKey and
-            // kCGFontVariationAxisName will always be equal.
-            // If they are ever not, seach the project history for "get_tag_for_name".
-            CFTypeRef axisName = CFDictionaryGetValue(axisInfoDict, kCTFontVariationAxisNameKey);
-            if (!axisName || CFGetTypeID(axisName) != CFStringGetTypeID()) {
-                return CGFontVariations();
-            }
-
             CFTypeRef tag = CFDictionaryGetValue(axisInfoDict, kCTFontVariationAxisIdentifierKey);
             if (!tag || CFGetTypeID(tag) != CFNumberGetTypeID()) {
-                return CGFontVariations();
+                return CTFontVariation();
             }
             CFNumberRef tagNumber = static_cast<CFNumberRef>(tag);
             int64_t tagLong;
             if (!CFNumberGetValue(tagNumber, kCFNumberSInt64Type, &tagLong)) {
-                return CGFontVariations();
+                return CTFontVariation();
             }
 
             // The variation axes can be set to any value, but cg will effectively pin them.
@@ -2779,7 +2759,7 @@
                 !max || CFGetTypeID(max) != CFNumberGetTypeID() ||
                 !def || CFGetTypeID(def) != CFNumberGetTypeID())
             {
-                return CGFontVariations();
+                return CTFontVariation();
             }
             CFNumberRef minNumber = static_cast<CFNumberRef>(min);
             CFNumberRef maxNumber = static_cast<CFNumberRef>(max);
@@ -2791,7 +2771,7 @@
                 !CFNumberGetValue(maxNumber, kCFNumberDoubleType, &maxDouble) ||
                 !CFNumberGetValue(defNumber, kCFNumberDoubleType, &defDouble))
             {
-                return CGFontVariations();
+                return CTFontVariation();
             }
 
             double value = defDouble;
@@ -2812,73 +2792,118 @@
             }
             SkUniqueCFRef<CFNumberRef> valueNumber(
                 CFNumberCreate(kCFAllocatorDefault, kCFNumberDoubleType, &value));
-            CFDictionaryAddValue(dict.get(), axisName, valueNumber.get());
+            CFDictionaryAddValue(dict.get(), tagNumber, valueNumber.get());
         }
         return { SkUniqueCFRef<CFDictionaryRef>(std::move(dict)), opsz };
     }
-    sk_sp<SkTypeface> onMakeFromStreamArgs(std::unique_ptr<SkStreamAsset> s,
-                                           const SkFontArguments& args) const override {
-        if (args.getCollectionIndex() != 0) {
-            return nullptr;
+
+    static sk_sp<SkData> skdata_from_skstreamasset(std::unique_ptr<SkStreamAsset> stream) {
+        size_t size = stream->getLength();
+        if (const void* base = stream->getMemoryBase()) {
+            return SkData::MakeWithProc(base, size,
+                                        [](const void*, void* ctx) -> void {
+                                            delete (SkStreamAsset*)ctx;
+                                        }, stream.release());
         }
-        SkUniqueCFRef<CGDataProviderRef> provider(SkCreateDataProviderFromStream(s->duplicate()));
-        if (!provider) {
-            return nullptr;
-        }
-        SkUniqueCFRef<CGFontRef> cg(CGFontCreateWithDataProvider(provider.get()));
-        if (!cg) {
+        return SkData::MakeFromStream(stream.get(), size);
+    }
+
+    static SkUniqueCFRef<CFDataRef> cfdata_from_skdata(sk_sp<SkData> data) {
+        void const * const addr = data->data();
+        size_t const size = data->size();
+
+        CFAllocatorContext ctx = {
+            0, // CFIndex version
+            data.release(), // void* info
+            nullptr, // const void *(*retain)(const void *info);
+            nullptr, // void (*release)(const void *info);
+            nullptr, // CFStringRef (*copyDescription)(const void *info);
+            nullptr, // void * (*allocate)(CFIndex size, CFOptionFlags hint, void *info);
+            nullptr, // void*(*reallocate)(void* ptr,CFIndex newsize,CFOptionFlags hint,void* info);
+            [](void*,void* info) -> void { // void (*deallocate)(void *ptr, void *info);
+                SkASSERT(info);
+                ((SkData*)info)->unref();
+            },
+            nullptr, // CFIndex (*preferredSize)(CFIndex size, CFOptionFlags hint, void *info);
+        };
+        SkUniqueCFRef<CFAllocatorRef> alloc(CFAllocatorCreate(kCFAllocatorDefault, &ctx));
+        return SkUniqueCFRef<CFDataRef>(CFDataCreateWithBytesNoCopy(
+                kCFAllocatorDefault, (const UInt8 *)addr, size, alloc.get()));
+    }
+
+    static SkUniqueCFRef<CTFontRef> ctfont_from_skdata(sk_sp<SkData> data, int ttcIndex) {
+        // TODO: Use CTFontManagerCreateFontDescriptorsFromData when available.
+        if (ttcIndex != 0) {
             return nullptr;
         }
 
-        CGFontVariations cgVariations = copy_axes(cg.get(), args);
-        // 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.
-        SkUniqueCFRef<CGFontRef> cgVariant;
-        if (cgVariations.dict) {
-            cgVariant.reset(CGFontCreateCopyWithVariations(cg.get(), cgVariations.dict.get()));
-        } else {
-            cgVariant.reset(cg.release());
+        SkUniqueCFRef<CFDataRef> cfData(cfdata_from_skdata(std::move(data)));
+
+        SkUniqueCFRef<CTFontDescriptorRef> desc(
+                CTFontManagerCreateFontDescriptorFromData(cfData.get()));
+        if (!desc) {
+            return nullptr;
+        }
+        return SkUniqueCFRef<CTFontRef>(CTFontCreateWithFontDescriptor(desc.get(), 0, nullptr));
+    }
+
+    sk_sp<SkTypeface> onMakeFromStreamArgs(std::unique_ptr<SkStreamAsset> stream,
+                                           const SkFontArguments& args) const override
+    {
+        // TODO: Use CTFontManagerCreateFontDescriptorsFromData when available.
+        int ttcIndex = args.getCollectionIndex();
+        if (ttcIndex != 0) {
+            return nullptr;
         }
 
-        SkUniqueCFRef<CTFontDescriptorRef> desc;
-        if (cgVariations.opsz.isSet) {
-            desc = create_opsz_descriptor(cgVariations.opsz.value);
+        sk_sp<SkData> data = skdata_from_skstreamasset(stream->duplicate());
+        if (!data) {
+            return nullptr;
         }
-
-        SkUniqueCFRef<CTFontRef> ct(
-                CTFontCreateWithGraphicsFont(cgVariant.get(), 0, nullptr, desc.get()));
+        SkUniqueCFRef<CTFontRef> ct = ctfont_from_skdata(std::move(data), ttcIndex);
         if (!ct) {
             return nullptr;
         }
-        return create_from_CTFontRef(std::move(ct), std::move(cg), cgVariations.opsz, std::move(s));
+
+        CTFontVariation ctVariation = ctvariation_from_skfontarguments(ct.get(), args);
+
+        SkUniqueCFRef<CTFontRef> ctVariant;
+        if (ctVariation.dict) {
+            SkUniqueCFRef<CFMutableDictionaryRef> attributes(
+                    CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
+                                              &kCFTypeDictionaryKeyCallBacks,
+                                              &kCFTypeDictionaryValueCallBacks));
+            CFDictionaryAddValue(attributes.get(),
+                                 kCTFontVariationAttribute, ctVariation.dict.get());
+            SkUniqueCFRef<CTFontDescriptorRef> varDesc(
+                    CTFontDescriptorCreateWithAttributes(attributes.get()));
+            ctVariant.reset(CTFontCreateCopyWithAttributes(ct.get(), 0, nullptr, varDesc.get()));
+        } else {
+            ctVariant.reset(ct.release());
+        }
+        if (!ctVariant) {
+            return nullptr;
+        }
+
+        return create_from_CTFontRef(std::move(ctVariant), nullptr, ctVariation.opsz,
+                                     std::move(stream));
     }
 
-    /** Creates a dictionary suitable for setting the axes on a CGFont. */
-    static CGFontVariations copy_axes(CGFontRef cg, SkFontData* fontData) {
+    /** Creates a dictionary suitable for setting the axes on a CTFont. */
+    static CTFontVariation ctvariation_from_skfontdata(CTFontRef ct, SkFontData* fontData) {
         // In macOS 10.15 CTFontCreate* overrides any 'opsz' variation with the 'size'.
         // Track the 'opsz' and return it, since it is an out of band axis.
         OpszVariation opsz;
         constexpr const SkFourByteTag opszTag = SkSetFourByteTag('o','p','s','z');
 
-        // The CGFont variation data is keyed by name, but lacks the tag.
-        // The CTFont variation data is keyed by tag, and also has the name.
-        // We would like to work with CTFont variations, 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.
-        SkUniqueCFRef<CTFontRef> ct(CTFontCreateWithGraphicsFont(cg, 0, nullptr, nullptr));
-        // CTFontCopyVariationAxes returns nullptr for CGFontCreateWithDataProvider fonts with
-        // macOS 10.10 and iOS 9 or earlier. When this happens, there is no API to provide the tag.
-        SkUniqueCFRef<CFArrayRef> ctAxes(CTFontCopyVariationAxes(ct.get()));
-
-        SkUniqueCFRef<CFArrayRef> cgAxes(CGFontCopyVariationAxes(cg));
-        if (!cgAxes) {
-            return CGFontVariations();
+        SkUniqueCFRef<CFArrayRef> ctAxes(CTFontCopyVariationAxes(ct));
+        if (!ctAxes) {
+            return CTFontVariation();
         }
 
-        CFIndex axisCount = CFArrayGetCount(cgAxes.get());
+        CFIndex axisCount = CFArrayGetCount(ctAxes.get());
         if (0 == axisCount || axisCount != fontData->getAxisCount()) {
-            return CGFontVariations();
+            return CTFontVariation();
         }
 
         SkUniqueCFRef<CFMutableDictionaryRef> dict(
@@ -2887,25 +2912,31 @@
                                           &kCFTypeDictionaryValueCallBacks));
 
         for (int i = 0; i < fontData->getAxisCount(); ++i) {
-            CFTypeRef axisInfo = CFArrayGetValueAtIndex(cgAxes.get(), i);
+            CFTypeRef axisInfo = CFArrayGetValueAtIndex(ctAxes.get(), i);
             if (CFDictionaryGetTypeID() != CFGetTypeID(axisInfo)) {
-                return CGFontVariations();
+                return CTFontVariation();
             }
             CFDictionaryRef axisInfoDict = static_cast<CFDictionaryRef>(axisInfo);
 
-            CFTypeRef axisName = CFDictionaryGetValue(axisInfoDict, kCGFontVariationAxisName);
-            if (!axisName || CFGetTypeID(axisName) != CFStringGetTypeID()) {
-                return CGFontVariations();
+            CFTypeRef tag = CFDictionaryGetValue(axisInfoDict,
+                                                 kCTFontVariationAxisIdentifierKey);
+            if (!tag || CFGetTypeID(tag) != CFNumberGetTypeID()) {
+                return CTFontVariation();
+            }
+            CFNumberRef tagNumber = static_cast<CFNumberRef>(tag);
+            int64_t tagLong;
+            if (!CFNumberGetValue(tagNumber, kCFNumberSInt64Type, &tagLong)) {
+                return CTFontVariation();
             }
 
             // The variation axes can be set to any value, but cg will effectively pin them.
             // Pin them here to normalize.
-            CFTypeRef min = CFDictionaryGetValue(axisInfoDict, kCGFontVariationAxisMinValue);
-            CFTypeRef max = CFDictionaryGetValue(axisInfoDict, kCGFontVariationAxisMaxValue);
+            CFTypeRef min = CFDictionaryGetValue(axisInfoDict, kCTFontVariationAxisMinimumValueKey);
+            CFTypeRef max = CFDictionaryGetValue(axisInfoDict, kCTFontVariationAxisMaximumValueKey);
             if (!min || CFGetTypeID(min) != CFNumberGetTypeID() ||
                 !max || CFGetTypeID(max) != CFNumberGetTypeID())
             {
-                return CGFontVariations();
+                return CTFontVariation();
             }
             CFNumberRef minNumber = static_cast<CFNumberRef>(min);
             CFNumberRef maxNumber = static_cast<CFNumberRef>(max);
@@ -2914,87 +2945,71 @@
             if (!CFNumberGetValue(minNumber, kCFNumberDoubleType, &minDouble) ||
                 !CFNumberGetValue(maxNumber, kCFNumberDoubleType, &maxDouble))
             {
-                return CGFontVariations();
+                return CTFontVariation();
             }
             double value = SkTPin(SkFixedToDouble(fontData->getAxis()[i]), minDouble, maxDouble);
 
-            // If this is the opsz axis, set the opsz return value.
-            // Note that ctAxes will be nullptr on macOS 10.10 and iOS 9 and earlier.
-            if (ctAxes) {
-                CFTypeRef axisInfo = CFArrayGetValueAtIndex(ctAxes.get(), i);
-                if (CFDictionaryGetTypeID() != CFGetTypeID(axisInfo)) {
-                    return CGFontVariations();
-                }
-                CFDictionaryRef axisInfoDict = static_cast<CFDictionaryRef>(axisInfo);
-
-                CFTypeRef tag = CFDictionaryGetValue(axisInfoDict,
-                                                     kCTFontVariationAxisIdentifierKey);
-                if (!tag || CFGetTypeID(tag) != CFNumberGetTypeID()) {
-                    return CGFontVariations();
-                }
-                CFNumberRef tagNumber = static_cast<CFNumberRef>(tag);
-                int64_t tagLong;
-                if (!CFNumberGetValue(tagNumber, kCFNumberSInt64Type, &tagLong)) {
-                    return CGFontVariations();
-                }
-
-                if (tagLong == opszTag) {
-                    opsz.isSet = true;
-                    opsz.value = value;
-                }
+            if (tagLong == opszTag) {
+                opsz.isSet = true;
+                opsz.value = value;
             }
 
             SkUniqueCFRef<CFNumberRef> valueNumber(
                     CFNumberCreate(kCFAllocatorDefault, kCFNumberDoubleType, &value));
-            CFDictionaryAddValue(dict.get(), axisName, valueNumber.get());
+            CFDictionaryAddValue(dict.get(), tagNumber, valueNumber.get());
         }
         return { SkUniqueCFRef<CFDictionaryRef>(std::move(dict)), opsz };
     }
     sk_sp<SkTypeface> onMakeFromFontData(std::unique_ptr<SkFontData> fontData) const override {
+        // TODO: Use CTFontManagerCreateFontDescriptorsFromData when available.
         if (fontData->getIndex() != 0) {
             return nullptr;
         }
-        SkUniqueCFRef<CGDataProviderRef> provider(
-                SkCreateDataProviderFromStream(fontData->getStream()->duplicate()));
-        if (!provider) {
+
+        sk_sp<SkData> data = skdata_from_skstreamasset(fontData->getStream()->duplicate());
+        if (!data) {
             return nullptr;
         }
-        SkUniqueCFRef<CGFontRef> cg(CGFontCreateWithDataProvider(provider.get()));
-        if (!cg) {
-            return nullptr;
-        }
-
-        CGFontVariations 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.
-        SkUniqueCFRef<CGFontRef> cgVariant;
-        if (cgVariations.dict) {
-            cgVariant.reset(CGFontCreateCopyWithVariations(cg.get(), cgVariations.dict.get()));
-        } else {
-            cgVariant.reset(cg.release());
-        }
-
-        SkUniqueCFRef<CTFontDescriptorRef> desc;
-        if (cgVariations.opsz.isSet) {
-            desc = create_opsz_descriptor(cgVariations.opsz.value);
-        }
-
-        SkUniqueCFRef<CTFontRef> ct(
-                CTFontCreateWithGraphicsFont(cgVariant.get(), 0, nullptr, desc.get()));
+        SkUniqueCFRef<CTFontRef> ct = ctfont_from_skdata(std::move(data), fontData->getIndex());
         if (!ct) {
             return nullptr;
         }
-        return create_from_CTFontRef(std::move(ct), std::move(cg),
-                                     cgVariations.opsz, fontData->detachStream());
+
+        CTFontVariation ctVariation = ctvariation_from_skfontdata(ct.get(), fontData.get());
+
+        SkUniqueCFRef<CTFontRef> ctVariant;
+        if (ctVariation.dict) {
+            SkUniqueCFRef<CFMutableDictionaryRef> attributes(
+                    CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
+                                              &kCFTypeDictionaryKeyCallBacks,
+                                              &kCFTypeDictionaryValueCallBacks));
+            CFDictionaryAddValue(attributes.get(),
+                                 kCTFontVariationAttribute, ctVariation.dict.get());
+            SkUniqueCFRef<CTFontDescriptorRef> varDesc(
+                    CTFontDescriptorCreateWithAttributes(attributes.get()));
+            ctVariant.reset(CTFontCreateCopyWithAttributes(ct.get(), 0, nullptr, varDesc.get()));
+        } else {
+            ctVariant.reset(ct.release());
+        }
+        if (!ctVariant) {
+            return nullptr;
+        }
+
+        return create_from_CTFontRef(std::move(ctVariant), nullptr,
+                                     ctVariation.opsz, fontData->detachStream());
     }
 
     sk_sp<SkTypeface> onMakeFromFile(const char path[], int ttcIndex) const override {
-        SkUniqueCFRef<CGDataProviderRef> pr(CGDataProviderCreateWithFilename(path));
-        if (!pr) {
+        if (ttcIndex != 0) {
             return nullptr;
         }
-        return create_from_dataProvider(std::move(pr), SkFILEStream::Make(path), ttcIndex);
+
+        sk_sp<SkData> data = SkData::MakeFromFileName(path);
+        if (!data) {
+            return nullptr;
+        }
+
+        return this->onMakeFromData(std::move(data), ttcIndex);
     }
 
     sk_sp<SkTypeface> onLegacyMakeTypeface(const char familyName[], SkFontStyle style) const override {
diff --git a/src/utils/mac/SkStream_mac.cpp b/src/utils/mac/SkStream_mac.cpp
index 30f8e1e..b299fce 100644
--- a/src/utils/mac/SkStream_mac.cpp
+++ b/src/utils/mac/SkStream_mac.cpp
@@ -5,79 +5,4 @@
  * found in the LICENSE file.
  */
 
-#include "include/core/SkTypes.h"
-
-#if defined(SK_BUILD_FOR_MAC) || defined(SK_BUILD_FOR_IOS)
-
-#include "include/core/SkStream.h"
-#include "include/private/SkMalloc.h"
-#include "include/utils/mac/SkCGUtils.h"
-
-// These are used by CGDataProviderCreateWithData
-
-static void unref_proc(void* info, const void* addr, size_t size) {
-    SkASSERT(info);
-    ((SkRefCnt*)info)->unref();
-}
-
-static void delete_stream_proc(void* info, const void* addr, size_t size) {
-    SkASSERT(info);
-    SkStream* stream = (SkStream*)info;
-    SkASSERT(stream->getMemoryBase() == addr);
-    SkASSERT(stream->getLength() == size);
-    delete stream;
-}
-
-// These are used by CGDataProviderSequentialCallbacks
-
-static size_t get_bytes_proc(void* info, void* buffer, size_t bytes) {
-    SkASSERT(info);
-    return ((SkStream*)info)->read(buffer, bytes);
-}
-
-static off_t skip_forward_proc(void* info, off_t bytes) {
-    return ((SkStream*)info)->skip((size_t) bytes);
-}
-
-static void rewind_proc(void* info) {
-    SkASSERT(info);
-    ((SkStream*)info)->rewind();
-}
-
-// Used when info is an SkStream.
-static void release_info_proc(void* info) {
-    SkASSERT(info);
-    delete (SkStream*)info;
-}
-
-CGDataProviderRef SkCreateDataProviderFromStream(std::unique_ptr<SkStreamRewindable> stream) {
-    // TODO: Replace with SkStream::getData() when that is added. Then we only
-    // have one version of CGDataProviderCreateWithData (i.e. same release proc)
-    const void* addr = stream->getMemoryBase();
-    if (addr) {
-        // special-case when the stream is just a block of ram
-        size_t size = stream->getLength();
-        return CGDataProviderCreateWithData(stream.release(), addr, size, delete_stream_proc);
-    }
-
-    CGDataProviderSequentialCallbacks rec;
-    sk_bzero(&rec, sizeof(rec));
-    rec.version = 0;
-    rec.getBytes = get_bytes_proc;
-    rec.skipForward = skip_forward_proc;
-    rec.rewind = rewind_proc;
-    rec.releaseInfo = release_info_proc;
-    return CGDataProviderCreateSequential(stream.release(), &rec);
-}
-
-///////////////////////////////////////////////////////////////////////////////
-
-#include "include/core/SkData.h"
-
-CGDataProviderRef SkCreateDataProviderFromData(sk_sp<SkData> data) {
-    const void* addr = data->data();
-    size_t size = data->size();
-    return CGDataProviderCreateWithData(data.release(), addr, size, unref_proc);
-}
-
-#endif//defined(SK_BUILD_FOR_MAC) || defined(SK_BUILD_FOR_IOS)
+// Remove file after it is removed from downstream builds.