| Index: src/ports/SkFontHost_mac.cpp
|
| diff --git a/src/ports/SkFontHost_mac.cpp b/src/ports/SkFontHost_mac.cpp
|
| index 0d4bbb73d97a10437547f540091ba017ad006396..8d3a6fac86777ce0a063144148315a8a3eddbbec 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);
|
| }
|
|
|
|
|