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

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: Refactor. 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 264 matching lines...) Expand 10 before | Expand all | Expand 10 after
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 SkScalar sx = SK_Scalar1, 286 return CGAffineTransformMake( ScalarToCG(matrix[SkMatrix::kMScaleX]),
287 SkScalar sy = SK_Scalar1) { 287 -ScalarToCG(matrix[SkMatrix::kMSkewY]),
288 return CGAffineTransformMake( ScalarToCG(matrix[SkMatrix::kMScaleX] * sx), 288 -ScalarToCG(matrix[SkMatrix::kMSkewX]),
289 -ScalarToCG(matrix[SkMatrix::kMSkewY] * sy), 289 ScalarToCG(matrix[SkMatrix::kMScaleY]),
290 -ScalarToCG(matrix[SkMatrix::kMSkewX] * sx), 290 ScalarToCG(matrix[SkMatrix::kMTransX]),
291 ScalarToCG(matrix[SkMatrix::kMScaleY] * sy), 291 ScalarToCG(matrix[SkMatrix::kMTransY]));
292 ScalarToCG(matrix[SkMatrix::kMTransX] * sx),
293 ScalarToCG(matrix[SkMatrix::kMTransY] * sy));
294 } 292 }
295 293
296 /////////////////////////////////////////////////////////////////////////////// 294 ///////////////////////////////////////////////////////////////////////////////
297 295
298 #define BITMAP_INFO_RGB (kCGImageAlphaNoneSkipFirst | kCGBitmapByteOrder32Host) 296 #define BITMAP_INFO_RGB (kCGImageAlphaNoneSkipFirst | kCGBitmapByteOrder32Host)
299 297
300 /** 298 /**
301 * There does not appear to be a publicly accessable API for determining if lcd 299 * There does not appear to be a publicly accessable API for determining if lcd
302 * font smoothing will be applied if we request it. The main issue is that if 300 * font smoothing will be applied if we request it. The main issue is that if
303 * smoothing is applied a gamma of 2.0 will be used, if not a gamma of 1.0. 301 * 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
707 uint16_t fGlyphCount; 705 uint16_t fGlyphCount;
708 bool fGeneratedFBoundingBoxes; 706 bool fGeneratedFBoundingBoxes;
709 const bool fDoSubPosition; 707 const bool fDoSubPosition;
710 const bool fVertical; 708 const bool fVertical;
711 709
712 friend class Offscreen; 710 friend class Offscreen;
713 711
714 typedef SkScalerContext INHERITED; 712 typedef SkScalerContext INHERITED;
715 }; 713 };
716 714
715 // CTFontCreateCopyWithAttributes or CTFontCreateCopyWithSymbolicTraits cannot b e used on 10.10
Mark Mentovai 2015/09/19 03:18:41 The comment says 10.10 but the BUG= is about 10.11
bungeman-skia 2015/09/19 06:25:47 After letting this run through the bots and seeing
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
717 SkScalerContext_Mac::SkScalerContext_Mac(SkTypeface_Mac* typeface, 766 SkScalerContext_Mac::SkScalerContext_Mac(SkTypeface_Mac* typeface,
718 const SkDescriptor* desc) 767 const SkDescriptor* desc)
719 : INHERITED(typeface, desc) 768 : INHERITED(typeface, desc)
720 , fFBoundingBoxes() 769 , fFBoundingBoxes()
721 , fFBoundingBoxesGlyphOffset(0) 770 , fFBoundingBoxesGlyphOffset(0)
722 , fGeneratedFBoundingBoxes(false) 771 , fGeneratedFBoundingBoxes(false)
723 , fDoSubPosition(SkToBool(fRec.fFlags & kSubpixelPositioning_Flag)) 772 , fDoSubPosition(SkToBool(fRec.fFlags & kSubpixelPositioning_Flag))
724 , fVertical(SkToBool(fRec.fFlags & kVertical_Flag)) 773 , fVertical(SkToBool(fRec.fFlags & kVertical_Flag))
725 774
726 { 775 {
727 AUTO_CG_LOCK(); 776 AUTO_CG_LOCK();
728 777
729 CTFontRef ctFont = typeface->fFontRef.get(); 778 CTFontRef ctFont = typeface->fFontRef.get();
730 CFIndex numGlyphs = CTFontGetGlyphCount(ctFont); 779 CFIndex numGlyphs = CTFontGetGlyphCount(ctFont);
731 SkASSERT(numGlyphs >= 1 && numGlyphs <= 0xFFFF); 780 SkASSERT(numGlyphs >= 1 && numGlyphs <= 0xFFFF);
732 fGlyphCount = SkToU16(numGlyphs); 781 fGlyphCount = SkToU16(numGlyphs);
733 782
734 // CT on (at least) 10.9 will size color glyphs down from the requested size , but not up. 783 // 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. 784 // As a result, it is necessary to know the actual device size and request t hat.
736 SkVector scale; 785 SkVector scale;
737 SkMatrix skTransform; 786 SkMatrix skTransform;
738 fRec.computeMatrices(SkScalerContextRec::kVertical_PreMatrixScale, &scale, & skTransform, 787 fRec.computeMatrices(SkScalerContextRec::kVertical_PreMatrixScale, &scale, & skTransform,
739 nullptr, nullptr, &fFUnitMatrix); 788 nullptr, nullptr, &fFUnitMatrix);
740 fTransform = MatrixToCGAffineTransform(skTransform); 789 fTransform = MatrixToCGAffineTransform(skTransform);
741 fInvTransform = CGAffineTransformInvert(fTransform); 790 fInvTransform = CGAffineTransformInvert(fTransform);
742 791
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. 792 // The transform contains everything except the requested text size.
760 // Some properties, like 'trak', are based on the text size (before applying the matrix). 793 // Some properties, like 'trak', are based on the text size (before applying the matrix).
761 CGFloat textSize = ScalarToCG(scale.y()); 794 CGFloat textSize = ScalarToCG(scale.y());
762 795
763 fCTFont.reset(CTFontCreateCopyWithAttributes(ctFont, textSize, &fTransform, ctFontDesc)); 796 fCTFont.reset(ctfont_create_exact_copy(ctFont, textSize, &fTransform, fVerti cal));
764 fCGFont.reset(CTFontCopyGraphicsFont(fCTFont, nullptr)); 797 fCGFont.reset(CTFontCopyGraphicsFont(fCTFont, nullptr));
765 fCTUnrotatedFont.reset(CTFontCreateCopyWithAttributes(ctFont, textSize, 798 fCTUnrotatedFont.reset(ctfont_create_exact_copy(ctFont, textSize, nullptr, f alse));
766 &CGAffineTransformIden tity, nullptr));
767 799
768 // The fUnitMatrix includes the text size (and em) as it is used to scale th e raw font data. 800 // 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))); 801 SkScalar emPerFUnit = SkScalarInvert(SkIntToScalar(CGFontGetUnitsPerEm(fCGFo nt)));
770 fFUnitMatrix.preScale(emPerFUnit, -emPerFUnit); 802 fFUnitMatrix.preScale(emPerFUnit, -emPerFUnit);
771 } 803 }
772 804
773 /** This is an implementation of CTFontDrawGlyphs for 10.6; it was introduced in 10.7. */ 805 /** 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[], 806 static void legacy_CTFontDrawGlyphs(CTFontRef, const CGGlyph glyphs[], const CGP oint points[],
775 size_t count, CGContextRef cg) { 807 size_t count, CGContextRef cg) {
776 CGContextShowGlyphsAtPositions(cg, glyphs, points, count); 808 CGContextShowGlyphsAtPositions(cg, glyphs, points, count);
(...skipping 561 matching lines...) Expand 10 before | Expand all | Expand 10 after
1338 1370
1339 /* 1371 /*
1340 * For subpixel positioning, we want to return an unhinted outline, so it 1372 * For subpixel positioning, we want to return an unhinted outline, so it
1341 * can be positioned nicely at fractional offsets. However, we special-case 1373 * 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 1374 * 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. 1375 * 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. 1376 * 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 1377 * 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. 1378 * direction, ask for the path, and then scale the path back down.
1347 */ 1379 */
1348 if (fRec.fFlags & SkScalerContext::kSubpixelPositioning_Flag) { 1380 if (fRec.fFlags & SkScalerContext::kSubpixelPositioning_Flag) {
Mark Mentovai 2015/09/19 03:18:41 Can this be if (fDoSubPosition)? It’s harder to re
bungeman-skia 2015/09/19 06:25:47 Yes, that should be changed, so why not change it
1349 SkMatrix m; 1381 SkMatrix m;
1350 fRec.getSingleMatrix(&m); 1382 fRec.getSingleMatrix(&m);
1351 1383
1352 // start out by assuming that we want no hining in X and Y 1384 // start out by assuming that we want no hining in X and Y
1353 scaleX = scaleY = kScaleForSubPixelPositionHinting; 1385 scaleX = scaleY = kScaleForSubPixelPositionHinting;
1354 // now see if we need to restore hinting for axis-aligned baselines 1386 // now see if we need to restore hinting for axis-aligned baselines
1355 switch (SkComputeAxisAlignmentForHText(m)) { 1387 switch (SkComputeAxisAlignmentForHText(m)) {
1356 case kX_SkAxisAlignment: 1388 case kX_SkAxisAlignment:
1357 scaleY = SK_Scalar1; // want hinting in the Y direction 1389 scaleY = SK_Scalar1; // want hinting in the Y direction
1358 break; 1390 break;
1359 case kY_SkAxisAlignment: 1391 case kY_SkAxisAlignment:
1360 scaleX = SK_Scalar1; // want hinting in the X direction 1392 scaleX = SK_Scalar1; // want hinting in the X direction
1361 break; 1393 break;
1362 default: 1394 default:
1363 break; 1395 break;
1364 } 1396 }
1365 1397
1366 CGAffineTransform xform = MatrixToCGAffineTransform(m, scaleX, scaleY); 1398 CGFloat textSize = CTFontGetSize(fCTFont);
1367 // need to release font when we're done 1399 CGAffineTransform baseTransform = CTFontGetMatrix(fCTFont);
1368 font = CTFontCreateCopyWithAttributes(fCTFont, 1, &xform, nullptr); 1400 CGAffineTransform newTransform =
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) ;
1369 } 1405 }
1370 1406
1371 CGGlyph cgGlyph = (CGGlyph)glyph.getGlyphID(); 1407 CGGlyph cgGlyph = (CGGlyph)glyph.getGlyphID();
1372 AutoCFRelease<CGPathRef> cgPath(CTFontCreatePathForGlyph(font, cgGlyph, null ptr)); 1408 AutoCFRelease<CGPathRef> cgPath(CTFontCreatePathForGlyph(font, cgGlyph, null ptr));
1373 1409
1374 path->reset(); 1410 path->reset();
1375 if (cgPath != nullptr) { 1411 if (cgPath != nullptr) {
1376 CGPathApply(cgPath, path, SkScalerContext_Mac::CTPathElement); 1412 CGPathApply(cgPath, path, SkScalerContext_Mac::CTPathElement);
1377 } 1413 }
1378 1414
1379 if (fDoSubPosition) { 1415 if (fDoSubPosition) {
1380 SkMatrix m; 1416 SkMatrix m;
1381 m.setScale(SkScalarInvert(scaleX), SkScalarInvert(scaleY)); 1417 m.setScale(SkScalarInvert(scaleX), SkScalarInvert(scaleY));
1382 path->transform(m); 1418 path->transform(m);
1383 // balance the call to CTFontCreateCopyWithAttributes 1419 // balance the call to ctfont_create_exact_copy
1384 CFSafeRelease(font); 1420 CFSafeRelease(font);
1385 } 1421 }
1386 if (fVertical) { 1422 if (fVertical) {
1387 SkPoint offset; 1423 SkPoint offset;
1388 getVerticalOffset(cgGlyph, &offset); 1424 getVerticalOffset(cgGlyph, &offset);
1389 path->offset(offset.fX, offset.fY); 1425 path->offset(offset.fX, offset.fY);
1390 } 1426 }
1391 } 1427 }
1392 1428
1393 void SkScalerContext_Mac::generateFontMetrics(SkPaint::FontMetrics* metrics) { 1429 void SkScalerContext_Mac::generateFontMetrics(SkPaint::FontMetrics* metrics) {
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after
1554 } 1590 }
1555 1591
1556 SkAdvancedTypefaceMetrics* SkTypeface_Mac::onGetAdvancedTypefaceMetrics( 1592 SkAdvancedTypefaceMetrics* SkTypeface_Mac::onGetAdvancedTypefaceMetrics(
1557 PerGlyphInfo perGlyphInfo, 1593 PerGlyphInfo perGlyphInfo,
1558 const uint32_t* glyphIDs, 1594 const uint32_t* glyphIDs,
1559 uint32_t glyphIDsCount) const { 1595 uint32_t glyphIDsCount) const {
1560 1596
1561 AUTO_CG_LOCK(); 1597 AUTO_CG_LOCK();
1562 1598
1563 CTFontRef originalCTFont = fFontRef.get(); 1599 CTFontRef originalCTFont = fFontRef.get();
1564 AutoCFRelease<CTFontRef> ctFont(CTFontCreateCopyWithAttributes( 1600 AutoCFRelease<CTFontRef> ctFont(ctfont_create_exact_copy(
1565 originalCTFont, CTFontGetUnitsPerEm(originalCTFont), nullptr, nullpt r)); 1601 originalCTFont, CTFontGetUnitsPerEm(originalCTFont), nullptr, false) );
1602
1566 SkAdvancedTypefaceMetrics* info = new SkAdvancedTypefaceMetrics; 1603 SkAdvancedTypefaceMetrics* info = new SkAdvancedTypefaceMetrics;
1567 1604
1568 { 1605 {
1569 AutoCFRelease<CFStringRef> fontName(CTFontCopyPostScriptName(ctFont)); 1606 AutoCFRelease<CFStringRef> fontName(CTFontCopyPostScriptName(ctFont));
1570 if (fontName.get()) { 1607 if (fontName.get()) {
1571 CFStringToSkString(fontName, &info->fFontName); 1608 CFStringToSkString(fontName, &info->fFontName);
1572 } 1609 }
1573 } 1610 }
1574 1611
1575 CFIndex glyphCount = CTFontGetGlyphCount(ctFont); 1612 CFIndex glyphCount = CTFontGetGlyphCount(ctFont);
(...skipping 898 matching lines...) Expand 10 before | Expand all | Expand 10 after
2474 face->ref(); 2511 face->ref();
2475 } 2512 }
2476 } 2513 }
2477 return face; 2514 return face;
2478 } 2515 }
2479 }; 2516 };
2480 2517
2481 /////////////////////////////////////////////////////////////////////////////// 2518 ///////////////////////////////////////////////////////////////////////////////
2482 2519
2483 SkFontMgr* SkFontMgr::Factory() { return new SkFontMgr_Mac; } 2520 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