diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/core/SkXfermode.cpp | 21 | ||||
-rw-r--r-- | src/effects/SkBlendImageFilter.cpp | 29 |
2 files changed, 37 insertions, 13 deletions
diff --git a/src/core/SkXfermode.cpp b/src/core/SkXfermode.cpp index 520ab876a6..c0a825cde0 100644 --- a/src/core/SkXfermode.cpp +++ b/src/core/SkXfermode.cpp @@ -191,10 +191,28 @@ static SkPMColor modulate_modeproc(SkPMColor src, SkPMColor dst) { return SkPackARGB32(a, r, g, b); } -// kScreen_Mode static inline int srcover_byte(int a, int b) { return a + b - SkAlphaMulAlpha(a, b); } + +// kMultiply_Mode +// B(Cb, Cs) = Cb x Cs +// multiply uses its own version of blendfunc_byte because sa and da are not needed +static int blendfunc_multiply_byte(int sc, int dc, int sa, int da) { + return clamp_div255round(sc * (255 - da) + dc * (255 - sa) + sc * dc); +} + +static SkPMColor multiply_modeproc(SkPMColor src, SkPMColor dst) { + int sa = SkGetPackedA32(src); + int da = SkGetPackedA32(dst); + int a = srcover_byte(sa, da); + int r = blendfunc_multiply_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da); + int g = blendfunc_multiply_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da); + int b = blendfunc_multiply_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da); + return SkPackARGB32(a, r, g, b); +} + +// kScreen_Mode static SkPMColor screen_modeproc(SkPMColor src, SkPMColor dst) { int a = srcover_byte(SkGetPackedA32(src), SkGetPackedA32(dst)); int r = srcover_byte(SkGetPackedR32(src), SkGetPackedR32(dst)); @@ -447,6 +465,7 @@ static const ProcCoeff gProcCoeffs[] = { { softlight_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF }, { difference_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF }, { exclusion_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF }, + { multiply_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF }, }; /////////////////////////////////////////////////////////////////////////////// diff --git a/src/effects/SkBlendImageFilter.cpp b/src/effects/SkBlendImageFilter.cpp index 3f6d3c575f..6da37641f4 100644 --- a/src/effects/SkBlendImageFilter.cpp +++ b/src/effects/SkBlendImageFilter.cpp @@ -19,24 +19,24 @@ namespace { -SkXfermode::Mode modeToXfermode(SkBlendImageFilter::Mode mode) -{ +SkXfermode::Mode modeToXfermode(SkBlendImageFilter::Mode mode) { switch (mode) { - case SkBlendImageFilter::kNormal_Mode: - return SkXfermode::kSrcOver_Mode; - case SkBlendImageFilter::kMultiply_Mode: - return SkXfermode::kModulate_Mode; - case SkBlendImageFilter::kScreen_Mode: - return SkXfermode::kScreen_Mode; - case SkBlendImageFilter::kDarken_Mode: - return SkXfermode::kDarken_Mode; - case SkBlendImageFilter::kLighten_Mode: - return SkXfermode::kLighten_Mode; + case SkBlendImageFilter::kNormal_Mode: + return SkXfermode::kSrcOver_Mode; + case SkBlendImageFilter::kMultiply_Mode: + return SkXfermode::kMultiply_Mode; + case SkBlendImageFilter::kScreen_Mode: + return SkXfermode::kScreen_Mode; + case SkBlendImageFilter::kDarken_Mode: + return SkXfermode::kDarken_Mode; + case SkBlendImageFilter::kLighten_Mode: + return SkXfermode::kLighten_Mode; } SkASSERT(0); return SkXfermode::kSrcOver_Mode; } +#ifdef SK_IGNORE_MULTIPLY_XFERMODE_OPT SkPMColor multiply_proc(SkPMColor src, SkPMColor dst) { int omsa = 255 - SkGetPackedA32(src); int sr = SkGetPackedR32(src), sg = SkGetPackedG32(src), sb = SkGetPackedB32(src); @@ -48,6 +48,7 @@ SkPMColor multiply_proc(SkPMColor src, SkPMColor dst) { int b = SkMulDiv255Round(omsa, db) + SkMulDiv255Round(omda, sb) + SkMulDiv255Round(sb, db); return SkPackARGB32(a, r, g, b); } +#endif }; @@ -97,6 +98,7 @@ bool SkBlendImageFilter::onFilterImage(Proxy* proxy, SkPaint paint; paint.setXfermodeMode(SkXfermode::kSrc_Mode); canvas.drawBitmap(background, 0, 0, &paint); +#ifdef SK_IGNORE_MULTIPLY_XFERMODE_OPT // FEBlend's multiply mode is (1 - Sa) * Da + (1 - Da) * Sc + Sc * Dc // Skia's is just Sc * Dc. So we use a custom proc to implement FEBlend's // version. @@ -105,6 +107,9 @@ bool SkBlendImageFilter::onFilterImage(Proxy* proxy, } else { paint.setXfermodeMode(modeToXfermode(fMode)); } +#else + paint.setXfermodeMode(modeToXfermode(fMode)); +#endif canvas.drawBitmap(foreground, 0, 0, &paint); return true; } |