OLD | NEW |
1 | 1 |
2 /* | 2 /* |
3 * Copyright 2006 The Android Open Source Project | 3 * Copyright 2006 The Android Open Source Project |
4 * | 4 * |
5 * Use of this source code is governed by a BSD-style license that can be | 5 * Use of this source code is governed by a BSD-style license that can be |
6 * found in the LICENSE file. | 6 * found in the LICENSE file. |
7 */ | 7 */ |
8 | 8 |
9 #include "SkTypes.h" // Keep this before any #ifdef ... | 9 #include "SkTypes.h" // Keep this before any #ifdef ... |
10 | 10 |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
61 | 61 |
62 // Set to make glyph bounding boxes visible. | 62 // Set to make glyph bounding boxes visible. |
63 #define SK_SHOW_TEXT_BLIT_COVERAGE 0 | 63 #define SK_SHOW_TEXT_BLIT_COVERAGE 0 |
64 | 64 |
65 class SkScalerContext_Mac; | 65 class SkScalerContext_Mac; |
66 | 66 |
67 // CTFontManagerCopyAvailableFontFamilyNames() is not always available, so we | 67 // CTFontManagerCopyAvailableFontFamilyNames() is not always available, so we |
68 // provide a wrapper here that will return an empty array if need be. | 68 // provide a wrapper here that will return an empty array if need be. |
69 static CFArrayRef SkCTFontManagerCopyAvailableFontFamilyNames() { | 69 static CFArrayRef SkCTFontManagerCopyAvailableFontFamilyNames() { |
70 #ifdef SK_BUILD_FOR_IOS | 70 #ifdef SK_BUILD_FOR_IOS |
71 return CFArrayCreate(NULL, NULL, 0, NULL); | 71 return CFArrayCreate(nullptr, nullptr, 0, nullptr); |
72 #else | 72 #else |
73 return CTFontManagerCopyAvailableFontFamilyNames(); | 73 return CTFontManagerCopyAvailableFontFamilyNames(); |
74 #endif | 74 #endif |
75 } | 75 } |
76 | 76 |
77 | 77 |
78 // Being templated and taking const T* prevents calling | 78 // Being templated and taking const T* prevents calling |
79 // CFSafeRelease(autoCFRelease) through implicit conversion. | 79 // CFSafeRelease(autoCFRelease) through implicit conversion. |
80 template <typename T> static void CFSafeRelease(/*CFTypeRef*/const T* cfTypeRef)
{ | 80 template <typename T> static void CFSafeRelease(/*CFTypeRef*/const T* cfTypeRef)
{ |
81 if (cfTypeRef) { | 81 if (cfTypeRef) { |
82 CFRelease(cfTypeRef); | 82 CFRelease(cfTypeRef); |
83 } | 83 } |
84 } | 84 } |
85 | 85 |
86 // Being templated and taking const T* prevents calling | 86 // Being templated and taking const T* prevents calling |
87 // CFSafeRetain(autoCFRelease) through implicit conversion. | 87 // CFSafeRetain(autoCFRelease) through implicit conversion. |
88 template <typename T> static void CFSafeRetain(/*CFTypeRef*/const T* cfTypeRef)
{ | 88 template <typename T> static void CFSafeRetain(/*CFTypeRef*/const T* cfTypeRef)
{ |
89 if (cfTypeRef) { | 89 if (cfTypeRef) { |
90 CFRetain(cfTypeRef); | 90 CFRetain(cfTypeRef); |
91 } | 91 } |
92 } | 92 } |
93 | 93 |
94 /** Acts like a CFRef, but calls CFSafeRelease when it goes out of scope. */ | 94 /** Acts like a CFRef, but calls CFSafeRelease when it goes out of scope. */ |
95 template<typename CFRef> class AutoCFRelease : private SkNoncopyable { | 95 template<typename CFRef> class AutoCFRelease : private SkNoncopyable { |
96 public: | 96 public: |
97 explicit AutoCFRelease(CFRef cfRef = NULL) : fCFRef(cfRef) { } | 97 explicit AutoCFRelease(CFRef cfRef = nullptr) : fCFRef(cfRef) { } |
98 ~AutoCFRelease() { CFSafeRelease(fCFRef); } | 98 ~AutoCFRelease() { CFSafeRelease(fCFRef); } |
99 | 99 |
100 void reset(CFRef that = NULL) { | 100 void reset(CFRef that = nullptr) { |
101 if (that != fCFRef) { | 101 if (that != fCFRef) { |
102 CFSafeRelease(fCFRef); | 102 CFSafeRelease(fCFRef); |
103 fCFRef = that; | 103 fCFRef = that; |
104 } | 104 } |
105 } | 105 } |
106 | 106 |
107 CFRef detach() { | 107 CFRef detach() { |
108 CFRef self = fCFRef; | 108 CFRef self = fCFRef; |
109 fCFRef = NULL; | 109 fCFRef = nullptr; |
110 return self; | 110 return self; |
111 } | 111 } |
112 | 112 |
113 operator CFRef() const { return fCFRef; } | 113 operator CFRef() const { return fCFRef; } |
114 CFRef get() const { return fCFRef; } | 114 CFRef get() const { return fCFRef; } |
115 | 115 |
116 CFRef* operator&() { SkASSERT(fCFRef == NULL); return &fCFRef; } | 116 CFRef* operator&() { SkASSERT(fCFRef == nullptr); return &fCFRef; } |
117 private: | 117 private: |
118 CFRef fCFRef; | 118 CFRef fCFRef; |
119 }; | 119 }; |
120 | 120 |
121 static CFStringRef make_CFString(const char str[]) { | 121 static CFStringRef make_CFString(const char str[]) { |
122 return CFStringCreateWithCString(NULL, str, kCFStringEncodingUTF8); | 122 return CFStringCreateWithCString(nullptr, str, kCFStringEncodingUTF8); |
123 } | 123 } |
124 | 124 |
125 template<typename T> class AutoCGTable : SkNoncopyable { | 125 template<typename T> class AutoCGTable : SkNoncopyable { |
126 public: | 126 public: |
127 AutoCGTable(CGFontRef font) | 127 AutoCGTable(CGFontRef font) |
128 //Undocumented: the tag parameter in this call is expected in machine order
and not BE order. | 128 //Undocumented: the tag parameter in this call is expected in machine order
and not BE order. |
129 : fCFData(CGFontCopyTableForTag(font, SkSetFourByteTag(T::TAG0, T::TAG1, T::
TAG2, T::TAG3))) | 129 : fCFData(CGFontCopyTableForTag(font, SkSetFourByteTag(T::TAG0, T::TAG1, T::
TAG2, T::TAG3))) |
130 , fData(fCFData ? reinterpret_cast<const T*>(CFDataGetBytePtr(fCFData)) : NU
LL) | 130 , fData(fCFData ? reinterpret_cast<const T*>(CFDataGetBytePtr(fCFData)) : nu
llptr) |
131 { } | 131 { } |
132 | 132 |
133 const T* operator->() const { return fData; } | 133 const T* operator->() const { return fData; } |
134 | 134 |
135 private: | 135 private: |
136 AutoCFRelease<CFDataRef> fCFData; | 136 AutoCFRelease<CFDataRef> fCFData; |
137 public: | 137 public: |
138 const T* fData; | 138 const T* fData; |
139 }; | 139 }; |
140 | 140 |
(...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
320 uint32_t r = (rgb >> 16) & 0xFF; | 320 uint32_t r = (rgb >> 16) & 0xFF; |
321 uint32_t g = (rgb >> 8) & 0xFF; | 321 uint32_t g = (rgb >> 8) & 0xFF; |
322 uint32_t b = (rgb >> 0) & 0xFF; | 322 uint32_t b = (rgb >> 0) & 0xFF; |
323 gSupportsLCD = (r != g || r != b); | 323 gSupportsLCD = (r != g || r != b); |
324 return (bool) gSupportsLCD; | 324 return (bool) gSupportsLCD; |
325 } | 325 } |
326 | 326 |
327 class Offscreen { | 327 class Offscreen { |
328 public: | 328 public: |
329 Offscreen() | 329 Offscreen() |
330 : fRGBSpace(NULL) | 330 : fRGBSpace(nullptr) |
331 , fCG(NULL) | 331 , fCG(nullptr) |
332 , fDoAA(false) | 332 , fDoAA(false) |
333 , fDoLCD(false) | 333 , fDoLCD(false) |
334 { | 334 { |
335 fSize.set(0, 0); | 335 fSize.set(0, 0); |
336 } | 336 } |
337 | 337 |
338 CGRGBPixel* getCG(const SkScalerContext_Mac& context, const SkGlyph& glyph, | 338 CGRGBPixel* getCG(const SkScalerContext_Mac& context, const SkGlyph& glyph, |
339 CGGlyph glyphID, size_t* rowBytesPtr, | 339 CGGlyph glyphID, size_t* rowBytesPtr, |
340 bool generateA8FromLCD); | 340 bool generateA8FromLCD); |
341 | 341 |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
382 value = 1 + (1 + unit) * 4; | 382 value = 1 + (1 + unit) * 4; |
383 } else { | 383 } else { |
384 value = 5 + unit * 4; | 384 value = 5 + unit * 4; |
385 } | 385 } |
386 return sk_float_round2int(value); | 386 return sk_float_round2int(value); |
387 } | 387 } |
388 | 388 |
389 static SkFontStyle fontstyle_from_descriptor(CTFontDescriptorRef desc) { | 389 static SkFontStyle fontstyle_from_descriptor(CTFontDescriptorRef desc) { |
390 AutoCFRelease<CFDictionaryRef> dict( | 390 AutoCFRelease<CFDictionaryRef> dict( |
391 (CFDictionaryRef)CTFontDescriptorCopyAttribute(desc, kCTFontTraitsAt
tribute)); | 391 (CFDictionaryRef)CTFontDescriptorCopyAttribute(desc, kCTFontTraitsAt
tribute)); |
392 if (NULL == dict.get()) { | 392 if (nullptr == dict.get()) { |
393 return SkFontStyle(); | 393 return SkFontStyle(); |
394 } | 394 } |
395 | 395 |
396 float weight, width, slant; | 396 float weight, width, slant; |
397 if (!find_dict_float(dict, kCTFontWeightTrait, &weight)) { | 397 if (!find_dict_float(dict, kCTFontWeightTrait, &weight)) { |
398 weight = 0; | 398 weight = 0; |
399 } | 399 } |
400 if (!find_dict_float(dict, kCTFontWidthTrait, &width)) { | 400 if (!find_dict_float(dict, kCTFontWidthTrait, &width)) { |
401 width = 0; | 401 width = 0; |
402 } | 402 } |
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
521 CFDictionaryCreateMutable(kCFAllocatorDefault, 0, | 521 CFDictionaryCreateMutable(kCFAllocatorDefault, 0, |
522 &kCFTypeDictionaryKeyCallBacks, | 522 &kCFTypeDictionaryKeyCallBacks, |
523 &kCFTypeDictionaryValueCallBacks)); | 523 &kCFTypeDictionaryValueCallBacks)); |
524 | 524 |
525 AutoCFRelease<CFMutableDictionaryRef> cfTraits( | 525 AutoCFRelease<CFMutableDictionaryRef> cfTraits( |
526 CFDictionaryCreateMutable(kCFAllocatorDefault, 0, | 526 CFDictionaryCreateMutable(kCFAllocatorDefault, 0, |
527 &kCFTypeDictionaryKeyCallBacks, | 527 &kCFTypeDictionaryKeyCallBacks, |
528 &kCFTypeDictionaryValueCallBacks)); | 528 &kCFTypeDictionaryValueCallBacks)); |
529 | 529 |
530 if (!cfFontName || !cfFontTraits || !cfAttributes || !cfTraits) { | 530 if (!cfFontName || !cfFontTraits || !cfAttributes || !cfTraits) { |
531 return NULL; | 531 return nullptr; |
532 } | 532 } |
533 | 533 |
534 CFDictionaryAddValue(cfTraits, kCTFontSymbolicTrait, cfFontTraits); | 534 CFDictionaryAddValue(cfTraits, kCTFontSymbolicTrait, cfFontTraits); |
535 | 535 |
536 CFDictionaryAddValue(cfAttributes, kCTFontFamilyNameAttribute, cfFontName); | 536 CFDictionaryAddValue(cfAttributes, kCTFontFamilyNameAttribute, cfFontName); |
537 CFDictionaryAddValue(cfAttributes, kCTFontTraitsAttribute, cfTraits); | 537 CFDictionaryAddValue(cfAttributes, kCTFontTraitsAttribute, cfTraits); |
538 | 538 |
539 AutoCFRelease<CTFontDescriptorRef> ctFontDesc( | 539 AutoCFRelease<CTFontDescriptorRef> ctFontDesc( |
540 CTFontDescriptorCreateWithAttributes(cfAttributes)); | 540 CTFontDescriptorCreateWithAttributes(cfAttributes)); |
541 if (!ctFontDesc) { | 541 if (!ctFontDesc) { |
542 return NULL; | 542 return nullptr; |
543 } | 543 } |
544 | 544 |
545 AutoCFRelease<CTFontRef> ctFont(CTFontCreateWithFontDescriptor(ctFontDesc, 0
, NULL)); | 545 AutoCFRelease<CTFontRef> ctFont(CTFontCreateWithFontDescriptor(ctFontDesc, 0
, nullptr)); |
546 if (!ctFont) { | 546 if (!ctFont) { |
547 return NULL; | 547 return nullptr; |
548 } | 548 } |
549 | 549 |
550 SkTypeface* face = SkTypefaceCache::FindByProcAndRef(find_by_CTFontRef, (voi
d*)ctFont.get()); | 550 SkTypeface* face = SkTypefaceCache::FindByProcAndRef(find_by_CTFontRef, (voi
d*)ctFont.get()); |
551 if (!face) { | 551 if (!face) { |
552 face = NewFromFontRef(ctFont.detach(), NULL, NULL, false); | 552 face = NewFromFontRef(ctFont.detach(), nullptr, nullptr, false); |
553 SkTypefaceCache::Add(face, face->fontStyle()); | 553 SkTypefaceCache::Add(face, face->fontStyle()); |
554 } | 554 } |
555 return face; | 555 return face; |
556 } | 556 } |
557 | 557 |
558 SK_DECLARE_STATIC_MUTEX(gGetDefaultFaceMutex); | 558 SK_DECLARE_STATIC_MUTEX(gGetDefaultFaceMutex); |
559 static SkTypeface* GetDefaultFace() { | 559 static SkTypeface* GetDefaultFace() { |
560 SkAutoMutexAcquire ma(gGetDefaultFaceMutex); | 560 SkAutoMutexAcquire ma(gGetDefaultFaceMutex); |
561 | 561 |
562 static SkTypeface* gDefaultFace; | 562 static SkTypeface* gDefaultFace; |
563 | 563 |
564 if (NULL == gDefaultFace) { | 564 if (nullptr == gDefaultFace) { |
565 gDefaultFace = NewFromName(FONT_DEFAULT_NAME, SkFontStyle()); | 565 gDefaultFace = NewFromName(FONT_DEFAULT_NAME, SkFontStyle()); |
566 SkTypefaceCache::Add(gDefaultFace, SkFontStyle()); | 566 SkTypefaceCache::Add(gDefaultFace, SkFontStyle()); |
567 } | 567 } |
568 return gDefaultFace; | 568 return gDefaultFace; |
569 } | 569 } |
570 | 570 |
571 /////////////////////////////////////////////////////////////////////////////// | 571 /////////////////////////////////////////////////////////////////////////////// |
572 | 572 |
573 extern CTFontRef SkTypeface_GetCTFontRef(const SkTypeface* face); | 573 extern CTFontRef SkTypeface_GetCTFontRef(const SkTypeface* face); |
574 CTFontRef SkTypeface_GetCTFontRef(const SkTypeface* face) { | 574 CTFontRef SkTypeface_GetCTFontRef(const SkTypeface* face) { |
575 const SkTypeface_Mac* macface = (const SkTypeface_Mac*)face; | 575 const SkTypeface_Mac* macface = (const SkTypeface_Mac*)face; |
576 return macface ? macface->fFontRef.get() : NULL; | 576 return macface ? macface->fFontRef.get() : nullptr; |
577 } | 577 } |
578 | 578 |
579 /* This function is visible on the outside. It first searches the cache, and if | 579 /* This function is visible on the outside. It first searches the cache, and if |
580 * not found, returns a new entry (after adding it to the cache). | 580 * not found, returns a new entry (after adding it to the cache). |
581 */ | 581 */ |
582 SkTypeface* SkCreateTypefaceFromCTFont(CTFontRef fontRef, CFTypeRef resourceRef)
{ | 582 SkTypeface* SkCreateTypefaceFromCTFont(CTFontRef fontRef, CFTypeRef resourceRef)
{ |
583 SkTypeface* face = SkTypefaceCache::FindByProcAndRef(find_by_CTFontRef, (voi
d*)fontRef); | 583 SkTypeface* face = SkTypefaceCache::FindByProcAndRef(find_by_CTFontRef, (voi
d*)fontRef); |
584 if (!face) { | 584 if (!face) { |
585 CFRetain(fontRef); | 585 CFRetain(fontRef); |
586 if (resourceRef) { | 586 if (resourceRef) { |
587 CFRetain(resourceRef); | 587 CFRetain(resourceRef); |
588 } | 588 } |
589 face = NewFromFontRef(fontRef, resourceRef, NULL, false); | 589 face = NewFromFontRef(fontRef, resourceRef, nullptr, false); |
590 SkTypefaceCache::Add(face, face->fontStyle()); | 590 SkTypefaceCache::Add(face, face->fontStyle()); |
591 } | 591 } |
592 return face; | 592 return face; |
593 } | 593 } |
594 | 594 |
595 struct NameStyle { | 595 struct NameStyle { |
596 const char* fName; | 596 const char* fName; |
597 SkFontStyle fStyle; | 597 SkFontStyle fStyle; |
598 }; | 598 }; |
599 | 599 |
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
729 CTFontRef ctFont = typeface->fFontRef.get(); | 729 CTFontRef ctFont = typeface->fFontRef.get(); |
730 CFIndex numGlyphs = CTFontGetGlyphCount(ctFont); | 730 CFIndex numGlyphs = CTFontGetGlyphCount(ctFont); |
731 SkASSERT(numGlyphs >= 1 && numGlyphs <= 0xFFFF); | 731 SkASSERT(numGlyphs >= 1 && numGlyphs <= 0xFFFF); |
732 fGlyphCount = SkToU16(numGlyphs); | 732 fGlyphCount = SkToU16(numGlyphs); |
733 | 733 |
734 // CT on (at least) 10.9 will size color glyphs down from the requested size
, but not up. | 734 // CT on (at least) 10.9 will size color glyphs down from the requested size
, but not up. |
735 // As a result, it is necessary to know the actual device size and request t
hat. | 735 // As a result, it is necessary to know the actual device size and request t
hat. |
736 SkVector scale; | 736 SkVector scale; |
737 SkMatrix skTransform; | 737 SkMatrix skTransform; |
738 fRec.computeMatrices(SkScalerContextRec::kVertical_PreMatrixScale, &scale, &
skTransform, | 738 fRec.computeMatrices(SkScalerContextRec::kVertical_PreMatrixScale, &scale, &
skTransform, |
739 NULL, NULL, &fFUnitMatrix); | 739 nullptr, nullptr, &fFUnitMatrix); |
740 fTransform = MatrixToCGAffineTransform(skTransform); | 740 fTransform = MatrixToCGAffineTransform(skTransform); |
741 fInvTransform = CGAffineTransformInvert(fTransform); | 741 fInvTransform = CGAffineTransformInvert(fTransform); |
742 | 742 |
743 AutoCFRelease<CTFontDescriptorRef> ctFontDesc; | 743 AutoCFRelease<CTFontDescriptorRef> ctFontDesc; |
744 if (fVertical) { | 744 if (fVertical) { |
745 // Setting the vertical orientation here is required for vertical metric
s on some versions. | 745 // Setting the vertical orientation here is required for vertical metric
s on some versions. |
746 AutoCFRelease<CFMutableDictionaryRef> cfAttributes(CFDictionaryCreateMut
able( | 746 AutoCFRelease<CFMutableDictionaryRef> cfAttributes(CFDictionaryCreateMut
able( |
747 kCFAllocatorDefault, 0, | 747 kCFAllocatorDefault, 0, |
748 &kCFTypeDictionaryKeyCallBacks, | 748 &kCFTypeDictionaryKeyCallBacks, |
749 &kCFTypeDictionaryValueCallBacks)); | 749 &kCFTypeDictionaryValueCallBacks)); |
750 if (cfAttributes) { | 750 if (cfAttributes) { |
751 CTFontOrientation ctOrientation = kCTFontVerticalOrientation; | 751 CTFontOrientation ctOrientation = kCTFontVerticalOrientation; |
752 AutoCFRelease<CFNumberRef> cfVertical(CFNumberCreate( | 752 AutoCFRelease<CFNumberRef> cfVertical(CFNumberCreate( |
753 kCFAllocatorDefault, kCFNumberSInt32Type, &ctOrientation)); | 753 kCFAllocatorDefault, kCFNumberSInt32Type, &ctOrientation)); |
754 CFDictionaryAddValue(cfAttributes, kCTFontOrientationAttribute, cfVe
rtical); | 754 CFDictionaryAddValue(cfAttributes, kCTFontOrientationAttribute, cfVe
rtical); |
755 ctFontDesc.reset(CTFontDescriptorCreateWithAttributes(cfAttributes))
; | 755 ctFontDesc.reset(CTFontDescriptorCreateWithAttributes(cfAttributes))
; |
756 } | 756 } |
757 } | 757 } |
758 | 758 |
759 // The transform contains everything except the requested text size. | 759 // The transform contains everything except the requested text size. |
760 // Some properties, like 'trak', are based on the text size (before applying
the matrix). | 760 // Some properties, like 'trak', are based on the text size (before applying
the matrix). |
761 CGFloat textSize = ScalarToCG(scale.y()); | 761 CGFloat textSize = ScalarToCG(scale.y()); |
762 | 762 |
763 fCTFont.reset(CTFontCreateCopyWithAttributes(ctFont, textSize, &fTransform,
ctFontDesc)); | 763 fCTFont.reset(CTFontCreateCopyWithAttributes(ctFont, textSize, &fTransform,
ctFontDesc)); |
764 fCGFont.reset(CTFontCopyGraphicsFont(fCTFont, NULL)); | 764 fCGFont.reset(CTFontCopyGraphicsFont(fCTFont, nullptr)); |
765 fCTUnrotatedFont.reset(CTFontCreateCopyWithAttributes(ctFont, textSize, | 765 fCTUnrotatedFont.reset(CTFontCreateCopyWithAttributes(ctFont, textSize, |
766 &CGAffineTransformIden
tity, NULL)); | 766 &CGAffineTransformIden
tity, nullptr)); |
767 | 767 |
768 // The fUnitMatrix includes the text size (and em) as it is used to scale th
e raw font data. | 768 // The fUnitMatrix includes the text size (and em) as it is used to scale th
e raw font data. |
769 SkScalar emPerFUnit = SkScalarInvert(SkIntToScalar(CGFontGetUnitsPerEm(fCGFo
nt))); | 769 SkScalar emPerFUnit = SkScalarInvert(SkIntToScalar(CGFontGetUnitsPerEm(fCGFo
nt))); |
770 fFUnitMatrix.preScale(emPerFUnit, -emPerFUnit); | 770 fFUnitMatrix.preScale(emPerFUnit, -emPerFUnit); |
771 } | 771 } |
772 | 772 |
773 extern "C" { | 773 extern "C" { |
774 | 774 |
775 /** CTFontDrawGlyphs was introduced in 10.7. */ | 775 /** CTFontDrawGlyphs was introduced in 10.7. */ |
776 typedef void (*CTFontDrawGlyphsProc)(CTFontRef, const CGGlyph[], const CGPoint[]
, | 776 typedef void (*CTFontDrawGlyphsProc)(CTFontRef, const CGGlyph[], const CGPoint[]
, |
(...skipping 304 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1081 CGRect cgBounds; | 1081 CGRect cgBounds; |
1082 CTFontGetBoundingRectsForGlyphs(fCTFont, kCTFontHorizontalOrientation, | 1082 CTFontGetBoundingRectsForGlyphs(fCTFont, kCTFontHorizontalOrientation, |
1083 &cgGlyph, &cgBounds, 1); | 1083 &cgGlyph, &cgBounds, 1); |
1084 | 1084 |
1085 // BUG? | 1085 // BUG? |
1086 // 0x200B (zero-advance space) seems to return a huge (garbage) bounds,
when | 1086 // 0x200B (zero-advance space) seems to return a huge (garbage) bounds,
when |
1087 // it should be empty. So, if we see a zero-advance, we check if it has
an | 1087 // it should be empty. So, if we see a zero-advance, we check if it has
an |
1088 // empty path or not, and if so, we jam the bounds to 0. Hopefully a zer
o-advance | 1088 // empty path or not, and if so, we jam the bounds to 0. Hopefully a zer
o-advance |
1089 // is rare, so we won't incur a big performance cost for this extra chec
k. | 1089 // is rare, so we won't incur a big performance cost for this extra chec
k. |
1090 if (0 == cgAdvance.width && 0 == cgAdvance.height) { | 1090 if (0 == cgAdvance.width && 0 == cgAdvance.height) { |
1091 AutoCFRelease<CGPathRef> path(CTFontCreatePathForGlyph(fCTFont, cgGl
yph, NULL)); | 1091 AutoCFRelease<CGPathRef> path(CTFontCreatePathForGlyph(fCTFont, cgGl
yph, nullptr)); |
1092 if (NULL == path || CGPathIsEmpty(path)) { | 1092 if (nullptr == path || CGPathIsEmpty(path)) { |
1093 return; | 1093 return; |
1094 } | 1094 } |
1095 } | 1095 } |
1096 | 1096 |
1097 if (CGRectIsEmpty_inline(cgBounds)) { | 1097 if (CGRectIsEmpty_inline(cgBounds)) { |
1098 return; | 1098 return; |
1099 } | 1099 } |
1100 | 1100 |
1101 // Convert cgBounds to SkGlyph units (pixels, y down). | 1101 // Convert cgBounds to SkGlyph units (pixels, y down). |
1102 skBounds = SkRect::MakeXYWH(cgBounds.origin.x, -cgBounds.origin.y - cgBo
unds.size.height, | 1102 skBounds = SkRect::MakeXYWH(cgBounds.origin.x, -cgBounds.origin.y - cgBo
unds.size.height, |
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1246 | 1246 |
1247 void SkScalerContext_Mac::generateImage(const SkGlyph& glyph) { | 1247 void SkScalerContext_Mac::generateImage(const SkGlyph& glyph) { |
1248 CGGlyph cgGlyph = (CGGlyph) glyph.getGlyphID(); | 1248 CGGlyph cgGlyph = (CGGlyph) glyph.getGlyphID(); |
1249 | 1249 |
1250 // FIXME: lcd smoothed un-hinted rasterization unsupported. | 1250 // FIXME: lcd smoothed un-hinted rasterization unsupported. |
1251 bool generateA8FromLCD = fRec.getHinting() != SkPaint::kNo_Hinting; | 1251 bool generateA8FromLCD = fRec.getHinting() != SkPaint::kNo_Hinting; |
1252 | 1252 |
1253 // Draw the glyph | 1253 // Draw the glyph |
1254 size_t cgRowBytes; | 1254 size_t cgRowBytes; |
1255 CGRGBPixel* cgPixels = fOffscreen.getCG(*this, glyph, cgGlyph, &cgRowBytes,
generateA8FromLCD); | 1255 CGRGBPixel* cgPixels = fOffscreen.getCG(*this, glyph, cgGlyph, &cgRowBytes,
generateA8FromLCD); |
1256 if (cgPixels == NULL) { | 1256 if (cgPixels == nullptr) { |
1257 return; | 1257 return; |
1258 } | 1258 } |
1259 | 1259 |
1260 //TODO: see if drawing black on white and inverting is faster (at least in | 1260 //TODO: see if drawing black on white and inverting is faster (at least in |
1261 //lcd case) as core graphics appears to have special case code for drawing | 1261 //lcd case) as core graphics appears to have special case code for drawing |
1262 //black text. | 1262 //black text. |
1263 | 1263 |
1264 // Fix the glyph | 1264 // Fix the glyph |
1265 const bool isLCD = isLCDFormat(glyph.fMaskFormat); | 1265 const bool isLCD = isLCDFormat(glyph.fMaskFormat); |
1266 if (isLCD || (glyph.fMaskFormat == SkMask::kA8_Format && supports_LCD() && g
enerateA8FromLCD)) { | 1266 if (isLCD || (glyph.fMaskFormat == SkMask::kA8_Format && supports_LCD() && g
enerateA8FromLCD)) { |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1365 break; | 1365 break; |
1366 case kY_SkAxisAlignment: | 1366 case kY_SkAxisAlignment: |
1367 scaleX = SK_Scalar1; // want hinting in the X direction | 1367 scaleX = SK_Scalar1; // want hinting in the X direction |
1368 break; | 1368 break; |
1369 default: | 1369 default: |
1370 break; | 1370 break; |
1371 } | 1371 } |
1372 | 1372 |
1373 CGAffineTransform xform = MatrixToCGAffineTransform(m, scaleX, scaleY); | 1373 CGAffineTransform xform = MatrixToCGAffineTransform(m, scaleX, scaleY); |
1374 // need to release font when we're done | 1374 // need to release font when we're done |
1375 font = CTFontCreateCopyWithAttributes(fCTFont, 1, &xform, NULL); | 1375 font = CTFontCreateCopyWithAttributes(fCTFont, 1, &xform, nullptr); |
1376 } | 1376 } |
1377 | 1377 |
1378 CGGlyph cgGlyph = (CGGlyph)glyph.getGlyphID(); | 1378 CGGlyph cgGlyph = (CGGlyph)glyph.getGlyphID(); |
1379 AutoCFRelease<CGPathRef> cgPath(CTFontCreatePathForGlyph(font, cgGlyph, NULL
)); | 1379 AutoCFRelease<CGPathRef> cgPath(CTFontCreatePathForGlyph(font, cgGlyph, null
ptr)); |
1380 | 1380 |
1381 path->reset(); | 1381 path->reset(); |
1382 if (cgPath != NULL) { | 1382 if (cgPath != nullptr) { |
1383 CGPathApply(cgPath, path, SkScalerContext_Mac::CTPathElement); | 1383 CGPathApply(cgPath, path, SkScalerContext_Mac::CTPathElement); |
1384 } | 1384 } |
1385 | 1385 |
1386 if (fDoSubPosition) { | 1386 if (fDoSubPosition) { |
1387 SkMatrix m; | 1387 SkMatrix m; |
1388 m.setScale(SkScalarInvert(scaleX), SkScalarInvert(scaleY)); | 1388 m.setScale(SkScalarInvert(scaleX), SkScalarInvert(scaleY)); |
1389 path->transform(m); | 1389 path->transform(m); |
1390 // balance the call to CTFontCreateCopyWithAttributes | 1390 // balance the call to CTFontCreateCopyWithAttributes |
1391 CFSafeRelease(font); | 1391 CFSafeRelease(font); |
1392 } | 1392 } |
1393 if (fVertical) { | 1393 if (fVertical) { |
1394 SkPoint offset; | 1394 SkPoint offset; |
1395 getVerticalOffset(cgGlyph, &offset); | 1395 getVerticalOffset(cgGlyph, &offset); |
1396 path->offset(offset.fX, offset.fY); | 1396 path->offset(offset.fX, offset.fY); |
1397 } | 1397 } |
1398 } | 1398 } |
1399 | 1399 |
1400 void SkScalerContext_Mac::generateFontMetrics(SkPaint::FontMetrics* metrics) { | 1400 void SkScalerContext_Mac::generateFontMetrics(SkPaint::FontMetrics* metrics) { |
1401 if (NULL == metrics) { | 1401 if (nullptr == metrics) { |
1402 return; | 1402 return; |
1403 } | 1403 } |
1404 | 1404 |
1405 AUTO_CG_LOCK(); | 1405 AUTO_CG_LOCK(); |
1406 | 1406 |
1407 CGRect theBounds = CTFontGetBoundingBox(fCTFont); | 1407 CGRect theBounds = CTFontGetBoundingBox(fCTFont); |
1408 | 1408 |
1409 metrics->fTop = CGToScalar(-CGRectGetMaxY_inline(theBounds)); | 1409 metrics->fTop = CGToScalar(-CGRectGetMaxY_inline(theBounds)); |
1410 metrics->fAscent = CGToScalar(-CTFontGetAscent(fCTFont)); | 1410 metrics->fAscent = CGToScalar(-CTFontGetAscent(fCTFont)); |
1411 metrics->fDescent = CGToScalar( CTFontGetDescent(fCTFont)); | 1411 metrics->fDescent = CGToScalar( CTFontGetDescent(fCTFont)); |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1454 | 1454 |
1455 default: | 1455 default: |
1456 SkDEBUGFAIL("Unknown path element!"); | 1456 SkDEBUGFAIL("Unknown path element!"); |
1457 break; | 1457 break; |
1458 } | 1458 } |
1459 } | 1459 } |
1460 | 1460 |
1461 | 1461 |
1462 /////////////////////////////////////////////////////////////////////////////// | 1462 /////////////////////////////////////////////////////////////////////////////// |
1463 | 1463 |
1464 // Returns NULL on failure | 1464 // Returns nullptr on failure |
1465 // Call must still manage its ownership of provider | 1465 // Call must still manage its ownership of provider |
1466 static SkTypeface* create_from_dataProvider(CGDataProviderRef provider) { | 1466 static SkTypeface* create_from_dataProvider(CGDataProviderRef provider) { |
1467 AutoCFRelease<CGFontRef> cg(CGFontCreateWithDataProvider(provider)); | 1467 AutoCFRelease<CGFontRef> cg(CGFontCreateWithDataProvider(provider)); |
1468 if (NULL == cg) { | 1468 if (nullptr == cg) { |
1469 return NULL; | 1469 return nullptr; |
1470 } | 1470 } |
1471 CTFontRef ct = CTFontCreateWithGraphicsFont(cg, 0, NULL, NULL); | 1471 CTFontRef ct = CTFontCreateWithGraphicsFont(cg, 0, nullptr, nullptr); |
1472 return ct ? NewFromFontRef(ct, NULL, NULL, true) : NULL; | 1472 return ct ? NewFromFontRef(ct, nullptr, nullptr, true) : nullptr; |
1473 } | 1473 } |
1474 | 1474 |
1475 // Web fonts added to the the CTFont registry do not return their character set. | 1475 // Web fonts added to the the CTFont registry do not return their character set. |
1476 // Iterate through the font in this case. The existing caller caches the result, | 1476 // Iterate through the font in this case. The existing caller caches the result, |
1477 // so the performance impact isn't too bad. | 1477 // so the performance impact isn't too bad. |
1478 static void populate_glyph_to_unicode_slow(CTFontRef ctFont, CFIndex glyphCount, | 1478 static void populate_glyph_to_unicode_slow(CTFontRef ctFont, CFIndex glyphCount, |
1479 SkTDArray<SkUnichar>* glyphToUnicode)
{ | 1479 SkTDArray<SkUnichar>* glyphToUnicode)
{ |
1480 glyphToUnicode->setCount(SkToInt(glyphCount)); | 1480 glyphToUnicode->setCount(SkToInt(glyphCount)); |
1481 SkUnichar* out = glyphToUnicode->begin(); | 1481 SkUnichar* out = glyphToUnicode->begin(); |
1482 sk_bzero(out, glyphCount * sizeof(SkUnichar)); | 1482 sk_bzero(out, glyphCount * sizeof(SkUnichar)); |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1541 | 1541 |
1542 static bool getWidthAdvance(CTFontRef ctFont, int gId, int16_t* data) { | 1542 static bool getWidthAdvance(CTFontRef ctFont, int gId, int16_t* data) { |
1543 CGSize advance; | 1543 CGSize advance; |
1544 advance.width = 0; | 1544 advance.width = 0; |
1545 CGGlyph glyph = gId; | 1545 CGGlyph glyph = gId; |
1546 CTFontGetAdvancesForGlyphs(ctFont, kCTFontHorizontalOrientation, &glyph, &ad
vance, 1); | 1546 CTFontGetAdvancesForGlyphs(ctFont, kCTFontHorizontalOrientation, &glyph, &ad
vance, 1); |
1547 *data = sk_float_round2int(advance.width); | 1547 *data = sk_float_round2int(advance.width); |
1548 return true; | 1548 return true; |
1549 } | 1549 } |
1550 | 1550 |
1551 /** Assumes src and dst are not NULL. */ | 1551 /** Assumes src and dst are not nullptr. */ |
1552 static void CFStringToSkString(CFStringRef src, SkString* dst) { | 1552 static void CFStringToSkString(CFStringRef src, SkString* dst) { |
1553 // Reserve enough room for the worst-case string, | 1553 // Reserve enough room for the worst-case string, |
1554 // plus 1 byte for the trailing null. | 1554 // plus 1 byte for the trailing null. |
1555 CFIndex length = CFStringGetMaximumSizeForEncoding(CFStringGetLength(src), | 1555 CFIndex length = CFStringGetMaximumSizeForEncoding(CFStringGetLength(src), |
1556 kCFStringEncodingUTF8) +
1; | 1556 kCFStringEncodingUTF8) +
1; |
1557 dst->resize(length); | 1557 dst->resize(length); |
1558 CFStringGetCString(src, dst->writable_str(), length, kCFStringEncodingUTF8); | 1558 CFStringGetCString(src, dst->writable_str(), length, kCFStringEncodingUTF8); |
1559 // Resize to the actual UTF-8 length used, stripping the null character. | 1559 // Resize to the actual UTF-8 length used, stripping the null character. |
1560 dst->resize(strlen(dst->c_str())); | 1560 dst->resize(strlen(dst->c_str())); |
1561 } | 1561 } |
1562 | 1562 |
1563 SkAdvancedTypefaceMetrics* SkTypeface_Mac::onGetAdvancedTypefaceMetrics( | 1563 SkAdvancedTypefaceMetrics* SkTypeface_Mac::onGetAdvancedTypefaceMetrics( |
1564 PerGlyphInfo perGlyphInfo, | 1564 PerGlyphInfo perGlyphInfo, |
1565 const uint32_t* glyphIDs, | 1565 const uint32_t* glyphIDs, |
1566 uint32_t glyphIDsCount) const { | 1566 uint32_t glyphIDsCount) const { |
1567 | 1567 |
1568 AUTO_CG_LOCK(); | 1568 AUTO_CG_LOCK(); |
1569 | 1569 |
1570 CTFontRef originalCTFont = fFontRef.get(); | 1570 CTFontRef originalCTFont = fFontRef.get(); |
1571 AutoCFRelease<CTFontRef> ctFont(CTFontCreateCopyWithAttributes( | 1571 AutoCFRelease<CTFontRef> ctFont(CTFontCreateCopyWithAttributes( |
1572 originalCTFont, CTFontGetUnitsPerEm(originalCTFont), NULL, NULL)); | 1572 originalCTFont, CTFontGetUnitsPerEm(originalCTFont), nullptr, nullpt
r)); |
1573 SkAdvancedTypefaceMetrics* info = new SkAdvancedTypefaceMetrics; | 1573 SkAdvancedTypefaceMetrics* info = new SkAdvancedTypefaceMetrics; |
1574 | 1574 |
1575 { | 1575 { |
1576 AutoCFRelease<CFStringRef> fontName(CTFontCopyPostScriptName(ctFont)); | 1576 AutoCFRelease<CFStringRef> fontName(CTFontCopyPostScriptName(ctFont)); |
1577 if (fontName.get()) { | 1577 if (fontName.get()) { |
1578 CFStringToSkString(fontName, &info->fFontName); | 1578 CFStringToSkString(fontName, &info->fFontName); |
1579 } | 1579 } |
1580 } | 1580 } |
1581 | 1581 |
1582 CFIndex glyphCount = CTFontGetGlyphCount(ctFont); | 1582 CFIndex glyphCount = CTFontGetGlyphCount(ctFont); |
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1692 //CT seems to be unreliable in being able to obtain the type, | 1692 //CT seems to be unreliable in being able to obtain the type, |
1693 //even if all we want is the first four bytes of the font resource. | 1693 //even if all we want is the first four bytes of the font resource. |
1694 //Just the presence of the FontForge 'FFTM' table seems to throw it
off. | 1694 //Just the presence of the FontForge 'FFTM' table seems to throw it
off. |
1695 return SkSFNTHeader::fontType_WindowsTrueType::TAG; | 1695 return SkSFNTHeader::fontType_WindowsTrueType::TAG; |
1696 } | 1696 } |
1697 } | 1697 } |
1698 | 1698 |
1699 SkStreamAsset* SkTypeface_Mac::onOpenStream(int* ttcIndex) const { | 1699 SkStreamAsset* SkTypeface_Mac::onOpenStream(int* ttcIndex) const { |
1700 SK_SFNT_ULONG fontType = get_font_type_tag(this); | 1700 SK_SFNT_ULONG fontType = get_font_type_tag(this); |
1701 if (0 == fontType) { | 1701 if (0 == fontType) { |
1702 return NULL; | 1702 return nullptr; |
1703 } | 1703 } |
1704 | 1704 |
1705 // get table tags | 1705 // get table tags |
1706 int numTables = this->countTables(); | 1706 int numTables = this->countTables(); |
1707 SkTDArray<SkFontTableTag> tableTags; | 1707 SkTDArray<SkFontTableTag> tableTags; |
1708 tableTags.setCount(numTables); | 1708 tableTags.setCount(numTables); |
1709 this->getTableTags(tableTags.begin()); | 1709 this->getTableTags(tableTags.begin()); |
1710 | 1710 |
1711 // calc total size for font, save sizes | 1711 // calc total size for font, save sizes |
1712 SkTDArray<size_t> tableSizes; | 1712 SkTDArray<size_t> tableSizes; |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1804 valueDouble < SkFixedToDouble(SK_FixedMin) || SkFixedToDouble(SK_FixedMa
x) < valueDouble) | 1804 valueDouble < SkFixedToDouble(SK_FixedMin) || SkFixedToDouble(SK_FixedMa
x) < valueDouble) |
1805 { | 1805 { |
1806 return; | 1806 return; |
1807 } | 1807 } |
1808 self->axisValue[keyIndex] = SkDoubleToFixed(valueDouble); | 1808 self->axisValue[keyIndex] = SkDoubleToFixed(valueDouble); |
1809 } | 1809 } |
1810 static bool get_variations(CTFontRef fFontRef, CFIndex* cgAxisCount, | 1810 static bool get_variations(CTFontRef fFontRef, CFIndex* cgAxisCount, |
1811 SkAutoSTMalloc<4, SkFixed>* axisValues) | 1811 SkAutoSTMalloc<4, SkFixed>* axisValues) |
1812 { | 1812 { |
1813 // CTFontCopyVariationAxes and CTFontCopyVariation do not work when applied
to fonts which | 1813 // CTFontCopyVariationAxes and CTFontCopyVariation do not work when applied
to fonts which |
1814 // started life with CGFontCreateWithDataProvider (they simply always return
NULL). | 1814 // started life with CGFontCreateWithDataProvider (they simply always return
nullptr). |
1815 // As a result, we are limited to CGFontCopyVariationAxes and CGFontCopyVari
ations. | 1815 // As a result, we are limited to CGFontCopyVariationAxes and CGFontCopyVari
ations. |
1816 AutoCFRelease<CGFontRef> cgFont(CTFontCopyGraphicsFont(fFontRef, NULL)); | 1816 AutoCFRelease<CGFontRef> cgFont(CTFontCopyGraphicsFont(fFontRef, nullptr)); |
1817 | 1817 |
1818 AutoCFRelease<CFDictionaryRef> cgVariations(CGFontCopyVariations(cgFont)); | 1818 AutoCFRelease<CFDictionaryRef> cgVariations(CGFontCopyVariations(cgFont)); |
1819 // If a font has no variations CGFontCopyVariations returns NULL (instead of
an empty dict). | 1819 // If a font has no variations CGFontCopyVariations returns nullptr (instead
of an empty dict). |
1820 if (!cgVariations.get()) { | 1820 if (!cgVariations.get()) { |
1821 return false; | 1821 return false; |
1822 } | 1822 } |
1823 | 1823 |
1824 AutoCFRelease<CFArrayRef> cgAxes(CGFontCopyVariationAxes(cgFont)); | 1824 AutoCFRelease<CFArrayRef> cgAxes(CGFontCopyVariationAxes(cgFont)); |
1825 *cgAxisCount = CFArrayGetCount(cgAxes); | 1825 *cgAxisCount = CFArrayGetCount(cgAxes); |
1826 axisValues->reset(*cgAxisCount); | 1826 axisValues->reset(*cgAxisCount); |
1827 | 1827 |
1828 // Set all of the axes to their default values. | 1828 // Set all of the axes to their default values. |
1829 // Fail if any default value cannot be determined. | 1829 // Fail if any default value cannot be determined. |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1861 } | 1861 } |
1862 SkFontData* SkTypeface_Mac::onCreateFontData() const { | 1862 SkFontData* SkTypeface_Mac::onCreateFontData() const { |
1863 int index; | 1863 int index; |
1864 SkAutoTDelete<SkStreamAsset> stream(this->onOpenStream(&index)); | 1864 SkAutoTDelete<SkStreamAsset> stream(this->onOpenStream(&index)); |
1865 | 1865 |
1866 CFIndex cgAxisCount; | 1866 CFIndex cgAxisCount; |
1867 SkAutoSTMalloc<4, SkFixed> axisValues; | 1867 SkAutoSTMalloc<4, SkFixed> axisValues; |
1868 if (get_variations(fFontRef, &cgAxisCount, &axisValues)) { | 1868 if (get_variations(fFontRef, &cgAxisCount, &axisValues)) { |
1869 return new SkFontData(stream.detach(), index, axisValues.get(), cgAxisCo
unt); | 1869 return new SkFontData(stream.detach(), index, axisValues.get(), cgAxisCo
unt); |
1870 } | 1870 } |
1871 return new SkFontData(stream.detach(), index, NULL, 0); | 1871 return new SkFontData(stream.detach(), index, nullptr, 0); |
1872 } | 1872 } |
1873 | 1873 |
1874 /////////////////////////////////////////////////////////////////////////////// | 1874 /////////////////////////////////////////////////////////////////////////////// |
1875 /////////////////////////////////////////////////////////////////////////////// | 1875 /////////////////////////////////////////////////////////////////////////////// |
1876 | 1876 |
1877 int SkTypeface_Mac::onGetUPEM() const { | 1877 int SkTypeface_Mac::onGetUPEM() const { |
1878 AutoCFRelease<CGFontRef> cgFont(CTFontCopyGraphicsFont(fFontRef, NULL)); | 1878 AutoCFRelease<CGFontRef> cgFont(CTFontCopyGraphicsFont(fFontRef, nullptr)); |
1879 return CGFontGetUnitsPerEm(cgFont); | 1879 return CGFontGetUnitsPerEm(cgFont); |
1880 } | 1880 } |
1881 | 1881 |
1882 SkTypeface::LocalizedStrings* SkTypeface_Mac::onCreateFamilyNameIterator() const
{ | 1882 SkTypeface::LocalizedStrings* SkTypeface_Mac::onCreateFamilyNameIterator() const
{ |
1883 SkTypeface::LocalizedStrings* nameIter = | 1883 SkTypeface::LocalizedStrings* nameIter = |
1884 SkOTUtils::LocalizedStrings_NameTable::CreateForFamilyNames(*this); | 1884 SkOTUtils::LocalizedStrings_NameTable::CreateForFamilyNames(*this); |
1885 if (NULL == nameIter) { | 1885 if (nullptr == nameIter) { |
1886 AutoCFRelease<CFStringRef> cfLanguage; | 1886 AutoCFRelease<CFStringRef> cfLanguage; |
1887 AutoCFRelease<CFStringRef> cfFamilyName( | 1887 AutoCFRelease<CFStringRef> cfFamilyName( |
1888 CTFontCopyLocalizedName(fFontRef, kCTFontFamilyNameKey, &cfLanguage)
); | 1888 CTFontCopyLocalizedName(fFontRef, kCTFontFamilyNameKey, &cfLanguage)
); |
1889 | 1889 |
1890 SkString skLanguage; | 1890 SkString skLanguage; |
1891 SkString skFamilyName; | 1891 SkString skFamilyName; |
1892 if (cfLanguage.get()) { | 1892 if (cfLanguage.get()) { |
1893 CFStringToSkString(cfLanguage.get(), &skLanguage); | 1893 CFStringToSkString(cfLanguage.get(), &skLanguage); |
1894 } else { | 1894 } else { |
1895 skLanguage = "und"; //undetermined | 1895 skLanguage = "und"; //undetermined |
1896 } | 1896 } |
1897 if (cfFamilyName.get()) { | 1897 if (cfFamilyName.get()) { |
1898 CFStringToSkString(cfFamilyName.get(), &skFamilyName); | 1898 CFStringToSkString(cfFamilyName.get(), &skFamilyName); |
1899 } | 1899 } |
1900 | 1900 |
1901 nameIter = new SkOTUtils::LocalizedStrings_SingleName(skFamilyName, skLa
nguage); | 1901 nameIter = new SkOTUtils::LocalizedStrings_SingleName(skFamilyName, skLa
nguage); |
1902 } | 1902 } |
1903 return nameIter; | 1903 return nameIter; |
1904 } | 1904 } |
1905 | 1905 |
1906 // If, as is the case with web fonts, the CTFont data isn't available, | 1906 // If, as is the case with web fonts, the CTFont data isn't available, |
1907 // the CGFont data may work. While the CGFont may always provide the | 1907 // the CGFont data may work. While the CGFont may always provide the |
1908 // right result, leave the CTFont code path to minimize disruption. | 1908 // right result, leave the CTFont code path to minimize disruption. |
1909 static CFDataRef copyTableFromFont(CTFontRef ctFont, SkFontTableTag tag) { | 1909 static CFDataRef copyTableFromFont(CTFontRef ctFont, SkFontTableTag tag) { |
1910 CFDataRef data = CTFontCopyTable(ctFont, (CTFontTableTag) tag, | 1910 CFDataRef data = CTFontCopyTable(ctFont, (CTFontTableTag) tag, |
1911 kCTFontTableOptionNoOptions); | 1911 kCTFontTableOptionNoOptions); |
1912 if (NULL == data) { | 1912 if (nullptr == data) { |
1913 AutoCFRelease<CGFontRef> cgFont(CTFontCopyGraphicsFont(ctFont, NULL)); | 1913 AutoCFRelease<CGFontRef> cgFont(CTFontCopyGraphicsFont(ctFont, nullptr))
; |
1914 data = CGFontCopyTableForTag(cgFont, tag); | 1914 data = CGFontCopyTableForTag(cgFont, tag); |
1915 } | 1915 } |
1916 return data; | 1916 return data; |
1917 } | 1917 } |
1918 | 1918 |
1919 int SkTypeface_Mac::onGetTableTags(SkFontTableTag tags[]) const { | 1919 int SkTypeface_Mac::onGetTableTags(SkFontTableTag tags[]) const { |
1920 AutoCFRelease<CFArrayRef> cfArray(CTFontCopyAvailableTables(fFontRef, | 1920 AutoCFRelease<CFArrayRef> cfArray(CTFontCopyAvailableTables(fFontRef, |
1921 kCTFontTableOptionNoOptions)); | 1921 kCTFontTableOptionNoOptions)); |
1922 if (NULL == cfArray) { | 1922 if (nullptr == cfArray) { |
1923 return 0; | 1923 return 0; |
1924 } | 1924 } |
1925 int count = SkToInt(CFArrayGetCount(cfArray)); | 1925 int count = SkToInt(CFArrayGetCount(cfArray)); |
1926 if (tags) { | 1926 if (tags) { |
1927 for (int i = 0; i < count; ++i) { | 1927 for (int i = 0; i < count; ++i) { |
1928 uintptr_t fontTag = reinterpret_cast<uintptr_t>(CFArrayGetValueAtInd
ex(cfArray, i)); | 1928 uintptr_t fontTag = reinterpret_cast<uintptr_t>(CFArrayGetValueAtInd
ex(cfArray, i)); |
1929 tags[i] = static_cast<SkFontTableTag>(fontTag); | 1929 tags[i] = static_cast<SkFontTableTag>(fontTag); |
1930 } | 1930 } |
1931 } | 1931 } |
1932 return count; | 1932 return count; |
1933 } | 1933 } |
1934 | 1934 |
1935 size_t SkTypeface_Mac::onGetTableData(SkFontTableTag tag, size_t offset, | 1935 size_t SkTypeface_Mac::onGetTableData(SkFontTableTag tag, size_t offset, |
1936 size_t length, void* dstData) const { | 1936 size_t length, void* dstData) const { |
1937 AutoCFRelease<CFDataRef> srcData(copyTableFromFont(fFontRef, tag)); | 1937 AutoCFRelease<CFDataRef> srcData(copyTableFromFont(fFontRef, tag)); |
1938 if (NULL == srcData) { | 1938 if (nullptr == srcData) { |
1939 return 0; | 1939 return 0; |
1940 } | 1940 } |
1941 | 1941 |
1942 size_t srcSize = CFDataGetLength(srcData); | 1942 size_t srcSize = CFDataGetLength(srcData); |
1943 if (offset >= srcSize) { | 1943 if (offset >= srcSize) { |
1944 return 0; | 1944 return 0; |
1945 } | 1945 } |
1946 if (length > srcSize - offset) { | 1946 if (length > srcSize - offset) { |
1947 length = srcSize - offset; | 1947 length = srcSize - offset; |
1948 } | 1948 } |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2032 rec->ignorePreBlend(); | 2032 rec->ignorePreBlend(); |
2033 #endif | 2033 #endif |
2034 } else { | 2034 } else { |
2035 //CoreGraphics dialates smoothed text as needed. | 2035 //CoreGraphics dialates smoothed text as needed. |
2036 rec->setContrast(0); | 2036 rec->setContrast(0); |
2037 } | 2037 } |
2038 } | 2038 } |
2039 | 2039 |
2040 // we take ownership of the ref | 2040 // we take ownership of the ref |
2041 static const char* get_str(CFStringRef ref, SkString* str) { | 2041 static const char* get_str(CFStringRef ref, SkString* str) { |
2042 if (NULL == ref) { | 2042 if (nullptr == ref) { |
2043 return NULL; | 2043 return nullptr; |
2044 } | 2044 } |
2045 CFStringToSkString(ref, str); | 2045 CFStringToSkString(ref, str); |
2046 CFSafeRelease(ref); | 2046 CFSafeRelease(ref); |
2047 return str->c_str(); | 2047 return str->c_str(); |
2048 } | 2048 } |
2049 | 2049 |
2050 void SkTypeface_Mac::onGetFamilyName(SkString* familyName) const { | 2050 void SkTypeface_Mac::onGetFamilyName(SkString* familyName) const { |
2051 get_str(CTFontCopyFamilyName(fFontRef), familyName); | 2051 get_str(CTFontCopyFamilyName(fFontRef), familyName); |
2052 } | 2052 } |
2053 | 2053 |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2099 UniChar* utf16 = charStorage.reset(2 * glyphCount); | 2099 UniChar* utf16 = charStorage.reset(2 * glyphCount); |
2100 src = utf16; | 2100 src = utf16; |
2101 for (int i = 0; i < glyphCount; ++i) { | 2101 for (int i = 0; i < glyphCount; ++i) { |
2102 utf16 += SkUTF16_FromUnichar(utf32[i], utf16); | 2102 utf16 += SkUTF16_FromUnichar(utf32[i], utf16); |
2103 } | 2103 } |
2104 srcCount = SkToInt(utf16 - src); | 2104 srcCount = SkToInt(utf16 - src); |
2105 break; | 2105 break; |
2106 } | 2106 } |
2107 } | 2107 } |
2108 | 2108 |
2109 // If glyphs is NULL, CT still needs glyph storage for finding the first fai
lure. | 2109 // If glyphs is nullptr, CT still needs glyph storage for finding the first
failure. |
2110 // Also, if there are any non-bmp code points, the provided 'glyphs' storage
will be inadequate. | 2110 // Also, if there are any non-bmp code points, the provided 'glyphs' storage
will be inadequate. |
2111 SkAutoSTMalloc<1024, uint16_t> glyphStorage; | 2111 SkAutoSTMalloc<1024, uint16_t> glyphStorage; |
2112 uint16_t* macGlyphs = glyphs; | 2112 uint16_t* macGlyphs = glyphs; |
2113 if (NULL == macGlyphs || srcCount > glyphCount) { | 2113 if (nullptr == macGlyphs || srcCount > glyphCount) { |
2114 macGlyphs = glyphStorage.reset(srcCount); | 2114 macGlyphs = glyphStorage.reset(srcCount); |
2115 } | 2115 } |
2116 | 2116 |
2117 bool allEncoded = CTFontGetGlyphsForCharacters(fFontRef, src, macGlyphs, src
Count); | 2117 bool allEncoded = CTFontGetGlyphsForCharacters(fFontRef, src, macGlyphs, src
Count); |
2118 | 2118 |
2119 // If there were any non-bmp, then copy and compact. | 2119 // If there were any non-bmp, then copy and compact. |
2120 // If 'glyphs' is NULL, then compact glyphStorage in-place. | 2120 // If 'glyphs' is nullptr, then compact glyphStorage in-place. |
2121 // If all are bmp and 'glyphs' is non-NULL, 'glyphs' already contains the co
mpact glyphs. | 2121 // If all are bmp and 'glyphs' is non-nullptr, 'glyphs' already contains the
compact glyphs. |
2122 // If some are non-bmp and 'glyphs' is non-NULL, copy and compact into 'glyp
hs'. | 2122 // If some are non-bmp and 'glyphs' is non-nullptr, copy and compact into 'g
lyphs'. |
2123 uint16_t* compactedGlyphs = glyphs; | 2123 uint16_t* compactedGlyphs = glyphs; |
2124 if (NULL == compactedGlyphs) { | 2124 if (nullptr == compactedGlyphs) { |
2125 compactedGlyphs = macGlyphs; | 2125 compactedGlyphs = macGlyphs; |
2126 } | 2126 } |
2127 if (srcCount > glyphCount) { | 2127 if (srcCount > glyphCount) { |
2128 int extra = 0; | 2128 int extra = 0; |
2129 for (int i = 0; i < glyphCount; ++i) { | 2129 for (int i = 0; i < glyphCount; ++i) { |
2130 compactedGlyphs[i] = macGlyphs[i + extra]; | 2130 compactedGlyphs[i] = macGlyphs[i + extra]; |
2131 if (SkUTF16_IsHighSurrogate(src[i + extra])) { | 2131 if (SkUTF16_IsHighSurrogate(src[i + extra])) { |
2132 ++extra; | 2132 ++extra; |
2133 } | 2133 } |
2134 } | 2134 } |
(...skipping 15 matching lines...) Expand all Loading... |
2150 | 2150 |
2151 int SkTypeface_Mac::onCountGlyphs() const { | 2151 int SkTypeface_Mac::onCountGlyphs() const { |
2152 return SkToInt(CTFontGetGlyphCount(fFontRef)); | 2152 return SkToInt(CTFontGetGlyphCount(fFontRef)); |
2153 } | 2153 } |
2154 | 2154 |
2155 /////////////////////////////////////////////////////////////////////////////// | 2155 /////////////////////////////////////////////////////////////////////////////// |
2156 /////////////////////////////////////////////////////////////////////////////// | 2156 /////////////////////////////////////////////////////////////////////////////// |
2157 | 2157 |
2158 static bool find_desc_str(CTFontDescriptorRef desc, CFStringRef name, SkString*
value) { | 2158 static bool find_desc_str(CTFontDescriptorRef desc, CFStringRef name, SkString*
value) { |
2159 AutoCFRelease<CFStringRef> ref((CFStringRef)CTFontDescriptorCopyAttribute(de
sc, name)); | 2159 AutoCFRelease<CFStringRef> ref((CFStringRef)CTFontDescriptorCopyAttribute(de
sc, name)); |
2160 if (NULL == ref.get()) { | 2160 if (nullptr == ref.get()) { |
2161 return false; | 2161 return false; |
2162 } | 2162 } |
2163 CFStringToSkString(ref, value); | 2163 CFStringToSkString(ref, value); |
2164 return true; | 2164 return true; |
2165 } | 2165 } |
2166 | 2166 |
2167 #include "SkFontMgr.h" | 2167 #include "SkFontMgr.h" |
2168 | 2168 |
2169 static inline int sqr(int value) { | 2169 static inline int sqr(int value) { |
2170 SkASSERT(SkAbs32(value) < 0x7FFF); // check for overflow | 2170 SkASSERT(SkAbs32(value) < 0x7FFF); // check for overflow |
(...skipping 12 matching lines...) Expand all Loading... |
2183 SkString skFamilyName; | 2183 SkString skFamilyName; |
2184 CFStringToSkString(cfFamilyName, &skFamilyName); | 2184 CFStringToSkString(cfFamilyName, &skFamilyName); |
2185 cacheRequest.fName = skFamilyName.c_str(); | 2185 cacheRequest.fName = skFamilyName.c_str(); |
2186 cacheRequest.fStyle = fontstyle_from_descriptor(desc); | 2186 cacheRequest.fStyle = fontstyle_from_descriptor(desc); |
2187 | 2187 |
2188 SkTypeface* face = SkTypefaceCache::FindByProcAndRef(find_by_NameStyle, &cac
heRequest); | 2188 SkTypeface* face = SkTypefaceCache::FindByProcAndRef(find_by_NameStyle, &cac
heRequest); |
2189 if (face) { | 2189 if (face) { |
2190 return face; | 2190 return face; |
2191 } | 2191 } |
2192 | 2192 |
2193 AutoCFRelease<CTFontRef> ctFont(CTFontCreateWithFontDescriptor(desc, 0, NULL
)); | 2193 AutoCFRelease<CTFontRef> ctFont(CTFontCreateWithFontDescriptor(desc, 0, null
ptr)); |
2194 if (!ctFont) { | 2194 if (!ctFont) { |
2195 return NULL; | 2195 return nullptr; |
2196 } | 2196 } |
2197 | 2197 |
2198 bool isFixedPitch; | 2198 bool isFixedPitch; |
2199 (void)computeStyleBits(ctFont, &isFixedPitch); | 2199 (void)computeStyleBits(ctFont, &isFixedPitch); |
2200 | 2200 |
2201 face = new SkTypeface_Mac(ctFont.detach(), NULL, cacheRequest.fStyle, isFixe
dPitch, | 2201 face = new SkTypeface_Mac(ctFont.detach(), nullptr, cacheRequest.fStyle, isF
ixedPitch, |
2202 skFamilyName.c_str(), false); | 2202 skFamilyName.c_str(), false); |
2203 SkTypefaceCache::Add(face, face->fontStyle()); | 2203 SkTypefaceCache::Add(face, face->fontStyle()); |
2204 return face; | 2204 return face; |
2205 } | 2205 } |
2206 | 2206 |
2207 class SkFontStyleSet_Mac : public SkFontStyleSet { | 2207 class SkFontStyleSet_Mac : public SkFontStyleSet { |
2208 public: | 2208 public: |
2209 SkFontStyleSet_Mac(CFStringRef familyName, CTFontDescriptorRef desc) | 2209 SkFontStyleSet_Mac(CFStringRef familyName, CTFontDescriptorRef desc) |
2210 : fArray(CTFontDescriptorCreateMatchingFontDescriptors(desc, NULL)) | 2210 : fArray(CTFontDescriptorCreateMatchingFontDescriptors(desc, nullptr)) |
2211 , fFamilyName(familyName) | 2211 , fFamilyName(familyName) |
2212 , fCount(0) { | 2212 , fCount(0) { |
2213 CFRetain(familyName); | 2213 CFRetain(familyName); |
2214 if (NULL == fArray) { | 2214 if (nullptr == fArray) { |
2215 fArray = CFArrayCreate(NULL, NULL, 0, NULL); | 2215 fArray = CFArrayCreate(nullptr, nullptr, 0, nullptr); |
2216 } | 2216 } |
2217 fCount = SkToInt(CFArrayGetCount(fArray)); | 2217 fCount = SkToInt(CFArrayGetCount(fArray)); |
2218 } | 2218 } |
2219 | 2219 |
2220 virtual ~SkFontStyleSet_Mac() { | 2220 virtual ~SkFontStyleSet_Mac() { |
2221 CFRelease(fArray); | 2221 CFRelease(fArray); |
2222 CFRelease(fFamilyName); | 2222 CFRelease(fFamilyName); |
2223 } | 2223 } |
2224 | 2224 |
2225 int count() override { | 2225 int count() override { |
(...skipping 15 matching lines...) Expand all Loading... |
2241 | 2241 |
2242 SkTypeface* createTypeface(int index) override { | 2242 SkTypeface* createTypeface(int index) override { |
2243 SkASSERT((unsigned)index < (unsigned)CFArrayGetCount(fArray)); | 2243 SkASSERT((unsigned)index < (unsigned)CFArrayGetCount(fArray)); |
2244 CTFontDescriptorRef desc = (CTFontDescriptorRef)CFArrayGetValueAtIndex(f
Array, index); | 2244 CTFontDescriptorRef desc = (CTFontDescriptorRef)CFArrayGetValueAtIndex(f
Array, index); |
2245 | 2245 |
2246 return createFromDesc(fFamilyName, desc); | 2246 return createFromDesc(fFamilyName, desc); |
2247 } | 2247 } |
2248 | 2248 |
2249 SkTypeface* matchStyle(const SkFontStyle& pattern) override { | 2249 SkTypeface* matchStyle(const SkFontStyle& pattern) override { |
2250 if (0 == fCount) { | 2250 if (0 == fCount) { |
2251 return NULL; | 2251 return nullptr; |
2252 } | 2252 } |
2253 return createFromDesc(fFamilyName, findMatchingDesc(pattern)); | 2253 return createFromDesc(fFamilyName, findMatchingDesc(pattern)); |
2254 } | 2254 } |
2255 | 2255 |
2256 private: | 2256 private: |
2257 CFArrayRef fArray; | 2257 CFArrayRef fArray; |
2258 CFStringRef fFamilyName; | 2258 CFStringRef fFamilyName; |
2259 int fCount; | 2259 int fCount; |
2260 | 2260 |
2261 CTFontDescriptorRef findMatchingDesc(const SkFontStyle& pattern) const { | 2261 CTFontDescriptorRef findMatchingDesc(const SkFontStyle& pattern) const { |
2262 int bestMetric = SK_MaxS32; | 2262 int bestMetric = SK_MaxS32; |
2263 CTFontDescriptorRef bestDesc = NULL; | 2263 CTFontDescriptorRef bestDesc = nullptr; |
2264 | 2264 |
2265 for (int i = 0; i < fCount; ++i) { | 2265 for (int i = 0; i < fCount; ++i) { |
2266 CTFontDescriptorRef desc = (CTFontDescriptorRef)CFArrayGetValueAtInd
ex(fArray, i); | 2266 CTFontDescriptorRef desc = (CTFontDescriptorRef)CFArrayGetValueAtInd
ex(fArray, i); |
2267 int metric = compute_metric(pattern, fontstyle_from_descriptor(desc)
); | 2267 int metric = compute_metric(pattern, fontstyle_from_descriptor(desc)
); |
2268 if (0 == metric) { | 2268 if (0 == metric) { |
2269 return desc; | 2269 return desc; |
2270 } | 2270 } |
2271 if (metric < bestMetric) { | 2271 if (metric < bestMetric) { |
2272 bestMetric = metric; | 2272 bestMetric = metric; |
2273 bestDesc = desc; | 2273 bestDesc = desc; |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2317 void onGetFamilyName(int index, SkString* familyName) const override { | 2317 void onGetFamilyName(int index, SkString* familyName) const override { |
2318 if ((unsigned)index < (unsigned)fCount) { | 2318 if ((unsigned)index < (unsigned)fCount) { |
2319 CFStringToSkString(this->stringAt(index), familyName); | 2319 CFStringToSkString(this->stringAt(index), familyName); |
2320 } else { | 2320 } else { |
2321 familyName->reset(); | 2321 familyName->reset(); |
2322 } | 2322 } |
2323 } | 2323 } |
2324 | 2324 |
2325 SkFontStyleSet* onCreateStyleSet(int index) const override { | 2325 SkFontStyleSet* onCreateStyleSet(int index) const override { |
2326 if ((unsigned)index >= (unsigned)fCount) { | 2326 if ((unsigned)index >= (unsigned)fCount) { |
2327 return NULL; | 2327 return nullptr; |
2328 } | 2328 } |
2329 return CreateSet(this->stringAt(index)); | 2329 return CreateSet(this->stringAt(index)); |
2330 } | 2330 } |
2331 | 2331 |
2332 SkFontStyleSet* onMatchFamily(const char familyName[]) const override { | 2332 SkFontStyleSet* onMatchFamily(const char familyName[]) const override { |
2333 AutoCFRelease<CFStringRef> cfName(make_CFString(familyName)); | 2333 AutoCFRelease<CFStringRef> cfName(make_CFString(familyName)); |
2334 return CreateSet(cfName); | 2334 return CreateSet(cfName); |
2335 } | 2335 } |
2336 | 2336 |
2337 virtual SkTypeface* onMatchFamilyStyle(const char familyName[], | 2337 virtual SkTypeface* onMatchFamilyStyle(const char familyName[], |
2338 const SkFontStyle&) const override { | 2338 const SkFontStyle&) const override { |
2339 return NULL; | 2339 return nullptr; |
2340 } | 2340 } |
2341 | 2341 |
2342 virtual SkTypeface* onMatchFamilyStyleCharacter(const char familyName[], con
st SkFontStyle&, | 2342 virtual SkTypeface* onMatchFamilyStyleCharacter(const char familyName[], con
st SkFontStyle&, |
2343 const char* bcp47[], int bcp
47Count, | 2343 const char* bcp47[], int bcp
47Count, |
2344 SkUnichar character) const o
verride { | 2344 SkUnichar character) const o
verride { |
2345 return NULL; | 2345 return nullptr; |
2346 } | 2346 } |
2347 | 2347 |
2348 virtual SkTypeface* onMatchFaceStyle(const SkTypeface* familyMember, | 2348 virtual SkTypeface* onMatchFaceStyle(const SkTypeface* familyMember, |
2349 const SkFontStyle&) const override { | 2349 const SkFontStyle&) const override { |
2350 return NULL; | 2350 return nullptr; |
2351 } | 2351 } |
2352 | 2352 |
2353 SkTypeface* onCreateFromData(SkData* data, int ttcIndex) const override { | 2353 SkTypeface* onCreateFromData(SkData* data, int ttcIndex) const override { |
2354 AutoCFRelease<CGDataProviderRef> pr(SkCreateDataProviderFromData(data)); | 2354 AutoCFRelease<CGDataProviderRef> pr(SkCreateDataProviderFromData(data)); |
2355 if (NULL == pr) { | 2355 if (nullptr == pr) { |
2356 return NULL; | 2356 return nullptr; |
2357 } | 2357 } |
2358 return create_from_dataProvider(pr); | 2358 return create_from_dataProvider(pr); |
2359 } | 2359 } |
2360 | 2360 |
2361 SkTypeface* onCreateFromStream(SkStreamAsset* stream, int ttcIndex) const ov
erride { | 2361 SkTypeface* onCreateFromStream(SkStreamAsset* stream, int ttcIndex) const ov
erride { |
2362 AutoCFRelease<CGDataProviderRef> pr(SkCreateDataProviderFromStream(strea
m)); | 2362 AutoCFRelease<CGDataProviderRef> pr(SkCreateDataProviderFromStream(strea
m)); |
2363 if (NULL == pr) { | 2363 if (nullptr == pr) { |
2364 return NULL; | 2364 return nullptr; |
2365 } | 2365 } |
2366 return create_from_dataProvider(pr); | 2366 return create_from_dataProvider(pr); |
2367 } | 2367 } |
2368 | 2368 |
2369 static CFDictionaryRef get_axes(CGFontRef cg, SkFontData* fontData) { | 2369 static CFDictionaryRef get_axes(CGFontRef cg, SkFontData* fontData) { |
2370 AutoCFRelease<CFArrayRef> cgAxes(CGFontCopyVariationAxes(cg)); | 2370 AutoCFRelease<CFArrayRef> cgAxes(CGFontCopyVariationAxes(cg)); |
2371 if (!cgAxes) { | 2371 if (!cgAxes) { |
2372 return NULL; | 2372 return nullptr; |
2373 } | 2373 } |
2374 | 2374 |
2375 CFIndex axisCount = CFArrayGetCount(cgAxes); | 2375 CFIndex axisCount = CFArrayGetCount(cgAxes); |
2376 if (0 == axisCount || axisCount != fontData->getAxisCount()) { | 2376 if (0 == axisCount || axisCount != fontData->getAxisCount()) { |
2377 return NULL; | 2377 return nullptr; |
2378 } | 2378 } |
2379 | 2379 |
2380 CFMutableDictionaryRef dict = CFDictionaryCreateMutable(kCFAllocatorDefa
ult, axisCount, | 2380 CFMutableDictionaryRef dict = CFDictionaryCreateMutable(kCFAllocatorDefa
ult, axisCount, |
2381 &kCFTypeDictiona
ryKeyCallBacks, | 2381 &kCFTypeDictiona
ryKeyCallBacks, |
2382 &kCFTypeDictiona
ryValueCallBacks); | 2382 &kCFTypeDictiona
ryValueCallBacks); |
2383 for (int i = 0; i < fontData->getAxisCount(); ++i) { | 2383 for (int i = 0; i < fontData->getAxisCount(); ++i) { |
2384 CFTypeRef axisInfo = CFArrayGetValueAtIndex(cgAxes, i); | 2384 CFTypeRef axisInfo = CFArrayGetValueAtIndex(cgAxes, i); |
2385 if (CFDictionaryGetTypeID() != CFGetTypeID(axisInfo)) { | 2385 if (CFDictionaryGetTypeID() != CFGetTypeID(axisInfo)) { |
2386 return NULL; | 2386 return nullptr; |
2387 } | 2387 } |
2388 CFDictionaryRef axisInfoDict = static_cast<CFDictionaryRef>(axisInfo
); | 2388 CFDictionaryRef axisInfoDict = static_cast<CFDictionaryRef>(axisInfo
); |
2389 | 2389 |
2390 CFTypeRef axisName = CFDictionaryGetValue(axisInfoDict, kCGFontVaria
tionAxisName); | 2390 CFTypeRef axisName = CFDictionaryGetValue(axisInfoDict, kCGFontVaria
tionAxisName); |
2391 if (!axisName || CFGetTypeID(axisName) != CFStringGetTypeID()) { | 2391 if (!axisName || CFGetTypeID(axisName) != CFStringGetTypeID()) { |
2392 return NULL; | 2392 return nullptr; |
2393 } | 2393 } |
2394 | 2394 |
2395 // The variation axes can be set to any value, but cg will effective
ly pin them. | 2395 // The variation axes can be set to any value, but cg will effective
ly pin them. |
2396 // Pin them here to normalize. | 2396 // Pin them here to normalize. |
2397 CFTypeRef min = CFDictionaryGetValue(axisInfoDict, kCGFontVariationA
xisMinValue); | 2397 CFTypeRef min = CFDictionaryGetValue(axisInfoDict, kCGFontVariationA
xisMinValue); |
2398 CFTypeRef max = CFDictionaryGetValue(axisInfoDict, kCGFontVariationA
xisMaxValue); | 2398 CFTypeRef max = CFDictionaryGetValue(axisInfoDict, kCGFontVariationA
xisMaxValue); |
2399 if (!min || CFGetTypeID(min) != CFNumberGetTypeID() || | 2399 if (!min || CFGetTypeID(min) != CFNumberGetTypeID() || |
2400 !max || CFGetTypeID(max) != CFNumberGetTypeID()) | 2400 !max || CFGetTypeID(max) != CFNumberGetTypeID()) |
2401 { | 2401 { |
2402 return NULL; | 2402 return nullptr; |
2403 } | 2403 } |
2404 CFNumberRef minNumber = static_cast<CFNumberRef>(min); | 2404 CFNumberRef minNumber = static_cast<CFNumberRef>(min); |
2405 CFNumberRef maxNumber = static_cast<CFNumberRef>(max); | 2405 CFNumberRef maxNumber = static_cast<CFNumberRef>(max); |
2406 double minDouble; | 2406 double minDouble; |
2407 double maxDouble; | 2407 double maxDouble; |
2408 if (!CFNumberGetValue(minNumber, kCFNumberDoubleType, &minDouble) || | 2408 if (!CFNumberGetValue(minNumber, kCFNumberDoubleType, &minDouble) || |
2409 !CFNumberGetValue(maxNumber, kCFNumberDoubleType, &maxDouble)) | 2409 !CFNumberGetValue(maxNumber, kCFNumberDoubleType, &maxDouble)) |
2410 { | 2410 { |
2411 return NULL; | 2411 return nullptr; |
2412 } | 2412 } |
2413 double value = SkTPin(SkFixedToDouble(fontData->getAxis()[i]), minDo
uble, maxDouble); | 2413 double value = SkTPin(SkFixedToDouble(fontData->getAxis()[i]), minDo
uble, maxDouble); |
2414 CFNumberRef valueNumber = CFNumberCreate(kCFAllocatorDefault, kCFNum
berDoubleType, | 2414 CFNumberRef valueNumber = CFNumberCreate(kCFAllocatorDefault, kCFNum
berDoubleType, |
2415 &value); | 2415 &value); |
2416 | 2416 |
2417 CFDictionaryAddValue(dict, axisName, valueNumber); | 2417 CFDictionaryAddValue(dict, axisName, valueNumber); |
2418 CFRelease(valueNumber); | 2418 CFRelease(valueNumber); |
2419 } | 2419 } |
2420 return dict; | 2420 return dict; |
2421 } | 2421 } |
2422 SkTypeface* onCreateFromFontData(SkFontData* data) const override { | 2422 SkTypeface* onCreateFromFontData(SkFontData* data) const override { |
2423 SkAutoTDelete<SkFontData> fontData(data); | 2423 SkAutoTDelete<SkFontData> fontData(data); |
2424 SkStreamAsset* stream = fontData->detachStream(); | 2424 SkStreamAsset* stream = fontData->detachStream(); |
2425 AutoCFRelease<CGDataProviderRef> provider(SkCreateDataProviderFromStream
(stream)); | 2425 AutoCFRelease<CGDataProviderRef> provider(SkCreateDataProviderFromStream
(stream)); |
2426 if (NULL == provider) { | 2426 if (nullptr == provider) { |
2427 return NULL; | 2427 return nullptr; |
2428 } | 2428 } |
2429 AutoCFRelease<CGFontRef> cg(CGFontCreateWithDataProvider(provider)); | 2429 AutoCFRelease<CGFontRef> cg(CGFontCreateWithDataProvider(provider)); |
2430 if (NULL == cg) { | 2430 if (nullptr == cg) { |
2431 return NULL; | 2431 return nullptr; |
2432 } | 2432 } |
2433 | 2433 |
2434 AutoCFRelease<CFDictionaryRef> cgVariations(get_axes(cg, fontData)); | 2434 AutoCFRelease<CFDictionaryRef> cgVariations(get_axes(cg, fontData)); |
2435 // The CGFontRef returned by CGFontCreateCopyWithVariations when the pas
sed CGFontRef was | 2435 // The CGFontRef returned by CGFontCreateCopyWithVariations when the pas
sed CGFontRef was |
2436 // created from a data provider does not appear to have any ownership of
the underlying | 2436 // created from a data provider does not appear to have any ownership of
the underlying |
2437 // data. The original CGFontRef must be kept alive until the copy will n
o longer be used. | 2437 // data. The original CGFontRef must be kept alive until the copy will n
o longer be used. |
2438 AutoCFRelease<CGFontRef> cgVariant; | 2438 AutoCFRelease<CGFontRef> cgVariant; |
2439 if (cgVariations) { | 2439 if (cgVariations) { |
2440 cgVariant.reset(CGFontCreateCopyWithVariations(cg, cgVariations)); | 2440 cgVariant.reset(CGFontCreateCopyWithVariations(cg, cgVariations)); |
2441 } else { | 2441 } else { |
2442 cgVariant.reset(cg.detach()); | 2442 cgVariant.reset(cg.detach()); |
2443 } | 2443 } |
2444 | 2444 |
2445 CTFontRef ct = CTFontCreateWithGraphicsFont(cgVariant, 0, NULL, NULL); | 2445 CTFontRef ct = CTFontCreateWithGraphicsFont(cgVariant, 0, nullptr, nullp
tr); |
2446 if (!ct) { | 2446 if (!ct) { |
2447 return NULL; | 2447 return nullptr; |
2448 } | 2448 } |
2449 return NewFromFontRef(ct, cg.detach(), NULL, true); | 2449 return NewFromFontRef(ct, cg.detach(), nullptr, true); |
2450 } | 2450 } |
2451 | 2451 |
2452 SkTypeface* onCreateFromFile(const char path[], int ttcIndex) const override
{ | 2452 SkTypeface* onCreateFromFile(const char path[], int ttcIndex) const override
{ |
2453 AutoCFRelease<CGDataProviderRef> pr(CGDataProviderCreateWithFilename(pat
h)); | 2453 AutoCFRelease<CGDataProviderRef> pr(CGDataProviderCreateWithFilename(pat
h)); |
2454 if (NULL == pr) { | 2454 if (nullptr == pr) { |
2455 return NULL; | 2455 return nullptr; |
2456 } | 2456 } |
2457 return create_from_dataProvider(pr); | 2457 return create_from_dataProvider(pr); |
2458 } | 2458 } |
2459 | 2459 |
2460 virtual SkTypeface* onLegacyCreateTypeface(const char familyName[], | 2460 virtual SkTypeface* onLegacyCreateTypeface(const char familyName[], |
2461 unsigned styleBits) const overrid
e { | 2461 unsigned styleBits) const overrid
e { |
2462 | 2462 |
2463 SkFontStyle style = SkFontStyle((SkTypeface::Style)styleBits); | 2463 SkFontStyle style = SkFontStyle((SkTypeface::Style)styleBits); |
2464 if (familyName) { | 2464 if (familyName) { |
2465 familyName = map_css_names(familyName); | 2465 familyName = map_css_names(familyName); |
2466 } | 2466 } |
2467 | 2467 |
2468 if (!familyName || !*familyName) { | 2468 if (!familyName || !*familyName) { |
2469 familyName = FONT_DEFAULT_NAME; | 2469 familyName = FONT_DEFAULT_NAME; |
2470 } | 2470 } |
2471 | 2471 |
2472 NameStyle cacheRequest = { familyName, style }; | 2472 NameStyle cacheRequest = { familyName, style }; |
2473 SkTypeface* face = SkTypefaceCache::FindByProcAndRef(find_by_NameStyle,
&cacheRequest); | 2473 SkTypeface* face = SkTypefaceCache::FindByProcAndRef(find_by_NameStyle,
&cacheRequest); |
2474 | 2474 |
2475 if (NULL == face) { | 2475 if (nullptr == face) { |
2476 face = NewFromName(familyName, style); | 2476 face = NewFromName(familyName, style); |
2477 if (face) { | 2477 if (face) { |
2478 SkTypefaceCache::Add(face, style); | 2478 SkTypefaceCache::Add(face, style); |
2479 } else { | 2479 } else { |
2480 face = GetDefaultFace(); | 2480 face = GetDefaultFace(); |
2481 face->ref(); | 2481 face->ref(); |
2482 } | 2482 } |
2483 } | 2483 } |
2484 return face; | 2484 return face; |
2485 } | 2485 } |
2486 }; | 2486 }; |
2487 | 2487 |
2488 /////////////////////////////////////////////////////////////////////////////// | 2488 /////////////////////////////////////////////////////////////////////////////// |
2489 | 2489 |
2490 SkFontMgr* SkFontMgr::Factory() { return new SkFontMgr_Mac; } | 2490 SkFontMgr* SkFontMgr::Factory() { return new SkFontMgr_Mac; } |
OLD | NEW |