SkColorFilters.cpp revision c4cae85752e3e486cf4eac8cd8128f57b6f40563
1845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com/*
2845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com * Copyright (C) 2006 The Android Open Source Project
3845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com *
4845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com * Licensed under the Apache License, Version 2.0 (the "License");
5845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com * you may not use this file except in compliance with the License.
6845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com * You may obtain a copy of the License at
7845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com *
8845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com *      http://www.apache.org/licenses/LICENSE-2.0
9845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com *
10845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com * Unless required by applicable law or agreed to in writing, software
11845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com * distributed under the License is distributed on an "AS IS" BASIS,
12845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com * See the License for the specific language governing permissions and
14845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com * limitations under the License.
15845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com */
168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
17c4cae85752e3e486cf4eac8cd8128f57b6f40563reed@android.com#include "SkBlitRow.h"
188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkColorFilter.h"
198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkColorPriv.h"
208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkUtils.h"
218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com// common baseclass
238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comclass Sk_XfermodeColorFilter : public SkColorFilter {
248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comprotected:
25845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com    Sk_XfermodeColorFilter(SkColor color)
26845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com        : fPMColor(SkPreMultiplyColor(color)) {}
278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
28845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com    virtual void flatten(SkFlattenableWriteBuffer& buffer) {
29845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com        buffer.write32(fPMColor);
308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
31845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com
32845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com    Sk_XfermodeColorFilter(SkFlattenableReadBuffer& buffer) {
33845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com        fPMColor = buffer.readU32();
348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
35845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com
36845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com    SkPMColor   fPMColor;
378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com};
388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comclass SkSrc_XfermodeColorFilter : public Sk_XfermodeColorFilter {
408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.compublic:
418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkSrc_XfermodeColorFilter(SkColor color) : INHERITED(color) {}
428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
43845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com    virtual uint32_t getFlags() {
44845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com        if (SkGetPackedA32(fPMColor) == 0xFF) {
458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            return kAlphaUnchanged_Flag | kHasFilter16_Flag;
46845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com        } else {
478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            return 0;
48845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com        }
498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
51845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com    virtual void filterSpan(const SkPMColor shader[], int count,
52845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com                            SkPMColor result[]) {
53845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com        sk_memset32(result, fPMColor, count);
548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
56845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com    virtual void filterSpan16(const uint16_t shader[], int count,
57845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com                              uint16_t result[]) {
588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        SkASSERT(this->getFlags() & kHasFilter16_Flag);
59845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com        sk_memset16(result, SkPixel32ToPixel16(fPMColor), count);
608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comprotected:
638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    virtual Factory getFactory() { return CreateProc; }
648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
65845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com    SkSrc_XfermodeColorFilter(SkFlattenableReadBuffer& buffer)
66845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com        : INHERITED(buffer) {}
678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comprivate:
69845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com    static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) {
708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        return SkNEW_ARGS(SkSrc_XfermodeColorFilter, (buffer));
718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
72845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com
738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    typedef Sk_XfermodeColorFilter INHERITED;
748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com};
758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comclass SkSrcOver_XfermodeColorFilter : public Sk_XfermodeColorFilter {
778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.compublic:
788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkSrcOver_XfermodeColorFilter(SkColor color) : INHERITED(color) {}
798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
80845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com    virtual uint32_t getFlags() {
81845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com        if (SkGetPackedA32(fPMColor) == 0xFF) {
828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            return kAlphaUnchanged_Flag | kHasFilter16_Flag;
83845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com        } else {
848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            return 0;
85845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com        }
868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
88845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com    virtual void filterSpan(const SkPMColor shader[], int count,
89845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com                            SkPMColor result[]) {
90c4cae85752e3e486cf4eac8cd8128f57b6f40563reed@android.com        SkBlitRow::Color32(result, shader, count, fPMColor);
918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
93845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com    virtual void filterSpan16(const uint16_t shader[], int count,
94845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com                              uint16_t result[]) {
958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        SkASSERT(this->getFlags() & kHasFilter16_Flag);
96845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com        sk_memset16(result, SkPixel32ToPixel16(fPMColor), count);
978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comprotected:
1008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    virtual Factory getFactory() { return CreateProc;  }
1018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
102845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com    SkSrcOver_XfermodeColorFilter(SkFlattenableReadBuffer& buffer)
103845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com        : INHERITED(buffer) {}
1048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comprivate:
106845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com    static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) {
1078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        return SkNEW_ARGS(SkSrcOver_XfermodeColorFilter, (buffer));
1088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
1098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    typedef Sk_XfermodeColorFilter INHERITED;
1118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com};
1128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com//////////////////////////////////////////////////////////////////////////////
1148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comclass SkXfermodeColorFilter : public Sk_XfermodeColorFilter {
1168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.compublic:
1178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkXfermodeColorFilter(SkColor color, SkXfermodeProc proc,
118845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com                          SkXfermodeProc16 proc16) : INHERITED(color) {
1198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        fProc = proc;
1208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        fProc16 = proc16;
1218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
1228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
123845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com    virtual uint32_t getFlags() {
1248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        return fProc16 ? (kAlphaUnchanged_Flag | kHasFilter16_Flag) : 0;
1258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
1268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
127845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com    virtual void filterSpan(const SkPMColor shader[], int count,
128845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com                            SkPMColor result[]) {
129845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com        SkPMColor       color = fPMColor;
1308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        SkXfermodeProc  proc = fProc;
131845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com
132845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com        for (int i = 0; i < count; i++) {
1338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            result[i] = proc(color, shader[i]);
134845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com        }
1358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
1368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
137845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com    virtual void filterSpan16(const uint16_t shader[], int count,
138845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com                              uint16_t result[]) {
1398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        SkASSERT(this->getFlags() & kHasFilter16_Flag);
1408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
141845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com        SkPMColor        color = fPMColor;
1428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        SkXfermodeProc16 proc16 = fProc16;
1438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
144845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com        for (int i = 0; i < count; i++) {
1458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            result[i] = proc16(color, shader[i]);
146845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com        }
1478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
1488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comprotected:
1508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    virtual void flatten(SkFlattenableWriteBuffer& buffer) {
1518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        this->INHERITED::flatten(buffer);
1528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        buffer.writeFunctionPtr((void*)fProc);
1538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        buffer.writeFunctionPtr((void*)fProc16);
1548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
1558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    virtual Factory getFactory() {
1578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        return CreateProc;
1588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
1598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkXfermodeColorFilter(SkFlattenableReadBuffer& buffer) : INHERITED(buffer) {
1618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        fProc = (SkXfermodeProc) buffer.readFunctionPtr();
1628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        fProc16 = (SkXfermodeProc16) buffer.readFunctionPtr();
1638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
1648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comprivate:
1658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) {
1668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        return SkNEW_ARGS(SkXfermodeColorFilter, (buffer));
1678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
1688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkXfermodeProc   fProc;
1708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkXfermodeProc16 fProc16;
1718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    typedef Sk_XfermodeColorFilter INHERITED;
1738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com};
1748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
175845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.comSkColorFilter* SkColorFilter::CreateProcFilter(SkColor color,
176845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com                                               SkXfermodeProc proc,
177845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com                                               SkXfermodeProc16 proc16) {
1788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    return proc ?
1798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            SkNEW_ARGS(SkXfermodeColorFilter, (color, proc, proc16)) :
1808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            NULL;
1818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
1828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com///////////////////////////////////////////////////////////////////////////////
1848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
185845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.comSkColorFilter* SkColorFilter::CreateModeFilter(SkColor color,
186845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com                                               SkXfermode::Mode mode) {
1878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    unsigned alpha = SkColorGetA(color);
1888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    // first collaps some modes if possible
1908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
191845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com    if (SkXfermode::kClear_Mode == mode) {
1928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        color = 0;
193845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com        mode = SkXfermode::kSrc_Mode;
194845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com    } else if (SkXfermode::kSrcOver_Mode == mode) {
195845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com        if (0 == alpha) {
196845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com            mode = SkXfermode::kDst_Mode;
197845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com        } else if (255 == alpha) {
198845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com            mode = SkXfermode::kSrc_Mode;
1998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        }
2008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        // else just stay srcover
2018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
2028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    // weed out combinations that are noops, and just return null
204845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com    if (SkXfermode::kDst_Mode == mode ||
205845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com        (0 == alpha && (SkXfermode::kSrcOver_Mode == mode ||
206845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com                        SkXfermode::kDstOver_Mode == mode ||
207845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com                        SkXfermode::kDstOut_Mode == mode ||
208845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com                        SkXfermode::kSrcATop_Mode == mode ||
209845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com                        SkXfermode::kXor_Mode == mode ||
210845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com                        SkXfermode::kDarken_Mode == mode)) ||
211845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com            (0xFF == alpha && SkXfermode::kDstIn_Mode == mode)) {
2128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        return NULL;
2138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
2148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    switch (mode) {
216845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com    case SkXfermode::kSrc_Mode:
2178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        return SkNEW_ARGS(SkSrc_XfermodeColorFilter, (color));
218845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com    case SkXfermode::kSrcOver_Mode:
2198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        return SkNEW_ARGS(SkSrcOver_XfermodeColorFilter, (color));
2208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    default:
221845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com        return SkColorFilter::CreateProcFilter(color, SkXfermode::GetProc(mode),
222845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com                                            SkXfermode::GetProc16(mode, color));
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
235845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.comstatic inline unsigned SkUClampMax(unsigned value, unsigned max) {
2368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkASSERT((int32_t)value >= 0);
2378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkASSERT((int32_t)max >= 0);
2388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    int diff = max - value;
2408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    // clear diff if diff is positive
2418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    diff &= diff >> 31;
2428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    return value + diff;
2448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
2458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comclass SkLightingColorFilter : public SkColorFilter {
2478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.compublic:
2488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkLightingColorFilter(SkColor mul, SkColor add) : fMul(mul), fAdd(add) {}
2498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
250845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com    virtual void filterSpan(const SkPMColor shader[], int count,
251845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com                            SkPMColor result[]) {
2528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        unsigned scaleR = SkAlpha255To256(SkColorGetR(fMul));
2538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        unsigned scaleG = SkAlpha255To256(SkColorGetG(fMul));
2548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        unsigned scaleB = SkAlpha255To256(SkColorGetB(fMul));
2558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        unsigned addR = SkColorGetR(fAdd);
2578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        unsigned addG = SkColorGetG(fAdd);
2588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        unsigned addB = SkColorGetB(fAdd);
2598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
260845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com        for (int i = 0; i < count; i++) {
2618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            SkPMColor c = shader[i];
262845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com            if (c) {
2638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                unsigned a = SkGetPackedA32(c);
2648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                unsigned scaleA = SkAlpha255To256(a);
2658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                unsigned r = pin(SkAlphaMul(SkGetPackedR32(c), scaleR) + SkAlphaMul(addR, scaleA), a);
2668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                unsigned g = pin(SkAlphaMul(SkGetPackedG32(c), scaleG) + SkAlphaMul(addG, scaleA), a);
2678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                unsigned b = pin(SkAlphaMul(SkGetPackedB32(c), scaleB) + SkAlphaMul(addB, scaleA), a);
2688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                c = SkPackARGB32(a, r, g, b);
2698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            }
2708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            result[i] = c;
2718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        }
2728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
2738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comprotected:
275845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com    virtual void flatten(SkFlattenableWriteBuffer& buffer) {
2768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        buffer.write32(fMul);
2778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        buffer.write32(fAdd);
2788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
2798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
280845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com    virtual Factory getFactory() {
2818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        return CreateProc;
2828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
2838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
284845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com    SkLightingColorFilter(SkFlattenableReadBuffer& buffer) {
2858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        fMul = buffer.readU32();
2868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        fAdd = buffer.readU32();
2878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
2888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkColor fMul, fAdd;
2908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comprivate:
292845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com    static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) {
2938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        return SkNEW_ARGS(SkLightingColorFilter, (buffer));
2948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
2958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com};
2968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comclass SkLightingColorFilter_JustAdd : public SkLightingColorFilter {
2988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.compublic:
2998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkLightingColorFilter_JustAdd(SkColor mul, SkColor add)
3008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        : INHERITED(mul, add) {}
3018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
302845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com    virtual void filterSpan(const SkPMColor shader[], int count,
303845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com                            SkPMColor result[]) {
3048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        unsigned addR = SkColorGetR(fAdd);
3058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        unsigned addG = SkColorGetG(fAdd);
3068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        unsigned addB = SkColorGetB(fAdd);
3078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
308845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com        for (int i = 0; i < count; i++) {
3098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            SkPMColor c = shader[i];
310845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com            if (c) {
3118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                unsigned a = SkGetPackedA32(c);
3128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                unsigned scaleA = SkAlpha255To256(a);
3138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                unsigned r = pin(SkGetPackedR32(c) + SkAlphaMul(addR, scaleA), a);
3148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                unsigned g = pin(SkGetPackedG32(c) + SkAlphaMul(addG, scaleA), a);
3158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                unsigned b = pin(SkGetPackedB32(c) + SkAlphaMul(addB, scaleA), a);
3168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                c = SkPackARGB32(a, r, g, b);
3178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            }
3188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            result[i] = c;
3198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        }
3208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
3218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
3228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comprotected:
3238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    virtual Factory getFactory() { return CreateProc; }
3248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
3258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkLightingColorFilter_JustAdd(SkFlattenableReadBuffer& buffer)
3268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        : INHERITED(buffer) {}
3278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
3288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comprivate:
329845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com    static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer)  {
3308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        return SkNEW_ARGS(SkLightingColorFilter_JustAdd, (buffer));
3318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
3328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    typedef SkLightingColorFilter INHERITED;
3338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com};
3348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
3358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comclass SkLightingColorFilter_JustMul : public SkLightingColorFilter {
3368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.compublic:
3378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkLightingColorFilter_JustMul(SkColor mul, SkColor add)
3388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        : INHERITED(mul, add) {}
3398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
340845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com    virtual void filterSpan(const SkPMColor shader[], int count,
341845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com                            SkPMColor result[]) {
3428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        unsigned scaleR = SkAlpha255To256(SkColorGetR(fMul));
3438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        unsigned scaleG = SkAlpha255To256(SkColorGetG(fMul));
3448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        unsigned scaleB = SkAlpha255To256(SkColorGetB(fMul));
3458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
346845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com        for (int i = 0; i < count; i++) {
3478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            SkPMColor c = shader[i];
348845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com            if (c) {
3498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                unsigned a = SkGetPackedA32(c);
3508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                unsigned r = SkAlphaMul(SkGetPackedR32(c), scaleR);
3518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                unsigned g = SkAlphaMul(SkGetPackedG32(c), scaleG);
3528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                unsigned b = SkAlphaMul(SkGetPackedB32(c), scaleB);
3538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                c = SkPackARGB32(a, r, g, b);
3548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            }
3558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            result[i] = c;
3568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        }
3578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
3588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
3598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comprotected:
3608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    virtual Factory getFactory() { return CreateProc; }
3618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
3628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkLightingColorFilter_JustMul(SkFlattenableReadBuffer& buffer)
3638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        : INHERITED(buffer) {}
3648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
3658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comprivate:
366845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com    static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) {
3678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        return SkNEW_ARGS(SkLightingColorFilter_JustMul, (buffer));
3688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
3698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
3708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    typedef SkLightingColorFilter INHERITED;
3718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com};
3728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
3738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comclass SkLightingColorFilter_SingleMul : public SkLightingColorFilter {
3748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.compublic:
3758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkLightingColorFilter_SingleMul(SkColor mul, SkColor add)
376845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com            : INHERITED(mul, add) {
3778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        SkASSERT(SkColorGetR(add) == 0);
3788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        SkASSERT(SkColorGetG(add) == 0);
3798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        SkASSERT(SkColorGetB(add) == 0);
3808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        SkASSERT(SkColorGetR(mul) == SkColorGetG(mul));
3818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        SkASSERT(SkColorGetR(mul) == SkColorGetB(mul));
3828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
3838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
384845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com    virtual uint32_t getFlags() {
3858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        return this->INHERITED::getFlags() | (kAlphaUnchanged_Flag | kHasFilter16_Flag);
3868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
3878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
388845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com    virtual void filterSpan16(const uint16_t shader[], int count,
389845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com                              uint16_t result[]) {
3908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        // all mul components are the same
3918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        unsigned scale = SkAlpha255To256(SkColorGetR(fMul));
3928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
393845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com        if (count > 0) {
3948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            do {
3958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                *result++ = SkAlphaMulRGB16(*shader++, scale);
3968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            } while (--count > 0);
397845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com        }
3988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
3998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
4008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comprotected:
4018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    virtual Factory getFactory() { return CreateProc; }
4028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
4038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkLightingColorFilter_SingleMul(SkFlattenableReadBuffer& buffer)
4048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        : INHERITED(buffer) {}
4058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
4068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comprivate:
407845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com    static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) {
4088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        return SkNEW_ARGS(SkLightingColorFilter_SingleMul, (buffer));
4098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
4108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
4118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    typedef SkLightingColorFilter INHERITED;
4128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com};
4138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
4148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comclass SkLightingColorFilter_NoPin : public SkLightingColorFilter {
4158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.compublic:
4168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkLightingColorFilter_NoPin(SkColor mul, SkColor add)
4178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    : INHERITED(mul, add) {}
4188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
419845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com    virtual void filterSpan(const SkPMColor shader[], int count,
420845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com                            SkPMColor result[]) {
4218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        unsigned scaleR = SkAlpha255To256(SkColorGetR(fMul));
4228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        unsigned scaleG = SkAlpha255To256(SkColorGetG(fMul));
4238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        unsigned scaleB = SkAlpha255To256(SkColorGetB(fMul));
4248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
4258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        unsigned addR = SkColorGetR(fAdd);
4268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        unsigned addG = SkColorGetG(fAdd);
4278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        unsigned addB = SkColorGetB(fAdd);
4288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
429845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com        for (int i = 0; i < count; i++) {
4308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            SkPMColor c = shader[i];
431845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com            if (c) {
4328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                unsigned a = SkGetPackedA32(c);
4338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                unsigned scaleA = SkAlpha255To256(a);
4348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                unsigned r = SkAlphaMul(SkGetPackedR32(c), scaleR) + SkAlphaMul(addR, scaleA);
4358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                unsigned g = SkAlphaMul(SkGetPackedG32(c), scaleG) + SkAlphaMul(addG, scaleA);
4368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                unsigned b = SkAlphaMul(SkGetPackedB32(c), scaleB) + SkAlphaMul(addB, scaleA);
4378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                c = SkPackARGB32(a, r, g, b);
4388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            }
4398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            result[i] = c;
4408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        }
4418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
4428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
4438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comprotected:
4448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    virtual Factory getFactory() { return CreateProc; }
4458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
4468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkLightingColorFilter_NoPin(SkFlattenableReadBuffer& buffer)
4478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        : INHERITED(buffer) {}
4488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
4498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comprivate:
450845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com    static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) {
4518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        return SkNEW_ARGS(SkLightingColorFilter_NoPin, (buffer));
4528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
4538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
4548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    typedef SkLightingColorFilter INHERITED;
4558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com};
4568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
457845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com///////////////////////////////////////////////////////////////////////////////
4588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
4598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comclass SkSimpleColorFilter : public SkColorFilter {
4608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comprotected:
461845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com    void filterSpan(const SkPMColor src[], int count, SkPMColor result[]) {
462845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com        if (result != src) {
4638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            memcpy(result, src, count * sizeof(SkPMColor));
464845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com        }
4658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
4668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
467845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com    virtual void flatten(SkFlattenableWriteBuffer& buffer) {}
4688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
469845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com    virtual Factory getFactory() {
4708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        return CreateProc;
4718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
4728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
473845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com    static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) {
4748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        return SkNEW(SkSimpleColorFilter);
4758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
4768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com};
4778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
478845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.comSkColorFilter* SkColorFilter::CreateLightingFilter(SkColor mul, SkColor add) {
4798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    mul &= 0x00FFFFFF;
4808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    add &= 0x00FFFFFF;
4818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
482845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com    if (0xFFFFFF == mul) {
483845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com        if (0 == add) {
4848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            return SkNEW(SkSimpleColorFilter);   // no change to the colors
485845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com        } else {
4868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            return SkNEW_ARGS(SkLightingColorFilter_JustAdd, (mul, add));
487845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com        }
4888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
4898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
490845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com    if (0 == add) {
4918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        if (SkColorGetR(mul) == SkColorGetG(mul) &&
492845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com                SkColorGetR(mul) == SkColorGetB(mul)) {
4938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            return SkNEW_ARGS(SkLightingColorFilter_SingleMul, (mul, add));
494845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com        } else {
4958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            return SkNEW_ARGS(SkLightingColorFilter_JustMul, (mul, add));
4968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        }
4978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
4988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
4998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (SkColorGetR(mul) + SkColorGetR(add) <= 255 &&
5008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        SkColorGetG(mul) + SkColorGetG(add) <= 255 &&
501845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com        SkColorGetB(mul) + SkColorGetB(add) <= 255) {
502845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com            return SkNEW_ARGS(SkLightingColorFilter_NoPin, (mul, add));
503845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com    }
5048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
5058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    return SkNEW_ARGS(SkLightingColorFilter, (mul, add));
5068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
5078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
508