SkColorFilters.cpp revision 8b0d0f6a9c01f45cd5bacf7aea2a32306fb16684
1ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com
2845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com/*
3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2006 The Android Open Source Project
4845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com *
5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be
6ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file.
7845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com */
88a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
9ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com
10c4cae85752e3e486cf4eac8cd8128f57b6f40563reed@android.com#include "SkBlitRow.h"
118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkColorFilter.h"
128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkColorPriv.h"
138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkUtils.h"
148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1543c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com#define ILLEGAL_XFERMODE_MODE   ((SkXfermode::Mode)-1)
1643c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com
1743c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com// baseclass for filters that store a color and mode
1843c50c8c77df82c5cffb55cae2d386e59802b88freed@google.comclass SkModeColorFilter : public SkColorFilter {
1943c50c8c77df82c5cffb55cae2d386e59802b88freed@google.compublic:
2043c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com    SkModeColorFilter(SkColor color) {
2143c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com        fColor = color;
2243c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com        fMode = ILLEGAL_XFERMODE_MODE;
238b0d0f6a9c01f45cd5bacf7aea2a32306fb16684reed@google.com        this->updateCache();
2443c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com    }
2543c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com
2643c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com    SkModeColorFilter(SkColor color, SkXfermode::Mode mode) {
2743c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com        fColor = color;
2843c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com        fMode = mode;
298b0d0f6a9c01f45cd5bacf7aea2a32306fb16684reed@google.com        this->updateCache();
3043c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com    };
311447c6f7f4579942b32af6ffff1eadede40b42bctomhudson@google.com
328b0d0f6a9c01f45cd5bacf7aea2a32306fb16684reed@google.com    SkColor getColor() const { return fColor; }
338b0d0f6a9c01f45cd5bacf7aea2a32306fb16684reed@google.com    SkXfermode::Mode getMode() const { return fMode; }
348b0d0f6a9c01f45cd5bacf7aea2a32306fb16684reed@google.com    bool isModeValid() const { return ILLEGAL_XFERMODE_MODE != fMode; }
358b0d0f6a9c01f45cd5bacf7aea2a32306fb16684reed@google.com    SkPMColor getPMColor() const { return fPMColor; }
368b0d0f6a9c01f45cd5bacf7aea2a32306fb16684reed@google.com
378b0d0f6a9c01f45cd5bacf7aea2a32306fb16684reed@google.com    virtual bool asColorMode(SkColor* color, SkXfermode::Mode* mode) SK_OVERRIDE {
3843c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com        if (ILLEGAL_XFERMODE_MODE == fMode) {
3943c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com            return false;
4043c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com        }
4143c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com
4243c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com        if (color) {
4343c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com            *color = fColor;
4443c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com        }
4543c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com        if (mode) {
4643c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com            *mode = fMode;
4743c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com        }
4843c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com        return true;
4943c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com    }
508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
518b0d0f6a9c01f45cd5bacf7aea2a32306fb16684reed@google.com    virtual uint32_t getFlags() SK_OVERRIDE {
528b0d0f6a9c01f45cd5bacf7aea2a32306fb16684reed@google.com        return fProc16 ? (kAlphaUnchanged_Flag | kHasFilter16_Flag) : 0;
538b0d0f6a9c01f45cd5bacf7aea2a32306fb16684reed@google.com    }
548b0d0f6a9c01f45cd5bacf7aea2a32306fb16684reed@google.com
558b0d0f6a9c01f45cd5bacf7aea2a32306fb16684reed@google.com    virtual void filterSpan(const SkPMColor shader[], int count,
568b0d0f6a9c01f45cd5bacf7aea2a32306fb16684reed@google.com                            SkPMColor result[]) SK_OVERRIDE {
578b0d0f6a9c01f45cd5bacf7aea2a32306fb16684reed@google.com        SkPMColor       color = fPMColor;
588b0d0f6a9c01f45cd5bacf7aea2a32306fb16684reed@google.com        SkXfermodeProc  proc = fProc;
598b0d0f6a9c01f45cd5bacf7aea2a32306fb16684reed@google.com
608b0d0f6a9c01f45cd5bacf7aea2a32306fb16684reed@google.com        for (int i = 0; i < count; i++) {
618b0d0f6a9c01f45cd5bacf7aea2a32306fb16684reed@google.com            result[i] = proc(color, shader[i]);
628b0d0f6a9c01f45cd5bacf7aea2a32306fb16684reed@google.com        }
638b0d0f6a9c01f45cd5bacf7aea2a32306fb16684reed@google.com    }
648b0d0f6a9c01f45cd5bacf7aea2a32306fb16684reed@google.com
658b0d0f6a9c01f45cd5bacf7aea2a32306fb16684reed@google.com    virtual void filterSpan16(const uint16_t shader[], int count,
668b0d0f6a9c01f45cd5bacf7aea2a32306fb16684reed@google.com                              uint16_t result[]) SK_OVERRIDE {
678b0d0f6a9c01f45cd5bacf7aea2a32306fb16684reed@google.com        SkASSERT(this->getFlags() & kHasFilter16_Flag);
688b0d0f6a9c01f45cd5bacf7aea2a32306fb16684reed@google.com
698b0d0f6a9c01f45cd5bacf7aea2a32306fb16684reed@google.com        SkPMColor        color = fPMColor;
708b0d0f6a9c01f45cd5bacf7aea2a32306fb16684reed@google.com        SkXfermodeProc16 proc16 = fProc16;
718b0d0f6a9c01f45cd5bacf7aea2a32306fb16684reed@google.com
728b0d0f6a9c01f45cd5bacf7aea2a32306fb16684reed@google.com        for (int i = 0; i < count; i++) {
738b0d0f6a9c01f45cd5bacf7aea2a32306fb16684reed@google.com            result[i] = proc16(color, shader[i]);
748b0d0f6a9c01f45cd5bacf7aea2a32306fb16684reed@google.com        }
758b0d0f6a9c01f45cd5bacf7aea2a32306fb16684reed@google.com    }
768b0d0f6a9c01f45cd5bacf7aea2a32306fb16684reed@google.com
778b0d0f6a9c01f45cd5bacf7aea2a32306fb16684reed@google.com    SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkModeColorFilter)
7843c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com
7943c50c8c77df82c5cffb55cae2d386e59802b88freed@google.comprotected:
8054924243c1b65b3ee6d8fa064b50a9b1bb2a19a5djsollen@google.com    virtual void flatten(SkFlattenableWriteBuffer& buffer) const SK_OVERRIDE {
811447c6f7f4579942b32af6ffff1eadede40b42bctomhudson@google.com        this->INHERITED::flatten(buffer);
8243c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com        buffer.write32(fColor);
8343c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com        buffer.write32(fMode);
848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
851447c6f7f4579942b32af6ffff1eadede40b42bctomhudson@google.com
8643c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com    SkModeColorFilter(SkFlattenableReadBuffer& buffer) {
8743c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com        fColor = buffer.readU32();
8843c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com        fMode = (SkXfermode::Mode)buffer.readU32();
898b0d0f6a9c01f45cd5bacf7aea2a32306fb16684reed@google.com        this->updateCache();
908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
91845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com
9243c50c8c77df82c5cffb55cae2d386e59802b88freed@google.comprivate:
9343c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com    SkColor             fColor;
9443c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com    SkXfermode::Mode    fMode;
958b0d0f6a9c01f45cd5bacf7aea2a32306fb16684reed@google.com    // cache
968b0d0f6a9c01f45cd5bacf7aea2a32306fb16684reed@google.com    SkPMColor           fPMColor;
978b0d0f6a9c01f45cd5bacf7aea2a32306fb16684reed@google.com    SkXfermodeProc      fProc;
988b0d0f6a9c01f45cd5bacf7aea2a32306fb16684reed@google.com    SkXfermodeProc16    fProc16;
998b0d0f6a9c01f45cd5bacf7aea2a32306fb16684reed@google.com
1008b0d0f6a9c01f45cd5bacf7aea2a32306fb16684reed@google.com    void updateCache() {
1018b0d0f6a9c01f45cd5bacf7aea2a32306fb16684reed@google.com        fPMColor = SkPreMultiplyColor(fColor);
1028b0d0f6a9c01f45cd5bacf7aea2a32306fb16684reed@google.com        fProc = SkXfermode::GetProc(fMode);
1038b0d0f6a9c01f45cd5bacf7aea2a32306fb16684reed@google.com        fProc16 = SkXfermode::GetProc16(fMode, fColor);
1048b0d0f6a9c01f45cd5bacf7aea2a32306fb16684reed@google.com    }
1058b0d0f6a9c01f45cd5bacf7aea2a32306fb16684reed@google.com
1061447c6f7f4579942b32af6ffff1eadede40b42bctomhudson@google.com    typedef SkColorFilter INHERITED;
1078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com};
1088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
10943c50c8c77df82c5cffb55cae2d386e59802b88freed@google.comclass Src_SkModeColorFilter : public SkModeColorFilter {
1108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.compublic:
11143c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com    Src_SkModeColorFilter(SkColor color) : INHERITED(color, SkXfermode::kSrc_Mode) {}
1128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
113845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com    virtual uint32_t getFlags() {
1148b0d0f6a9c01f45cd5bacf7aea2a32306fb16684reed@google.com        if (SkGetPackedA32(this->getPMColor()) == 0xFF) {
1158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            return kAlphaUnchanged_Flag | kHasFilter16_Flag;
116845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com        } else {
1178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            return 0;
118845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com        }
1198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
1208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
121845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com    virtual void filterSpan(const SkPMColor shader[], int count,
122845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com                            SkPMColor result[]) {
1238b0d0f6a9c01f45cd5bacf7aea2a32306fb16684reed@google.com        sk_memset32(result, this->getPMColor(), count);
1248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
1258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
126845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com    virtual void filterSpan16(const uint16_t shader[], int count,
127845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com                              uint16_t result[]) {
1288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        SkASSERT(this->getFlags() & kHasFilter16_Flag);
1298b0d0f6a9c01f45cd5bacf7aea2a32306fb16684reed@google.com        sk_memset16(result, SkPixel32ToPixel16(this->getPMColor()), count);
1308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
1318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
132ba28d03e94dc221d6a803bf2a84a420b9159255cdjsollen@google.com    SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(Src_SkModeColorFilter)
1331447c6f7f4579942b32af6ffff1eadede40b42bctomhudson@google.com
1348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comprotected:
13543c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com    Src_SkModeColorFilter(SkFlattenableReadBuffer& buffer)
136845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com        : INHERITED(buffer) {}
137845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com
1381447c6f7f4579942b32af6ffff1eadede40b42bctomhudson@google.comprivate:
13943c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com    typedef SkModeColorFilter INHERITED;
1408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com};
1418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
14243c50c8c77df82c5cffb55cae2d386e59802b88freed@google.comclass SrcOver_SkModeColorFilter : public SkModeColorFilter {
1438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.compublic:
14443c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com    SrcOver_SkModeColorFilter(SkColor color)
14543c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com            : INHERITED(color, SkXfermode::kSrcOver_Mode) {
14643c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com        fColor32Proc = NULL;
14743c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com    }
1488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
149845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com    virtual uint32_t getFlags() {
1508b0d0f6a9c01f45cd5bacf7aea2a32306fb16684reed@google.com        if (SkGetPackedA32(this->getPMColor()) == 0xFF) {
1518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            return kAlphaUnchanged_Flag | kHasFilter16_Flag;
152845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com        } else {
1538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            return 0;
154845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com        }
1558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
1561447c6f7f4579942b32af6ffff1eadede40b42bctomhudson@google.com
157845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com    virtual void filterSpan(const SkPMColor shader[], int count,
158845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com                            SkPMColor result[]) {
15943c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com        if (NULL == fColor32Proc) {
16043c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com            fColor32Proc = SkBlitRow::ColorProcFactory();
16143c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com        }
1628b0d0f6a9c01f45cd5bacf7aea2a32306fb16684reed@google.com        fColor32Proc(result, shader, count, this->getPMColor());
1638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
1648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
165845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com    virtual void filterSpan16(const uint16_t shader[], int count,
166845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com                              uint16_t result[]) {
1678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        SkASSERT(this->getFlags() & kHasFilter16_Flag);
1688b0d0f6a9c01f45cd5bacf7aea2a32306fb16684reed@google.com        sk_memset16(result, SkPixel32ToPixel16(this->getPMColor()), count);
1698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
1701447c6f7f4579942b32af6ffff1eadede40b42bctomhudson@google.com
171ba28d03e94dc221d6a803bf2a84a420b9159255cdjsollen@google.com    SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SrcOver_SkModeColorFilter)
1721447c6f7f4579942b32af6ffff1eadede40b42bctomhudson@google.com
1738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comprotected:
17443c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com    SrcOver_SkModeColorFilter(SkFlattenableReadBuffer& buffer)
17543c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com        : INHERITED(buffer), fColor32Proc(NULL) {}
1761447c6f7f4579942b32af6ffff1eadede40b42bctomhudson@google.com
1778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comprivate:
1781447c6f7f4579942b32af6ffff1eadede40b42bctomhudson@google.com
17929e5054dd07c97c2195c5f64bf67aaa6b5afa204senorblanco@chromium.org    SkBlitRow::ColorProc fColor32Proc;
18043c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com
18143c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com    typedef SkModeColorFilter INHERITED;
1828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com};
1838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
18443c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com///////////////////////////////////////////////////////////////////////////////
1858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
186845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.comSkColorFilter* SkColorFilter::CreateModeFilter(SkColor color,
187845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com                                               SkXfermode::Mode mode) {
1888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    unsigned alpha = SkColorGetA(color);
1898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    // first collaps some modes if possible
1918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
192845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com    if (SkXfermode::kClear_Mode == mode) {
1938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        color = 0;
194845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com        mode = SkXfermode::kSrc_Mode;
195845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com    } else if (SkXfermode::kSrcOver_Mode == mode) {
196845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com        if (0 == alpha) {
197845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com            mode = SkXfermode::kDst_Mode;
198845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com        } else if (255 == alpha) {
199845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com            mode = SkXfermode::kSrc_Mode;
2008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        }
2018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        // else just stay srcover
2028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
2038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    // weed out combinations that are noops, and just return null
205845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com    if (SkXfermode::kDst_Mode == mode ||
206845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com        (0 == alpha && (SkXfermode::kSrcOver_Mode == mode ||
207845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com                        SkXfermode::kDstOver_Mode == mode ||
208845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com                        SkXfermode::kDstOut_Mode == mode ||
209845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com                        SkXfermode::kSrcATop_Mode == mode ||
210845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com                        SkXfermode::kXor_Mode == mode ||
211845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com                        SkXfermode::kDarken_Mode == mode)) ||
212845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com            (0xFF == alpha && SkXfermode::kDstIn_Mode == mode)) {
2138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        return NULL;
2148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
2151447c6f7f4579942b32af6ffff1eadede40b42bctomhudson@google.com
2168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    switch (mode) {
21743c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com        case SkXfermode::kSrc_Mode:
21843c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com            return SkNEW_ARGS(Src_SkModeColorFilter, (color));
21943c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com        case SkXfermode::kSrcOver_Mode:
22043c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com            return SkNEW_ARGS(SrcOver_SkModeColorFilter, (color));
22143c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com        default:
2228b0d0f6a9c01f45cd5bacf7aea2a32306fb16684reed@google.com            return SkNEW_ARGS(SkModeColorFilter, (color, mode));
2238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
2248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
2258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
226845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com///////////////////////////////////////////////////////////////////////////////
2278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
228845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.comstatic inline unsigned pin(unsigned value, unsigned max) {
229845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com    if (value > max) {
2308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        value = max;
231845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com    }
2328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    return value;
2338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
2348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comclass SkLightingColorFilter : public SkColorFilter {
2368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.compublic:
2378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkLightingColorFilter(SkColor mul, SkColor add) : fMul(mul), fAdd(add) {}
2388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
239845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com    virtual void filterSpan(const SkPMColor shader[], int count,
240845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com                            SkPMColor result[]) {
2418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        unsigned scaleR = SkAlpha255To256(SkColorGetR(fMul));
2428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        unsigned scaleG = SkAlpha255To256(SkColorGetG(fMul));
2438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        unsigned scaleB = SkAlpha255To256(SkColorGetB(fMul));
2441447c6f7f4579942b32af6ffff1eadede40b42bctomhudson@google.com
2458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        unsigned addR = SkColorGetR(fAdd);
2468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        unsigned addG = SkColorGetG(fAdd);
2478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        unsigned addB = SkColorGetB(fAdd);
2488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
249845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com        for (int i = 0; i < count; i++) {
2508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            SkPMColor c = shader[i];
251845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com            if (c) {
2528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                unsigned a = SkGetPackedA32(c);
2531447c6f7f4579942b32af6ffff1eadede40b42bctomhudson@google.com                unsigned scaleA = SkAlpha255To256(a);
2548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                unsigned r = pin(SkAlphaMul(SkGetPackedR32(c), scaleR) + SkAlphaMul(addR, scaleA), a);
2558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                unsigned g = pin(SkAlphaMul(SkGetPackedG32(c), scaleG) + SkAlphaMul(addG, scaleA), a);
2568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                unsigned b = pin(SkAlphaMul(SkGetPackedB32(c), scaleB) + SkAlphaMul(addB, scaleA), a);
2578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                c = SkPackARGB32(a, r, g, b);
2588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            }
2598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            result[i] = c;
2608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        }
2618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
2628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
263ba28d03e94dc221d6a803bf2a84a420b9159255cdjsollen@google.com    SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkLightingColorFilter)
264d26147adbbdca85f07dff432025afee0c8614387caryclark@google.com
2658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comprotected:
26654924243c1b65b3ee6d8fa064b50a9b1bb2a19a5djsollen@google.com    virtual void flatten(SkFlattenableWriteBuffer& buffer) const SK_OVERRIDE {
2671447c6f7f4579942b32af6ffff1eadede40b42bctomhudson@google.com        this->INHERITED::flatten(buffer);
2688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        buffer.write32(fMul);
2698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        buffer.write32(fAdd);
2708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
2711447c6f7f4579942b32af6ffff1eadede40b42bctomhudson@google.com
272845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com    SkLightingColorFilter(SkFlattenableReadBuffer& buffer) {
2738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        fMul = buffer.readU32();
2748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        fAdd = buffer.readU32();
2758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
2761447c6f7f4579942b32af6ffff1eadede40b42bctomhudson@google.com
2778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkColor fMul, fAdd;
2788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comprivate:
2801447c6f7f4579942b32af6ffff1eadede40b42bctomhudson@google.com    typedef SkColorFilter INHERITED;
2818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com};
2828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comclass SkLightingColorFilter_JustAdd : public SkLightingColorFilter {
2848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.compublic:
2858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkLightingColorFilter_JustAdd(SkColor mul, SkColor add)
2868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        : INHERITED(mul, add) {}
2878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
288845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com    virtual void filterSpan(const SkPMColor shader[], int count,
289845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com                            SkPMColor result[]) {
2908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        unsigned addR = SkColorGetR(fAdd);
2918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        unsigned addG = SkColorGetG(fAdd);
2928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        unsigned addB = SkColorGetB(fAdd);
2938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
294845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com        for (int i = 0; i < count; i++) {
2958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            SkPMColor c = shader[i];
296845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com            if (c) {
2978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                unsigned a = SkGetPackedA32(c);
2981447c6f7f4579942b32af6ffff1eadede40b42bctomhudson@google.com                unsigned scaleA = SkAlpha255To256(a);
2998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                unsigned r = pin(SkGetPackedR32(c) + SkAlphaMul(addR, scaleA), a);
3008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                unsigned g = pin(SkGetPackedG32(c) + SkAlphaMul(addG, scaleA), a);
3018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                unsigned b = pin(SkGetPackedB32(c) + SkAlphaMul(addB, scaleA), a);
3028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                c = SkPackARGB32(a, r, g, b);
3038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            }
3048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            result[i] = c;
3058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        }
3068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
3078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
308ba28d03e94dc221d6a803bf2a84a420b9159255cdjsollen@google.com    SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkLightingColorFilter_JustAdd)
309d26147adbbdca85f07dff432025afee0c8614387caryclark@google.com
3108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comprotected:
3118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkLightingColorFilter_JustAdd(SkFlattenableReadBuffer& buffer)
3128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        : INHERITED(buffer) {}
3138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
3148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comprivate:
3158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    typedef SkLightingColorFilter INHERITED;
3168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com};
3178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
3188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comclass SkLightingColorFilter_JustMul : public SkLightingColorFilter {
3198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.compublic:
3208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkLightingColorFilter_JustMul(SkColor mul, SkColor add)
3218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        : INHERITED(mul, add) {}
3228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
323845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com    virtual void filterSpan(const SkPMColor shader[], int count,
324845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com                            SkPMColor result[]) {
3258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        unsigned scaleR = SkAlpha255To256(SkColorGetR(fMul));
3268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        unsigned scaleG = SkAlpha255To256(SkColorGetG(fMul));
3278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        unsigned scaleB = SkAlpha255To256(SkColorGetB(fMul));
3281447c6f7f4579942b32af6ffff1eadede40b42bctomhudson@google.com
329845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com        for (int i = 0; i < count; i++) {
3308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            SkPMColor c = shader[i];
331845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com            if (c) {
3328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                unsigned a = SkGetPackedA32(c);
3338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                unsigned r = SkAlphaMul(SkGetPackedR32(c), scaleR);
3348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                unsigned g = SkAlphaMul(SkGetPackedG32(c), scaleG);
3358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                unsigned b = SkAlphaMul(SkGetPackedB32(c), scaleB);
3368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                c = SkPackARGB32(a, r, g, b);
3378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            }
3388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            result[i] = c;
3398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        }
3408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
3418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
342ba28d03e94dc221d6a803bf2a84a420b9159255cdjsollen@google.com    SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkLightingColorFilter_JustMul)
343d26147adbbdca85f07dff432025afee0c8614387caryclark@google.com
3448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comprotected:
3458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkLightingColorFilter_JustMul(SkFlattenableReadBuffer& buffer)
3468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        : INHERITED(buffer) {}
3471447c6f7f4579942b32af6ffff1eadede40b42bctomhudson@google.com
3488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comprivate:
3498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    typedef SkLightingColorFilter INHERITED;
3508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com};
3518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
3528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comclass SkLightingColorFilter_SingleMul : public SkLightingColorFilter {
3538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.compublic:
3548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkLightingColorFilter_SingleMul(SkColor mul, SkColor add)
355845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com            : INHERITED(mul, add) {
3568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        SkASSERT(SkColorGetR(add) == 0);
3578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        SkASSERT(SkColorGetG(add) == 0);
3588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        SkASSERT(SkColorGetB(add) == 0);
3598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        SkASSERT(SkColorGetR(mul) == SkColorGetG(mul));
3608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        SkASSERT(SkColorGetR(mul) == SkColorGetB(mul));
3618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
3621447c6f7f4579942b32af6ffff1eadede40b42bctomhudson@google.com
363845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com    virtual uint32_t getFlags() {
3648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        return this->INHERITED::getFlags() | (kAlphaUnchanged_Flag | kHasFilter16_Flag);
3658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
3668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
367845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com    virtual void filterSpan16(const uint16_t shader[], int count,
368845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com                              uint16_t result[]) {
3698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        // all mul components are the same
3708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        unsigned scale = SkAlpha255To256(SkColorGetR(fMul));
3718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
372845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com        if (count > 0) {
3738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            do {
3748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                *result++ = SkAlphaMulRGB16(*shader++, scale);
3758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            } while (--count > 0);
376845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com        }
3778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
3788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
379ba28d03e94dc221d6a803bf2a84a420b9159255cdjsollen@google.com    SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkLightingColorFilter_SingleMul)
380d26147adbbdca85f07dff432025afee0c8614387caryclark@google.com
3818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comprotected:
3828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkLightingColorFilter_SingleMul(SkFlattenableReadBuffer& buffer)
3838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        : INHERITED(buffer) {}
3848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
3858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comprivate:
3868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    typedef SkLightingColorFilter INHERITED;
3878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com};
3888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
3898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comclass SkLightingColorFilter_NoPin : public SkLightingColorFilter {
3908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.compublic:
3918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkLightingColorFilter_NoPin(SkColor mul, SkColor add)
3928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    : INHERITED(mul, add) {}
3931447c6f7f4579942b32af6ffff1eadede40b42bctomhudson@google.com
394845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com    virtual void filterSpan(const SkPMColor shader[], int count,
395845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com                            SkPMColor result[]) {
3968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        unsigned scaleR = SkAlpha255To256(SkColorGetR(fMul));
3978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        unsigned scaleG = SkAlpha255To256(SkColorGetG(fMul));
3988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        unsigned scaleB = SkAlpha255To256(SkColorGetB(fMul));
3991447c6f7f4579942b32af6ffff1eadede40b42bctomhudson@google.com
4008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        unsigned addR = SkColorGetR(fAdd);
4018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        unsigned addG = SkColorGetG(fAdd);
4028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        unsigned addB = SkColorGetB(fAdd);
4031447c6f7f4579942b32af6ffff1eadede40b42bctomhudson@google.com
404845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com        for (int i = 0; i < count; i++) {
4058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            SkPMColor c = shader[i];
406845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com            if (c) {
4078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                unsigned a = SkGetPackedA32(c);
4081447c6f7f4579942b32af6ffff1eadede40b42bctomhudson@google.com                unsigned scaleA = SkAlpha255To256(a);
4098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                unsigned r = SkAlphaMul(SkGetPackedR32(c), scaleR) + SkAlphaMul(addR, scaleA);
4108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                unsigned g = SkAlphaMul(SkGetPackedG32(c), scaleG) + SkAlphaMul(addG, scaleA);
4118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                unsigned b = SkAlphaMul(SkGetPackedB32(c), scaleB) + SkAlphaMul(addB, scaleA);
4128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                c = SkPackARGB32(a, r, g, b);
4138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            }
4148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            result[i] = c;
4158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        }
4168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
4171447c6f7f4579942b32af6ffff1eadede40b42bctomhudson@google.com
418ba28d03e94dc221d6a803bf2a84a420b9159255cdjsollen@google.com    SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkLightingColorFilter_NoPin)
419d26147adbbdca85f07dff432025afee0c8614387caryclark@google.com
4208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comprotected:
4218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkLightingColorFilter_NoPin(SkFlattenableReadBuffer& buffer)
4228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        : INHERITED(buffer) {}
4231447c6f7f4579942b32af6ffff1eadede40b42bctomhudson@google.com
4248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comprivate:
4258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    typedef SkLightingColorFilter INHERITED;
4268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com};
4278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
428845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com///////////////////////////////////////////////////////////////////////////////
4298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
4308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comclass SkSimpleColorFilter : public SkColorFilter {
431d26147adbbdca85f07dff432025afee0c8614387caryclark@google.compublic:
432d26147adbbdca85f07dff432025afee0c8614387caryclark@google.com    static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) {
433d26147adbbdca85f07dff432025afee0c8614387caryclark@google.com        return SkNEW(SkSimpleColorFilter);
434d26147adbbdca85f07dff432025afee0c8614387caryclark@google.com    }
435d26147adbbdca85f07dff432025afee0c8614387caryclark@google.com
4368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comprotected:
437845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com    void filterSpan(const SkPMColor src[], int count, SkPMColor result[]) {
438845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com        if (result != src) {
4398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            memcpy(result, src, count * sizeof(SkPMColor));
440845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com        }
4418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
4428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
44354924243c1b65b3ee6d8fa064b50a9b1bb2a19a5djsollen@google.com    virtual void flatten(SkFlattenableWriteBuffer& buffer) const SK_OVERRIDE {}
4441447c6f7f4579942b32af6ffff1eadede40b42bctomhudson@google.com
445845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com    virtual Factory getFactory() {
4468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        return CreateProc;
4478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
4488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
4498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com};
4508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
451845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.comSkColorFilter* SkColorFilter::CreateLightingFilter(SkColor mul, SkColor add) {
4528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    mul &= 0x00FFFFFF;
4538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    add &= 0x00FFFFFF;
4548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
455845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com    if (0xFFFFFF == mul) {
456845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com        if (0 == add) {
4578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            return SkNEW(SkSimpleColorFilter);   // no change to the colors
458845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com        } else {
4598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            return SkNEW_ARGS(SkLightingColorFilter_JustAdd, (mul, add));
460845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com        }
4618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
4628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
463845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com    if (0 == add) {
4648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        if (SkColorGetR(mul) == SkColorGetG(mul) &&
465845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com                SkColorGetR(mul) == SkColorGetB(mul)) {
4668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            return SkNEW_ARGS(SkLightingColorFilter_SingleMul, (mul, add));
467845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com        } else {
4688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            return SkNEW_ARGS(SkLightingColorFilter_JustMul, (mul, add));
4698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        }
4708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
4718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
4728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (SkColorGetR(mul) + SkColorGetR(add) <= 255 &&
4738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        SkColorGetG(mul) + SkColorGetG(add) <= 255 &&
474845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com        SkColorGetB(mul) + SkColorGetB(add) <= 255) {
475845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com            return SkNEW_ARGS(SkLightingColorFilter_NoPin, (mul, add));
476845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com    }
4778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
4788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    return SkNEW_ARGS(SkLightingColorFilter, (mul, add));
4798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
4808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
481d26147adbbdca85f07dff432025afee0c8614387caryclark@google.comSK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkColorFilter)
4828b0d0f6a9c01f45cd5bacf7aea2a32306fb16684reed@google.com    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkModeColorFilter)
483d26147adbbdca85f07dff432025afee0c8614387caryclark@google.com    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(Src_SkModeColorFilter)
484d26147adbbdca85f07dff432025afee0c8614387caryclark@google.com    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SrcOver_SkModeColorFilter)
485d26147adbbdca85f07dff432025afee0c8614387caryclark@google.com    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLightingColorFilter)
486d26147adbbdca85f07dff432025afee0c8614387caryclark@google.com    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLightingColorFilter_JustAdd)
487d26147adbbdca85f07dff432025afee0c8614387caryclark@google.com    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLightingColorFilter_JustMul)
488d26147adbbdca85f07dff432025afee0c8614387caryclark@google.com    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLightingColorFilter_SingleMul)
489d26147adbbdca85f07dff432025afee0c8614387caryclark@google.com    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLightingColorFilter_NoPin)
490d26147adbbdca85f07dff432025afee0c8614387caryclark@google.com    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkSimpleColorFilter)
491d26147adbbdca85f07dff432025afee0c8614387caryclark@google.comSK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END
4921447c6f7f4579942b32af6ffff1eadede40b42bctomhudson@google.com
493