Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

land https://codereview.appspot.com/7221086/ -- add Multiply xfermode…

… matching CSS spec

git-svn-id: http://skia.googlecode.com/svn/trunk@7553 2bbb7eff-a529-9590-31e7-b0007b416f81
  • Loading branch information...
commit 794bde85adda25f1a0211430899be3e363daad6a 1 parent c381d3f
reed@google.com authored
View
1  gm/xfermodes.cpp
@@ -113,6 +113,7 @@ class XfermodesGM : public GM {
{ SkXfermode::kSoftLight_Mode, "SoftLight" },
{ SkXfermode::kDifference_Mode, "Difference" },
{ SkXfermode::kExclusion_Mode, "Exclusion" },
+ { SkXfermode::kMultiply_Mode, "Multiply" },
};
const SkScalar w = SkIntToScalar(W);
View
3  include/core/SkXfermode.h
@@ -118,8 +118,9 @@ class SK_API SkXfermode : public SkFlattenable {
kSoftLight_Mode,
kDifference_Mode,
kExclusion_Mode,
+ kMultiply_Mode,
- kLastMode = kExclusion_Mode
+ kLastMode = kMultiply_Mode
};
/**
View
21 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 },
};
///////////////////////////////////////////////////////////////////////////////
View
29 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;
}
Please sign in to comment.
Something went wrong with that request. Please try again.