Home | History | Annotate | Download | only in ports
      1 
      2 /*
      3  * Copyright 2006 The Android Open Source Project
      4  *
      5  * Use of this source code is governed by a BSD-style license that can be
      6  * found in the LICENSE file.
      7  */
      8 
      9 #include "SkTypes.h"  // Keep this before any #ifdef ...
     10 #if defined(SK_BUILD_FOR_MAC) || defined(SK_BUILD_FOR_IOS)
     11 
     12 #ifdef SK_BUILD_FOR_MAC
     13 #import <ApplicationServices/ApplicationServices.h>
     14 #endif
     15 
     16 #ifdef SK_BUILD_FOR_IOS
     17 #include <CoreText/CoreText.h>
     18 #include <CoreText/CTFontManager.h>
     19 #include <CoreGraphics/CoreGraphics.h>
     20 #include <CoreFoundation/CoreFoundation.h>
     21 #endif
     22 
     23 #include "SkAdvancedTypefaceMetrics.h"
     24 #include "SkCGUtils.h"
     25 #include "SkColorPriv.h"
     26 #include "SkDescriptor.h"
     27 #include "SkEndian.h"
     28 #include "SkFloatingPoint.h"
     29 #include "SkFontDescriptor.h"
     30 #include "SkFontMgr.h"
     31 #include "SkGlyph.h"
     32 #include "SkMaskGamma.h"
     33 #include "SkMutex.h"
     34 #include "SkOTTable_glyf.h"
     35 #include "SkOTTable_head.h"
     36 #include "SkOTTable_hhea.h"
     37 #include "SkOTTable_loca.h"
     38 #include "SkOTUtils.h"
     39 #include "SkOncePtr.h"
     40 #include "SkPaint.h"
     41 #include "SkPath.h"
     42 #include "SkSFNTHeader.h"
     43 #include "SkStream.h"
     44 #include "SkString.h"
     45 #include "SkTemplates.h"
     46 #include "SkTypefaceCache.h"
     47 #include "SkTypeface_mac.h"
     48 #include "SkUtils.h"
     49 #include "SkUtils.h"
     50 
     51 #include <dlfcn.h>
     52 
     53 // Experimental code to use a global lock whenever we access CG, to see if this reduces
     54 // crashes in Chrome
     55 #define USE_GLOBAL_MUTEX_FOR_CG_ACCESS
     56 
     57 #ifdef USE_GLOBAL_MUTEX_FOR_CG_ACCESS
     58     SK_DECLARE_STATIC_MUTEX(gCGMutex);
     59     #define AUTO_CG_LOCK()  SkAutoMutexAcquire amc(gCGMutex)
     60 #else
     61     #define AUTO_CG_LOCK()
     62 #endif
     63 
     64 // Set to make glyph bounding boxes visible.
     65 #define SK_SHOW_TEXT_BLIT_COVERAGE 0
     66 
     67 class SkScalerContext_Mac;
     68 
     69 // CTFontManagerCopyAvailableFontFamilyNames() is not always available, so we
     70 // provide a wrapper here that will return an empty array if need be.
     71 static CFArrayRef SkCTFontManagerCopyAvailableFontFamilyNames() {
     72 #ifdef SK_BUILD_FOR_IOS
     73     return CFArrayCreate(nullptr, nullptr, 0, nullptr);
     74 #else
     75     return CTFontManagerCopyAvailableFontFamilyNames();
     76 #endif
     77 }
     78 
     79 
     80 // Being templated and taking const T* prevents calling
     81 // CFSafeRelease(autoCFRelease) through implicit conversion.
     82 template <typename T> static void CFSafeRelease(/*CFTypeRef*/const T* cfTypeRef) {
     83     if (cfTypeRef) {
     84         CFRelease(cfTypeRef);
     85     }
     86 }
     87 
     88 // Being templated and taking const T* prevents calling
     89 // CFSafeRetain(autoCFRelease) through implicit conversion.
     90 template <typename T> static void CFSafeRetain(/*CFTypeRef*/const T* cfTypeRef) {
     91     if (cfTypeRef) {
     92         CFRetain(cfTypeRef);
     93     }
     94 }
     95 
     96 /** Acts like a CFRef, but calls CFSafeRelease when it goes out of scope. */
     97 template<typename CFRef> class AutoCFRelease : private SkNoncopyable {
     98 public:
     99     explicit AutoCFRelease(CFRef cfRef = nullptr) : fCFRef(cfRef) { }
    100     ~AutoCFRelease() { CFSafeRelease(fCFRef); }
    101 
    102     void reset(CFRef that = nullptr) {
    103         if (that != fCFRef) {
    104             CFSafeRelease(fCFRef);
    105             fCFRef = that;
    106         }
    107     }
    108 
    109     CFRef detach() {
    110         CFRef self = fCFRef;
    111         fCFRef = nullptr;
    112         return self;
    113     }
    114 
    115     operator CFRef() const { return fCFRef; }
    116     CFRef get() const { return fCFRef; }
    117 
    118     CFRef* operator&() { SkASSERT(fCFRef == nullptr); return &fCFRef; }
    119 private:
    120     CFRef fCFRef;
    121 };
    122 
    123 static CFStringRef make_CFString(const char str[]) {
    124     return CFStringCreateWithCString(nullptr, str, kCFStringEncodingUTF8);
    125 }
    126 
    127 template<typename T> class AutoCGTable : SkNoncopyable {
    128 public:
    129     AutoCGTable(CGFontRef font)
    130     //Undocumented: the tag parameter in this call is expected in machine order and not BE order.
    131     : fCFData(CGFontCopyTableForTag(font, SkSetFourByteTag(T::TAG0, T::TAG1, T::TAG2, T::TAG3)))
    132     , fData(fCFData ? reinterpret_cast<const T*>(CFDataGetBytePtr(fCFData)) : nullptr)
    133     { }
    134 
    135     const T* operator->() const { return fData; }
    136 
    137 private:
    138     AutoCFRelease<CFDataRef> fCFData;
    139 public:
    140     const T* fData;
    141 };
    142 
    143 // inline versions of these rect helpers
    144 
    145 static bool CGRectIsEmpty_inline(const CGRect& rect) {
    146     return rect.size.width <= 0 || rect.size.height <= 0;
    147 }
    148 
    149 static CGFloat CGRectGetMinX_inline(const CGRect& rect) {
    150     return rect.origin.x;
    151 }
    152 
    153 static CGFloat CGRectGetMaxX_inline(const CGRect& rect) {
    154     return rect.origin.x + rect.size.width;
    155 }
    156 
    157 static CGFloat CGRectGetMinY_inline(const CGRect& rect) {
    158     return rect.origin.y;
    159 }
    160 
    161 static CGFloat CGRectGetMaxY_inline(const CGRect& rect) {
    162     return rect.origin.y + rect.size.height;
    163 }
    164 
    165 static CGFloat CGRectGetWidth_inline(const CGRect& rect) {
    166     return rect.size.width;
    167 }
    168 
    169 ///////////////////////////////////////////////////////////////////////////////
    170 
    171 static void sk_memset_rect32(uint32_t* ptr, uint32_t value,
    172                              int width, int height, size_t rowBytes) {
    173     SkASSERT(width);
    174     SkASSERT(width * sizeof(uint32_t) <= rowBytes);
    175 
    176     if (width >= 32) {
    177         while (height) {
    178             sk_memset32(ptr, value, width);
    179             ptr = (uint32_t*)((char*)ptr + rowBytes);
    180             height -= 1;
    181         }
    182         return;
    183     }
    184 
    185     rowBytes -= width * sizeof(uint32_t);
    186 
    187     if (width >= 8) {
    188         while (height) {
    189             int w = width;
    190             do {
    191                 *ptr++ = value; *ptr++ = value;
    192                 *ptr++ = value; *ptr++ = value;
    193                 *ptr++ = value; *ptr++ = value;
    194                 *ptr++ = value; *ptr++ = value;
    195                 w -= 8;
    196             } while (w >= 8);
    197             while (--w >= 0) {
    198                 *ptr++ = value;
    199             }
    200             ptr = (uint32_t*)((char*)ptr + rowBytes);
    201             height -= 1;
    202         }
    203     } else {
    204         while (height) {
    205             int w = width;
    206             do {
    207                 *ptr++ = value;
    208             } while (--w > 0);
    209             ptr = (uint32_t*)((char*)ptr + rowBytes);
    210             height -= 1;
    211         }
    212     }
    213 }
    214 
    215 #include <sys/utsname.h>
    216 
    217 typedef uint32_t CGRGBPixel;
    218 
    219 static unsigned CGRGBPixel_getAlpha(CGRGBPixel pixel) {
    220     return pixel & 0xFF;
    221 }
    222 
    223 static const char FONT_DEFAULT_NAME[] = "Lucida Sans";
    224 
    225 // See Source/WebKit/chromium/base/mac/mac_util.mm DarwinMajorVersionInternal for original source.
    226 static int readVersion() {
    227     struct utsname info;
    228     if (uname(&info) != 0) {
    229         SkDebugf("uname failed\n");
    230         return 0;
    231     }
    232     if (strcmp(info.sysname, "Darwin") != 0) {
    233         SkDebugf("unexpected uname sysname %s\n", info.sysname);
    234         return 0;
    235     }
    236     char* dot = strchr(info.release, '.');
    237     if (!dot) {
    238         SkDebugf("expected dot in uname release %s\n", info.release);
    239         return 0;
    240     }
    241     int version = atoi(info.release);
    242     if (version == 0) {
    243         SkDebugf("could not parse uname release %s\n", info.release);
    244     }
    245     return version;
    246 }
    247 
    248 static int darwinVersion() {
    249     static int darwin_version = readVersion();
    250     return darwin_version;
    251 }
    252 
    253 static bool isSnowLeopard() {
    254     return darwinVersion() == 10;
    255 }
    256 
    257 static bool isLion() {
    258     return darwinVersion() == 11;
    259 }
    260 
    261 static bool isMountainLion() {
    262     return darwinVersion() == 12;
    263 }
    264 
    265 static bool isLCDFormat(unsigned format) {
    266     return SkMask::kLCD16_Format == format;
    267 }
    268 
    269 static CGFloat ScalarToCG(SkScalar scalar) {
    270     if (sizeof(CGFloat) == sizeof(float)) {
    271         return SkScalarToFloat(scalar);
    272     } else {
    273         SkASSERT(sizeof(CGFloat) == sizeof(double));
    274         return (CGFloat) SkScalarToDouble(scalar);
    275     }
    276 }
    277 
    278 static SkScalar CGToScalar(CGFloat cgFloat) {
    279     if (sizeof(CGFloat) == sizeof(float)) {
    280         return cgFloat;
    281     } else {
    282         SkASSERT(sizeof(CGFloat) == sizeof(double));
    283         return SkDoubleToScalar(cgFloat);
    284     }
    285 }
    286 
    287 static CGAffineTransform MatrixToCGAffineTransform(const SkMatrix& matrix,
    288                                                    SkScalar sx = SK_Scalar1,
    289                                                    SkScalar sy = SK_Scalar1) {
    290     return CGAffineTransformMake( ScalarToCG(matrix[SkMatrix::kMScaleX] * sx),
    291                                  -ScalarToCG(matrix[SkMatrix::kMSkewY]  * sy),
    292                                  -ScalarToCG(matrix[SkMatrix::kMSkewX]  * sx),
    293                                   ScalarToCG(matrix[SkMatrix::kMScaleY] * sy),
    294                                   ScalarToCG(matrix[SkMatrix::kMTransX] * sx),
    295                                   ScalarToCG(matrix[SkMatrix::kMTransY] * sy));
    296 }
    297 
    298 ///////////////////////////////////////////////////////////////////////////////
    299 
    300 #define BITMAP_INFO_RGB (kCGImageAlphaNoneSkipFirst | kCGBitmapByteOrder32Host)
    301 
    302 /**
    303  * There does not appear to be a publicly accessable API for determining if lcd
    304  * font smoothing will be applied if we request it. The main issue is that if
    305  * smoothing is applied a gamma of 2.0 will be used, if not a gamma of 1.0.
    306  */
    307 static bool supports_LCD() {
    308     static int gSupportsLCD = -1;
    309     if (gSupportsLCD >= 0) {
    310         return (bool) gSupportsLCD;
    311     }
    312     uint32_t rgb = 0;
    313     AutoCFRelease<CGColorSpaceRef> colorspace(CGColorSpaceCreateDeviceRGB());
    314     AutoCFRelease<CGContextRef> cgContext(CGBitmapContextCreate(&rgb, 1, 1, 8, 4,
    315                                                                 colorspace, BITMAP_INFO_RGB));
    316     CGContextSelectFont(cgContext, "Helvetica", 16, kCGEncodingMacRoman);
    317     CGContextSetShouldSmoothFonts(cgContext, true);
    318     CGContextSetShouldAntialias(cgContext, true);
    319     CGContextSetTextDrawingMode(cgContext, kCGTextFill);
    320     CGContextSetGrayFillColor(cgContext, 1, 1);
    321     CGContextShowTextAtPoint(cgContext, -1, 0, "|", 1);
    322     uint32_t r = (rgb >> 16) & 0xFF;
    323     uint32_t g = (rgb >>  8) & 0xFF;
    324     uint32_t b = (rgb >>  0) & 0xFF;
    325     gSupportsLCD = (r != g || r != b);
    326     return (bool) gSupportsLCD;
    327 }
    328 
    329 class Offscreen {
    330 public:
    331     Offscreen()
    332         : fRGBSpace(nullptr)
    333         , fCG(nullptr)
    334         , fDoAA(false)
    335         , fDoLCD(false)
    336     {
    337         fSize.set(0, 0);
    338     }
    339 
    340     CGRGBPixel* getCG(const SkScalerContext_Mac& context, const SkGlyph& glyph,
    341                       CGGlyph glyphID, size_t* rowBytesPtr,
    342                       bool generateA8FromLCD);
    343 
    344 private:
    345     enum {
    346         kSize = 32 * 32 * sizeof(CGRGBPixel)
    347     };
    348     SkAutoSMalloc<kSize> fImageStorage;
    349     AutoCFRelease<CGColorSpaceRef> fRGBSpace;
    350 
    351     // cached state
    352     AutoCFRelease<CGContextRef> fCG;
    353     SkISize fSize;
    354     bool fDoAA;
    355     bool fDoLCD;
    356 
    357     static int RoundSize(int dimension) {
    358         return SkNextPow2(dimension);
    359     }
    360 };
    361 
    362 ///////////////////////////////////////////////////////////////////////////////
    363 
    364 static bool find_dict_float(CFDictionaryRef dict, CFStringRef name, float* value) {
    365     CFNumberRef num;
    366     return CFDictionaryGetValueIfPresent(dict, name, (const void**)&num)
    367     && CFNumberIsFloatType(num)
    368     && CFNumberGetValue(num, kCFNumberFloatType, value);
    369 }
    370 
    371 static int unit_weight_to_fontstyle(float unit) {
    372     float value;
    373     if (unit < 0) {
    374         value = 100 + (1 + unit) * 300;
    375     } else {
    376         value = 400 + unit * 500;
    377     }
    378     return sk_float_round2int(value);
    379 }
    380 
    381 static int unit_width_to_fontstyle(float unit) {
    382     float value;
    383     if (unit < 0) {
    384         value = 1 + (1 + unit) * 4;
    385     } else {
    386         value = 5 + unit * 4;
    387     }
    388     return sk_float_round2int(value);
    389 }
    390 
    391 static SkFontStyle fontstyle_from_descriptor(CTFontDescriptorRef desc) {
    392     AutoCFRelease<CFDictionaryRef> dict(
    393             (CFDictionaryRef)CTFontDescriptorCopyAttribute(desc, kCTFontTraitsAttribute));
    394     if (nullptr == dict.get()) {
    395         return SkFontStyle();
    396     }
    397 
    398     float weight, width, slant;
    399     if (!find_dict_float(dict, kCTFontWeightTrait, &weight)) {
    400         weight = 0;
    401     }
    402     if (!find_dict_float(dict, kCTFontWidthTrait, &width)) {
    403         width = 0;
    404     }
    405     if (!find_dict_float(dict, kCTFontSlantTrait, &slant)) {
    406         slant = 0;
    407     }
    408 
    409     return SkFontStyle(unit_weight_to_fontstyle(weight),
    410                        unit_width_to_fontstyle(width),
    411                        slant ? SkFontStyle::kItalic_Slant
    412                        : SkFontStyle::kUpright_Slant);
    413 }
    414 
    415 static SkTypeface::Style computeStyleBits(CTFontRef font, bool* isFixedPitch) {
    416     unsigned style = SkTypeface::kNormal;
    417     CTFontSymbolicTraits traits = CTFontGetSymbolicTraits(font);
    418 
    419     if (traits & kCTFontBoldTrait) {
    420         style |= SkTypeface::kBold;
    421     }
    422     if (traits & kCTFontItalicTrait) {
    423         style |= SkTypeface::kItalic;
    424     }
    425     if (isFixedPitch) {
    426         *isFixedPitch = (traits & kCTFontMonoSpaceTrait) != 0;
    427     }
    428     return (SkTypeface::Style)style;
    429 }
    430 
    431 #define WEIGHT_THRESHOLD    ((SkFontStyle::kNormal_Weight + SkFontStyle::kBold_Weight)/2)
    432 
    433 // kCTFontColorGlyphsTrait was added in the Mac 10.7 and iPhone 4.3 SDKs.
    434 // Being an enum value it is not guarded by version macros, but old SDKs must still be supported.
    435 #if defined(__MAC_10_7) || defined(__IPHONE_4_3)
    436 static const uint32_t SkCTFontColorGlyphsTrait = kCTFontColorGlyphsTrait;
    437 #else
    438 static const uint32_t SkCTFontColorGlyphsTrait = (1 << 13);
    439 #endif
    440 
    441 class SkTypeface_Mac : public SkTypeface {
    442 public:
    443     SkTypeface_Mac(CTFontRef fontRef, CFTypeRef resourceRef,
    444                    const SkFontStyle& fs, bool isFixedPitch,
    445                    const char requestedName[], bool isLocalStream)
    446         : SkTypeface(fs, SkTypefaceCache::NewFontID(), isFixedPitch)
    447         , fRequestedName(requestedName)
    448         , fFontRef(fontRef) // caller has already called CFRetain for us
    449         , fOriginatingCFTypeRef(resourceRef) // caller has already called CFRetain for us
    450         , fHasColorGlyphs(SkToBool(CTFontGetSymbolicTraits(fFontRef) & SkCTFontColorGlyphsTrait))
    451         , fIsLocalStream(isLocalStream)
    452     {
    453         SkASSERT(fontRef);
    454     }
    455 
    456     SkString fRequestedName;
    457     AutoCFRelease<CTFontRef> fFontRef;
    458     AutoCFRelease<CFTypeRef> fOriginatingCFTypeRef;
    459     const bool fHasColorGlyphs;
    460 
    461 protected:
    462     int onGetUPEM() const override;
    463     SkStreamAsset* onOpenStream(int* ttcIndex) const override;
    464     SkFontData* onCreateFontData() const override;
    465     void onGetFamilyName(SkString* familyName) const override;
    466     SkTypeface::LocalizedStrings* onCreateFamilyNameIterator() const override;
    467     int onGetTableTags(SkFontTableTag tags[]) const override;
    468     virtual size_t onGetTableData(SkFontTableTag, size_t offset,
    469                                   size_t length, void* data) const override;
    470     SkScalerContext* onCreateScalerContext(const SkDescriptor*) const override;
    471     void onFilterRec(SkScalerContextRec*) const override;
    472     void onGetFontDescriptor(SkFontDescriptor*, bool*) const override;
    473     virtual SkAdvancedTypefaceMetrics* onGetAdvancedTypefaceMetrics(
    474                                 PerGlyphInfo,
    475                                 const uint32_t*, uint32_t) const override;
    476     virtual int onCharsToGlyphs(const void* chars, Encoding, uint16_t glyphs[],
    477                                 int glyphCount) const override;
    478     int onCountGlyphs() const override;
    479 
    480 private:
    481     bool fIsLocalStream;
    482 
    483     typedef SkTypeface INHERITED;
    484 };
    485 
    486 /** Creates a typeface without searching the cache. Takes ownership of the CTFontRef. */
    487 static SkTypeface* NewFromFontRef(CTFontRef fontRef, CFTypeRef resourceRef,
    488                                   const char name[], bool isLocalStream)
    489 {
    490     SkASSERT(fontRef);
    491     bool isFixedPitch;
    492     SkFontStyle style = SkFontStyle(computeStyleBits(fontRef, &isFixedPitch));
    493 
    494     return new SkTypeface_Mac(fontRef, resourceRef, style, isFixedPitch, name, isLocalStream);
    495 }
    496 
    497 static bool find_by_CTFontRef(SkTypeface* cached, const SkFontStyle&, void* context) {
    498     CTFontRef self = (CTFontRef)context;
    499     CTFontRef other = ((SkTypeface_Mac*)cached)->fFontRef;
    500 
    501     return CFEqual(self, other);
    502 }
    503 
    504 /** Creates a typeface from a name, searching the cache. */
    505 static SkTypeface* NewFromName(const char familyName[], const SkFontStyle& theStyle) {
    506     CTFontSymbolicTraits ctFontTraits = 0;
    507     if (theStyle.weight() >= SkFontStyle::kBold_Weight) {
    508         ctFontTraits |= kCTFontBoldTrait;
    509     }
    510     if (theStyle.slant() != SkFontStyle::kUpright_Slant) {
    511         ctFontTraits |= kCTFontItalicTrait;
    512     }
    513 
    514     //TODO: add weight width slant
    515 
    516     // Create the font info
    517     AutoCFRelease<CFStringRef> cfFontName(make_CFString(familyName));
    518 
    519     AutoCFRelease<CFNumberRef> cfFontTraits(
    520             CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &ctFontTraits));
    521 
    522     AutoCFRelease<CFMutableDictionaryRef> cfAttributes(
    523             CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
    524                                       &kCFTypeDictionaryKeyCallBacks,
    525                                       &kCFTypeDictionaryValueCallBacks));
    526 
    527     AutoCFRelease<CFMutableDictionaryRef> cfTraits(
    528             CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
    529                                       &kCFTypeDictionaryKeyCallBacks,
    530                                       &kCFTypeDictionaryValueCallBacks));
    531 
    532     if (!cfFontName || !cfFontTraits || !cfAttributes || !cfTraits) {
    533         return nullptr;
    534     }
    535 
    536     CFDictionaryAddValue(cfTraits, kCTFontSymbolicTrait, cfFontTraits);
    537 
    538     CFDictionaryAddValue(cfAttributes, kCTFontFamilyNameAttribute, cfFontName);
    539     CFDictionaryAddValue(cfAttributes, kCTFontTraitsAttribute, cfTraits);
    540 
    541     AutoCFRelease<CTFontDescriptorRef> ctFontDesc(
    542             CTFontDescriptorCreateWithAttributes(cfAttributes));
    543     if (!ctFontDesc) {
    544         return nullptr;
    545     }
    546 
    547     AutoCFRelease<CTFontRef> ctFont(CTFontCreateWithFontDescriptor(ctFontDesc, 0, nullptr));
    548     if (!ctFont) {
    549         return nullptr;
    550     }
    551 
    552     SkTypeface* face = SkTypefaceCache::FindByProcAndRef(find_by_CTFontRef, (void*)ctFont.get());
    553     if (!face) {
    554         face = NewFromFontRef(ctFont.detach(), nullptr, nullptr, false);
    555         SkTypefaceCache::Add(face, face->fontStyle());
    556     }
    557     return face;
    558 }
    559 
    560 SK_DECLARE_STATIC_MUTEX(gGetDefaultFaceMutex);
    561 static SkTypeface* GetDefaultFace() {
    562     SkAutoMutexAcquire ma(gGetDefaultFaceMutex);
    563 
    564     static SkTypeface* gDefaultFace;
    565 
    566     if (nullptr == gDefaultFace) {
    567         gDefaultFace = NewFromName(FONT_DEFAULT_NAME, SkFontStyle());
    568         SkTypefaceCache::Add(gDefaultFace, SkFontStyle());
    569     }
    570     return gDefaultFace;
    571 }
    572 
    573 ///////////////////////////////////////////////////////////////////////////////
    574 
    575 extern CTFontRef SkTypeface_GetCTFontRef(const SkTypeface* face);
    576 CTFontRef SkTypeface_GetCTFontRef(const SkTypeface* face) {
    577     const SkTypeface_Mac* macface = (const SkTypeface_Mac*)face;
    578     return macface ? macface->fFontRef.get() : nullptr;
    579 }
    580 
    581 /*  This function is visible on the outside. It first searches the cache, and if
    582  *  not found, returns a new entry (after adding it to the cache).
    583  */
    584 SkTypeface* SkCreateTypefaceFromCTFont(CTFontRef fontRef, CFTypeRef resourceRef) {
    585     SkTypeface* face = SkTypefaceCache::FindByProcAndRef(find_by_CTFontRef, (void*)fontRef);
    586     if (!face) {
    587         CFRetain(fontRef);
    588         if (resourceRef) {
    589             CFRetain(resourceRef);
    590         }
    591         face = NewFromFontRef(fontRef, resourceRef, nullptr, false);
    592         SkTypefaceCache::Add(face, face->fontStyle());
    593     }
    594     return face;
    595 }
    596 
    597 struct NameStyle {
    598     const char* fName;
    599     SkFontStyle fStyle;
    600 };
    601 
    602 static bool find_by_NameStyle(SkTypeface* cachedFace, const SkFontStyle& cachedStyle, void* ctx) {
    603     const SkTypeface_Mac* cachedMacFace = static_cast<SkTypeface_Mac*>(cachedFace);
    604     const NameStyle* requested = static_cast<const NameStyle*>(ctx);
    605 
    606     return cachedStyle == requested->fStyle
    607         && cachedMacFace->fRequestedName.equals(requested->fName);
    608 }
    609 
    610 static const char* map_css_names(const char* name) {
    611     static const struct {
    612         const char* fFrom;  // name the caller specified
    613         const char* fTo;    // "canonical" name we map to
    614     } gPairs[] = {
    615         { "sans-serif", "Helvetica" },
    616         { "serif",      "Times"     },
    617         { "monospace",  "Courier"   }
    618     };
    619 
    620     for (size_t i = 0; i < SK_ARRAY_COUNT(gPairs); i++) {
    621         if (strcmp(name, gPairs[i].fFrom) == 0) {
    622             return gPairs[i].fTo;
    623         }
    624     }
    625     return name;    // no change
    626 }
    627 
    628 ///////////////////////////////////////////////////////////////////////////////
    629 
    630 /** GlyphRect is in FUnits (em space, y up). */
    631 struct GlyphRect {
    632     int16_t fMinX;
    633     int16_t fMinY;
    634     int16_t fMaxX;
    635     int16_t fMaxY;
    636 };
    637 
    638 class SkScalerContext_Mac : public SkScalerContext {
    639 public:
    640     SkScalerContext_Mac(SkTypeface_Mac*, const SkDescriptor*);
    641 
    642 protected:
    643     unsigned generateGlyphCount(void) override;
    644     uint16_t generateCharToGlyph(SkUnichar uni) override;
    645     void generateAdvance(SkGlyph* glyph) override;
    646     void generateMetrics(SkGlyph* glyph) override;
    647     void generateImage(const SkGlyph& glyph) override;
    648     void generatePath(const SkGlyph& glyph, SkPath* path) override;
    649     void generateFontMetrics(SkPaint::FontMetrics*) override;
    650 
    651 private:
    652     static void CTPathElement(void *info, const CGPathElement *element);
    653 
    654     /** Returns the offset from the horizontal origin to the vertical origin in SkGlyph units. */
    655     void getVerticalOffset(CGGlyph glyphID, SkPoint* offset) const;
    656 
    657     /** Initializes and returns the value of fFBoundingBoxesGlyphOffset.
    658      *
    659      *  For use with (and must be called before) generateBBoxes.
    660      */
    661     uint16_t getFBoundingBoxesGlyphOffset();
    662 
    663     /** Initializes fFBoundingBoxes and returns true on success.
    664      *
    665      *  On Lion and Mountain Lion, CTFontGetBoundingRectsForGlyphs has a bug which causes it to
    666      *  return a bad value in bounds.origin.x for SFNT fonts whose hhea::numberOfHMetrics is
    667      *  less than its maxp::numGlyphs. When this is the case we try to read the bounds from the
    668      *  font directly.
    669      *
    670      *  This routine initializes fFBoundingBoxes to an array of
    671      *  fGlyphCount - fFBoundingBoxesGlyphOffset GlyphRects which contain the bounds in FUnits
    672      *  (em space, y up) of glyphs with ids in the range [fFBoundingBoxesGlyphOffset, fGlyphCount).
    673      *
    674      *  Returns true if fFBoundingBoxes is properly initialized. The table can only be properly
    675      *  initialized for a TrueType font with 'head', 'loca', and 'glyf' tables.
    676      *
    677      *  TODO: A future optimization will compute fFBoundingBoxes once per fCTFont.
    678      */
    679     bool generateBBoxes();
    680 
    681     /** Converts from FUnits (em space, y up) to SkGlyph units (pixels, y down).
    682      *
    683      *  Used on Snow Leopard to correct CTFontGetVerticalTranslationsForGlyphs.
    684      *  Used on Lion to correct CTFontGetBoundingRectsForGlyphs.
    685      */
    686     SkMatrix fFUnitMatrix;
    687 
    688     Offscreen fOffscreen;
    689 
    690     /** Unrotated variant of fCTFont.
    691      *
    692      *  In 10.10.1 CTFontGetAdvancesForGlyphs applies the font transform to the width of the
    693      *  advances, but always sets the height to 0. This font is used to get the advances of the
    694      *  unrotated glyph, and then the rotation is applied separately.
    695      *
    696      *  CT vertical metrics are pre-rotated (in em space, before transform) 90deg clock-wise.
    697      *  This makes kCTFontDefaultOrientation dangerous, because the metrics from
    698      *  kCTFontHorizontalOrientation are in a different space from kCTFontVerticalOrientation.
    699      *  With kCTFontVerticalOrientation the advances must be unrotated.
    700      *
    701      *  Sometimes, creating a copy of a CTFont with the same size but different trasform will select
    702      *  different underlying font data. As a result, avoid ever creating more than one CTFont per
    703      *  SkScalerContext to ensure that only one CTFont is used.
    704      *
    705      *  As a result of the above (and other constraints) this font contains the size, but not the
    706      *  transform. The transform must always be applied separately.
    707      */
    708     AutoCFRelease<CTFontRef> fCTFont;
    709 
    710     /** The transform without the font size. */
    711     CGAffineTransform fTransform;
    712     CGAffineTransform fInvTransform;
    713 
    714     AutoCFRelease<CGFontRef> fCGFont;
    715     SkAutoTMalloc<GlyphRect> fFBoundingBoxes;
    716     uint16_t fFBoundingBoxesGlyphOffset;
    717     uint16_t fGlyphCount;
    718     bool fGeneratedFBoundingBoxes;
    719     const bool fDoSubPosition;
    720     const bool fVertical;
    721 
    722     friend class Offscreen;
    723 
    724     typedef SkScalerContext INHERITED;
    725 };
    726 
    727 // CTFontCreateCopyWithAttributes or CTFontCreateCopyWithSymbolicTraits cannot be used on 10.10
    728 // and later, as they will return different underlying fonts depending on the size requested.
    729 // It is not possible to use descriptors with CTFontCreateWithFontDescriptor, since that does not
    730 // work with non-system fonts. As a result, create the strike specific CTFonts from the underlying
    731 // CGFont.
    732 static CTFontRef ctfont_create_exact_copy(CTFontRef baseFont, CGFloat textSize,
    733                                           const CGAffineTransform* transform)
    734 {
    735     AutoCFRelease<CGFontRef> baseCGFont(CTFontCopyGraphicsFont(baseFont, nullptr));
    736 
    737     // The last parameter (CTFontDescriptorRef attributes) *must* be nullptr.
    738     // If non-nullptr then with fonts with variation axes, the copy will fail in
    739     // CGFontVariationFromDictCallback when it assumes kCGFontVariationAxisName is CFNumberRef
    740     // which it quite obviously is not.
    741 
    742     // Because we cannot setup the CTFont descriptor to match, the same restriction applies here
    743     // as other uses of CTFontCreateWithGraphicsFont which is that such CTFonts should not escape
    744     // the scaler context, since they aren't 'normal'.
    745     return CTFontCreateWithGraphicsFont(baseCGFont, textSize, transform, nullptr);
    746 }
    747 
    748 SkScalerContext_Mac::SkScalerContext_Mac(SkTypeface_Mac* typeface,
    749                                          const SkDescriptor* desc)
    750         : INHERITED(typeface, desc)
    751         , fFBoundingBoxes()
    752         , fFBoundingBoxesGlyphOffset(0)
    753         , fGeneratedFBoundingBoxes(false)
    754         , fDoSubPosition(SkToBool(fRec.fFlags & kSubpixelPositioning_Flag))
    755         , fVertical(SkToBool(fRec.fFlags & kVertical_Flag))
    756 
    757 {
    758     AUTO_CG_LOCK();
    759 
    760     CTFontRef ctFont = typeface->fFontRef.get();
    761     CFIndex numGlyphs = CTFontGetGlyphCount(ctFont);
    762     SkASSERT(numGlyphs >= 1 && numGlyphs <= 0xFFFF);
    763     fGlyphCount = SkToU16(numGlyphs);
    764 
    765     // CT on (at least) 10.9 will size color glyphs down from the requested size, but not up.
    766     // As a result, it is necessary to know the actual device size and request that.
    767     SkVector scale;
    768     SkMatrix skTransform;
    769     fRec.computeMatrices(SkScalerContextRec::kVertical_PreMatrixScale, &scale, &skTransform,
    770                          nullptr, nullptr, &fFUnitMatrix);
    771     fTransform = MatrixToCGAffineTransform(skTransform);
    772     fInvTransform = CGAffineTransformInvert(fTransform);
    773 
    774     // The transform contains everything except the requested text size.
    775     // Some properties, like 'trak', are based on the text size (before applying the matrix).
    776     CGFloat textSize = ScalarToCG(scale.y());
    777     fCTFont.reset(ctfont_create_exact_copy(ctFont, textSize, nullptr));
    778     fCGFont.reset(CTFontCopyGraphicsFont(fCTFont, nullptr));
    779 
    780     // The fUnitMatrix includes the text size (and em) as it is used to scale the raw font data.
    781     SkScalar emPerFUnit = SkScalarInvert(SkIntToScalar(CGFontGetUnitsPerEm(fCGFont)));
    782     fFUnitMatrix.preScale(emPerFUnit, -emPerFUnit);
    783 }
    784 
    785 /** This is an implementation of CTFontDrawGlyphs for 10.6; it was introduced in 10.7. */
    786 static void legacy_CTFontDrawGlyphs(CTFontRef, const CGGlyph glyphs[], const CGPoint points[],
    787                                     size_t count, CGContextRef cg) {
    788     CGContextShowGlyphsAtPositions(cg, glyphs, points, count);
    789 }
    790 
    791 typedef decltype(legacy_CTFontDrawGlyphs) CTFontDrawGlyphsProc;
    792 
    793 static CTFontDrawGlyphsProc* choose_CTFontDrawGlyphs() {
    794     if (void* real = dlsym(RTLD_DEFAULT, "CTFontDrawGlyphs")) {
    795         return (CTFontDrawGlyphsProc*)real;
    796     }
    797     return &legacy_CTFontDrawGlyphs;
    798 }
    799 
    800 SK_DECLARE_STATIC_ONCE_PTR(CTFontDrawGlyphsProc, gCTFontDrawGlyphs);
    801 
    802 CGRGBPixel* Offscreen::getCG(const SkScalerContext_Mac& context, const SkGlyph& glyph,
    803                              CGGlyph glyphID, size_t* rowBytesPtr,
    804                              bool generateA8FromLCD) {
    805     auto ctFontDrawGlyphs = gCTFontDrawGlyphs.get(choose_CTFontDrawGlyphs);
    806 
    807     if (!fRGBSpace) {
    808         //It doesn't appear to matter what color space is specified.
    809         //Regular blends and antialiased text are always (s*a + d*(1-a))
    810         //and smoothed text is always g=2.0.
    811         fRGBSpace.reset(CGColorSpaceCreateDeviceRGB());
    812     }
    813 
    814     // default to kBW_Format
    815     bool doAA = false;
    816     bool doLCD = false;
    817 
    818     if (SkMask::kBW_Format != glyph.fMaskFormat) {
    819         doLCD = true;
    820         doAA = true;
    821     }
    822 
    823     // FIXME: lcd smoothed un-hinted rasterization unsupported.
    824     if (!generateA8FromLCD && SkMask::kA8_Format == glyph.fMaskFormat) {
    825         doLCD = false;
    826         doAA = true;
    827     }
    828 
    829     // If this font might have color glyphs, disable LCD as there's no way to support it.
    830     // CoreText doesn't tell us which format it ended up using, so we can't detect it.
    831     // A8 will end up black on transparent, but TODO: we can detect gray and set to A8.
    832     if (SkMask::kARGB32_Format == glyph.fMaskFormat) {
    833         doLCD = false;
    834     }
    835 
    836     size_t rowBytes = fSize.fWidth * sizeof(CGRGBPixel);
    837     if (!fCG || fSize.fWidth < glyph.fWidth || fSize.fHeight < glyph.fHeight) {
    838         if (fSize.fWidth < glyph.fWidth) {
    839             fSize.fWidth = RoundSize(glyph.fWidth);
    840         }
    841         if (fSize.fHeight < glyph.fHeight) {
    842             fSize.fHeight = RoundSize(glyph.fHeight);
    843         }
    844 
    845         rowBytes = fSize.fWidth * sizeof(CGRGBPixel);
    846         void* image = fImageStorage.reset(rowBytes * fSize.fHeight);
    847         const CGImageAlphaInfo alpha = (SkMask::kARGB32_Format == glyph.fMaskFormat)
    848                                      ? kCGImageAlphaPremultipliedFirst
    849                                      : kCGImageAlphaNoneSkipFirst;
    850         const CGBitmapInfo bitmapInfo = kCGBitmapByteOrder32Host | alpha;
    851         fCG.reset(CGBitmapContextCreate(image, fSize.fWidth, fSize.fHeight, 8,
    852                                         rowBytes, fRGBSpace, bitmapInfo));
    853 
    854         // Skia handles quantization and subpixel positioning,
    855         // so disable quantization and enabe subpixel positioning in CG.
    856         CGContextSetAllowsFontSubpixelQuantization(fCG, false);
    857         CGContextSetShouldSubpixelQuantizeFonts(fCG, false);
    858 
    859         // Because CG always draws from the horizontal baseline,
    860         // if there is a non-integral translation from the horizontal origin to the vertical origin,
    861         // then CG cannot draw the glyph in the correct location without subpixel positioning.
    862         CGContextSetAllowsFontSubpixelPositioning(fCG, true);
    863         CGContextSetShouldSubpixelPositionFonts(fCG, true);
    864 
    865         CGContextSetTextDrawingMode(fCG, kCGTextFill);
    866 
    867         // Draw black on white to create mask. (Special path exists to speed this up in CG.)
    868         CGContextSetGrayFillColor(fCG, 0.0f, 1.0f);
    869 
    870         // force our checks below to happen
    871         fDoAA = !doAA;
    872         fDoLCD = !doLCD;
    873 
    874         if (legacy_CTFontDrawGlyphs == ctFontDrawGlyphs) {
    875             // CTFontDrawGlyphs will apply the font, font size, and font matrix to the CGContext.
    876             // Our 'fake' one does not, so set up the CGContext here.
    877             CGContextSetFont(fCG, context.fCGFont);
    878             CGContextSetFontSize(fCG, CTFontGetSize(context.fCTFont));
    879         }
    880         CGContextSetTextMatrix(fCG, context.fTransform);
    881     }
    882 
    883     if (fDoAA != doAA) {
    884         CGContextSetShouldAntialias(fCG, doAA);
    885         fDoAA = doAA;
    886     }
    887     if (fDoLCD != doLCD) {
    888         CGContextSetShouldSmoothFonts(fCG, doLCD);
    889         fDoLCD = doLCD;
    890     }
    891 
    892     CGRGBPixel* image = (CGRGBPixel*)fImageStorage.get();
    893     // skip rows based on the glyph's height
    894     image += (fSize.fHeight - glyph.fHeight) * fSize.fWidth;
    895 
    896     // Erase to white (or transparent black if it's a color glyph, to not composite against white).
    897     uint32_t bgColor = (SkMask::kARGB32_Format != glyph.fMaskFormat) ? 0xFFFFFFFF : 0x00000000;
    898     sk_memset_rect32(image, bgColor, glyph.fWidth, glyph.fHeight, rowBytes);
    899 
    900     float subX = 0;
    901     float subY = 0;
    902     if (context.fDoSubPosition) {
    903         subX = SkFixedToFloat(glyph.getSubXFixed());
    904         subY = SkFixedToFloat(glyph.getSubYFixed());
    905     }
    906 
    907     // CoreText and CoreGraphics always draw using the horizontal baseline origin.
    908     if (context.fVertical) {
    909         SkPoint offset;
    910         context.getVerticalOffset(glyphID, &offset);
    911         subX += offset.fX;
    912         subY += offset.fY;
    913     }
    914 
    915     CGPoint point = CGPointMake(-glyph.fLeft + subX, glyph.fTop + glyph.fHeight - subY);
    916     // Prior to 10.10, CTFontDrawGlyphs acted like CGContextShowGlyphsAtPositions and took
    917     // 'positions' which are in text space. The glyph location (in device space) must be
    918     // mapped into text space, so that CG can convert it back into device space.
    919     // In 10.10.1, this is handled directly inCTFontDrawGlyphs.
    920     //
    921     // However, in 10.10.2 color glyphs no longer rotate based on the font transform.
    922     // So always make the font transform identity and place the transform on the context.
    923     point = CGPointApplyAffineTransform(point, context.fInvTransform);
    924 
    925     ctFontDrawGlyphs(context.fCTFont, &glyphID, &point, 1, fCG);
    926 
    927     SkASSERT(rowBytesPtr);
    928     *rowBytesPtr = rowBytes;
    929     return image;
    930 }
    931 
    932 void SkScalerContext_Mac::getVerticalOffset(CGGlyph glyphID, SkPoint* offset) const {
    933     // Snow Leopard returns cgVertOffset in completely un-transformed FUnits (em space, y up).
    934     // Lion and Leopard return cgVertOffset in CG units (pixels, y up).
    935     CGSize cgVertOffset;
    936     CTFontGetVerticalTranslationsForGlyphs(fCTFont, &glyphID, &cgVertOffset, 1);
    937     if (isSnowLeopard()) {
    938         SkPoint skVertOffset = { CGToScalar(cgVertOffset.width), CGToScalar(cgVertOffset.height) };
    939         // From FUnits (em space, y up) to SkGlyph units (pixels, y down).
    940         fFUnitMatrix.mapPoints(&skVertOffset, 1);
    941         *offset = skVertOffset;
    942         return;
    943     }
    944     cgVertOffset = CGSizeApplyAffineTransform(cgVertOffset, fTransform);
    945     SkPoint skVertOffset = { CGToScalar(cgVertOffset.width), CGToScalar(cgVertOffset.height) };
    946     // From CG units (pixels, y up) to SkGlyph units (pixels, y down).
    947     skVertOffset.fY = -skVertOffset.fY;
    948     *offset = skVertOffset;
    949 }
    950 
    951 uint16_t SkScalerContext_Mac::getFBoundingBoxesGlyphOffset() {
    952     if (fFBoundingBoxesGlyphOffset) {
    953         return fFBoundingBoxesGlyphOffset;
    954     }
    955     fFBoundingBoxesGlyphOffset = fGlyphCount; // fallback for all fonts
    956     AutoCGTable<SkOTTableHorizontalHeader> hheaTable(fCGFont);
    957     if (hheaTable.fData) {
    958         fFBoundingBoxesGlyphOffset = SkEndian_SwapBE16(hheaTable->numberOfHMetrics);
    959     }
    960     return fFBoundingBoxesGlyphOffset;
    961 }
    962 
    963 bool SkScalerContext_Mac::generateBBoxes() {
    964     if (fGeneratedFBoundingBoxes) {
    965         return SkToBool(fFBoundingBoxes.get());
    966     }
    967     fGeneratedFBoundingBoxes = true;
    968 
    969     AutoCGTable<SkOTTableHead> headTable(fCGFont);
    970     if (!headTable.fData) {
    971         return false;
    972     }
    973 
    974     AutoCGTable<SkOTTableIndexToLocation> locaTable(fCGFont);
    975     if (!locaTable.fData) {
    976         return false;
    977     }
    978 
    979     AutoCGTable<SkOTTableGlyph> glyfTable(fCGFont);
    980     if (!glyfTable.fData) {
    981         return false;
    982     }
    983 
    984     uint16_t entries = fGlyphCount - fFBoundingBoxesGlyphOffset;
    985     fFBoundingBoxes.reset(entries);
    986 
    987     SkOTTableHead::IndexToLocFormat locaFormat = headTable->indexToLocFormat;
    988     SkOTTableGlyph::Iterator glyphDataIter(*glyfTable.fData, *locaTable.fData, locaFormat);
    989     glyphDataIter.advance(fFBoundingBoxesGlyphOffset);
    990     for (uint16_t boundingBoxesIndex = 0; boundingBoxesIndex < entries; ++boundingBoxesIndex) {
    991         const SkOTTableGlyphData* glyphData = glyphDataIter.next();
    992         GlyphRect& rect = fFBoundingBoxes[boundingBoxesIndex];
    993         rect.fMinX = SkEndian_SwapBE16(glyphData->xMin);
    994         rect.fMinY = SkEndian_SwapBE16(glyphData->yMin);
    995         rect.fMaxX = SkEndian_SwapBE16(glyphData->xMax);
    996         rect.fMaxY = SkEndian_SwapBE16(glyphData->yMax);
    997     }
    998 
    999     return true;
   1000 }
   1001 
   1002 unsigned SkScalerContext_Mac::generateGlyphCount(void) {
   1003     return fGlyphCount;
   1004 }
   1005 
   1006 uint16_t SkScalerContext_Mac::generateCharToGlyph(SkUnichar uni) {
   1007     AUTO_CG_LOCK();
   1008 
   1009     CGGlyph cgGlyph[2];
   1010     UniChar theChar[2]; // UniChar is a UTF-16 16-bit code unit.
   1011 
   1012     // Get the glyph
   1013     size_t numUniChar = SkUTF16_FromUnichar(uni, theChar);
   1014     SkASSERT(sizeof(CGGlyph) <= sizeof(uint16_t));
   1015 
   1016     // Undocumented behavior of CTFontGetGlyphsForCharacters with non-bmp code points:
   1017     // When a surrogate pair is detected, the glyph index used is the index of the high surrogate.
   1018     // It is documented that if a mapping is unavailable, the glyph will be set to 0.
   1019     CTFontGetGlyphsForCharacters(fCTFont, theChar, cgGlyph, numUniChar);
   1020     return cgGlyph[0];
   1021 }
   1022 
   1023 void SkScalerContext_Mac::generateAdvance(SkGlyph* glyph) {
   1024     this->generateMetrics(glyph);
   1025 }
   1026 
   1027 void SkScalerContext_Mac::generateMetrics(SkGlyph* glyph) {
   1028     AUTO_CG_LOCK();
   1029 
   1030     const CGGlyph cgGlyph = (CGGlyph) glyph->getGlyphID();
   1031     glyph->zeroMetrics();
   1032 
   1033     // The following block produces cgAdvance in CG units (pixels, y up).
   1034     CGSize cgAdvance;
   1035     if (fVertical) {
   1036         CTFontGetAdvancesForGlyphs(fCTFont, kCTFontVerticalOrientation,
   1037                                    &cgGlyph, &cgAdvance, 1);
   1038         // Vertical advances are returned as widths instead of heights.
   1039         SkTSwap(cgAdvance.height, cgAdvance.width);
   1040         cgAdvance.height = -cgAdvance.height;
   1041     } else {
   1042         CTFontGetAdvancesForGlyphs(fCTFont, kCTFontHorizontalOrientation,
   1043                                    &cgGlyph, &cgAdvance, 1);
   1044     }
   1045     cgAdvance = CGSizeApplyAffineTransform(cgAdvance, fTransform);
   1046     glyph->fAdvanceX =  SkFloatToFixed_Check(cgAdvance.width);
   1047     glyph->fAdvanceY = -SkFloatToFixed_Check(cgAdvance.height);
   1048 
   1049     // The following produces skBounds in SkGlyph units (pixels, y down),
   1050     // or returns early if skBounds would be empty.
   1051     SkRect skBounds;
   1052 
   1053     // On Mountain Lion, CTFontGetBoundingRectsForGlyphs with kCTFontVerticalOrientation and
   1054     // CTFontGetVerticalTranslationsForGlyphs do not agree when using OTF CFF fonts.
   1055     // For TTF fonts these two do agree and we can use CTFontGetBoundingRectsForGlyphs to get
   1056     // the bounding box and CTFontGetVerticalTranslationsForGlyphs to then draw the glyph
   1057     // inside that bounding box. However, with OTF CFF fonts this does not work. It appears that
   1058     // CTFontGetBoundingRectsForGlyphs with kCTFontVerticalOrientation on OTF CFF fonts tries
   1059     // to center the glyph along the vertical baseline and also perform some mysterious shift
   1060     // along the baseline. CTFontGetVerticalTranslationsForGlyphs does not appear to perform
   1061     // these steps.
   1062     //
   1063     // It is not known which is correct (or if either is correct). However, we must always draw
   1064     // from the horizontal origin and must use CTFontGetVerticalTranslationsForGlyphs to draw.
   1065     // As a result, we do not call CTFontGetBoundingRectsForGlyphs for vertical glyphs.
   1066 
   1067     // On Snow Leopard, CTFontGetBoundingRectsForGlyphs ignores kCTFontVerticalOrientation and
   1068     // returns horizontal bounds.
   1069 
   1070     // On Lion and Mountain Lion, CTFontGetBoundingRectsForGlyphs has a bug which causes it to
   1071     // return a bad value in cgBounds.origin.x for SFNT fonts whose hhea::numberOfHMetrics is
   1072     // less than its maxp::numGlyphs. When this is the case we try to read the bounds from the
   1073     // font directly.
   1074     if ((isLion() || isMountainLion()) &&
   1075         (cgGlyph < fGlyphCount && cgGlyph >= getFBoundingBoxesGlyphOffset() && generateBBoxes()))
   1076     {
   1077         const GlyphRect& gRect = fFBoundingBoxes[cgGlyph - fFBoundingBoxesGlyphOffset];
   1078         if (gRect.fMinX >= gRect.fMaxX || gRect.fMinY >= gRect.fMaxY) {
   1079             return;
   1080         }
   1081         skBounds = SkRect::MakeLTRB(gRect.fMinX, gRect.fMinY, gRect.fMaxX, gRect.fMaxY);
   1082         // From FUnits (em space, y up) to SkGlyph units (pixels, y down).
   1083         fFUnitMatrix.mapRect(&skBounds);
   1084 
   1085     } else {
   1086         // CTFontGetBoundingRectsForGlyphs produces cgBounds in CG units (pixels, y up).
   1087         CGRect cgBounds;
   1088         CTFontGetBoundingRectsForGlyphs(fCTFont, kCTFontHorizontalOrientation,
   1089                                         &cgGlyph, &cgBounds, 1);
   1090         cgBounds = CGRectApplyAffineTransform(cgBounds, fTransform);
   1091 
   1092         // BUG?
   1093         // 0x200B (zero-advance space) seems to return a huge (garbage) bounds, when
   1094         // it should be empty. So, if we see a zero-advance, we check if it has an
   1095         // empty path or not, and if so, we jam the bounds to 0. Hopefully a zero-advance
   1096         // is rare, so we won't incur a big performance cost for this extra check.
   1097         if (0 == cgAdvance.width && 0 == cgAdvance.height) {
   1098             AutoCFRelease<CGPathRef> path(CTFontCreatePathForGlyph(fCTFont, cgGlyph, nullptr));
   1099             if (nullptr == path || CGPathIsEmpty(path)) {
   1100                 return;
   1101             }
   1102         }
   1103 
   1104         if (CGRectIsEmpty_inline(cgBounds)) {
   1105             return;
   1106         }
   1107 
   1108         // Convert cgBounds to SkGlyph units (pixels, y down).
   1109         skBounds = SkRect::MakeXYWH(cgBounds.origin.x, -cgBounds.origin.y - cgBounds.size.height,
   1110                                     cgBounds.size.width, cgBounds.size.height);
   1111     }
   1112 
   1113     if (fVertical) {
   1114         // Due to all of the vertical bounds bugs, skBounds is always the horizontal bounds.
   1115         // Convert these horizontal bounds into vertical bounds.
   1116         SkPoint offset;
   1117         getVerticalOffset(cgGlyph, &offset);
   1118         skBounds.offset(offset);
   1119     }
   1120 
   1121     // Currently the bounds are based on being rendered at (0,0).
   1122     // The top left must not move, since that is the base from which subpixel positioning is offset.
   1123     if (fDoSubPosition) {
   1124         skBounds.fRight += SkFixedToFloat(glyph->getSubXFixed());
   1125         skBounds.fBottom += SkFixedToFloat(glyph->getSubYFixed());
   1126     }
   1127 
   1128     SkIRect skIBounds;
   1129     skBounds.roundOut(&skIBounds);
   1130     // Expand the bounds by 1 pixel, to give CG room for anti-aliasing.
   1131     // Note that this outset is to allow room for LCD smoothed glyphs. However, the correct outset
   1132     // is not currently known, as CG dilates the outlines by some percentage.
   1133     // Note that if this context is A8 and not back-forming from LCD, there is no need to outset.
   1134     skIBounds.outset(1, 1);
   1135     glyph->fLeft = SkToS16(skIBounds.fLeft);
   1136     glyph->fTop = SkToS16(skIBounds.fTop);
   1137     glyph->fWidth = SkToU16(skIBounds.width());
   1138     glyph->fHeight = SkToU16(skIBounds.height());
   1139 }
   1140 
   1141 #include "SkColorPriv.h"
   1142 
   1143 static void build_power_table(uint8_t table[]) {
   1144     for (int i = 0; i < 256; i++) {
   1145         float x = i / 255.f;
   1146         int xx = SkScalarRoundToInt(x * x * 255);
   1147         table[i] = SkToU8(xx);
   1148     }
   1149 }
   1150 
   1151 /**
   1152  *  This will invert the gamma applied by CoreGraphics, so we can get linear
   1153  *  values.
   1154  *
   1155  *  CoreGraphics obscurely defaults to 2.0 as the smoothing gamma value.
   1156  *  The color space used does not appear to affect this choice.
   1157  */
   1158 static const uint8_t* getInverseGammaTableCoreGraphicSmoothing() {
   1159     static bool gInited;
   1160     static uint8_t gTableCoreGraphicsSmoothing[256];
   1161     if (!gInited) {
   1162         build_power_table(gTableCoreGraphicsSmoothing);
   1163         gInited = true;
   1164     }
   1165     return gTableCoreGraphicsSmoothing;
   1166 }
   1167 
   1168 static void cgpixels_to_bits(uint8_t dst[], const CGRGBPixel src[], int count) {
   1169     while (count > 0) {
   1170         uint8_t mask = 0;
   1171         for (int i = 7; i >= 0; --i) {
   1172             mask |= ((CGRGBPixel_getAlpha(*src++) >> 7) ^ 0x1) << i;
   1173             if (0 == --count) {
   1174                 break;
   1175             }
   1176         }
   1177         *dst++ = mask;
   1178     }
   1179 }
   1180 
   1181 template<bool APPLY_PREBLEND>
   1182 static inline uint8_t rgb_to_a8(CGRGBPixel rgb, const uint8_t* table8) {
   1183     U8CPU r = 0xFF - ((rgb >> 16) & 0xFF);
   1184     U8CPU g = 0xFF - ((rgb >>  8) & 0xFF);
   1185     U8CPU b = 0xFF - ((rgb >>  0) & 0xFF);
   1186     U8CPU lum = sk_apply_lut_if<APPLY_PREBLEND>(SkComputeLuminance(r, g, b), table8);
   1187 #if SK_SHOW_TEXT_BLIT_COVERAGE
   1188     lum = SkTMax(lum, (U8CPU)0x30);
   1189 #endif
   1190     return lum;
   1191 }
   1192 template<bool APPLY_PREBLEND>
   1193 static void rgb_to_a8(const CGRGBPixel* SK_RESTRICT cgPixels, size_t cgRowBytes,
   1194                       const SkGlyph& glyph, const uint8_t* table8) {
   1195     const int width = glyph.fWidth;
   1196     size_t dstRB = glyph.rowBytes();
   1197     uint8_t* SK_RESTRICT dst = (uint8_t*)glyph.fImage;
   1198 
   1199     for (int y = 0; y < glyph.fHeight; y++) {
   1200         for (int i = 0; i < width; ++i) {
   1201             dst[i] = rgb_to_a8<APPLY_PREBLEND>(cgPixels[i], table8);
   1202         }
   1203         cgPixels = (CGRGBPixel*)((char*)cgPixels + cgRowBytes);
   1204         dst += dstRB;
   1205     }
   1206 }
   1207 
   1208 template<bool APPLY_PREBLEND>
   1209 static inline uint16_t rgb_to_lcd16(CGRGBPixel rgb, const uint8_t* tableR,
   1210                                                     const uint8_t* tableG,
   1211                                                     const uint8_t* tableB) {
   1212     U8CPU r = sk_apply_lut_if<APPLY_PREBLEND>(0xFF - ((rgb >> 16) & 0xFF), tableR);
   1213     U8CPU g = sk_apply_lut_if<APPLY_PREBLEND>(0xFF - ((rgb >>  8) & 0xFF), tableG);
   1214     U8CPU b = sk_apply_lut_if<APPLY_PREBLEND>(0xFF - ((rgb >>  0) & 0xFF), tableB);
   1215 #if SK_SHOW_TEXT_BLIT_COVERAGE
   1216     r = SkTMax(r, (U8CPU)0x30);
   1217     g = SkTMax(g, (U8CPU)0x30);
   1218     b = SkTMax(b, (U8CPU)0x30);
   1219 #endif
   1220     return SkPack888ToRGB16(r, g, b);
   1221 }
   1222 template<bool APPLY_PREBLEND>
   1223 static void rgb_to_lcd16(const CGRGBPixel* SK_RESTRICT cgPixels, size_t cgRowBytes, const SkGlyph& glyph,
   1224                          const uint8_t* tableR, const uint8_t* tableG, const uint8_t* tableB) {
   1225     const int width = glyph.fWidth;
   1226     size_t dstRB = glyph.rowBytes();
   1227     uint16_t* SK_RESTRICT dst = (uint16_t*)glyph.fImage;
   1228 
   1229     for (int y = 0; y < glyph.fHeight; y++) {
   1230         for (int i = 0; i < width; i++) {
   1231             dst[i] = rgb_to_lcd16<APPLY_PREBLEND>(cgPixels[i], tableR, tableG, tableB);
   1232         }
   1233         cgPixels = (CGRGBPixel*)((char*)cgPixels + cgRowBytes);
   1234         dst = (uint16_t*)((char*)dst + dstRB);
   1235     }
   1236 }
   1237 
   1238 static SkPMColor cgpixels_to_pmcolor(CGRGBPixel rgb) {
   1239     U8CPU a = (rgb >> 24) & 0xFF;
   1240     U8CPU r = (rgb >> 16) & 0xFF;
   1241     U8CPU g = (rgb >>  8) & 0xFF;
   1242     U8CPU b = (rgb >>  0) & 0xFF;
   1243 #if SK_SHOW_TEXT_BLIT_COVERAGE
   1244     a = SkTMax(a, (U8CPU)0x30);
   1245 #endif
   1246     return SkPackARGB32(a, r, g, b);
   1247 }
   1248 
   1249 void SkScalerContext_Mac::generateImage(const SkGlyph& glyph) {
   1250     CGGlyph cgGlyph = (CGGlyph) glyph.getGlyphID();
   1251 
   1252     // FIXME: lcd smoothed un-hinted rasterization unsupported.
   1253     bool generateA8FromLCD = fRec.getHinting() != SkPaint::kNo_Hinting;
   1254 
   1255     // Draw the glyph
   1256     size_t cgRowBytes;
   1257     CGRGBPixel* cgPixels = fOffscreen.getCG(*this, glyph, cgGlyph, &cgRowBytes, generateA8FromLCD);
   1258     if (cgPixels == nullptr) {
   1259         return;
   1260     }
   1261 
   1262     // Fix the glyph
   1263     const bool isLCD = isLCDFormat(glyph.fMaskFormat);
   1264     if (isLCD || (glyph.fMaskFormat == SkMask::kA8_Format && supports_LCD() && generateA8FromLCD)) {
   1265         const uint8_t* table = getInverseGammaTableCoreGraphicSmoothing();
   1266 
   1267         //Note that the following cannot really be integrated into the
   1268         //pre-blend, since we may not be applying the pre-blend; when we aren't
   1269         //applying the pre-blend it means that a filter wants linear anyway.
   1270         //Other code may also be applying the pre-blend, so we'd need another
   1271         //one with this and one without.
   1272         CGRGBPixel* addr = cgPixels;
   1273         for (int y = 0; y < glyph.fHeight; ++y) {
   1274             for (int x = 0; x < glyph.fWidth; ++x) {
   1275                 int r = (addr[x] >> 16) & 0xFF;
   1276                 int g = (addr[x] >>  8) & 0xFF;
   1277                 int b = (addr[x] >>  0) & 0xFF;
   1278                 addr[x] = (table[r] << 16) | (table[g] << 8) | table[b];
   1279             }
   1280             addr = SkTAddOffset<CGRGBPixel>(addr, cgRowBytes);
   1281         }
   1282     }
   1283 
   1284     // Convert glyph to mask
   1285     switch (glyph.fMaskFormat) {
   1286         case SkMask::kLCD16_Format: {
   1287             if (fPreBlend.isApplicable()) {
   1288                 rgb_to_lcd16<true>(cgPixels, cgRowBytes, glyph,
   1289                                    fPreBlend.fR, fPreBlend.fG, fPreBlend.fB);
   1290             } else {
   1291                 rgb_to_lcd16<false>(cgPixels, cgRowBytes, glyph,
   1292                                     fPreBlend.fR, fPreBlend.fG, fPreBlend.fB);
   1293             }
   1294         } break;
   1295         case SkMask::kA8_Format: {
   1296             if (fPreBlend.isApplicable()) {
   1297                 rgb_to_a8<true>(cgPixels, cgRowBytes, glyph, fPreBlend.fG);
   1298             } else {
   1299                 rgb_to_a8<false>(cgPixels, cgRowBytes, glyph, fPreBlend.fG);
   1300             }
   1301         } break;
   1302         case SkMask::kBW_Format: {
   1303             const int width = glyph.fWidth;
   1304             size_t dstRB = glyph.rowBytes();
   1305             uint8_t* dst = (uint8_t*)glyph.fImage;
   1306             for (int y = 0; y < glyph.fHeight; y++) {
   1307                 cgpixels_to_bits(dst, cgPixels, width);
   1308                 cgPixels = (CGRGBPixel*)((char*)cgPixels + cgRowBytes);
   1309                 dst += dstRB;
   1310             }
   1311         } break;
   1312         case SkMask::kARGB32_Format: {
   1313             const int width = glyph.fWidth;
   1314             size_t dstRB = glyph.rowBytes();
   1315             SkPMColor* dst = (SkPMColor*)glyph.fImage;
   1316             for (int y = 0; y < glyph.fHeight; y++) {
   1317                 for (int x = 0; x < width; ++x) {
   1318                     dst[x] = cgpixels_to_pmcolor(cgPixels[x]);
   1319                 }
   1320                 cgPixels = (CGRGBPixel*)((char*)cgPixels + cgRowBytes);
   1321                 dst = (SkPMColor*)((char*)dst + dstRB);
   1322             }
   1323         } break;
   1324         default:
   1325             SkDEBUGFAIL("unexpected mask format");
   1326             break;
   1327     }
   1328 }
   1329 
   1330 /*
   1331  *  Our subpixel resolution is only 2 bits in each direction, so a scale of 4
   1332  *  seems sufficient, and possibly even correct, to allow the hinted outline
   1333  *  to be subpixel positioned.
   1334  */
   1335 #define kScaleForSubPixelPositionHinting (4.0f)
   1336 
   1337 void SkScalerContext_Mac::generatePath(const SkGlyph& glyph, SkPath* path) {
   1338     AUTO_CG_LOCK();
   1339 
   1340     SkScalar scaleX = SK_Scalar1;
   1341     SkScalar scaleY = SK_Scalar1;
   1342 
   1343     CGAffineTransform xform = fTransform;
   1344     /*
   1345      *  For subpixel positioning, we want to return an unhinted outline, so it
   1346      *  can be positioned nicely at fractional offsets. However, we special-case
   1347      *  if the baseline of the (horizontal) text is axis-aligned. In those cases
   1348      *  we want to retain hinting in the direction orthogonal to the baseline.
   1349      *  e.g. for horizontal baseline, we want to retain hinting in Y.
   1350      *  The way we remove hinting is to scale the font by some value (4) in that
   1351      *  direction, ask for the path, and then scale the path back down.
   1352      */
   1353     if (fDoSubPosition) {
   1354         SkMatrix m;
   1355         fRec.getSingleMatrix(&m);
   1356 
   1357         // start out by assuming that we want no hining in X and Y
   1358         scaleX = scaleY = kScaleForSubPixelPositionHinting;
   1359         // now see if we need to restore hinting for axis-aligned baselines
   1360         switch (SkComputeAxisAlignmentForHText(m)) {
   1361             case kX_SkAxisAlignment:
   1362                 scaleY = SK_Scalar1; // want hinting in the Y direction
   1363                 break;
   1364             case kY_SkAxisAlignment:
   1365                 scaleX = SK_Scalar1; // want hinting in the X direction
   1366                 break;
   1367             default:
   1368                 break;
   1369         }
   1370 
   1371         CGAffineTransform scale(CGAffineTransformMakeScale(ScalarToCG(scaleX), ScalarToCG(scaleY)));
   1372         xform = CGAffineTransformConcat(fTransform, scale);
   1373     }
   1374 
   1375     CGGlyph cgGlyph = (CGGlyph)glyph.getGlyphID();
   1376     AutoCFRelease<CGPathRef> cgPath(CTFontCreatePathForGlyph(fCTFont, cgGlyph, &xform));
   1377 
   1378     path->reset();
   1379     if (cgPath != nullptr) {
   1380         CGPathApply(cgPath, path, SkScalerContext_Mac::CTPathElement);
   1381     }
   1382 
   1383     if (fDoSubPosition) {
   1384         SkMatrix m;
   1385         m.setScale(SkScalarInvert(scaleX), SkScalarInvert(scaleY));
   1386         path->transform(m);
   1387     }
   1388     if (fVertical) {
   1389         SkPoint offset;
   1390         getVerticalOffset(cgGlyph, &offset);
   1391         path->offset(offset.fX, offset.fY);
   1392     }
   1393 }
   1394 
   1395 void SkScalerContext_Mac::generateFontMetrics(SkPaint::FontMetrics* metrics) {
   1396     if (nullptr == metrics) {
   1397         return;
   1398     }
   1399 
   1400     AUTO_CG_LOCK();
   1401 
   1402     CGRect theBounds = CTFontGetBoundingBox(fCTFont);
   1403 
   1404     metrics->fTop          = CGToScalar(-CGRectGetMaxY_inline(theBounds));
   1405     metrics->fAscent       = CGToScalar(-CTFontGetAscent(fCTFont));
   1406     metrics->fDescent      = CGToScalar( CTFontGetDescent(fCTFont));
   1407     metrics->fBottom       = CGToScalar(-CGRectGetMinY_inline(theBounds));
   1408     metrics->fLeading      = CGToScalar( CTFontGetLeading(fCTFont));
   1409     metrics->fAvgCharWidth = CGToScalar( CGRectGetWidth_inline(theBounds));
   1410     metrics->fXMin         = CGToScalar( CGRectGetMinX_inline(theBounds));
   1411     metrics->fXMax         = CGToScalar( CGRectGetMaxX_inline(theBounds));
   1412     metrics->fMaxCharWidth = metrics->fXMax - metrics->fXMin;
   1413     metrics->fXHeight      = CGToScalar( CTFontGetXHeight(fCTFont));
   1414     metrics->fCapHeight    = CGToScalar( CTFontGetCapHeight(fCTFont));
   1415     metrics->fUnderlineThickness = CGToScalar( CTFontGetUnderlineThickness(fCTFont));
   1416     metrics->fUnderlinePosition = -CGToScalar( CTFontGetUnderlinePosition(fCTFont));
   1417 
   1418     metrics->fFlags |= SkPaint::FontMetrics::kUnderlineThinknessIsValid_Flag;
   1419     metrics->fFlags |= SkPaint::FontMetrics::kUnderlinePositionIsValid_Flag;
   1420 }
   1421 
   1422 void SkScalerContext_Mac::CTPathElement(void *info, const CGPathElement *element) {
   1423     SkPath* skPath = (SkPath*)info;
   1424 
   1425     // Process the path element
   1426     switch (element->type) {
   1427         case kCGPathElementMoveToPoint:
   1428             skPath->moveTo(element->points[0].x, -element->points[0].y);
   1429             break;
   1430 
   1431         case kCGPathElementAddLineToPoint:
   1432             skPath->lineTo(element->points[0].x, -element->points[0].y);
   1433             break;
   1434 
   1435         case kCGPathElementAddQuadCurveToPoint:
   1436             skPath->quadTo(element->points[0].x, -element->points[0].y,
   1437                            element->points[1].x, -element->points[1].y);
   1438             break;
   1439 
   1440         case kCGPathElementAddCurveToPoint:
   1441             skPath->cubicTo(element->points[0].x, -element->points[0].y,
   1442                             element->points[1].x, -element->points[1].y,
   1443                             element->points[2].x, -element->points[2].y);
   1444             break;
   1445 
   1446         case kCGPathElementCloseSubpath:
   1447             skPath->close();
   1448             break;
   1449 
   1450         default:
   1451             SkDEBUGFAIL("Unknown path element!");
   1452             break;
   1453         }
   1454 }
   1455 
   1456 
   1457 ///////////////////////////////////////////////////////////////////////////////
   1458 
   1459 // Returns nullptr on failure
   1460 // Call must still manage its ownership of provider
   1461 static SkTypeface* create_from_dataProvider(CGDataProviderRef provider) {
   1462     AutoCFRelease<CGFontRef> cg(CGFontCreateWithDataProvider(provider));
   1463     if (nullptr == cg) {
   1464         return nullptr;
   1465     }
   1466     CTFontRef ct = CTFontCreateWithGraphicsFont(cg, 0, nullptr, nullptr);
   1467     return ct ? NewFromFontRef(ct, nullptr, nullptr, true) : nullptr;
   1468 }
   1469 
   1470 // Web fonts added to the the CTFont registry do not return their character set.
   1471 // Iterate through the font in this case. The existing caller caches the result,
   1472 // so the performance impact isn't too bad.
   1473 static void populate_glyph_to_unicode_slow(CTFontRef ctFont, CFIndex glyphCount,
   1474                                            SkTDArray<SkUnichar>* glyphToUnicode) {
   1475     glyphToUnicode->setCount(SkToInt(glyphCount));
   1476     SkUnichar* out = glyphToUnicode->begin();
   1477     sk_bzero(out, glyphCount * sizeof(SkUnichar));
   1478     UniChar unichar = 0;
   1479     while (glyphCount > 0) {
   1480         CGGlyph glyph;
   1481         if (CTFontGetGlyphsForCharacters(ctFont, &unichar, &glyph, 1)) {
   1482             out[glyph] = unichar;
   1483             --glyphCount;
   1484         }
   1485         if (++unichar == 0) {
   1486             break;
   1487         }
   1488     }
   1489 }
   1490 
   1491 // Construct Glyph to Unicode table.
   1492 // Unicode code points that require conjugate pairs in utf16 are not
   1493 // supported.
   1494 static void populate_glyph_to_unicode(CTFontRef ctFont, CFIndex glyphCount,
   1495                                       SkTDArray<SkUnichar>* glyphToUnicode) {
   1496     AutoCFRelease<CFCharacterSetRef> charSet(CTFontCopyCharacterSet(ctFont));
   1497     if (!charSet) {
   1498         populate_glyph_to_unicode_slow(ctFont, glyphCount, glyphToUnicode);
   1499         return;
   1500     }
   1501 
   1502     AutoCFRelease<CFDataRef> bitmap(CFCharacterSetCreateBitmapRepresentation(kCFAllocatorDefault,
   1503                                                                              charSet));
   1504     if (!bitmap) {
   1505         return;
   1506     }
   1507     CFIndex length = CFDataGetLength(bitmap);
   1508     if (!length) {
   1509         return;
   1510     }
   1511     if (length > 8192) {
   1512         // TODO: Add support for Unicode above 0xFFFF
   1513         // Consider only the BMP portion of the Unicode character points.
   1514         // The bitmap may contain other planes, up to plane 16.
   1515         // See http://developer.apple.com/library/ios/#documentation/CoreFoundation/Reference/CFCharacterSetRef/Reference/reference.html
   1516         length = 8192;
   1517     }
   1518     const UInt8* bits = CFDataGetBytePtr(bitmap);
   1519     glyphToUnicode->setCount(SkToInt(glyphCount));
   1520     SkUnichar* out = glyphToUnicode->begin();
   1521     sk_bzero(out, glyphCount * sizeof(SkUnichar));
   1522     for (int i = 0; i < length; i++) {
   1523         int mask = bits[i];
   1524         if (!mask) {
   1525             continue;
   1526         }
   1527         for (int j = 0; j < 8; j++) {
   1528             CGGlyph glyph;
   1529             UniChar unichar = static_cast<UniChar>((i << 3) + j);
   1530             if (mask & (1 << j) && CTFontGetGlyphsForCharacters(ctFont, &unichar, &glyph, 1)) {
   1531                 out[glyph] = unichar;
   1532             }
   1533         }
   1534     }
   1535 }
   1536 
   1537 static bool getWidthAdvance(CTFontRef ctFont, int gId, int16_t* data) {
   1538     CGSize advance;
   1539     advance.width = 0;
   1540     CGGlyph glyph = gId;
   1541     CTFontGetAdvancesForGlyphs(ctFont, kCTFontHorizontalOrientation, &glyph, &advance, 1);
   1542     *data = sk_float_round2int(advance.width);
   1543     return true;
   1544 }
   1545 
   1546 /** Assumes src and dst are not nullptr. */
   1547 static void CFStringToSkString(CFStringRef src, SkString* dst) {
   1548     // Reserve enough room for the worst-case string,
   1549     // plus 1 byte for the trailing null.
   1550     CFIndex length = CFStringGetMaximumSizeForEncoding(CFStringGetLength(src),
   1551                                                        kCFStringEncodingUTF8) + 1;
   1552     dst->resize(length);
   1553     CFStringGetCString(src, dst->writable_str(), length, kCFStringEncodingUTF8);
   1554     // Resize to the actual UTF-8 length used, stripping the null character.
   1555     dst->resize(strlen(dst->c_str()));
   1556 }
   1557 
   1558 SkAdvancedTypefaceMetrics* SkTypeface_Mac::onGetAdvancedTypefaceMetrics(
   1559         PerGlyphInfo perGlyphInfo,
   1560         const uint32_t* glyphIDs,
   1561         uint32_t glyphIDsCount) const {
   1562 
   1563     AUTO_CG_LOCK();
   1564 
   1565     CTFontRef originalCTFont = fFontRef.get();
   1566     AutoCFRelease<CTFontRef> ctFont(ctfont_create_exact_copy(
   1567             originalCTFont, CTFontGetUnitsPerEm(originalCTFont), nullptr));
   1568 
   1569     SkAdvancedTypefaceMetrics* info = new SkAdvancedTypefaceMetrics;
   1570 
   1571     {
   1572         AutoCFRelease<CFStringRef> fontName(CTFontCopyPostScriptName(ctFont));
   1573         if (fontName.get()) {
   1574             CFStringToSkString(fontName, &info->fFontName);
   1575         }
   1576     }
   1577 
   1578     CFIndex glyphCount = CTFontGetGlyphCount(ctFont);
   1579     info->fLastGlyphID = SkToU16(glyphCount - 1);
   1580     info->fEmSize = CTFontGetUnitsPerEm(ctFont);
   1581 
   1582     if (perGlyphInfo & kToUnicode_PerGlyphInfo) {
   1583         populate_glyph_to_unicode(ctFont, glyphCount, &info->fGlyphToUnicode);
   1584     }
   1585 
   1586     // If it's not a truetype font, mark it as 'other'. Assume that TrueType
   1587     // fonts always have both glyf and loca tables. At the least, this is what
   1588     // sfntly needs to subset the font. CTFontCopyAttribute() does not always
   1589     // succeed in determining this directly.
   1590     if (!this->getTableSize('glyf') || !this->getTableSize('loca')) {
   1591         return info;
   1592     }
   1593 
   1594     info->fType = SkAdvancedTypefaceMetrics::kTrueType_Font;
   1595     CTFontSymbolicTraits symbolicTraits = CTFontGetSymbolicTraits(ctFont);
   1596     if (symbolicTraits & kCTFontMonoSpaceTrait) {
   1597         info->fStyle |= SkAdvancedTypefaceMetrics::kFixedPitch_Style;
   1598     }
   1599     if (symbolicTraits & kCTFontItalicTrait) {
   1600         info->fStyle |= SkAdvancedTypefaceMetrics::kItalic_Style;
   1601     }
   1602     CTFontStylisticClass stylisticClass = symbolicTraits & kCTFontClassMaskTrait;
   1603     if (stylisticClass >= kCTFontOldStyleSerifsClass && stylisticClass <= kCTFontSlabSerifsClass) {
   1604         info->fStyle |= SkAdvancedTypefaceMetrics::kSerif_Style;
   1605     } else if (stylisticClass & kCTFontScriptsClass) {
   1606         info->fStyle |= SkAdvancedTypefaceMetrics::kScript_Style;
   1607     }
   1608     info->fItalicAngle = (int16_t) CTFontGetSlantAngle(ctFont);
   1609     info->fAscent = (int16_t) CTFontGetAscent(ctFont);
   1610     info->fDescent = (int16_t) CTFontGetDescent(ctFont);
   1611     info->fCapHeight = (int16_t) CTFontGetCapHeight(ctFont);
   1612     CGRect bbox = CTFontGetBoundingBox(ctFont);
   1613 
   1614     SkRect r;
   1615     r.set( CGToScalar(CGRectGetMinX_inline(bbox)),   // Left
   1616            CGToScalar(CGRectGetMaxY_inline(bbox)),   // Top
   1617            CGToScalar(CGRectGetMaxX_inline(bbox)),   // Right
   1618            CGToScalar(CGRectGetMinY_inline(bbox)));  // Bottom
   1619 
   1620     r.roundOut(&(info->fBBox));
   1621 
   1622     // Figure out a good guess for StemV - Min width of i, I, !, 1.
   1623     // This probably isn't very good with an italic font.
   1624     int16_t min_width = SHRT_MAX;
   1625     info->fStemV = 0;
   1626     static const UniChar stem_chars[] = {'i', 'I', '!', '1'};
   1627     const size_t count = sizeof(stem_chars) / sizeof(stem_chars[0]);
   1628     CGGlyph glyphs[count];
   1629     CGRect boundingRects[count];
   1630     if (CTFontGetGlyphsForCharacters(ctFont, stem_chars, glyphs, count)) {
   1631         CTFontGetBoundingRectsForGlyphs(ctFont, kCTFontHorizontalOrientation,
   1632                                         glyphs, boundingRects, count);
   1633         for (size_t i = 0; i < count; i++) {
   1634             int16_t width = (int16_t) boundingRects[i].size.width;
   1635             if (width > 0 && width < min_width) {
   1636                 min_width = width;
   1637                 info->fStemV = min_width;
   1638             }
   1639         }
   1640     }
   1641 
   1642     if (perGlyphInfo & kHAdvance_PerGlyphInfo) {
   1643         if (info->fStyle & SkAdvancedTypefaceMetrics::kFixedPitch_Style) {
   1644             skia_advanced_typeface_metrics_utils::appendRange(&info->fGlyphWidths, 0);
   1645             info->fGlyphWidths->fAdvance.append(1, &min_width);
   1646             skia_advanced_typeface_metrics_utils::finishRange(info->fGlyphWidths.get(), 0,
   1647                         SkAdvancedTypefaceMetrics::WidthRange::kDefault);
   1648         } else {
   1649             info->fGlyphWidths.reset(
   1650                 skia_advanced_typeface_metrics_utils::getAdvanceData(ctFont.get(),
   1651                                SkToInt(glyphCount),
   1652                                glyphIDs,
   1653                                glyphIDsCount,
   1654                                &getWidthAdvance));
   1655         }
   1656     }
   1657     return info;
   1658 }
   1659 
   1660 ///////////////////////////////////////////////////////////////////////////////
   1661 
   1662 static SK_SFNT_ULONG get_font_type_tag(const SkTypeface_Mac* typeface) {
   1663     CTFontRef ctFont = typeface->fFontRef.get();
   1664     AutoCFRelease<CFNumberRef> fontFormatRef(
   1665             static_cast<CFNumberRef>(CTFontCopyAttribute(ctFont, kCTFontFormatAttribute)));
   1666     if (!fontFormatRef) {
   1667         return 0;
   1668     }
   1669 
   1670     SInt32 fontFormatValue;
   1671     if (!CFNumberGetValue(fontFormatRef, kCFNumberSInt32Type, &fontFormatValue)) {
   1672         return 0;
   1673     }
   1674 
   1675     switch (fontFormatValue) {
   1676         case kCTFontFormatOpenTypePostScript:
   1677             return SkSFNTHeader::fontType_OpenTypeCFF::TAG;
   1678         case kCTFontFormatOpenTypeTrueType:
   1679             return SkSFNTHeader::fontType_WindowsTrueType::TAG;
   1680         case kCTFontFormatTrueType:
   1681             return SkSFNTHeader::fontType_MacTrueType::TAG;
   1682         case kCTFontFormatPostScript:
   1683             return SkSFNTHeader::fontType_PostScript::TAG;
   1684         case kCTFontFormatBitmap:
   1685             return SkSFNTHeader::fontType_MacTrueType::TAG;
   1686         case kCTFontFormatUnrecognized:
   1687         default:
   1688             //CT seems to be unreliable in being able to obtain the type,
   1689             //even if all we want is the first four bytes of the font resource.
   1690             //Just the presence of the FontForge 'FFTM' table seems to throw it off.
   1691             return SkSFNTHeader::fontType_WindowsTrueType::TAG;
   1692     }
   1693 }
   1694 
   1695 SkStreamAsset* SkTypeface_Mac::onOpenStream(int* ttcIndex) const {
   1696     SK_SFNT_ULONG fontType = get_font_type_tag(this);
   1697     if (0 == fontType) {
   1698         return nullptr;
   1699     }
   1700 
   1701     // get table tags
   1702     int numTables = this->countTables();
   1703     SkTDArray<SkFontTableTag> tableTags;
   1704     tableTags.setCount(numTables);
   1705     this->getTableTags(tableTags.begin());
   1706 
   1707     // calc total size for font, save sizes
   1708     SkTDArray<size_t> tableSizes;
   1709     size_t totalSize = sizeof(SkSFNTHeader) + sizeof(SkSFNTHeader::TableDirectoryEntry) * numTables;
   1710     for (int tableIndex = 0; tableIndex < numTables; ++tableIndex) {
   1711         size_t tableSize = this->getTableSize(tableTags[tableIndex]);
   1712         totalSize += (tableSize + 3) & ~3;
   1713         *tableSizes.append() = tableSize;
   1714     }
   1715 
   1716     // reserve memory for stream, and zero it (tables must be zero padded)
   1717     SkMemoryStream* stream = new SkMemoryStream(totalSize);
   1718     char* dataStart = (char*)stream->getMemoryBase();
   1719     sk_bzero(dataStart, totalSize);
   1720     char* dataPtr = dataStart;
   1721 
   1722     // compute font header entries
   1723     uint16_t entrySelector = 0;
   1724     uint16_t searchRange = 1;
   1725     while (searchRange < numTables >> 1) {
   1726         entrySelector++;
   1727         searchRange <<= 1;
   1728     }
   1729     searchRange <<= 4;
   1730     uint16_t rangeShift = (numTables << 4) - searchRange;
   1731 
   1732     // write font header
   1733     SkSFNTHeader* header = (SkSFNTHeader*)dataPtr;
   1734     header->fontType = fontType;
   1735     header->numTables = SkEndian_SwapBE16(numTables);
   1736     header->searchRange = SkEndian_SwapBE16(searchRange);
   1737     header->entrySelector = SkEndian_SwapBE16(entrySelector);
   1738     header->rangeShift = SkEndian_SwapBE16(rangeShift);
   1739     dataPtr += sizeof(SkSFNTHeader);
   1740 
   1741     // write tables
   1742     SkSFNTHeader::TableDirectoryEntry* entry = (SkSFNTHeader::TableDirectoryEntry*)dataPtr;
   1743     dataPtr += sizeof(SkSFNTHeader::TableDirectoryEntry) * numTables;
   1744     for (int tableIndex = 0; tableIndex < numTables; ++tableIndex) {
   1745         size_t tableSize = tableSizes[tableIndex];
   1746         this->getTableData(tableTags[tableIndex], 0, tableSize, dataPtr);
   1747         entry->tag = SkEndian_SwapBE32(tableTags[tableIndex]);
   1748         entry->checksum = SkEndian_SwapBE32(SkOTUtils::CalcTableChecksum((SK_OT_ULONG*)dataPtr,
   1749                                                                          tableSize));
   1750         entry->offset = SkEndian_SwapBE32(SkToU32(dataPtr - dataStart));
   1751         entry->logicalLength = SkEndian_SwapBE32(SkToU32(tableSize));
   1752 
   1753         dataPtr += (tableSize + 3) & ~3;
   1754         ++entry;
   1755     }
   1756 
   1757     *ttcIndex = 0;
   1758     return stream;
   1759 }
   1760 
   1761 struct NonDefaultAxesContext {
   1762     SkFixed* axisValue;
   1763     CFArrayRef cgAxes;
   1764 };
   1765 static void set_non_default_axes(CFTypeRef key, CFTypeRef value, void* context) {
   1766     NonDefaultAxesContext* self = static_cast<NonDefaultAxesContext*>(context);
   1767 
   1768     if (CFGetTypeID(key) != CFStringGetTypeID() || CFGetTypeID(value) != CFNumberGetTypeID()) {
   1769         return;
   1770     }
   1771 
   1772     // The key is a CFString which is a string from the 'name' table.
   1773     // Search the cgAxes for an axis with this name, and use its index to store the value.
   1774     CFIndex keyIndex = -1;
   1775     CFStringRef keyString = static_cast<CFStringRef>(key);
   1776     for (CFIndex i = 0; i < CFArrayGetCount(self->cgAxes); ++i) {
   1777         CFTypeRef cgAxis = CFArrayGetValueAtIndex(self->cgAxes, i);
   1778         if (CFGetTypeID(cgAxis) != CFDictionaryGetTypeID()) {
   1779             continue;
   1780         }
   1781 
   1782         CFDictionaryRef cgAxisDict = static_cast<CFDictionaryRef>(cgAxis);
   1783         CFTypeRef cgAxisName = CFDictionaryGetValue(cgAxisDict, kCGFontVariationAxisName);
   1784         if (!cgAxisName || CFGetTypeID(cgAxisName) != CFStringGetTypeID()) {
   1785             continue;
   1786         }
   1787         CFStringRef cgAxisNameString = static_cast<CFStringRef>(cgAxisName);
   1788         if (CFStringCompare(keyString, cgAxisNameString, 0) == kCFCompareEqualTo) {
   1789             keyIndex = i;
   1790             break;
   1791         }
   1792     }
   1793     if (keyIndex == -1) {
   1794         return;
   1795     }
   1796 
   1797     CFNumberRef valueNumber = static_cast<CFNumberRef>(value);
   1798     double valueDouble;
   1799     if (!CFNumberGetValue(valueNumber, kCFNumberDoubleType, &valueDouble) ||
   1800         valueDouble < SkFixedToDouble(SK_FixedMin) || SkFixedToDouble(SK_FixedMax) < valueDouble)
   1801     {
   1802         return;
   1803     }
   1804     self->axisValue[keyIndex] = SkDoubleToFixed(valueDouble);
   1805 }
   1806 static bool get_variations(CTFontRef fFontRef, CFIndex* cgAxisCount,
   1807                            SkAutoSTMalloc<4, SkFixed>* axisValues)
   1808 {
   1809     // CTFontCopyVariationAxes and CTFontCopyVariation do not work when applied to fonts which
   1810     // started life with CGFontCreateWithDataProvider (they simply always return nullptr).
   1811     // As a result, we are limited to CGFontCopyVariationAxes and CGFontCopyVariations.
   1812     AutoCFRelease<CGFontRef> cgFont(CTFontCopyGraphicsFont(fFontRef, nullptr));
   1813 
   1814     AutoCFRelease<CFDictionaryRef> cgVariations(CGFontCopyVariations(cgFont));
   1815     // If a font has no variations CGFontCopyVariations returns nullptr (instead of an empty dict).
   1816     if (!cgVariations.get()) {
   1817         return false;
   1818     }
   1819 
   1820     AutoCFRelease<CFArrayRef> cgAxes(CGFontCopyVariationAxes(cgFont));
   1821     *cgAxisCount = CFArrayGetCount(cgAxes);
   1822     axisValues->reset(*cgAxisCount);
   1823 
   1824     // Set all of the axes to their default values.
   1825     // Fail if any default value cannot be determined.
   1826     for (CFIndex i = 0; i < *cgAxisCount; ++i) {
   1827         CFTypeRef cgAxis = CFArrayGetValueAtIndex(cgAxes, i);
   1828         if (CFGetTypeID(cgAxis) != CFDictionaryGetTypeID()) {
   1829             return false;
   1830         }
   1831 
   1832         CFDictionaryRef cgAxisDict = static_cast<CFDictionaryRef>(cgAxis);
   1833         CFTypeRef axisDefaultValue = CFDictionaryGetValue(cgAxisDict,
   1834                                                           kCGFontVariationAxisDefaultValue);
   1835         if (!axisDefaultValue || CFGetTypeID(axisDefaultValue) != CFNumberGetTypeID()) {
   1836             return false;
   1837         }
   1838         CFNumberRef axisDefaultValueNumber = static_cast<CFNumberRef>(axisDefaultValue);
   1839         double axisDefaultValueDouble;
   1840         if (!CFNumberGetValue(axisDefaultValueNumber, kCFNumberDoubleType, &axisDefaultValueDouble))
   1841         {
   1842             return false;
   1843         }
   1844         if (axisDefaultValueDouble < SkFixedToDouble(SK_FixedMin) ||
   1845                                      SkFixedToDouble(SK_FixedMax) < axisDefaultValueDouble)
   1846         {
   1847             return false;
   1848         }
   1849         (*axisValues)[(int)i] = SkDoubleToFixed(axisDefaultValueDouble);
   1850     }
   1851 
   1852     // Override the default values with the given font's stated axis values.
   1853     NonDefaultAxesContext c = { axisValues->get(), cgAxes.get() };
   1854     CFDictionaryApplyFunction(cgVariations, set_non_default_axes, &c);
   1855 
   1856     return true;
   1857 }
   1858 SkFontData* SkTypeface_Mac::onCreateFontData() const {
   1859     int index;
   1860     SkAutoTDelete<SkStreamAsset> stream(this->onOpenStream(&index));
   1861 
   1862     CFIndex cgAxisCount;
   1863     SkAutoSTMalloc<4, SkFixed> axisValues;
   1864     if (get_variations(fFontRef, &cgAxisCount, &axisValues)) {
   1865         return new SkFontData(stream.detach(), index, axisValues.get(), cgAxisCount);
   1866     }
   1867     return new SkFontData(stream.detach(), index, nullptr, 0);
   1868 }
   1869 
   1870 ///////////////////////////////////////////////////////////////////////////////
   1871 ///////////////////////////////////////////////////////////////////////////////
   1872 
   1873 int SkTypeface_Mac::onGetUPEM() const {
   1874     AutoCFRelease<CGFontRef> cgFont(CTFontCopyGraphicsFont(fFontRef, nullptr));
   1875     return CGFontGetUnitsPerEm(cgFont);
   1876 }
   1877 
   1878 SkTypeface::LocalizedStrings* SkTypeface_Mac::onCreateFamilyNameIterator() const {
   1879     SkTypeface::LocalizedStrings* nameIter =
   1880         SkOTUtils::LocalizedStrings_NameTable::CreateForFamilyNames(*this);
   1881     if (nullptr == nameIter) {
   1882         AutoCFRelease<CFStringRef> cfLanguage;
   1883         AutoCFRelease<CFStringRef> cfFamilyName(
   1884             CTFontCopyLocalizedName(fFontRef, kCTFontFamilyNameKey, &cfLanguage));
   1885 
   1886         SkString skLanguage;
   1887         SkString skFamilyName;
   1888         if (cfLanguage.get()) {
   1889             CFStringToSkString(cfLanguage.get(), &skLanguage);
   1890         } else {
   1891             skLanguage = "und"; //undetermined
   1892         }
   1893         if (cfFamilyName.get()) {
   1894             CFStringToSkString(cfFamilyName.get(), &skFamilyName);
   1895         }
   1896 
   1897         nameIter = new SkOTUtils::LocalizedStrings_SingleName(skFamilyName, skLanguage);
   1898     }
   1899     return nameIter;
   1900 }
   1901 
   1902 // If, as is the case with web fonts, the CTFont data isn't available,
   1903 // the CGFont data may work. While the CGFont may always provide the
   1904 // right result, leave the CTFont code path to minimize disruption.
   1905 static CFDataRef copyTableFromFont(CTFontRef ctFont, SkFontTableTag tag) {
   1906     CFDataRef data = CTFontCopyTable(ctFont, (CTFontTableTag) tag,
   1907                                      kCTFontTableOptionNoOptions);
   1908     if (nullptr == data) {
   1909         AutoCFRelease<CGFontRef> cgFont(CTFontCopyGraphicsFont(ctFont, nullptr));
   1910         data = CGFontCopyTableForTag(cgFont, tag);
   1911     }
   1912     return data;
   1913 }
   1914 
   1915 int SkTypeface_Mac::onGetTableTags(SkFontTableTag tags[]) const {
   1916     AutoCFRelease<CFArrayRef> cfArray(CTFontCopyAvailableTables(fFontRef,
   1917                                                 kCTFontTableOptionNoOptions));
   1918     if (nullptr == cfArray) {
   1919         return 0;
   1920     }
   1921     int count = SkToInt(CFArrayGetCount(cfArray));
   1922     if (tags) {
   1923         for (int i = 0; i < count; ++i) {
   1924             uintptr_t fontTag = reinterpret_cast<uintptr_t>(CFArrayGetValueAtIndex(cfArray, i));
   1925             tags[i] = static_cast<SkFontTableTag>(fontTag);
   1926         }
   1927     }
   1928     return count;
   1929 }
   1930 
   1931 size_t SkTypeface_Mac::onGetTableData(SkFontTableTag tag, size_t offset,
   1932                                       size_t length, void* dstData) const {
   1933     AutoCFRelease<CFDataRef> srcData(copyTableFromFont(fFontRef, tag));
   1934     if (nullptr == srcData) {
   1935         return 0;
   1936     }
   1937 
   1938     size_t srcSize = CFDataGetLength(srcData);
   1939     if (offset >= srcSize) {
   1940         return 0;
   1941     }
   1942     if (length > srcSize - offset) {
   1943         length = srcSize - offset;
   1944     }
   1945     if (dstData) {
   1946         memcpy(dstData, CFDataGetBytePtr(srcData) + offset, length);
   1947     }
   1948     return length;
   1949 }
   1950 
   1951 SkScalerContext* SkTypeface_Mac::onCreateScalerContext(const SkDescriptor* desc) const {
   1952     return new SkScalerContext_Mac(const_cast<SkTypeface_Mac*>(this), desc);
   1953 }
   1954 
   1955 void SkTypeface_Mac::onFilterRec(SkScalerContextRec* rec) const {
   1956     if (rec->fFlags & SkScalerContext::kLCD_BGROrder_Flag ||
   1957         rec->fFlags & SkScalerContext::kLCD_Vertical_Flag)
   1958     {
   1959         rec->fMaskFormat = SkMask::kA8_Format;
   1960         // Render the glyphs as close as possible to what was requested.
   1961         // The above turns off subpixel rendering, but the user requested it.
   1962         // Normal hinting will cause the A8 masks to be generated from CoreGraphics subpixel masks.
   1963         // See comments below for more details.
   1964         rec->setHinting(SkPaint::kNormal_Hinting);
   1965     }
   1966 
   1967     unsigned flagsWeDontSupport = SkScalerContext::kDevKernText_Flag  |
   1968                                   SkScalerContext::kForceAutohinting_Flag  |
   1969                                   SkScalerContext::kLCD_BGROrder_Flag |
   1970                                   SkScalerContext::kLCD_Vertical_Flag;
   1971 
   1972     rec->fFlags &= ~flagsWeDontSupport;
   1973 
   1974     bool lcdSupport = supports_LCD();
   1975 
   1976     // Only two levels of hinting are supported.
   1977     // kNo_Hinting means avoid CoreGraphics outline dilation.
   1978     // kNormal_Hinting means CoreGraphics outline dilation is allowed.
   1979     // If there is no lcd support, hinting (dilation) cannot be supported.
   1980     SkPaint::Hinting hinting = rec->getHinting();
   1981     if (SkPaint::kSlight_Hinting == hinting || !lcdSupport) {
   1982         hinting = SkPaint::kNo_Hinting;
   1983     } else if (SkPaint::kFull_Hinting == hinting) {
   1984         hinting = SkPaint::kNormal_Hinting;
   1985     }
   1986     rec->setHinting(hinting);
   1987 
   1988     // FIXME: lcd smoothed un-hinted rasterization unsupported.
   1989     // Tracked by http://code.google.com/p/skia/issues/detail?id=915 .
   1990     // There is no current means to honor a request for unhinted lcd,
   1991     // so arbitrarilly ignore the hinting request and honor lcd.
   1992 
   1993     // Hinting and smoothing should be orthogonal, but currently they are not.
   1994     // CoreGraphics has no API to influence hinting. However, its lcd smoothed
   1995     // output is drawn from auto-dilated outlines (the amount of which is
   1996     // determined by AppleFontSmoothing). Its regular anti-aliased output is
   1997     // drawn from un-dilated outlines.
   1998 
   1999     // The behavior of Skia is as follows:
   2000     // [AA][no-hint]: generate AA using CoreGraphic's AA output.
   2001     // [AA][yes-hint]: use CoreGraphic's LCD output and reduce it to a single
   2002     // channel. This matches [LCD][yes-hint] in weight.
   2003     // [LCD][no-hint]: curently unable to honor, and must pick which to respect.
   2004     // Currenly side with LCD, effectively ignoring the hinting setting.
   2005     // [LCD][yes-hint]: generate LCD using CoreGraphic's LCD output.
   2006 
   2007     if (isLCDFormat(rec->fMaskFormat)) {
   2008         if (lcdSupport) {
   2009             //CoreGraphics creates 555 masks for smoothed text anyway.
   2010             rec->fMaskFormat = SkMask::kLCD16_Format;
   2011             rec->setHinting(SkPaint::kNormal_Hinting);
   2012         } else {
   2013             rec->fMaskFormat = SkMask::kA8_Format;
   2014         }
   2015     }
   2016 
   2017     // CoreText provides no information as to whether a glyph will be color or not.
   2018     // Fonts may mix outlines and bitmaps, so information is needed on a glyph by glyph basis.
   2019     // If a font contains an 'sbix' table, consider it to be a color font, and disable lcd.
   2020     if (fHasColorGlyphs) {
   2021         rec->fMaskFormat = SkMask::kARGB32_Format;
   2022     }
   2023 
   2024     // Unhinted A8 masks (those not derived from LCD masks) must respect SK_GAMMA_APPLY_TO_A8.
   2025     // All other masks can use regular gamma.
   2026     if (SkMask::kA8_Format == rec->fMaskFormat && SkPaint::kNo_Hinting == hinting) {
   2027 #ifndef SK_GAMMA_APPLY_TO_A8
   2028         rec->ignorePreBlend();
   2029 #endif
   2030     } else {
   2031         //CoreGraphics dialates smoothed text as needed.
   2032         rec->setContrast(0);
   2033     }
   2034 }
   2035 
   2036 // we take ownership of the ref
   2037 static const char* get_str(CFStringRef ref, SkString* str) {
   2038     if (nullptr == ref) {
   2039         return nullptr;
   2040     }
   2041     CFStringToSkString(ref, str);
   2042     CFSafeRelease(ref);
   2043     return str->c_str();
   2044 }
   2045 
   2046 void SkTypeface_Mac::onGetFamilyName(SkString* familyName) const {
   2047     get_str(CTFontCopyFamilyName(fFontRef), familyName);
   2048 }
   2049 
   2050 void SkTypeface_Mac::onGetFontDescriptor(SkFontDescriptor* desc,
   2051                                          bool* isLocalStream) const {
   2052     SkString tmpStr;
   2053 
   2054     desc->setFamilyName(get_str(CTFontCopyFamilyName(fFontRef), &tmpStr));
   2055     desc->setFullName(get_str(CTFontCopyFullName(fFontRef), &tmpStr));
   2056     desc->setPostscriptName(get_str(CTFontCopyPostScriptName(fFontRef), &tmpStr));
   2057     *isLocalStream = fIsLocalStream;
   2058 }
   2059 
   2060 int SkTypeface_Mac::onCharsToGlyphs(const void* chars, Encoding encoding,
   2061                                     uint16_t glyphs[], int glyphCount) const
   2062 {
   2063     // Undocumented behavior of CTFontGetGlyphsForCharacters with non-bmp code points:
   2064     // When a surrogate pair is detected, the glyph index used is the index of the high surrogate.
   2065     // It is documented that if a mapping is unavailable, the glyph will be set to 0.
   2066 
   2067     SkAutoSTMalloc<1024, UniChar> charStorage;
   2068     const UniChar* src; // UniChar is a UTF-16 16-bit code unit.
   2069     int srcCount;
   2070     switch (encoding) {
   2071         case kUTF8_Encoding: {
   2072             const char* utf8 = reinterpret_cast<const char*>(chars);
   2073             UniChar* utf16 = charStorage.reset(2 * glyphCount);
   2074             src = utf16;
   2075             for (int i = 0; i < glyphCount; ++i) {
   2076                 SkUnichar uni = SkUTF8_NextUnichar(&utf8);
   2077                 utf16 += SkUTF16_FromUnichar(uni, utf16);
   2078             }
   2079             srcCount = SkToInt(utf16 - src);
   2080             break;
   2081         }
   2082         case kUTF16_Encoding: {
   2083             src = reinterpret_cast<const UniChar*>(chars);
   2084             int extra = 0;
   2085             for (int i = 0; i < glyphCount; ++i) {
   2086                 if (SkUTF16_IsHighSurrogate(src[i + extra])) {
   2087                     ++extra;
   2088                 }
   2089             }
   2090             srcCount = glyphCount + extra;
   2091             break;
   2092         }
   2093         case kUTF32_Encoding: {
   2094             const SkUnichar* utf32 = reinterpret_cast<const SkUnichar*>(chars);
   2095             UniChar* utf16 = charStorage.reset(2 * glyphCount);
   2096             src = utf16;
   2097             for (int i = 0; i < glyphCount; ++i) {
   2098                 utf16 += SkUTF16_FromUnichar(utf32[i], utf16);
   2099             }
   2100             srcCount = SkToInt(utf16 - src);
   2101             break;
   2102         }
   2103     }
   2104 
   2105     // If glyphs is nullptr, CT still needs glyph storage for finding the first failure.
   2106     // Also, if there are any non-bmp code points, the provided 'glyphs' storage will be inadequate.
   2107     SkAutoSTMalloc<1024, uint16_t> glyphStorage;
   2108     uint16_t* macGlyphs = glyphs;
   2109     if (nullptr == macGlyphs || srcCount > glyphCount) {
   2110         macGlyphs = glyphStorage.reset(srcCount);
   2111     }
   2112 
   2113     bool allEncoded = CTFontGetGlyphsForCharacters(fFontRef, src, macGlyphs, srcCount);
   2114 
   2115     // If there were any non-bmp, then copy and compact.
   2116     // If 'glyphs' is nullptr, then compact glyphStorage in-place.
   2117     // If all are bmp and 'glyphs' is non-nullptr, 'glyphs' already contains the compact glyphs.
   2118     // If some are non-bmp and 'glyphs' is non-nullptr, copy and compact into 'glyphs'.
   2119     uint16_t* compactedGlyphs = glyphs;
   2120     if (nullptr == compactedGlyphs) {
   2121         compactedGlyphs = macGlyphs;
   2122     }
   2123     if (srcCount > glyphCount) {
   2124         int extra = 0;
   2125         for (int i = 0; i < glyphCount; ++i) {
   2126             compactedGlyphs[i] = macGlyphs[i + extra];
   2127             if (SkUTF16_IsHighSurrogate(src[i + extra])) {
   2128                 ++extra;
   2129             }
   2130         }
   2131     }
   2132 
   2133     if (allEncoded) {
   2134         return glyphCount;
   2135     }
   2136 
   2137     // If we got false, then we need to manually look for first failure.
   2138     for (int i = 0; i < glyphCount; ++i) {
   2139         if (0 == compactedGlyphs[i]) {
   2140             return i;
   2141         }
   2142     }
   2143     // Odd to get here, as we expected CT to have returned true up front.
   2144     return glyphCount;
   2145 }
   2146 
   2147 int SkTypeface_Mac::onCountGlyphs() const {
   2148     return SkToInt(CTFontGetGlyphCount(fFontRef));
   2149 }
   2150 
   2151 ///////////////////////////////////////////////////////////////////////////////
   2152 ///////////////////////////////////////////////////////////////////////////////
   2153 
   2154 static bool find_desc_str(CTFontDescriptorRef desc, CFStringRef name, SkString* value) {
   2155     AutoCFRelease<CFStringRef> ref((CFStringRef)CTFontDescriptorCopyAttribute(desc, name));
   2156     if (nullptr == ref.get()) {
   2157         return false;
   2158     }
   2159     CFStringToSkString(ref, value);
   2160     return true;
   2161 }
   2162 
   2163 #include "SkFontMgr.h"
   2164 
   2165 static inline int sqr(int value) {
   2166     SkASSERT(SkAbs32(value) < 0x7FFF);  // check for overflow
   2167     return value * value;
   2168 }
   2169 
   2170 // We normalize each axis (weight, width, italic) to be base-900
   2171 static int compute_metric(const SkFontStyle& a, const SkFontStyle& b) {
   2172     return sqr(a.weight() - b.weight()) +
   2173            sqr((a.width() - b.width()) * 100) +
   2174            sqr((a.isItalic() != b.isItalic()) * 900);
   2175 }
   2176 
   2177 static SkTypeface* createFromDesc(CFStringRef cfFamilyName, CTFontDescriptorRef desc) {
   2178     NameStyle cacheRequest;
   2179     SkString skFamilyName;
   2180     CFStringToSkString(cfFamilyName, &skFamilyName);
   2181     cacheRequest.fName = skFamilyName.c_str();
   2182     cacheRequest.fStyle = fontstyle_from_descriptor(desc);
   2183 
   2184     SkTypeface* face = SkTypefaceCache::FindByProcAndRef(find_by_NameStyle, &cacheRequest);
   2185     if (face) {
   2186         return face;
   2187     }
   2188 
   2189     AutoCFRelease<CTFontRef> ctFont(CTFontCreateWithFontDescriptor(desc, 0, nullptr));
   2190     if (!ctFont) {
   2191         return nullptr;
   2192     }
   2193 
   2194     bool isFixedPitch;
   2195     (void)computeStyleBits(ctFont, &isFixedPitch);
   2196 
   2197     face = new SkTypeface_Mac(ctFont.detach(), nullptr, cacheRequest.fStyle, isFixedPitch,
   2198                               skFamilyName.c_str(), false);
   2199     SkTypefaceCache::Add(face, face->fontStyle());
   2200     return face;
   2201 }
   2202 
   2203 class SkFontStyleSet_Mac : public SkFontStyleSet {
   2204 public:
   2205     SkFontStyleSet_Mac(CFStringRef familyName, CTFontDescriptorRef desc)
   2206         : fArray(CTFontDescriptorCreateMatchingFontDescriptors(desc, nullptr))
   2207         , fFamilyName(familyName)
   2208         , fCount(0) {
   2209         CFRetain(familyName);
   2210         if (nullptr == fArray) {
   2211             fArray = CFArrayCreate(nullptr, nullptr, 0, nullptr);
   2212         }
   2213         fCount = SkToInt(CFArrayGetCount(fArray));
   2214     }
   2215 
   2216     virtual ~SkFontStyleSet_Mac() {
   2217         CFRelease(fArray);
   2218         CFRelease(fFamilyName);
   2219     }
   2220 
   2221     int count() override {
   2222         return fCount;
   2223     }
   2224 
   2225     void getStyle(int index, SkFontStyle* style, SkString* name) override {
   2226         SkASSERT((unsigned)index < (unsigned)fCount);
   2227         CTFontDescriptorRef desc = (CTFontDescriptorRef)CFArrayGetValueAtIndex(fArray, index);
   2228         if (style) {
   2229             *style = fontstyle_from_descriptor(desc);
   2230         }
   2231         if (name) {
   2232             if (!find_desc_str(desc, kCTFontStyleNameAttribute, name)) {
   2233                 name->reset();
   2234             }
   2235         }
   2236     }
   2237 
   2238     SkTypeface* createTypeface(int index) override {
   2239         SkASSERT((unsigned)index < (unsigned)CFArrayGetCount(fArray));
   2240         CTFontDescriptorRef desc = (CTFontDescriptorRef)CFArrayGetValueAtIndex(fArray, index);
   2241 
   2242         return createFromDesc(fFamilyName, desc);
   2243     }
   2244 
   2245     SkTypeface* matchStyle(const SkFontStyle& pattern) override {
   2246         if (0 == fCount) {
   2247             return nullptr;
   2248         }
   2249         return createFromDesc(fFamilyName, findMatchingDesc(pattern));
   2250     }
   2251 
   2252 private:
   2253     CFArrayRef  fArray;
   2254     CFStringRef fFamilyName;
   2255     int         fCount;
   2256 
   2257     CTFontDescriptorRef findMatchingDesc(const SkFontStyle& pattern) const {
   2258         int bestMetric = SK_MaxS32;
   2259         CTFontDescriptorRef bestDesc = nullptr;
   2260 
   2261         for (int i = 0; i < fCount; ++i) {
   2262             CTFontDescriptorRef desc = (CTFontDescriptorRef)CFArrayGetValueAtIndex(fArray, i);
   2263             int metric = compute_metric(pattern, fontstyle_from_descriptor(desc));
   2264             if (0 == metric) {
   2265                 return desc;
   2266             }
   2267             if (metric < bestMetric) {
   2268                 bestMetric = metric;
   2269                 bestDesc = desc;
   2270             }
   2271         }
   2272         SkASSERT(bestDesc);
   2273         return bestDesc;
   2274     }
   2275 };
   2276 
   2277 class SkFontMgr_Mac : public SkFontMgr {
   2278     CFArrayRef  fNames;
   2279     int         fCount;
   2280 
   2281     CFStringRef stringAt(int index) const {
   2282         SkASSERT((unsigned)index < (unsigned)fCount);
   2283         return (CFStringRef)CFArrayGetValueAtIndex(fNames, index);
   2284     }
   2285 
   2286     static SkFontStyleSet* CreateSet(CFStringRef cfFamilyName) {
   2287         AutoCFRelease<CFMutableDictionaryRef> cfAttr(
   2288                  CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
   2289                                            &kCFTypeDictionaryKeyCallBacks,
   2290                                            &kCFTypeDictionaryValueCallBacks));
   2291 
   2292         CFDictionaryAddValue(cfAttr, kCTFontFamilyNameAttribute, cfFamilyName);
   2293 
   2294         AutoCFRelease<CTFontDescriptorRef> desc(
   2295                                 CTFontDescriptorCreateWithAttributes(cfAttr));
   2296         return new SkFontStyleSet_Mac(cfFamilyName, desc);
   2297     }
   2298 
   2299 public:
   2300     SkFontMgr_Mac()
   2301         : fNames(SkCTFontManagerCopyAvailableFontFamilyNames())
   2302         , fCount(fNames ? SkToInt(CFArrayGetCount(fNames)) : 0) {}
   2303 
   2304     virtual ~SkFontMgr_Mac() {
   2305         CFSafeRelease(fNames);
   2306     }
   2307 
   2308 protected:
   2309     int onCountFamilies() const override {
   2310         return fCount;
   2311     }
   2312 
   2313     void onGetFamilyName(int index, SkString* familyName) const override {
   2314         if ((unsigned)index < (unsigned)fCount) {
   2315             CFStringToSkString(this->stringAt(index), familyName);
   2316         } else {
   2317             familyName->reset();
   2318         }
   2319     }
   2320 
   2321     SkFontStyleSet* onCreateStyleSet(int index) const override {
   2322         if ((unsigned)index >= (unsigned)fCount) {
   2323             return nullptr;
   2324         }
   2325         return CreateSet(this->stringAt(index));
   2326     }
   2327 
   2328     SkFontStyleSet* onMatchFamily(const char familyName[]) const override {
   2329         AutoCFRelease<CFStringRef> cfName(make_CFString(familyName));
   2330         return CreateSet(cfName);
   2331     }
   2332 
   2333     virtual SkTypeface* onMatchFamilyStyle(const char familyName[],
   2334                                            const SkFontStyle& fontStyle) const override {
   2335         SkAutoTUnref<SkFontStyleSet> sset(this->matchFamily(familyName));
   2336         return sset->matchStyle(fontStyle);
   2337     }
   2338 
   2339     virtual SkTypeface* onMatchFamilyStyleCharacter(const char familyName[], const SkFontStyle&,
   2340                                                     const char* bcp47[], int bcp47Count,
   2341                                                     SkUnichar character) const override {
   2342         return nullptr;
   2343     }
   2344 
   2345     virtual SkTypeface* onMatchFaceStyle(const SkTypeface* familyMember,
   2346                                          const SkFontStyle&) const override {
   2347         return nullptr;
   2348     }
   2349 
   2350     SkTypeface* onCreateFromData(SkData* data, int ttcIndex) const override {
   2351         AutoCFRelease<CGDataProviderRef> pr(SkCreateDataProviderFromData(data));
   2352         if (nullptr == pr) {
   2353             return nullptr;
   2354         }
   2355         return create_from_dataProvider(pr);
   2356     }
   2357 
   2358     SkTypeface* onCreateFromStream(SkStreamAsset* stream, int ttcIndex) const override {
   2359         AutoCFRelease<CGDataProviderRef> pr(SkCreateDataProviderFromStream(stream));
   2360         if (nullptr == pr) {
   2361             return nullptr;
   2362         }
   2363         return create_from_dataProvider(pr);
   2364     }
   2365 
   2366     static CFNumberRef get_tag_for_name(CFStringRef name, CFArrayRef ctAxes) {
   2367         CFIndex ctAxisCount = CFArrayGetCount(ctAxes);
   2368         for (int i = 0; i < ctAxisCount; ++i) {
   2369             CFTypeRef ctAxisInfo = CFArrayGetValueAtIndex(ctAxes, i);
   2370             if (CFDictionaryGetTypeID() != CFGetTypeID(ctAxisInfo)) {
   2371                 return nullptr;
   2372             }
   2373             CFDictionaryRef ctAxisInfoDict = static_cast<CFDictionaryRef>(ctAxisInfo);
   2374 
   2375             CFTypeRef ctAxisName = CFDictionaryGetValue(ctAxisInfoDict,
   2376                                                         kCTFontVariationAxisNameKey);
   2377             if (!ctAxisName || CFGetTypeID(ctAxisName) != CFStringGetTypeID()) {
   2378                 return nullptr;
   2379             }
   2380 
   2381             if (CFEqual(name, ctAxisName)) {
   2382                 CFTypeRef tag = CFDictionaryGetValue(ctAxisInfoDict,
   2383                                                      kCTFontVariationAxisIdentifierKey);
   2384                 if (!tag || CFGetTypeID(tag) != CFNumberGetTypeID()) {
   2385                     return nullptr;
   2386                 }
   2387                 return static_cast<CFNumberRef>(tag);
   2388             }
   2389         }
   2390         return nullptr;
   2391     }
   2392     static CFDictionaryRef get_axes(CGFontRef cg, const FontParameters& params) {
   2393         AutoCFRelease<CFArrayRef> cgAxes(CGFontCopyVariationAxes(cg));
   2394         if (!cgAxes) {
   2395             return nullptr;
   2396         }
   2397         CFIndex axisCount = CFArrayGetCount(cgAxes);
   2398 
   2399         // The CGFont variation data is keyed by name, and lacks the tag.
   2400         // The CTFont variation data is keyed by tag, and also has the name.
   2401         // We would like to work with CTFont variaitons, but creating a CTFont font with
   2402         // CTFont variation dictionary runs into bugs. So use the CTFont variation data
   2403         // to match names to tags to create the appropriate CGFont.
   2404         AutoCFRelease<CTFontRef> ct(CTFontCreateWithGraphicsFont(cg, 0, nullptr, nullptr));
   2405         AutoCFRelease<CFArrayRef> ctAxes(CTFontCopyVariationAxes(ct));
   2406         if (!ctAxes || CFArrayGetCount(ctAxes) != axisCount) {
   2407             return nullptr;
   2408         }
   2409 
   2410         int paramAxisCount;
   2411         const FontParameters::Axis* paramAxes = params.getAxes(&paramAxisCount);
   2412 
   2413         CFMutableDictionaryRef dict = CFDictionaryCreateMutable(kCFAllocatorDefault, axisCount,
   2414                                                                 &kCFTypeDictionaryKeyCallBacks,
   2415                                                                 &kCFTypeDictionaryValueCallBacks);
   2416         for (int i = 0; i < axisCount; ++i) {
   2417             CFTypeRef axisInfo = CFArrayGetValueAtIndex(cgAxes, i);
   2418             if (CFDictionaryGetTypeID() != CFGetTypeID(axisInfo)) {
   2419                 return nullptr;
   2420             }
   2421             CFDictionaryRef axisInfoDict = static_cast<CFDictionaryRef>(axisInfo);
   2422 
   2423             CFTypeRef axisName = CFDictionaryGetValue(axisInfoDict, kCGFontVariationAxisName);
   2424             if (!axisName || CFGetTypeID(axisName) != CFStringGetTypeID()) {
   2425                 return nullptr;
   2426             }
   2427 
   2428             CFNumberRef tagNumber = get_tag_for_name(static_cast<CFStringRef>(axisName), ctAxes);
   2429             if (!tagNumber) {
   2430                 // Could not find a tag to go with the name of this index.
   2431                 // This would be a bug in CG/CT.
   2432                 continue;
   2433             }
   2434             int64_t tagLong;
   2435             if (!CFNumberGetValue(tagNumber, kCFNumberSInt64Type, &tagLong)) {
   2436                 return nullptr;
   2437             }
   2438 
   2439             // The variation axes can be set to any value, but cg will effectively pin them.
   2440             // Pin them here to normalize.
   2441             CFTypeRef min = CFDictionaryGetValue(axisInfoDict, kCGFontVariationAxisMinValue);
   2442             CFTypeRef max = CFDictionaryGetValue(axisInfoDict, kCGFontVariationAxisMaxValue);
   2443             CFTypeRef def = CFDictionaryGetValue(axisInfoDict, kCGFontVariationAxisDefaultValue);
   2444             if (!min || CFGetTypeID(min) != CFNumberGetTypeID() ||
   2445                 !max || CFGetTypeID(max) != CFNumberGetTypeID() ||
   2446                 !def || CFGetTypeID(def) != CFNumberGetTypeID())
   2447             {
   2448                 return nullptr;
   2449             }
   2450             CFNumberRef minNumber = static_cast<CFNumberRef>(min);
   2451             CFNumberRef maxNumber = static_cast<CFNumberRef>(max);
   2452             CFNumberRef defNumber = static_cast<CFNumberRef>(def);
   2453             double minDouble;
   2454             double maxDouble;
   2455             double defDouble;
   2456             if (!CFNumberGetValue(minNumber, kCFNumberDoubleType, &minDouble) ||
   2457                 !CFNumberGetValue(maxNumber, kCFNumberDoubleType, &maxDouble) ||
   2458                 !CFNumberGetValue(defNumber, kCFNumberDoubleType, &defDouble))
   2459             {
   2460                 return nullptr;
   2461             }
   2462 
   2463             double value = defDouble;
   2464             for (int j = 0; j < paramAxisCount; ++j) {
   2465                 if (paramAxes[j].fTag == tagLong) {
   2466                     value = SkTPin(SkScalarToDouble(paramAxes[j].fStyleValue),minDouble,maxDouble);
   2467                     break;
   2468                 }
   2469             }
   2470             CFNumberRef valueNumber = CFNumberCreate(kCFAllocatorDefault, kCFNumberDoubleType,
   2471                                                      &value);
   2472             CFDictionaryAddValue(dict, axisName, valueNumber);
   2473             CFRelease(valueNumber);
   2474         }
   2475         return dict;
   2476     }
   2477     SkTypeface* onCreateFromStream(SkStreamAsset* s, const FontParameters& params) const override {
   2478         AutoCFRelease<CGDataProviderRef> provider(SkCreateDataProviderFromStream(s));
   2479         if (nullptr == provider) {
   2480             return nullptr;
   2481         }
   2482         AutoCFRelease<CGFontRef> cg(CGFontCreateWithDataProvider(provider));
   2483         if (nullptr == cg) {
   2484             return nullptr;
   2485         }
   2486 
   2487         AutoCFRelease<CFDictionaryRef> cgVariations(get_axes(cg, params));
   2488         // The CGFontRef returned by CGFontCreateCopyWithVariations when the passed CGFontRef was
   2489         // created from a data provider does not appear to have any ownership of the underlying
   2490         // data. The original CGFontRef must be kept alive until the copy will no longer be used.
   2491         AutoCFRelease<CGFontRef> cgVariant;
   2492         if (cgVariations) {
   2493             cgVariant.reset(CGFontCreateCopyWithVariations(cg, cgVariations));
   2494         } else {
   2495             cgVariant.reset(cg.detach());
   2496         }
   2497 
   2498         CTFontRef ct = CTFontCreateWithGraphicsFont(cgVariant, 0, nullptr, nullptr);
   2499         if (!ct) {
   2500             return nullptr;
   2501         }
   2502         return NewFromFontRef(ct, cg.detach(), nullptr, true);
   2503     }
   2504 
   2505     static CFDictionaryRef get_axes(CGFontRef cg, SkFontData* fontData) {
   2506         AutoCFRelease<CFArrayRef> cgAxes(CGFontCopyVariationAxes(cg));
   2507         if (!cgAxes) {
   2508             return nullptr;
   2509         }
   2510 
   2511         CFIndex axisCount = CFArrayGetCount(cgAxes);
   2512         if (0 == axisCount || axisCount != fontData->getAxisCount()) {
   2513             return nullptr;
   2514         }
   2515 
   2516         CFMutableDictionaryRef dict = CFDictionaryCreateMutable(kCFAllocatorDefault, axisCount,
   2517                                                                 &kCFTypeDictionaryKeyCallBacks,
   2518                                                                 &kCFTypeDictionaryValueCallBacks);
   2519         for (int i = 0; i < fontData->getAxisCount(); ++i) {
   2520             CFTypeRef axisInfo = CFArrayGetValueAtIndex(cgAxes, i);
   2521             if (CFDictionaryGetTypeID() != CFGetTypeID(axisInfo)) {
   2522                 return nullptr;
   2523             }
   2524             CFDictionaryRef axisInfoDict = static_cast<CFDictionaryRef>(axisInfo);
   2525 
   2526             CFTypeRef axisName = CFDictionaryGetValue(axisInfoDict, kCGFontVariationAxisName);
   2527             if (!axisName || CFGetTypeID(axisName) != CFStringGetTypeID()) {
   2528                 return nullptr;
   2529             }
   2530 
   2531             // The variation axes can be set to any value, but cg will effectively pin them.
   2532             // Pin them here to normalize.
   2533             CFTypeRef min = CFDictionaryGetValue(axisInfoDict, kCGFontVariationAxisMinValue);
   2534             CFTypeRef max = CFDictionaryGetValue(axisInfoDict, kCGFontVariationAxisMaxValue);
   2535             if (!min || CFGetTypeID(min) != CFNumberGetTypeID() ||
   2536                 !max || CFGetTypeID(max) != CFNumberGetTypeID())
   2537             {
   2538                 return nullptr;
   2539             }
   2540             CFNumberRef minNumber = static_cast<CFNumberRef>(min);
   2541             CFNumberRef maxNumber = static_cast<CFNumberRef>(max);
   2542             double minDouble;
   2543             double maxDouble;
   2544             if (!CFNumberGetValue(minNumber, kCFNumberDoubleType, &minDouble) ||
   2545                 !CFNumberGetValue(maxNumber, kCFNumberDoubleType, &maxDouble))
   2546             {
   2547                 return nullptr;
   2548             }
   2549             double value = SkTPin(SkFixedToDouble(fontData->getAxis()[i]), minDouble, maxDouble);
   2550             CFNumberRef valueNumber = CFNumberCreate(kCFAllocatorDefault, kCFNumberDoubleType,
   2551                                                      &value);
   2552 
   2553             CFDictionaryAddValue(dict, axisName, valueNumber);
   2554             CFRelease(valueNumber);
   2555         }
   2556         return dict;
   2557     }
   2558     SkTypeface* onCreateFromFontData(SkFontData* data) const override {
   2559         SkAutoTDelete<SkFontData> fontData(data);
   2560         SkStreamAsset* stream = fontData->detachStream();
   2561         AutoCFRelease<CGDataProviderRef> provider(SkCreateDataProviderFromStream(stream));
   2562         if (nullptr == provider) {
   2563             return nullptr;
   2564         }
   2565         AutoCFRelease<CGFontRef> cg(CGFontCreateWithDataProvider(provider));
   2566         if (nullptr == cg) {
   2567             return nullptr;
   2568         }
   2569 
   2570         AutoCFRelease<CFDictionaryRef> cgVariations(get_axes(cg, fontData));
   2571         // The CGFontRef returned by CGFontCreateCopyWithVariations when the passed CGFontRef was
   2572         // created from a data provider does not appear to have any ownership of the underlying
   2573         // data. The original CGFontRef must be kept alive until the copy will no longer be used.
   2574         AutoCFRelease<CGFontRef> cgVariant;
   2575         if (cgVariations) {
   2576             cgVariant.reset(CGFontCreateCopyWithVariations(cg, cgVariations));
   2577         } else {
   2578             cgVariant.reset(cg.detach());
   2579         }
   2580 
   2581         CTFontRef ct = CTFontCreateWithGraphicsFont(cgVariant, 0, nullptr, nullptr);
   2582         if (!ct) {
   2583             return nullptr;
   2584         }
   2585         return NewFromFontRef(ct, cg.detach(), nullptr, true);
   2586     }
   2587 
   2588     SkTypeface* onCreateFromFile(const char path[], int ttcIndex) const override {
   2589         AutoCFRelease<CGDataProviderRef> pr(CGDataProviderCreateWithFilename(path));
   2590         if (nullptr == pr) {
   2591             return nullptr;
   2592         }
   2593         return create_from_dataProvider(pr);
   2594     }
   2595 
   2596     virtual SkTypeface* onLegacyCreateTypeface(const char familyName[],
   2597                                                unsigned styleBits) const override {
   2598 
   2599         SkFontStyle style = SkFontStyle((SkTypeface::Style)styleBits);
   2600         if (familyName) {
   2601             familyName = map_css_names(familyName);
   2602         }
   2603 
   2604         if (!familyName || !*familyName) {
   2605             familyName = FONT_DEFAULT_NAME;
   2606         }
   2607 
   2608         NameStyle cacheRequest = { familyName, style };
   2609         SkTypeface* face = SkTypefaceCache::FindByProcAndRef(find_by_NameStyle, &cacheRequest);
   2610 
   2611         if (nullptr == face) {
   2612             face = NewFromName(familyName, style);
   2613             if (face) {
   2614                 SkTypefaceCache::Add(face, style);
   2615             } else {
   2616                 face = GetDefaultFace();
   2617                 face->ref();
   2618             }
   2619         }
   2620         return face;
   2621     }
   2622 };
   2623 
   2624 ///////////////////////////////////////////////////////////////////////////////
   2625 
   2626 SkFontMgr* SkFontMgr::Factory() { return new SkFontMgr_Mac; }
   2627 
   2628 #endif//defined(SK_BUILD_FOR_MAC) || defined(SK_BUILD_FOR_IOS)
   2629