aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/ports/SkFontHost_mac.cpp
diff options
context:
space:
mode:
authorGravatar bungeman <bungeman@google.com>2015-09-18 20:13:06 -0700
committerGravatar Commit bot <commit-bot@chromium.org>2015-09-18 20:13:06 -0700
commitd3296717b9d0930237be3502b82ab94d0b4d177f (patch)
treec388a58783eb8e4776bea9355a3640454b630e62 /src/ports/SkFontHost_mac.cpp
parent2440fcd9413cf6c235352eb540404e98e573219d (diff)
Avoid CTFontCreateCopyWithAttributes.
It appears that CTFontCreateCopyWithAttributes and CTFontCreateCopyWithSymbolicTraits share similar issues with the default font on OSX10.10. CTFontCreateWithFontDescriptor cannot be used as it will not work with webfonts. Since this is all low-level use, create the CTFonts from the underlying CGFonts directly. BUG=chromium:524646 Review URL: https://codereview.chromium.org/1344213004
Diffstat (limited to 'src/ports/SkFontHost_mac.cpp')
-rw-r--r--src/ports/SkFontHost_mac.cpp105
1 files changed, 71 insertions, 34 deletions
diff --git a/src/ports/SkFontHost_mac.cpp b/src/ports/SkFontHost_mac.cpp
index 7d90d84695..a01c37efc0 100644
--- a/src/ports/SkFontHost_mac.cpp
+++ b/src/ports/SkFontHost_mac.cpp
@@ -282,15 +282,13 @@ static SkScalar CGToScalar(CGFloat cgFloat) {
}
}
-static CGAffineTransform MatrixToCGAffineTransform(const SkMatrix& matrix,
- SkScalar sx = SK_Scalar1,
- SkScalar sy = SK_Scalar1) {
- return CGAffineTransformMake( ScalarToCG(matrix[SkMatrix::kMScaleX] * sx),
- -ScalarToCG(matrix[SkMatrix::kMSkewY] * sy),
- -ScalarToCG(matrix[SkMatrix::kMSkewX] * sx),
- ScalarToCG(matrix[SkMatrix::kMScaleY] * sy),
- ScalarToCG(matrix[SkMatrix::kMTransX] * sx),
- ScalarToCG(matrix[SkMatrix::kMTransY] * sy));
+static CGAffineTransform MatrixToCGAffineTransform(const SkMatrix& matrix) {
+ return CGAffineTransformMake( ScalarToCG(matrix[SkMatrix::kMScaleX]),
+ -ScalarToCG(matrix[SkMatrix::kMSkewY]),
+ -ScalarToCG(matrix[SkMatrix::kMSkewX]),
+ ScalarToCG(matrix[SkMatrix::kMScaleY]),
+ ScalarToCG(matrix[SkMatrix::kMTransX]),
+ ScalarToCG(matrix[SkMatrix::kMTransY]));
}
///////////////////////////////////////////////////////////////////////////////
@@ -714,6 +712,57 @@ private:
typedef SkScalerContext INHERITED;
};
+// CTFontCreateCopyWithAttributes or CTFontCreateCopyWithSymbolicTraits cannot be used on 10.10
+// as they appear to be buggy with respect to the default font. It is not possible to use
+// descriptors with CTFontCreateWithFontDescriptor, since that does not work with non-system
+// fonts. As a result, create the strike specific CTFonts from the underlying CGFont.
+static CTFontRef ctfont_create_exact_copy(CTFontRef baseFont, CGFloat textSize,
+ const CGAffineTransform* transform, bool setVertical)
+{
+ AutoCFRelease<CTFontDescriptorRef> baseDescriptor;
+ AutoCFRelease<CGFontRef> baseCGFont(CTFontCopyGraphicsFont(baseFont, &baseDescriptor));
+
+ // Make a mutable copy of baseDescriptor attributes.
+ AutoCFRelease<CFMutableDictionaryRef> newAttributes([](CTFontDescriptorRef descriptor) ->
+ CFMutableDictionaryRef {
+ if (nullptr == descriptor) {
+ return CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
+ &kCFTypeDictionaryKeyCallBacks,
+ &kCFTypeDictionaryValueCallBacks);
+ }
+ AutoCFRelease<CFDictionaryRef> attributes(CTFontDescriptorCopyAttributes(descriptor));
+ return CFDictionaryCreateMutableCopy(kCFAllocatorDefault, 0, attributes);
+ }(baseDescriptor));
+
+ // Set the text size in attributes.
+ AutoCFRelease<CFNumberRef> cfTextSize(
+ CFNumberCreate(kCFAllocatorDefault, kCFNumberCGFloatType, &textSize));
+ CFDictionarySetValue(newAttributes, kCTFontSizeAttribute, cfTextSize);
+
+ // Set the transform in attributes.
+ if (nullptr == transform) {
+ CFDictionaryRemoveValue(newAttributes, kCTFontMatrixAttribute);
+ } else {
+ AutoCFRelease<CFDataRef> cfMatrixData(CFDataCreate(
+ kCFAllocatorDefault, reinterpret_cast<const UInt8*>(transform), sizeof(*transform)));
+ CFDictionarySetValue(newAttributes, kCTFontMatrixAttribute, cfMatrixData);
+ }
+
+ // Set vertical orientation to attributes if requested.
+ if (setVertical) {
+ CTFontOrientation ctOrientation = kCTFontVerticalOrientation;
+ AutoCFRelease<CFNumberRef> cfVertical(
+ CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &ctOrientation));
+ CFDictionarySetValue(newAttributes, kCTFontOrientationAttribute, cfVertical);
+ }
+
+ // Create the new CTFont from the baseCGFont.
+ AutoCFRelease<CTFontDescriptorRef> newDescriptor(
+ CTFontDescriptorCreateWithAttributes(newAttributes));
+ return CTFontCreateWithGraphicsFont(baseCGFont, textSize, transform, newDescriptor);
+
+}
+
SkScalerContext_Mac::SkScalerContext_Mac(SkTypeface_Mac* typeface,
const SkDescriptor* desc)
: INHERITED(typeface, desc)
@@ -740,30 +789,13 @@ SkScalerContext_Mac::SkScalerContext_Mac(SkTypeface_Mac* typeface,
fTransform = MatrixToCGAffineTransform(skTransform);
fInvTransform = CGAffineTransformInvert(fTransform);
- AutoCFRelease<CTFontDescriptorRef> ctFontDesc;
- if (fVertical) {
- // Setting the vertical orientation here is required for vertical metrics on some versions.
- AutoCFRelease<CFMutableDictionaryRef> cfAttributes(CFDictionaryCreateMutable(
- kCFAllocatorDefault, 0,
- &kCFTypeDictionaryKeyCallBacks,
- &kCFTypeDictionaryValueCallBacks));
- if (cfAttributes) {
- CTFontOrientation ctOrientation = kCTFontVerticalOrientation;
- AutoCFRelease<CFNumberRef> cfVertical(CFNumberCreate(
- kCFAllocatorDefault, kCFNumberSInt32Type, &ctOrientation));
- CFDictionaryAddValue(cfAttributes, kCTFontOrientationAttribute, cfVertical);
- ctFontDesc.reset(CTFontDescriptorCreateWithAttributes(cfAttributes));
- }
- }
-
// The transform contains everything except the requested text size.
// Some properties, like 'trak', are based on the text size (before applying the matrix).
CGFloat textSize = ScalarToCG(scale.y());
- fCTFont.reset(CTFontCreateCopyWithAttributes(ctFont, textSize, &fTransform, ctFontDesc));
+ fCTFont.reset(ctfont_create_exact_copy(ctFont, textSize, &fTransform, fVertical));
fCGFont.reset(CTFontCopyGraphicsFont(fCTFont, nullptr));
- fCTUnrotatedFont.reset(CTFontCreateCopyWithAttributes(ctFont, textSize,
- &CGAffineTransformIdentity, nullptr));
+ fCTUnrotatedFont.reset(ctfont_create_exact_copy(ctFont, textSize, nullptr, false));
// The fUnitMatrix includes the text size (and em) as it is used to scale the raw font data.
SkScalar emPerFUnit = SkScalarInvert(SkIntToScalar(CGFontGetUnitsPerEm(fCGFont)));
@@ -1363,9 +1395,13 @@ void SkScalerContext_Mac::generatePath(const SkGlyph& glyph, SkPath* path) {
break;
}
- CGAffineTransform xform = MatrixToCGAffineTransform(m, scaleX, scaleY);
- // need to release font when we're done
- font = CTFontCreateCopyWithAttributes(fCTFont, 1, &xform, nullptr);
+ CGFloat textSize = CTFontGetSize(fCTFont);
+ CGAffineTransform baseTransform = CTFontGetMatrix(fCTFont);
+ CGAffineTransform newTransform =
+ CGAffineTransformScale(baseTransform, ScalarToCG(scaleX), ScalarToCG(scaleY));
+
+ // need to release this font when we're done
+ font = ctfont_create_exact_copy(fCTFont, textSize, &newTransform, false);
}
CGGlyph cgGlyph = (CGGlyph)glyph.getGlyphID();
@@ -1380,7 +1416,7 @@ void SkScalerContext_Mac::generatePath(const SkGlyph& glyph, SkPath* path) {
SkMatrix m;
m.setScale(SkScalarInvert(scaleX), SkScalarInvert(scaleY));
path->transform(m);
- // balance the call to CTFontCreateCopyWithAttributes
+ // balance the call to ctfont_create_exact_copy
CFSafeRelease(font);
}
if (fVertical) {
@@ -1561,8 +1597,9 @@ SkAdvancedTypefaceMetrics* SkTypeface_Mac::onGetAdvancedTypefaceMetrics(
AUTO_CG_LOCK();
CTFontRef originalCTFont = fFontRef.get();
- AutoCFRelease<CTFontRef> ctFont(CTFontCreateCopyWithAttributes(
- originalCTFont, CTFontGetUnitsPerEm(originalCTFont), nullptr, nullptr));
+ AutoCFRelease<CTFontRef> ctFont(ctfont_create_exact_copy(
+ originalCTFont, CTFontGetUnitsPerEm(originalCTFont), nullptr, false));
+
SkAdvancedTypefaceMetrics* info = new SkAdvancedTypefaceMetrics;
{