gfx/skia/patches/archive/0010-Bug-836892-Add-new-blending-modes-to-SkXfermode.patch

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.

michael@0 1 # HG changeset patch
michael@0 2 # User Rik Cabanier <cabanier@adobe.com>
michael@0 3 # Date 1360273929 -46800
michael@0 4 # Node ID 3ac8edca3a03b3d22240b5a5b95ae3b5ada9877d
michael@0 5 # Parent cbb67fe70b864b36165061e1fd3b083cd09af087
michael@0 6 Bug 836892 - Add new blending modes to SkXfermode. r=gw280
michael@0 7
michael@0 8 diff --git a/gfx/skia/include/core/SkXfermode.h b/gfx/skia/include/core/SkXfermode.h
michael@0 9 --- a/gfx/skia/include/core/SkXfermode.h
michael@0 10 +++ b/gfx/skia/include/core/SkXfermode.h
michael@0 11 @@ -96,33 +96,37 @@ public:
michael@0 12 kDstOut_Mode, //!< [Da * (1 - Sa), Dc * (1 - Sa)]
michael@0 13 kSrcATop_Mode, //!< [Da, Sc * Da + (1 - Sa) * Dc]
michael@0 14 kDstATop_Mode, //!< [Sa, Sa * Dc + Sc * (1 - Da)]
michael@0 15 kXor_Mode, //!< [Sa + Da - 2 * Sa * Da, Sc * (1 - Da) + (1 - Sa) * Dc]
michael@0 16
michael@0 17 // all remaining modes are defined in the SVG Compositing standard
michael@0 18 // http://www.w3.org/TR/2009/WD-SVGCompositing-20090430/
michael@0 19 kPlus_Mode,
michael@0 20 - kMultiply_Mode,
michael@0 21
michael@0 22 // all above modes can be expressed as pair of src/dst Coeffs
michael@0 23 kCoeffModesCnt,
michael@0 24
michael@0 25 - kScreen_Mode = kCoeffModesCnt,
michael@0 26 + kMultiply_Mode = kCoeffModesCnt,
michael@0 27 + kScreen_Mode,
michael@0 28 kOverlay_Mode,
michael@0 29 kDarken_Mode,
michael@0 30 kLighten_Mode,
michael@0 31 kColorDodge_Mode,
michael@0 32 kColorBurn_Mode,
michael@0 33 kHardLight_Mode,
michael@0 34 kSoftLight_Mode,
michael@0 35 kDifference_Mode,
michael@0 36 kExclusion_Mode,
michael@0 37 + kHue_Mode,
michael@0 38 + kSaturation_Mode,
michael@0 39 + kColor_Mode,
michael@0 40 + kLuminosity_Mode,
michael@0 41
michael@0 42 - kLastMode = kExclusion_Mode
michael@0 43 + kLastMode = kLuminosity_Mode
michael@0 44 };
michael@0 45
michael@0 46 /**
michael@0 47 * If the xfermode is one of the modes in the Mode enum, then asMode()
michael@0 48 * returns true and sets (if not null) mode accordingly. Otherwise it
michael@0 49 * returns false and ignores the mode parameter.
michael@0 50 */
michael@0 51 virtual bool asMode(Mode* mode);
michael@0 52 diff --git a/gfx/skia/src/core/SkXfermode.cpp b/gfx/skia/src/core/SkXfermode.cpp
michael@0 53 --- a/gfx/skia/src/core/SkXfermode.cpp
michael@0 54 +++ b/gfx/skia/src/core/SkXfermode.cpp
michael@0 55 @@ -7,16 +7,18 @@
michael@0 56 */
michael@0 57
michael@0 58
michael@0 59 #include "SkXfermode.h"
michael@0 60 #include "SkColorPriv.h"
michael@0 61 #include "SkFlattenableBuffers.h"
michael@0 62 #include "SkMathPriv.h"
michael@0 63
michael@0 64 +#include <algorithm>
michael@0 65 +
michael@0 66 SK_DEFINE_INST_COUNT(SkXfermode)
michael@0 67
michael@0 68 #define SkAlphaMulAlpha(a, b) SkMulDiv255Round(a, b)
michael@0 69
michael@0 70 #if 0
michael@0 71 // idea for higher precision blends in xfer procs (and slightly faster)
michael@0 72 // see DstATop as a probable caller
michael@0 73 static U8CPU mulmuldiv255round(U8CPU a, U8CPU b, U8CPU c, U8CPU d) {
michael@0 74 @@ -176,244 +178,439 @@ static SkPMColor xor_modeproc(SkPMColor
michael@0 75 static SkPMColor plus_modeproc(SkPMColor src, SkPMColor dst) {
michael@0 76 unsigned b = saturated_add(SkGetPackedB32(src), SkGetPackedB32(dst));
michael@0 77 unsigned g = saturated_add(SkGetPackedG32(src), SkGetPackedG32(dst));
michael@0 78 unsigned r = saturated_add(SkGetPackedR32(src), SkGetPackedR32(dst));
michael@0 79 unsigned a = saturated_add(SkGetPackedA32(src), SkGetPackedA32(dst));
michael@0 80 return SkPackARGB32(a, r, g, b);
michael@0 81 }
michael@0 82
michael@0 83 +static inline int srcover_byte(int a, int b) {
michael@0 84 + return a + b - SkAlphaMulAlpha(a, b);
michael@0 85 +}
michael@0 86 +
michael@0 87 +#define blendfunc_byte(sc, dc, sa, da, blendfunc) \
michael@0 88 + clamp_div255round(sc * (255 - da) + dc * (255 - sa) + blendfunc(sc, dc, sa, da))
michael@0 89 +
michael@0 90 // kMultiply_Mode
michael@0 91 +static inline int multiply_byte(int sc, int dc, int sa, int da) {
michael@0 92 + return sc * dc;
michael@0 93 +}
michael@0 94 static SkPMColor multiply_modeproc(SkPMColor src, SkPMColor dst) {
michael@0 95 - int a = SkAlphaMulAlpha(SkGetPackedA32(src), SkGetPackedA32(dst));
michael@0 96 - int r = SkAlphaMulAlpha(SkGetPackedR32(src), SkGetPackedR32(dst));
michael@0 97 - int g = SkAlphaMulAlpha(SkGetPackedG32(src), SkGetPackedG32(dst));
michael@0 98 - int b = SkAlphaMulAlpha(SkGetPackedB32(src), SkGetPackedB32(dst));
michael@0 99 + int sa = SkGetPackedA32(src);
michael@0 100 + int da = SkGetPackedA32(dst);
michael@0 101 + int a = srcover_byte(sa, da);
michael@0 102 + int r = blendfunc_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da, multiply_byte);
michael@0 103 + int g = blendfunc_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da, multiply_byte);
michael@0 104 + int b = blendfunc_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da, multiply_byte);
michael@0 105 return SkPackARGB32(a, r, g, b);
michael@0 106 }
michael@0 107
michael@0 108 // kScreen_Mode
michael@0 109 -static inline int srcover_byte(int a, int b) {
michael@0 110 - return a + b - SkAlphaMulAlpha(a, b);
michael@0 111 +static inline int screen_byte(int sc, int dc, int sa, int da) {
michael@0 112 + return sc * da + sa * dc - sc * dc;
michael@0 113 }
michael@0 114 static SkPMColor screen_modeproc(SkPMColor src, SkPMColor dst) {
michael@0 115 - int a = srcover_byte(SkGetPackedA32(src), SkGetPackedA32(dst));
michael@0 116 - int r = srcover_byte(SkGetPackedR32(src), SkGetPackedR32(dst));
michael@0 117 - int g = srcover_byte(SkGetPackedG32(src), SkGetPackedG32(dst));
michael@0 118 - int b = srcover_byte(SkGetPackedB32(src), SkGetPackedB32(dst));
michael@0 119 + int sa = SkGetPackedA32(src);
michael@0 120 + int da = SkGetPackedA32(dst);
michael@0 121 + int a = srcover_byte(sa, da);
michael@0 122 + int r = blendfunc_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da, screen_byte);
michael@0 123 + int g = blendfunc_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da, screen_byte);
michael@0 124 + int b = blendfunc_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da, screen_byte);
michael@0 125 + return SkPackARGB32(a, r, g, b);
michael@0 126 +}
michael@0 127 +
michael@0 128 +// kHardLight_Mode
michael@0 129 +static inline int hardlight_byte(int sc, int dc, int sa, int da) {
michael@0 130 + if(!sa || !da)
michael@0 131 + return sc * da;
michael@0 132 + float Sc = (float)sc/sa;
michael@0 133 + float Dc = (float)dc/da;
michael@0 134 + if(Sc <= 0.5)
michael@0 135 + Sc *= 2 * Dc;
michael@0 136 + else
michael@0 137 + Sc = -1 + 2 * Sc + 2 * Dc - 2 * Sc * Dc;
michael@0 138 +
michael@0 139 + return Sc * sa * da;
michael@0 140 +}
michael@0 141 +static SkPMColor hardlight_modeproc(SkPMColor src, SkPMColor dst) {
michael@0 142 + int sa = SkGetPackedA32(src);
michael@0 143 + int da = SkGetPackedA32(dst);
michael@0 144 + int a = srcover_byte(sa, da);
michael@0 145 + int r = blendfunc_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da, hardlight_byte);
michael@0 146 + int g = blendfunc_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da, hardlight_byte);
michael@0 147 + int b = blendfunc_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da, hardlight_byte);
michael@0 148 return SkPackARGB32(a, r, g, b);
michael@0 149 }
michael@0 150
michael@0 151 // kOverlay_Mode
michael@0 152 static inline int overlay_byte(int sc, int dc, int sa, int da) {
michael@0 153 - int tmp = sc * (255 - da) + dc * (255 - sa);
michael@0 154 - int rc;
michael@0 155 - if (2 * dc <= da) {
michael@0 156 - rc = 2 * sc * dc;
michael@0 157 - } else {
michael@0 158 - rc = sa * da - 2 * (da - dc) * (sa - sc);
michael@0 159 - }
michael@0 160 - return clamp_div255round(rc + tmp);
michael@0 161 + return hardlight_byte(dc, sc, da, sa);
michael@0 162 }
michael@0 163 static SkPMColor overlay_modeproc(SkPMColor src, SkPMColor dst) {
michael@0 164 int sa = SkGetPackedA32(src);
michael@0 165 int da = SkGetPackedA32(dst);
michael@0 166 int a = srcover_byte(sa, da);
michael@0 167 - int r = overlay_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da);
michael@0 168 - int g = overlay_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da);
michael@0 169 - int b = overlay_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da);
michael@0 170 + int r = blendfunc_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da, overlay_byte);
michael@0 171 + int g = blendfunc_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da, overlay_byte);
michael@0 172 + int b = blendfunc_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da, overlay_byte);
michael@0 173 return SkPackARGB32(a, r, g, b);
michael@0 174 }
michael@0 175
michael@0 176 // kDarken_Mode
michael@0 177 static inline int darken_byte(int sc, int dc, int sa, int da) {
michael@0 178 - int sd = sc * da;
michael@0 179 - int ds = dc * sa;
michael@0 180 - if (sd < ds) {
michael@0 181 - // srcover
michael@0 182 - return sc + dc - SkDiv255Round(ds);
michael@0 183 - } else {
michael@0 184 - // dstover
michael@0 185 - return dc + sc - SkDiv255Round(sd);
michael@0 186 - }
michael@0 187 + return SkMin32(sc * da, sa * dc);
michael@0 188 }
michael@0 189 static SkPMColor darken_modeproc(SkPMColor src, SkPMColor dst) {
michael@0 190 int sa = SkGetPackedA32(src);
michael@0 191 int da = SkGetPackedA32(dst);
michael@0 192 int a = srcover_byte(sa, da);
michael@0 193 - int r = darken_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da);
michael@0 194 - int g = darken_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da);
michael@0 195 - int b = darken_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da);
michael@0 196 + int r = blendfunc_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da, darken_byte);
michael@0 197 + int g = blendfunc_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da, darken_byte);
michael@0 198 + int b = blendfunc_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da, darken_byte);
michael@0 199 return SkPackARGB32(a, r, g, b);
michael@0 200 }
michael@0 201
michael@0 202 // kLighten_Mode
michael@0 203 static inline int lighten_byte(int sc, int dc, int sa, int da) {
michael@0 204 - int sd = sc * da;
michael@0 205 - int ds = dc * sa;
michael@0 206 - if (sd > ds) {
michael@0 207 - // srcover
michael@0 208 - return sc + dc - SkDiv255Round(ds);
michael@0 209 - } else {
michael@0 210 - // dstover
michael@0 211 - return dc + sc - SkDiv255Round(sd);
michael@0 212 - }
michael@0 213 + return SkMax32(sc * da, sa * dc);
michael@0 214 }
michael@0 215 static SkPMColor lighten_modeproc(SkPMColor src, SkPMColor dst) {
michael@0 216 int sa = SkGetPackedA32(src);
michael@0 217 int da = SkGetPackedA32(dst);
michael@0 218 int a = srcover_byte(sa, da);
michael@0 219 - int r = lighten_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da);
michael@0 220 - int g = lighten_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da);
michael@0 221 - int b = lighten_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da);
michael@0 222 + int r = blendfunc_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da, lighten_byte);
michael@0 223 + int g = blendfunc_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da, lighten_byte);
michael@0 224 + int b = blendfunc_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da, lighten_byte);
michael@0 225 return SkPackARGB32(a, r, g, b);
michael@0 226 }
michael@0 227
michael@0 228 // kColorDodge_Mode
michael@0 229 static inline int colordodge_byte(int sc, int dc, int sa, int da) {
michael@0 230 - int diff = sa - sc;
michael@0 231 - int rc;
michael@0 232 - if (0 == diff) {
michael@0 233 - rc = sa * da + sc * (255 - da) + dc * (255 - sa);
michael@0 234 - rc = SkDiv255Round(rc);
michael@0 235 - } else {
michael@0 236 - int tmp = (dc * sa << 15) / (da * diff);
michael@0 237 - rc = SkDiv255Round(sa * da) * tmp >> 15;
michael@0 238 - // don't clamp here, since we'll do it in our modeproc
michael@0 239 - }
michael@0 240 - return rc;
michael@0 241 + if (dc == 0)
michael@0 242 + return 0;
michael@0 243 + // Avoid division by 0
michael@0 244 + if (sc == sa)
michael@0 245 + return da * sa;
michael@0 246 +
michael@0 247 + return SkMin32(sa * da, sa * sa * dc / (sa - sc));
michael@0 248 }
michael@0 249 static SkPMColor colordodge_modeproc(SkPMColor src, SkPMColor dst) {
michael@0 250 - // added to avoid div-by-zero in colordodge_byte
michael@0 251 - if (0 == dst) {
michael@0 252 - return src;
michael@0 253 - }
michael@0 254 -
michael@0 255 int sa = SkGetPackedA32(src);
michael@0 256 int da = SkGetPackedA32(dst);
michael@0 257 int a = srcover_byte(sa, da);
michael@0 258 - int r = colordodge_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da);
michael@0 259 - int g = colordodge_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da);
michael@0 260 - int b = colordodge_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da);
michael@0 261 - r = clamp_max(r, a);
michael@0 262 - g = clamp_max(g, a);
michael@0 263 - b = clamp_max(b, a);
michael@0 264 + int r = blendfunc_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da, colordodge_byte);
michael@0 265 + int g = blendfunc_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da, colordodge_byte);
michael@0 266 + int b = blendfunc_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da, colordodge_byte);
michael@0 267 return SkPackARGB32(a, r, g, b);
michael@0 268 }
michael@0 269
michael@0 270 // kColorBurn_Mode
michael@0 271 static inline int colorburn_byte(int sc, int dc, int sa, int da) {
michael@0 272 - int rc;
michael@0 273 - if (dc == da && 0 == sc) {
michael@0 274 - rc = sa * da + dc * (255 - sa);
michael@0 275 - } else if (0 == sc) {
michael@0 276 - return SkAlphaMulAlpha(dc, 255 - sa);
michael@0 277 - } else {
michael@0 278 - int tmp = (sa * (da - dc) * 256) / (sc * da);
michael@0 279 - if (tmp > 256) {
michael@0 280 - tmp = 256;
michael@0 281 - }
michael@0 282 - int tmp2 = sa * da;
michael@0 283 - rc = tmp2 - (tmp2 * tmp >> 8) + sc * (255 - da) + dc * (255 - sa);
michael@0 284 - }
michael@0 285 - return SkDiv255Round(rc);
michael@0 286 + // Avoid division by 0
michael@0 287 + if(dc == da)
michael@0 288 + return sa * da;
michael@0 289 + if(sc == 0)
michael@0 290 + return 0;
michael@0 291 +
michael@0 292 + return sa * da - SkMin32(sa * da, sa * sa * (da - dc) / sc);
michael@0 293 }
michael@0 294 static SkPMColor colorburn_modeproc(SkPMColor src, SkPMColor dst) {
michael@0 295 - // added to avoid div-by-zero in colorburn_byte
michael@0 296 - if (0 == dst) {
michael@0 297 - return src;
michael@0 298 - }
michael@0 299 -
michael@0 300 int sa = SkGetPackedA32(src);
michael@0 301 int da = SkGetPackedA32(dst);
michael@0 302 int a = srcover_byte(sa, da);
michael@0 303 - int r = colorburn_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da);
michael@0 304 - int g = colorburn_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da);
michael@0 305 - int b = colorburn_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da);
michael@0 306 - return SkPackARGB32(a, r, g, b);
michael@0 307 -}
michael@0 308 -
michael@0 309 -// kHardLight_Mode
michael@0 310 -static inline int hardlight_byte(int sc, int dc, int sa, int da) {
michael@0 311 - int rc;
michael@0 312 - if (2 * sc <= sa) {
michael@0 313 - rc = 2 * sc * dc;
michael@0 314 - } else {
michael@0 315 - rc = sa * da - 2 * (da - dc) * (sa - sc);
michael@0 316 - }
michael@0 317 - return clamp_div255round(rc + sc * (255 - da) + dc * (255 - sa));
michael@0 318 -}
michael@0 319 -static SkPMColor hardlight_modeproc(SkPMColor src, SkPMColor dst) {
michael@0 320 - int sa = SkGetPackedA32(src);
michael@0 321 - int da = SkGetPackedA32(dst);
michael@0 322 - int a = srcover_byte(sa, da);
michael@0 323 - int r = hardlight_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da);
michael@0 324 - int g = hardlight_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da);
michael@0 325 - int b = hardlight_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da);
michael@0 326 + int r = blendfunc_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da, colorburn_byte);
michael@0 327 + int g = blendfunc_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da, colorburn_byte);
michael@0 328 + int b = blendfunc_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da, colorburn_byte);
michael@0 329 return SkPackARGB32(a, r, g, b);
michael@0 330 }
michael@0 331
michael@0 332 // returns 255 * sqrt(n/255)
michael@0 333 static U8CPU sqrt_unit_byte(U8CPU n) {
michael@0 334 return SkSqrtBits(n, 15+4);
michael@0 335 }
michael@0 336
michael@0 337 // kSoftLight_Mode
michael@0 338 static inline int softlight_byte(int sc, int dc, int sa, int da) {
michael@0 339 int m = da ? dc * 256 / da : 0;
michael@0 340 int rc;
michael@0 341 - if (2 * sc <= sa) {
michael@0 342 - rc = dc * (sa + ((2 * sc - sa) * (256 - m) >> 8));
michael@0 343 - } else if (4 * dc <= da) {
michael@0 344 + if (2 * sc <= sa)
michael@0 345 + return dc * (sa + ((2 * sc - sa) * (256 - m) >> 8));
michael@0 346 +
michael@0 347 + if (4 * dc <= da) {
michael@0 348 int tmp = (4 * m * (4 * m + 256) * (m - 256) >> 16) + 7 * m;
michael@0 349 - rc = dc * sa + (da * (2 * sc - sa) * tmp >> 8);
michael@0 350 - } else {
michael@0 351 - int tmp = sqrt_unit_byte(m) - m;
michael@0 352 - rc = dc * sa + (da * (2 * sc - sa) * tmp >> 8);
michael@0 353 + return dc * sa + (da * (2 * sc - sa) * tmp >> 8);
michael@0 354 }
michael@0 355 - return clamp_div255round(rc + sc * (255 - da) + dc * (255 - sa));
michael@0 356 + int tmp = sqrt_unit_byte(m) - m;
michael@0 357 + return rc = dc * sa + (da * (2 * sc - sa) * tmp >> 8);
michael@0 358 }
michael@0 359 static SkPMColor softlight_modeproc(SkPMColor src, SkPMColor dst) {
michael@0 360 int sa = SkGetPackedA32(src);
michael@0 361 int da = SkGetPackedA32(dst);
michael@0 362 int a = srcover_byte(sa, da);
michael@0 363 - int r = softlight_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da);
michael@0 364 - int g = softlight_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da);
michael@0 365 - int b = softlight_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da);
michael@0 366 + int r = blendfunc_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da, softlight_byte);
michael@0 367 + int g = blendfunc_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da, softlight_byte);
michael@0 368 + int b = blendfunc_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da, softlight_byte);
michael@0 369 return SkPackARGB32(a, r, g, b);
michael@0 370 }
michael@0 371
michael@0 372 // kDifference_Mode
michael@0 373 static inline int difference_byte(int sc, int dc, int sa, int da) {
michael@0 374 - int tmp = SkMin32(sc * da, dc * sa);
michael@0 375 - return clamp_signed_byte(sc + dc - 2 * SkDiv255Round(tmp));
michael@0 376 + int tmp = dc * sa - sc * da;
michael@0 377 + if(tmp<0)
michael@0 378 + return - tmp;
michael@0 379 +
michael@0 380 + return tmp;
michael@0 381 }
michael@0 382 static SkPMColor difference_modeproc(SkPMColor src, SkPMColor dst) {
michael@0 383 int sa = SkGetPackedA32(src);
michael@0 384 int da = SkGetPackedA32(dst);
michael@0 385 int a = srcover_byte(sa, da);
michael@0 386 - int r = difference_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da);
michael@0 387 - int g = difference_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da);
michael@0 388 - int b = difference_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da);
michael@0 389 + int r = blendfunc_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da, difference_byte);
michael@0 390 + int g = blendfunc_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da, difference_byte);
michael@0 391 + int b = blendfunc_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da, difference_byte);
michael@0 392 return SkPackARGB32(a, r, g, b);
michael@0 393 }
michael@0 394
michael@0 395 // kExclusion_Mode
michael@0 396 static inline int exclusion_byte(int sc, int dc, int sa, int da) {
michael@0 397 - // this equations is wacky, wait for SVG to confirm it
michael@0 398 - int r = sc * da + dc * sa - 2 * sc * dc + sc * (255 - da) + dc * (255 - sa);
michael@0 399 - return clamp_div255round(r);
michael@0 400 + return sc * da + dc * sa - 2 * dc * sc;
michael@0 401 }
michael@0 402 static SkPMColor exclusion_modeproc(SkPMColor src, SkPMColor dst) {
michael@0 403 int sa = SkGetPackedA32(src);
michael@0 404 int da = SkGetPackedA32(dst);
michael@0 405 int a = srcover_byte(sa, da);
michael@0 406 - int r = exclusion_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da);
michael@0 407 - int g = exclusion_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da);
michael@0 408 - int b = exclusion_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da);
michael@0 409 + int r = blendfunc_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da, exclusion_byte);
michael@0 410 + int g = blendfunc_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da, exclusion_byte);
michael@0 411 + int b = blendfunc_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da, exclusion_byte);
michael@0 412 + return SkPackARGB32(a, r, g, b);
michael@0 413 +}
michael@0 414 +
michael@0 415 +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
michael@0 416 +struct BlendColor {
michael@0 417 + float r;
michael@0 418 + float g;
michael@0 419 + float b;
michael@0 420 +
michael@0 421 + BlendColor(): r(0), g(0), b(0)
michael@0 422 + {}
michael@0 423 +};
michael@0 424 +
michael@0 425 +static inline float Lum(BlendColor C)
michael@0 426 +{
michael@0 427 + return C.r * 0.3 + C.g * 0.59 + C.b* 0.11;
michael@0 428 +}
michael@0 429 +
michael@0 430 +static inline float SkMinFloat(float a, float b)
michael@0 431 +{
michael@0 432 + if (a > b)
michael@0 433 + a = b;
michael@0 434 + return a;
michael@0 435 +}
michael@0 436 +
michael@0 437 +static inline float SkMaxFloat(float a, float b)
michael@0 438 +{
michael@0 439 + if (a < b)
michael@0 440 + a = b;
michael@0 441 + return a;
michael@0 442 +}
michael@0 443 +
michael@0 444 +#define minimum(C) SkMinFloat(SkMinFloat(C.r, C.g), C.b)
michael@0 445 +#define maximum(C) SkMaxFloat(SkMaxFloat(C.r, C.g), C.b)
michael@0 446 +
michael@0 447 +static inline float Sat(BlendColor c) {
michael@0 448 + return maximum(c) - minimum(c);
michael@0 449 +}
michael@0 450 +
michael@0 451 +static inline void setSaturationComponents(float& Cmin, float& Cmid, float& Cmax, float s) {
michael@0 452 + if(Cmax > Cmin) {
michael@0 453 + Cmid = (((Cmid - Cmin) * s ) / (Cmax - Cmin));
michael@0 454 + Cmax = s;
michael@0 455 + } else {
michael@0 456 + Cmax = 0;
michael@0 457 + Cmid = 0;
michael@0 458 + }
michael@0 459 + Cmin = 0;
michael@0 460 +}
michael@0 461 +
michael@0 462 +static inline BlendColor SetSat(BlendColor C, float s) {
michael@0 463 + if(C.r <= C.g) {
michael@0 464 + if(C.g <= C.b)
michael@0 465 + setSaturationComponents(C.r, C.g, C.b, s);
michael@0 466 + else
michael@0 467 + if(C.r <= C.b)
michael@0 468 + setSaturationComponents(C.r, C.b, C.g, s);
michael@0 469 + else
michael@0 470 + setSaturationComponents(C.b, C.r, C.g, s);
michael@0 471 + } else if(C.r <= C.b)
michael@0 472 + setSaturationComponents(C.g, C.r, C.b, s);
michael@0 473 + else
michael@0 474 + if(C.g <= C.b)
michael@0 475 + setSaturationComponents(C.g, C.b, C.r, s);
michael@0 476 + else
michael@0 477 + setSaturationComponents(C.b, C.g, C.r, s);
michael@0 478 +
michael@0 479 + return C;
michael@0 480 +}
michael@0 481 +
michael@0 482 +static inline BlendColor clipColor(BlendColor C) {
michael@0 483 + float L = Lum(C);
michael@0 484 + float n = minimum(C);
michael@0 485 + float x = maximum(C);
michael@0 486 + if(n < 0) {
michael@0 487 + C.r = L + (((C.r - L) * L) / (L - n));
michael@0 488 + C.g = L + (((C.g - L) * L) / (L - n));
michael@0 489 + C.b = L + (((C.b - L) * L) / (L - n));
michael@0 490 + }
michael@0 491 +
michael@0 492 + if(x > 1) {
michael@0 493 + C.r = L + (((C.r - L) * (1 - L)) / (x - L));
michael@0 494 + C.g = L + (((C.g - L) * (1 - L)) / (x - L));
michael@0 495 + C.b = L + (((C.b - L) * (1 - L)) / (x - L));
michael@0 496 + }
michael@0 497 + return C;
michael@0 498 +}
michael@0 499 +
michael@0 500 +static inline BlendColor SetLum(BlendColor C, float l) {
michael@0 501 + float d = l - Lum(C);
michael@0 502 + C.r += d;
michael@0 503 + C.g += d;
michael@0 504 + C.b += d;
michael@0 505 +
michael@0 506 + return clipColor(C);
michael@0 507 +}
michael@0 508 +
michael@0 509 +#define blendfunc_nonsep_byte(sc, dc, sa, da, blendval) \
michael@0 510 + clamp_div255round(sc * (255 - da) + dc * (255 - sa) + (int)(sa * da * blendval))
michael@0 511 +
michael@0 512 +static SkPMColor hue_modeproc(SkPMColor src, SkPMColor dst) {
michael@0 513 + int sr = SkGetPackedR32(src);
michael@0 514 + int sg = SkGetPackedG32(src);
michael@0 515 + int sb = SkGetPackedB32(src);
michael@0 516 + int sa = SkGetPackedA32(src);
michael@0 517 +
michael@0 518 + int dr = SkGetPackedR32(dst);
michael@0 519 + int dg = SkGetPackedG32(dst);
michael@0 520 + int db = SkGetPackedB32(dst);
michael@0 521 + int da = SkGetPackedA32(dst);
michael@0 522 +
michael@0 523 + BlendColor Cs;
michael@0 524 + if(sa) {
michael@0 525 + Cs.r = (float)sr / sa;
michael@0 526 + Cs.g = (float)sg / sa;
michael@0 527 + Cs.b = (float)sb / sa;
michael@0 528 + BlendColor Cd;
michael@0 529 + if(da) {
michael@0 530 + Cd.r = (float)dr / da;
michael@0 531 + Cd.g = (float)dg / da;
michael@0 532 + Cd.b = (float)db / da;
michael@0 533 + Cs = SetLum(SetSat(Cs, Sat(Cd)), Lum(Cd));
michael@0 534 + }
michael@0 535 + }
michael@0 536 +
michael@0 537 + int a = srcover_byte(sa, da);
michael@0 538 + int r = blendfunc_nonsep_byte(sr, dr, sa, da, Cs.r);
michael@0 539 + int g = blendfunc_nonsep_byte(sg, dg, sa, da, Cs.g);
michael@0 540 + int b = blendfunc_nonsep_byte(sb, db, sa, da, Cs.b);
michael@0 541 + return SkPackARGB32(a, r, g, b);
michael@0 542 +}
michael@0 543 +
michael@0 544 +static SkPMColor saturation_modeproc(SkPMColor src, SkPMColor dst) {
michael@0 545 + int sr = SkGetPackedR32(src);
michael@0 546 + int sg = SkGetPackedG32(src);
michael@0 547 + int sb = SkGetPackedB32(src);
michael@0 548 + int sa = SkGetPackedA32(src);
michael@0 549 +
michael@0 550 + int dr = SkGetPackedR32(dst);
michael@0 551 + int dg = SkGetPackedG32(dst);
michael@0 552 + int db = SkGetPackedB32(dst);
michael@0 553 + int da = SkGetPackedA32(dst);
michael@0 554 +
michael@0 555 + BlendColor Cs;
michael@0 556 + if(sa) {
michael@0 557 + Cs.r = (float)sr / sa;
michael@0 558 + Cs.g = (float)sg / sa;
michael@0 559 + Cs.b = (float)sb / sa;
michael@0 560 + BlendColor Cd;
michael@0 561 + if(da) {
michael@0 562 + Cd.r = (float)dr / da;
michael@0 563 + Cd.g = (float)dg / da;
michael@0 564 + Cd.b = (float)db / da;
michael@0 565 + Cs = SetLum(SetSat(Cd, Sat(Cs)), Lum(Cd));
michael@0 566 + }
michael@0 567 + }
michael@0 568 +
michael@0 569 + int a = srcover_byte(sa, da);
michael@0 570 + int r = blendfunc_nonsep_byte(sr, dr, sa, da, Cs.r);
michael@0 571 + int g = blendfunc_nonsep_byte(sg, dg, sa, da, Cs.g);
michael@0 572 + int b = blendfunc_nonsep_byte(sb, db, sa, da, Cs.b);
michael@0 573 + return SkPackARGB32(a, r, g, b);
michael@0 574 +}
michael@0 575 +
michael@0 576 +static SkPMColor color_modeproc(SkPMColor src, SkPMColor dst) {
michael@0 577 + int sr = SkGetPackedR32(src);
michael@0 578 + int sg = SkGetPackedG32(src);
michael@0 579 + int sb = SkGetPackedB32(src);
michael@0 580 + int sa = SkGetPackedA32(src);
michael@0 581 +
michael@0 582 + int dr = SkGetPackedR32(dst);
michael@0 583 + int dg = SkGetPackedG32(dst);
michael@0 584 + int db = SkGetPackedB32(dst);
michael@0 585 + int da = SkGetPackedA32(dst);
michael@0 586 +
michael@0 587 + BlendColor Cs;
michael@0 588 + if(sa) {
michael@0 589 + Cs.r = (float)sr / sa;
michael@0 590 + Cs.g = (float)sg / sa;
michael@0 591 + Cs.b = (float)sb / sa;
michael@0 592 + BlendColor Cd;
michael@0 593 + if(da) {
michael@0 594 + Cd.r = (float)dr / da;
michael@0 595 + Cd.g = (float)dg / da;
michael@0 596 + Cd.b = (float)db / da;
michael@0 597 + Cs = SetLum(Cs, Lum(Cd));
michael@0 598 + }
michael@0 599 + }
michael@0 600 +
michael@0 601 + int a = srcover_byte(sa, da);
michael@0 602 + int r = blendfunc_nonsep_byte(sr, dr, sa, da, Cs.r);
michael@0 603 + int g = blendfunc_nonsep_byte(sg, dg, sa, da, Cs.g);
michael@0 604 + int b = blendfunc_nonsep_byte(sb, db, sa, da, Cs.b);
michael@0 605 + return SkPackARGB32(a, r, g, b);
michael@0 606 +}
michael@0 607 +
michael@0 608 +static SkPMColor luminosity_modeproc(SkPMColor src, SkPMColor dst) {
michael@0 609 + int sr = SkGetPackedR32(src);
michael@0 610 + int sg = SkGetPackedG32(src);
michael@0 611 + int sb = SkGetPackedB32(src);
michael@0 612 + int sa = SkGetPackedA32(src);
michael@0 613 +
michael@0 614 + int dr = SkGetPackedR32(dst);
michael@0 615 + int dg = SkGetPackedG32(dst);
michael@0 616 + int db = SkGetPackedB32(dst);
michael@0 617 + int da = SkGetPackedA32(dst);
michael@0 618 +
michael@0 619 + BlendColor Cs;
michael@0 620 + if(sa) {
michael@0 621 + Cs.r = (float)sr / sa;
michael@0 622 + Cs.g = (float)sg / sa;
michael@0 623 + Cs.b = (float)sb / sa;
michael@0 624 + BlendColor Cd;
michael@0 625 + if(da) {
michael@0 626 + Cd.r = (float)dr / da;
michael@0 627 + Cd.g = (float)dg / da;
michael@0 628 + Cd.b = (float)db / da;
michael@0 629 + Cs = SetLum(Cd, Lum(Cs));
michael@0 630 + }
michael@0 631 + }
michael@0 632 +
michael@0 633 + int a = srcover_byte(sa, da);
michael@0 634 + int r = blendfunc_nonsep_byte(sr, dr, sa, da, Cs.r);
michael@0 635 + int g = blendfunc_nonsep_byte(sg, dg, sa, da, Cs.g);
michael@0 636 + int b = blendfunc_nonsep_byte(sb, db, sa, da, Cs.b);
michael@0 637 return SkPackARGB32(a, r, g, b);
michael@0 638 }
michael@0 639
michael@0 640 struct ProcCoeff {
michael@0 641 SkXfermodeProc fProc;
michael@0 642 SkXfermode::Coeff fSC;
michael@0 643 SkXfermode::Coeff fDC;
michael@0 644 };
michael@0 645 @@ -430,27 +627,31 @@ static const ProcCoeff gProcCoeffs[] = {
michael@0 646 { dstin_modeproc, SkXfermode::kZero_Coeff, SkXfermode::kSA_Coeff },
michael@0 647 { srcout_modeproc, SkXfermode::kIDA_Coeff, SkXfermode::kZero_Coeff },
michael@0 648 { dstout_modeproc, SkXfermode::kZero_Coeff, SkXfermode::kISA_Coeff },
michael@0 649 { srcatop_modeproc, SkXfermode::kDA_Coeff, SkXfermode::kISA_Coeff },
michael@0 650 { dstatop_modeproc, SkXfermode::kIDA_Coeff, SkXfermode::kSA_Coeff },
michael@0 651 { xor_modeproc, SkXfermode::kIDA_Coeff, SkXfermode::kISA_Coeff },
michael@0 652
michael@0 653 { plus_modeproc, SkXfermode::kOne_Coeff, SkXfermode::kOne_Coeff },
michael@0 654 - { multiply_modeproc,SkXfermode::kZero_Coeff, SkXfermode::kSC_Coeff },
michael@0 655 + { multiply_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF},
michael@0 656 { screen_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF },
michael@0 657 { overlay_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF },
michael@0 658 { darken_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF },
michael@0 659 { lighten_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF },
michael@0 660 { colordodge_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF },
michael@0 661 { colorburn_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF },
michael@0 662 { hardlight_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF },
michael@0 663 { softlight_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF },
michael@0 664 { difference_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF },
michael@0 665 { exclusion_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF },
michael@0 666 + { hue_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF },
michael@0 667 + { saturation_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF },
michael@0 668 + { color_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF },
michael@0 669 + { luminosity_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF },
michael@0 670 };
michael@0 671
michael@0 672 ///////////////////////////////////////////////////////////////////////////////
michael@0 673
michael@0 674 bool SkXfermode::asCoeff(Coeff* src, Coeff* dst) {
michael@0 675 return false;
michael@0 676 }
michael@0 677
michael@0 678 @@ -1172,16 +1373,20 @@ static const Proc16Rec gModeProcs16[] =
michael@0 679 { darken_modeproc16_0, darken_modeproc16_255, NULL }, // darken
michael@0 680 { lighten_modeproc16_0, lighten_modeproc16_255, NULL }, // lighten
michael@0 681 { NULL, NULL, NULL }, // colordodge
michael@0 682 { NULL, NULL, NULL }, // colorburn
michael@0 683 { NULL, NULL, NULL }, // hardlight
michael@0 684 { NULL, NULL, NULL }, // softlight
michael@0 685 { NULL, NULL, NULL }, // difference
michael@0 686 { NULL, NULL, NULL }, // exclusion
michael@0 687 + { NULL, NULL, NULL }, // hue
michael@0 688 + { NULL, NULL, NULL }, // saturation
michael@0 689 + { NULL, NULL, NULL }, // color
michael@0 690 + { NULL, NULL, NULL }, // luminosity
michael@0 691 };
michael@0 692
michael@0 693 SkXfermodeProc16 SkXfermode::GetProc16(Mode mode, SkColor srcColor) {
michael@0 694 SkXfermodeProc16 proc16 = NULL;
michael@0 695 if ((unsigned)mode < kModeCount) {
michael@0 696 const Proc16Rec& rec = gModeProcs16[mode];
michael@0 697 unsigned a = SkColorGetA(srcColor);
michael@0 698

mercurial