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