aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/ports
diff options
context:
space:
mode:
authorGravatar bungeman <bungeman@google.com>2015-01-08 08:33:44 -0800
committerGravatar Commit bot <commit-bot@chromium.org>2015-01-08 08:33:44 -0800
commit3b4b66c04a2567c72754a55e53db41394249b223 (patch)
treecdcd4af0a2c83a0b56439b071c0e259b499f6fd7 /src/ports
parent9558f653877b982df415e4d075db55b7558f7654 (diff)
Work around changes in OSX 10.10.
In 10.10.1 CTFontGetAdvancesForGlyphs applies the font transform to the width of the advance but always sets the height of the advance to 0. Work around this by measuring the advance with an unrotated font and apply the transform manually. In 10.7 through 10.9 CTFontDrawGlyphs appears to take 'positions' in text space and acts like CGContextShowGlyphsAtPosition. In 10.10.1, these 'positions' now appear to be in glyph space, and CTFontDrawGlyphs maps the glyph positions internally. BUG=chromium:442574 Review URL: https://codereview.chromium.org/841843002
Diffstat (limited to 'src/ports')
-rwxr-xr-xsrc/ports/SkFontHost_mac.cpp55
1 files changed, 39 insertions, 16 deletions
diff --git a/src/ports/SkFontHost_mac.cpp b/src/ports/SkFontHost_mac.cpp
index 0d4bbb73d9..8d3a6fac86 100755
--- a/src/ports/SkFontHost_mac.cpp
+++ b/src/ports/SkFontHost_mac.cpp
@@ -46,6 +46,9 @@
#include <dlfcn.h>
+// Set to make glyph bounding boxes visible.
+#define SK_SHOW_TEXT_BLIT_COVERAGE 0
+
class SkScalerContext_Mac;
// CTFontManagerCopyAvailableFontFamilyNames() is not always available, so we
@@ -681,14 +684,18 @@ private:
AutoCFRelease<CTFontRef> fCTFont;
CGAffineTransform fInvTransform;
- /** Vertical variant of fCTFont.
+ /** Unrotated variant of fCTFont.
+ *
+ * In 10.10.1 CTFontGetAdvancesForGlyphs applies the font transform to the width of the
+ * advances, but always sets the height to 0. This font is used to get the advances of the
+ * unrotated glyph, and then the rotation is applied separately.
*
* CT vertical metrics are pre-rotated (in em space, before transform) 90deg clock-wise.
* This makes kCTFontDefaultOrientation dangerous, because the metrics from
* kCTFontHorizontalOrientation are in a different space from kCTFontVerticalOrientation.
- * Use fCTVerticalFont with kCTFontVerticalOrientation to get metrics in the same space.
+ * With kCTFontVerticalOrientation the advances must be unrotated.
*/
- AutoCFRelease<CTFontRef> fCTVerticalFont;
+ AutoCFRelease<CTFontRef> fCTUnrotatedFont;
AutoCFRelease<CGFontRef> fCGFont;
SkAutoTMalloc<GlyphRect> fFBoundingBoxes;
@@ -729,6 +736,7 @@ SkScalerContext_Mac::SkScalerContext_Mac(SkTypeface_Mac* typeface,
AutoCFRelease<CTFontDescriptorRef> ctFontDesc;
if (fVertical) {
+ // Setting the vertical orientation here affects the character to glyph mapping.
AutoCFRelease<CFMutableDictionaryRef> cfAttributes(CFDictionaryCreateMutable(
kCFAllocatorDefault, 0,
&kCFTypeDictionaryKeyCallBacks,
@@ -748,11 +756,8 @@ SkScalerContext_Mac::SkScalerContext_Mac(SkTypeface_Mac* typeface,
fCTFont.reset(CTFontCreateCopyWithAttributes(ctFont, textSize, &transform, ctFontDesc));
fCGFont.reset(CTFontCopyGraphicsFont(fCTFont, NULL));
- if (fVertical) {
- CGAffineTransform rotateLeft = CGAffineTransformMake(0, -1, 1, 0, 0, 0);
- transform = CGAffineTransformConcat(rotateLeft, transform);
- fCTVerticalFont.reset(CTFontCreateCopyWithAttributes(ctFont, textSize, &transform, NULL));
- }
+ fCTUnrotatedFont.reset(CTFontCreateCopyWithAttributes(ctFont, textSize,
+ &CGAffineTransformIdentity, NULL));
// The fUnitMatrix includes the text size (and em) as it is used to scale the raw font data.
SkScalar emPerFUnit = SkScalarInvert(SkIntToScalar(CGFontGetUnitsPerEm(fCGFont)));
@@ -896,11 +901,14 @@ CGRGBPixel* Offscreen::getCG(const SkScalerContext_Mac& context, const SkGlyph&
subY += offset.fY;
}
- // CTFontDrawGlyphs and CGContextShowGlyphsAtPositions take 'positions' which are in text space.
- // The glyph location (in device space) must be mapped into text space, so that CG can convert
- // it back into device space.
CGPoint point = CGPointMake(-glyph.fLeft + subX, glyph.fTop + glyph.fHeight - subY);
- point = CGPointApplyAffineTransform(point, context.fInvTransform);
+ if (darwinVersion() < 14) {
+ // Prior to 10.10, CTFontDrawGlyphs acted like CGContextShowGlyphsAtPositions and took
+ // 'positions' which are in text space. The glyph location (in device space) must be
+ // mapped into text space, so that CG can convert it back into device space.
+ // In 10.10 and later, this is handled directly in CTFontDrawGlyphs.
+ point = CGPointApplyAffineTransform(point, context.fInvTransform);
+ }
ctFontDrawGlyphs(context.fCTFont, &glyphID, &point, 1, fCG);
SkASSERT(rowBytesPtr);
@@ -1007,12 +1015,16 @@ void SkScalerContext_Mac::generateMetrics(SkGlyph* glyph) {
// The following block produces cgAdvance in CG units (pixels, y up).
CGSize cgAdvance;
if (fVertical) {
- CTFontGetAdvancesForGlyphs(fCTVerticalFont, kCTFontVerticalOrientation,
+ CTFontGetAdvancesForGlyphs(fCTUnrotatedFont, kCTFontVerticalOrientation,
&cgGlyph, &cgAdvance, 1);
+ // Vertical advances are returned as widths instead of heights.
+ SkTSwap(cgAdvance.height, cgAdvance.width);
+ cgAdvance.height = -cgAdvance.height;
} else {
- CTFontGetAdvancesForGlyphs(fCTFont, kCTFontHorizontalOrientation,
+ CTFontGetAdvancesForGlyphs(fCTUnrotatedFont, kCTFontHorizontalOrientation,
&cgGlyph, &cgAdvance, 1);
}
+ cgAdvance = CGSizeApplyAffineTransform(cgAdvance, CTFontGetMatrix(fCTFont));
glyph->fAdvanceX = SkFloatToFixed_Check(cgAdvance.width);
glyph->fAdvanceY = -SkFloatToFixed_Check(cgAdvance.height);
@@ -1153,7 +1165,11 @@ static inline uint8_t rgb_to_a8(CGRGBPixel rgb, const uint8_t* table8) {
U8CPU r = (rgb >> 16) & 0xFF;
U8CPU g = (rgb >> 8) & 0xFF;
U8CPU b = (rgb >> 0) & 0xFF;
- return sk_apply_lut_if<APPLY_PREBLEND>(SkComputeLuminance(r, g, b), table8);
+ U8CPU lum = sk_apply_lut_if<APPLY_PREBLEND>(SkComputeLuminance(r, g, b), table8);
+#if SK_SHOW_TEXT_BLIT_COVERAGE
+ lum = SkTMax(lum, (U8CPU)0x30);
+#endif
+ return lum;
}
template<bool APPLY_PREBLEND>
static void rgb_to_a8(const CGRGBPixel* SK_RESTRICT cgPixels, size_t cgRowBytes,
@@ -1178,6 +1194,11 @@ static inline uint16_t rgb_to_lcd16(CGRGBPixel rgb, const uint8_t* tableR,
U8CPU r = sk_apply_lut_if<APPLY_PREBLEND>((rgb >> 16) & 0xFF, tableR);
U8CPU g = sk_apply_lut_if<APPLY_PREBLEND>((rgb >> 8) & 0xFF, tableG);
U8CPU b = sk_apply_lut_if<APPLY_PREBLEND>((rgb >> 0) & 0xFF, tableB);
+#if SK_SHOW_TEXT_BLIT_COVERAGE
+ r = SkTMax(r, (U8CPU)0x30);
+ g = SkTMax(g, (U8CPU)0x30);
+ b = SkTMax(b, (U8CPU)0x30);
+#endif
return SkPack888ToRGB16(r, g, b);
}
template<bool APPLY_PREBLEND>
@@ -1201,7 +1222,9 @@ static SkPMColor cgpixels_to_pmcolor(CGRGBPixel rgb) {
U8CPU r = (rgb >> 16) & 0xFF;
U8CPU g = (rgb >> 8) & 0xFF;
U8CPU b = (rgb >> 0) & 0xFF;
-
+#if SK_SHOW_TEXT_BLIT_COVERAGE
+ a = SkTMax(a, (U8CPU)0x30);
+#endif
return SkPackARGB32(a, r, g, b);
}