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