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 264 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
275 | 275 |
276 static SkScalar CGToScalar(CGFloat cgFloat) { | 276 static SkScalar CGToScalar(CGFloat cgFloat) { |
277 if (sizeof(CGFloat) == sizeof(float)) { | 277 if (sizeof(CGFloat) == sizeof(float)) { |
278 return cgFloat; | 278 return cgFloat; |
279 } else { | 279 } else { |
280 SkASSERT(sizeof(CGFloat) == sizeof(double)); | 280 SkASSERT(sizeof(CGFloat) == sizeof(double)); |
281 return SkDoubleToScalar(cgFloat); | 281 return SkDoubleToScalar(cgFloat); |
282 } | 282 } |
283 } | 283 } |
284 | 284 |
285 static CGAffineTransform MatrixToCGAffineTransform(const SkMatrix& matrix) { | 285 static CGAffineTransform MatrixToCGAffineTransform(const SkMatrix& matrix, |
286 return CGAffineTransformMake( ScalarToCG(matrix[SkMatrix::kMScaleX]), | 286 SkScalar sx = SK_Scalar1, |
287 -ScalarToCG(matrix[SkMatrix::kMSkewY]), | 287 SkScalar sy = SK_Scalar1) { |
288 -ScalarToCG(matrix[SkMatrix::kMSkewX]), | 288 return CGAffineTransformMake( ScalarToCG(matrix[SkMatrix::kMScaleX] * sx), |
289 ScalarToCG(matrix[SkMatrix::kMScaleY]), | 289 -ScalarToCG(matrix[SkMatrix::kMSkewY] * sy), |
290 ScalarToCG(matrix[SkMatrix::kMTransX]), | 290 -ScalarToCG(matrix[SkMatrix::kMSkewX] * sx), |
291 ScalarToCG(matrix[SkMatrix::kMTransY])); | 291 ScalarToCG(matrix[SkMatrix::kMScaleY] * sy), |
| 292 ScalarToCG(matrix[SkMatrix::kMTransX] * sx), |
| 293 ScalarToCG(matrix[SkMatrix::kMTransY] * sy)); |
292 } | 294 } |
293 | 295 |
294 /////////////////////////////////////////////////////////////////////////////// | 296 /////////////////////////////////////////////////////////////////////////////// |
295 | 297 |
296 #define BITMAP_INFO_RGB (kCGImageAlphaNoneSkipFirst | kCGBitmapByteOrder32Host) | 298 #define BITMAP_INFO_RGB (kCGImageAlphaNoneSkipFirst | kCGBitmapByteOrder32Host) |
297 | 299 |
298 /** | 300 /** |
299 * There does not appear to be a publicly accessable API for determining if lcd | 301 * There does not appear to be a publicly accessable API for determining if lcd |
300 * font smoothing will be applied if we request it. The main issue is that if | 302 * font smoothing will be applied if we request it. The main issue is that if |
301 * smoothing is applied a gamma of 2.0 will be used, if not a gamma of 1.0. | 303 * smoothing is applied a gamma of 2.0 will be used, if not a gamma of 1.0. |
(...skipping 403 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
705 uint16_t fGlyphCount; | 707 uint16_t fGlyphCount; |
706 bool fGeneratedFBoundingBoxes; | 708 bool fGeneratedFBoundingBoxes; |
707 const bool fDoSubPosition; | 709 const bool fDoSubPosition; |
708 const bool fVertical; | 710 const bool fVertical; |
709 | 711 |
710 friend class Offscreen; | 712 friend class Offscreen; |
711 | 713 |
712 typedef SkScalerContext INHERITED; | 714 typedef SkScalerContext INHERITED; |
713 }; | 715 }; |
714 | 716 |
715 // CTFontCreateCopyWithAttributes or CTFontCreateCopyWithSymbolicTraits cannot b
e used on 10.10 | |
716 // as they appear to be buggy with respect to the default font. It is not possib
le to use | |
717 // descriptors with CTFontCreateWithFontDescriptor, since that does not work wit
h non-system | |
718 // fonts. As a result, create the strike specific CTFonts from the underlying CG
Font. | |
719 static CTFontRef ctfont_create_exact_copy(CTFontRef baseFont, CGFloat textSize, | |
720 const CGAffineTransform* transform, bo
ol setVertical) | |
721 { | |
722 AutoCFRelease<CTFontDescriptorRef> baseDescriptor; | |
723 AutoCFRelease<CGFontRef> baseCGFont(CTFontCopyGraphicsFont(baseFont, &baseDe
scriptor)); | |
724 | |
725 // Make a mutable copy of baseDescriptor attributes. | |
726 AutoCFRelease<CFMutableDictionaryRef> newAttributes([](CTFontDescriptorRef d
escriptor) -> | |
727 CFMutableDictionaryRef { | |
728 if (nullptr == descriptor) { | |
729 return CFDictionaryCreateMutable(kCFAllocatorDefault, 0, | |
730 &kCFTypeDictionaryKeyCallBacks, | |
731 &kCFTypeDictionaryValueCallBacks); | |
732 } | |
733 AutoCFRelease<CFDictionaryRef> attributes(CTFontDescriptorCopyAttributes
(descriptor)); | |
734 return CFDictionaryCreateMutableCopy(kCFAllocatorDefault, 0, attributes)
; | |
735 }(baseDescriptor)); | |
736 | |
737 // Set the text size in attributes. | |
738 AutoCFRelease<CFNumberRef> cfTextSize( | |
739 CFNumberCreate(kCFAllocatorDefault, kCFNumberCGFloatType, &textSize)); | |
740 CFDictionarySetValue(newAttributes, kCTFontSizeAttribute, cfTextSize); | |
741 | |
742 // Set the transform in attributes. | |
743 if (nullptr == transform) { | |
744 CFDictionaryRemoveValue(newAttributes, kCTFontMatrixAttribute); | |
745 } else { | |
746 AutoCFRelease<CFDataRef> cfMatrixData(CFDataCreate( | |
747 kCFAllocatorDefault, reinterpret_cast<const UInt8*>(transform), size
of(*transform))); | |
748 CFDictionarySetValue(newAttributes, kCTFontMatrixAttribute, cfMatrixData
); | |
749 } | |
750 | |
751 // Set vertical orientation to attributes if requested. | |
752 if (setVertical) { | |
753 CTFontOrientation ctOrientation = kCTFontVerticalOrientation; | |
754 AutoCFRelease<CFNumberRef> cfVertical( | |
755 CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &ctOrientat
ion)); | |
756 CFDictionarySetValue(newAttributes, kCTFontOrientationAttribute, cfVerti
cal); | |
757 } | |
758 | |
759 // Create the new CTFont from the baseCGFont. | |
760 AutoCFRelease<CTFontDescriptorRef> newDescriptor( | |
761 CTFontDescriptorCreateWithAttributes(newAttributes)); | |
762 return CTFontCreateWithGraphicsFont(baseCGFont, textSize, transform, newDesc
riptor); | |
763 | |
764 } | |
765 | |
766 SkScalerContext_Mac::SkScalerContext_Mac(SkTypeface_Mac* typeface, | 717 SkScalerContext_Mac::SkScalerContext_Mac(SkTypeface_Mac* typeface, |
767 const SkDescriptor* desc) | 718 const SkDescriptor* desc) |
768 : INHERITED(typeface, desc) | 719 : INHERITED(typeface, desc) |
769 , fFBoundingBoxes() | 720 , fFBoundingBoxes() |
770 , fFBoundingBoxesGlyphOffset(0) | 721 , fFBoundingBoxesGlyphOffset(0) |
771 , fGeneratedFBoundingBoxes(false) | 722 , fGeneratedFBoundingBoxes(false) |
772 , fDoSubPosition(SkToBool(fRec.fFlags & kSubpixelPositioning_Flag)) | 723 , fDoSubPosition(SkToBool(fRec.fFlags & kSubpixelPositioning_Flag)) |
773 , fVertical(SkToBool(fRec.fFlags & kVertical_Flag)) | 724 , fVertical(SkToBool(fRec.fFlags & kVertical_Flag)) |
774 | 725 |
775 { | 726 { |
776 AUTO_CG_LOCK(); | 727 AUTO_CG_LOCK(); |
777 | 728 |
778 CTFontRef ctFont = typeface->fFontRef.get(); | 729 CTFontRef ctFont = typeface->fFontRef.get(); |
779 CFIndex numGlyphs = CTFontGetGlyphCount(ctFont); | 730 CFIndex numGlyphs = CTFontGetGlyphCount(ctFont); |
780 SkASSERT(numGlyphs >= 1 && numGlyphs <= 0xFFFF); | 731 SkASSERT(numGlyphs >= 1 && numGlyphs <= 0xFFFF); |
781 fGlyphCount = SkToU16(numGlyphs); | 732 fGlyphCount = SkToU16(numGlyphs); |
782 | 733 |
783 // 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. |
784 // 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. |
785 SkVector scale; | 736 SkVector scale; |
786 SkMatrix skTransform; | 737 SkMatrix skTransform; |
787 fRec.computeMatrices(SkScalerContextRec::kVertical_PreMatrixScale, &scale, &
skTransform, | 738 fRec.computeMatrices(SkScalerContextRec::kVertical_PreMatrixScale, &scale, &
skTransform, |
788 nullptr, nullptr, &fFUnitMatrix); | 739 nullptr, nullptr, &fFUnitMatrix); |
789 fTransform = MatrixToCGAffineTransform(skTransform); | 740 fTransform = MatrixToCGAffineTransform(skTransform); |
790 fInvTransform = CGAffineTransformInvert(fTransform); | 741 fInvTransform = CGAffineTransformInvert(fTransform); |
791 | 742 |
| 743 AutoCFRelease<CTFontDescriptorRef> ctFontDesc; |
| 744 if (fVertical) { |
| 745 // Setting the vertical orientation here is required for vertical metric
s on some versions. |
| 746 AutoCFRelease<CFMutableDictionaryRef> cfAttributes(CFDictionaryCreateMut
able( |
| 747 kCFAllocatorDefault, 0, |
| 748 &kCFTypeDictionaryKeyCallBacks, |
| 749 &kCFTypeDictionaryValueCallBacks)); |
| 750 if (cfAttributes) { |
| 751 CTFontOrientation ctOrientation = kCTFontVerticalOrientation; |
| 752 AutoCFRelease<CFNumberRef> cfVertical(CFNumberCreate( |
| 753 kCFAllocatorDefault, kCFNumberSInt32Type, &ctOrientation)); |
| 754 CFDictionaryAddValue(cfAttributes, kCTFontOrientationAttribute, cfVe
rtical); |
| 755 ctFontDesc.reset(CTFontDescriptorCreateWithAttributes(cfAttributes))
; |
| 756 } |
| 757 } |
| 758 |
792 // The transform contains everything except the requested text size. | 759 // The transform contains everything except the requested text size. |
793 // 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). |
794 CGFloat textSize = ScalarToCG(scale.y()); | 761 CGFloat textSize = ScalarToCG(scale.y()); |
795 | 762 |
796 fCTFont.reset(ctfont_create_exact_copy(ctFont, textSize, &fTransform, fVerti
cal)); | 763 fCTFont.reset(CTFontCreateCopyWithAttributes(ctFont, textSize, &fTransform,
ctFontDesc)); |
797 fCGFont.reset(CTFontCopyGraphicsFont(fCTFont, nullptr)); | 764 fCGFont.reset(CTFontCopyGraphicsFont(fCTFont, nullptr)); |
798 fCTUnrotatedFont.reset(ctfont_create_exact_copy(ctFont, textSize, nullptr, f
alse)); | 765 fCTUnrotatedFont.reset(CTFontCreateCopyWithAttributes(ctFont, textSize, |
| 766 &CGAffineTransformIden
tity, nullptr)); |
799 | 767 |
800 // 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. |
801 SkScalar emPerFUnit = SkScalarInvert(SkIntToScalar(CGFontGetUnitsPerEm(fCGFo
nt))); | 769 SkScalar emPerFUnit = SkScalarInvert(SkIntToScalar(CGFontGetUnitsPerEm(fCGFo
nt))); |
802 fFUnitMatrix.preScale(emPerFUnit, -emPerFUnit); | 770 fFUnitMatrix.preScale(emPerFUnit, -emPerFUnit); |
803 } | 771 } |
804 | 772 |
805 /** This is an implementation of CTFontDrawGlyphs for 10.6; it was introduced in
10.7. */ | 773 /** This is an implementation of CTFontDrawGlyphs for 10.6; it was introduced in
10.7. */ |
806 static void legacy_CTFontDrawGlyphs(CTFontRef, const CGGlyph glyphs[], const CGP
oint points[], | 774 static void legacy_CTFontDrawGlyphs(CTFontRef, const CGGlyph glyphs[], const CGP
oint points[], |
807 size_t count, CGContextRef cg) { | 775 size_t count, CGContextRef cg) { |
808 CGContextShowGlyphsAtPositions(cg, glyphs, points, count); | 776 CGContextShowGlyphsAtPositions(cg, glyphs, points, count); |
(...skipping 579 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1388 case kX_SkAxisAlignment: | 1356 case kX_SkAxisAlignment: |
1389 scaleY = SK_Scalar1; // want hinting in the Y direction | 1357 scaleY = SK_Scalar1; // want hinting in the Y direction |
1390 break; | 1358 break; |
1391 case kY_SkAxisAlignment: | 1359 case kY_SkAxisAlignment: |
1392 scaleX = SK_Scalar1; // want hinting in the X direction | 1360 scaleX = SK_Scalar1; // want hinting in the X direction |
1393 break; | 1361 break; |
1394 default: | 1362 default: |
1395 break; | 1363 break; |
1396 } | 1364 } |
1397 | 1365 |
1398 CGFloat textSize = CTFontGetSize(fCTFont); | 1366 CGAffineTransform xform = MatrixToCGAffineTransform(m, scaleX, scaleY); |
1399 CGAffineTransform baseTransform = CTFontGetMatrix(fCTFont); | 1367 // need to release font when we're done |
1400 CGAffineTransform newTransform = | 1368 font = CTFontCreateCopyWithAttributes(fCTFont, 1, &xform, nullptr); |
1401 CGAffineTransformScale(baseTransform, ScalarToCG(scaleX), ScalarToCG
(scaleY)); | |
1402 | |
1403 // need to release this font when we're done | |
1404 font = ctfont_create_exact_copy(fCTFont, textSize, &newTransform, false)
; | |
1405 } | 1369 } |
1406 | 1370 |
1407 CGGlyph cgGlyph = (CGGlyph)glyph.getGlyphID(); | 1371 CGGlyph cgGlyph = (CGGlyph)glyph.getGlyphID(); |
1408 AutoCFRelease<CGPathRef> cgPath(CTFontCreatePathForGlyph(font, cgGlyph, null
ptr)); | 1372 AutoCFRelease<CGPathRef> cgPath(CTFontCreatePathForGlyph(font, cgGlyph, null
ptr)); |
1409 | 1373 |
1410 path->reset(); | 1374 path->reset(); |
1411 if (cgPath != nullptr) { | 1375 if (cgPath != nullptr) { |
1412 CGPathApply(cgPath, path, SkScalerContext_Mac::CTPathElement); | 1376 CGPathApply(cgPath, path, SkScalerContext_Mac::CTPathElement); |
1413 } | 1377 } |
1414 | 1378 |
1415 if (fDoSubPosition) { | 1379 if (fDoSubPosition) { |
1416 SkMatrix m; | 1380 SkMatrix m; |
1417 m.setScale(SkScalarInvert(scaleX), SkScalarInvert(scaleY)); | 1381 m.setScale(SkScalarInvert(scaleX), SkScalarInvert(scaleY)); |
1418 path->transform(m); | 1382 path->transform(m); |
1419 // balance the call to ctfont_create_exact_copy | 1383 // balance the call to CTFontCreateCopyWithAttributes |
1420 CFSafeRelease(font); | 1384 CFSafeRelease(font); |
1421 } | 1385 } |
1422 if (fVertical) { | 1386 if (fVertical) { |
1423 SkPoint offset; | 1387 SkPoint offset; |
1424 getVerticalOffset(cgGlyph, &offset); | 1388 getVerticalOffset(cgGlyph, &offset); |
1425 path->offset(offset.fX, offset.fY); | 1389 path->offset(offset.fX, offset.fY); |
1426 } | 1390 } |
1427 } | 1391 } |
1428 | 1392 |
1429 void SkScalerContext_Mac::generateFontMetrics(SkPaint::FontMetrics* metrics) { | 1393 void SkScalerContext_Mac::generateFontMetrics(SkPaint::FontMetrics* metrics) { |
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1590 } | 1554 } |
1591 | 1555 |
1592 SkAdvancedTypefaceMetrics* SkTypeface_Mac::onGetAdvancedTypefaceMetrics( | 1556 SkAdvancedTypefaceMetrics* SkTypeface_Mac::onGetAdvancedTypefaceMetrics( |
1593 PerGlyphInfo perGlyphInfo, | 1557 PerGlyphInfo perGlyphInfo, |
1594 const uint32_t* glyphIDs, | 1558 const uint32_t* glyphIDs, |
1595 uint32_t glyphIDsCount) const { | 1559 uint32_t glyphIDsCount) const { |
1596 | 1560 |
1597 AUTO_CG_LOCK(); | 1561 AUTO_CG_LOCK(); |
1598 | 1562 |
1599 CTFontRef originalCTFont = fFontRef.get(); | 1563 CTFontRef originalCTFont = fFontRef.get(); |
1600 AutoCFRelease<CTFontRef> ctFont(ctfont_create_exact_copy( | 1564 AutoCFRelease<CTFontRef> ctFont(CTFontCreateCopyWithAttributes( |
1601 originalCTFont, CTFontGetUnitsPerEm(originalCTFont), nullptr, false)
); | 1565 originalCTFont, CTFontGetUnitsPerEm(originalCTFont), nullptr, nullpt
r)); |
1602 | |
1603 SkAdvancedTypefaceMetrics* info = new SkAdvancedTypefaceMetrics; | 1566 SkAdvancedTypefaceMetrics* info = new SkAdvancedTypefaceMetrics; |
1604 | 1567 |
1605 { | 1568 { |
1606 AutoCFRelease<CFStringRef> fontName(CTFontCopyPostScriptName(ctFont)); | 1569 AutoCFRelease<CFStringRef> fontName(CTFontCopyPostScriptName(ctFont)); |
1607 if (fontName.get()) { | 1570 if (fontName.get()) { |
1608 CFStringToSkString(fontName, &info->fFontName); | 1571 CFStringToSkString(fontName, &info->fFontName); |
1609 } | 1572 } |
1610 } | 1573 } |
1611 | 1574 |
1612 CFIndex glyphCount = CTFontGetGlyphCount(ctFont); | 1575 CFIndex glyphCount = CTFontGetGlyphCount(ctFont); |
(...skipping 898 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2511 face->ref(); | 2474 face->ref(); |
2512 } | 2475 } |
2513 } | 2476 } |
2514 return face; | 2477 return face; |
2515 } | 2478 } |
2516 }; | 2479 }; |
2517 | 2480 |
2518 /////////////////////////////////////////////////////////////////////////////// | 2481 /////////////////////////////////////////////////////////////////////////////// |
2519 | 2482 |
2520 SkFontMgr* SkFontMgr::Factory() { return new SkFontMgr_Mac; } | 2483 SkFontMgr* SkFontMgr::Factory() { return new SkFontMgr_Mac; } |
OLD | NEW |