Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(134)

Unified Diff: src/core/Sk4pxXfermode.h

Issue 1241683003: Fix buggy blend modes. (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Created 5 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/core/Sk4pxXfermode.h
diff --git a/src/core/Sk4pxXfermode.h b/src/core/Sk4pxXfermode.h
index 97321b7413cdfe98ad8072f96f3082ac4ec98704..c671b679f82534c9c82b38d2a0ed12ba96052dad 100644
--- a/src/core/Sk4pxXfermode.h
+++ b/src/core/Sk4pxXfermode.h
@@ -62,37 +62,53 @@ XFERMODE(Exclusion) {
return (s - p) + (d - p.zeroAlphas());
}
-XFERMODE(HardLight) {
- auto alphas = SrcOver::Xfer(s,d);
+// We take care to use exact math for these next few modes where alphas
+// and colors are calculated using significantly different math. We need
+// to preserve premul invariants, and exact math makes this easier.
+//
+// TODO: Some of these implementations might be able to be sped up a bit
+// while maintaining exact math, but let's follow up with that.
+XFERMODE(HardLight) {
auto sa = s.alphas(),
da = d.alphas();
+ auto srcover = s + (d * sa.inv()).div255();
+
auto isLite = ((sa-s) < s).widenLoHi();
- auto dark = s*d << 1,
- lite = sa*da - ((da-d)*(sa-s) << 1),
+ auto lite = sa*da - ((da-d)*(sa-s) << 1),
+ dark = s*d << 1,
both = s*da.inv() + d*sa.inv();
+ auto alphas = srcover;
auto colors = (both + isLite.thenElse(lite, dark)).div255();
return alphas.zeroColors() + colors.zeroAlphas();
}
XFERMODE(Overlay) { return HardLight::Xfer(d,s); }
XFERMODE(Darken) {
- auto sda = s.approxMulDiv255(d.alphas()),
- dsa = d.approxMulDiv255(s.alphas());
- auto srcover = s + (d - dsa),
- dstover = d + (s - sda);
+ auto sa = s.alphas(),
+ da = d.alphas();
+
+ auto sda = (s*da).div255(),
+ dsa = (d*sa).div255();
+
+ auto srcover = s + (d * sa.inv()).div255(),
+ dstover = d + (s * da.inv()).div255();
auto alphas = srcover,
colors = (sda < dsa).thenElse(srcover, dstover);
return alphas.zeroColors() + colors.zeroAlphas();
}
XFERMODE(Lighten) {
- auto sda = s.approxMulDiv255(d.alphas()),
- dsa = d.approxMulDiv255(s.alphas());
- auto srcover = s + (d - dsa),
- dstover = d + (s - sda);
+ auto sa = s.alphas(),
+ da = d.alphas();
+
+ auto sda = (s*da).div255(),
+ dsa = (d*sa).div255();
+
+ auto srcover = s + (d * sa.inv()).div255(),
+ dstover = d + (s * da.inv()).div255();
auto alphas = srcover,
colors = (dsa < sda).thenElse(srcover, dstover);
return alphas.zeroColors() + colors.zeroAlphas();
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698