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 
     16 #define ILLEGAL_XFERMODE_MODE   ((SkXfermode::Mode)-1)
     17 
     18 // baseclass for filters that store a color and mode
     19 class SkModeColorFilter : public SkColorFilter {
     20 public:
     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 
     80 protected:
     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 
     93 private:
     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 
    110 class Src_SkModeColorFilter : public SkModeColorFilter {
    111 public:
    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 
    135 protected:
    136     Src_SkModeColorFilter(SkFlattenableReadBuffer& buffer)
    137         : INHERITED(buffer) {}
    138 
    139 private:
    140     typedef SkModeColorFilter INHERITED;
    141 };
    142 
    143 class SrcOver_SkModeColorFilter : public SkModeColorFilter {
    144 public:
    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 
    171 protected:
    172     SrcOver_SkModeColorFilter(SkFlattenableReadBuffer& buffer)
    173         : INHERITED(buffer) {
    174             fColor32Proc = SkBlitRow::ColorProcFactory();
    175         }
    176 
    177 private:
    178 
    179     SkBlitRow::ColorProc fColor32Proc;
    180 
    181     typedef SkModeColorFilter INHERITED;
    182 };
    183 
    184 ///////////////////////////////////////////////////////////////////////////////
    185 
    186 SkColorFilter* 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 
    228 static inline unsigned pin(unsigned value, unsigned max) {
    229     if (value > max) {
    230         value = max;
    231     }
    232     return value;
    233 }
    234 
    235 class SkLightingColorFilter : public SkColorFilter {
    236 public:
    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 
    265 protected:
    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 
    279 private:
    280     typedef SkColorFilter INHERITED;
    281 };
    282 
    283 class SkLightingColorFilter_JustAdd : public SkLightingColorFilter {
    284 public:
    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 
    310 protected:
    311     SkLightingColorFilter_JustAdd(SkFlattenableReadBuffer& buffer)
    312         : INHERITED(buffer) {}
    313 
    314 private:
    315     typedef SkLightingColorFilter INHERITED;
    316 };
    317 
    318 class SkLightingColorFilter_JustMul : public SkLightingColorFilter {
    319 public:
    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 
    344 protected:
    345     SkLightingColorFilter_JustMul(SkFlattenableReadBuffer& buffer)
    346         : INHERITED(buffer) {}
    347 
    348 private:
    349     typedef SkLightingColorFilter INHERITED;
    350 };
    351 
    352 class SkLightingColorFilter_SingleMul : public SkLightingColorFilter {
    353 public:
    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 
    381 protected:
    382     SkLightingColorFilter_SingleMul(SkFlattenableReadBuffer& buffer)
    383         : INHERITED(buffer) {}
    384 
    385 private:
    386     typedef SkLightingColorFilter INHERITED;
    387 };
    388 
    389 class SkLightingColorFilter_NoPin : public SkLightingColorFilter {
    390 public:
    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 
    420 protected:
    421     SkLightingColorFilter_NoPin(SkFlattenableReadBuffer& buffer)
    422         : INHERITED(buffer) {}
    423 
    424 private:
    425     typedef SkLightingColorFilter INHERITED;
    426 };
    427 
    428 ///////////////////////////////////////////////////////////////////////////////
    429 
    430 class SkSimpleColorFilter : public SkColorFilter {
    431 public:
    432     static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) {
    433         return SkNEW(SkSimpleColorFilter);
    434     }
    435 
    436 protected:
    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 
    452 SkColorFilter* 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 
    482 SK_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)
    492 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END
    493