/*
 * Copyright 2006 The Android Open Source Project
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "include/core/SkTypes.h"
#if defined(SK_BUILD_FOR_MAC) || defined(SK_BUILD_FOR_IOS)

#ifdef SK_BUILD_FOR_MAC
#import <ApplicationServices/ApplicationServices.h>
#endif

#ifdef SK_BUILD_FOR_IOS
#include <CoreText/CoreText.h>
#include <CoreText/CTFontManager.h>
#include <CoreGraphics/CoreGraphics.h>
#include <CoreFoundation/CoreFoundation.h>
#endif

#include "include/core/SkColor.h"
#include "include/core/SkData.h"
#include "include/core/SkFontArguments.h"
#include "include/core/SkFontParameters.h"
#include "include/core/SkFontStyle.h"
#include "include/core/SkFontTypes.h"
#include "include/core/SkRect.h"
#include "include/core/SkRefCnt.h"
#include "include/core/SkScalar.h"
#include "include/core/SkStream.h"
#include "include/core/SkString.h"
#include "include/core/SkTypeface.h"
#include "include/ports/SkTypeface_mac.h"
#include "include/private/SkFixed.h"
#include "include/private/SkMalloc.h"
#include "include/private/SkMutex.h"
#include "include/private/SkOnce.h"
#include "include/private/SkTDArray.h"
#include "include/private/SkTPin.h"
#include "include/private/SkTemplates.h"
#include "include/private/SkTo.h"
#include "src/core/SkAdvancedTypefaceMetrics.h"
#include "src/core/SkEndian.h"
#include "src/core/SkFontDescriptor.h"
#include "src/core/SkMask.h"
#include "src/core/SkScalerContext.h"
#include "src/core/SkTypefaceCache.h"
#include "src/ports/SkScalerContext_mac_ct.h"
#include "src/ports/SkTypeface_mac_ct.h"
#include "src/sfnt/SkOTTableTypes.h"
#include "src/sfnt/SkOTTable_OS_2.h"
#include "src/sfnt/SkOTTable_OS_2_V4.h"
#include "src/sfnt/SkOTUtils.h"
#include "src/sfnt/SkSFNTHeader.h"
#include "src/utils/SkUTF.h"
#include "src/utils/mac/SkCGBase.h"
#include "src/utils/mac/SkCGGeometry.h"
#include "src/utils/mac/SkCTFont.h"
#include "src/utils/mac/SkUniqueCFRef.h"

#include <dlfcn.h>
#include <limits.h>
#include <string.h>
#include <memory>

/** Assumes src and dst are not nullptr. */
void SkStringFromCFString(CFStringRef src, SkString* dst) {
    // Reserve enough room for the worst-case string,
    // plus 1 byte for the trailing null.
    CFIndex length = CFStringGetMaximumSizeForEncoding(CFStringGetLength(src),
                                                       kCFStringEncodingUTF8) + 1;
    dst->resize(length);
    CFStringGetCString(src, dst->data(), length, kCFStringEncodingUTF8);
    // Resize to the actual UTF-8 length used, stripping the null character.
    dst->resize(strlen(dst->c_str()));
}

SkString SkCFTypeIDDescription(CFTypeID id) {
    SkUniqueCFRef<CFStringRef> typeDescription(CFCopyTypeIDDescription(id));
    SkString skTypeDescription;
    SkStringFromCFString(typeDescription.get(), &skTypeDescription);
    return skTypeDescription;
}

template<typename CF> CFTypeID SkCFGetTypeID();
#define SK_GETCFTYPEID(cf) \
template<> CFTypeID SkCFGetTypeID<cf##Ref>() { return cf##GetTypeID(); }
SK_GETCFTYPEID(CFBoolean);
SK_GETCFTYPEID(CFDictionary);
SK_GETCFTYPEID(CFNumber);

/* Checked dynamic downcast of CFTypeRef.
 *
 * @param cf the ref to downcast.
 * @param cfAsCF if cf can be cast to the type CF, receives the downcast ref.
 * @param name if non-nullptr the cast is expected to succeed and failures will be logged.
 * @return true if the cast succeeds, false otherwise.
 */
template <typename CF>
static bool SkCFDynamicCast(CFTypeRef cf, CF* cfAsCF, char const* name) {
    //SkDEBUGF("SkCFDynamicCast '%s' of type %s to type %s\n", name ? name : "<annon>",
    //         SkCFTypeIDDescription(  CFGetTypeID(cf)  ).c_str()
    //         SkCFTypeIDDescription(SkCFGetTypeID<CF>()).c_str());
    if (!cf) {
        if (name) {
            SkDEBUGF("%s not present\n", name);
        }
        return false;
    }
    if (CFGetTypeID(cf) != SkCFGetTypeID<CF>()) {
        if (name) {
            SkDEBUGF("%s is a %s but expected a %s\n", name,
                     SkCFTypeIDDescription(  CFGetTypeID(cf)  ).c_str(),
                     SkCFTypeIDDescription(SkCFGetTypeID<CF>()).c_str());
        }
        return false;
    }
    *cfAsCF = static_cast<CF>(cf);
    return true;
}

template<typename T> struct SkCFNumberTypeFor {};
#define SK_CFNUMBERTYPE_FOR(c, cf) \
template<> struct SkCFNumberTypeFor<c> : std::integral_constant<CFNumberType, cf> {};
SK_CFNUMBERTYPE_FOR(char     , kCFNumberCharType    );
SK_CFNUMBERTYPE_FOR(short    , kCFNumberShortType   );
SK_CFNUMBERTYPE_FOR(int      , kCFNumberIntType     );
SK_CFNUMBERTYPE_FOR(long     , kCFNumberLongType    );
SK_CFNUMBERTYPE_FOR(long long, kCFNumberLongLongType);
SK_CFNUMBERTYPE_FOR(float    , kCFNumberFloatType   );
SK_CFNUMBERTYPE_FOR(double   , kCFNumberDoubleType  );

template <typename T>
static bool SkCFNumberDynamicCast(CFTypeRef cf, T* number, CFNumberRef* cfNumber, char const* name){
    CFNumberRef cfAsCFNumber;
    if (!SkCFDynamicCast(cf, &cfAsCFNumber, name)) {
        return false;
    }
    if (!CFNumberGetValue(cfAsCFNumber, SkCFNumberTypeFor<T>::value, number)) {
        if (name) {
            SkDEBUGF("%s CFNumber not extractable\n", name);
        }
        return false;
    }
    if (cfNumber) {
        *cfNumber = cfAsCFNumber;
    }
    return true;
}

// In macOS 10.12 and later any variation on the CGFont which has default axis value will be
// dropped when creating the CTFont. Unfortunately, in macOS 10.15 the priority of setting
// the optical size (and opsz variation) is
// 1. the value of kCTFontOpticalSizeAttribute in the CTFontDescriptor (undocumented)
// 2. the opsz axis default value if kCTFontOpticalSizeAttribute is 'none' (undocumented)
// 3. the opsz variation on the nascent CTFont from the CGFont (was dropped if default)
// 4. the opsz variation in kCTFontVariationAttribute in CTFontDescriptor (crashes 10.10)
// 5. the size requested (can fudge in SkTypeface but not SkScalerContext)
// The first one which is found will be used to set the opsz variation (after clamping).
static void add_opsz_attr(CFMutableDictionaryRef attr, double opsz) {
    SkUniqueCFRef<CFNumberRef> opszValueNumber(
        CFNumberCreate(kCFAllocatorDefault, kCFNumberDoubleType, &opsz));
    // Avoid using kCTFontOpticalSizeAttribute directly
    CFStringRef SkCTFontOpticalSizeAttribute = CFSTR("NSCTFontOpticalSizeAttribute");
    CFDictionarySetValue(attr, SkCTFontOpticalSizeAttribute, opszValueNumber.get());
}

// This turns off application of the 'trak' table to advances, but also all other tracking.
static void add_notrak_attr(CFMutableDictionaryRef attr) {
    int zero = 0;
    SkUniqueCFRef<CFNumberRef> unscaledTrackingNumber(
        CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &zero));
    CFStringRef SkCTFontUnscaledTrackingAttribute = CFSTR("NSCTFontUnscaledTrackingAttribute");
    CFDictionarySetValue(attr, SkCTFontUnscaledTrackingAttribute, unscaledTrackingNumber.get());
}

SkUniqueCFRef<CTFontRef> SkCTFontCreateExactCopy(CTFontRef baseFont, CGFloat textSize,
                                                 OpszVariation opszVariation)
{
    SkUniqueCFRef<CFMutableDictionaryRef> attr(
    CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
                              &kCFTypeDictionaryKeyCallBacks,
                              &kCFTypeDictionaryValueCallBacks));

    if (opszVariation.isSet) {
        add_opsz_attr(attr.get(), opszVariation.value);
    } else {
        // On (at least) 10.10 though 10.14 the default system font was SFNSText/SFNSDisplay.
        // The CTFont is backed by both; optical size < 20 means SFNSText else SFNSDisplay.
        // On at least 10.11 the glyph ids in these fonts became non-interchangable.
        // To keep glyph ids stable over size changes, preserve the optical size.
        // In 10.15 this was replaced with use of variable fonts with an opsz axis.
        // A CTFont backed by multiple fonts picked by opsz where the multiple backing fonts are
        // variable fonts with opsz axis and non-interchangeable glyph ids would break the
        // opsz.isSet branch above, but hopefully that never happens.
        // See https://crbug.com/524646 .
        CFStringRef SkCTFontOpticalSizeAttribute = CFSTR("NSCTFontOpticalSizeAttribute");
        SkUniqueCFRef<CFTypeRef> opsz(CTFontCopyAttribute(baseFont, SkCTFontOpticalSizeAttribute));
        double opsz_val;
        if (!opsz ||
            CFGetTypeID(opsz.get()) != CFNumberGetTypeID() ||
            !CFNumberGetValue(static_cast<CFNumberRef>(opsz.get()),kCFNumberDoubleType,&opsz_val) ||
            opsz_val <= 0)
        {
            opsz_val = CTFontGetSize(baseFont);
        }
        add_opsz_attr(attr.get(), opsz_val);
    }
    add_notrak_attr(attr.get());

    SkUniqueCFRef<CTFontDescriptorRef> desc(CTFontDescriptorCreateWithAttributes(attr.get()));

    return SkUniqueCFRef<CTFontRef>(
            CTFontCreateCopyWithAttributes(baseFont, textSize, nullptr, desc.get()));
}

CTFontRef SkTypeface_GetCTFontRef(const SkTypeface* face) {
    return face ? (CTFontRef)face->internal_private_getCTFontRef() : nullptr;
}

static bool find_by_CTFontRef(SkTypeface* cached, void* context) {
    CTFontRef self = (CTFontRef)context;
    CTFontRef other = (CTFontRef)cached->internal_private_getCTFontRef();

    return CFEqual(self, other);
}

/** Creates a typeface, searching the cache if providedData is nullptr. */
sk_sp<SkTypeface> SkTypeface_Mac::Make(SkUniqueCFRef<CTFontRef> font,
                                       OpszVariation opszVariation,
                                       std::unique_ptr<SkStreamAsset> providedData) {
    static SkMutex gTFCacheMutex;
    static SkTypefaceCache gTFCache;

    SkASSERT(font);
    const bool isFromStream(providedData);

    auto makeTypeface = [&]() {
        SkUniqueCFRef<CTFontDescriptorRef> desc(CTFontCopyFontDescriptor(font.get()));
        SkFontStyle style = SkCTFontDescriptorGetSkFontStyle(desc.get(), isFromStream);
        CTFontSymbolicTraits traits = CTFontGetSymbolicTraits(font.get());
        bool isFixedPitch = SkToBool(traits & kCTFontMonoSpaceTrait);

        return sk_sp<SkTypeface>(new SkTypeface_Mac(std::move(font), style, isFixedPitch,
                                                    opszVariation, std::move(providedData)));
    };

    if (isFromStream) {
        return makeTypeface();
    }

    SkAutoMutexExclusive ama(gTFCacheMutex);
    sk_sp<SkTypeface> face = gTFCache.findByProcAndRef(find_by_CTFontRef, (void*)font.get());
    if (!face) {
        face = makeTypeface();
        if (face) {
            gTFCache.add(face);
        }
    }
    return face;
}

/*  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).
 */
sk_sp<SkTypeface> SkMakeTypefaceFromCTFont(CTFontRef font) {
    CFRetain(font);
    return SkTypeface_Mac::Make(SkUniqueCFRef<CTFontRef>(font),
                                OpszVariation(),
                                nullptr);
}

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);
}

template <typename S, typename D, typename C> struct LinearInterpolater {
    struct Mapping {
        S src_val;
        D dst_val;
    };
    constexpr LinearInterpolater(Mapping const mapping[], int mappingCount)
        : fMapping(mapping), fMappingCount(mappingCount) {}

    static D map(S value, S src_min, S src_max, D dst_min, D dst_max) {
        SkASSERT(src_min < src_max);
        SkASSERT(dst_min <= dst_max);
        return C()(dst_min + (((value - src_min) * (dst_max - dst_min)) / (src_max - src_min)));
    }

    D map(S val) const {
        // -Inf to [0]
        if (val < fMapping[0].src_val) {
            return fMapping[0].dst_val;
        }

        // Linear from [i] to [i+1]
        for (int i = 0; i < fMappingCount - 1; ++i) {
            if (val < fMapping[i+1].src_val) {
                return map(val, fMapping[i].src_val, fMapping[i+1].src_val,
                                fMapping[i].dst_val, fMapping[i+1].dst_val);
            }
        }

        // From [n] to +Inf
        // if (fcweight < Inf)
        return fMapping[fMappingCount - 1].dst_val;
    }

    Mapping const * fMapping;
    int fMappingCount;
};

struct RoundCGFloatToInt {
    int operator()(CGFloat s) { return s + 0.5; }
};
struct CGFloatIdentity {
    CGFloat operator()(CGFloat s) { return s; }
};

/** Convert the [0, 1000] CSS weight to [-1, 1] CTFontDescriptor weight (for system fonts).
 *
 *  The -1 to 1 weights reported by CTFontDescriptors have different mappings depending on if the
 *  CTFont is native or created from a CGDataProvider.
 */
CGFloat SkCTFontCTWeightForCSSWeight(int fontstyleWeight) {
    using Interpolator = LinearInterpolater<int, CGFloat, CGFloatIdentity>;

    // Note that Mac supports the old OS2 version A so 0 through 10 are as if multiplied by 100.
    // However, on this end we can't tell, so this is ignored.

    static Interpolator::Mapping nativeWeightMappings[11];
    static SkOnce once;
    once([&] {
        const CGFloat(&nsFontWeights)[11] = SkCTFontGetNSFontWeightMapping();
        for (int i = 0; i < 11; ++i) {
            nativeWeightMappings[i].src_val = i * 100;
            nativeWeightMappings[i].dst_val = nsFontWeights[i];
        }
    });
    static constexpr Interpolator nativeInterpolator(
            nativeWeightMappings, std::size(nativeWeightMappings));

    return nativeInterpolator.map(fontstyleWeight);
}

/** Convert the [-1, 1] CTFontDescriptor weight to [0, 1000] CSS weight.
 *
 *  The -1 to 1 weights reported by CTFontDescriptors have different mappings depending on if the
 *  CTFont is native or created from a CGDataProvider.
 */
static int ct_weight_to_fontstyle(CGFloat cgWeight, bool fromDataProvider) {
    using Interpolator = LinearInterpolater<CGFloat, int, RoundCGFloatToInt>;

    // Note that Mac supports the old OS2 version A so 0 through 10 are as if multiplied by 100.
    // However, on this end we can't tell, so this is ignored.

    static Interpolator::Mapping nativeWeightMappings[11];
    static Interpolator::Mapping dataProviderWeightMappings[11];
    static SkOnce once;
    once([&] {
        const CGFloat(&nsFontWeights)[11] = SkCTFontGetNSFontWeightMapping();
        const CGFloat(&userFontWeights)[11] = SkCTFontGetDataFontWeightMapping();
        for (int i = 0; i < 11; ++i) {
            nativeWeightMappings[i].src_val = nsFontWeights[i];
            nativeWeightMappings[i].dst_val = i * 100;

            dataProviderWeightMappings[i].src_val = userFontWeights[i];
            dataProviderWeightMappings[i].dst_val = i * 100;
        }
    });
    static constexpr Interpolator nativeInterpolator(
            nativeWeightMappings, std::size(nativeWeightMappings));
    static constexpr Interpolator dataProviderInterpolator(
            dataProviderWeightMappings, std::size(dataProviderWeightMappings));

    return fromDataProvider ? dataProviderInterpolator.map(cgWeight)
                            : nativeInterpolator.map(cgWeight);
}

/** Convert the [0, 10] CSS weight to [-1, 1] CTFontDescriptor width. */
CGFloat SkCTFontCTWidthForCSSWidth(int fontstyleWidth) {
    using Interpolator = LinearInterpolater<int, CGFloat, CGFloatIdentity>;

    // Values determined by creating font data with every width, creating a CTFont,
    // and asking the CTFont for its width. See TypefaceStyle test for basics.
    static constexpr Interpolator::Mapping widthMappings[] = {
        {  0, -0.5 },
        { 10,  0.5 },
    };
    static constexpr Interpolator interpolator(widthMappings, std::size(widthMappings));
    return interpolator.map(fontstyleWidth);
}

/** Convert the [-1, 1] CTFontDescriptor width to [0, 10] CSS weight. */
static int ct_width_to_fontstyle(CGFloat cgWidth) {
    using Interpolator = LinearInterpolater<CGFloat, int, RoundCGFloatToInt>;

    // Values determined by creating font data with every width, creating a CTFont,
    // and asking the CTFont for its width. See TypefaceStyle test for basics.
    static constexpr Interpolator::Mapping widthMappings[] = {
        { -0.5,  0 },
        {  0.5, 10 },
    };
    static constexpr Interpolator interpolator(widthMappings, std::size(widthMappings));
    return interpolator.map(cgWidth);
}

SkFontStyle SkCTFontDescriptorGetSkFontStyle(CTFontDescriptorRef desc, bool fromDataProvider) {
    SkUniqueCFRef<CFTypeRef> traits(CTFontDescriptorCopyAttribute(desc, kCTFontTraitsAttribute));
    CFDictionaryRef fontTraitsDict;
    if (!SkCFDynamicCast(traits.get(), &fontTraitsDict, "Font traits")) {
        return SkFontStyle();
    }

    CGFloat weight, width, slant;
    if (!find_dict_CGFloat(fontTraitsDict, kCTFontWeightTrait, &weight)) {
        weight = 0;
    }
    if (!find_dict_CGFloat(fontTraitsDict, kCTFontWidthTrait, &width)) {
        width = 0;
    }
    if (!find_dict_CGFloat(fontTraitsDict, kCTFontSlantTrait, &slant)) {
        slant = 0;
    }

    return SkFontStyle(ct_weight_to_fontstyle(weight, fromDataProvider),
                       ct_width_to_fontstyle(width),
                       slant ? SkFontStyle::kItalic_Slant
                             : SkFontStyle::kUpright_Slant);
}


// 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,
                                           SkUnichar* out) {
    sk_bzero(out, glyphCount * sizeof(SkUnichar));
    UniChar unichar = 0;
    while (glyphCount > 0) {
        CGGlyph glyph;
        if (CTFontGetGlyphsForCharacters(ctFont, &unichar, &glyph, 1)) {
            if (out[glyph] == 0) {
                out[glyph] = unichar;
                --glyphCount;
            }
        }
        if (++unichar == 0) {
            break;
        }
    }
}

static constexpr uint16_t kPlaneSize = 1 << 13;

static void get_plane_glyph_map(const uint8_t* bits,
                                CTFontRef ctFont,
                                CFIndex glyphCount,
                                SkUnichar* glyphToUnicode,
                                uint8_t planeIndex) {
    SkUnichar planeOrigin = (SkUnichar)planeIndex << 16; // top half of codepoint.
    for (uint16_t i = 0; i < kPlaneSize; i++) {
        uint8_t mask = bits[i];
        if (!mask) {
            continue;
        }
        for (uint8_t j = 0; j < 8; j++) {
            if (0 == (mask & ((uint8_t)1 << j))) {
                continue;
            }
            uint16_t planeOffset = (i << 3) | j;
            SkUnichar codepoint = planeOrigin | (SkUnichar)planeOffset;
            uint16_t utf16[2] = {planeOffset, 0};
            size_t count = 1;
            if (planeOrigin != 0) {
                count = SkUTF::ToUTF16(codepoint, utf16);
            }
            CGGlyph glyphs[2] = {0, 0};
            if (CTFontGetGlyphsForCharacters(ctFont, utf16, glyphs, count)) {
                SkASSERT(glyphs[1] == 0);
                SkASSERT(glyphs[0] < glyphCount);
                // CTFontCopyCharacterSet and CTFontGetGlyphsForCharacters seem to add 'support'
                // for characters 0x9, 0xA, and 0xD mapping them to the glyph for character 0x20?
                // Prefer mappings to codepoints at or above 0x20.
                if (glyphToUnicode[glyphs[0]] < 0x20) {
                    glyphToUnicode[glyphs[0]] = codepoint;
                }
            }
        }
    }
}
// Construct Glyph to Unicode table.
static void populate_glyph_to_unicode(CTFontRef ctFont, CFIndex glyphCount,
                                      SkUnichar* glyphToUnicode) {
    sk_bzero(glyphToUnicode, sizeof(SkUnichar) * glyphCount);
    SkUniqueCFRef<CFCharacterSetRef> charSet(CTFontCopyCharacterSet(ctFont));
    if (!charSet) {
        populate_glyph_to_unicode_slow(ctFont, glyphCount, glyphToUnicode);
        return;
    }

    SkUniqueCFRef<CFDataRef> bitmap(
            CFCharacterSetCreateBitmapRepresentation(nullptr, charSet.get()));
    if (!bitmap) {
        return;
    }
    CFIndex dataLength = CFDataGetLength(bitmap.get());
    if (!dataLength) {
        return;
    }
    SkASSERT(dataLength >= kPlaneSize);
    const UInt8* bits = CFDataGetBytePtr(bitmap.get());

    get_plane_glyph_map(bits, ctFont, glyphCount, glyphToUnicode, 0);
    /*
    A CFData object that specifies the bitmap representation of the Unicode
    character points the for the new character set. The bitmap representation could
    contain all the Unicode character range starting from BMP to Plane 16. The
    first 8KiB (8192 bytes) of the data represent the BMP range. The BMP range 8KiB
    can be followed by zero to sixteen 8KiB bitmaps, each prepended with the plane
    index byte. For example, the bitmap representing the BMP and Plane 2 has the
    size of 16385 bytes (8KiB for BMP, 1 byte index, and a 8KiB bitmap for Plane
    2). The plane index byte, in this case, contains the integer value two.
    */

    if (dataLength <= kPlaneSize) {
        return;
    }
    int extraPlaneCount = (dataLength - kPlaneSize) / (1 + kPlaneSize);
    SkASSERT(dataLength == kPlaneSize + extraPlaneCount * (1 + kPlaneSize));
    while (extraPlaneCount-- > 0) {
        bits += kPlaneSize;
        uint8_t planeIndex = *bits++;
        SkASSERT(planeIndex >= 1);
        SkASSERT(planeIndex <= 16);
        get_plane_glyph_map(bits, ctFont, glyphCount, glyphToUnicode, planeIndex);
    }
}

void SkTypeface_Mac::getGlyphToUnicodeMap(SkUnichar* dstArray) const {
    SkUniqueCFRef<CTFontRef> ctFont =
            SkCTFontCreateExactCopy(fFontRef.get(), CTFontGetUnitsPerEm(fFontRef.get()),
                                    fOpszVariation);
    CFIndex glyphCount = CTFontGetGlyphCount(ctFont.get());
    populate_glyph_to_unicode(ctFont.get(), glyphCount, dstArray);
}

std::unique_ptr<SkAdvancedTypefaceMetrics> SkTypeface_Mac::onGetAdvancedMetrics() const {

    SkUniqueCFRef<CTFontRef> ctFont =
            SkCTFontCreateExactCopy(fFontRef.get(), CTFontGetUnitsPerEm(fFontRef.get()),
                                    fOpszVariation);

    std::unique_ptr<SkAdvancedTypefaceMetrics> info(new SkAdvancedTypefaceMetrics);

    {
        SkUniqueCFRef<CFStringRef> fontName(CTFontCopyPostScriptName(ctFont.get()));
        if (fontName.get()) {
            SkStringFromCFString(fontName.get(), &info->fPostScriptName);
            info->fFontName = info->fPostScriptName;
        }
    }

    CFArrayRef ctAxes = this->getVariationAxes();
    if (ctAxes && CFArrayGetCount(ctAxes) > 0) {
        info->fFlags |= SkAdvancedTypefaceMetrics::kVariable_FontFlag;
    }

    SkOTTableOS2_V4::Type fsType;
    if (sizeof(fsType) == this->getTableData(SkTEndian_SwapBE32(SkOTTableOS2::TAG),
                                             offsetof(SkOTTableOS2_V4, fsType),
                                             sizeof(fsType),
                                             &fsType)) {
        SkOTUtils::SetAdvancedTypefaceFlags(fsType, info.get());
    }

    // If it's not a truetype font, mark it as 'other'. Assume that TrueType
    // fonts always have both glyf and loca tables. At the least, this is what
    // sfntly needs to subset the font. CTFontCopyAttribute() does not always
    // succeed in determining this directly.
    if (!this->getTableSize(SkSetFourByteTag('g','l','y','f')) ||
        !this->getTableSize(SkSetFourByteTag('l','o','c','a')))
    {
        return info;
    }

    info->fType = SkAdvancedTypefaceMetrics::kTrueType_Font;
    CTFontSymbolicTraits symbolicTraits = CTFontGetSymbolicTraits(ctFont.get());
    if (symbolicTraits & kCTFontMonoSpaceTrait) {
        info->fStyle |= SkAdvancedTypefaceMetrics::kFixedPitch_Style;
    }
    if (symbolicTraits & kCTFontItalicTrait) {
        info->fStyle |= SkAdvancedTypefaceMetrics::kItalic_Style;
    }
    CTFontStylisticClass stylisticClass = symbolicTraits & kCTFontClassMaskTrait;
    if (stylisticClass >= kCTFontOldStyleSerifsClass && stylisticClass <= kCTFontSlabSerifsClass) {
        info->fStyle |= SkAdvancedTypefaceMetrics::kSerif_Style;
    } else if (stylisticClass & kCTFontScriptsClass) {
        info->fStyle |= SkAdvancedTypefaceMetrics::kScript_Style;
    }
    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.setLTRB(SkScalarFromCGFloat(SkCGRectGetMinX(bbox)),   // Left
              SkScalarFromCGFloat(SkCGRectGetMaxY(bbox)),   // Top
              SkScalarFromCGFloat(SkCGRectGetMaxX(bbox)),   // Right
              SkScalarFromCGFloat(SkCGRectGetMinY(bbox)));  // Bottom

    r.roundOut(&(info->fBBox));

    // Figure out a good guess for StemV - Min width of i, I, !, 1.
    // This probably isn't very good with an italic font.
    int16_t min_width = SHRT_MAX;
    info->fStemV = 0;
    static const UniChar stem_chars[] = {'i', 'I', '!', '1'};
    const size_t count = sizeof(stem_chars) / sizeof(stem_chars[0]);
    CGGlyph glyphs[count];
    CGRect boundingRects[count];
    if (CTFontGetGlyphsForCharacters(ctFont.get(), stem_chars, glyphs, count)) {
        CTFontGetBoundingRectsForGlyphs(ctFont.get(), kCTFontOrientationHorizontal,
                                        glyphs, boundingRects, count);
        for (size_t i = 0; i < count; i++) {
            int16_t width = (int16_t) boundingRects[i].size.width;
            if (width > 0 && width < min_width) {
                min_width = width;
                info->fStemV = min_width;
            }
        }
    }
    return info;
}

static SK_SFNT_ULONG get_font_type_tag(CTFontRef ctFont) {
    SkUniqueCFRef<CFNumberRef> fontFormatRef(
            static_cast<CFNumberRef>(CTFontCopyAttribute(ctFont, kCTFontFormatAttribute)));
    if (!fontFormatRef) {
        return 0;
    }

    SInt32 fontFormatValue;
    if (!CFNumberGetValue(fontFormatRef.get(), kCFNumberSInt32Type, &fontFormatValue)) {
        return 0;
    }

    switch (fontFormatValue) {
        case kCTFontFormatOpenTypePostScript:
            return SkSFNTHeader::fontType_OpenTypeCFF::TAG;
        case kCTFontFormatOpenTypeTrueType:
            return SkSFNTHeader::fontType_WindowsTrueType::TAG;
        case kCTFontFormatTrueType:
            return SkSFNTHeader::fontType_MacTrueType::TAG;
        case kCTFontFormatPostScript:
            return SkSFNTHeader::fontType_PostScript::TAG;
        case kCTFontFormatBitmap:
            return SkSFNTHeader::fontType_MacTrueType::TAG;
        case kCTFontFormatUnrecognized:
        default:
            return 0;
    }
}

std::unique_ptr<SkStreamAsset> SkTypeface_Mac::onOpenStream(int* ttcIndex) const {
    *ttcIndex = 0;

    fInitStream([this]{
    if (fStream) {
        return;
    }

    SK_SFNT_ULONG fontType = get_font_type_tag(fFontRef.get());

    // get table tags
    int numTables = this->countTables();
    SkTDArray<SkFontTableTag> tableTags;
    tableTags.resize(numTables);
    this->getTableTags(tableTags.begin());

    // CT seems to be unreliable in being able to obtain the type,
    // even if all we want is the first four bytes of the font resource.
    // Just the presence of the FontForge 'FFTM' table seems to throw it off.
    if (fontType == 0) {
        fontType = SkSFNTHeader::fontType_WindowsTrueType::TAG;

        // see https://skbug.com/7630#c7
        bool couldBeCFF = false;
        constexpr SkFontTableTag CFFTag = SkSetFourByteTag('C', 'F', 'F', ' ');
        constexpr SkFontTableTag CFF2Tag = SkSetFourByteTag('C', 'F', 'F', '2');
        for (int tableIndex = 0; tableIndex < numTables; ++tableIndex) {
            if (CFFTag == tableTags[tableIndex] || CFF2Tag == tableTags[tableIndex]) {
                couldBeCFF = true;
            }
        }
        if (couldBeCFF) {
            fontType = SkSFNTHeader::fontType_OpenTypeCFF::TAG;
        }
    }

    // Sometimes CoreGraphics incorrectly thinks a font is kCTFontFormatPostScript.
    // It is exceedingly unlikely that this is the case, so double check
    // (see https://crbug.com/809763 ).
    if (fontType == SkSFNTHeader::fontType_PostScript::TAG) {
        // see if there are any required 'typ1' tables (see Adobe Technical Note #5180)
        bool couldBeTyp1 = false;
        constexpr SkFontTableTag TYPE1Tag = SkSetFourByteTag('T', 'Y', 'P', '1');
        constexpr SkFontTableTag CIDTag = SkSetFourByteTag('C', 'I', 'D', ' ');
        for (int tableIndex = 0; tableIndex < numTables; ++tableIndex) {
            if (TYPE1Tag == tableTags[tableIndex] || CIDTag == tableTags[tableIndex]) {
                couldBeTyp1 = true;
            }
        }
        if (!couldBeTyp1) {
            fontType = SkSFNTHeader::fontType_OpenTypeCFF::TAG;
        }
    }

    // get the table sizes and accumulate the total size of the font
    SkTDArray<size_t> tableSizes;
    size_t totalSize = sizeof(SkSFNTHeader) + sizeof(SkSFNTHeader::TableDirectoryEntry) * numTables;
    for (int tableIndex = 0; tableIndex < numTables; ++tableIndex) {
        size_t tableSize = this->getTableSize(tableTags[tableIndex]);
        totalSize += (tableSize + 3) & ~3;
        *tableSizes.append() = tableSize;
    }

    // reserve memory for stream, and zero it (tables must be zero padded)
    fStream = std::make_unique<SkMemoryStream>(totalSize);
    char* dataStart = (char*)fStream->getMemoryBase();
    sk_bzero(dataStart, totalSize);
    char* dataPtr = dataStart;

    // compute font header entries
    uint16_t entrySelector = 0;
    uint16_t searchRange = 1;
    while (searchRange < numTables >> 1) {
        entrySelector++;
        searchRange <<= 1;
    }
    searchRange <<= 4;
    uint16_t rangeShift = (numTables << 4) - searchRange;

    // write font header
    SkSFNTHeader* header = (SkSFNTHeader*)dataPtr;
    header->fontType = fontType;
    header->numTables = SkEndian_SwapBE16(numTables);
    header->searchRange = SkEndian_SwapBE16(searchRange);
    header->entrySelector = SkEndian_SwapBE16(entrySelector);
    header->rangeShift = SkEndian_SwapBE16(rangeShift);
    dataPtr += sizeof(SkSFNTHeader);

    // write tables
    SkSFNTHeader::TableDirectoryEntry* entry = (SkSFNTHeader::TableDirectoryEntry*)dataPtr;
    dataPtr += sizeof(SkSFNTHeader::TableDirectoryEntry) * numTables;
    for (int tableIndex = 0; tableIndex < numTables; ++tableIndex) {
        size_t tableSize = tableSizes[tableIndex];
        this->getTableData(tableTags[tableIndex], 0, tableSize, dataPtr);
        entry->tag = SkEndian_SwapBE32(tableTags[tableIndex]);
        entry->checksum = SkEndian_SwapBE32(SkOTUtils::CalcTableChecksum((SK_OT_ULONG*)dataPtr,
                                                                         tableSize));
        entry->offset = SkEndian_SwapBE32(SkToU32(dataPtr - dataStart));
        entry->logicalLength = SkEndian_SwapBE32(SkToU32(tableSize));

        dataPtr += (tableSize + 3) & ~3;
        ++entry;
    }
    });
    return fStream->duplicate();
}

std::unique_ptr<SkStreamAsset> SkTypeface_Mac::onOpenExistingStream(int* ttcIndex) const {
    *ttcIndex = 0;
    return fStream ? fStream->duplicate() : nullptr;
}

bool SkTypeface_Mac::onGlyphMaskNeedsCurrentColor() const {
    // `CPAL` (`COLR` and `SVG`) fonts may need the current color.
    // However, even `sbix` fonts can have glyphs which need the current color.
    // These may be glyphs with paths but no `sbix` entries, which are impossible to distinguish.
    return this->fHasColorGlyphs;
}

CFArrayRef SkTypeface_Mac::getVariationAxes() const {
    fInitVariationAxes([this]{
        fVariationAxes.reset(CTFontCopyVariationAxes(fFontRef.get()));
    });
    return fVariationAxes.get();
}

int SkTypeface_Mac::onGetVariationDesignPosition(
        SkFontArguments::VariationPosition::Coordinate coordinates[], int coordinateCount) const
{
    CFArrayRef ctAxes = this->getVariationAxes();
    if (!ctAxes) {
        return -1;
    }
    CFIndex axisCount = CFArrayGetCount(ctAxes);
    if (!coordinates || coordinateCount < axisCount) {
        return axisCount;
    }

    // On 10.12 and later, this only returns non-default variations.
    SkUniqueCFRef<CFDictionaryRef> ctVariation(CTFontCopyVariation(fFontRef.get()));
    if (!ctVariation) {
        return -1;
    }

    for (int i = 0; i < axisCount; ++i) {
        CFDictionaryRef axisInfoDict;
        if (!SkCFDynamicCast(CFArrayGetValueAtIndex(ctAxes, i), &axisInfoDict, "Axis")) {
            return -1;
        }

        int64_t tagLong;
        CFNumberRef tagNumber;
        CFTypeRef tag = CFDictionaryGetValue(axisInfoDict, kCTFontVariationAxisIdentifierKey);
        if (!SkCFNumberDynamicCast(tag, &tagLong, &tagNumber, "Axis tag")) {
            return -1;
        }
        coordinates[i].axis = tagLong;

        CGFloat valueCGFloat;
        CFTypeRef value = CFDictionaryGetValue(ctVariation.get(), tagNumber);
        if (value) {
            if (!SkCFNumberDynamicCast(value, &valueCGFloat, nullptr, "Variation value")) {
                return -1;
            }
        } else {
            CFTypeRef def = CFDictionaryGetValue(axisInfoDict, kCTFontVariationAxisDefaultValueKey);
            if (!SkCFNumberDynamicCast(def, &valueCGFloat, nullptr, "Axis default value")) {
                return -1;
            }
        }
        coordinates[i].value = SkScalarFromCGFloat(valueCGFloat);
    }
    return axisCount;
}

int SkTypeface_Mac::onGetUPEM() const {
    SkUniqueCFRef<CGFontRef> cgFont(CTFontCopyGraphicsFont(fFontRef.get(), nullptr));
    return CGFontGetUnitsPerEm(cgFont.get());
}

SkTypeface::LocalizedStrings* SkTypeface_Mac::onCreateFamilyNameIterator() const {
    sk_sp<SkTypeface::LocalizedStrings> nameIter =
            SkOTUtils::LocalizedStrings_NameTable::MakeForFamilyNames(*this);
    if (!nameIter) {
        CFStringRef cfLanguageRaw;
        SkUniqueCFRef<CFStringRef> cfFamilyName(
                CTFontCopyLocalizedName(fFontRef.get(), kCTFontFamilyNameKey, &cfLanguageRaw));
        SkUniqueCFRef<CFStringRef> cfLanguage(cfLanguageRaw);

        SkString skLanguage;
        SkString skFamilyName;
        if (cfLanguage) {
            SkStringFromCFString(cfLanguage.get(), &skLanguage);
        } else {
            skLanguage = "und"; //undetermined
        }
        if (cfFamilyName) {
            SkStringFromCFString(cfFamilyName.get(), &skFamilyName);
        }

        nameIter = sk_make_sp<SkOTUtils::LocalizedStrings_SingleName>(skFamilyName, skLanguage);
    }
    return nameIter.release();
}

int SkTypeface_Mac::onGetTableTags(SkFontTableTag tags[]) const {
    SkUniqueCFRef<CFArrayRef> cfArray(
            CTFontCopyAvailableTables(fFontRef.get(), kCTFontTableOptionNoOptions));
    if (!cfArray) {
        return 0;
    }
    CFIndex count = CFArrayGetCount(cfArray.get());
    if (tags) {
        for (CFIndex i = 0; i < count; ++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 SkUniqueCFRef<CFDataRef> copy_table_from_font(CTFontRef ctFont, SkFontTableTag tag) {
    SkUniqueCFRef<CFDataRef> data(CTFontCopyTable(ctFont, (CTFontTableTag) tag,
                                                  kCTFontTableOptionNoOptions));
    if (!data) {
        SkUniqueCFRef<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 {
    SkUniqueCFRef<CFDataRef> srcData = copy_table_from_font(fFontRef.get(), tag);
    if (!srcData) {
        return 0;
    }

    size_t srcSize = CFDataGetLength(srcData.get());
    if (offset >= srcSize) {
        return 0;
    }
    if (length > srcSize - offset) {
        length = srcSize - offset;
    }
    if (dstData) {
        memcpy(dstData, CFDataGetBytePtr(srcData.get()) + offset, length);
    }
    return length;
}

sk_sp<SkData> SkTypeface_Mac::onCopyTableData(SkFontTableTag tag) const {
    SkUniqueCFRef<CFDataRef> srcData = copy_table_from_font(fFontRef.get(), tag);
    if (!srcData) {
        return nullptr;
    }
    const UInt8* data = CFDataGetBytePtr(srcData.get());
    CFIndex length = CFDataGetLength(srcData.get());
    return SkData::MakeWithProc(data, length,
                                [](const void*, void* ctx) {
                                    CFRelease((CFDataRef)ctx);
                                }, (void*)srcData.release());
}

std::unique_ptr<SkScalerContext> SkTypeface_Mac::onCreateScalerContext(
    const SkScalerContextEffects& effects, const SkDescriptor* desc) const
{
    return std::make_unique<SkScalerContext_Mac>(
            sk_ref_sp(const_cast<SkTypeface_Mac*>(this)), effects, desc);
}

void SkTypeface_Mac::onFilterRec(SkScalerContextRec* rec) const {
    if (rec->fFlags & SkScalerContext::kLCD_BGROrder_Flag ||
        rec->fFlags & SkScalerContext::kLCD_Vertical_Flag)
    {
        rec->fMaskFormat = SkMask::kA8_Format;
        // Render the glyphs as close as possible to what was requested.
        // The above turns off subpixel rendering, but the user requested it.
        // Normal hinting will cause the A8 masks to be generated from CoreGraphics subpixel masks.
        // See comments below for more details.
        rec->setHinting(SkFontHinting::kNormal);
    }

    unsigned flagsWeDontSupport = SkScalerContext::kForceAutohinting_Flag  |
                                  SkScalerContext::kLCD_BGROrder_Flag |
                                  SkScalerContext::kLCD_Vertical_Flag;

    rec->fFlags &= ~flagsWeDontSupport;

    const SkCTFontSmoothBehavior smoothBehavior = SkCTFontGetSmoothBehavior();

    // Only two levels of hinting are supported.
    // kNo_Hinting means avoid CoreGraphics outline dilation (smoothing).
    // kNormal_Hinting means CoreGraphics outline dilation (smoothing) is allowed.
    if (rec->getHinting() != SkFontHinting::kNone) {
        rec->setHinting(SkFontHinting::kNormal);
    }
    // If smoothing has no effect, don't request it.
    if (smoothBehavior == SkCTFontSmoothBehavior::none) {
        rec->setHinting(SkFontHinting::kNone);
    }

    // FIXME: lcd smoothed un-hinted rasterization unsupported.
    // Tracked by http://code.google.com/p/skia/issues/detail?id=915 .
    // There is no current means to honor a request for unhinted lcd,
    // so arbitrarilly ignore the hinting request and honor lcd.

    // Hinting and smoothing should be orthogonal, but currently they are not.
    // CoreGraphics has no API to influence hinting. However, its lcd smoothed
    // output is drawn from auto-dilated outlines (the amount of which is
    // determined by AppleFontSmoothing). Its regular anti-aliased output is
    // drawn from un-dilated outlines.

    // The behavior of Skia is as follows:
    // [AA][no-hint]: generate AA using CoreGraphic's AA output.
    // [AA][yes-hint]: use CoreGraphic's LCD output and reduce it to a single
    // channel. This matches [LCD][yes-hint] in weight.
    // [LCD][no-hint]: currently unable to honor, and must pick which to respect.
    // Currently side with LCD, effectively ignoring the hinting setting.
    // [LCD][yes-hint]: generate LCD using CoreGraphic's LCD output.
    if (rec->fMaskFormat == SkMask::kLCD16_Format) {
        if (smoothBehavior == SkCTFontSmoothBehavior::subpixel) {
            //CoreGraphics creates 555 masks for smoothed text anyway.
            rec->fMaskFormat = SkMask::kLCD16_Format;
            rec->setHinting(SkFontHinting::kNormal);
        } else {
            rec->fMaskFormat = SkMask::kA8_Format;
            if (smoothBehavior != SkCTFontSmoothBehavior::none) {
                rec->setHinting(SkFontHinting::kNormal);
            }
        }
    }

    // CoreText provides no information as to whether a glyph will be color or not.
    // Fonts may mix outlines and bitmaps, so information is needed on a glyph by glyph basis.
    // If a font contains an 'sbix' table, consider it to be a color font, and disable lcd.
    if (fHasColorGlyphs) {
        rec->fMaskFormat = SkMask::kARGB32_Format;
    }

    // Unhinted A8 masks (those not derived from LCD masks) must respect SK_GAMMA_APPLY_TO_A8.
    // All other masks can use regular gamma.
    if (SkMask::kA8_Format == rec->fMaskFormat && SkFontHinting::kNone == rec->getHinting()) {
#ifndef SK_GAMMA_APPLY_TO_A8
        // SRGBTODO: Is this correct? Do we want contrast boost?
        rec->ignorePreBlend();
#endif
    } else {
        SkColor color = rec->getLuminanceColor();
        if (smoothBehavior == SkCTFontSmoothBehavior::some) {
            // CoreGraphics smoothed text without subpixel coverage blitting goes from a gamma of
            // 2.0 for black foreground to a gamma of 1.0 for white foreground. Emulate this
            // through the mask gamma by reducing the color values to 1/2.
            color = SkColorSetRGB(SkColorGetR(color) * 1/2,
                                  SkColorGetG(color) * 1/2,
                                  SkColorGetB(color) * 1/2);
        } else if (smoothBehavior == SkCTFontSmoothBehavior::subpixel) {
            // CoreGraphics smoothed text with subpixel coverage blitting goes from a gamma of
            // 2.0 for black foreground to a gamma of ~1.4? for white foreground. Emulate this
            // through the mask gamma by reducing the color values to 3/4.
            color = SkColorSetRGB(SkColorGetR(color) * 3/4,
                                  SkColorGetG(color) * 3/4,
                                  SkColorGetB(color) * 3/4);
        }
        rec->setLuminanceColor(color);

        // CoreGraphics dialates smoothed text to provide contrast.
        rec->setContrast(0);
    }
}

/** Takes ownership of the CFStringRef. */
static const char* get_str(CFStringRef ref, SkString* str) {
    if (nullptr == ref) {
        return nullptr;
    }
    SkStringFromCFString(ref, str);
    CFRelease(ref);
    return str->c_str();
}

void SkTypeface_Mac::onGetFamilyName(SkString* familyName) const {
    get_str(CTFontCopyFamilyName(fFontRef.get()), familyName);
}

bool SkTypeface_Mac::onGetPostScriptName(SkString* skPostScriptName) const {
    SkUniqueCFRef<CFStringRef> ctPostScriptName(CTFontCopyPostScriptName(fFontRef.get()));
    if (!ctPostScriptName) {
        return false;
    }
    if (skPostScriptName) {
        SkStringFromCFString(ctPostScriptName.get(), skPostScriptName);
    }
    return true;
}

void SkTypeface_Mac::onGetFontDescriptor(SkFontDescriptor* desc,
                                         bool* isLocalStream) const {
    SkString 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 = fIsFromStream;
}

void SkTypeface_Mac::onCharsToGlyphs(const SkUnichar uni[], int count, SkGlyphID glyphs[]) const {
    // 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.

    SkAutoSTMalloc<1024, UniChar> charStorage;
    const UniChar* src; // UniChar is a UTF-16 16-bit code unit.
    int srcCount;
    const SkUnichar* utf32 = reinterpret_cast<const SkUnichar*>(uni);
    UniChar* utf16 = charStorage.reset(2 * count);
    src = utf16;
    for (int i = 0; i < count; ++i) {
        utf16 += SkUTF::ToUTF16(utf32[i], utf16);
    }
    srcCount = SkToInt(utf16 - src);

    // If there are any non-bmp code points, the provided 'glyphs' storage will be inadequate.
    SkAutoSTMalloc<1024, uint16_t> glyphStorage;
    uint16_t* macGlyphs = glyphs;
    if (srcCount > count) {
        macGlyphs = glyphStorage.reset(srcCount);
    }

    CTFontGetGlyphsForCharacters(fFontRef.get(), src, macGlyphs, srcCount);

    // If there were any non-bmp, then copy and compact.
    // If all are bmp, 'glyphs' already contains the compact glyphs.
    // If some are non-bmp, copy and compact into 'glyphs'.
    if (srcCount > count) {
        SkASSERT(glyphs != macGlyphs);
        int extra = 0;
        for (int i = 0; i < count; ++i) {
            glyphs[i] = macGlyphs[i + extra];
            if (SkUTF::IsLeadingSurrogateUTF16(src[i + extra])) {
                ++extra;
            }
        }
    } else {
        SkASSERT(glyphs == macGlyphs);
    }
}

int SkTypeface_Mac::onCountGlyphs() const {
    return SkToInt(CTFontGetGlyphCount(fFontRef.get()));
}

/** Creates a dictionary suitable for setting the axes on a CTFont. */
CTFontVariation SkCTVariationFromSkFontArguments(CTFontRef ct, CFArrayRef ctAxes,
                                                 const SkFontArguments& args) {
    OpszVariation opsz;
    constexpr const SkFourByteTag opszTag = SkSetFourByteTag('o','p','s','z');

    if (!ctAxes) {
        return CTFontVariation();
    }
    CFIndex axisCount = CFArrayGetCount(ctAxes);

    // On 10.12 and later, this only returns non-default variations.
    SkUniqueCFRef<CFDictionaryRef> oldCtVariation(CTFontCopyVariation(ct));

    const SkFontArguments::VariationPosition position = args.getVariationDesignPosition();

    SkUniqueCFRef<CFMutableDictionaryRef> newCtVariation(
            CFDictionaryCreateMutable(kCFAllocatorDefault, axisCount,
                                      &kCFTypeDictionaryKeyCallBacks,
                                      &kCFTypeDictionaryValueCallBacks));
    SkUniqueCFRef<CFMutableDictionaryRef> wrongOpszVariation;

    for (int i = 0; i < axisCount; ++i) {
        CFDictionaryRef axisInfoDict;
        if (!SkCFDynamicCast(CFArrayGetValueAtIndex(ctAxes, i), &axisInfoDict, "Axis")) {
            return CTFontVariation();
        }

        int64_t tagLong;
        CFNumberRef tagNumber;
        CFTypeRef tag = CFDictionaryGetValue(axisInfoDict, kCTFontVariationAxisIdentifierKey);
        if (!SkCFNumberDynamicCast(tag, &tagLong, &tagNumber, "Axis tag")) {
            return CTFontVariation();
        }

        // The variation axes can be set to any value, but cg will effectively pin them.
        // Pin them here to normalize.
        double minDouble;
        double maxDouble;
        double defDouble;
        CFTypeRef min = CFDictionaryGetValue(axisInfoDict, kCTFontVariationAxisMinimumValueKey);
        CFTypeRef max = CFDictionaryGetValue(axisInfoDict, kCTFontVariationAxisMaximumValueKey);
        CFTypeRef def = CFDictionaryGetValue(axisInfoDict, kCTFontVariationAxisDefaultValueKey);
        if (!SkCFNumberDynamicCast(min, &minDouble, nullptr, "Axis min") ||
            !SkCFNumberDynamicCast(max, &maxDouble, nullptr, "Axis max") ||
            !SkCFNumberDynamicCast(def, &defDouble, nullptr, "Axis def"))
        {
            return CTFontVariation();
        }

        // Start with the default value.
        double value = defDouble;

        // Then the current value.
        bool haveCurrentDouble = false;
        double currentDouble = 0;
        if (oldCtVariation) {
            CFTypeRef currentNumber = CFDictionaryGetValue(oldCtVariation.get(), tagNumber);
            if (currentNumber) {
                if (!SkCFNumberDynamicCast(currentNumber, &value, nullptr, "Variation value")) {
                    return CTFontVariation();
                }
                currentDouble = value;
                haveCurrentDouble = true;
            }
        }

        // Then the requested value.
        // The position may be over specified. If there are multiple values for a given axis,
        // use the last one since that's what css-fonts-4 requires.
        for (int j = position.coordinateCount; j --> 0;) {
            if (position.coordinates[j].axis == tagLong) {
                value = SkTPin<double>(position.coordinates[j].value, minDouble, maxDouble);
                if (tagLong == opszTag) {
                    opsz.isSet = true;
                }
                break;
            }
        }
        if (tagLong == opszTag) {
            opsz.value = value;
            if (haveCurrentDouble && value == currentDouble) {
                // Calculate a value strictly in range but different from currentValue.
                double wrongOpszDouble = ((maxDouble - minDouble) / 2.0) + minDouble;
                if (wrongOpszDouble == currentDouble) {
                    wrongOpszDouble = ((maxDouble - minDouble) / 4.0) + minDouble;
                }
                wrongOpszVariation.reset(
                    CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
                                              &kCFTypeDictionaryKeyCallBacks,
                                              &kCFTypeDictionaryValueCallBacks));
                SkUniqueCFRef<CFNumberRef> wrongOpszNumber(
                    CFNumberCreate(kCFAllocatorDefault, kCFNumberDoubleType, &wrongOpszDouble));
                CFDictionarySetValue(wrongOpszVariation.get(), tagNumber, wrongOpszNumber.get());
            }
        }
        SkUniqueCFRef<CFNumberRef> valueNumber(
            CFNumberCreate(kCFAllocatorDefault, kCFNumberDoubleType, &value));
        CFDictionaryAddValue(newCtVariation.get(), tagNumber, valueNumber.get());
    }
    return { SkUniqueCFRef<CFDictionaryRef>(std::move(newCtVariation)),
             SkUniqueCFRef<CFDictionaryRef>(std::move(wrongOpszVariation)),
             opsz };
}

sk_sp<SkTypeface> SkTypeface_Mac::onMakeClone(const SkFontArguments& args) const {
    CTFontVariation ctVariation = SkCTVariationFromSkFontArguments(fFontRef.get(),
                                                                   this->getVariationAxes(),
                                                                   args);

    SkUniqueCFRef<CTFontRef> ctVariant;
    if (ctVariation.variation) {
        SkUniqueCFRef<CFMutableDictionaryRef> attributes(
                CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
                                          &kCFTypeDictionaryKeyCallBacks,
                                          &kCFTypeDictionaryValueCallBacks));

        CTFontRef ctFont = fFontRef.get();
        SkUniqueCFRef<CTFontRef> wrongOpszFont;
        if (ctVariation.wrongOpszVariation) {
            // On macOS 11 cloning a system font with an opsz axis and not changing the
            // value of the opsz axis (either by setting it to the same value or not
            // specifying it at all) when setting a variation causes the variation to
            // be set but the cloned font will still compare CFEqual to the original
            // font. Work around this by setting the opsz to something which isn't the
            // desired value before setting the entire desired variation.
            //
            // A similar issue occurs with fonts from data on macOS 10.15 and the same
            // work around seems to apply. This is less noticeable though since CFEqual
            // isn't used on these fonts.
            CFDictionarySetValue(attributes.get(),
                                 kCTFontVariationAttribute, ctVariation.wrongOpszVariation.get());
            SkUniqueCFRef<CTFontDescriptorRef> varDesc(
                CTFontDescriptorCreateWithAttributes(attributes.get()));
            wrongOpszFont.reset(CTFontCreateCopyWithAttributes(ctFont, 0, nullptr, varDesc.get()));
            ctFont = wrongOpszFont.get();
        }

        CFDictionarySetValue(attributes.get(),
                             kCTFontVariationAttribute, ctVariation.variation.get());
        SkUniqueCFRef<CTFontDescriptorRef> varDesc(
                CTFontDescriptorCreateWithAttributes(attributes.get()));
        ctVariant.reset(CTFontCreateCopyWithAttributes(ctFont, 0, nullptr, varDesc.get()));
    } else {
        ctVariant.reset((CTFontRef)CFRetain(fFontRef.get()));
    }
    if (!ctVariant) {
        return nullptr;
    }

    return SkTypeface_Mac::Make(std::move(ctVariant), ctVariation.opsz,
                                fStream ? fStream->duplicate() : nullptr);
}

int SkTypeface_Mac::onGetVariationDesignParameters(SkFontParameters::Variation::Axis parameters[],
                                                   int parameterCount) const
{
    CFArrayRef ctAxes = this->getVariationAxes();
    if (!ctAxes) {
        return -1;
    }
    CFIndex axisCount = CFArrayGetCount(ctAxes);

    if (!parameters || parameterCount < axisCount) {
        return axisCount;
    }

    // Added in 10.13
    static CFStringRef* kCTFontVariationAxisHiddenKeyPtr =
            static_cast<CFStringRef*>(dlsym(RTLD_DEFAULT, "kCTFontVariationAxisHiddenKey"));

    for (int i = 0; i < axisCount; ++i) {
        CFDictionaryRef axisInfoDict;
        if (!SkCFDynamicCast(CFArrayGetValueAtIndex(ctAxes, i), &axisInfoDict, "Axis")) {
            return -1;
        }

        int64_t tagLong;
        CFTypeRef tag = CFDictionaryGetValue(axisInfoDict, kCTFontVariationAxisIdentifierKey);
        if (!SkCFNumberDynamicCast(tag, &tagLong, nullptr, "Axis tag")) {
            return -1;
        }

        double minDouble;
        double maxDouble;
        double defDouble;
        CFTypeRef min = CFDictionaryGetValue(axisInfoDict, kCTFontVariationAxisMinimumValueKey);
        CFTypeRef max = CFDictionaryGetValue(axisInfoDict, kCTFontVariationAxisMaximumValueKey);
        CFTypeRef def = CFDictionaryGetValue(axisInfoDict, kCTFontVariationAxisDefaultValueKey);
        if (!SkCFNumberDynamicCast(min, &minDouble, nullptr, "Axis min") ||
            !SkCFNumberDynamicCast(max, &maxDouble, nullptr, "Axis max") ||
            !SkCFNumberDynamicCast(def, &defDouble, nullptr, "Axis def"))
        {
            return -1;
        }

        SkFontParameters::Variation::Axis& skAxis = parameters[i];
        skAxis.tag = tagLong;
        skAxis.min = minDouble;
        skAxis.max = maxDouble;
        skAxis.def = defDouble;
        skAxis.setHidden(false);
        if (kCTFontVariationAxisHiddenKeyPtr) {
            CFTypeRef hidden = CFDictionaryGetValue(axisInfoDict,*kCTFontVariationAxisHiddenKeyPtr);
            if (hidden) {
                // At least macOS 11 Big Sur Beta 4 uses CFNumberRef instead of CFBooleanRef.
                // https://crbug.com/1113444
                CFBooleanRef hiddenBoolean;
                int hiddenInt;
                if (SkCFDynamicCast(hidden, &hiddenBoolean, nullptr)) {
                    skAxis.setHidden(CFBooleanGetValue(hiddenBoolean));
                } else if (SkCFNumberDynamicCast(hidden, &hiddenInt, nullptr, "Axis hidden")) {
                    skAxis.setHidden(hiddenInt);
                } else {
                    return -1;
                }
            }
        }
    }
    return axisCount;
}

#endif
