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 696 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
707 uint16_t fGlyphCount; | 707 uint16_t fGlyphCount; |
708 bool fGeneratedFBoundingBoxes; | 708 bool fGeneratedFBoundingBoxes; |
709 const bool fDoSubPosition; | 709 const bool fDoSubPosition; |
710 const bool fVertical; | 710 const bool fVertical; |
711 | 711 |
712 friend class Offscreen; | 712 friend class Offscreen; |
713 | 713 |
714 typedef SkScalerContext INHERITED; | 714 typedef SkScalerContext INHERITED; |
715 }; | 715 }; |
716 | 716 |
| 717 // CTFontCreateCopyWithAttributes or CTFontCreateCopyWithSymbolicTraits cannot b
e used on 10.10 |
| 718 // as they appear to be buggy with respect to the default font. It is not possib
le to use |
| 719 // descriptors with CTFontCreateWithFontDescriptor, since that does not work wit
h non-system |
| 720 // fonts. As a result, create the strike specific CTFonts from the underlying CG
Font. |
| 721 static CTFontRef ctfont_create_exact_copy(CTFontRef baseFont, CGFloat textSize, |
| 722 const CGAffineTransform* transform, bo
ol setVertical) |
| 723 { |
| 724 AutoCFRelease<CTFontDescriptorRef> baseExtraDescriptor; |
| 725 AutoCFRelease<CGFontRef> baseCGFont(CTFontCopyGraphicsFont(baseFont, &baseEx
traDescriptor)); |
| 726 |
| 727 // Make a mutable copy of baseExtraDescriptor attributes. |
| 728 AutoCFRelease<CFMutableDictionaryRef> newAttributes([](CTFontDescriptorRef d
escriptor) -> |
| 729 CFMutableDictionaryRef { |
| 730 if (nullptr == descriptor) { |
| 731 return CFDictionaryCreateMutable(kCFAllocatorDefault, 0, |
| 732 &kCFTypeDictionaryKeyCallBacks, |
| 733 &kCFTypeDictionaryValueCallBacks); |
| 734 } |
| 735 AutoCFRelease<CFDictionaryRef> attributes(CTFontDescriptorCopyAttributes
(descriptor)); |
| 736 return CFDictionaryCreateMutableCopy(kCFAllocatorDefault, 0, attributes)
; |
| 737 }(baseExtraDescriptor)); |
| 738 |
| 739 // Copy all of the attributes out of the CTFont. |
| 740 AutoCFRelease<CTFontDescriptorRef> baseDescriptor(CTFontCopyFontDescriptor(b
aseFont)); |
| 741 AutoCFRelease<CFDictionaryRef> baseAttributes(CTFontDescriptorCopyAttributes
(baseDescriptor)); |
| 742 CFDictionaryApplyFunction(baseAttributes, [](CFTypeRef key, CFTypeRef value,
void* context) { |
| 743 CFMutableDictionaryRef self = static_cast<CFMutableDictionaryRef>(contex
t); |
| 744 CFDictionarySetValue(self, key, value); |
| 745 }, newAttributes.get()); |
| 746 |
| 747 // Set the text size in attributes. |
| 748 AutoCFRelease<CFNumberRef> cfTextSize( |
| 749 CFNumberCreate(kCFAllocatorDefault, kCFNumberCGFloatType, &textSize)); |
| 750 CFDictionarySetValue(newAttributes, kCTFontSizeAttribute, cfTextSize); |
| 751 |
| 752 // Set the transform in attributes. |
| 753 if (nullptr == transform) { |
| 754 CFDictionaryRemoveValue(newAttributes, kCTFontMatrixAttribute); |
| 755 } else { |
| 756 AutoCFRelease<CFDataRef> cfMatrixData(CFDataCreate( |
| 757 kCFAllocatorDefault, reinterpret_cast<const UInt8*>(transform), size
of(*transform))); |
| 758 CFDictionarySetValue(newAttributes, kCTFontMatrixAttribute, cfMatrixData
); |
| 759 } |
| 760 |
| 761 // Set vertical orientation to attributes if requested. |
| 762 if (setVertical) { |
| 763 CTFontOrientation ctOrientation = kCTFontVerticalOrientation; |
| 764 AutoCFRelease<CFNumberRef> cfVertical( |
| 765 CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &ctOrientat
ion)); |
| 766 CFDictionarySetValue(newAttributes, kCTFontOrientationAttribute, cfVerti
cal); |
| 767 } |
| 768 |
| 769 // Create the new CTFont from the baseCGFont. |
| 770 AutoCFRelease<CTFontDescriptorRef> newDescriptor( |
| 771 CTFontDescriptorCreateWithAttributes(newAttributes)); |
| 772 return CTFontCreateWithGraphicsFont(baseCGFont, textSize, transform, newDesc
riptor); |
| 773 |
| 774 } |
| 775 |
717 SkScalerContext_Mac::SkScalerContext_Mac(SkTypeface_Mac* typeface, | 776 SkScalerContext_Mac::SkScalerContext_Mac(SkTypeface_Mac* typeface, |
718 const SkDescriptor* desc) | 777 const SkDescriptor* desc) |
719 : INHERITED(typeface, desc) | 778 : INHERITED(typeface, desc) |
720 , fFBoundingBoxes() | 779 , fFBoundingBoxes() |
721 , fFBoundingBoxesGlyphOffset(0) | 780 , fFBoundingBoxesGlyphOffset(0) |
722 , fGeneratedFBoundingBoxes(false) | 781 , fGeneratedFBoundingBoxes(false) |
723 , fDoSubPosition(SkToBool(fRec.fFlags & kSubpixelPositioning_Flag)) | 782 , fDoSubPosition(SkToBool(fRec.fFlags & kSubpixelPositioning_Flag)) |
724 , fVertical(SkToBool(fRec.fFlags & kVertical_Flag)) | 783 , fVertical(SkToBool(fRec.fFlags & kVertical_Flag)) |
725 | 784 |
726 { | 785 { |
727 AUTO_CG_LOCK(); | 786 AUTO_CG_LOCK(); |
728 | 787 |
729 CTFontRef ctFont = typeface->fFontRef.get(); | 788 CTFontRef ctFont = typeface->fFontRef.get(); |
730 CFIndex numGlyphs = CTFontGetGlyphCount(ctFont); | 789 CFIndex numGlyphs = CTFontGetGlyphCount(ctFont); |
731 SkASSERT(numGlyphs >= 1 && numGlyphs <= 0xFFFF); | 790 SkASSERT(numGlyphs >= 1 && numGlyphs <= 0xFFFF); |
732 fGlyphCount = SkToU16(numGlyphs); | 791 fGlyphCount = SkToU16(numGlyphs); |
733 | 792 |
734 // CT on (at least) 10.9 will size color glyphs down from the requested size
, but not up. | 793 // 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. | 794 // As a result, it is necessary to know the actual device size and request t
hat. |
736 SkVector scale; | 795 SkVector scale; |
737 SkMatrix skTransform; | 796 SkMatrix skTransform; |
738 fRec.computeMatrices(SkScalerContextRec::kVertical_PreMatrixScale, &scale, &
skTransform, | 797 fRec.computeMatrices(SkScalerContextRec::kVertical_PreMatrixScale, &scale, &
skTransform, |
739 nullptr, nullptr, &fFUnitMatrix); | 798 nullptr, nullptr, &fFUnitMatrix); |
740 fTransform = MatrixToCGAffineTransform(skTransform); | 799 fTransform = MatrixToCGAffineTransform(skTransform); |
741 fInvTransform = CGAffineTransformInvert(fTransform); | 800 fInvTransform = CGAffineTransformInvert(fTransform); |
742 | 801 |
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 | |
759 // The transform contains everything except the requested text size. | 802 // The transform contains everything except the requested text size. |
760 // Some properties, like 'trak', are based on the text size (before applying
the matrix). | 803 // Some properties, like 'trak', are based on the text size (before applying
the matrix). |
761 CGFloat textSize = ScalarToCG(scale.y()); | 804 CGFloat textSize = ScalarToCG(scale.y()); |
762 | 805 |
763 fCTFont.reset(CTFontCreateCopyWithAttributes(ctFont, textSize, &fTransform,
ctFontDesc)); | 806 fCTFont.reset(ctfont_create_exact_copy(ctFont, textSize, &fTransform, fVerti
cal)); |
764 fCGFont.reset(CTFontCopyGraphicsFont(fCTFont, nullptr)); | 807 fCGFont.reset(CTFontCopyGraphicsFont(fCTFont, nullptr)); |
765 fCTUnrotatedFont.reset(CTFontCreateCopyWithAttributes(ctFont, textSize, | 808 fCTUnrotatedFont.reset(ctfont_create_exact_copy(ctFont, textSize, nullptr, f
alse)); |
766 &CGAffineTransformIden
tity, nullptr)); | |
767 | 809 |
768 // The fUnitMatrix includes the text size (and em) as it is used to scale th
e raw font data. | 810 // 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))); | 811 SkScalar emPerFUnit = SkScalarInvert(SkIntToScalar(CGFontGetUnitsPerEm(fCGFo
nt))); |
770 fFUnitMatrix.preScale(emPerFUnit, -emPerFUnit); | 812 fFUnitMatrix.preScale(emPerFUnit, -emPerFUnit); |
771 } | 813 } |
772 | 814 |
773 /** This is an implementation of CTFontDrawGlyphs for 10.6; it was introduced in
10.7. */ | 815 /** This is an implementation of CTFontDrawGlyphs for 10.6; it was introduced in
10.7. */ |
774 static void legacy_CTFontDrawGlyphs(CTFontRef, const CGGlyph glyphs[], const CGP
oint points[], | 816 static void legacy_CTFontDrawGlyphs(CTFontRef, const CGGlyph glyphs[], const CGP
oint points[], |
775 size_t count, CGContextRef cg) { | 817 size_t count, CGContextRef cg) { |
776 CGContextShowGlyphsAtPositions(cg, glyphs, points, count); | 818 CGContextShowGlyphsAtPositions(cg, glyphs, points, count); |
(...skipping 561 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1338 | 1380 |
1339 /* | 1381 /* |
1340 * For subpixel positioning, we want to return an unhinted outline, so it | 1382 * For subpixel positioning, we want to return an unhinted outline, so it |
1341 * can be positioned nicely at fractional offsets. However, we special-case | 1383 * can be positioned nicely at fractional offsets. However, we special-case |
1342 * if the baseline of the (horizontal) text is axis-aligned. In those cases | 1384 * if the baseline of the (horizontal) text is axis-aligned. In those cases |
1343 * we want to retain hinting in the direction orthogonal to the baseline. | 1385 * we want to retain hinting in the direction orthogonal to the baseline. |
1344 * e.g. for horizontal baseline, we want to retain hinting in Y. | 1386 * e.g. for horizontal baseline, we want to retain hinting in Y. |
1345 * The way we remove hinting is to scale the font by some value (4) in that | 1387 * The way we remove hinting is to scale the font by some value (4) in that |
1346 * direction, ask for the path, and then scale the path back down. | 1388 * direction, ask for the path, and then scale the path back down. |
1347 */ | 1389 */ |
1348 if (fRec.fFlags & SkScalerContext::kSubpixelPositioning_Flag) { | 1390 if (fDoSubPosition) { |
1349 SkMatrix m; | 1391 SkMatrix m; |
1350 fRec.getSingleMatrix(&m); | 1392 fRec.getSingleMatrix(&m); |
1351 | 1393 |
1352 // start out by assuming that we want no hining in X and Y | 1394 // start out by assuming that we want no hining in X and Y |
1353 scaleX = scaleY = kScaleForSubPixelPositionHinting; | 1395 scaleX = scaleY = kScaleForSubPixelPositionHinting; |
1354 // now see if we need to restore hinting for axis-aligned baselines | 1396 // now see if we need to restore hinting for axis-aligned baselines |
1355 switch (SkComputeAxisAlignmentForHText(m)) { | 1397 switch (SkComputeAxisAlignmentForHText(m)) { |
1356 case kX_SkAxisAlignment: | 1398 case kX_SkAxisAlignment: |
1357 scaleY = SK_Scalar1; // want hinting in the Y direction | 1399 scaleY = SK_Scalar1; // want hinting in the Y direction |
1358 break; | 1400 break; |
1359 case kY_SkAxisAlignment: | 1401 case kY_SkAxisAlignment: |
1360 scaleX = SK_Scalar1; // want hinting in the X direction | 1402 scaleX = SK_Scalar1; // want hinting in the X direction |
1361 break; | 1403 break; |
1362 default: | 1404 default: |
1363 break; | 1405 break; |
1364 } | 1406 } |
1365 | 1407 |
1366 CGAffineTransform xform = MatrixToCGAffineTransform(m, scaleX, scaleY); | 1408 CGAffineTransform xform = MatrixToCGAffineTransform(m, scaleX, scaleY); |
1367 // need to release font when we're done | 1409 font = ctfont_create_exact_copy(fCTFont, 1, &xform, false); |
1368 font = CTFontCreateCopyWithAttributes(fCTFont, 1, &xform, nullptr); | |
1369 } | 1410 } |
1370 | 1411 |
1371 CGGlyph cgGlyph = (CGGlyph)glyph.getGlyphID(); | 1412 CGGlyph cgGlyph = (CGGlyph)glyph.getGlyphID(); |
1372 AutoCFRelease<CGPathRef> cgPath(CTFontCreatePathForGlyph(font, cgGlyph, null
ptr)); | 1413 AutoCFRelease<CGPathRef> cgPath(CTFontCreatePathForGlyph(font, cgGlyph, null
ptr)); |
1373 | 1414 |
1374 path->reset(); | 1415 path->reset(); |
1375 if (cgPath != nullptr) { | 1416 if (cgPath != nullptr) { |
1376 CGPathApply(cgPath, path, SkScalerContext_Mac::CTPathElement); | 1417 CGPathApply(cgPath, path, SkScalerContext_Mac::CTPathElement); |
1377 } | 1418 } |
1378 | 1419 |
1379 if (fDoSubPosition) { | 1420 if (fDoSubPosition) { |
1380 SkMatrix m; | 1421 SkMatrix m; |
1381 m.setScale(SkScalarInvert(scaleX), SkScalarInvert(scaleY)); | 1422 m.setScale(SkScalarInvert(scaleX), SkScalarInvert(scaleY)); |
1382 path->transform(m); | 1423 path->transform(m); |
1383 // balance the call to CTFontCreateCopyWithAttributes | 1424 // balance the call to ctfont_create_exact_copy |
1384 CFSafeRelease(font); | 1425 CFSafeRelease(font); |
1385 } | 1426 } |
1386 if (fVertical) { | 1427 if (fVertical) { |
1387 SkPoint offset; | 1428 SkPoint offset; |
1388 getVerticalOffset(cgGlyph, &offset); | 1429 getVerticalOffset(cgGlyph, &offset); |
1389 path->offset(offset.fX, offset.fY); | 1430 path->offset(offset.fX, offset.fY); |
1390 } | 1431 } |
1391 } | 1432 } |
1392 | 1433 |
1393 void SkScalerContext_Mac::generateFontMetrics(SkPaint::FontMetrics* metrics) { | 1434 void SkScalerContext_Mac::generateFontMetrics(SkPaint::FontMetrics* metrics) { |
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1554 } | 1595 } |
1555 | 1596 |
1556 SkAdvancedTypefaceMetrics* SkTypeface_Mac::onGetAdvancedTypefaceMetrics( | 1597 SkAdvancedTypefaceMetrics* SkTypeface_Mac::onGetAdvancedTypefaceMetrics( |
1557 PerGlyphInfo perGlyphInfo, | 1598 PerGlyphInfo perGlyphInfo, |
1558 const uint32_t* glyphIDs, | 1599 const uint32_t* glyphIDs, |
1559 uint32_t glyphIDsCount) const { | 1600 uint32_t glyphIDsCount) const { |
1560 | 1601 |
1561 AUTO_CG_LOCK(); | 1602 AUTO_CG_LOCK(); |
1562 | 1603 |
1563 CTFontRef originalCTFont = fFontRef.get(); | 1604 CTFontRef originalCTFont = fFontRef.get(); |
1564 AutoCFRelease<CTFontRef> ctFont(CTFontCreateCopyWithAttributes( | 1605 AutoCFRelease<CTFontRef> ctFont(ctfont_create_exact_copy( |
1565 originalCTFont, CTFontGetUnitsPerEm(originalCTFont), nullptr, nullpt
r)); | 1606 originalCTFont, CTFontGetUnitsPerEm(originalCTFont), nullptr, false)
); |
| 1607 |
1566 SkAdvancedTypefaceMetrics* info = new SkAdvancedTypefaceMetrics; | 1608 SkAdvancedTypefaceMetrics* info = new SkAdvancedTypefaceMetrics; |
1567 | 1609 |
1568 { | 1610 { |
1569 AutoCFRelease<CFStringRef> fontName(CTFontCopyPostScriptName(ctFont)); | 1611 AutoCFRelease<CFStringRef> fontName(CTFontCopyPostScriptName(ctFont)); |
1570 if (fontName.get()) { | 1612 if (fontName.get()) { |
1571 CFStringToSkString(fontName, &info->fFontName); | 1613 CFStringToSkString(fontName, &info->fFontName); |
1572 } | 1614 } |
1573 } | 1615 } |
1574 | 1616 |
1575 CFIndex glyphCount = CTFontGetGlyphCount(ctFont); | 1617 CFIndex glyphCount = CTFontGetGlyphCount(ctFont); |
(...skipping 898 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2474 face->ref(); | 2516 face->ref(); |
2475 } | 2517 } |
2476 } | 2518 } |
2477 return face; | 2519 return face; |
2478 } | 2520 } |
2479 }; | 2521 }; |
2480 | 2522 |
2481 /////////////////////////////////////////////////////////////////////////////// | 2523 /////////////////////////////////////////////////////////////////////////////// |
2482 | 2524 |
2483 SkFontMgr* SkFontMgr::Factory() { return new SkFontMgr_Mac; } | 2525 SkFontMgr* SkFontMgr::Factory() { return new SkFontMgr_Mac; } |
OLD | NEW |