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