aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/core/SkXfermode.cpp21
-rw-r--r--src/effects/SkBlendImageFilter.cpp29
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;
}