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