Chromium Code Reviews| 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 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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; } |
| OLD | NEW |