Home | History | Annotate | Download | only in effects
      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