diff options
author | reed@google.com <reed@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2011-09-30 20:31:25 +0000 |
---|---|---|
committer | reed@google.com <reed@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2011-09-30 20:31:25 +0000 |
commit | 6fc3c1fe428eaaa1581d32988354870cf005d03b (patch) | |
tree | 78e6a679bd78bf668ee13fd0885fc396e82e26b5 | |
parent | e958c6949af2def03ae894917e81eab008116947 (diff) |
Detect that we're drawing to a device that has per-pixel alpha, and if so,
disable LCD text.
Add experimental flag to force AA in fontscaler (windows-only). Hope to remove
this later.
git-svn-id: http://skia.googlecode.com/svn/trunk@2387 2bbb7eff-a529-9590-31e7-b0007b416f81
-rw-r--r-- | src/core/SkBlitter_ARGB32.cpp | 35 | ||||
-rw-r--r-- | src/core/SkDevice.cpp | 7 | ||||
-rw-r--r-- | src/core/SkPaint.cpp | 5 | ||||
-rwxr-xr-x | src/ports/SkFontHost_win.cpp | 34 |
4 files changed, 41 insertions, 40 deletions
diff --git a/src/core/SkBlitter_ARGB32.cpp b/src/core/SkBlitter_ARGB32.cpp index af55aba951..4e2916af0e 100644 --- a/src/core/SkBlitter_ARGB32.cpp +++ b/src/core/SkBlitter_ARGB32.cpp @@ -60,18 +60,16 @@ static void blit_lcd16_row(SkPMColor dst[], const uint16_t src[], maskG = maskG * srcA >> 8; maskB = maskB * srcA >> 8; - int maskA = SkMax32(SkMax32(maskR, maskG), maskB); - - int dstA = SkGetPackedA32(d); int dstR = SkGetPackedR32(d); int dstG = SkGetPackedG32(d); int dstB = SkGetPackedB32(d); - // nocheck version for now, until we cleanup GDI's garbage bits - dst[i] = SkPackARGB32NoCheck(blend32(0xFF, dstA, maskA), - blend32(srcR, dstR, maskR), - blend32(srcG, dstG, maskG), - blend32(srcB, dstB, maskB)); + // LCD blitting is only supported if the dst is known/required\ + // to be opaque + dst[i] = SkPackARGB32(0xFF, + blend32(srcR, dstR, maskR), + blend32(srcG, dstG, maskG), + blend32(srcB, dstB, maskB)); } } @@ -105,18 +103,16 @@ static void blit_lcd16_opaque_row(SkPMColor dst[], const uint16_t src[], maskG = upscale31To32(maskG); maskB = upscale31To32(maskB); - int maskA = SkMax32(SkMax32(maskR, maskG), maskB); - - int dstA = SkGetPackedA32(d); int dstR = SkGetPackedR32(d); int dstG = SkGetPackedG32(d); int dstB = SkGetPackedB32(d); - // nocheck version for now, until we cleanup GDI's garbage bits - dst[i] = SkPackARGB32NoCheck(blend32(0xFF, dstA, maskA), - blend32(srcR, dstR, maskR), - blend32(srcG, dstG, maskG), - blend32(srcB, dstB, maskB)); + // LCD blitting is only supported if the dst is known/required + // to be opaque + dst[i] = SkPackARGB32(0xFF, + blend32(srcR, dstR, maskR), + blend32(srcG, dstG, maskG), + blend32(srcB, dstB, maskB)); } } @@ -150,14 +146,13 @@ static void blit_lcd32_row(SkPMColor dst[], const uint32_t src[], maskG = maskG * srcA >> 8; maskB = maskB * srcA >> 8; - int maskA = SkMax32(SkMax32(maskR, maskG), maskB); - - int dstA = SkGetPackedA32(d); int dstR = SkGetPackedR32(d); int dstG = SkGetPackedG32(d); int dstB = SkGetPackedB32(d); - dst[i] = SkPackARGB32(SkAlphaBlend(0xFF, dstA, maskA), + // LCD blitting is only supported if the dst is known/required + // to be opaque + dst[i] = SkPackARGB32(0xFF, SkAlphaBlend(srcR, dstR, maskR), SkAlphaBlend(srcG, dstG, maskG), SkAlphaBlend(srcB, dstB, maskB)); diff --git a/src/core/SkDevice.cpp b/src/core/SkDevice.cpp index 69f86ccf52..c88ad9afb7 100644 --- a/src/core/SkDevice.cpp +++ b/src/core/SkDevice.cpp @@ -219,12 +219,13 @@ void SkDevice::drawDevice(const SkDraw& draw, SkDevice* device, /////////////////////////////////////////////////////////////////////////////// bool SkDevice::filterTextFlags(const SkPaint& paint, TextFlags* flags) { - if (!paint.isLCDRenderText()) { + if (!paint.isLCDRenderText() || !paint.isAntiAlias()) { // we're cool with the paint as is return false; } if (SkBitmap::kARGB_8888_Config != fBitmap.config() || + !fBitmap.isOpaque() || paint.getShader() || paint.getXfermode() || // unless its srcover paint.getMaskFilter() || @@ -235,6 +236,10 @@ bool SkDevice::filterTextFlags(const SkPaint& paint, TextFlags* flags) { paint.getStyle() != SkPaint::kFill_Style) { // turn off lcd flags->fFlags = paint.getFlags() & ~SkPaint::kLCDRenderText_Flag; +#ifdef SK_BUILD_FOR_WIN + // flag that we *really* want AA + flags->fFlags |= SkPaint::kForceAAText_Flag; +#endif flags->fHinting = paint.getHinting(); return true; } diff --git a/src/core/SkPaint.cpp b/src/core/SkPaint.cpp index 9197adde0f..b2f5d8e0e1 100644 --- a/src/core/SkPaint.cpp +++ b/src/core/SkPaint.cpp @@ -1340,6 +1340,11 @@ void SkScalerContext::MakeRec(const SkPaint& paint, if (paint.isAutohinted()) { flags |= SkScalerContext::kAutohinting_Flag; } +#ifdef SK_BUILD_FOR_WIN + if (paint.getFlags() & SkPaint::kForceAAText_Flag) { + flags |= SkScalerContext::kForceAA_Flag; + } +#endif rec->fFlags = SkToU16(flags); // setHinting modifies fFlags, so do this last diff --git a/src/ports/SkFontHost_win.cpp b/src/ports/SkFontHost_win.cpp index e265c139dc..87dbb80859 100755 --- a/src/ports/SkFontHost_win.cpp +++ b/src/ports/SkFontHost_win.cpp @@ -31,11 +31,6 @@ template <typename T> T* SkTAddByteOffset(T* ptr, size_t byteOffset) { return (T*)((char*)ptr + byteOffset); } -// When we request ANTIALIAS quality, we often seemt to get BW instead -// This flag "fixes" that by actually requesting LCD output, and filtering -// it down to gray-aa -#define FORCE_AA_BY_CAPTURING_LCD_OUTPUT - // define this in your Makefile or .gyp to enforce AA requests // which GDI ignores at small sizes. This flag guarantees AA // for rotated text, regardless of GDI's notions. @@ -483,11 +478,15 @@ static BYTE compute_quality(const SkScalerContext::Rec& rec) { case SkMask::kLCD32_Format: return CLEARTYPE_QUALITY; default: -#ifdef FORCE_AA_BY_CAPTURING_LCD_OUTPUT - return CLEARTYPE_QUALITY; -#else - return ANTIALIASED_QUALITY; -#endif + // here we just want AA, but we may have to force the issue + // since sometimes GDI will instead really give us BW + // (for some fonts and some sizes) + if (rec.fFlags & SkScalerContext::kForceAA_Flag) { + return CLEARTYPE_QUALITY; + } else { + return ANTIALIASED_QUALITY; + } + break; } } @@ -697,19 +696,11 @@ void SkScalerContext_Windows::generateFontMetrics(SkPaint::FontMetrics* mx, SkPa // whenever we copy it into skia's buffer static inline uint8_t rgb_to_a8(SkGdiRGB rgb) { -#ifdef FORCE_AA_BY_CAPTURING_LCD_OUTPUT int r = (rgb >> 16) & 0xFF; int g = (rgb >> 8) & 0xFF; int b = (rgb >> 0) & 0xFF; -// int ave = (r * 5 + g * 6 + b * 5) >> 4; - int ave = (r * 2 + g * 5 + b) >> 3; // luminance - - return ave; -#else - // can pick any component (low 3 bytes), since we're grayscale - return rgb & 0xFF; -#endif + return (r * 2 + g * 5 + b) >> 3; // luminance } static inline uint16_t rgb_to_lcd16(SkGdiRGB rgb) { @@ -1309,6 +1300,11 @@ void SkFontHost::FilterRec(SkScalerContext::Rec* rec) { rec->fMaskFormat = SkMask::kLCD32_Format; } #endif + // don't specify gamma if we BW (perhaps caller should do this check) + if (SkMask::kBW_Format == rec->fMaskFormat) { + rec->fFlags &= ~(SkScalerContext::kGammaForBlack_Flag | + SkScalerContext::kGammaForWhite_Flag); + } } ////////////////////////////////////////////////////////////////////////// |