| 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 666 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 677 bool generateBBoxes(); | 677 bool generateBBoxes(); |
| 678 | 678 |
| 679 /** Converts from FUnits (em space, y up) to SkGlyph units (pixels, y down). | 679 /** Converts from FUnits (em space, y up) to SkGlyph units (pixels, y down). |
| 680 * | 680 * |
| 681 * Used on Snow Leopard to correct CTFontGetVerticalTranslationsForGlyphs. | 681 * Used on Snow Leopard to correct CTFontGetVerticalTranslationsForGlyphs. |
| 682 * Used on Lion to correct CTFontGetBoundingRectsForGlyphs. | 682 * Used on Lion to correct CTFontGetBoundingRectsForGlyphs. |
| 683 */ | 683 */ |
| 684 SkMatrix fFUnitMatrix; | 684 SkMatrix fFUnitMatrix; |
| 685 | 685 |
| 686 Offscreen fOffscreen; | 686 Offscreen fOffscreen; |
| 687 AutoCFRelease<CTFontRef> fCTFont; | |
| 688 CGAffineTransform fTransform; | |
| 689 CGAffineTransform fInvTransform; | |
| 690 | 687 |
| 691 /** Unrotated variant of fCTFont. | 688 /** Unrotated variant of fCTFont. |
| 692 * | 689 * |
| 693 * In 10.10.1 CTFontGetAdvancesForGlyphs applies the font transform to the
width of the | 690 * In 10.10.1 CTFontGetAdvancesForGlyphs applies the font transform to the
width of the |
| 694 * advances, but always sets the height to 0. This font is used to get the
advances of the | 691 * advances, but always sets the height to 0. This font is used to get the
advances of the |
| 695 * unrotated glyph, and then the rotation is applied separately. | 692 * unrotated glyph, and then the rotation is applied separately. |
| 696 * | 693 * |
| 697 * CT vertical metrics are pre-rotated (in em space, before transform) 90de
g clock-wise. | 694 * CT vertical metrics are pre-rotated (in em space, before transform) 90de
g clock-wise. |
| 698 * This makes kCTFontDefaultOrientation dangerous, because the metrics from | 695 * This makes kCTFontDefaultOrientation dangerous, because the metrics from |
| 699 * kCTFontHorizontalOrientation are in a different space from kCTFontVertic
alOrientation. | 696 * kCTFontHorizontalOrientation are in a different space from kCTFontVertic
alOrientation. |
| 700 * With kCTFontVerticalOrientation the advances must be unrotated. | 697 * With kCTFontVerticalOrientation the advances must be unrotated. |
| 698 * |
| 699 * Sometimes, creating a copy of a CTFont with the same size but different
trasform will select |
| 700 * different underlying font data. As a result, avoid ever creating more th
an one CTFont per |
| 701 * SkScalerContext to ensure that only one CTFont is used. |
| 702 * |
| 703 * As a result of the above (and other constraints) this font contains the
size, but not the |
| 704 * transform. The transform must always be applied separately. |
| 701 */ | 705 */ |
| 702 AutoCFRelease<CTFontRef> fCTUnrotatedFont; | 706 AutoCFRelease<CTFontRef> fCTFont; |
| 707 |
| 708 /** The transform without the font size. */ |
| 709 CGAffineTransform fTransform; |
| 710 CGAffineTransform fInvTransform; |
| 703 | 711 |
| 704 AutoCFRelease<CGFontRef> fCGFont; | 712 AutoCFRelease<CGFontRef> fCGFont; |
| 705 SkAutoTMalloc<GlyphRect> fFBoundingBoxes; | 713 SkAutoTMalloc<GlyphRect> fFBoundingBoxes; |
| 706 uint16_t fFBoundingBoxesGlyphOffset; | 714 uint16_t fFBoundingBoxesGlyphOffset; |
| 707 uint16_t fGlyphCount; | 715 uint16_t fGlyphCount; |
| 708 bool fGeneratedFBoundingBoxes; | 716 bool fGeneratedFBoundingBoxes; |
| 709 const bool fDoSubPosition; | 717 const bool fDoSubPosition; |
| 710 const bool fVertical; | 718 const bool fVertical; |
| 711 | 719 |
| 712 friend class Offscreen; | 720 friend class Offscreen; |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 757 SkVector scale; | 765 SkVector scale; |
| 758 SkMatrix skTransform; | 766 SkMatrix skTransform; |
| 759 fRec.computeMatrices(SkScalerContextRec::kVertical_PreMatrixScale, &scale, &
skTransform, | 767 fRec.computeMatrices(SkScalerContextRec::kVertical_PreMatrixScale, &scale, &
skTransform, |
| 760 nullptr, nullptr, &fFUnitMatrix); | 768 nullptr, nullptr, &fFUnitMatrix); |
| 761 fTransform = MatrixToCGAffineTransform(skTransform); | 769 fTransform = MatrixToCGAffineTransform(skTransform); |
| 762 fInvTransform = CGAffineTransformInvert(fTransform); | 770 fInvTransform = CGAffineTransformInvert(fTransform); |
| 763 | 771 |
| 764 // The transform contains everything except the requested text size. | 772 // The transform contains everything except the requested text size. |
| 765 // Some properties, like 'trak', are based on the text size (before applying
the matrix). | 773 // Some properties, like 'trak', are based on the text size (before applying
the matrix). |
| 766 CGFloat textSize = ScalarToCG(scale.y()); | 774 CGFloat textSize = ScalarToCG(scale.y()); |
| 767 | 775 fCTFont.reset(ctfont_create_exact_copy(ctFont, textSize, nullptr)); |
| 768 fCTFont.reset(ctfont_create_exact_copy(ctFont, textSize, &fTransform)); | |
| 769 fCGFont.reset(CTFontCopyGraphicsFont(fCTFont, nullptr)); | 776 fCGFont.reset(CTFontCopyGraphicsFont(fCTFont, nullptr)); |
| 770 fCTUnrotatedFont.reset(ctfont_create_exact_copy(ctFont, textSize, nullptr)); | |
| 771 | 777 |
| 772 // The fUnitMatrix includes the text size (and em) as it is used to scale th
e raw font data. | 778 // The fUnitMatrix includes the text size (and em) as it is used to scale th
e raw font data. |
| 773 SkScalar emPerFUnit = SkScalarInvert(SkIntToScalar(CGFontGetUnitsPerEm(fCGFo
nt))); | 779 SkScalar emPerFUnit = SkScalarInvert(SkIntToScalar(CGFontGetUnitsPerEm(fCGFo
nt))); |
| 774 fFUnitMatrix.preScale(emPerFUnit, -emPerFUnit); | 780 fFUnitMatrix.preScale(emPerFUnit, -emPerFUnit); |
| 775 } | 781 } |
| 776 | 782 |
| 777 /** This is an implementation of CTFontDrawGlyphs for 10.6; it was introduced in
10.7. */ | 783 /** This is an implementation of CTFontDrawGlyphs for 10.6; it was introduced in
10.7. */ |
| 778 static void legacy_CTFontDrawGlyphs(CTFontRef, const CGGlyph glyphs[], const CGP
oint points[], | 784 static void legacy_CTFontDrawGlyphs(CTFontRef, const CGGlyph glyphs[], const CGP
oint points[], |
| 779 size_t count, CGContextRef cg) { | 785 size_t count, CGContextRef cg) { |
| 780 CGContextShowGlyphsAtPositions(cg, glyphs, points, count); | 786 CGContextShowGlyphsAtPositions(cg, glyphs, points, count); |
| (...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 907 CGPoint point = CGPointMake(-glyph.fLeft + subX, glyph.fTop + glyph.fHeight
- subY); | 913 CGPoint point = CGPointMake(-glyph.fLeft + subX, glyph.fTop + glyph.fHeight
- subY); |
| 908 // Prior to 10.10, CTFontDrawGlyphs acted like CGContextShowGlyphsAtPosition
s and took | 914 // Prior to 10.10, CTFontDrawGlyphs acted like CGContextShowGlyphsAtPosition
s and took |
| 909 // 'positions' which are in text space. The glyph location (in device space)
must be | 915 // 'positions' which are in text space. The glyph location (in device space)
must be |
| 910 // mapped into text space, so that CG can convert it back into device space. | 916 // mapped into text space, so that CG can convert it back into device space. |
| 911 // In 10.10.1, this is handled directly in CTFontDrawGlyphs. | 917 // In 10.10.1, this is handled directly in CTFontDrawGlyphs. |
| 912 // | 918 // |
| 913 // However, in 10.10.2 color glyphs no longer rotate based on the font trans
form. | 919 // However, in 10.10.2 color glyphs no longer rotate based on the font trans
form. |
| 914 // So always make the font transform identity and place the transform on the
context. | 920 // So always make the font transform identity and place the transform on the
context. |
| 915 point = CGPointApplyAffineTransform(point, context.fInvTransform); | 921 point = CGPointApplyAffineTransform(point, context.fInvTransform); |
| 916 | 922 |
| 917 ctFontDrawGlyphs(context.fCTUnrotatedFont, &glyphID, &point, 1, fCG); | 923 ctFontDrawGlyphs(context.fCTFont, &glyphID, &point, 1, fCG); |
| 918 | 924 |
| 919 SkASSERT(rowBytesPtr); | 925 SkASSERT(rowBytesPtr); |
| 920 *rowBytesPtr = rowBytes; | 926 *rowBytesPtr = rowBytes; |
| 921 return image; | 927 return image; |
| 922 } | 928 } |
| 923 | 929 |
| 924 void SkScalerContext_Mac::getVerticalOffset(CGGlyph glyphID, SkPoint* offset) co
nst { | 930 void SkScalerContext_Mac::getVerticalOffset(CGGlyph glyphID, SkPoint* offset) co
nst { |
| 925 // Snow Leopard returns cgVertOffset in completely un-transformed FUnits (em
space, y up). | 931 // Snow Leopard returns cgVertOffset in completely un-transformed FUnits (em
space, y up). |
| 926 // Lion and Leopard return cgVertOffset in CG units (pixels, y up). | 932 // Lion and Leopard return cgVertOffset in CG units (pixels, y up). |
| 927 CGSize cgVertOffset; | 933 CGSize cgVertOffset; |
| 928 CTFontGetVerticalTranslationsForGlyphs(fCTFont, &glyphID, &cgVertOffset, 1); | 934 CTFontGetVerticalTranslationsForGlyphs(fCTFont, &glyphID, &cgVertOffset, 1); |
| 929 | |
| 930 SkPoint skVertOffset = { CGToScalar(cgVertOffset.width), CGToScalar(cgVertOf
fset.height) }; | |
| 931 if (isSnowLeopard()) { | 935 if (isSnowLeopard()) { |
| 936 SkPoint skVertOffset = { CGToScalar(cgVertOffset.width), CGToScalar(cgVe
rtOffset.height) }; |
| 932 // From FUnits (em space, y up) to SkGlyph units (pixels, y down). | 937 // From FUnits (em space, y up) to SkGlyph units (pixels, y down). |
| 933 fFUnitMatrix.mapPoints(&skVertOffset, 1); | 938 fFUnitMatrix.mapPoints(&skVertOffset, 1); |
| 934 } else { | 939 *offset = skVertOffset; |
| 935 // From CG units (pixels, y up) to SkGlyph units (pixels, y down). | 940 return; |
| 936 skVertOffset.fY = -skVertOffset.fY; | |
| 937 } | 941 } |
| 938 | 942 cgVertOffset = CGSizeApplyAffineTransform(cgVertOffset, fTransform); |
| 943 SkPoint skVertOffset = { CGToScalar(cgVertOffset.width), CGToScalar(cgVertOf
fset.height) }; |
| 944 // From CG units (pixels, y up) to SkGlyph units (pixels, y down). |
| 945 skVertOffset.fY = -skVertOffset.fY; |
| 939 *offset = skVertOffset; | 946 *offset = skVertOffset; |
| 940 } | 947 } |
| 941 | 948 |
| 942 uint16_t SkScalerContext_Mac::getFBoundingBoxesGlyphOffset() { | 949 uint16_t SkScalerContext_Mac::getFBoundingBoxesGlyphOffset() { |
| 943 if (fFBoundingBoxesGlyphOffset) { | 950 if (fFBoundingBoxesGlyphOffset) { |
| 944 return fFBoundingBoxesGlyphOffset; | 951 return fFBoundingBoxesGlyphOffset; |
| 945 } | 952 } |
| 946 fFBoundingBoxesGlyphOffset = fGlyphCount; // fallback for all fonts | 953 fFBoundingBoxesGlyphOffset = fGlyphCount; // fallback for all fonts |
| 947 AutoCGTable<SkOTTableHorizontalHeader> hheaTable(fCGFont); | 954 AutoCGTable<SkOTTableHorizontalHeader> hheaTable(fCGFont); |
| 948 if (hheaTable.fData) { | 955 if (hheaTable.fData) { |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1017 | 1024 |
| 1018 void SkScalerContext_Mac::generateMetrics(SkGlyph* glyph) { | 1025 void SkScalerContext_Mac::generateMetrics(SkGlyph* glyph) { |
| 1019 AUTO_CG_LOCK(); | 1026 AUTO_CG_LOCK(); |
| 1020 | 1027 |
| 1021 const CGGlyph cgGlyph = (CGGlyph) glyph->getGlyphID(); | 1028 const CGGlyph cgGlyph = (CGGlyph) glyph->getGlyphID(); |
| 1022 glyph->zeroMetrics(); | 1029 glyph->zeroMetrics(); |
| 1023 | 1030 |
| 1024 // The following block produces cgAdvance in CG units (pixels, y up). | 1031 // The following block produces cgAdvance in CG units (pixels, y up). |
| 1025 CGSize cgAdvance; | 1032 CGSize cgAdvance; |
| 1026 if (fVertical) { | 1033 if (fVertical) { |
| 1027 CTFontGetAdvancesForGlyphs(fCTUnrotatedFont, kCTFontVerticalOrientation, | 1034 CTFontGetAdvancesForGlyphs(fCTFont, kCTFontVerticalOrientation, |
| 1028 &cgGlyph, &cgAdvance, 1); | 1035 &cgGlyph, &cgAdvance, 1); |
| 1029 // Vertical advances are returned as widths instead of heights. | 1036 // Vertical advances are returned as widths instead of heights. |
| 1030 SkTSwap(cgAdvance.height, cgAdvance.width); | 1037 SkTSwap(cgAdvance.height, cgAdvance.width); |
| 1031 cgAdvance.height = -cgAdvance.height; | 1038 cgAdvance.height = -cgAdvance.height; |
| 1032 } else { | 1039 } else { |
| 1033 CTFontGetAdvancesForGlyphs(fCTUnrotatedFont, kCTFontHorizontalOrientatio
n, | 1040 CTFontGetAdvancesForGlyphs(fCTFont, kCTFontHorizontalOrientation, |
| 1034 &cgGlyph, &cgAdvance, 1); | 1041 &cgGlyph, &cgAdvance, 1); |
| 1035 } | 1042 } |
| 1036 cgAdvance = CGSizeApplyAffineTransform(cgAdvance, CTFontGetMatrix(fCTFont)); | 1043 cgAdvance = CGSizeApplyAffineTransform(cgAdvance, fTransform); |
| 1037 glyph->fAdvanceX = SkFloatToFixed_Check(cgAdvance.width); | 1044 glyph->fAdvanceX = SkFloatToFixed_Check(cgAdvance.width); |
| 1038 glyph->fAdvanceY = -SkFloatToFixed_Check(cgAdvance.height); | 1045 glyph->fAdvanceY = -SkFloatToFixed_Check(cgAdvance.height); |
| 1039 | 1046 |
| 1040 // The following produces skBounds in SkGlyph units (pixels, y down), | 1047 // The following produces skBounds in SkGlyph units (pixels, y down), |
| 1041 // or returns early if skBounds would be empty. | 1048 // or returns early if skBounds would be empty. |
| 1042 SkRect skBounds; | 1049 SkRect skBounds; |
| 1043 | 1050 |
| 1044 // On Mountain Lion, CTFontGetBoundingRectsForGlyphs with kCTFontVerticalOri
entation and | 1051 // On Mountain Lion, CTFontGetBoundingRectsForGlyphs with kCTFontVerticalOri
entation and |
| 1045 // CTFontGetVerticalTranslationsForGlyphs do not agree when using OTF CFF fo
nts. | 1052 // CTFontGetVerticalTranslationsForGlyphs do not agree when using OTF CFF fo
nts. |
| 1046 // For TTF fonts these two do agree and we can use CTFontGetBoundingRectsFor
Glyphs to get | 1053 // For TTF fonts these two do agree and we can use CTFontGetBoundingRectsFor
Glyphs to get |
| (...skipping 24 matching lines...) Expand all Loading... |
| 1071 } | 1078 } |
| 1072 skBounds = SkRect::MakeLTRB(gRect.fMinX, gRect.fMinY, gRect.fMaxX, gRect
.fMaxY); | 1079 skBounds = SkRect::MakeLTRB(gRect.fMinX, gRect.fMinY, gRect.fMaxX, gRect
.fMaxY); |
| 1073 // From FUnits (em space, y up) to SkGlyph units (pixels, y down). | 1080 // From FUnits (em space, y up) to SkGlyph units (pixels, y down). |
| 1074 fFUnitMatrix.mapRect(&skBounds); | 1081 fFUnitMatrix.mapRect(&skBounds); |
| 1075 | 1082 |
| 1076 } else { | 1083 } else { |
| 1077 // CTFontGetBoundingRectsForGlyphs produces cgBounds in CG units (pixels
, y up). | 1084 // CTFontGetBoundingRectsForGlyphs produces cgBounds in CG units (pixels
, y up). |
| 1078 CGRect cgBounds; | 1085 CGRect cgBounds; |
| 1079 CTFontGetBoundingRectsForGlyphs(fCTFont, kCTFontHorizontalOrientation, | 1086 CTFontGetBoundingRectsForGlyphs(fCTFont, kCTFontHorizontalOrientation, |
| 1080 &cgGlyph, &cgBounds, 1); | 1087 &cgGlyph, &cgBounds, 1); |
| 1088 cgBounds = CGRectApplyAffineTransform(cgBounds, fTransform); |
| 1081 | 1089 |
| 1082 // BUG? | 1090 // BUG? |
| 1083 // 0x200B (zero-advance space) seems to return a huge (garbage) bounds,
when | 1091 // 0x200B (zero-advance space) seems to return a huge (garbage) bounds,
when |
| 1084 // it should be empty. So, if we see a zero-advance, we check if it has
an | 1092 // it should be empty. So, if we see a zero-advance, we check if it has
an |
| 1085 // empty path or not, and if so, we jam the bounds to 0. Hopefully a zer
o-advance | 1093 // empty path or not, and if so, we jam the bounds to 0. Hopefully a zer
o-advance |
| 1086 // is rare, so we won't incur a big performance cost for this extra chec
k. | 1094 // is rare, so we won't incur a big performance cost for this extra chec
k. |
| 1087 if (0 == cgAdvance.width && 0 == cgAdvance.height) { | 1095 if (0 == cgAdvance.width && 0 == cgAdvance.height) { |
| 1088 AutoCFRelease<CGPathRef> path(CTFontCreatePathForGlyph(fCTFont, cgGl
yph, nullptr)); | 1096 AutoCFRelease<CGPathRef> path(CTFontCreatePathForGlyph(fCTFont, cgGl
yph, nullptr)); |
| 1089 if (nullptr == path || CGPathIsEmpty(path)) { | 1097 if (nullptr == path || CGPathIsEmpty(path)) { |
| 1090 return; | 1098 return; |
| (...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1329 /* | 1337 /* |
| 1330 * Our subpixel resolution is only 2 bits in each direction, so a scale of 4 | 1338 * Our subpixel resolution is only 2 bits in each direction, so a scale of 4 |
| 1331 * seems sufficient, and possibly even correct, to allow the hinted outline | 1339 * seems sufficient, and possibly even correct, to allow the hinted outline |
| 1332 * to be subpixel positioned. | 1340 * to be subpixel positioned. |
| 1333 */ | 1341 */ |
| 1334 #define kScaleForSubPixelPositionHinting (4.0f) | 1342 #define kScaleForSubPixelPositionHinting (4.0f) |
| 1335 | 1343 |
| 1336 void SkScalerContext_Mac::generatePath(const SkGlyph& glyph, SkPath* path) { | 1344 void SkScalerContext_Mac::generatePath(const SkGlyph& glyph, SkPath* path) { |
| 1337 AUTO_CG_LOCK(); | 1345 AUTO_CG_LOCK(); |
| 1338 | 1346 |
| 1339 CTFontRef font = fCTFont; | |
| 1340 SkScalar scaleX = SK_Scalar1; | 1347 SkScalar scaleX = SK_Scalar1; |
| 1341 SkScalar scaleY = SK_Scalar1; | 1348 SkScalar scaleY = SK_Scalar1; |
| 1342 | 1349 |
| 1350 CGAffineTransform xform = fTransform; |
| 1343 /* | 1351 /* |
| 1344 * For subpixel positioning, we want to return an unhinted outline, so it | 1352 * For subpixel positioning, we want to return an unhinted outline, so it |
| 1345 * can be positioned nicely at fractional offsets. However, we special-case | 1353 * can be positioned nicely at fractional offsets. However, we special-case |
| 1346 * if the baseline of the (horizontal) text is axis-aligned. In those cases | 1354 * if the baseline of the (horizontal) text is axis-aligned. In those cases |
| 1347 * we want to retain hinting in the direction orthogonal to the baseline. | 1355 * we want to retain hinting in the direction orthogonal to the baseline. |
| 1348 * e.g. for horizontal baseline, we want to retain hinting in Y. | 1356 * e.g. for horizontal baseline, we want to retain hinting in Y. |
| 1349 * The way we remove hinting is to scale the font by some value (4) in that | 1357 * The way we remove hinting is to scale the font by some value (4) in that |
| 1350 * direction, ask for the path, and then scale the path back down. | 1358 * direction, ask for the path, and then scale the path back down. |
| 1351 */ | 1359 */ |
| 1352 if (fDoSubPosition) { | 1360 if (fDoSubPosition) { |
| 1353 SkMatrix m; | 1361 SkMatrix m; |
| 1354 fRec.getSingleMatrix(&m); | 1362 fRec.getSingleMatrix(&m); |
| 1355 | 1363 |
| 1356 // start out by assuming that we want no hining in X and Y | 1364 // start out by assuming that we want no hining in X and Y |
| 1357 scaleX = scaleY = kScaleForSubPixelPositionHinting; | 1365 scaleX = scaleY = kScaleForSubPixelPositionHinting; |
| 1358 // now see if we need to restore hinting for axis-aligned baselines | 1366 // now see if we need to restore hinting for axis-aligned baselines |
| 1359 switch (SkComputeAxisAlignmentForHText(m)) { | 1367 switch (SkComputeAxisAlignmentForHText(m)) { |
| 1360 case kX_SkAxisAlignment: | 1368 case kX_SkAxisAlignment: |
| 1361 scaleY = SK_Scalar1; // want hinting in the Y direction | 1369 scaleY = SK_Scalar1; // want hinting in the Y direction |
| 1362 break; | 1370 break; |
| 1363 case kY_SkAxisAlignment: | 1371 case kY_SkAxisAlignment: |
| 1364 scaleX = SK_Scalar1; // want hinting in the X direction | 1372 scaleX = SK_Scalar1; // want hinting in the X direction |
| 1365 break; | 1373 break; |
| 1366 default: | 1374 default: |
| 1367 break; | 1375 break; |
| 1368 } | 1376 } |
| 1369 | 1377 |
| 1370 CGAffineTransform xform = MatrixToCGAffineTransform(m, scaleX, scaleY); | 1378 CGAffineTransform scale(CGAffineTransformMakeScale(ScalarToCG(scaleX), S
calarToCG(scaleY))); |
| 1371 font = ctfont_create_exact_copy(fCTFont, 1, &xform); | 1379 xform = CGAffineTransformConcat(fTransform, scale); |
| 1372 } | 1380 } |
| 1373 | 1381 |
| 1374 CGGlyph cgGlyph = (CGGlyph)glyph.getGlyphID(); | 1382 CGGlyph cgGlyph = (CGGlyph)glyph.getGlyphID(); |
| 1375 AutoCFRelease<CGPathRef> cgPath(CTFontCreatePathForGlyph(font, cgGlyph, null
ptr)); | 1383 AutoCFRelease<CGPathRef> cgPath(CTFontCreatePathForGlyph(fCTFont, cgGlyph, &
xform)); |
| 1376 | 1384 |
| 1377 path->reset(); | 1385 path->reset(); |
| 1378 if (cgPath != nullptr) { | 1386 if (cgPath != nullptr) { |
| 1379 CGPathApply(cgPath, path, SkScalerContext_Mac::CTPathElement); | 1387 CGPathApply(cgPath, path, SkScalerContext_Mac::CTPathElement); |
| 1380 } | 1388 } |
| 1381 | 1389 |
| 1382 if (fDoSubPosition) { | 1390 if (fDoSubPosition) { |
| 1383 SkMatrix m; | 1391 SkMatrix m; |
| 1384 m.setScale(SkScalarInvert(scaleX), SkScalarInvert(scaleY)); | 1392 m.setScale(SkScalarInvert(scaleX), SkScalarInvert(scaleY)); |
| 1385 path->transform(m); | 1393 path->transform(m); |
| 1386 // balance the call to ctfont_create_exact_copy | |
| 1387 CFSafeRelease(font); | |
| 1388 } | 1394 } |
| 1389 if (fVertical) { | 1395 if (fVertical) { |
| 1390 SkPoint offset; | 1396 SkPoint offset; |
| 1391 getVerticalOffset(cgGlyph, &offset); | 1397 getVerticalOffset(cgGlyph, &offset); |
| 1392 path->offset(offset.fX, offset.fY); | 1398 path->offset(offset.fX, offset.fY); |
| 1393 } | 1399 } |
| 1394 } | 1400 } |
| 1395 | 1401 |
| 1396 void SkScalerContext_Mac::generateFontMetrics(SkPaint::FontMetrics* metrics) { | 1402 void SkScalerContext_Mac::generateFontMetrics(SkPaint::FontMetrics* metrics) { |
| 1397 if (nullptr == metrics) { | 1403 if (nullptr == metrics) { |
| (...skipping 1080 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2478 face->ref(); | 2484 face->ref(); |
| 2479 } | 2485 } |
| 2480 } | 2486 } |
| 2481 return face; | 2487 return face; |
| 2482 } | 2488 } |
| 2483 }; | 2489 }; |
| 2484 | 2490 |
| 2485 /////////////////////////////////////////////////////////////////////////////// | 2491 /////////////////////////////////////////////////////////////////////////////// |
| 2486 | 2492 |
| 2487 SkFontMgr* SkFontMgr::Factory() { return new SkFontMgr_Mac; } | 2493 SkFontMgr* SkFontMgr::Factory() { return new SkFontMgr_Mac; } |
| OLD | NEW |