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 "SkBlitRow.h" 11 #include "SkColorFilter.h" 12 #include "SkColorPriv.h" 13 #include "SkUtils.h" 14 15 #define ILLEGAL_XFERMODE_MODE ((SkXfermode::Mode)-1) 16 17 // baseclass for filters that store a color and mode 18 class SkModeColorFilter : public SkColorFilter { 19 public: 20 SkModeColorFilter(SkColor color) { 21 fColor = color; 22 fMode = ILLEGAL_XFERMODE_MODE; 23 24 fPMColor = SkPreMultiplyColor(fColor); 25 } 26 27 SkModeColorFilter(SkColor color, SkXfermode::Mode mode) { 28 fColor = color; 29 fMode = mode; 30 31 fPMColor = SkPreMultiplyColor(fColor); 32 }; 33 34 virtual bool asColorMode(SkColor* color, SkXfermode::Mode* mode) { 35 if (ILLEGAL_XFERMODE_MODE == fMode) { 36 return false; 37 } 38 39 if (color) { 40 *color = fColor; 41 } 42 if (mode) { 43 *mode = fMode; 44 } 45 return true; 46 } 47 48 SkColor getColor() const { return fColor; } 49 SkXfermode::Mode getMode() const { return fMode; } 50 bool isModeValid() const { return ILLEGAL_XFERMODE_MODE != fMode; } 51 52 protected: 53 virtual void flatten(SkFlattenableWriteBuffer& buffer) { 54 this->INHERITED::flatten(buffer); 55 buffer.write32(fColor); 56 buffer.write32(fMode); 57 } 58 59 SkModeColorFilter(SkFlattenableReadBuffer& buffer) { 60 fColor = buffer.readU32(); 61 fMode = (SkXfermode::Mode)buffer.readU32(); 62 63 fPMColor = SkPreMultiplyColor(fColor); 64 } 65 66 // cache of fColor in premultiply space 67 SkPMColor fPMColor; 68 69 private: 70 SkColor fColor; 71 SkXfermode::Mode fMode; 72 73 typedef SkColorFilter INHERITED; 74 }; 75 76 class Src_SkModeColorFilter : public SkModeColorFilter { 77 public: 78 Src_SkModeColorFilter(SkColor color) : INHERITED(color, SkXfermode::kSrc_Mode) {} 79 80 virtual uint32_t getFlags() { 81 if (SkGetPackedA32(fPMColor) == 0xFF) { 82 return kAlphaUnchanged_Flag | kHasFilter16_Flag; 83 } else { 84 return 0; 85 } 86 } 87 88 virtual void filterSpan(const SkPMColor shader[], int count, 89 SkPMColor result[]) { 90 sk_memset32(result, fPMColor, count); 91 } 92 93 virtual void filterSpan16(const uint16_t shader[], int count, 94 uint16_t result[]) { 95 SkASSERT(this->getFlags() & kHasFilter16_Flag); 96 sk_memset16(result, SkPixel32ToPixel16(fPMColor), count); 97 } 98 99 static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) { 100 return SkNEW_ARGS(Src_SkModeColorFilter, (buffer)); 101 } 102 103 protected: 104 virtual Factory getFactory() { return CreateProc; } 105 106 Src_SkModeColorFilter(SkFlattenableReadBuffer& buffer) 107 : INHERITED(buffer) {} 108 109 private: 110 typedef SkModeColorFilter INHERITED; 111 }; 112 113 class SrcOver_SkModeColorFilter : public SkModeColorFilter { 114 public: 115 SrcOver_SkModeColorFilter(SkColor color) 116 : INHERITED(color, SkXfermode::kSrcOver_Mode) { 117 fColor32Proc = NULL; 118 } 119 120 virtual uint32_t getFlags() { 121 if (SkGetPackedA32(fPMColor) == 0xFF) { 122 return kAlphaUnchanged_Flag | kHasFilter16_Flag; 123 } else { 124 return 0; 125 } 126 } 127 128 virtual void filterSpan(const SkPMColor shader[], int count, 129 SkPMColor result[]) { 130 if (NULL == fColor32Proc) { 131 fColor32Proc = SkBlitRow::ColorProcFactory(); 132 } 133 fColor32Proc(result, shader, count, fPMColor); 134 } 135 136 virtual void filterSpan16(const uint16_t shader[], int count, 137 uint16_t result[]) { 138 SkASSERT(this->getFlags() & kHasFilter16_Flag); 139 sk_memset16(result, SkPixel32ToPixel16(fPMColor), count); 140 } 141 142 static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) { 143 return SkNEW_ARGS(SrcOver_SkModeColorFilter, (buffer)); 144 } 145 146 protected: 147 virtual Factory getFactory() { return CreateProc; } 148 149 SrcOver_SkModeColorFilter(SkFlattenableReadBuffer& buffer) 150 : INHERITED(buffer), fColor32Proc(NULL) {} 151 152 private: 153 154 SkBlitRow::ColorProc fColor32Proc; 155 156 typedef SkModeColorFilter INHERITED; 157 }; 158 159 /////////////////////////////////////////////////////////////////////////////// 160 161 class Proc_SkModeColorFilter : public SkModeColorFilter { 162 public: 163 Proc_SkModeColorFilter(SkColor color, SkXfermode::Mode mode) : INHERITED(color, mode) { 164 fProc = SkXfermode::GetProc(mode); 165 fProc16 = SkXfermode::GetProc16(mode, color); 166 } 167 168 Proc_SkModeColorFilter(SkColor color, 169 SkXfermodeProc proc, SkXfermodeProc16 proc16) 170 : INHERITED(color, ILLEGAL_XFERMODE_MODE) { 171 fProc = proc; 172 fProc16 = proc16; 173 } 174 175 virtual uint32_t getFlags() { 176 return fProc16 ? (kAlphaUnchanged_Flag | kHasFilter16_Flag) : 0; 177 } 178 179 virtual void filterSpan(const SkPMColor shader[], int count, 180 SkPMColor result[]) { 181 SkPMColor color = fPMColor; 182 SkXfermodeProc proc = fProc; 183 184 for (int i = 0; i < count; i++) { 185 result[i] = proc(color, shader[i]); 186 } 187 } 188 189 virtual void filterSpan16(const uint16_t shader[], int count, 190 uint16_t result[]) { 191 SkASSERT(this->getFlags() & kHasFilter16_Flag); 192 193 SkPMColor color = fPMColor; 194 SkXfermodeProc16 proc16 = fProc16; 195 196 for (int i = 0; i < count; i++) { 197 result[i] = proc16(color, shader[i]); 198 } 199 } 200 201 static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) { 202 return SkNEW_ARGS(Proc_SkModeColorFilter, (buffer)); 203 } 204 205 protected: 206 virtual void flatten(SkFlattenableWriteBuffer& buffer) { 207 this->INHERITED::flatten(buffer); 208 buffer.writeFunctionPtr((void*)fProc); 209 buffer.writeFunctionPtr((void*)fProc16); 210 } 211 212 virtual Factory getFactory() { 213 return CreateProc; 214 } 215 216 Proc_SkModeColorFilter(SkFlattenableReadBuffer& buffer) : INHERITED(buffer) { 217 fProc = (SkXfermodeProc) buffer.readFunctionPtr(); 218 fProc16 = (SkXfermodeProc16) buffer.readFunctionPtr(); 219 } 220 221 private: 222 SkXfermodeProc fProc; 223 SkXfermodeProc16 fProc16; 224 225 typedef SkModeColorFilter INHERITED; 226 }; 227 228 SkColorFilter* SkColorFilter::CreateProcFilter(SkColor color, 229 SkXfermodeProc proc, 230 SkXfermodeProc16 proc16) { 231 return proc ? 232 SkNEW_ARGS(Proc_SkModeColorFilter, (color, proc, proc16)) : 233 NULL; 234 } 235 236 /////////////////////////////////////////////////////////////////////////////// 237 238 SkColorFilter* SkColorFilter::CreateModeFilter(SkColor color, 239 SkXfermode::Mode mode) { 240 unsigned alpha = SkColorGetA(color); 241 242 // first collaps some modes if possible 243 244 if (SkXfermode::kClear_Mode == mode) { 245 color = 0; 246 mode = SkXfermode::kSrc_Mode; 247 } else if (SkXfermode::kSrcOver_Mode == mode) { 248 if (0 == alpha) { 249 mode = SkXfermode::kDst_Mode; 250 } else if (255 == alpha) { 251 mode = SkXfermode::kSrc_Mode; 252 } 253 // else just stay srcover 254 } 255 256 // weed out combinations that are noops, and just return null 257 if (SkXfermode::kDst_Mode == mode || 258 (0 == alpha && (SkXfermode::kSrcOver_Mode == mode || 259 SkXfermode::kDstOver_Mode == mode || 260 SkXfermode::kDstOut_Mode == mode || 261 SkXfermode::kSrcATop_Mode == mode || 262 SkXfermode::kXor_Mode == mode || 263 SkXfermode::kDarken_Mode == mode)) || 264 (0xFF == alpha && SkXfermode::kDstIn_Mode == mode)) { 265 return NULL; 266 } 267 268 switch (mode) { 269 case SkXfermode::kSrc_Mode: 270 return SkNEW_ARGS(Src_SkModeColorFilter, (color)); 271 case SkXfermode::kSrcOver_Mode: 272 return SkNEW_ARGS(SrcOver_SkModeColorFilter, (color)); 273 default: 274 return SkNEW_ARGS(Proc_SkModeColorFilter, (color, mode)); 275 } 276 } 277 278 /////////////////////////////////////////////////////////////////////////////// 279 280 static inline unsigned pin(unsigned value, unsigned max) { 281 if (value > max) { 282 value = max; 283 } 284 return value; 285 } 286 287 static inline unsigned SkUClampMax(unsigned value, unsigned max) { 288 SkASSERT((int32_t)value >= 0); 289 SkASSERT((int32_t)max >= 0); 290 291 int diff = max - value; 292 // clear diff if diff is positive 293 diff &= diff >> 31; 294 295 return value + diff; 296 } 297 298 class SkLightingColorFilter : public SkColorFilter { 299 public: 300 SkLightingColorFilter(SkColor mul, SkColor add) : fMul(mul), fAdd(add) {} 301 302 virtual void filterSpan(const SkPMColor shader[], int count, 303 SkPMColor result[]) { 304 unsigned scaleR = SkAlpha255To256(SkColorGetR(fMul)); 305 unsigned scaleG = SkAlpha255To256(SkColorGetG(fMul)); 306 unsigned scaleB = SkAlpha255To256(SkColorGetB(fMul)); 307 308 unsigned addR = SkColorGetR(fAdd); 309 unsigned addG = SkColorGetG(fAdd); 310 unsigned addB = SkColorGetB(fAdd); 311 312 for (int i = 0; i < count; i++) { 313 SkPMColor c = shader[i]; 314 if (c) { 315 unsigned a = SkGetPackedA32(c); 316 unsigned scaleA = SkAlpha255To256(a); 317 unsigned r = pin(SkAlphaMul(SkGetPackedR32(c), scaleR) + SkAlphaMul(addR, scaleA), a); 318 unsigned g = pin(SkAlphaMul(SkGetPackedG32(c), scaleG) + SkAlphaMul(addG, scaleA), a); 319 unsigned b = pin(SkAlphaMul(SkGetPackedB32(c), scaleB) + SkAlphaMul(addB, scaleA), a); 320 c = SkPackARGB32(a, r, g, b); 321 } 322 result[i] = c; 323 } 324 } 325 326 static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) { 327 return SkNEW_ARGS(SkLightingColorFilter, (buffer)); 328 } 329 330 protected: 331 virtual void flatten(SkFlattenableWriteBuffer& buffer) { 332 this->INHERITED::flatten(buffer); 333 buffer.write32(fMul); 334 buffer.write32(fAdd); 335 } 336 337 virtual Factory getFactory() { 338 return CreateProc; 339 } 340 341 SkLightingColorFilter(SkFlattenableReadBuffer& buffer) { 342 fMul = buffer.readU32(); 343 fAdd = buffer.readU32(); 344 } 345 346 SkColor fMul, fAdd; 347 348 private: 349 typedef SkColorFilter INHERITED; 350 }; 351 352 class SkLightingColorFilter_JustAdd : public SkLightingColorFilter { 353 public: 354 SkLightingColorFilter_JustAdd(SkColor mul, SkColor add) 355 : INHERITED(mul, add) {} 356 357 virtual void filterSpan(const SkPMColor shader[], int count, 358 SkPMColor result[]) { 359 unsigned addR = SkColorGetR(fAdd); 360 unsigned addG = SkColorGetG(fAdd); 361 unsigned addB = SkColorGetB(fAdd); 362 363 for (int i = 0; i < count; i++) { 364 SkPMColor c = shader[i]; 365 if (c) { 366 unsigned a = SkGetPackedA32(c); 367 unsigned scaleA = SkAlpha255To256(a); 368 unsigned r = pin(SkGetPackedR32(c) + SkAlphaMul(addR, scaleA), a); 369 unsigned g = pin(SkGetPackedG32(c) + SkAlphaMul(addG, scaleA), a); 370 unsigned b = pin(SkGetPackedB32(c) + SkAlphaMul(addB, scaleA), a); 371 c = SkPackARGB32(a, r, g, b); 372 } 373 result[i] = c; 374 } 375 } 376 377 static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) { 378 return SkNEW_ARGS(SkLightingColorFilter_JustAdd, (buffer)); 379 } 380 381 protected: 382 virtual Factory getFactory() { return CreateProc; } 383 384 SkLightingColorFilter_JustAdd(SkFlattenableReadBuffer& buffer) 385 : INHERITED(buffer) {} 386 387 private: 388 typedef SkLightingColorFilter INHERITED; 389 }; 390 391 class SkLightingColorFilter_JustMul : public SkLightingColorFilter { 392 public: 393 SkLightingColorFilter_JustMul(SkColor mul, SkColor add) 394 : INHERITED(mul, add) {} 395 396 virtual void filterSpan(const SkPMColor shader[], int count, 397 SkPMColor result[]) { 398 unsigned scaleR = SkAlpha255To256(SkColorGetR(fMul)); 399 unsigned scaleG = SkAlpha255To256(SkColorGetG(fMul)); 400 unsigned scaleB = SkAlpha255To256(SkColorGetB(fMul)); 401 402 for (int i = 0; i < count; i++) { 403 SkPMColor c = shader[i]; 404 if (c) { 405 unsigned a = SkGetPackedA32(c); 406 unsigned r = SkAlphaMul(SkGetPackedR32(c), scaleR); 407 unsigned g = SkAlphaMul(SkGetPackedG32(c), scaleG); 408 unsigned b = SkAlphaMul(SkGetPackedB32(c), scaleB); 409 c = SkPackARGB32(a, r, g, b); 410 } 411 result[i] = c; 412 } 413 } 414 415 static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) { 416 return SkNEW_ARGS(SkLightingColorFilter_JustMul, (buffer)); 417 } 418 419 protected: 420 virtual Factory getFactory() { return CreateProc; } 421 422 SkLightingColorFilter_JustMul(SkFlattenableReadBuffer& buffer) 423 : INHERITED(buffer) {} 424 425 private: 426 typedef SkLightingColorFilter INHERITED; 427 }; 428 429 class SkLightingColorFilter_SingleMul : public SkLightingColorFilter { 430 public: 431 SkLightingColorFilter_SingleMul(SkColor mul, SkColor add) 432 : INHERITED(mul, add) { 433 SkASSERT(SkColorGetR(add) == 0); 434 SkASSERT(SkColorGetG(add) == 0); 435 SkASSERT(SkColorGetB(add) == 0); 436 SkASSERT(SkColorGetR(mul) == SkColorGetG(mul)); 437 SkASSERT(SkColorGetR(mul) == SkColorGetB(mul)); 438 } 439 440 virtual uint32_t getFlags() { 441 return this->INHERITED::getFlags() | (kAlphaUnchanged_Flag | kHasFilter16_Flag); 442 } 443 444 virtual void filterSpan16(const uint16_t shader[], int count, 445 uint16_t result[]) { 446 // all mul components are the same 447 unsigned scale = SkAlpha255To256(SkColorGetR(fMul)); 448 449 if (count > 0) { 450 do { 451 *result++ = SkAlphaMulRGB16(*shader++, scale); 452 } while (--count > 0); 453 } 454 } 455 456 static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) { 457 return SkNEW_ARGS(SkLightingColorFilter_SingleMul, (buffer)); 458 } 459 460 protected: 461 virtual Factory getFactory() { return CreateProc; } 462 463 SkLightingColorFilter_SingleMul(SkFlattenableReadBuffer& buffer) 464 : INHERITED(buffer) {} 465 466 private: 467 typedef SkLightingColorFilter INHERITED; 468 }; 469 470 class SkLightingColorFilter_NoPin : public SkLightingColorFilter { 471 public: 472 SkLightingColorFilter_NoPin(SkColor mul, SkColor add) 473 : INHERITED(mul, add) {} 474 475 virtual void filterSpan(const SkPMColor shader[], int count, 476 SkPMColor result[]) { 477 unsigned scaleR = SkAlpha255To256(SkColorGetR(fMul)); 478 unsigned scaleG = SkAlpha255To256(SkColorGetG(fMul)); 479 unsigned scaleB = SkAlpha255To256(SkColorGetB(fMul)); 480 481 unsigned addR = SkColorGetR(fAdd); 482 unsigned addG = SkColorGetG(fAdd); 483 unsigned addB = SkColorGetB(fAdd); 484 485 for (int i = 0; i < count; i++) { 486 SkPMColor c = shader[i]; 487 if (c) { 488 unsigned a = SkGetPackedA32(c); 489 unsigned scaleA = SkAlpha255To256(a); 490 unsigned r = SkAlphaMul(SkGetPackedR32(c), scaleR) + SkAlphaMul(addR, scaleA); 491 unsigned g = SkAlphaMul(SkGetPackedG32(c), scaleG) + SkAlphaMul(addG, scaleA); 492 unsigned b = SkAlphaMul(SkGetPackedB32(c), scaleB) + SkAlphaMul(addB, scaleA); 493 c = SkPackARGB32(a, r, g, b); 494 } 495 result[i] = c; 496 } 497 } 498 499 static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) { 500 return SkNEW_ARGS(SkLightingColorFilter_NoPin, (buffer)); 501 } 502 503 protected: 504 virtual Factory getFactory() { return CreateProc; } 505 506 SkLightingColorFilter_NoPin(SkFlattenableReadBuffer& buffer) 507 : INHERITED(buffer) {} 508 509 private: 510 typedef SkLightingColorFilter INHERITED; 511 }; 512 513 /////////////////////////////////////////////////////////////////////////////// 514 515 class SkSimpleColorFilter : public SkColorFilter { 516 public: 517 static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) { 518 return SkNEW(SkSimpleColorFilter); 519 } 520 521 protected: 522 void filterSpan(const SkPMColor src[], int count, SkPMColor result[]) { 523 if (result != src) { 524 memcpy(result, src, count * sizeof(SkPMColor)); 525 } 526 } 527 528 virtual void flatten(SkFlattenableWriteBuffer& buffer) {} 529 530 virtual Factory getFactory() { 531 return CreateProc; 532 } 533 534 }; 535 536 SkColorFilter* SkColorFilter::CreateLightingFilter(SkColor mul, SkColor add) { 537 mul &= 0x00FFFFFF; 538 add &= 0x00FFFFFF; 539 540 if (0xFFFFFF == mul) { 541 if (0 == add) { 542 return SkNEW(SkSimpleColorFilter); // no change to the colors 543 } else { 544 return SkNEW_ARGS(SkLightingColorFilter_JustAdd, (mul, add)); 545 } 546 } 547 548 if (0 == add) { 549 if (SkColorGetR(mul) == SkColorGetG(mul) && 550 SkColorGetR(mul) == SkColorGetB(mul)) { 551 return SkNEW_ARGS(SkLightingColorFilter_SingleMul, (mul, add)); 552 } else { 553 return SkNEW_ARGS(SkLightingColorFilter_JustMul, (mul, add)); 554 } 555 } 556 557 if (SkColorGetR(mul) + SkColorGetR(add) <= 255 && 558 SkColorGetG(mul) + SkColorGetG(add) <= 255 && 559 SkColorGetB(mul) + SkColorGetB(add) <= 255) { 560 return SkNEW_ARGS(SkLightingColorFilter_NoPin, (mul, add)); 561 } 562 563 return SkNEW_ARGS(SkLightingColorFilter, (mul, add)); 564 } 565 566 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkColorFilter) 567 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(Src_SkModeColorFilter) 568 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SrcOver_SkModeColorFilter) 569 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(Proc_SkModeColorFilter) 570 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLightingColorFilter) 571 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLightingColorFilter_JustAdd) 572 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLightingColorFilter_JustMul) 573 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLightingColorFilter_SingleMul) 574 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLightingColorFilter_NoPin) 575 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkSimpleColorFilter) 576 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END 577 578