Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(665)

Side by Side Diff: src/ports/SkFontHost_mac.cpp

Issue 1344213004: Avoid CTFontCreateCopyWithAttributes. (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Fix synthetic bold italic. Created 5 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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; }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698