diff --git a/gm/gradtext.cpp b/gm/gradtext.cpp index 6c75db1b1a..a3769d2728 100644 --- a/gm/gradtext.cpp +++ b/gm/gradtext.cpp @@ -9,15 +9,16 @@ #include "SkCanvas.h" #include "SkGradientShader.h" +// test shader w/ transparency static SkShader* make_grad(SkScalar width) { - SkColor colors[] = { SK_ColorBLACK, SK_ColorBLACK, 0 }; - SkScalar pos[] = { 0, SK_Scalar1 * 5 / 10, SK_Scalar1 }; + SkColor colors[] = { SK_ColorRED, 0x0000FF00, SK_ColorBLUE }; SkPoint pts[] = { { 0, 0 }, { width, 0 } }; - return SkGradientShader::CreateLinear(pts, colors, pos, + return SkGradientShader::CreateLinear(pts, colors, NULL, SK_ARRAY_COUNT(colors), SkShader::kMirror_TileMode); } +// test opaque shader static SkShader* make_grad2(SkScalar width) { SkColor colors[] = { SK_ColorRED, SK_ColorGREEN, SK_ColorBLUE }; SkPoint pts[] = { { 0, 0 }, { width, 0 } }; @@ -38,7 +39,7 @@ protected: return SkString("gradtext"); } - virtual SkISize onISize() { return make_isize(640, 480); } + virtual SkISize onISize() { return make_isize(500, 480); } static void draw_text(SkCanvas* canvas, const SkPaint& paint) { const char* text = "When in the course of human events"; @@ -52,26 +53,35 @@ protected: p.setAntiAlias(false); draw_text(canvas, p); p.setAntiAlias(true); - canvas->translate(0, SkIntToScalar(20)); + canvas->translate(0, paint.getTextSize() * 4/3); draw_text(canvas, p); p.setLCDRenderText(true); - canvas->translate(0, SkIntToScalar(20)); + canvas->translate(0, paint.getTextSize() * 4/3); draw_text(canvas, p); } virtual void onDraw(SkCanvas* canvas) { - canvas->translate(SkIntToScalar(20), SkIntToScalar(20)); - - // The blits special-case opaque and non-paque shaders, so test both - SkPaint paint; - paint.setTextSize(SkIntToScalar(16)); - paint.setShader(make_grad(SkIntToScalar(80)))->unref(); + paint.setTextSize(SkIntToScalar(26)); - draw_text3(canvas, paint); - canvas->translate(0, SkIntToScalar(40)); - paint.setShader(make_grad2(SkIntToScalar(80)))->unref(); - draw_text3(canvas, paint); + const SkISize& size = this->getISize(); + SkRect r = SkRect::MakeWH(SkIntToScalar(size.width()), + SkIntToScalar(size.height()) / 2); + canvas->drawRect(r, paint); + + canvas->translate(SkIntToScalar(20), paint.getTextSize()); + + for (int i = 0; i < 2; ++i) { + paint.setShader(make_grad(SkIntToScalar(80)))->unref(); + draw_text3(canvas, paint); + + canvas->translate(0, paint.getTextSize() * 2); + + paint.setShader(make_grad2(SkIntToScalar(80)))->unref(); + draw_text3(canvas, paint); + + canvas->translate(0, paint.getTextSize() * 2); + } } private: diff --git a/src/core/SkBlitMask_D32.cpp b/src/core/SkBlitMask_D32.cpp index 1a006e5e1f..72a83ee2eb 100644 --- a/src/core/SkBlitMask_D32.cpp +++ b/src/core/SkBlitMask_D32.cpp @@ -552,6 +552,14 @@ static void LCD16_RowProc_Opaque(SkPMColor* SK_RESTRICT dst, } } +static int mul(int a, int b) { + return a * b >> 8; +} + +static int src_alpha_blend(int src, int dst, int srcA, int mask) { + return dst + mul(src - mul(srcA, dst), mask); +} + static void LCD32_RowProc_Blend(SkPMColor* SK_RESTRICT dst, const SkPMColor* SK_RESTRICT mask, const SkPMColor* SK_RESTRICT src, int count) { @@ -564,7 +572,7 @@ static void LCD32_RowProc_Blend(SkPMColor* SK_RESTRICT dst, SkPMColor s = src[i]; int srcA = SkGetPackedA32(s); int srcR = SkGetPackedR32(s); - int srcG = SkGetPackedB32(s); + int srcG = SkGetPackedG32(s); int srcB = SkGetPackedB32(s); srcA = SkAlpha255To256(srcA); @@ -575,15 +583,11 @@ static void LCD32_RowProc_Blend(SkPMColor* SK_RESTRICT dst, int maskG = SkGetPackedG32(m); int maskB = SkGetPackedB32(m); - // Now upscale them to 0..256, so we can use SkAlphaBlend + // Now upscale them to 0..256 maskR = SkAlpha255To256(maskR); maskG = SkAlpha255To256(maskG); maskB = SkAlpha255To256(maskB); - - maskR = maskR * srcA >> 8; - maskG = maskG * srcA >> 8; - maskB = maskB * srcA >> 8; - + int dstR = SkGetPackedR32(d); int dstG = SkGetPackedG32(d); int dstB = SkGetPackedB32(d); @@ -591,9 +595,9 @@ static void LCD32_RowProc_Blend(SkPMColor* SK_RESTRICT dst, // 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)); + src_alpha_blend(srcR, dstR, srcA, maskR), + src_alpha_blend(srcG, dstG, srcA, maskG), + src_alpha_blend(srcB, dstB, srcA, maskB)); } } @@ -612,9 +616,11 @@ static void LCD32_RowProc_Opaque(SkPMColor* SK_RESTRICT dst, int maskR = SkGetPackedR32(m); int maskG = SkGetPackedG32(m); int maskB = SkGetPackedB32(m); + int srcR = SkGetPackedR32(s); - int srcG = SkGetPackedB32(s); - int srcB = SkGetPackedB32(s); + int srcG = SkGetPackedG32(s); + int srcB = SkGetPackedB32(s); + int dstR = SkGetPackedR32(d); int dstG = SkGetPackedG32(d); int dstB = SkGetPackedB32(d); @@ -637,7 +643,6 @@ SkBlitMask::RowProc SkBlitMask::RowFactory(SkBitmap::Config config, SkMask::Format format, RowFlags flags) { // make this opt-in until chrome can rebaseline -#ifdef SK_ENABLE_FAST_SHADERMASK RowProc proc = PlatformRowProcs(config, format, flags); if (proc) { return proc; @@ -670,7 +675,6 @@ SkBlitMask::RowProc SkBlitMask::RowFactory(SkBitmap::Config config, default: break; } -#endif return NULL; } diff --git a/src/core/SkDevice.cpp b/src/core/SkDevice.cpp index 860e45b0ed..1865212e6e 100644 --- a/src/core/SkDevice.cpp +++ b/src/core/SkDevice.cpp @@ -365,11 +365,6 @@ bool SkDevice::filterTextFlags(const SkPaint& paint, TextFlags* flags) { } if (SkBitmap::kARGB_8888_Config != fBitmap.config() || -#ifndef SK_ENABLE_FAST_SHADERMASK - paint.getShader() || - paint.getMaskFilter() || - paint.getColorFilter() || -#endif paint.getRasterizer() || paint.getPathEffect() || paint.isFakeBoldText() ||