Index: src/core/SkXfermode.cpp |
=================================================================== |
--- src/core/SkXfermode.cpp (revision 8084) |
+++ src/core/SkXfermode.cpp (working copy) |
@@ -290,57 +290,41 @@ |
static inline int colordodge_byte(int sc, int dc, int sa, int da) { |
int diff = sa - sc; |
int rc; |
- if (0 == diff) { |
+ if (0 == dc) { |
+ return SkAlphaMulAlpha(sc, 255 - da); |
+ } else if (0 == diff) { |
rc = sa * da + sc * (255 - da) + dc * (255 - sa); |
- rc = SkDiv255Round(rc); |
} else { |
- int tmp = (dc * sa << 15) / (da * diff); |
- rc = SkDiv255Round(sa * da) * tmp >> 15; |
- // don't clamp here, since we'll do it in our modeproc |
+ diff = dc * sa / diff; |
+ rc = sa * ((da < diff) ? da : diff) + sc * (255 - da) + dc * (255 - sa); |
} |
- return rc; |
+ return clamp_div255round(rc); |
} |
static SkPMColor colordodge_modeproc(SkPMColor src, SkPMColor dst) { |
- // added to avoid div-by-zero in colordodge_byte |
- if (0 == dst) { |
- return src; |
- } |
- |
int sa = SkGetPackedA32(src); |
int da = SkGetPackedA32(dst); |
int a = srcover_byte(sa, da); |
int r = colordodge_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da); |
int g = colordodge_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da); |
int b = colordodge_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da); |
- r = clamp_max(r, a); |
- g = clamp_max(g, a); |
- b = clamp_max(b, a); |
return SkPackARGB32(a, r, g, b); |
} |
// kColorBurn_Mode |
static inline int colorburn_byte(int sc, int dc, int sa, int da) { |
int rc; |
- if (dc == da && 0 == sc) { |
- rc = sa * da + dc * (255 - sa); |
+ if (dc == da) { |
+ rc = sa * da + sc * (255 - da) + dc * (255 - sa); |
} else if (0 == sc) { |
return SkAlphaMulAlpha(dc, 255 - sa); |
} else { |
- int tmp = (sa * (da - dc) * 256) / (sc * da); |
- if (tmp > 256) { |
- tmp = 256; |
- } |
- int tmp2 = sa * da; |
- rc = tmp2 - (tmp2 * tmp >> 8) + sc * (255 - da) + dc * (255 - sa); |
+ int tmp = (da - dc) * sa / sc; |
+ rc = sa * (da - ((da < tmp) ? da : tmp)) |
+ + sc * (255 - da) + dc * (255 - sa); |
} |
- return SkDiv255Round(rc); |
+ return clamp_div255round(rc); |
} |
static SkPMColor colorburn_modeproc(SkPMColor src, SkPMColor dst) { |
- // added to avoid div-by-zero in colorburn_byte |
- if (0 == dst) { |
- return src; |
- } |
- |
int sa = SkGetPackedA32(src); |
int da = SkGetPackedA32(dst); |
int a = srcover_byte(sa, da); |
@@ -438,7 +422,7 @@ |
// See http://www.glennchan.info/articles/technical/hd-versus-sd-color-space/hd-versus-sd-color-space.htm |
static inline int Lum(int r, int g, int b) |
{ |
- return (r * 77 + g * 151 + b * 28) >> 8; |
+ return SkDiv255Round(r * 77 + g * 150 + b * 28); |
} |
static inline int min2(int a, int b) { return a < b ? a : b; } |
@@ -452,7 +436,7 @@ |
static inline void setSaturationComponents(int* Cmin, int* Cmid, int* Cmax, int s) { |
if(*Cmax > *Cmin) { |
- *Cmid = (((*Cmid - *Cmin) * s ) / (*Cmax - *Cmin)); |
+ *Cmid = SkMulDiv(*Cmid - *Cmin, s, *Cmax - *Cmin); |
*Cmax = s; |
} else { |
*Cmax = 0; |
@@ -480,35 +464,35 @@ |
} |
} |
-static inline void clipColor(int* r, int* g, int* b) { |
+static inline void clipColor(int* r, int* g, int* b, int a) { |
int L = Lum(*r, *g, *b); |
int n = minimum(*r, *g, *b); |
int x = maximum(*r, *g, *b); |
if(n < 0) { |
- *r = L + (((*r - L) * L) / (L - n)); |
- *g = L + (((*g - L) * L) / (L - n)); |
- *b = L + (((*b - L) * L) / (L - n)); |
+ *r = L + SkMulDiv(*r - L, L, L - n); |
+ *g = L + SkMulDiv(*g - L, L, L - n); |
+ *b = L + SkMulDiv(*b - L, L, L - n); |
} |
- if(x > 255) { |
- *r = L + (((*r - L) * (255 - L)) / (x - L)); |
- *g = L + (((*g - L) * (255 - L)) / (x - L)); |
- *b = L + (((*b - L) * (255 - L)) / (x - L)); |
+ if (x > a) { |
+ *r = L + SkMulDiv(*r - L, a - L, x - L); |
+ *g = L + SkMulDiv(*g - L, a - L, x - L); |
+ *b = L + SkMulDiv(*b - L, a - L, x - L); |
} |
} |
-static inline void SetLum(int* r, int* g, int* b, int l) { |
+static inline void SetLum(int* r, int* g, int* b, int a, int l) { |
int d = l - Lum(*r, *g, *b); |
*r += d; |
*g += d; |
*b += d; |
- clipColor(r, g, b); |
+ clipColor(r, g, b, a); |
} |
// non-separable blend modes are done in non-premultiplied alpha |
#define blendfunc_nonsep_byte(sc, dc, sa, da, blendval) \ |
- clamp_div255round(sc * (255 - da) + dc * (255 - sa) + clamp_div255round(sa * da) * blendval) |
+ clamp_div255round(sc * (255 - da) + dc * (255 - sa) + blendval) |
// kHue_Mode |
// B(Cb, Cs) = SetLum(SetSat(Cs, Sat(Cb)), Lum(Cb)) |
@@ -526,14 +510,11 @@ |
int Sr, Sg, Sb; |
if(sa && da) { |
- Sr = SkMulDiv255Round(sr, sa); |
- Sg = SkMulDiv255Round(sg, sa); |
- Sb = SkMulDiv255Round(sb, sa); |
- int Dr = SkMulDiv255Round(dr, da); |
- int Dg = SkMulDiv255Round(dg, da); |
- int Db = SkMulDiv255Round(db, da); |
- SetSat(&Sr, &Sg, &Sb, Sat(Dr, Dg, Db)); |
- SetLum(&Sr, &Sg, &Sb, Lum(Dr, Dg, Db)); |
+ Sr = sr * sa; |
+ Sg = sg * sa; |
+ Sb = sb * sa; |
+ SetSat(&Sr, &Sg, &Sb, Sat(dr, dg, db) * sa); |
+ SetLum(&Sr, &Sg, &Sb, sa * da, Lum(dr, dg, db) * sa); |
} else { |
Sr = 0; |
Sg = 0; |
@@ -563,15 +544,11 @@ |
int Dr, Dg, Db; |
if(sa && da) { |
- int Sr = SkMulDiv255Round(sr, sa); |
- int Sg = SkMulDiv255Round(sg, sa); |
- int Sb = SkMulDiv255Round(sb, sa); |
- Dr = SkMulDiv255Round(dr, da); |
- Dg = SkMulDiv255Round(dg, da); |
- Db = SkMulDiv255Round(db, da); |
- int LumD = Lum(Dr, Dg, Db); |
- SetSat(&Dr, &Dg, &Db, Sat(Sr, Sg, Sb)); |
- SetLum(&Dr, &Dg, &Db, LumD); |
+ Dr = dr * sa; |
+ Dg = dg * sa; |
+ Db = db * sa; |
+ SetSat(&Dr, &Dg, &Db, Sat(sr, sg, sb) * da); |
+ SetLum(&Dr, &Dg, &Db, sa * da, Lum(dr, dg, db) * sa); |
} else { |
Dr = 0; |
Dg = 0; |
@@ -601,13 +578,10 @@ |
int Sr, Sg, Sb; |
if(sa && da) { |
- Sr = SkMulDiv255Round(sr, sa); |
- Sg = SkMulDiv255Round(sg, sa); |
- Sb = SkMulDiv255Round(sb, sa); |
- int Dr = SkMulDiv255Round(dr, da); |
- int Dg = SkMulDiv255Round(dg, da); |
- int Db = SkMulDiv255Round(db, da); |
- SetLum(&Sr, &Sg, &Sb, Lum(Dr, Dg, Db)); |
+ Sr = sr * da; |
+ Sg = sg * da; |
+ Sb = sb * da; |
+ SetLum(&Sr, &Sg, &Sb, sa * da, Lum(dr, dg, db) * sa); |
} else { |
Sr = 0; |
Sg = 0; |
@@ -637,13 +611,10 @@ |
int Dr, Dg, Db; |
if(sa && da) { |
- int Sr = SkMulDiv255Round(sr, sa); |
- int Sg = SkMulDiv255Round(sg, sa); |
- int Sb = SkMulDiv255Round(sb, sa); |
- Dr = SkMulDiv255Round(dr, da); |
- Dg = SkMulDiv255Round(dg, da); |
- Db = SkMulDiv255Round(db, da); |
- SetLum(&Dr, &Dg, &Db, Lum(Sr, Sg, Sb)); |
+ Dr = dr * sa; |
+ Dg = dg * sa; |
+ Db = db * sa; |
+ SetLum(&Dr, &Dg, &Db, sa * da, Lum(sr, sg, sb) * da); |
} else { |
Dr = 0; |
Dg = 0; |