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 16 SK_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 23 static 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 35 static 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 45 static 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 54 static 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 64 static 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] 74 static SkPMColor clear_modeproc(SkPMColor src, SkPMColor dst) { 75 return 0; 76 } 77 78 // kSrc_Mode, //!< [Sa, Sc] 79 static SkPMColor src_modeproc(SkPMColor src, SkPMColor dst) { 80 return src; 81 } 82 83 // kDst_Mode, //!< [Da, Dc] 84 static SkPMColor dst_modeproc(SkPMColor src, SkPMColor dst) { 85 return dst; 86 } 87 88 // kSrcOver_Mode, //!< [Sa + Da - Sa*Da, Sc + (1 - Sa)*Dc] 89 static 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] 102 static 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] 109 static SkPMColor srcin_modeproc(SkPMColor src, SkPMColor dst) { 110 return SkAlphaMulQ(src, SkAlpha255To256(SkGetPackedA32(dst))); 111 } 112 113 // kDstIn_Mode, //!< [Sa * Da, Sa * Dc] 114 static 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)] 119 static 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)] 124 static 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] 129 static 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)] 144 static 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] 159 static 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 177 static 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 186 static 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 194 // kScreen_Mode 195 static inline int srcover_byte(int a, int b) { 196 return a + b - SkAlphaMulAlpha(a, b); 197 } 198 static SkPMColor screen_modeproc(SkPMColor src, SkPMColor dst) { 199 int a = srcover_byte(SkGetPackedA32(src), SkGetPackedA32(dst)); 200 int r = srcover_byte(SkGetPackedR32(src), SkGetPackedR32(dst)); 201 int g = srcover_byte(SkGetPackedG32(src), SkGetPackedG32(dst)); 202 int b = srcover_byte(SkGetPackedB32(src), SkGetPackedB32(dst)); 203 return SkPackARGB32(a, r, g, b); 204 } 205 206 // kOverlay_Mode 207 static inline int overlay_byte(int sc, int dc, int sa, int da) { 208 int tmp = sc * (255 - da) + dc * (255 - sa); 209 int rc; 210 if (2 * dc <= da) { 211 rc = 2 * sc * dc; 212 } else { 213 rc = sa * da - 2 * (da - dc) * (sa - sc); 214 } 215 return clamp_div255round(rc + tmp); 216 } 217 static SkPMColor overlay_modeproc(SkPMColor src, SkPMColor dst) { 218 int sa = SkGetPackedA32(src); 219 int da = SkGetPackedA32(dst); 220 int a = srcover_byte(sa, da); 221 int r = overlay_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da); 222 int g = overlay_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da); 223 int b = overlay_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da); 224 return SkPackARGB32(a, r, g, b); 225 } 226 227 // kDarken_Mode 228 static inline int darken_byte(int sc, int dc, int sa, int da) { 229 int sd = sc * da; 230 int ds = dc * sa; 231 if (sd < ds) { 232 // srcover 233 return sc + dc - SkDiv255Round(ds); 234 } else { 235 // dstover 236 return dc + sc - SkDiv255Round(sd); 237 } 238 } 239 static SkPMColor darken_modeproc(SkPMColor src, SkPMColor dst) { 240 int sa = SkGetPackedA32(src); 241 int da = SkGetPackedA32(dst); 242 int a = srcover_byte(sa, da); 243 int r = darken_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da); 244 int g = darken_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da); 245 int b = darken_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da); 246 return SkPackARGB32(a, r, g, b); 247 } 248 249 // kLighten_Mode 250 static inline int lighten_byte(int sc, int dc, int sa, int da) { 251 int sd = sc * da; 252 int ds = dc * sa; 253 if (sd > ds) { 254 // srcover 255 return sc + dc - SkDiv255Round(ds); 256 } else { 257 // dstover 258 return dc + sc - SkDiv255Round(sd); 259 } 260 } 261 static SkPMColor lighten_modeproc(SkPMColor src, SkPMColor dst) { 262 int sa = SkGetPackedA32(src); 263 int da = SkGetPackedA32(dst); 264 int a = srcover_byte(sa, da); 265 int r = lighten_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da); 266 int g = lighten_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da); 267 int b = lighten_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da); 268 return SkPackARGB32(a, r, g, b); 269 } 270 271 // kColorDodge_Mode 272 static inline int colordodge_byte(int sc, int dc, int sa, int da) { 273 int diff = sa - sc; 274 int rc; 275 if (0 == diff) { 276 rc = sa * da + sc * (255 - da) + dc * (255 - sa); 277 rc = SkDiv255Round(rc); 278 } else { 279 int tmp = (dc * sa << 15) / (da * diff); 280 rc = SkDiv255Round(sa * da) * tmp >> 15; 281 // don't clamp here, since we'll do it in our modeproc 282 } 283 return rc; 284 } 285 static SkPMColor colordodge_modeproc(SkPMColor src, SkPMColor dst) { 286 // added to avoid div-by-zero in colordodge_byte 287 if (0 == dst) { 288 return src; 289 } 290 291 int sa = SkGetPackedA32(src); 292 int da = SkGetPackedA32(dst); 293 int a = srcover_byte(sa, da); 294 int r = colordodge_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da); 295 int g = colordodge_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da); 296 int b = colordodge_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da); 297 r = clamp_max(r, a); 298 g = clamp_max(g, a); 299 b = clamp_max(b, a); 300 return SkPackARGB32(a, r, g, b); 301 } 302 303 // kColorBurn_Mode 304 static inline int colorburn_byte(int sc, int dc, int sa, int da) { 305 int rc; 306 if (dc == da && 0 == sc) { 307 rc = sa * da + dc * (255 - sa); 308 } else if (0 == sc) { 309 return SkAlphaMulAlpha(dc, 255 - sa); 310 } else { 311 int tmp = (sa * (da - dc) * 256) / (sc * da); 312 if (tmp > 256) { 313 tmp = 256; 314 } 315 int tmp2 = sa * da; 316 rc = tmp2 - (tmp2 * tmp >> 8) + sc * (255 - da) + dc * (255 - sa); 317 } 318 return SkDiv255Round(rc); 319 } 320 static SkPMColor colorburn_modeproc(SkPMColor src, SkPMColor dst) { 321 // added to avoid div-by-zero in colorburn_byte 322 if (0 == dst) { 323 return src; 324 } 325 326 int sa = SkGetPackedA32(src); 327 int da = SkGetPackedA32(dst); 328 int a = srcover_byte(sa, da); 329 int r = colorburn_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da); 330 int g = colorburn_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da); 331 int b = colorburn_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da); 332 return SkPackARGB32(a, r, g, b); 333 } 334 335 // kHardLight_Mode 336 static inline int hardlight_byte(int sc, int dc, int sa, int da) { 337 int rc; 338 if (2 * sc <= sa) { 339 rc = 2 * sc * dc; 340 } else { 341 rc = sa * da - 2 * (da - dc) * (sa - sc); 342 } 343 return clamp_div255round(rc + sc * (255 - da) + dc * (255 - sa)); 344 } 345 static SkPMColor hardlight_modeproc(SkPMColor src, SkPMColor dst) { 346 int sa = SkGetPackedA32(src); 347 int da = SkGetPackedA32(dst); 348 int a = srcover_byte(sa, da); 349 int r = hardlight_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da); 350 int g = hardlight_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da); 351 int b = hardlight_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da); 352 return SkPackARGB32(a, r, g, b); 353 } 354 355 // returns 255 * sqrt(n/255) 356 static U8CPU sqrt_unit_byte(U8CPU n) { 357 return SkSqrtBits(n, 15+4); 358 } 359 360 // kSoftLight_Mode 361 static inline int softlight_byte(int sc, int dc, int sa, int da) { 362 int m = da ? dc * 256 / da : 0; 363 int rc; 364 if (2 * sc <= sa) { 365 rc = dc * (sa + ((2 * sc - sa) * (256 - m) >> 8)); 366 } else if (4 * dc <= da) { 367 int tmp = (4 * m * (4 * m + 256) * (m - 256) >> 16) + 7 * m; 368 rc = dc * sa + (da * (2 * sc - sa) * tmp >> 8); 369 } else { 370 int tmp = sqrt_unit_byte(m) - m; 371 rc = dc * sa + (da * (2 * sc - sa) * tmp >> 8); 372 } 373 return clamp_div255round(rc + sc * (255 - da) + dc * (255 - sa)); 374 } 375 static SkPMColor softlight_modeproc(SkPMColor src, SkPMColor dst) { 376 int sa = SkGetPackedA32(src); 377 int da = SkGetPackedA32(dst); 378 int a = srcover_byte(sa, da); 379 int r = softlight_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da); 380 int g = softlight_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da); 381 int b = softlight_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da); 382 return SkPackARGB32(a, r, g, b); 383 } 384 385 // kDifference_Mode 386 static inline int difference_byte(int sc, int dc, int sa, int da) { 387 int tmp = SkMin32(sc * da, dc * sa); 388 return clamp_signed_byte(sc + dc - 2 * SkDiv255Round(tmp)); 389 } 390 static SkPMColor difference_modeproc(SkPMColor src, SkPMColor dst) { 391 int sa = SkGetPackedA32(src); 392 int da = SkGetPackedA32(dst); 393 int a = srcover_byte(sa, da); 394 int r = difference_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da); 395 int g = difference_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da); 396 int b = difference_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da); 397 return SkPackARGB32(a, r, g, b); 398 } 399 400 // kExclusion_Mode 401 static inline int exclusion_byte(int sc, int dc, int sa, int da) { 402 // this equations is wacky, wait for SVG to confirm it 403 int r = sc * da + dc * sa - 2 * sc * dc + sc * (255 - da) + dc * (255 - sa); 404 return clamp_div255round(r); 405 } 406 static SkPMColor exclusion_modeproc(SkPMColor src, SkPMColor dst) { 407 int sa = SkGetPackedA32(src); 408 int da = SkGetPackedA32(dst); 409 int a = srcover_byte(sa, da); 410 int r = exclusion_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da); 411 int g = exclusion_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da); 412 int b = exclusion_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da); 413 return SkPackARGB32(a, r, g, b); 414 } 415 416 struct ProcCoeff { 417 SkXfermodeProc fProc; 418 SkXfermode::Coeff fSC; 419 SkXfermode::Coeff fDC; 420 }; 421 422 #define CANNOT_USE_COEFF SkXfermode::Coeff(-1) 423 424 static const ProcCoeff gProcCoeffs[] = { 425 { clear_modeproc, SkXfermode::kZero_Coeff, SkXfermode::kZero_Coeff }, 426 { src_modeproc, SkXfermode::kOne_Coeff, SkXfermode::kZero_Coeff }, 427 { dst_modeproc, SkXfermode::kZero_Coeff, SkXfermode::kOne_Coeff }, 428 { srcover_modeproc, SkXfermode::kOne_Coeff, SkXfermode::kISA_Coeff }, 429 { dstover_modeproc, SkXfermode::kIDA_Coeff, SkXfermode::kOne_Coeff }, 430 { srcin_modeproc, SkXfermode::kDA_Coeff, SkXfermode::kZero_Coeff }, 431 { dstin_modeproc, SkXfermode::kZero_Coeff, SkXfermode::kSA_Coeff }, 432 { srcout_modeproc, SkXfermode::kIDA_Coeff, SkXfermode::kZero_Coeff }, 433 { dstout_modeproc, SkXfermode::kZero_Coeff, SkXfermode::kISA_Coeff }, 434 { srcatop_modeproc, SkXfermode::kDA_Coeff, SkXfermode::kISA_Coeff }, 435 { dstatop_modeproc, SkXfermode::kIDA_Coeff, SkXfermode::kSA_Coeff }, 436 { xor_modeproc, SkXfermode::kIDA_Coeff, SkXfermode::kISA_Coeff }, 437 438 { plus_modeproc, SkXfermode::kOne_Coeff, SkXfermode::kOne_Coeff }, 439 { modulate_modeproc,SkXfermode::kZero_Coeff, SkXfermode::kSC_Coeff }, 440 { screen_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF }, 441 { overlay_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF }, 442 { darken_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF }, 443 { lighten_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF }, 444 { colordodge_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF }, 445 { colorburn_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF }, 446 { hardlight_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF }, 447 { softlight_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF }, 448 { difference_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF }, 449 { exclusion_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF }, 450 }; 451 452 /////////////////////////////////////////////////////////////////////////////// 453 454 bool SkXfermode::asCoeff(Coeff* src, Coeff* dst) const { 455 return false; 456 } 457 458 bool SkXfermode::asMode(Mode* mode) const { 459 return false; 460 } 461 462 SkPMColor SkXfermode::xferColor(SkPMColor src, SkPMColor dst) const{ 463 // no-op. subclasses should override this 464 return dst; 465 } 466 467 void SkXfermode::xfer32(SkPMColor* SK_RESTRICT dst, 468 const SkPMColor* SK_RESTRICT src, int count, 469 const SkAlpha* SK_RESTRICT aa) const { 470 SkASSERT(dst && src && count >= 0); 471 472 if (NULL == aa) { 473 for (int i = count - 1; i >= 0; --i) { 474 dst[i] = this->xferColor(src[i], dst[i]); 475 } 476 } else { 477 for (int i = count - 1; i >= 0; --i) { 478 unsigned a = aa[i]; 479 if (0 != a) { 480 SkPMColor dstC = dst[i]; 481 SkPMColor C = this->xferColor(src[i], dstC); 482 if (0xFF != a) { 483 C = SkFourByteInterp(C, dstC, a); 484 } 485 dst[i] = C; 486 } 487 } 488 } 489 } 490 491 void SkXfermode::xfer16(uint16_t* dst, 492 const SkPMColor* SK_RESTRICT src, int count, 493 const SkAlpha* SK_RESTRICT aa) const { 494 SkASSERT(dst && src && count >= 0); 495 496 if (NULL == aa) { 497 for (int i = count - 1; i >= 0; --i) { 498 SkPMColor dstC = SkPixel16ToPixel32(dst[i]); 499 dst[i] = SkPixel32ToPixel16_ToU16(this->xferColor(src[i], dstC)); 500 } 501 } else { 502 for (int i = count - 1; i >= 0; --i) { 503 unsigned a = aa[i]; 504 if (0 != a) { 505 SkPMColor dstC = SkPixel16ToPixel32(dst[i]); 506 SkPMColor C = this->xferColor(src[i], dstC); 507 if (0xFF != a) { 508 C = SkFourByteInterp(C, dstC, a); 509 } 510 dst[i] = SkPixel32ToPixel16_ToU16(C); 511 } 512 } 513 } 514 } 515 516 void SkXfermode::xfer4444(SkPMColor16* SK_RESTRICT dst, 517 const SkPMColor* SK_RESTRICT src, int count, 518 const SkAlpha* SK_RESTRICT aa) const { 519 SkASSERT(dst && src && count >= 0); 520 521 if (NULL == aa) { 522 for (int i = count - 1; i >= 0; --i) { 523 SkPMColor dstC = SkPixel4444ToPixel32(dst[i]); 524 dst[i] = SkPixel32ToPixel4444(this->xferColor(src[i], dstC)); 525 } 526 } else { 527 for (int i = count - 1; i >= 0; --i) { 528 unsigned a = aa[i]; 529 if (0 != a) { 530 SkPMColor dstC = SkPixel4444ToPixel32(dst[i]); 531 SkPMColor C = this->xferColor(src[i], dstC); 532 if (0xFF != a) { 533 C = SkFourByteInterp(C, dstC, a); 534 } 535 dst[i] = SkPixel32ToPixel4444(C); 536 } 537 } 538 } 539 } 540 541 void SkXfermode::xferA8(SkAlpha* SK_RESTRICT dst, 542 const SkPMColor src[], int count, 543 const SkAlpha* SK_RESTRICT aa) const { 544 SkASSERT(dst && src && count >= 0); 545 546 if (NULL == aa) { 547 for (int i = count - 1; i >= 0; --i) { 548 SkPMColor res = this->xferColor(src[i], (dst[i] << SK_A32_SHIFT)); 549 dst[i] = SkToU8(SkGetPackedA32(res)); 550 } 551 } else { 552 for (int i = count - 1; i >= 0; --i) { 553 unsigned a = aa[i]; 554 if (0 != a) { 555 SkAlpha dstA = dst[i]; 556 unsigned A = SkGetPackedA32(this->xferColor(src[i], 557 (SkPMColor)(dstA << SK_A32_SHIFT))); 558 if (0xFF != a) { 559 A = SkAlphaBlend(A, dstA, SkAlpha255To256(a)); 560 } 561 dst[i] = SkToU8(A); 562 } 563 } 564 } 565 } 566 567 /////////////////////////////////////////////////////////////////////////////// 568 569 void SkProcXfermode::xfer32(SkPMColor* SK_RESTRICT dst, 570 const SkPMColor* SK_RESTRICT src, int count, 571 const SkAlpha* SK_RESTRICT aa) const { 572 SkASSERT(dst && src && count >= 0); 573 574 SkXfermodeProc proc = fProc; 575 576 if (NULL != proc) { 577 if (NULL == aa) { 578 for (int i = count - 1; i >= 0; --i) { 579 dst[i] = proc(src[i], dst[i]); 580 } 581 } else { 582 for (int i = count - 1; i >= 0; --i) { 583 unsigned a = aa[i]; 584 if (0 != a) { 585 SkPMColor dstC = dst[i]; 586 SkPMColor C = proc(src[i], dstC); 587 if (a != 0xFF) { 588 C = SkFourByteInterp(C, dstC, a); 589 } 590 dst[i] = C; 591 } 592 } 593 } 594 } 595 } 596 597 void SkProcXfermode::xfer16(uint16_t* SK_RESTRICT dst, 598 const SkPMColor* SK_RESTRICT src, int count, 599 const SkAlpha* SK_RESTRICT aa) const { 600 SkASSERT(dst && src && count >= 0); 601 602 SkXfermodeProc proc = fProc; 603 604 if (NULL != proc) { 605 if (NULL == aa) { 606 for (int i = count - 1; i >= 0; --i) { 607 SkPMColor dstC = SkPixel16ToPixel32(dst[i]); 608 dst[i] = SkPixel32ToPixel16_ToU16(proc(src[i], dstC)); 609 } 610 } else { 611 for (int i = count - 1; i >= 0; --i) { 612 unsigned a = aa[i]; 613 if (0 != a) { 614 SkPMColor dstC = SkPixel16ToPixel32(dst[i]); 615 SkPMColor C = proc(src[i], dstC); 616 if (0xFF != a) { 617 C = SkFourByteInterp(C, dstC, a); 618 } 619 dst[i] = SkPixel32ToPixel16_ToU16(C); 620 } 621 } 622 } 623 } 624 } 625 626 void SkProcXfermode::xfer4444(SkPMColor16* SK_RESTRICT dst, 627 const SkPMColor* SK_RESTRICT src, int count, 628 const SkAlpha* SK_RESTRICT aa) const { 629 SkASSERT(dst && src && count >= 0); 630 631 SkXfermodeProc proc = fProc; 632 633 if (NULL != proc) { 634 if (NULL == aa) { 635 for (int i = count - 1; i >= 0; --i) { 636 SkPMColor dstC = SkPixel4444ToPixel32(dst[i]); 637 dst[i] = SkPixel32ToPixel4444(proc(src[i], dstC)); 638 } 639 } else { 640 for (int i = count - 1; i >= 0; --i) { 641 unsigned a = aa[i]; 642 if (0 != a) { 643 SkPMColor dstC = SkPixel4444ToPixel32(dst[i]); 644 SkPMColor C = proc(src[i], dstC); 645 if (0xFF != a) { 646 C = SkFourByteInterp(C, dstC, a); 647 } 648 dst[i] = SkPixel32ToPixel4444(C); 649 } 650 } 651 } 652 } 653 } 654 655 void SkProcXfermode::xferA8(SkAlpha* SK_RESTRICT dst, 656 const SkPMColor* SK_RESTRICT src, int count, 657 const SkAlpha* SK_RESTRICT aa) const { 658 SkASSERT(dst && src && count >= 0); 659 660 SkXfermodeProc proc = fProc; 661 662 if (NULL != proc) { 663 if (NULL == aa) { 664 for (int i = count - 1; i >= 0; --i) { 665 SkPMColor res = proc(src[i], dst[i] << SK_A32_SHIFT); 666 dst[i] = SkToU8(SkGetPackedA32(res)); 667 } 668 } else { 669 for (int i = count - 1; i >= 0; --i) { 670 unsigned a = aa[i]; 671 if (0 != a) { 672 SkAlpha dstA = dst[i]; 673 SkPMColor res = proc(src[i], dstA << SK_A32_SHIFT); 674 unsigned A = SkGetPackedA32(res); 675 if (0xFF != a) { 676 A = SkAlphaBlend(A, dstA, SkAlpha255To256(a)); 677 } 678 dst[i] = SkToU8(A); 679 } 680 } 681 } 682 } 683 } 684 685 SkProcXfermode::SkProcXfermode(SkFlattenableReadBuffer& buffer) 686 : SkXfermode(buffer) { 687 fProc = NULL; 688 if (!buffer.isCrossProcess()) { 689 fProc = (SkXfermodeProc)buffer.readFunctionPtr(); 690 } 691 } 692 693 void SkProcXfermode::flatten(SkFlattenableWriteBuffer& buffer) const { 694 this->INHERITED::flatten(buffer); 695 if (!buffer.isCrossProcess()) { 696 buffer.writeFunctionPtr((void*)fProc); 697 } 698 } 699 700 #ifdef SK_DEVELOPER 701 void SkProcXfermode::toString(SkString* str) const { 702 str->appendf("SkProcXfermode: %p", fProc); 703 } 704 #endif 705 706 /////////////////////////////////////////////////////////////////////////////// 707 /////////////////////////////////////////////////////////////////////////////// 708 709 class SkProcCoeffXfermode : public SkProcXfermode { 710 public: 711 SkProcCoeffXfermode(const ProcCoeff& rec, Mode mode) 712 : INHERITED(rec.fProc) { 713 fMode = mode; 714 // these may be valid, or may be CANNOT_USE_COEFF 715 fSrcCoeff = rec.fSC; 716 fDstCoeff = rec.fDC; 717 } 718 719 virtual bool asMode(Mode* mode) const SK_OVERRIDE { 720 if (mode) { 721 *mode = fMode; 722 } 723 return true; 724 } 725 726 virtual bool asCoeff(Coeff* sc, Coeff* dc) const SK_OVERRIDE { 727 if (CANNOT_USE_COEFF == fSrcCoeff) { 728 return false; 729 } 730 731 if (sc) { 732 *sc = fSrcCoeff; 733 } 734 if (dc) { 735 *dc = fDstCoeff; 736 } 737 return true; 738 } 739 740 SK_DEVELOPER_TO_STRING() 741 SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkProcCoeffXfermode) 742 743 protected: 744 SkProcCoeffXfermode(SkFlattenableReadBuffer& buffer) : INHERITED(buffer) { 745 fMode = (SkXfermode::Mode)buffer.read32(); 746 747 const ProcCoeff& rec = gProcCoeffs[fMode]; 748 // these may be valid, or may be CANNOT_USE_COEFF 749 fSrcCoeff = rec.fSC; 750 fDstCoeff = rec.fDC; 751 // now update our function-ptr in the super class 752 this->INHERITED::setProc(rec.fProc); 753 } 754 755 virtual void flatten(SkFlattenableWriteBuffer& buffer) const SK_OVERRIDE { 756 this->INHERITED::flatten(buffer); 757 buffer.write32(fMode); 758 } 759 760 private: 761 Mode fMode; 762 Coeff fSrcCoeff, fDstCoeff; 763 764 typedef SkProcXfermode INHERITED; 765 }; 766 767 #ifdef SK_DEVELOPER 768 void SkProcCoeffXfermode::toString(SkString* str) const { 769 str->append("SkProcCoeffXfermode: "); 770 771 const char *gModeStrings[kLastMode+1] = { 772 "Clear", "Src", "Dst", "SrcOver", "DstOver", "SrcIn", "DstIn", 773 "SrcOut", "DstOut", "SrcATop", "DstATop", "Xor", "Plus", 774 "Modulate", "Screen", "Overlay", "Darken", "Lighten", "ColorDodge", 775 "ColorBurn", "HardLight", "SoftLight", "Difference", "Exclusion" 776 }; 777 778 str->append("mode: "); 779 str->append(gModeStrings[fMode]); 780 781 static const char* gCoeffStrings[kCoeffCount] = { 782 "Zero", "One", "SC", "ISC", "DC", "IDC", "SA", "ISA", "DA", "IDA" 783 }; 784 785 str->append(" src: "); 786 if (CANNOT_USE_COEFF == fSrcCoeff) { 787 str->append("can't use"); 788 } else { 789 str->append(gCoeffStrings[fSrcCoeff]); 790 } 791 792 str->append(" dst: "); 793 if (CANNOT_USE_COEFF == fDstCoeff) { 794 str->append("can't use"); 795 } else { 796 str->append(gCoeffStrings[fDstCoeff]); 797 } 798 } 799 #endif 800 801 /////////////////////////////////////////////////////////////////////////////// 802 803 class SkClearXfermode : public SkProcCoeffXfermode { 804 public: 805 SkClearXfermode(const ProcCoeff& rec) : SkProcCoeffXfermode(rec, kClear_Mode) {} 806 807 virtual void xfer32(SkPMColor*, const SkPMColor*, int, const SkAlpha*) const SK_OVERRIDE; 808 virtual void xferA8(SkAlpha*, const SkPMColor*, int, const SkAlpha*) const SK_OVERRIDE; 809 810 SK_DEVELOPER_TO_STRING() 811 SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkClearXfermode) 812 813 private: 814 SkClearXfermode(SkFlattenableReadBuffer& buffer) 815 : SkProcCoeffXfermode(buffer) {} 816 817 typedef SkProcCoeffXfermode INHERITED; 818 }; 819 820 void SkClearXfermode::xfer32(SkPMColor* SK_RESTRICT dst, 821 const SkPMColor* SK_RESTRICT, int count, 822 const SkAlpha* SK_RESTRICT aa) const { 823 SkASSERT(dst && count >= 0); 824 825 if (NULL == aa) { 826 memset(dst, 0, count << 2); 827 } else { 828 for (int i = count - 1; i >= 0; --i) { 829 unsigned a = aa[i]; 830 if (0xFF == a) { 831 dst[i] = 0; 832 } else if (a != 0) { 833 dst[i] = SkAlphaMulQ(dst[i], SkAlpha255To256(255 - a)); 834 } 835 } 836 } 837 } 838 void SkClearXfermode::xferA8(SkAlpha* SK_RESTRICT dst, 839 const SkPMColor* SK_RESTRICT, int count, 840 const SkAlpha* SK_RESTRICT aa) const { 841 SkASSERT(dst && count >= 0); 842 843 if (NULL == aa) { 844 memset(dst, 0, count); 845 } else { 846 for (int i = count - 1; i >= 0; --i) { 847 unsigned a = aa[i]; 848 if (0xFF == a) { 849 dst[i] = 0; 850 } else if (0 != a) { 851 dst[i] = SkAlphaMulAlpha(dst[i], 255 - a); 852 } 853 } 854 } 855 } 856 857 #ifdef SK_DEVELOPER 858 void SkClearXfermode::toString(SkString* str) const { 859 this->INHERITED::toString(str); 860 } 861 #endif 862 863 /////////////////////////////////////////////////////////////////////////////// 864 865 class SkSrcXfermode : public SkProcCoeffXfermode { 866 public: 867 SkSrcXfermode(const ProcCoeff& rec) : SkProcCoeffXfermode(rec, kSrc_Mode) {} 868 869 virtual void xfer32(SkPMColor*, const SkPMColor*, int, const SkAlpha*) const SK_OVERRIDE; 870 virtual void xferA8(SkAlpha*, const SkPMColor*, int, const SkAlpha*) const SK_OVERRIDE; 871 872 SK_DEVELOPER_TO_STRING() 873 SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkSrcXfermode) 874 875 private: 876 SkSrcXfermode(SkFlattenableReadBuffer& buffer) 877 : SkProcCoeffXfermode(buffer) {} 878 879 typedef SkProcCoeffXfermode INHERITED; 880 }; 881 882 void SkSrcXfermode::xfer32(SkPMColor* SK_RESTRICT dst, 883 const SkPMColor* SK_RESTRICT src, int count, 884 const SkAlpha* SK_RESTRICT aa) const { 885 SkASSERT(dst && src && count >= 0); 886 887 if (NULL == aa) { 888 memcpy(dst, src, count << 2); 889 } else { 890 for (int i = count - 1; i >= 0; --i) { 891 unsigned a = aa[i]; 892 if (a == 0xFF) { 893 dst[i] = src[i]; 894 } else if (a != 0) { 895 dst[i] = SkFourByteInterp(src[i], dst[i], a); 896 } 897 } 898 } 899 } 900 901 void SkSrcXfermode::xferA8(SkAlpha* SK_RESTRICT dst, 902 const SkPMColor* SK_RESTRICT src, int count, 903 const SkAlpha* SK_RESTRICT aa) const { 904 SkASSERT(dst && src && count >= 0); 905 906 if (NULL == aa) { 907 for (int i = count - 1; i >= 0; --i) { 908 dst[i] = SkToU8(SkGetPackedA32(src[i])); 909 } 910 } else { 911 for (int i = count - 1; i >= 0; --i) { 912 unsigned a = aa[i]; 913 if (0 != a) { 914 unsigned srcA = SkGetPackedA32(src[i]); 915 if (a == 0xFF) { 916 dst[i] = SkToU8(srcA); 917 } else { 918 dst[i] = SkToU8(SkAlphaBlend(srcA, dst[i], a)); 919 } 920 } 921 } 922 } 923 } 924 #ifdef SK_DEVELOPER 925 void SkSrcXfermode::toString(SkString* str) const { 926 this->INHERITED::toString(str); 927 } 928 #endif 929 930 /////////////////////////////////////////////////////////////////////////////// 931 932 class SkDstInXfermode : public SkProcCoeffXfermode { 933 public: 934 SkDstInXfermode(const ProcCoeff& rec) : SkProcCoeffXfermode(rec, kDstIn_Mode) {} 935 936 virtual void xfer32(SkPMColor*, const SkPMColor*, int, const SkAlpha*) const SK_OVERRIDE; 937 938 SK_DEVELOPER_TO_STRING() 939 SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkDstInXfermode) 940 941 private: 942 SkDstInXfermode(SkFlattenableReadBuffer& buffer) : INHERITED(buffer) {} 943 944 typedef SkProcCoeffXfermode INHERITED; 945 }; 946 947 void SkDstInXfermode::xfer32(SkPMColor* SK_RESTRICT dst, 948 const SkPMColor* SK_RESTRICT src, int count, 949 const SkAlpha* SK_RESTRICT aa) const { 950 SkASSERT(dst && src); 951 952 if (count <= 0) { 953 return; 954 } 955 if (NULL != aa) { 956 return this->INHERITED::xfer32(dst, src, count, aa); 957 } 958 959 do { 960 unsigned a = SkGetPackedA32(*src); 961 *dst = SkAlphaMulQ(*dst, SkAlpha255To256(a)); 962 dst++; 963 src++; 964 } while (--count != 0); 965 } 966 967 #ifdef SK_DEVELOPER 968 void SkDstInXfermode::toString(SkString* str) const { 969 this->INHERITED::toString(str); 970 } 971 #endif 972 973 /////////////////////////////////////////////////////////////////////////////// 974 975 class SkDstOutXfermode : public SkProcCoeffXfermode { 976 public: 977 SkDstOutXfermode(const ProcCoeff& rec) : SkProcCoeffXfermode(rec, kDstOut_Mode) {} 978 979 virtual void xfer32(SkPMColor*, const SkPMColor*, int, const SkAlpha*) const SK_OVERRIDE; 980 981 SK_DEVELOPER_TO_STRING() 982 SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkDstOutXfermode) 983 984 private: 985 SkDstOutXfermode(SkFlattenableReadBuffer& buffer) 986 : INHERITED(buffer) {} 987 988 typedef SkProcCoeffXfermode INHERITED; 989 }; 990 991 void SkDstOutXfermode::xfer32(SkPMColor* SK_RESTRICT dst, 992 const SkPMColor* SK_RESTRICT src, int count, 993 const SkAlpha* SK_RESTRICT aa) const { 994 SkASSERT(dst && src); 995 996 if (count <= 0) { 997 return; 998 } 999 if (NULL != aa) { 1000 return this->INHERITED::xfer32(dst, src, count, aa); 1001 } 1002 1003 do { 1004 unsigned a = SkGetPackedA32(*src); 1005 *dst = SkAlphaMulQ(*dst, SkAlpha255To256(255 - a)); 1006 dst++; 1007 src++; 1008 } while (--count != 0); 1009 } 1010 1011 #ifdef SK_DEVELOPER 1012 void SkDstOutXfermode::toString(SkString* str) const { 1013 this->INHERITED::toString(str); 1014 } 1015 #endif 1016 1017 /////////////////////////////////////////////////////////////////////////////// 1018 1019 SkXfermode* SkXfermode::Create(Mode mode) { 1020 SkASSERT(SK_ARRAY_COUNT(gProcCoeffs) == kModeCount); 1021 SkASSERT((unsigned)mode < kModeCount); 1022 1023 const ProcCoeff& rec = gProcCoeffs[mode]; 1024 1025 switch (mode) { 1026 case kClear_Mode: 1027 return SkNEW_ARGS(SkClearXfermode, (rec)); 1028 case kSrc_Mode: 1029 return SkNEW_ARGS(SkSrcXfermode, (rec)); 1030 case kSrcOver_Mode: 1031 return NULL; 1032 case kDstIn_Mode: 1033 return SkNEW_ARGS(SkDstInXfermode, (rec)); 1034 case kDstOut_Mode: 1035 return SkNEW_ARGS(SkDstOutXfermode, (rec)); 1036 default: 1037 return SkNEW_ARGS(SkProcCoeffXfermode, (rec, mode)); 1038 } 1039 } 1040 1041 SkXfermodeProc SkXfermode::GetProc(Mode mode) { 1042 SkXfermodeProc proc = NULL; 1043 if ((unsigned)mode < kModeCount) { 1044 proc = gProcCoeffs[mode].fProc; 1045 } 1046 return proc; 1047 } 1048 1049 bool SkXfermode::ModeAsCoeff(Mode mode, Coeff* src, Coeff* dst) { 1050 SkASSERT(SK_ARRAY_COUNT(gProcCoeffs) == kModeCount); 1051 1052 if ((unsigned)mode >= (unsigned)kModeCount) { 1053 // illegal mode parameter 1054 return false; 1055 } 1056 1057 const ProcCoeff& rec = gProcCoeffs[mode]; 1058 1059 if (CANNOT_USE_COEFF == rec.fSC) { 1060 return false; 1061 } 1062 1063 SkASSERT(CANNOT_USE_COEFF != rec.fDC); 1064 if (src) { 1065 *src = rec.fSC; 1066 } 1067 if (dst) { 1068 *dst = rec.fDC; 1069 } 1070 return true; 1071 } 1072 1073 bool SkXfermode::AsMode(const SkXfermode* xfer, Mode* mode) { 1074 if (NULL == xfer) { 1075 if (mode) { 1076 *mode = kSrcOver_Mode; 1077 } 1078 return true; 1079 } 1080 return xfer->asMode(mode); 1081 } 1082 1083 bool SkXfermode::AsCoeff(const SkXfermode* xfer, Coeff* src, Coeff* dst) { 1084 if (NULL == xfer) { 1085 return ModeAsCoeff(kSrcOver_Mode, src, dst); 1086 } 1087 return xfer->asCoeff(src, dst); 1088 } 1089 1090 bool SkXfermode::IsMode(const SkXfermode* xfer, Mode mode) { 1091 // if xfer==null then the mode is srcover 1092 Mode m = kSrcOver_Mode; 1093 if (xfer && !xfer->asMode(&m)) { 1094 return false; 1095 } 1096 return mode == m; 1097 } 1098 1099 /////////////////////////////////////////////////////////////////////////////// 1100 //////////// 16bit xfermode procs 1101 1102 #ifdef SK_DEBUG 1103 static bool require_255(SkPMColor src) { return SkGetPackedA32(src) == 0xFF; } 1104 static bool require_0(SkPMColor src) { return SkGetPackedA32(src) == 0; } 1105 #endif 1106 1107 static uint16_t src_modeproc16_255(SkPMColor src, uint16_t dst) { 1108 SkASSERT(require_255(src)); 1109 return SkPixel32ToPixel16(src); 1110 } 1111 1112 static uint16_t dst_modeproc16(SkPMColor src, uint16_t dst) { 1113 return dst; 1114 } 1115 1116 static uint16_t srcover_modeproc16_0(SkPMColor src, uint16_t dst) { 1117 SkASSERT(require_0(src)); 1118 return dst; 1119 } 1120 1121 static uint16_t srcover_modeproc16_255(SkPMColor src, uint16_t dst) { 1122 SkASSERT(require_255(src)); 1123 return SkPixel32ToPixel16(src); 1124 } 1125 1126 static uint16_t dstover_modeproc16_0(SkPMColor src, uint16_t dst) { 1127 SkASSERT(require_0(src)); 1128 return dst; 1129 } 1130 1131 static uint16_t dstover_modeproc16_255(SkPMColor src, uint16_t dst) { 1132 SkASSERT(require_255(src)); 1133 return dst; 1134 } 1135 1136 static uint16_t srcin_modeproc16_255(SkPMColor src, uint16_t dst) { 1137 SkASSERT(require_255(src)); 1138 return SkPixel32ToPixel16(src); 1139 } 1140 1141 static uint16_t dstin_modeproc16_255(SkPMColor src, uint16_t dst) { 1142 SkASSERT(require_255(src)); 1143 return dst; 1144 } 1145 1146 static uint16_t dstout_modeproc16_0(SkPMColor src, uint16_t dst) { 1147 SkASSERT(require_0(src)); 1148 return dst; 1149 } 1150 1151 static uint16_t srcatop_modeproc16(SkPMColor src, uint16_t dst) { 1152 unsigned isa = 255 - SkGetPackedA32(src); 1153 1154 return SkPackRGB16( 1155 SkPacked32ToR16(src) + SkAlphaMulAlpha(SkGetPackedR16(dst), isa), 1156 SkPacked32ToG16(src) + SkAlphaMulAlpha(SkGetPackedG16(dst), isa), 1157 SkPacked32ToB16(src) + SkAlphaMulAlpha(SkGetPackedB16(dst), isa)); 1158 } 1159 1160 static uint16_t srcatop_modeproc16_0(SkPMColor src, uint16_t dst) { 1161 SkASSERT(require_0(src)); 1162 return dst; 1163 } 1164 1165 static uint16_t srcatop_modeproc16_255(SkPMColor src, uint16_t dst) { 1166 SkASSERT(require_255(src)); 1167 return SkPixel32ToPixel16(src); 1168 } 1169 1170 static uint16_t dstatop_modeproc16_255(SkPMColor src, uint16_t dst) { 1171 SkASSERT(require_255(src)); 1172 return dst; 1173 } 1174 1175 /********* 1176 darken and lighten boil down to this. 1177 1178 darken = (1 - Sa) * Dc + min(Sc, Dc) 1179 lighten = (1 - Sa) * Dc + max(Sc, Dc) 1180 1181 if (Sa == 0) these become 1182 darken = Dc + min(0, Dc) = 0 1183 lighten = Dc + max(0, Dc) = Dc 1184 1185 if (Sa == 1) these become 1186 darken = min(Sc, Dc) 1187 lighten = max(Sc, Dc) 1188 */ 1189 1190 static uint16_t darken_modeproc16_0(SkPMColor src, uint16_t dst) { 1191 SkASSERT(require_0(src)); 1192 return 0; 1193 } 1194 1195 static uint16_t darken_modeproc16_255(SkPMColor src, uint16_t dst) { 1196 SkASSERT(require_255(src)); 1197 unsigned r = SkFastMin32(SkPacked32ToR16(src), SkGetPackedR16(dst)); 1198 unsigned g = SkFastMin32(SkPacked32ToG16(src), SkGetPackedG16(dst)); 1199 unsigned b = SkFastMin32(SkPacked32ToB16(src), SkGetPackedB16(dst)); 1200 return SkPackRGB16(r, g, b); 1201 } 1202 1203 static uint16_t lighten_modeproc16_0(SkPMColor src, uint16_t dst) { 1204 SkASSERT(require_0(src)); 1205 return dst; 1206 } 1207 1208 static uint16_t lighten_modeproc16_255(SkPMColor src, uint16_t dst) { 1209 SkASSERT(require_255(src)); 1210 unsigned r = SkMax32(SkPacked32ToR16(src), SkGetPackedR16(dst)); 1211 unsigned g = SkMax32(SkPacked32ToG16(src), SkGetPackedG16(dst)); 1212 unsigned b = SkMax32(SkPacked32ToB16(src), SkGetPackedB16(dst)); 1213 return SkPackRGB16(r, g, b); 1214 } 1215 1216 struct Proc16Rec { 1217 SkXfermodeProc16 fProc16_0; 1218 SkXfermodeProc16 fProc16_255; 1219 SkXfermodeProc16 fProc16_General; 1220 }; 1221 1222 static const Proc16Rec gModeProcs16[] = { 1223 { NULL, NULL, NULL }, // CLEAR 1224 { NULL, src_modeproc16_255, NULL }, 1225 { dst_modeproc16, dst_modeproc16, dst_modeproc16 }, 1226 { srcover_modeproc16_0, srcover_modeproc16_255, NULL }, 1227 { dstover_modeproc16_0, dstover_modeproc16_255, NULL }, 1228 { NULL, srcin_modeproc16_255, NULL }, 1229 { NULL, dstin_modeproc16_255, NULL }, 1230 { NULL, NULL, NULL },// SRC_OUT 1231 { dstout_modeproc16_0, NULL, NULL }, 1232 { srcatop_modeproc16_0, srcatop_modeproc16_255, srcatop_modeproc16 }, 1233 { NULL, dstatop_modeproc16_255, NULL }, 1234 { NULL, NULL, NULL }, // XOR 1235 1236 { NULL, NULL, NULL }, // plus 1237 { NULL, NULL, NULL }, // modulate 1238 { NULL, NULL, NULL }, // screen 1239 { NULL, NULL, NULL }, // overlay 1240 { darken_modeproc16_0, darken_modeproc16_255, NULL }, // darken 1241 { lighten_modeproc16_0, lighten_modeproc16_255, NULL }, // lighten 1242 { NULL, NULL, NULL }, // colordodge 1243 { NULL, NULL, NULL }, // colorburn 1244 { NULL, NULL, NULL }, // hardlight 1245 { NULL, NULL, NULL }, // softlight 1246 { NULL, NULL, NULL }, // difference 1247 { NULL, NULL, NULL }, // exclusion 1248 }; 1249 1250 SkXfermodeProc16 SkXfermode::GetProc16(Mode mode, SkColor srcColor) { 1251 SkXfermodeProc16 proc16 = NULL; 1252 if ((unsigned)mode < kModeCount) { 1253 const Proc16Rec& rec = gModeProcs16[mode]; 1254 unsigned a = SkColorGetA(srcColor); 1255 1256 if (0 == a) { 1257 proc16 = rec.fProc16_0; 1258 } else if (255 == a) { 1259 proc16 = rec.fProc16_255; 1260 } else { 1261 proc16 = rec.fProc16_General; 1262 } 1263 } 1264 return proc16; 1265 } 1266 1267 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkXfermode) 1268 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkProcCoeffXfermode) 1269 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkClearXfermode) 1270 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkSrcXfermode) 1271 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkDstInXfermode) 1272 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkDstOutXfermode) 1273 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END 1274