| 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 |