| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2006 The Android Open Source Project | 2 * Copyright 2006 The Android Open Source Project |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
| 5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
| 6 */ | 6 */ |
| 7 | 7 |
| 8 #include "SkXfermode.h" | 8 #include "SkXfermode.h" |
| 9 #include "SkXfermode_proccoeff.h" | 9 #include "SkXfermode_proccoeff.h" |
| 10 #include "SkColorPriv.h" | 10 #include "SkColorPriv.h" |
| (...skipping 29 matching lines...) Expand all Loading... |
| 40 if (prod <= 0) { | 40 if (prod <= 0) { |
| 41 return 0; | 41 return 0; |
| 42 } else if (prod >= 255*255) { | 42 } else if (prod >= 255*255) { |
| 43 return 255; | 43 return 255; |
| 44 } else { | 44 } else { |
| 45 return SkDiv255Round(prod); | 45 return SkDiv255Round(prod); |
| 46 } | 46 } |
| 47 } | 47 } |
| 48 | 48 |
| 49 /////////////////////////////////////////////////////////////////////////////// | 49 /////////////////////////////////////////////////////////////////////////////// |
| 50 #include "SkNx.h" |
| 51 |
| 52 static Sk4f alpha(const Sk4f& color) { return Sk4f(color.kth<3>()); } |
| 53 static Sk4f inv_alpha(const Sk4f& color) { return Sk4f(1 - color.kth<3>()); } |
| 54 static Sk4f pin_1(const Sk4f& value) { return Sk4f::Min(value, Sk4f(1)); } |
| 55 |
| 56 static Sk4f clear_4f(const Sk4f& s, const Sk4f& d) { return Sk4f(0); } |
| 57 static Sk4f src_4f(const Sk4f& s, const Sk4f& d) { return s; } |
| 58 static Sk4f dst_4f(const Sk4f& s, const Sk4f& d) { return d; } |
| 59 static Sk4f srcover_4f(const Sk4f& s, const Sk4f& d) { return s + inv_alpha(s)
* d; } |
| 60 static Sk4f dstover_4f(const Sk4f& s, const Sk4f& d) { return d + inv_alpha(d)
* s; } |
| 61 static Sk4f srcin_4f(const Sk4f& s, const Sk4f& d) { return s * alpha(d); } |
| 62 static Sk4f dstin_4f(const Sk4f& s, const Sk4f& d) { return d * alpha(s); } |
| 63 static Sk4f srcout_4f(const Sk4f& s, const Sk4f& d) { return s * inv_alpha(d);
} |
| 64 static Sk4f dstout_4f(const Sk4f& s, const Sk4f& d) { return d * inv_alpha(s);
} |
| 65 static Sk4f srcatop_4f(const Sk4f& s, const Sk4f& d) { return s * alpha(d) + d
* inv_alpha(s); } |
| 66 static Sk4f dstatop_4f(const Sk4f& s, const Sk4f& d) { return d * alpha(s) + s
* inv_alpha(d); } |
| 67 static Sk4f xor_4f(const Sk4f& s, const Sk4f& d) { return s * inv_alpha(d)
+ d * inv_alpha(s);} |
| 68 static Sk4f plus_4f(const Sk4f& s, const Sk4f& d) { return pin_1(s + d); } |
| 69 static Sk4f modulate_4f(const Sk4f& s, const Sk4f& d) { return s * d; } |
| 70 static Sk4f screen_4f(const Sk4f& s, const Sk4f& d) { return s + d - s * d; } |
| 71 |
| 72 static Sk4f multiply_4f(const Sk4f& s, const Sk4f& d) { |
| 73 return s * inv_alpha(d) + d * inv_alpha(s) + s * d; |
| 74 } |
| 75 |
| 76 /////////////////////////////////////////////////////////////////////////////// |
| 50 | 77 |
| 78 static SkPM4f as_pm4f(const Sk4f& x) { |
| 79 SkPM4f pm4; |
| 80 x.store(pm4.fVec); |
| 81 return pm4; |
| 82 } |
| 83 |
| 84 static Sk4f as_4f(const SkPM4f& pm4) { |
| 85 return Sk4f::Load(pm4.fVec); |
| 86 } |
| 87 |
| 88 template <Sk4f (blend)(const Sk4f&, const Sk4f&)> |
| 89 SkPM4f proc_4f(const SkPM4f& src, const SkPM4f& dst) { |
| 90 return as_pm4f(blend(as_4f(src), as_4f(dst))); |
| 91 } |
| 92 |
| 93 /////////////////////////////////////////////////////////////////////////////// |
| 94 |
| 95 static SkPM4f not_implemented_yet_proc4f(const SkPM4f& src, const SkPM4f& dst) { |
| 96 return {{ 0.5f, 1.0f, 0.25f, 0.5f }}; |
| 97 } |
| 98 |
| 51 // kClear_Mode, //!< [0, 0] | 99 // kClear_Mode, //!< [0, 0] |
| 52 static SkPMColor clear_modeproc(SkPMColor src, SkPMColor dst) { | 100 static SkPMColor clear_modeproc(SkPMColor src, SkPMColor dst) { |
| 53 return 0; | 101 return 0; |
| 54 } | 102 } |
| 55 | 103 |
| 56 // kSrc_Mode, //!< [Sa, Sc] | 104 // kSrc_Mode, //!< [Sa, Sc] |
| 57 static SkPMColor src_modeproc(SkPMColor src, SkPMColor dst) { | 105 static SkPMColor src_modeproc(SkPMColor src, SkPMColor dst) { |
| 58 return src; | 106 return src; |
| 59 } | 107 } |
| 60 | 108 |
| (...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 212 } | 260 } |
| 213 static SkPMColor overlay_modeproc(SkPMColor src, SkPMColor dst) { | 261 static SkPMColor overlay_modeproc(SkPMColor src, SkPMColor dst) { |
| 214 int sa = SkGetPackedA32(src); | 262 int sa = SkGetPackedA32(src); |
| 215 int da = SkGetPackedA32(dst); | 263 int da = SkGetPackedA32(dst); |
| 216 int a = srcover_byte(sa, da); | 264 int a = srcover_byte(sa, da); |
| 217 int r = overlay_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da); | 265 int r = overlay_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da); |
| 218 int g = overlay_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da); | 266 int g = overlay_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da); |
| 219 int b = overlay_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da); | 267 int b = overlay_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da); |
| 220 return SkPackARGB32(a, r, g, b); | 268 return SkPackARGB32(a, r, g, b); |
| 221 } | 269 } |
| 270 static SkPM4f overlay_proc4f(const SkPM4f& src, const SkPM4f& dst) { |
| 271 return not_implemented_yet_proc4f(src, dst); |
| 272 } |
| 222 | 273 |
| 223 // kDarken_Mode | 274 // kDarken_Mode |
| 224 static inline int darken_byte(int sc, int dc, int sa, int da) { | 275 static inline int darken_byte(int sc, int dc, int sa, int da) { |
| 225 int sd = sc * da; | 276 int sd = sc * da; |
| 226 int ds = dc * sa; | 277 int ds = dc * sa; |
| 227 if (sd < ds) { | 278 if (sd < ds) { |
| 228 // srcover | 279 // srcover |
| 229 return sc + dc - SkDiv255Round(ds); | 280 return sc + dc - SkDiv255Round(ds); |
| 230 } else { | 281 } else { |
| 231 // dstover | 282 // dstover |
| 232 return dc + sc - SkDiv255Round(sd); | 283 return dc + sc - SkDiv255Round(sd); |
| 233 } | 284 } |
| 234 } | 285 } |
| 235 static SkPMColor darken_modeproc(SkPMColor src, SkPMColor dst) { | 286 static SkPMColor darken_modeproc(SkPMColor src, SkPMColor dst) { |
| 236 int sa = SkGetPackedA32(src); | 287 int sa = SkGetPackedA32(src); |
| 237 int da = SkGetPackedA32(dst); | 288 int da = SkGetPackedA32(dst); |
| 238 int a = srcover_byte(sa, da); | 289 int a = srcover_byte(sa, da); |
| 239 int r = darken_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da); | 290 int r = darken_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da); |
| 240 int g = darken_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da); | 291 int g = darken_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da); |
| 241 int b = darken_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da); | 292 int b = darken_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da); |
| 242 return SkPackARGB32(a, r, g, b); | 293 return SkPackARGB32(a, r, g, b); |
| 243 } | 294 } |
| 295 static SkPM4f darken_proc4f(const SkPM4f& src, const SkPM4f& dst) { |
| 296 return not_implemented_yet_proc4f(src, dst); |
| 297 } |
| 244 | 298 |
| 245 // kLighten_Mode | 299 // kLighten_Mode |
| 246 static inline int lighten_byte(int sc, int dc, int sa, int da) { | 300 static inline int lighten_byte(int sc, int dc, int sa, int da) { |
| 247 int sd = sc * da; | 301 int sd = sc * da; |
| 248 int ds = dc * sa; | 302 int ds = dc * sa; |
| 249 if (sd > ds) { | 303 if (sd > ds) { |
| 250 // srcover | 304 // srcover |
| 251 return sc + dc - SkDiv255Round(ds); | 305 return sc + dc - SkDiv255Round(ds); |
| 252 } else { | 306 } else { |
| 253 // dstover | 307 // dstover |
| 254 return dc + sc - SkDiv255Round(sd); | 308 return dc + sc - SkDiv255Round(sd); |
| 255 } | 309 } |
| 256 } | 310 } |
| 257 static SkPMColor lighten_modeproc(SkPMColor src, SkPMColor dst) { | 311 static SkPMColor lighten_modeproc(SkPMColor src, SkPMColor dst) { |
| 258 int sa = SkGetPackedA32(src); | 312 int sa = SkGetPackedA32(src); |
| 259 int da = SkGetPackedA32(dst); | 313 int da = SkGetPackedA32(dst); |
| 260 int a = srcover_byte(sa, da); | 314 int a = srcover_byte(sa, da); |
| 261 int r = lighten_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da); | 315 int r = lighten_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da); |
| 262 int g = lighten_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da); | 316 int g = lighten_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da); |
| 263 int b = lighten_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da); | 317 int b = lighten_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da); |
| 264 return SkPackARGB32(a, r, g, b); | 318 return SkPackARGB32(a, r, g, b); |
| 265 } | 319 } |
| 320 static SkPM4f lighten_proc4f(const SkPM4f& src, const SkPM4f& dst) { |
| 321 return not_implemented_yet_proc4f(src, dst); |
| 322 } |
| 266 | 323 |
| 267 // kColorDodge_Mode | 324 // kColorDodge_Mode |
| 268 static inline int colordodge_byte(int sc, int dc, int sa, int da) { | 325 static inline int colordodge_byte(int sc, int dc, int sa, int da) { |
| 269 int diff = sa - sc; | 326 int diff = sa - sc; |
| 270 int rc; | 327 int rc; |
| 271 if (0 == dc) { | 328 if (0 == dc) { |
| 272 return SkAlphaMulAlpha(sc, 255 - da); | 329 return SkAlphaMulAlpha(sc, 255 - da); |
| 273 } else if (0 == diff) { | 330 } else if (0 == diff) { |
| 274 rc = sa * da + sc * (255 - da) + dc * (255 - sa); | 331 rc = sa * da + sc * (255 - da) + dc * (255 - sa); |
| 275 } else { | 332 } else { |
| 276 diff = dc * sa / diff; | 333 diff = dc * sa / diff; |
| 277 rc = sa * ((da < diff) ? da : diff) + sc * (255 - da) + dc * (255 - sa); | 334 rc = sa * ((da < diff) ? da : diff) + sc * (255 - da) + dc * (255 - sa); |
| 278 } | 335 } |
| 279 return clamp_div255round(rc); | 336 return clamp_div255round(rc); |
| 280 } | 337 } |
| 281 static SkPMColor colordodge_modeproc(SkPMColor src, SkPMColor dst) { | 338 static SkPMColor colordodge_modeproc(SkPMColor src, SkPMColor dst) { |
| 282 int sa = SkGetPackedA32(src); | 339 int sa = SkGetPackedA32(src); |
| 283 int da = SkGetPackedA32(dst); | 340 int da = SkGetPackedA32(dst); |
| 284 int a = srcover_byte(sa, da); | 341 int a = srcover_byte(sa, da); |
| 285 int r = colordodge_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da); | 342 int r = colordodge_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da); |
| 286 int g = colordodge_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da); | 343 int g = colordodge_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da); |
| 287 int b = colordodge_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da); | 344 int b = colordodge_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da); |
| 288 return SkPackARGB32(a, r, g, b); | 345 return SkPackARGB32(a, r, g, b); |
| 289 } | 346 } |
| 347 static SkPM4f colordodge_proc4f(const SkPM4f& src, const SkPM4f& dst) { |
| 348 return not_implemented_yet_proc4f(src, dst); |
| 349 } |
| 290 | 350 |
| 291 // kColorBurn_Mode | 351 // kColorBurn_Mode |
| 292 static inline int colorburn_byte(int sc, int dc, int sa, int da) { | 352 static inline int colorburn_byte(int sc, int dc, int sa, int da) { |
| 293 int rc; | 353 int rc; |
| 294 if (dc == da) { | 354 if (dc == da) { |
| 295 rc = sa * da + sc * (255 - da) + dc * (255 - sa); | 355 rc = sa * da + sc * (255 - da) + dc * (255 - sa); |
| 296 } else if (0 == sc) { | 356 } else if (0 == sc) { |
| 297 return SkAlphaMulAlpha(dc, 255 - sa); | 357 return SkAlphaMulAlpha(dc, 255 - sa); |
| 298 } else { | 358 } else { |
| 299 int tmp = (da - dc) * sa / sc; | 359 int tmp = (da - dc) * sa / sc; |
| 300 rc = sa * (da - ((da < tmp) ? da : tmp)) | 360 rc = sa * (da - ((da < tmp) ? da : tmp)) |
| 301 + sc * (255 - da) + dc * (255 - sa); | 361 + sc * (255 - da) + dc * (255 - sa); |
| 302 } | 362 } |
| 303 return clamp_div255round(rc); | 363 return clamp_div255round(rc); |
| 304 } | 364 } |
| 305 static SkPMColor colorburn_modeproc(SkPMColor src, SkPMColor dst) { | 365 static SkPMColor colorburn_modeproc(SkPMColor src, SkPMColor dst) { |
| 306 int sa = SkGetPackedA32(src); | 366 int sa = SkGetPackedA32(src); |
| 307 int da = SkGetPackedA32(dst); | 367 int da = SkGetPackedA32(dst); |
| 308 int a = srcover_byte(sa, da); | 368 int a = srcover_byte(sa, da); |
| 309 int r = colorburn_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da); | 369 int r = colorburn_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da); |
| 310 int g = colorburn_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da); | 370 int g = colorburn_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da); |
| 311 int b = colorburn_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da); | 371 int b = colorburn_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da); |
| 312 return SkPackARGB32(a, r, g, b); | 372 return SkPackARGB32(a, r, g, b); |
| 313 } | 373 } |
| 374 static SkPM4f colorburn_proc4f(const SkPM4f& src, const SkPM4f& dst) { |
| 375 return not_implemented_yet_proc4f(src, dst); |
| 376 } |
| 314 | 377 |
| 315 // kHardLight_Mode | 378 // kHardLight_Mode |
| 316 static inline int hardlight_byte(int sc, int dc, int sa, int da) { | 379 static inline int hardlight_byte(int sc, int dc, int sa, int da) { |
| 317 int rc; | 380 int rc; |
| 318 if (2 * sc <= sa) { | 381 if (2 * sc <= sa) { |
| 319 rc = 2 * sc * dc; | 382 rc = 2 * sc * dc; |
| 320 } else { | 383 } else { |
| 321 rc = sa * da - 2 * (da - dc) * (sa - sc); | 384 rc = sa * da - 2 * (da - dc) * (sa - sc); |
| 322 } | 385 } |
| 323 return clamp_div255round(rc + sc * (255 - da) + dc * (255 - sa)); | 386 return clamp_div255round(rc + sc * (255 - da) + dc * (255 - sa)); |
| 324 } | 387 } |
| 325 static SkPMColor hardlight_modeproc(SkPMColor src, SkPMColor dst) { | 388 static SkPMColor hardlight_modeproc(SkPMColor src, SkPMColor dst) { |
| 326 int sa = SkGetPackedA32(src); | 389 int sa = SkGetPackedA32(src); |
| 327 int da = SkGetPackedA32(dst); | 390 int da = SkGetPackedA32(dst); |
| 328 int a = srcover_byte(sa, da); | 391 int a = srcover_byte(sa, da); |
| 329 int r = hardlight_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da); | 392 int r = hardlight_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da); |
| 330 int g = hardlight_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da); | 393 int g = hardlight_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da); |
| 331 int b = hardlight_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da); | 394 int b = hardlight_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da); |
| 332 return SkPackARGB32(a, r, g, b); | 395 return SkPackARGB32(a, r, g, b); |
| 333 } | 396 } |
| 397 static SkPM4f hardlight_proc4f(const SkPM4f& src, const SkPM4f& dst) { |
| 398 return not_implemented_yet_proc4f(src, dst); |
| 399 } |
| 334 | 400 |
| 335 // returns 255 * sqrt(n/255) | 401 // returns 255 * sqrt(n/255) |
| 336 static U8CPU sqrt_unit_byte(U8CPU n) { | 402 static U8CPU sqrt_unit_byte(U8CPU n) { |
| 337 return SkSqrtBits(n, 15+4); | 403 return SkSqrtBits(n, 15+4); |
| 338 } | 404 } |
| 339 | 405 |
| 340 // kSoftLight_Mode | 406 // kSoftLight_Mode |
| 341 static inline int softlight_byte(int sc, int dc, int sa, int da) { | 407 static inline int softlight_byte(int sc, int dc, int sa, int da) { |
| 342 int m = da ? dc * 256 / da : 0; | 408 int m = da ? dc * 256 / da : 0; |
| 343 int rc; | 409 int rc; |
| (...skipping 10 matching lines...) Expand all Loading... |
| 354 } | 420 } |
| 355 static SkPMColor softlight_modeproc(SkPMColor src, SkPMColor dst) { | 421 static SkPMColor softlight_modeproc(SkPMColor src, SkPMColor dst) { |
| 356 int sa = SkGetPackedA32(src); | 422 int sa = SkGetPackedA32(src); |
| 357 int da = SkGetPackedA32(dst); | 423 int da = SkGetPackedA32(dst); |
| 358 int a = srcover_byte(sa, da); | 424 int a = srcover_byte(sa, da); |
| 359 int r = softlight_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da); | 425 int r = softlight_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da); |
| 360 int g = softlight_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da); | 426 int g = softlight_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da); |
| 361 int b = softlight_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da); | 427 int b = softlight_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da); |
| 362 return SkPackARGB32(a, r, g, b); | 428 return SkPackARGB32(a, r, g, b); |
| 363 } | 429 } |
| 430 static SkPM4f softlight_proc4f(const SkPM4f& src, const SkPM4f& dst) { |
| 431 return not_implemented_yet_proc4f(src, dst); |
| 432 } |
| 364 | 433 |
| 365 // kDifference_Mode | 434 // kDifference_Mode |
| 366 static inline int difference_byte(int sc, int dc, int sa, int da) { | 435 static inline int difference_byte(int sc, int dc, int sa, int da) { |
| 367 int tmp = SkMin32(sc * da, dc * sa); | 436 int tmp = SkMin32(sc * da, dc * sa); |
| 368 return clamp_signed_byte(sc + dc - 2 * SkDiv255Round(tmp)); | 437 return clamp_signed_byte(sc + dc - 2 * SkDiv255Round(tmp)); |
| 369 } | 438 } |
| 370 static SkPMColor difference_modeproc(SkPMColor src, SkPMColor dst) { | 439 static SkPMColor difference_modeproc(SkPMColor src, SkPMColor dst) { |
| 371 int sa = SkGetPackedA32(src); | 440 int sa = SkGetPackedA32(src); |
| 372 int da = SkGetPackedA32(dst); | 441 int da = SkGetPackedA32(dst); |
| 373 int a = srcover_byte(sa, da); | 442 int a = srcover_byte(sa, da); |
| 374 int r = difference_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da); | 443 int r = difference_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da); |
| 375 int g = difference_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da); | 444 int g = difference_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da); |
| 376 int b = difference_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da); | 445 int b = difference_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da); |
| 377 return SkPackARGB32(a, r, g, b); | 446 return SkPackARGB32(a, r, g, b); |
| 378 } | 447 } |
| 448 static SkPM4f difference_proc4f(const SkPM4f& src, const SkPM4f& dst) { |
| 449 return not_implemented_yet_proc4f(src, dst); |
| 450 } |
| 379 | 451 |
| 380 // kExclusion_Mode | 452 // kExclusion_Mode |
| 381 static inline int exclusion_byte(int sc, int dc, int, int) { | 453 static inline int exclusion_byte(int sc, int dc, int, int) { |
| 382 // this equations is wacky, wait for SVG to confirm it | 454 // this equations is wacky, wait for SVG to confirm it |
| 383 //int r = sc * da + dc * sa - 2 * sc * dc + sc * (255 - da) + dc * (255 - sa
); | 455 //int r = sc * da + dc * sa - 2 * sc * dc + sc * (255 - da) + dc * (255 - sa
); |
| 384 | 456 |
| 385 // The above equation can be simplified as follows | 457 // The above equation can be simplified as follows |
| 386 int r = 255*(sc + dc) - 2 * sc * dc; | 458 int r = 255*(sc + dc) - 2 * sc * dc; |
| 387 return clamp_div255round(r); | 459 return clamp_div255round(r); |
| 388 } | 460 } |
| 389 static SkPMColor exclusion_modeproc(SkPMColor src, SkPMColor dst) { | 461 static SkPMColor exclusion_modeproc(SkPMColor src, SkPMColor dst) { |
| 390 int sa = SkGetPackedA32(src); | 462 int sa = SkGetPackedA32(src); |
| 391 int da = SkGetPackedA32(dst); | 463 int da = SkGetPackedA32(dst); |
| 392 int a = srcover_byte(sa, da); | 464 int a = srcover_byte(sa, da); |
| 393 int r = exclusion_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da); | 465 int r = exclusion_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da); |
| 394 int g = exclusion_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da); | 466 int g = exclusion_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da); |
| 395 int b = exclusion_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da); | 467 int b = exclusion_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da); |
| 396 return SkPackARGB32(a, r, g, b); | 468 return SkPackARGB32(a, r, g, b); |
| 397 } | 469 } |
| 470 static SkPM4f exclusion_proc4f(const SkPM4f& src, const SkPM4f& dst) { |
| 471 return not_implemented_yet_proc4f(src, dst); |
| 472 } |
| 398 | 473 |
| 399 // The CSS compositing spec introduces the following formulas: | 474 // The CSS compositing spec introduces the following formulas: |
| 400 // (See https://dvcs.w3.org/hg/FXTF/rawfile/tip/compositing/index.html#blendingn
onseparable) | 475 // (See https://dvcs.w3.org/hg/FXTF/rawfile/tip/compositing/index.html#blendingn
onseparable) |
| 401 // SkComputeLuminance is similar to this formula but it uses the new definition
from Rec. 709 | 476 // SkComputeLuminance is similar to this formula but it uses the new definition
from Rec. 709 |
| 402 // while PDF and CG uses the one from Rec. Rec. 601 | 477 // while PDF and CG uses the one from Rec. Rec. 601 |
| 403 // See http://www.glennchan.info/articles/technical/hd-versus-sd-color-space/hd-
versus-sd-color-space.htm | 478 // See http://www.glennchan.info/articles/technical/hd-versus-sd-color-space/hd-
versus-sd-color-space.htm |
| 404 static inline int Lum(int r, int g, int b) | 479 static inline int Lum(int r, int g, int b) |
| 405 { | 480 { |
| 406 return SkDiv255Round(r * 77 + g * 150 + b * 28); | 481 return SkDiv255Round(r * 77 + g * 150 + b * 28); |
| 407 } | 482 } |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 503 Sg = 0; | 578 Sg = 0; |
| 504 Sb = 0; | 579 Sb = 0; |
| 505 } | 580 } |
| 506 | 581 |
| 507 int a = srcover_byte(sa, da); | 582 int a = srcover_byte(sa, da); |
| 508 int r = blendfunc_nonsep_byte(sr, dr, sa, da, Sr); | 583 int r = blendfunc_nonsep_byte(sr, dr, sa, da, Sr); |
| 509 int g = blendfunc_nonsep_byte(sg, dg, sa, da, Sg); | 584 int g = blendfunc_nonsep_byte(sg, dg, sa, da, Sg); |
| 510 int b = blendfunc_nonsep_byte(sb, db, sa, da, Sb); | 585 int b = blendfunc_nonsep_byte(sb, db, sa, da, Sb); |
| 511 return SkPackARGB32(a, r, g, b); | 586 return SkPackARGB32(a, r, g, b); |
| 512 } | 587 } |
| 588 static SkPM4f hue_proc4f(const SkPM4f& src, const SkPM4f& dst) { |
| 589 return not_implemented_yet_proc4f(src, dst); |
| 590 } |
| 513 | 591 |
| 514 // kSaturation_Mode | 592 // kSaturation_Mode |
| 515 // B(Cb, Cs) = SetLum(SetSat(Cb, Sat(Cs)), Lum(Cb)) | 593 // B(Cb, Cs) = SetLum(SetSat(Cb, Sat(Cs)), Lum(Cb)) |
| 516 // Create a color with the saturation of the source color and the hue and lumino
sity of the backdrop color. | 594 // Create a color with the saturation of the source color and the hue and lumino
sity of the backdrop color. |
| 517 static SkPMColor saturation_modeproc(SkPMColor src, SkPMColor dst) { | 595 static SkPMColor saturation_modeproc(SkPMColor src, SkPMColor dst) { |
| 518 int sr = SkGetPackedR32(src); | 596 int sr = SkGetPackedR32(src); |
| 519 int sg = SkGetPackedG32(src); | 597 int sg = SkGetPackedG32(src); |
| 520 int sb = SkGetPackedB32(src); | 598 int sb = SkGetPackedB32(src); |
| 521 int sa = SkGetPackedA32(src); | 599 int sa = SkGetPackedA32(src); |
| 522 | 600 |
| (...skipping 14 matching lines...) Expand all Loading... |
| 537 Dg = 0; | 615 Dg = 0; |
| 538 Db = 0; | 616 Db = 0; |
| 539 } | 617 } |
| 540 | 618 |
| 541 int a = srcover_byte(sa, da); | 619 int a = srcover_byte(sa, da); |
| 542 int r = blendfunc_nonsep_byte(sr, dr, sa, da, Dr); | 620 int r = blendfunc_nonsep_byte(sr, dr, sa, da, Dr); |
| 543 int g = blendfunc_nonsep_byte(sg, dg, sa, da, Dg); | 621 int g = blendfunc_nonsep_byte(sg, dg, sa, da, Dg); |
| 544 int b = blendfunc_nonsep_byte(sb, db, sa, da, Db); | 622 int b = blendfunc_nonsep_byte(sb, db, sa, da, Db); |
| 545 return SkPackARGB32(a, r, g, b); | 623 return SkPackARGB32(a, r, g, b); |
| 546 } | 624 } |
| 625 static SkPM4f saturation_proc4f(const SkPM4f& src, const SkPM4f& dst) { |
| 626 return not_implemented_yet_proc4f(src, dst); |
| 627 } |
| 547 | 628 |
| 548 // kColor_Mode | 629 // kColor_Mode |
| 549 // B(Cb, Cs) = SetLum(Cs, Lum(Cb)) | 630 // B(Cb, Cs) = SetLum(Cs, Lum(Cb)) |
| 550 // Create a color with the hue and saturation of the source color and the lumino
sity of the backdrop color. | 631 // Create a color with the hue and saturation of the source color and the lumino
sity of the backdrop color. |
| 551 static SkPMColor color_modeproc(SkPMColor src, SkPMColor dst) { | 632 static SkPMColor color_modeproc(SkPMColor src, SkPMColor dst) { |
| 552 int sr = SkGetPackedR32(src); | 633 int sr = SkGetPackedR32(src); |
| 553 int sg = SkGetPackedG32(src); | 634 int sg = SkGetPackedG32(src); |
| 554 int sb = SkGetPackedB32(src); | 635 int sb = SkGetPackedB32(src); |
| 555 int sa = SkGetPackedA32(src); | 636 int sa = SkGetPackedA32(src); |
| 556 | 637 |
| (...skipping 13 matching lines...) Expand all Loading... |
| 570 Sg = 0; | 651 Sg = 0; |
| 571 Sb = 0; | 652 Sb = 0; |
| 572 } | 653 } |
| 573 | 654 |
| 574 int a = srcover_byte(sa, da); | 655 int a = srcover_byte(sa, da); |
| 575 int r = blendfunc_nonsep_byte(sr, dr, sa, da, Sr); | 656 int r = blendfunc_nonsep_byte(sr, dr, sa, da, Sr); |
| 576 int g = blendfunc_nonsep_byte(sg, dg, sa, da, Sg); | 657 int g = blendfunc_nonsep_byte(sg, dg, sa, da, Sg); |
| 577 int b = blendfunc_nonsep_byte(sb, db, sa, da, Sb); | 658 int b = blendfunc_nonsep_byte(sb, db, sa, da, Sb); |
| 578 return SkPackARGB32(a, r, g, b); | 659 return SkPackARGB32(a, r, g, b); |
| 579 } | 660 } |
| 661 static SkPM4f color_proc4f(const SkPM4f& src, const SkPM4f& dst) { |
| 662 return not_implemented_yet_proc4f(src, dst); |
| 663 } |
| 580 | 664 |
| 581 // kLuminosity_Mode | 665 // kLuminosity_Mode |
| 582 // B(Cb, Cs) = SetLum(Cb, Lum(Cs)) | 666 // B(Cb, Cs) = SetLum(Cb, Lum(Cs)) |
| 583 // Create a color with the luminosity of the source color and the hue and satura
tion of the backdrop color. | 667 // Create a color with the luminosity of the source color and the hue and satura
tion of the backdrop color. |
| 584 static SkPMColor luminosity_modeproc(SkPMColor src, SkPMColor dst) { | 668 static SkPMColor luminosity_modeproc(SkPMColor src, SkPMColor dst) { |
| 585 int sr = SkGetPackedR32(src); | 669 int sr = SkGetPackedR32(src); |
| 586 int sg = SkGetPackedG32(src); | 670 int sg = SkGetPackedG32(src); |
| 587 int sb = SkGetPackedB32(src); | 671 int sb = SkGetPackedB32(src); |
| 588 int sa = SkGetPackedA32(src); | 672 int sa = SkGetPackedA32(src); |
| 589 | 673 |
| (...skipping 13 matching lines...) Expand all Loading... |
| 603 Dg = 0; | 687 Dg = 0; |
| 604 Db = 0; | 688 Db = 0; |
| 605 } | 689 } |
| 606 | 690 |
| 607 int a = srcover_byte(sa, da); | 691 int a = srcover_byte(sa, da); |
| 608 int r = blendfunc_nonsep_byte(sr, dr, sa, da, Dr); | 692 int r = blendfunc_nonsep_byte(sr, dr, sa, da, Dr); |
| 609 int g = blendfunc_nonsep_byte(sg, dg, sa, da, Dg); | 693 int g = blendfunc_nonsep_byte(sg, dg, sa, da, Dg); |
| 610 int b = blendfunc_nonsep_byte(sb, db, sa, da, Db); | 694 int b = blendfunc_nonsep_byte(sb, db, sa, da, Db); |
| 611 return SkPackARGB32(a, r, g, b); | 695 return SkPackARGB32(a, r, g, b); |
| 612 } | 696 } |
| 697 static SkPM4f luminosity_proc4f(const SkPM4f& src, const SkPM4f& dst) { |
| 698 return not_implemented_yet_proc4f(src, dst); |
| 699 } |
| 613 | 700 |
| 614 const ProcCoeff gProcCoeffs[] = { | 701 const ProcCoeff gProcCoeffs[] = { |
| 615 { clear_modeproc, SkXfermode::kZero_Coeff, SkXfermode::kZero_Coeff }, | 702 { clear_modeproc, proc_4f<clear_4f>, SkXfermode::kZero_Coeff,
SkXfermode::kZero_Coeff }, |
| 616 { src_modeproc, SkXfermode::kOne_Coeff, SkXfermode::kZero_Coeff }, | 703 { src_modeproc, proc_4f<src_4f>, SkXfermode::kOne_Coeff,
SkXfermode::kZero_Coeff }, |
| 617 { dst_modeproc, SkXfermode::kZero_Coeff, SkXfermode::kOne_Coeff }, | 704 { dst_modeproc, proc_4f<dst_4f>, SkXfermode::kZero_Coeff,
SkXfermode::kOne_Coeff }, |
| 618 { srcover_modeproc, SkXfermode::kOne_Coeff, SkXfermode::kISA_Coeff }, | 705 { srcover_modeproc, proc_4f<srcover_4f>, SkXfermode::kOne_Coeff,
SkXfermode::kISA_Coeff }, |
| 619 { dstover_modeproc, SkXfermode::kIDA_Coeff, SkXfermode::kOne_Coeff }, | 706 { dstover_modeproc, proc_4f<dstover_4f>, SkXfermode::kIDA_Coeff,
SkXfermode::kOne_Coeff }, |
| 620 { srcin_modeproc, SkXfermode::kDA_Coeff, SkXfermode::kZero_Coeff }, | 707 { srcin_modeproc, proc_4f<srcin_4f>, SkXfermode::kDA_Coeff,
SkXfermode::kZero_Coeff }, |
| 621 { dstin_modeproc, SkXfermode::kZero_Coeff, SkXfermode::kSA_Coeff }, | 708 { dstin_modeproc, proc_4f<dstin_4f>, SkXfermode::kZero_Coeff,
SkXfermode::kSA_Coeff }, |
| 622 { srcout_modeproc, SkXfermode::kIDA_Coeff, SkXfermode::kZero_Coeff }, | 709 { srcout_modeproc, proc_4f<srcout_4f>, SkXfermode::kIDA_Coeff,
SkXfermode::kZero_Coeff }, |
| 623 { dstout_modeproc, SkXfermode::kZero_Coeff, SkXfermode::kISA_Coeff }, | 710 { dstout_modeproc, proc_4f<dstout_4f>, SkXfermode::kZero_Coeff,
SkXfermode::kISA_Coeff }, |
| 624 { srcatop_modeproc, SkXfermode::kDA_Coeff, SkXfermode::kISA_Coeff }, | 711 { srcatop_modeproc, proc_4f<srcatop_4f>, SkXfermode::kDA_Coeff,
SkXfermode::kISA_Coeff }, |
| 625 { dstatop_modeproc, SkXfermode::kIDA_Coeff, SkXfermode::kSA_Coeff }, | 712 { dstatop_modeproc, proc_4f<dstatop_4f>, SkXfermode::kIDA_Coeff,
SkXfermode::kSA_Coeff }, |
| 626 { xor_modeproc, SkXfermode::kIDA_Coeff, SkXfermode::kISA_Coeff }, | 713 { xor_modeproc, proc_4f<xor_4f>, SkXfermode::kIDA_Coeff,
SkXfermode::kISA_Coeff }, |
| 627 | 714 |
| 628 { plus_modeproc, SkXfermode::kOne_Coeff, SkXfermode::kOne_Coeff }, | 715 { plus_modeproc, proc_4f<plus_4f>, SkXfermode::kOne_Coeff,
SkXfermode::kOne_Coeff }, |
| 629 { modulate_modeproc,SkXfermode::kZero_Coeff, SkXfermode::kSC_Coeff }, | 716 { modulate_modeproc, proc_4f<modulate_4f>, SkXfermode::kZero_Coeff,
SkXfermode::kSC_Coeff }, |
| 630 { screen_modeproc, SkXfermode::kOne_Coeff, SkXfermode::kISC_Coeff }, | 717 { screen_modeproc, proc_4f<screen_4f>, SkXfermode::kOne_Coeff,
SkXfermode::kISC_Coeff }, |
| 631 { overlay_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF }, | 718 { overlay_modeproc, overlay_proc4f, CANNOT_USE_COEFF, CANNOT_USE
_COEFF }, |
| 632 { darken_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF }, | 719 { darken_modeproc, darken_proc4f, CANNOT_USE_COEFF, CANNOT_USE_
COEFF }, |
| 633 { lighten_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF }, | 720 { lighten_modeproc, lighten_proc4f, CANNOT_USE_COEFF, CANNOT_USE
_COEFF }, |
| 634 { colordodge_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF }, | 721 { colordodge_modeproc, colordodge_proc4f, CANNOT_USE_COEFF, CANNOT_
USE_COEFF }, |
| 635 { colorburn_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF }, | 722 { colorburn_modeproc, colorburn_proc4f, CANNOT_USE_COEFF, CANNOT_U
SE_COEFF }, |
| 636 { hardlight_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF }, | 723 { hardlight_modeproc, hardlight_proc4f, CANNOT_USE_COEFF, CANNOT_U
SE_COEFF }, |
| 637 { softlight_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF }, | 724 { softlight_modeproc, softlight_proc4f, CANNOT_USE_COEFF, CANNOT_U
SE_COEFF }, |
| 638 { difference_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF }, | 725 { difference_modeproc, difference_proc4f, CANNOT_USE_COEFF, CANNOT_
USE_COEFF }, |
| 639 { exclusion_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF }, | 726 { exclusion_modeproc, exclusion_proc4f, CANNOT_USE_COEFF, CANNOT_U
SE_COEFF }, |
| 640 { multiply_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF }, | 727 { multiply_modeproc, proc_4f<multiply_4f>, CANNOT_USE_COEFF, CANN
OT_USE_COEFF }, |
| 641 { hue_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF }, | 728 { hue_modeproc, hue_proc4f, CANNOT_USE_COEFF, CANNOT_USE_COE
FF }, |
| 642 { saturation_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF }, | 729 { saturation_modeproc, saturation_proc4f, CANNOT_USE_COEFF, CANNOT_
USE_COEFF }, |
| 643 { color_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF }, | 730 { color_modeproc, color_proc4f, CANNOT_USE_COEFF, CANNOT_USE_C
OEFF }, |
| 644 { luminosity_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF }, | 731 { luminosity_modeproc, luminosity_proc4f, CANNOT_USE_COEFF, CANNOT_
USE_COEFF }, |
| 645 }; | 732 }; |
| 646 | 733 |
| 647 /////////////////////////////////////////////////////////////////////////////// | 734 /////////////////////////////////////////////////////////////////////////////// |
| 648 | 735 |
| 649 bool SkXfermode::asMode(Mode* mode) const { | 736 bool SkXfermode::asMode(Mode* mode) const { |
| 650 return false; | 737 return false; |
| 651 } | 738 } |
| 652 | 739 |
| 653 bool SkXfermode::asFragmentProcessor(const GrFragmentProcessor**, | 740 bool SkXfermode::asFragmentProcessor(const GrFragmentProcessor**, |
| 654 const GrFragmentProcessor*) const { | 741 const GrFragmentProcessor*) const { |
| (...skipping 344 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 999 } | 1086 } |
| 1000 | 1087 |
| 1001 SkXfermodeProc SkXfermode::GetProc(Mode mode) { | 1088 SkXfermodeProc SkXfermode::GetProc(Mode mode) { |
| 1002 SkXfermodeProc proc = nullptr; | 1089 SkXfermodeProc proc = nullptr; |
| 1003 if ((unsigned)mode < kModeCount) { | 1090 if ((unsigned)mode < kModeCount) { |
| 1004 proc = gProcCoeffs[mode].fProc; | 1091 proc = gProcCoeffs[mode].fProc; |
| 1005 } | 1092 } |
| 1006 return proc; | 1093 return proc; |
| 1007 } | 1094 } |
| 1008 | 1095 |
| 1096 SkXfermodeProc4f SkXfermode::GetProc4f(Mode mode) { |
| 1097 SkXfermodeProc4f proc = nullptr; |
| 1098 if ((unsigned)mode < kModeCount) { |
| 1099 proc = gProcCoeffs[mode].fProc4f; |
| 1100 } |
| 1101 return proc; |
| 1102 } |
| 1103 |
| 1009 bool SkXfermode::ModeAsCoeff(Mode mode, Coeff* src, Coeff* dst) { | 1104 bool SkXfermode::ModeAsCoeff(Mode mode, Coeff* src, Coeff* dst) { |
| 1010 SkASSERT(SK_ARRAY_COUNT(gProcCoeffs) == kModeCount); | 1105 SkASSERT(SK_ARRAY_COUNT(gProcCoeffs) == kModeCount); |
| 1011 | 1106 |
| 1012 if ((unsigned)mode >= (unsigned)kModeCount) { | 1107 if ((unsigned)mode >= (unsigned)kModeCount) { |
| 1013 // illegal mode parameter | 1108 // illegal mode parameter |
| 1014 return false; | 1109 return false; |
| 1015 } | 1110 } |
| 1016 | 1111 |
| 1017 const ProcCoeff& rec = gProcCoeffs[mode]; | 1112 const ProcCoeff& rec = gProcCoeffs[mode]; |
| 1018 | 1113 |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1063 if (!xfer) { | 1158 if (!xfer) { |
| 1064 return SkXfermode::kOpaque_SrcColorOpacity == opacityType; | 1159 return SkXfermode::kOpaque_SrcColorOpacity == opacityType; |
| 1065 } | 1160 } |
| 1066 | 1161 |
| 1067 return xfer->isOpaque(opacityType); | 1162 return xfer->isOpaque(opacityType); |
| 1068 } | 1163 } |
| 1069 | 1164 |
| 1070 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkXfermode) | 1165 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkXfermode) |
| 1071 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkProcCoeffXfermode) | 1166 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkProcCoeffXfermode) |
| 1072 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END | 1167 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END |
| OLD | NEW |