Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(923)

Unified Diff: src/ports/SkFontHost_mac.cpp

Issue 775323002: Fix Apple Color Emoji support for OS X 10.7+ (Closed) Base URL: https://chromium.googlesource.com/skia.git@master
Patch Set: Created 6 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/ports/SkFontHost_mac.cpp
diff --git a/src/ports/SkFontHost_mac.cpp b/src/ports/SkFontHost_mac.cpp
index c19df196b3a9a97b1ff4ad667ff550f44f27d56e..e6ece49af3080c8267b230df0588dfc1f3f4843e 100755
--- a/src/ports/SkFontHost_mac.cpp
+++ b/src/ports/SkFontHost_mac.cpp
@@ -115,6 +115,11 @@ public:
const T* fData;
};
+static bool CTFontIsAppleColorEmoji(CTFontRef font) {
+ AutoCFRelease<CFStringRef> name(CTFontCopyFamilyName(font));
+ return CFStringCompare(name.get(), CFSTR("Apple Color Emoji"), 0) == kCFCompareEqualTo;
bungeman-skia 2014/12/04 14:47:14 No way we're doing this (testing by name).
+}
+
// inline versions of these rect helpers
static bool CGRectIsEmpty_inline(const CGRect& rect) {
@@ -680,6 +685,7 @@ private:
bool fGeneratedFBoundingBoxes;
const bool fDoSubPosition;
const bool fVertical;
+ bool fIsColorEmoji;
friend class Offscreen;
@@ -700,6 +706,7 @@ SkScalerContext_Mac::SkScalerContext_Mac(SkTypeface_Mac* typeface,
CFIndex numGlyphs = CTFontGetGlyphCount(ctFont);
SkASSERT(numGlyphs >= 1 && numGlyphs <= 0xFFFF);
fGlyphCount = SkToU16(numGlyphs);
+ fIsColorEmoji = CTFontIsAppleColorEmoji(ctFont);
SkMatrix skTransform;
fRec.getSingleMatrixWithoutTextSize(&skTransform);
@@ -788,10 +795,12 @@ CGRGBPixel* Offscreen::getCG(const SkScalerContext_Mac& context, const SkGlyph&
CGContextSetAllowsFontSubpixelQuantization(fCG, false);
CGContextSetShouldSubpixelQuantizeFonts(fCG, false);
- CGContextSetTextDrawingMode(fCG, kCGTextFill);
- CGContextSetFont(fCG, context.fCGFont);
- CGContextSetFontSize(fCG, CTFontGetSize(context.fCTFont));
- CGContextSetTextMatrix(fCG, CTFontGetMatrix(context.fCTFont));
+ if (!context.fIsColorEmoji) {
+ CGContextSetTextDrawingMode(fCG, kCGTextFill);
+ CGContextSetFont(fCG, context.fCGFont);
+ CGContextSetFontSize(fCG, CTFontGetSize(context.fCTFont));
+ CGContextSetTextMatrix(fCG, CTFontGetMatrix(context.fCTFont));
+ }
// Because CG always draws from the horizontal baseline,
// if there is a non-integral translation from the horizontal origin to the vertical origin,
@@ -821,8 +830,8 @@ CGRGBPixel* Offscreen::getCG(const SkScalerContext_Mac& context, const SkGlyph&
// skip rows based on the glyph's height
image += (fSize.fHeight - glyph.fHeight) * fSize.fWidth;
- // erase to black
- sk_memset_rect32(image, 0, glyph.fWidth, glyph.fHeight, rowBytes);
+ // erase to black or white.
+ sk_memset_rect32(image, context.fIsColorEmoji ? 0xFFFFFFFF : 0, glyph.fWidth, glyph.fHeight, rowBytes);
bungeman-skia 2014/12/04 14:47:13 We cannot make the background opaque.
float subX = 0;
float subY = 0;
@@ -839,9 +848,19 @@ CGRGBPixel* Offscreen::getCG(const SkScalerContext_Mac& context, const SkGlyph&
subY += offset.fY;
}
- CGContextShowGlyphsAtPoint(fCG, -glyph.fLeft + subX,
- glyph.fTop + glyph.fHeight - subY,
- &glyphID, 1);
+ CGPoint pos = CGPointMake(-glyph.fLeft + subX, glyph.fTop + glyph.fHeight - subY);
+ if (context.fIsColorEmoji) {
+ CGContextSaveGState(fCG);
+ // CGContextSetTextMatrix does not work with color glyphs, so we use the
bungeman-skia 2014/12/04 14:47:13 This isn't quite true, what happens is CoreText wo
+ // CTM instead. This means we must translate the CTM as well, to set the
+ // glyph position, instead of using CGContextSetTextPosition.
+ CGContextConcatCTM(fCG, CTFontGetMatrix(context.fCTFont));
+ CGContextTranslateCTM(fCG, pos.x, pos.y);
+ CTFontDrawGlyphs(context.fCTFont, &glyphID, &CGPointZero, 1, fCG);
+ CGContextRestoreGState(fCG);
+ } else {
+ CGContextShowGlyphsAtPoint(fCG, pos.x, pos.y, &glyphID, 1);
+ }
SkASSERT(rowBytesPtr);
*rowBytesPtr = rowBytes;
@@ -1140,22 +1159,12 @@ static void rgb_to_lcd16(const CGRGBPixel* SK_RESTRICT cgPixels, size_t cgRowByt
}
}
-#ifdef HACK_COLORGLYPHS
-// hack to colorize the output for testing kARGB32_Format
-static SkPMColor cgpixels_to_pmcolor(CGRGBPixel rgb, const SkGlyph& glyph,
- int x, int y) {
+static SkPMColor cgpixels_to_pmcolor(CGRGBPixel rgb) {
U8CPU r = (rgb >> 16) & 0xFF;
U8CPU g = (rgb >> 8) & 0xFF;
U8CPU b = (rgb >> 0) & 0xFF;
- unsigned a = SkComputeLuminance(r, g, b);
-
- // compute gradient from x,y
- r = x * 255 / glyph.fWidth;
- g = 0;
- b = (glyph.fHeight - y) * 255 / glyph.fHeight;
- return SkPreMultiplyARGB(a, r, g, b); // red
+ return SkPreMultiplyARGB(0xFF, r, g, b); // red
bungeman-skia 2014/12/04 14:47:13 We cannot make these opaque, transparency must be
}
-#endif
template <typename T> T* SkTAddByteOffset(T* ptr, size_t byteOffset) {
return (T*)((char*)ptr + byteOffset);
@@ -1228,20 +1237,18 @@ void SkScalerContext_Mac::generateImage(const SkGlyph& glyph) {
dst += dstRB;
}
} break;
-#ifdef HACK_COLORGLYPHS
case SkMask::kARGB32_Format: {
const int width = glyph.fWidth;
size_t dstRB = glyph.rowBytes();
SkPMColor* dst = (SkPMColor*)glyph.fImage;
for (int y = 0; y < glyph.fHeight; y++) {
for (int x = 0; x < width; ++x) {
- dst[x] = cgpixels_to_pmcolor(cgPixels[x], glyph, x, y);
+ dst[x] = cgpixels_to_pmcolor(cgPixels[x]);
}
cgPixels = (CGRGBPixel*)((char*)cgPixels + cgRowBytes);
dst = (SkPMColor*)((char*)dst + dstRB);
}
} break;
-#endif
default:
SkDEBUGFAIL("unexpected mask format");
break;
@@ -1828,6 +1835,9 @@ void SkTypeface_Mac::onFilterRec(SkScalerContextRec* rec) const {
}
}
+ if (CTFontIsAppleColorEmoji(fFontRef.get()))
+ rec->fMaskFormat = SkMask::kARGB32_Format;
+
// Unhinted A8 masks (those not derived from LCD masks) must respect SK_GAMMA_APPLY_TO_A8.
// All other masks can use regular gamma.
if (SkMask::kA8_Format == rec->fMaskFormat && SkPaint::kNo_Hinting == hinting) {
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698