SkXfermode.cpp revision e2022cc36e47b9f0d219eb5cd24be61772c28d3b
1 2/* 3 * Copyright 2006 The Android Open Source Project 4 * 5 * Use of this source code is governed by a BSD-style license that can be 6 * found in the LICENSE file. 7 */ 8 9 10#include "SkXfermode.h" 11#include "SkColorPriv.h" 12#include "SkFlattenableBuffers.h" 13#include "SkMathPriv.h" 14#include "SkString.h" 15 16SK_DEFINE_INST_COUNT(SkXfermode) 17 18#define SkAlphaMulAlpha(a, b) SkMulDiv255Round(a, b) 19 20#if 0 21// idea for higher precision blends in xfer procs (and slightly faster) 22// see DstATop as a probable caller 23static U8CPU mulmuldiv255round(U8CPU a, U8CPU b, U8CPU c, U8CPU d) { 24 SkASSERT(a <= 255); 25 SkASSERT(b <= 255); 26 SkASSERT(c <= 255); 27 SkASSERT(d <= 255); 28 unsigned prod = SkMulS16(a, b) + SkMulS16(c, d) + 128; 29 unsigned result = (prod + (prod >> 8)) >> 8; 30 SkASSERT(result <= 255); 31 return result; 32} 33#endif 34 35static inline unsigned saturated_add(unsigned a, unsigned b) { 36 SkASSERT(a <= 255); 37 SkASSERT(b <= 255); 38 unsigned sum = a + b; 39 if (sum > 255) { 40 sum = 255; 41 } 42 return sum; 43} 44 45static inline int clamp_signed_byte(int n) { 46 if (n < 0) { 47 n = 0; 48 } else if (n > 255) { 49 n = 255; 50 } 51 return n; 52} 53 54static inline int clamp_div255round(int prod) { 55 if (prod <= 0) { 56 return 0; 57 } else if (prod >= 255*255) { 58 return 255; 59 } else { 60 return SkDiv255Round(prod); 61 } 62} 63 64static inline int clamp_max(int value, int max) { 65 if (value > max) { 66 value = max; 67 } 68 return value; 69} 70 71/////////////////////////////////////////////////////////////////////////////// 72 73// kClear_Mode, //!< [0, 0] 74static SkPMColor clear_modeproc(SkPMColor src, SkPMColor dst) { 75 return 0; 76} 77 78// kSrc_Mode, //!< [Sa, Sc] 79static SkPMColor src_modeproc(SkPMColor src, SkPMColor dst) { 80 return src; 81} 82 83// kDst_Mode, //!< [Da, Dc] 84static SkPMColor dst_modeproc(SkPMColor src, SkPMColor dst) { 85 return dst; 86} 87 88// kSrcOver_Mode, //!< [Sa + Da - Sa*Da, Sc + (1 - Sa)*Dc] 89static SkPMColor srcover_modeproc(SkPMColor src, SkPMColor dst) { 90#if 0 91 // this is the old, more-correct way, but it doesn't guarantee that dst==255 92 // will always stay opaque 93 return src + SkAlphaMulQ(dst, SkAlpha255To256(255 - SkGetPackedA32(src))); 94#else 95 // this is slightly faster, but more importantly guarantees that dst==255 96 // will always stay opaque 97 return src + SkAlphaMulQ(dst, 256 - SkGetPackedA32(src)); 98#endif 99} 100 101// kDstOver_Mode, //!< [Sa + Da - Sa*Da, Dc + (1 - Da)*Sc] 102static SkPMColor dstover_modeproc(SkPMColor src, SkPMColor dst) { 103 // this is the reverse of srcover, just flipping src and dst 104 // see srcover's comment about the 256 for opaqueness guarantees 105 return dst + SkAlphaMulQ(src, 256 - SkGetPackedA32(dst)); 106} 107 108// kSrcIn_Mode, //!< [Sa * Da, Sc * Da] 109static SkPMColor srcin_modeproc(SkPMColor src, SkPMColor dst) { 110 return SkAlphaMulQ(src, SkAlpha255To256(SkGetPackedA32(dst))); 111} 112 113// kDstIn_Mode, //!< [Sa * Da, Sa * Dc] 114static SkPMColor dstin_modeproc(SkPMColor src, SkPMColor dst) { 115 return SkAlphaMulQ(dst, SkAlpha255To256(SkGetPackedA32(src))); 116} 117 118// kSrcOut_Mode, //!< [Sa * (1 - Da), Sc * (1 - Da)] 119static SkPMColor srcout_modeproc(SkPMColor src, SkPMColor dst) { 120 return SkAlphaMulQ(src, SkAlpha255To256(255 - SkGetPackedA32(dst))); 121} 122 123// kDstOut_Mode, //!< [Da * (1 - Sa), Dc * (1 - Sa)] 124static SkPMColor dstout_modeproc(SkPMColor src, SkPMColor dst) { 125 return SkAlphaMulQ(dst, SkAlpha255To256(255 - SkGetPackedA32(src))); 126} 127 128// kSrcATop_Mode, //!< [Da, Sc * Da + (1 - Sa) * Dc] 129static SkPMColor srcatop_modeproc(SkPMColor src, SkPMColor dst) { 130 unsigned sa = SkGetPackedA32(src); 131 unsigned da = SkGetPackedA32(dst); 132 unsigned isa = 255 - sa; 133 134 return SkPackARGB32(da, 135 SkAlphaMulAlpha(da, SkGetPackedR32(src)) + 136 SkAlphaMulAlpha(isa, SkGetPackedR32(dst)), 137 SkAlphaMulAlpha(da, SkGetPackedG32(src)) + 138 SkAlphaMulAlpha(isa, SkGetPackedG32(dst)), 139 SkAlphaMulAlpha(da, SkGetPackedB32(src)) + 140 SkAlphaMulAlpha(isa, SkGetPackedB32(dst))); 141} 142 143// kDstATop_Mode, //!< [Sa, Sa * Dc + Sc * (1 - Da)] 144static SkPMColor dstatop_modeproc(SkPMColor src, SkPMColor dst) { 145 unsigned sa = SkGetPackedA32(src); 146 unsigned da = SkGetPackedA32(dst); 147 unsigned ida = 255 - da; 148 149 return SkPackARGB32(sa, 150 SkAlphaMulAlpha(ida, SkGetPackedR32(src)) + 151 SkAlphaMulAlpha(sa, SkGetPackedR32(dst)), 152 SkAlphaMulAlpha(ida, SkGetPackedG32(src)) + 153 SkAlphaMulAlpha(sa, SkGetPackedG32(dst)), 154 SkAlphaMulAlpha(ida, SkGetPackedB32(src)) + 155 SkAlphaMulAlpha(sa, SkGetPackedB32(dst))); 156} 157 158// kXor_Mode [Sa + Da - 2 * Sa * Da, Sc * (1 - Da) + (1 - Sa) * Dc] 159static SkPMColor xor_modeproc(SkPMColor src, SkPMColor dst) { 160 unsigned sa = SkGetPackedA32(src); 161 unsigned da = SkGetPackedA32(dst); 162 unsigned isa = 255 - sa; 163 unsigned ida = 255 - da; 164 165 return SkPackARGB32(sa + da - (SkAlphaMulAlpha(sa, da) << 1), 166 SkAlphaMulAlpha(ida, SkGetPackedR32(src)) + 167 SkAlphaMulAlpha(isa, SkGetPackedR32(dst)), 168 SkAlphaMulAlpha(ida, SkGetPackedG32(src)) + 169 SkAlphaMulAlpha(isa, SkGetPackedG32(dst)), 170 SkAlphaMulAlpha(ida, SkGetPackedB32(src)) + 171 SkAlphaMulAlpha(isa, SkGetPackedB32(dst))); 172} 173 174/////////////////////////////////////////////////////////////////////////////// 175 176// kPlus_Mode 177static SkPMColor plus_modeproc(SkPMColor src, SkPMColor dst) { 178 unsigned b = saturated_add(SkGetPackedB32(src), SkGetPackedB32(dst)); 179 unsigned g = saturated_add(SkGetPackedG32(src), SkGetPackedG32(dst)); 180 unsigned r = saturated_add(SkGetPackedR32(src), SkGetPackedR32(dst)); 181 unsigned a = saturated_add(SkGetPackedA32(src), SkGetPackedA32(dst)); 182 return SkPackARGB32(a, r, g, b); 183} 184 185// kModulate_Mode 186static SkPMColor modulate_modeproc(SkPMColor src, SkPMColor dst) { 187 int a = SkAlphaMulAlpha(SkGetPackedA32(src), SkGetPackedA32(dst)); 188 int r = SkAlphaMulAlpha(SkGetPackedR32(src), SkGetPackedR32(dst)); 189 int g = SkAlphaMulAlpha(SkGetPackedG32(src), SkGetPackedG32(dst)); 190 int b = SkAlphaMulAlpha(SkGetPackedB32(src), SkGetPackedB32(dst)); 191 return SkPackARGB32(a, r, g, b); 192} 193 194static inline int srcover_byte(int a, int b) { 195 return a + b - SkAlphaMulAlpha(a, b); 196} 197 198// kMultiply_Mode 199// B(Cb, Cs) = Cb x Cs 200// multiply uses its own version of blendfunc_byte because sa and da are not needed 201static int blendfunc_multiply_byte(int sc, int dc, int sa, int da) { 202 return clamp_div255round(sc * (255 - da) + dc * (255 - sa) + sc * dc); 203} 204 205static SkPMColor multiply_modeproc(SkPMColor src, SkPMColor dst) { 206 int sa = SkGetPackedA32(src); 207 int da = SkGetPackedA32(dst); 208 int a = srcover_byte(sa, da); 209 int r = blendfunc_multiply_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da); 210 int g = blendfunc_multiply_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da); 211 int b = blendfunc_multiply_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da); 212 return SkPackARGB32(a, r, g, b); 213} 214 215// kScreen_Mode 216static SkPMColor screen_modeproc(SkPMColor src, SkPMColor dst) { 217 int a = srcover_byte(SkGetPackedA32(src), SkGetPackedA32(dst)); 218 int r = srcover_byte(SkGetPackedR32(src), SkGetPackedR32(dst)); 219 int g = srcover_byte(SkGetPackedG32(src), SkGetPackedG32(dst)); 220 int b = srcover_byte(SkGetPackedB32(src), SkGetPackedB32(dst)); 221 return SkPackARGB32(a, r, g, b); 222} 223 224// kOverlay_Mode 225static inline int overlay_byte(int sc, int dc, int sa, int da) { 226 int tmp = sc * (255 - da) + dc * (255 - sa); 227 int rc; 228 if (2 * dc <= da) { 229 rc = 2 * sc * dc; 230 } else { 231 rc = sa * da - 2 * (da - dc) * (sa - sc); 232 } 233 return clamp_div255round(rc + tmp); 234} 235static SkPMColor overlay_modeproc(SkPMColor src, SkPMColor dst) { 236 int sa = SkGetPackedA32(src); 237 int da = SkGetPackedA32(dst); 238 int a = srcover_byte(sa, da); 239 int r = overlay_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da); 240 int g = overlay_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da); 241 int b = overlay_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da); 242 return SkPackARGB32(a, r, g, b); 243} 244 245// kDarken_Mode 246static inline int darken_byte(int sc, int dc, int sa, int da) { 247 int sd = sc * da; 248 int ds = dc * sa; 249 if (sd < ds) { 250 // srcover 251 return sc + dc - SkDiv255Round(ds); 252 } else { 253 // dstover 254 return dc + sc - SkDiv255Round(sd); 255 } 256} 257static SkPMColor darken_modeproc(SkPMColor src, SkPMColor dst) { 258 int sa = SkGetPackedA32(src); 259 int da = SkGetPackedA32(dst); 260 int a = srcover_byte(sa, da); 261 int r = darken_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da); 262 int g = darken_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da); 263 int b = darken_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da); 264 return SkPackARGB32(a, r, g, b); 265} 266 267// kLighten_Mode 268static inline int lighten_byte(int sc, int dc, int sa, int da) { 269 int sd = sc * da; 270 int ds = dc * sa; 271 if (sd > ds) { 272 // srcover 273 return sc + dc - SkDiv255Round(ds); 274 } else { 275 // dstover 276 return dc + sc - SkDiv255Round(sd); 277 } 278} 279static SkPMColor lighten_modeproc(SkPMColor src, SkPMColor dst) { 280 int sa = SkGetPackedA32(src); 281 int da = SkGetPackedA32(dst); 282 int a = srcover_byte(sa, da); 283 int r = lighten_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da); 284 int g = lighten_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da); 285 int b = lighten_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da); 286 return SkPackARGB32(a, r, g, b); 287} 288 289// kColorDodge_Mode 290static inline int colordodge_byte(int sc, int dc, int sa, int da) { 291 int diff = sa - sc; 292 int rc; 293 if (0 == dc) { 294 return SkAlphaMulAlpha(sc, 255 - da); 295 } else if (0 == diff) { 296 rc = sa * da + sc * (255 - da) + dc * (255 - sa); 297 } else { 298 diff = dc * sa / diff; 299 rc = sa * ((da < diff) ? da : diff) + sc * (255 - da) + dc * (255 - sa); 300 } 301 return clamp_div255round(rc); 302} 303static SkPMColor colordodge_modeproc(SkPMColor src, SkPMColor dst) { 304 int sa = SkGetPackedA32(src); 305 int da = SkGetPackedA32(dst); 306 int a = srcover_byte(sa, da); 307 int r = colordodge_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da); 308 int g = colordodge_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da); 309 int b = colordodge_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da); 310 return SkPackARGB32(a, r, g, b); 311} 312 313// kColorBurn_Mode 314static inline int colorburn_byte(int sc, int dc, int sa, int da) { 315 int rc; 316 if (dc == da) { 317 rc = sa * da + sc * (255 - da) + dc * (255 - sa); 318 } else if (0 == sc) { 319 return SkAlphaMulAlpha(dc, 255 - sa); 320 } else { 321 int tmp = (da - dc) * sa / sc; 322 rc = sa * (da - ((da < tmp) ? da : tmp)) 323 + sc * (255 - da) + dc * (255 - sa); 324 } 325 return clamp_div255round(rc); 326} 327static SkPMColor colorburn_modeproc(SkPMColor src, SkPMColor dst) { 328 int sa = SkGetPackedA32(src); 329 int da = SkGetPackedA32(dst); 330 int a = srcover_byte(sa, da); 331 int r = colorburn_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da); 332 int g = colorburn_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da); 333 int b = colorburn_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da); 334 return SkPackARGB32(a, r, g, b); 335} 336 337// kHardLight_Mode 338static inline int hardlight_byte(int sc, int dc, int sa, int da) { 339 int rc; 340 if (2 * sc <= sa) { 341 rc = 2 * sc * dc; 342 } else { 343 rc = sa * da - 2 * (da - dc) * (sa - sc); 344 } 345 return clamp_div255round(rc + sc * (255 - da) + dc * (255 - sa)); 346} 347static SkPMColor hardlight_modeproc(SkPMColor src, SkPMColor dst) { 348 int sa = SkGetPackedA32(src); 349 int da = SkGetPackedA32(dst); 350 int a = srcover_byte(sa, da); 351 int r = hardlight_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da); 352 int g = hardlight_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da); 353 int b = hardlight_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da); 354 return SkPackARGB32(a, r, g, b); 355} 356 357// returns 255 * sqrt(n/255) 358static U8CPU sqrt_unit_byte(U8CPU n) { 359 return SkSqrtBits(n, 15+4); 360} 361 362// kSoftLight_Mode 363static inline int softlight_byte(int sc, int dc, int sa, int da) { 364 int m = da ? dc * 256 / da : 0; 365 int rc; 366 if (2 * sc <= sa) { 367 rc = dc * (sa + ((2 * sc - sa) * (256 - m) >> 8)); 368 } else if (4 * dc <= da) { 369 int tmp = (4 * m * (4 * m + 256) * (m - 256) >> 16) + 7 * m; 370 rc = dc * sa + (da * (2 * sc - sa) * tmp >> 8); 371 } else { 372 int tmp = sqrt_unit_byte(m) - m; 373 rc = dc * sa + (da * (2 * sc - sa) * tmp >> 8); 374 } 375 return clamp_div255round(rc + sc * (255 - da) + dc * (255 - sa)); 376} 377static SkPMColor softlight_modeproc(SkPMColor src, SkPMColor dst) { 378 int sa = SkGetPackedA32(src); 379 int da = SkGetPackedA32(dst); 380 int a = srcover_byte(sa, da); 381 int r = softlight_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da); 382 int g = softlight_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da); 383 int b = softlight_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da); 384 return SkPackARGB32(a, r, g, b); 385} 386 387// kDifference_Mode 388static inline int difference_byte(int sc, int dc, int sa, int da) { 389 int tmp = SkMin32(sc * da, dc * sa); 390 return clamp_signed_byte(sc + dc - 2 * SkDiv255Round(tmp)); 391} 392static SkPMColor difference_modeproc(SkPMColor src, SkPMColor dst) { 393 int sa = SkGetPackedA32(src); 394 int da = SkGetPackedA32(dst); 395 int a = srcover_byte(sa, da); 396 int r = difference_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da); 397 int g = difference_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da); 398 int b = difference_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da); 399 return SkPackARGB32(a, r, g, b); 400} 401 402// kExclusion_Mode 403static inline int exclusion_byte(int sc, int dc, int sa, int da) { 404 // this equations is wacky, wait for SVG to confirm it 405 int r = sc * da + dc * sa - 2 * sc * dc + sc * (255 - da) + dc * (255 - sa); 406 return clamp_div255round(r); 407} 408static SkPMColor exclusion_modeproc(SkPMColor src, SkPMColor dst) { 409 int sa = SkGetPackedA32(src); 410 int da = SkGetPackedA32(dst); 411 int a = srcover_byte(sa, da); 412 int r = exclusion_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da); 413 int g = exclusion_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da); 414 int b = exclusion_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da); 415 return SkPackARGB32(a, r, g, b); 416} 417 418// The CSS compositing spec introduces the following formulas: 419// (See https://dvcs.w3.org/hg/FXTF/rawfile/tip/compositing/index.html#blendingnonseparable) 420// SkComputeLuminance is similar to this formula but it uses the new definition from Rec. 709 421// while PDF and CG uses the one from Rec. Rec. 601 422// See http://www.glennchan.info/articles/technical/hd-versus-sd-color-space/hd-versus-sd-color-space.htm 423static inline int Lum(int r, int g, int b) 424{ 425 return SkDiv255Round(r * 77 + g * 150 + b * 28); 426} 427 428static inline int min2(int a, int b) { return a < b ? a : b; } 429static inline int max2(int a, int b) { return a > b ? a : b; } 430#define minimum(a, b, c) min2(min2(a, b), c) 431#define maximum(a, b, c) max2(max2(a, b), c) 432 433static inline int Sat(int r, int g, int b) { 434 return maximum(r, g, b) - minimum(r, g, b); 435} 436 437static inline void setSaturationComponents(int* Cmin, int* Cmid, int* Cmax, int s) { 438 if(*Cmax > *Cmin) { 439 *Cmid = SkMulDiv(*Cmid - *Cmin, s, *Cmax - *Cmin); 440 *Cmax = s; 441 } else { 442 *Cmax = 0; 443 *Cmid = 0; 444 } 445 446 *Cmin = 0; 447} 448 449static inline void SetSat(int* r, int* g, int* b, int s) { 450 if(*r <= *g) { 451 if(*g <= *b) { 452 setSaturationComponents(r, g, b, s); 453 } else if(*r <= *b) { 454 setSaturationComponents(r, b, g, s); 455 } else { 456 setSaturationComponents(b, r, g, s); 457 } 458 } else if(*r <= *b) { 459 setSaturationComponents(g, r, b, s); 460 } else if(*g <= *b) { 461 setSaturationComponents(g, b, r, s); 462 } else { 463 setSaturationComponents(b, g, r, s); 464 } 465} 466 467static inline void clipColor(int* r, int* g, int* b, int a) { 468 int L = Lum(*r, *g, *b); 469 int n = minimum(*r, *g, *b); 470 int x = maximum(*r, *g, *b); 471 if(n < 0) { 472 *r = L + SkMulDiv(*r - L, L, L - n); 473 *g = L + SkMulDiv(*g - L, L, L - n); 474 *b = L + SkMulDiv(*b - L, L, L - n); 475 } 476 477 if (x > a) { 478 *r = L + SkMulDiv(*r - L, a - L, x - L); 479 *g = L + SkMulDiv(*g - L, a - L, x - L); 480 *b = L + SkMulDiv(*b - L, a - L, x - L); 481 } 482} 483 484static inline void SetLum(int* r, int* g, int* b, int a, int l) { 485 int d = l - Lum(*r, *g, *b); 486 *r += d; 487 *g += d; 488 *b += d; 489 490 clipColor(r, g, b, a); 491} 492 493// non-separable blend modes are done in non-premultiplied alpha 494#define blendfunc_nonsep_byte(sc, dc, sa, da, blendval) \ 495 clamp_div255round(sc * (255 - da) + dc * (255 - sa) + blendval) 496 497// kHue_Mode 498// B(Cb, Cs) = SetLum(SetSat(Cs, Sat(Cb)), Lum(Cb)) 499// Create a color with the hue of the source color and the saturation and luminosity of the backdrop color. 500static SkPMColor hue_modeproc(SkPMColor src, SkPMColor dst) { 501 int sr = SkGetPackedR32(src); 502 int sg = SkGetPackedG32(src); 503 int sb = SkGetPackedB32(src); 504 int sa = SkGetPackedA32(src); 505 506 int dr = SkGetPackedR32(dst); 507 int dg = SkGetPackedG32(dst); 508 int db = SkGetPackedB32(dst); 509 int da = SkGetPackedA32(dst); 510 int Sr, Sg, Sb; 511 512 if(sa && da) { 513 Sr = sr * sa; 514 Sg = sg * sa; 515 Sb = sb * sa; 516 SetSat(&Sr, &Sg, &Sb, Sat(dr, dg, db) * sa); 517 SetLum(&Sr, &Sg, &Sb, sa * da, Lum(dr, dg, db) * sa); 518 } else { 519 Sr = 0; 520 Sg = 0; 521 Sb = 0; 522 } 523 524 int a = srcover_byte(sa, da); 525 int r = blendfunc_nonsep_byte(sr, dr, sa, da, Sr); 526 int g = blendfunc_nonsep_byte(sg, dg, sa, da, Sg); 527 int b = blendfunc_nonsep_byte(sb, db, sa, da, Sb); 528 return SkPackARGB32(a, r, g, b); 529} 530 531// kSaturation_Mode 532// B(Cb, Cs) = SetLum(SetSat(Cb, Sat(Cs)), Lum(Cb)) 533// Create a color with the saturation of the source color and the hue and luminosity of the backdrop color. 534static SkPMColor saturation_modeproc(SkPMColor src, SkPMColor dst) { 535 int sr = SkGetPackedR32(src); 536 int sg = SkGetPackedG32(src); 537 int sb = SkGetPackedB32(src); 538 int sa = SkGetPackedA32(src); 539 540 int dr = SkGetPackedR32(dst); 541 int dg = SkGetPackedG32(dst); 542 int db = SkGetPackedB32(dst); 543 int da = SkGetPackedA32(dst); 544 int Dr, Dg, Db; 545 546 if(sa && da) { 547 Dr = dr * sa; 548 Dg = dg * sa; 549 Db = db * sa; 550 SetSat(&Dr, &Dg, &Db, Sat(sr, sg, sb) * da); 551 SetLum(&Dr, &Dg, &Db, sa * da, Lum(dr, dg, db) * sa); 552 } else { 553 Dr = 0; 554 Dg = 0; 555 Db = 0; 556 } 557 558 int a = srcover_byte(sa, da); 559 int r = blendfunc_nonsep_byte(sr, dr, sa, da, Dr); 560 int g = blendfunc_nonsep_byte(sg, dg, sa, da, Dg); 561 int b = blendfunc_nonsep_byte(sb, db, sa, da, Db); 562 return SkPackARGB32(a, r, g, b); 563} 564 565// kColor_Mode 566// B(Cb, Cs) = SetLum(Cs, Lum(Cb)) 567// Create a color with the hue and saturation of the source color and the luminosity of the backdrop color. 568static SkPMColor color_modeproc(SkPMColor src, SkPMColor dst) { 569 int sr = SkGetPackedR32(src); 570 int sg = SkGetPackedG32(src); 571 int sb = SkGetPackedB32(src); 572 int sa = SkGetPackedA32(src); 573 574 int dr = SkGetPackedR32(dst); 575 int dg = SkGetPackedG32(dst); 576 int db = SkGetPackedB32(dst); 577 int da = SkGetPackedA32(dst); 578 int Sr, Sg, Sb; 579 580 if(sa && da) { 581 Sr = sr * da; 582 Sg = sg * da; 583 Sb = sb * da; 584 SetLum(&Sr, &Sg, &Sb, sa * da, Lum(dr, dg, db) * sa); 585 } else { 586 Sr = 0; 587 Sg = 0; 588 Sb = 0; 589 } 590 591 int a = srcover_byte(sa, da); 592 int r = blendfunc_nonsep_byte(sr, dr, sa, da, Sr); 593 int g = blendfunc_nonsep_byte(sg, dg, sa, da, Sg); 594 int b = blendfunc_nonsep_byte(sb, db, sa, da, Sb); 595 return SkPackARGB32(a, r, g, b); 596} 597 598// kLuminosity_Mode 599// B(Cb, Cs) = SetLum(Cb, Lum(Cs)) 600// Create a color with the luminosity of the source color and the hue and saturation of the backdrop color. 601static SkPMColor luminosity_modeproc(SkPMColor src, SkPMColor dst) { 602 int sr = SkGetPackedR32(src); 603 int sg = SkGetPackedG32(src); 604 int sb = SkGetPackedB32(src); 605 int sa = SkGetPackedA32(src); 606 607 int dr = SkGetPackedR32(dst); 608 int dg = SkGetPackedG32(dst); 609 int db = SkGetPackedB32(dst); 610 int da = SkGetPackedA32(dst); 611 int Dr, Dg, Db; 612 613 if(sa && da) { 614 Dr = dr * sa; 615 Dg = dg * sa; 616 Db = db * sa; 617 SetLum(&Dr, &Dg, &Db, sa * da, Lum(sr, sg, sb) * da); 618 } else { 619 Dr = 0; 620 Dg = 0; 621 Db = 0; 622 } 623 624 int a = srcover_byte(sa, da); 625 int r = blendfunc_nonsep_byte(sr, dr, sa, da, Dr); 626 int g = blendfunc_nonsep_byte(sg, dg, sa, da, Dg); 627 int b = blendfunc_nonsep_byte(sb, db, sa, da, Db); 628 return SkPackARGB32(a, r, g, b); 629} 630 631 632struct ProcCoeff { 633 SkXfermodeProc fProc; 634 SkXfermode::Coeff fSC; 635 SkXfermode::Coeff fDC; 636}; 637 638#define CANNOT_USE_COEFF SkXfermode::Coeff(-1) 639 640static const ProcCoeff gProcCoeffs[] = { 641 { clear_modeproc, SkXfermode::kZero_Coeff, SkXfermode::kZero_Coeff }, 642 { src_modeproc, SkXfermode::kOne_Coeff, SkXfermode::kZero_Coeff }, 643 { dst_modeproc, SkXfermode::kZero_Coeff, SkXfermode::kOne_Coeff }, 644 { srcover_modeproc, SkXfermode::kOne_Coeff, SkXfermode::kISA_Coeff }, 645 { dstover_modeproc, SkXfermode::kIDA_Coeff, SkXfermode::kOne_Coeff }, 646 { srcin_modeproc, SkXfermode::kDA_Coeff, SkXfermode::kZero_Coeff }, 647 { dstin_modeproc, SkXfermode::kZero_Coeff, SkXfermode::kSA_Coeff }, 648 { srcout_modeproc, SkXfermode::kIDA_Coeff, SkXfermode::kZero_Coeff }, 649 { dstout_modeproc, SkXfermode::kZero_Coeff, SkXfermode::kISA_Coeff }, 650 { srcatop_modeproc, SkXfermode::kDA_Coeff, SkXfermode::kISA_Coeff }, 651 { dstatop_modeproc, SkXfermode::kIDA_Coeff, SkXfermode::kSA_Coeff }, 652 { xor_modeproc, SkXfermode::kIDA_Coeff, SkXfermode::kISA_Coeff }, 653 654 { plus_modeproc, SkXfermode::kOne_Coeff, SkXfermode::kOne_Coeff }, 655 { modulate_modeproc,SkXfermode::kZero_Coeff, SkXfermode::kSC_Coeff }, 656 { screen_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF }, 657 { overlay_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF }, 658 { darken_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF }, 659 { lighten_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF }, 660 { colordodge_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF }, 661 { colorburn_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF }, 662 { hardlight_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF }, 663 { softlight_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF }, 664 { difference_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF }, 665 { exclusion_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF }, 666 { multiply_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF }, 667 { hue_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF }, 668 { saturation_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF }, 669 { color_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF }, 670 { luminosity_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF }, 671}; 672 673/////////////////////////////////////////////////////////////////////////////// 674 675bool SkXfermode::asCoeff(Coeff* src, Coeff* dst) const { 676 return false; 677} 678 679bool SkXfermode::asMode(Mode* mode) const { 680 return false; 681} 682 683SkPMColor SkXfermode::xferColor(SkPMColor src, SkPMColor dst) const{ 684 // no-op. subclasses should override this 685 return dst; 686} 687 688void SkXfermode::xfer32(SkPMColor* SK_RESTRICT dst, 689 const SkPMColor* SK_RESTRICT src, int count, 690 const SkAlpha* SK_RESTRICT aa) const { 691 SkASSERT(dst && src && count >= 0); 692 693 if (NULL == aa) { 694 for (int i = count - 1; i >= 0; --i) { 695 dst[i] = this->xferColor(src[i], dst[i]); 696 } 697 } else { 698 for (int i = count - 1; i >= 0; --i) { 699 unsigned a = aa[i]; 700 if (0 != a) { 701 SkPMColor dstC = dst[i]; 702 SkPMColor C = this->xferColor(src[i], dstC); 703 if (0xFF != a) { 704 C = SkFourByteInterp(C, dstC, a); 705 } 706 dst[i] = C; 707 } 708 } 709 } 710} 711 712void SkXfermode::xfer16(uint16_t* dst, 713 const SkPMColor* SK_RESTRICT src, int count, 714 const SkAlpha* SK_RESTRICT aa) const { 715 SkASSERT(dst && src && count >= 0); 716 717 if (NULL == aa) { 718 for (int i = count - 1; i >= 0; --i) { 719 SkPMColor dstC = SkPixel16ToPixel32(dst[i]); 720 dst[i] = SkPixel32ToPixel16_ToU16(this->xferColor(src[i], dstC)); 721 } 722 } else { 723 for (int i = count - 1; i >= 0; --i) { 724 unsigned a = aa[i]; 725 if (0 != a) { 726 SkPMColor dstC = SkPixel16ToPixel32(dst[i]); 727 SkPMColor C = this->xferColor(src[i], dstC); 728 if (0xFF != a) { 729 C = SkFourByteInterp(C, dstC, a); 730 } 731 dst[i] = SkPixel32ToPixel16_ToU16(C); 732 } 733 } 734 } 735} 736 737void SkXfermode::xfer4444(SkPMColor16* SK_RESTRICT dst, 738 const SkPMColor* SK_RESTRICT src, int count, 739 const SkAlpha* SK_RESTRICT aa) const { 740 SkASSERT(dst && src && count >= 0); 741 742 if (NULL == aa) { 743 for (int i = count - 1; i >= 0; --i) { 744 SkPMColor dstC = SkPixel4444ToPixel32(dst[i]); 745 dst[i] = SkPixel32ToPixel4444(this->xferColor(src[i], dstC)); 746 } 747 } else { 748 for (int i = count - 1; i >= 0; --i) { 749 unsigned a = aa[i]; 750 if (0 != a) { 751 SkPMColor dstC = SkPixel4444ToPixel32(dst[i]); 752 SkPMColor C = this->xferColor(src[i], dstC); 753 if (0xFF != a) { 754 C = SkFourByteInterp(C, dstC, a); 755 } 756 dst[i] = SkPixel32ToPixel4444(C); 757 } 758 } 759 } 760} 761 762void SkXfermode::xferA8(SkAlpha* SK_RESTRICT dst, 763 const SkPMColor src[], int count, 764 const SkAlpha* SK_RESTRICT aa) const { 765 SkASSERT(dst && src && count >= 0); 766 767 if (NULL == aa) { 768 for (int i = count - 1; i >= 0; --i) { 769 SkPMColor res = this->xferColor(src[i], (dst[i] << SK_A32_SHIFT)); 770 dst[i] = SkToU8(SkGetPackedA32(res)); 771 } 772 } else { 773 for (int i = count - 1; i >= 0; --i) { 774 unsigned a = aa[i]; 775 if (0 != a) { 776 SkAlpha dstA = dst[i]; 777 unsigned A = SkGetPackedA32(this->xferColor(src[i], 778 (SkPMColor)(dstA << SK_A32_SHIFT))); 779 if (0xFF != a) { 780 A = SkAlphaBlend(A, dstA, SkAlpha255To256(a)); 781 } 782 dst[i] = SkToU8(A); 783 } 784 } 785 } 786} 787 788/////////////////////////////////////////////////////////////////////////////// 789 790void SkProcXfermode::xfer32(SkPMColor* SK_RESTRICT dst, 791 const SkPMColor* SK_RESTRICT src, int count, 792 const SkAlpha* SK_RESTRICT aa) const { 793 SkASSERT(dst && src && count >= 0); 794 795 SkXfermodeProc proc = fProc; 796 797 if (NULL != proc) { 798 if (NULL == aa) { 799 for (int i = count - 1; i >= 0; --i) { 800 dst[i] = proc(src[i], dst[i]); 801 } 802 } else { 803 for (int i = count - 1; i >= 0; --i) { 804 unsigned a = aa[i]; 805 if (0 != a) { 806 SkPMColor dstC = dst[i]; 807 SkPMColor C = proc(src[i], dstC); 808 if (a != 0xFF) { 809 C = SkFourByteInterp(C, dstC, a); 810 } 811 dst[i] = C; 812 } 813 } 814 } 815 } 816} 817 818void SkProcXfermode::xfer16(uint16_t* SK_RESTRICT dst, 819 const SkPMColor* SK_RESTRICT src, int count, 820 const SkAlpha* SK_RESTRICT aa) const { 821 SkASSERT(dst && src && count >= 0); 822 823 SkXfermodeProc proc = fProc; 824 825 if (NULL != proc) { 826 if (NULL == aa) { 827 for (int i = count - 1; i >= 0; --i) { 828 SkPMColor dstC = SkPixel16ToPixel32(dst[i]); 829 dst[i] = SkPixel32ToPixel16_ToU16(proc(src[i], dstC)); 830 } 831 } else { 832 for (int i = count - 1; i >= 0; --i) { 833 unsigned a = aa[i]; 834 if (0 != a) { 835 SkPMColor dstC = SkPixel16ToPixel32(dst[i]); 836 SkPMColor C = proc(src[i], dstC); 837 if (0xFF != a) { 838 C = SkFourByteInterp(C, dstC, a); 839 } 840 dst[i] = SkPixel32ToPixel16_ToU16(C); 841 } 842 } 843 } 844 } 845} 846 847void SkProcXfermode::xfer4444(SkPMColor16* SK_RESTRICT dst, 848 const SkPMColor* SK_RESTRICT src, int count, 849 const SkAlpha* SK_RESTRICT aa) const { 850 SkASSERT(dst && src && count >= 0); 851 852 SkXfermodeProc proc = fProc; 853 854 if (NULL != proc) { 855 if (NULL == aa) { 856 for (int i = count - 1; i >= 0; --i) { 857 SkPMColor dstC = SkPixel4444ToPixel32(dst[i]); 858 dst[i] = SkPixel32ToPixel4444(proc(src[i], dstC)); 859 } 860 } else { 861 for (int i = count - 1; i >= 0; --i) { 862 unsigned a = aa[i]; 863 if (0 != a) { 864 SkPMColor dstC = SkPixel4444ToPixel32(dst[i]); 865 SkPMColor C = proc(src[i], dstC); 866 if (0xFF != a) { 867 C = SkFourByteInterp(C, dstC, a); 868 } 869 dst[i] = SkPixel32ToPixel4444(C); 870 } 871 } 872 } 873 } 874} 875 876void SkProcXfermode::xferA8(SkAlpha* SK_RESTRICT dst, 877 const SkPMColor* SK_RESTRICT src, int count, 878 const SkAlpha* SK_RESTRICT aa) const { 879 SkASSERT(dst && src && count >= 0); 880 881 SkXfermodeProc proc = fProc; 882 883 if (NULL != proc) { 884 if (NULL == aa) { 885 for (int i = count - 1; i >= 0; --i) { 886 SkPMColor res = proc(src[i], dst[i] << SK_A32_SHIFT); 887 dst[i] = SkToU8(SkGetPackedA32(res)); 888 } 889 } else { 890 for (int i = count - 1; i >= 0; --i) { 891 unsigned a = aa[i]; 892 if (0 != a) { 893 SkAlpha dstA = dst[i]; 894 SkPMColor res = proc(src[i], dstA << SK_A32_SHIFT); 895 unsigned A = SkGetPackedA32(res); 896 if (0xFF != a) { 897 A = SkAlphaBlend(A, dstA, SkAlpha255To256(a)); 898 } 899 dst[i] = SkToU8(A); 900 } 901 } 902 } 903 } 904} 905 906SkProcXfermode::SkProcXfermode(SkFlattenableReadBuffer& buffer) 907 : SkXfermode(buffer) { 908 fProc = NULL; 909 if (!buffer.isCrossProcess()) { 910 fProc = (SkXfermodeProc)buffer.readFunctionPtr(); 911 } 912} 913 914void SkProcXfermode::flatten(SkFlattenableWriteBuffer& buffer) const { 915 this->INHERITED::flatten(buffer); 916 if (!buffer.isCrossProcess()) { 917 buffer.writeFunctionPtr((void*)fProc); 918 } 919} 920 921#ifdef SK_DEVELOPER 922void SkProcXfermode::toString(SkString* str) const { 923 str->appendf("SkProcXfermode: %p", fProc); 924} 925#endif 926 927/////////////////////////////////////////////////////////////////////////////// 928/////////////////////////////////////////////////////////////////////////////// 929 930class SkProcCoeffXfermode : public SkProcXfermode { 931public: 932 SkProcCoeffXfermode(const ProcCoeff& rec, Mode mode) 933 : INHERITED(rec.fProc) { 934 fMode = mode; 935 // these may be valid, or may be CANNOT_USE_COEFF 936 fSrcCoeff = rec.fSC; 937 fDstCoeff = rec.fDC; 938 } 939 940 virtual bool asMode(Mode* mode) const SK_OVERRIDE { 941 if (mode) { 942 *mode = fMode; 943 } 944 return true; 945 } 946 947 virtual bool asCoeff(Coeff* sc, Coeff* dc) const SK_OVERRIDE { 948 if (CANNOT_USE_COEFF == fSrcCoeff) { 949 return false; 950 } 951 952 if (sc) { 953 *sc = fSrcCoeff; 954 } 955 if (dc) { 956 *dc = fDstCoeff; 957 } 958 return true; 959 } 960 961 SK_DEVELOPER_TO_STRING() 962 SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkProcCoeffXfermode) 963 964protected: 965 SkProcCoeffXfermode(SkFlattenableReadBuffer& buffer) : INHERITED(buffer) { 966 fMode = (SkXfermode::Mode)buffer.read32(); 967 968 const ProcCoeff& rec = gProcCoeffs[fMode]; 969 // these may be valid, or may be CANNOT_USE_COEFF 970 fSrcCoeff = rec.fSC; 971 fDstCoeff = rec.fDC; 972 // now update our function-ptr in the super class 973 this->INHERITED::setProc(rec.fProc); 974 } 975 976 virtual void flatten(SkFlattenableWriteBuffer& buffer) const SK_OVERRIDE { 977 this->INHERITED::flatten(buffer); 978 buffer.write32(fMode); 979 } 980 981private: 982 Mode fMode; 983 Coeff fSrcCoeff, fDstCoeff; 984 985 typedef SkProcXfermode INHERITED; 986}; 987 988#ifdef SK_DEVELOPER 989void SkProcCoeffXfermode::toString(SkString* str) const { 990 str->append("SkProcCoeffXfermode: "); 991 992 const char *gModeStrings[kLastMode+1] = { 993 "Clear", "Src", "Dst", "SrcOver", "DstOver", "SrcIn", "DstIn", 994 "SrcOut", "DstOut", "SrcATop", "DstATop", "Xor", "Plus", 995 "Modulate", "Screen", "Overlay", "Darken", "Lighten", "ColorDodge", 996 "ColorBurn", "HardLight", "SoftLight", "Difference", "Exclusion" 997 }; 998 999 str->append("mode: "); 1000 str->append(gModeStrings[fMode]); 1001 1002 static const char* gCoeffStrings[kCoeffCount] = { 1003 "Zero", "One", "SC", "ISC", "DC", "IDC", "SA", "ISA", "DA", "IDA" 1004 }; 1005 1006 str->append(" src: "); 1007 if (CANNOT_USE_COEFF == fSrcCoeff) { 1008 str->append("can't use"); 1009 } else { 1010 str->append(gCoeffStrings[fSrcCoeff]); 1011 } 1012 1013 str->append(" dst: "); 1014 if (CANNOT_USE_COEFF == fDstCoeff) { 1015 str->append("can't use"); 1016 } else { 1017 str->append(gCoeffStrings[fDstCoeff]); 1018 } 1019} 1020#endif 1021 1022/////////////////////////////////////////////////////////////////////////////// 1023 1024class SkClearXfermode : public SkProcCoeffXfermode { 1025public: 1026 SkClearXfermode(const ProcCoeff& rec) : SkProcCoeffXfermode(rec, kClear_Mode) {} 1027 1028 virtual void xfer32(SkPMColor*, const SkPMColor*, int, const SkAlpha*) const SK_OVERRIDE; 1029 virtual void xferA8(SkAlpha*, const SkPMColor*, int, const SkAlpha*) const SK_OVERRIDE; 1030 1031 SK_DEVELOPER_TO_STRING() 1032 SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkClearXfermode) 1033 1034private: 1035 SkClearXfermode(SkFlattenableReadBuffer& buffer) 1036 : SkProcCoeffXfermode(buffer) {} 1037 1038 typedef SkProcCoeffXfermode INHERITED; 1039}; 1040 1041void SkClearXfermode::xfer32(SkPMColor* SK_RESTRICT dst, 1042 const SkPMColor* SK_RESTRICT, int count, 1043 const SkAlpha* SK_RESTRICT aa) const { 1044 SkASSERT(dst && count >= 0); 1045 1046 if (NULL == aa) { 1047 memset(dst, 0, count << 2); 1048 } else { 1049 for (int i = count - 1; i >= 0; --i) { 1050 unsigned a = aa[i]; 1051 if (0xFF == a) { 1052 dst[i] = 0; 1053 } else if (a != 0) { 1054 dst[i] = SkAlphaMulQ(dst[i], SkAlpha255To256(255 - a)); 1055 } 1056 } 1057 } 1058} 1059void SkClearXfermode::xferA8(SkAlpha* SK_RESTRICT dst, 1060 const SkPMColor* SK_RESTRICT, int count, 1061 const SkAlpha* SK_RESTRICT aa) const { 1062 SkASSERT(dst && count >= 0); 1063 1064 if (NULL == aa) { 1065 memset(dst, 0, count); 1066 } else { 1067 for (int i = count - 1; i >= 0; --i) { 1068 unsigned a = aa[i]; 1069 if (0xFF == a) { 1070 dst[i] = 0; 1071 } else if (0 != a) { 1072 dst[i] = SkAlphaMulAlpha(dst[i], 255 - a); 1073 } 1074 } 1075 } 1076} 1077 1078#ifdef SK_DEVELOPER 1079void SkClearXfermode::toString(SkString* str) const { 1080 this->INHERITED::toString(str); 1081} 1082#endif 1083 1084/////////////////////////////////////////////////////////////////////////////// 1085 1086class SkSrcXfermode : public SkProcCoeffXfermode { 1087public: 1088 SkSrcXfermode(const ProcCoeff& rec) : SkProcCoeffXfermode(rec, kSrc_Mode) {} 1089 1090 virtual void xfer32(SkPMColor*, const SkPMColor*, int, const SkAlpha*) const SK_OVERRIDE; 1091 virtual void xferA8(SkAlpha*, const SkPMColor*, int, const SkAlpha*) const SK_OVERRIDE; 1092 1093 SK_DEVELOPER_TO_STRING() 1094 SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkSrcXfermode) 1095 1096private: 1097 SkSrcXfermode(SkFlattenableReadBuffer& buffer) 1098 : SkProcCoeffXfermode(buffer) {} 1099 1100 typedef SkProcCoeffXfermode INHERITED; 1101}; 1102 1103void SkSrcXfermode::xfer32(SkPMColor* SK_RESTRICT dst, 1104 const SkPMColor* SK_RESTRICT src, int count, 1105 const SkAlpha* SK_RESTRICT aa) const { 1106 SkASSERT(dst && src && count >= 0); 1107 1108 if (NULL == aa) { 1109 memcpy(dst, src, count << 2); 1110 } else { 1111 for (int i = count - 1; i >= 0; --i) { 1112 unsigned a = aa[i]; 1113 if (a == 0xFF) { 1114 dst[i] = src[i]; 1115 } else if (a != 0) { 1116 dst[i] = SkFourByteInterp(src[i], dst[i], a); 1117 } 1118 } 1119 } 1120} 1121 1122void SkSrcXfermode::xferA8(SkAlpha* SK_RESTRICT dst, 1123 const SkPMColor* SK_RESTRICT src, int count, 1124 const SkAlpha* SK_RESTRICT aa) const { 1125 SkASSERT(dst && src && count >= 0); 1126 1127 if (NULL == aa) { 1128 for (int i = count - 1; i >= 0; --i) { 1129 dst[i] = SkToU8(SkGetPackedA32(src[i])); 1130 } 1131 } else { 1132 for (int i = count - 1; i >= 0; --i) { 1133 unsigned a = aa[i]; 1134 if (0 != a) { 1135 unsigned srcA = SkGetPackedA32(src[i]); 1136 if (a == 0xFF) { 1137 dst[i] = SkToU8(srcA); 1138 } else { 1139 dst[i] = SkToU8(SkAlphaBlend(srcA, dst[i], a)); 1140 } 1141 } 1142 } 1143 } 1144} 1145#ifdef SK_DEVELOPER 1146void SkSrcXfermode::toString(SkString* str) const { 1147 this->INHERITED::toString(str); 1148} 1149#endif 1150 1151/////////////////////////////////////////////////////////////////////////////// 1152 1153class SkDstInXfermode : public SkProcCoeffXfermode { 1154public: 1155 SkDstInXfermode(const ProcCoeff& rec) : SkProcCoeffXfermode(rec, kDstIn_Mode) {} 1156 1157 virtual void xfer32(SkPMColor*, const SkPMColor*, int, const SkAlpha*) const SK_OVERRIDE; 1158 1159 SK_DEVELOPER_TO_STRING() 1160 SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkDstInXfermode) 1161 1162private: 1163 SkDstInXfermode(SkFlattenableReadBuffer& buffer) : INHERITED(buffer) {} 1164 1165 typedef SkProcCoeffXfermode INHERITED; 1166}; 1167 1168void SkDstInXfermode::xfer32(SkPMColor* SK_RESTRICT dst, 1169 const SkPMColor* SK_RESTRICT src, int count, 1170 const SkAlpha* SK_RESTRICT aa) const { 1171 SkASSERT(dst && src); 1172 1173 if (count <= 0) { 1174 return; 1175 } 1176 if (NULL != aa) { 1177 return this->INHERITED::xfer32(dst, src, count, aa); 1178 } 1179 1180 do { 1181 unsigned a = SkGetPackedA32(*src); 1182 *dst = SkAlphaMulQ(*dst, SkAlpha255To256(a)); 1183 dst++; 1184 src++; 1185 } while (--count != 0); 1186} 1187 1188#ifdef SK_DEVELOPER 1189void SkDstInXfermode::toString(SkString* str) const { 1190 this->INHERITED::toString(str); 1191} 1192#endif 1193 1194/////////////////////////////////////////////////////////////////////////////// 1195 1196class SkDstOutXfermode : public SkProcCoeffXfermode { 1197public: 1198 SkDstOutXfermode(const ProcCoeff& rec) : SkProcCoeffXfermode(rec, kDstOut_Mode) {} 1199 1200 virtual void xfer32(SkPMColor*, const SkPMColor*, int, const SkAlpha*) const SK_OVERRIDE; 1201 1202 SK_DEVELOPER_TO_STRING() 1203 SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkDstOutXfermode) 1204 1205private: 1206 SkDstOutXfermode(SkFlattenableReadBuffer& buffer) 1207 : INHERITED(buffer) {} 1208 1209 typedef SkProcCoeffXfermode INHERITED; 1210}; 1211 1212void SkDstOutXfermode::xfer32(SkPMColor* SK_RESTRICT dst, 1213 const SkPMColor* SK_RESTRICT src, int count, 1214 const SkAlpha* SK_RESTRICT aa) const { 1215 SkASSERT(dst && src); 1216 1217 if (count <= 0) { 1218 return; 1219 } 1220 if (NULL != aa) { 1221 return this->INHERITED::xfer32(dst, src, count, aa); 1222 } 1223 1224 do { 1225 unsigned a = SkGetPackedA32(*src); 1226 *dst = SkAlphaMulQ(*dst, SkAlpha255To256(255 - a)); 1227 dst++; 1228 src++; 1229 } while (--count != 0); 1230} 1231 1232#ifdef SK_DEVELOPER 1233void SkDstOutXfermode::toString(SkString* str) const { 1234 this->INHERITED::toString(str); 1235} 1236#endif 1237 1238/////////////////////////////////////////////////////////////////////////////// 1239 1240SkXfermode* SkXfermode::Create(Mode mode) { 1241 SkASSERT(SK_ARRAY_COUNT(gProcCoeffs) == kModeCount); 1242 SkASSERT((unsigned)mode < kModeCount); 1243 1244 const ProcCoeff& rec = gProcCoeffs[mode]; 1245 1246 switch (mode) { 1247 case kClear_Mode: 1248 return SkNEW_ARGS(SkClearXfermode, (rec)); 1249 case kSrc_Mode: 1250 return SkNEW_ARGS(SkSrcXfermode, (rec)); 1251 case kSrcOver_Mode: 1252 return NULL; 1253 case kDstIn_Mode: 1254 return SkNEW_ARGS(SkDstInXfermode, (rec)); 1255 case kDstOut_Mode: 1256 return SkNEW_ARGS(SkDstOutXfermode, (rec)); 1257 default: 1258 return SkNEW_ARGS(SkProcCoeffXfermode, (rec, mode)); 1259 } 1260} 1261 1262SkXfermodeProc SkXfermode::GetProc(Mode mode) { 1263 SkXfermodeProc proc = NULL; 1264 if ((unsigned)mode < kModeCount) { 1265 proc = gProcCoeffs[mode].fProc; 1266 } 1267 return proc; 1268} 1269 1270bool SkXfermode::ModeAsCoeff(Mode mode, Coeff* src, Coeff* dst) { 1271 SkASSERT(SK_ARRAY_COUNT(gProcCoeffs) == kModeCount); 1272 1273 if ((unsigned)mode >= (unsigned)kModeCount) { 1274 // illegal mode parameter 1275 return false; 1276 } 1277 1278 const ProcCoeff& rec = gProcCoeffs[mode]; 1279 1280 if (CANNOT_USE_COEFF == rec.fSC) { 1281 return false; 1282 } 1283 1284 SkASSERT(CANNOT_USE_COEFF != rec.fDC); 1285 if (src) { 1286 *src = rec.fSC; 1287 } 1288 if (dst) { 1289 *dst = rec.fDC; 1290 } 1291 return true; 1292} 1293 1294bool SkXfermode::AsMode(const SkXfermode* xfer, Mode* mode) { 1295 if (NULL == xfer) { 1296 if (mode) { 1297 *mode = kSrcOver_Mode; 1298 } 1299 return true; 1300 } 1301 return xfer->asMode(mode); 1302} 1303 1304bool SkXfermode::AsCoeff(const SkXfermode* xfer, Coeff* src, Coeff* dst) { 1305 if (NULL == xfer) { 1306 return ModeAsCoeff(kSrcOver_Mode, src, dst); 1307 } 1308 return xfer->asCoeff(src, dst); 1309} 1310 1311bool SkXfermode::IsMode(const SkXfermode* xfer, Mode mode) { 1312 // if xfer==null then the mode is srcover 1313 Mode m = kSrcOver_Mode; 1314 if (xfer && !xfer->asMode(&m)) { 1315 return false; 1316 } 1317 return mode == m; 1318} 1319 1320/////////////////////////////////////////////////////////////////////////////// 1321//////////// 16bit xfermode procs 1322 1323#ifdef SK_DEBUG 1324static bool require_255(SkPMColor src) { return SkGetPackedA32(src) == 0xFF; } 1325static bool require_0(SkPMColor src) { return SkGetPackedA32(src) == 0; } 1326#endif 1327 1328static uint16_t src_modeproc16_255(SkPMColor src, uint16_t dst) { 1329 SkASSERT(require_255(src)); 1330 return SkPixel32ToPixel16(src); 1331} 1332 1333static uint16_t dst_modeproc16(SkPMColor src, uint16_t dst) { 1334 return dst; 1335} 1336 1337static uint16_t srcover_modeproc16_0(SkPMColor src, uint16_t dst) { 1338 SkASSERT(require_0(src)); 1339 return dst; 1340} 1341 1342static uint16_t srcover_modeproc16_255(SkPMColor src, uint16_t dst) { 1343 SkASSERT(require_255(src)); 1344 return SkPixel32ToPixel16(src); 1345} 1346 1347static uint16_t dstover_modeproc16_0(SkPMColor src, uint16_t dst) { 1348 SkASSERT(require_0(src)); 1349 return dst; 1350} 1351 1352static uint16_t dstover_modeproc16_255(SkPMColor src, uint16_t dst) { 1353 SkASSERT(require_255(src)); 1354 return dst; 1355} 1356 1357static uint16_t srcin_modeproc16_255(SkPMColor src, uint16_t dst) { 1358 SkASSERT(require_255(src)); 1359 return SkPixel32ToPixel16(src); 1360} 1361 1362static uint16_t dstin_modeproc16_255(SkPMColor src, uint16_t dst) { 1363 SkASSERT(require_255(src)); 1364 return dst; 1365} 1366 1367static uint16_t dstout_modeproc16_0(SkPMColor src, uint16_t dst) { 1368 SkASSERT(require_0(src)); 1369 return dst; 1370} 1371 1372static uint16_t srcatop_modeproc16(SkPMColor src, uint16_t dst) { 1373 unsigned isa = 255 - SkGetPackedA32(src); 1374 1375 return SkPackRGB16( 1376 SkPacked32ToR16(src) + SkAlphaMulAlpha(SkGetPackedR16(dst), isa), 1377 SkPacked32ToG16(src) + SkAlphaMulAlpha(SkGetPackedG16(dst), isa), 1378 SkPacked32ToB16(src) + SkAlphaMulAlpha(SkGetPackedB16(dst), isa)); 1379} 1380 1381static uint16_t srcatop_modeproc16_0(SkPMColor src, uint16_t dst) { 1382 SkASSERT(require_0(src)); 1383 return dst; 1384} 1385 1386static uint16_t srcatop_modeproc16_255(SkPMColor src, uint16_t dst) { 1387 SkASSERT(require_255(src)); 1388 return SkPixel32ToPixel16(src); 1389} 1390 1391static uint16_t dstatop_modeproc16_255(SkPMColor src, uint16_t dst) { 1392 SkASSERT(require_255(src)); 1393 return dst; 1394} 1395 1396/********* 1397 darken and lighten boil down to this. 1398 1399 darken = (1 - Sa) * Dc + min(Sc, Dc) 1400 lighten = (1 - Sa) * Dc + max(Sc, Dc) 1401 1402 if (Sa == 0) these become 1403 darken = Dc + min(0, Dc) = 0 1404 lighten = Dc + max(0, Dc) = Dc 1405 1406 if (Sa == 1) these become 1407 darken = min(Sc, Dc) 1408 lighten = max(Sc, Dc) 1409*/ 1410 1411static uint16_t darken_modeproc16_0(SkPMColor src, uint16_t dst) { 1412 SkASSERT(require_0(src)); 1413 return 0; 1414} 1415 1416static uint16_t darken_modeproc16_255(SkPMColor src, uint16_t dst) { 1417 SkASSERT(require_255(src)); 1418 unsigned r = SkFastMin32(SkPacked32ToR16(src), SkGetPackedR16(dst)); 1419 unsigned g = SkFastMin32(SkPacked32ToG16(src), SkGetPackedG16(dst)); 1420 unsigned b = SkFastMin32(SkPacked32ToB16(src), SkGetPackedB16(dst)); 1421 return SkPackRGB16(r, g, b); 1422} 1423 1424static uint16_t lighten_modeproc16_0(SkPMColor src, uint16_t dst) { 1425 SkASSERT(require_0(src)); 1426 return dst; 1427} 1428 1429static uint16_t lighten_modeproc16_255(SkPMColor src, uint16_t dst) { 1430 SkASSERT(require_255(src)); 1431 unsigned r = SkMax32(SkPacked32ToR16(src), SkGetPackedR16(dst)); 1432 unsigned g = SkMax32(SkPacked32ToG16(src), SkGetPackedG16(dst)); 1433 unsigned b = SkMax32(SkPacked32ToB16(src), SkGetPackedB16(dst)); 1434 return SkPackRGB16(r, g, b); 1435} 1436 1437struct Proc16Rec { 1438 SkXfermodeProc16 fProc16_0; 1439 SkXfermodeProc16 fProc16_255; 1440 SkXfermodeProc16 fProc16_General; 1441}; 1442 1443static const Proc16Rec gModeProcs16[] = { 1444 { NULL, NULL, NULL }, // CLEAR 1445 { NULL, src_modeproc16_255, NULL }, 1446 { dst_modeproc16, dst_modeproc16, dst_modeproc16 }, 1447 { srcover_modeproc16_0, srcover_modeproc16_255, NULL }, 1448 { dstover_modeproc16_0, dstover_modeproc16_255, NULL }, 1449 { NULL, srcin_modeproc16_255, NULL }, 1450 { NULL, dstin_modeproc16_255, NULL }, 1451 { NULL, NULL, NULL },// SRC_OUT 1452 { dstout_modeproc16_0, NULL, NULL }, 1453 { srcatop_modeproc16_0, srcatop_modeproc16_255, srcatop_modeproc16 }, 1454 { NULL, dstatop_modeproc16_255, NULL }, 1455 { NULL, NULL, NULL }, // XOR 1456 1457 { NULL, NULL, NULL }, // plus 1458 { NULL, NULL, NULL }, // modulate 1459 { NULL, NULL, NULL }, // screen 1460 { NULL, NULL, NULL }, // overlay 1461 { darken_modeproc16_0, darken_modeproc16_255, NULL }, // darken 1462 { lighten_modeproc16_0, lighten_modeproc16_255, NULL }, // lighten 1463 { NULL, NULL, NULL }, // colordodge 1464 { NULL, NULL, NULL }, // colorburn 1465 { NULL, NULL, NULL }, // hardlight 1466 { NULL, NULL, NULL }, // softlight 1467 { NULL, NULL, NULL }, // difference 1468 { NULL, NULL, NULL }, // exclusion 1469 { NULL, NULL, NULL }, // multiply 1470 { NULL, NULL, NULL }, // hue 1471 { NULL, NULL, NULL }, // saturation 1472 { NULL, NULL, NULL }, // color 1473 { NULL, NULL, NULL }, // luminosity 1474}; 1475 1476SkXfermodeProc16 SkXfermode::GetProc16(Mode mode, SkColor srcColor) { 1477 SkXfermodeProc16 proc16 = NULL; 1478 if ((unsigned)mode < kModeCount) { 1479 const Proc16Rec& rec = gModeProcs16[mode]; 1480 unsigned a = SkColorGetA(srcColor); 1481 1482 if (0 == a) { 1483 proc16 = rec.fProc16_0; 1484 } else if (255 == a) { 1485 proc16 = rec.fProc16_255; 1486 } else { 1487 proc16 = rec.fProc16_General; 1488 } 1489 } 1490 return proc16; 1491} 1492 1493SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkXfermode) 1494 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkProcCoeffXfermode) 1495 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkClearXfermode) 1496 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkSrcXfermode) 1497 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkDstInXfermode) 1498 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkDstOutXfermode) 1499SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END 1500