11cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
259f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed/*
31cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * Copyright 2006 The Android Open Source Project
459f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed *
51cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * Use of this source code is governed by a BSD-style license that can be
61cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * found in the LICENSE file.
759f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed */
80910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
91cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
10d0195f840fa964da51f7a1192b432954794e660cMike Reed#include "SkBlitRow.h"
110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkColorFilter.h"
120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkColorPriv.h"
130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkUtils.h"
140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1535e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger#define ILLEGAL_XFERMODE_MODE   ((SkXfermode::Mode)-1)
1635e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger
1735e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger// baseclass for filters that store a color and mode
1835e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenbergerclass SkModeColorFilter : public SkColorFilter {
1935e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenbergerpublic:
2035e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger    SkModeColorFilter(SkColor color) {
2135e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger        fColor = color;
2235e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger        fMode = ILLEGAL_XFERMODE_MODE;
2335e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger
2435e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger        fPMColor = SkPreMultiplyColor(fColor);
2535e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger    }
2635e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger
2735e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger    SkModeColorFilter(SkColor color, SkXfermode::Mode mode) {
2835e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger        fColor = color;
2935e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger        fMode = mode;
3035e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger
3135e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger        fPMColor = SkPreMultiplyColor(fColor);
3235e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger    };
3335e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger
3435e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger    virtual bool asColorMode(SkColor* color, SkXfermode::Mode* mode) {
3535e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger        if (ILLEGAL_XFERMODE_MODE == fMode) {
3635e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger            return false;
3735e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger        }
3835e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger
3935e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger        if (color) {
4035e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger            *color = fColor;
4135e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger        }
4235e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger        if (mode) {
4335e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger            *mode = fMode;
4435e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger        }
4535e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger        return true;
4635e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger    }
470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
4835e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger    SkColor getColor() const { return fColor; }
4935e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger    SkXfermode::Mode getMode() const { return fMode; }
5035e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger    bool isModeValid() const { return ILLEGAL_XFERMODE_MODE != fMode; }
5135e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger
5235e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenbergerprotected:
5359f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed    virtual void flatten(SkFlattenableWriteBuffer& buffer) {
5435e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger        this->INHERITED::flatten(buffer);
5535e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger        buffer.write32(fColor);
5635e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger        buffer.write32(fMode);
570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
5859f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed
5935e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger    SkModeColorFilter(SkFlattenableReadBuffer& buffer) {
6035e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger        fColor = buffer.readU32();
6135e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger        fMode = (SkXfermode::Mode)buffer.readU32();
6235e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger
6335e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger        fPMColor = SkPreMultiplyColor(fColor);
640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
6559f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed
6635e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger    // cache of fColor in premultiply space
6759f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed    SkPMColor   fPMColor;
6835e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger
6935e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenbergerprivate:
7035e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger    SkColor             fColor;
7135e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger    SkXfermode::Mode    fMode;
7235e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger
7335e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger    typedef SkColorFilter INHERITED;
740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project};
750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
7635e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenbergerclass Src_SkModeColorFilter : public SkModeColorFilter {
770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectpublic:
7835e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger    Src_SkModeColorFilter(SkColor color) : INHERITED(color, SkXfermode::kSrc_Mode) {}
790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
8059f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed    virtual uint32_t getFlags() {
8159f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed        if (SkGetPackedA32(fPMColor) == 0xFF) {
820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            return kAlphaUnchanged_Flag | kHasFilter16_Flag;
8359f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed        } else {
840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            return 0;
8559f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed        }
860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
8859f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed    virtual void filterSpan(const SkPMColor shader[], int count,
8959f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed                            SkPMColor result[]) {
9059f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed        sk_memset32(result, fPMColor, count);
910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
9359f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed    virtual void filterSpan16(const uint16_t shader[], int count,
9459f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed                              uint16_t result[]) {
950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkASSERT(this->getFlags() & kHasFilter16_Flag);
9659f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed        sk_memset16(result, SkPixel32ToPixel16(fPMColor), count);
970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
9935e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger    static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) {
10035e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger        return SkNEW_ARGS(Src_SkModeColorFilter, (buffer));
10135e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger    }
10235e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger
1030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectprotected:
1040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    virtual Factory getFactory() { return CreateProc; }
1050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
10635e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger    Src_SkModeColorFilter(SkFlattenableReadBuffer& buffer)
10759f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed        : INHERITED(buffer) {}
10859f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed
10935e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenbergerprivate:
11035e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger    typedef SkModeColorFilter INHERITED;
1110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project};
1120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
11335e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenbergerclass SrcOver_SkModeColorFilter : public SkModeColorFilter {
1140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectpublic:
11535e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger    SrcOver_SkModeColorFilter(SkColor color)
11635e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger            : INHERITED(color, SkXfermode::kSrcOver_Mode) {
11735e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger        fColor32Proc = NULL;
11835e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger    }
1190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
12059f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed    virtual uint32_t getFlags() {
12159f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed        if (SkGetPackedA32(fPMColor) == 0xFF) {
1220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            return kAlphaUnchanged_Flag | kHasFilter16_Flag;
12359f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed        } else {
1240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            return 0;
12559f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed        }
1260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
12735e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger
12859f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed    virtual void filterSpan(const SkPMColor shader[], int count,
12959f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed                            SkPMColor result[]) {
13035e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger        if (NULL == fColor32Proc) {
13135e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger            fColor32Proc = SkBlitRow::ColorProcFactory();
13235e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger        }
13340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        fColor32Proc(result, shader, count, fPMColor);
1340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
1350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
13659f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed    virtual void filterSpan16(const uint16_t shader[], int count,
13759f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed                              uint16_t result[]) {
1380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkASSERT(this->getFlags() & kHasFilter16_Flag);
13959f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed        sk_memset16(result, SkPixel32ToPixel16(fPMColor), count);
1400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
14135e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger
14235e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger    static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) {
14335e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger        return SkNEW_ARGS(SrcOver_SkModeColorFilter, (buffer));
14435e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger    }
14535e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger
1460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectprotected:
1470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    virtual Factory getFactory() { return CreateProc;  }
14835e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger
14935e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger    SrcOver_SkModeColorFilter(SkFlattenableReadBuffer& buffer)
15035e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger        : INHERITED(buffer), fColor32Proc(NULL) {}
15135e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger
1520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectprivate:
15335e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger
15440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    SkBlitRow::ColorProc fColor32Proc;
15535e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger
15635e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger    typedef SkModeColorFilter INHERITED;
1570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project};
1580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
15935e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger///////////////////////////////////////////////////////////////////////////////
1600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
16135e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenbergerclass Proc_SkModeColorFilter : public SkModeColorFilter {
1620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectpublic:
16335e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger    Proc_SkModeColorFilter(SkColor color, SkXfermode::Mode mode) : INHERITED(color, mode) {
16435e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger        fProc = SkXfermode::GetProc(mode);
16535e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger        fProc16 = SkXfermode::GetProc16(mode, color);
16635e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger    }
16735e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger
16835e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger    Proc_SkModeColorFilter(SkColor color,
16935e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger                           SkXfermodeProc proc, SkXfermodeProc16 proc16)
17035e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger            : INHERITED(color, ILLEGAL_XFERMODE_MODE) {
1710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fProc = proc;
1720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fProc16 = proc16;
1730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
17435e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger
17559f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed    virtual uint32_t getFlags() {
1760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return fProc16 ? (kAlphaUnchanged_Flag | kHasFilter16_Flag) : 0;
1770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
1780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
17959f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed    virtual void filterSpan(const SkPMColor shader[], int count,
18059f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed                            SkPMColor result[]) {
18159f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed        SkPMColor       color = fPMColor;
1820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkXfermodeProc  proc = fProc;
18359f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed
18459f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed        for (int i = 0; i < count; i++) {
1850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            result[i] = proc(color, shader[i]);
18659f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed        }
1870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
18835e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger
18959f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed    virtual void filterSpan16(const uint16_t shader[], int count,
19059f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed                              uint16_t result[]) {
1910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkASSERT(this->getFlags() & kHasFilter16_Flag);
19235e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger
19359f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed        SkPMColor        color = fPMColor;
1940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkXfermodeProc16 proc16 = fProc16;
19535e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger
19659f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed        for (int i = 0; i < count; i++) {
1970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            result[i] = proc16(color, shader[i]);
19859f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed        }
1990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
20035e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger
20135e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger    static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) {
20235e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger        return SkNEW_ARGS(Proc_SkModeColorFilter, (buffer));
20335e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger    }
20435e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger
2050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectprotected:
2060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    virtual void flatten(SkFlattenableWriteBuffer& buffer) {
2070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        this->INHERITED::flatten(buffer);
2080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        buffer.writeFunctionPtr((void*)fProc);
2090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        buffer.writeFunctionPtr((void*)fProc16);
2100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
21135e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger
21235e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger    virtual Factory getFactory() {
2130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return CreateProc;
2140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
2150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
21635e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger    Proc_SkModeColorFilter(SkFlattenableReadBuffer& buffer) : INHERITED(buffer) {
2170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fProc = (SkXfermodeProc) buffer.readFunctionPtr();
2180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fProc16 = (SkXfermodeProc16) buffer.readFunctionPtr();
2190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
2200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
22135e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenbergerprivate:
2220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkXfermodeProc   fProc;
2230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkXfermodeProc16 fProc16;
22435e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger
22535e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger    typedef SkModeColorFilter INHERITED;
2260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project};
2270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
22859f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike ReedSkColorFilter* SkColorFilter::CreateProcFilter(SkColor color,
22959f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed                                               SkXfermodeProc proc,
23059f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed                                               SkXfermodeProc16 proc16) {
2310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return proc ?
23235e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger            SkNEW_ARGS(Proc_SkModeColorFilter, (color, proc, proc16)) :
2330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            NULL;
2340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
2350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
2360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project///////////////////////////////////////////////////////////////////////////////
2370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
23859f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike ReedSkColorFilter* SkColorFilter::CreateModeFilter(SkColor color,
23959f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed                                               SkXfermode::Mode mode) {
2400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    unsigned alpha = SkColorGetA(color);
2410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
2420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    // first collaps some modes if possible
2430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
24459f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed    if (SkXfermode::kClear_Mode == mode) {
2450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        color = 0;
24659f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed        mode = SkXfermode::kSrc_Mode;
24759f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed    } else if (SkXfermode::kSrcOver_Mode == mode) {
24859f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed        if (0 == alpha) {
24959f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed            mode = SkXfermode::kDst_Mode;
25059f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed        } else if (255 == alpha) {
25159f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed            mode = SkXfermode::kSrc_Mode;
2520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
2530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        // else just stay srcover
2540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
2550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
2560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    // weed out combinations that are noops, and just return null
25759f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed    if (SkXfermode::kDst_Mode == mode ||
25859f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed        (0 == alpha && (SkXfermode::kSrcOver_Mode == mode ||
25959f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed                        SkXfermode::kDstOver_Mode == mode ||
26059f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed                        SkXfermode::kDstOut_Mode == mode ||
26159f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed                        SkXfermode::kSrcATop_Mode == mode ||
26259f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed                        SkXfermode::kXor_Mode == mode ||
26359f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed                        SkXfermode::kDarken_Mode == mode)) ||
26459f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed            (0xFF == alpha && SkXfermode::kDstIn_Mode == mode)) {
2650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return NULL;
2660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
26735e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger
2680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    switch (mode) {
26935e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger        case SkXfermode::kSrc_Mode:
27035e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger            return SkNEW_ARGS(Src_SkModeColorFilter, (color));
27135e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger        case SkXfermode::kSrcOver_Mode:
27235e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger            return SkNEW_ARGS(SrcOver_SkModeColorFilter, (color));
27335e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger        default:
27435e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger            return SkNEW_ARGS(Proc_SkModeColorFilter, (color, mode));
2750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
2760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
2770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
27859f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed///////////////////////////////////////////////////////////////////////////////
2790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
28059f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reedstatic inline unsigned pin(unsigned value, unsigned max) {
28159f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed    if (value > max) {
2820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        value = max;
28359f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed    }
2840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return value;
2850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
2860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
28759f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reedstatic inline unsigned SkUClampMax(unsigned value, unsigned max) {
2880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT((int32_t)value >= 0);
2890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT((int32_t)max >= 0);
2900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
2910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    int diff = max - value;
2920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    // clear diff if diff is positive
2930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    diff &= diff >> 31;
2940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
2950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return value + diff;
2960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
2970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
2980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectclass SkLightingColorFilter : public SkColorFilter {
2990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectpublic:
3000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkLightingColorFilter(SkColor mul, SkColor add) : fMul(mul), fAdd(add) {}
3010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
30259f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed    virtual void filterSpan(const SkPMColor shader[], int count,
30359f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed                            SkPMColor result[]) {
3040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        unsigned scaleR = SkAlpha255To256(SkColorGetR(fMul));
3050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        unsigned scaleG = SkAlpha255To256(SkColorGetG(fMul));
3060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        unsigned scaleB = SkAlpha255To256(SkColorGetB(fMul));
30735e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger
3080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        unsigned addR = SkColorGetR(fAdd);
3090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        unsigned addG = SkColorGetG(fAdd);
3100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        unsigned addB = SkColorGetB(fAdd);
3110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
31259f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed        for (int i = 0; i < count; i++) {
3130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            SkPMColor c = shader[i];
31459f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed            if (c) {
3150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                unsigned a = SkGetPackedA32(c);
31635e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger                unsigned scaleA = SkAlpha255To256(a);
3170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                unsigned r = pin(SkAlphaMul(SkGetPackedR32(c), scaleR) + SkAlphaMul(addR, scaleA), a);
3180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                unsigned g = pin(SkAlphaMul(SkGetPackedG32(c), scaleG) + SkAlphaMul(addG, scaleA), a);
3190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                unsigned b = pin(SkAlphaMul(SkGetPackedB32(c), scaleB) + SkAlphaMul(addB, scaleA), a);
3200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                c = SkPackARGB32(a, r, g, b);
3210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            }
3220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            result[i] = c;
3230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
3240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
3250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
3261cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) {
3271cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        return SkNEW_ARGS(SkLightingColorFilter, (buffer));
3281cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
3291cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
3300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectprotected:
33159f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed    virtual void flatten(SkFlattenableWriteBuffer& buffer) {
33235e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger        this->INHERITED::flatten(buffer);
3330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        buffer.write32(fMul);
3340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        buffer.write32(fAdd);
3350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
33635e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger
33759f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed    virtual Factory getFactory() {
3380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return CreateProc;
3390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
3400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
34159f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed    SkLightingColorFilter(SkFlattenableReadBuffer& buffer) {
3420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fMul = buffer.readU32();
3430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fAdd = buffer.readU32();
3440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
34535e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger
3460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkColor fMul, fAdd;
3470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
3480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectprivate:
34935e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger    typedef SkColorFilter INHERITED;
3500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project};
3510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
3520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectclass SkLightingColorFilter_JustAdd : public SkLightingColorFilter {
3530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectpublic:
3540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkLightingColorFilter_JustAdd(SkColor mul, SkColor add)
3550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        : INHERITED(mul, add) {}
3560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
35759f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed    virtual void filterSpan(const SkPMColor shader[], int count,
35859f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed                            SkPMColor result[]) {
3590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        unsigned addR = SkColorGetR(fAdd);
3600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        unsigned addG = SkColorGetG(fAdd);
3610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        unsigned addB = SkColorGetB(fAdd);
3620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
36359f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed        for (int i = 0; i < count; i++) {
3640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            SkPMColor c = shader[i];
36559f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed            if (c) {
3660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                unsigned a = SkGetPackedA32(c);
36735e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger                unsigned scaleA = SkAlpha255To256(a);
3680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                unsigned r = pin(SkGetPackedR32(c) + SkAlphaMul(addR, scaleA), a);
3690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                unsigned g = pin(SkGetPackedG32(c) + SkAlphaMul(addG, scaleA), a);
3700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                unsigned b = pin(SkGetPackedB32(c) + SkAlphaMul(addB, scaleA), a);
3710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                c = SkPackARGB32(a, r, g, b);
3720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            }
3730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            result[i] = c;
3740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
3750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
3760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
3771cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer)  {
3781cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        return SkNEW_ARGS(SkLightingColorFilter_JustAdd, (buffer));
3791cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
3801cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
3810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectprotected:
3820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    virtual Factory getFactory() { return CreateProc; }
3830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
3840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkLightingColorFilter_JustAdd(SkFlattenableReadBuffer& buffer)
3850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        : INHERITED(buffer) {}
3860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
3870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectprivate:
3880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    typedef SkLightingColorFilter INHERITED;
3890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project};
3900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
3910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectclass SkLightingColorFilter_JustMul : public SkLightingColorFilter {
3920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectpublic:
3930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkLightingColorFilter_JustMul(SkColor mul, SkColor add)
3940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        : INHERITED(mul, add) {}
3950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
39659f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed    virtual void filterSpan(const SkPMColor shader[], int count,
39759f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed                            SkPMColor result[]) {
3980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        unsigned scaleR = SkAlpha255To256(SkColorGetR(fMul));
3990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        unsigned scaleG = SkAlpha255To256(SkColorGetG(fMul));
4000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        unsigned scaleB = SkAlpha255To256(SkColorGetB(fMul));
40135e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger
40259f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed        for (int i = 0; i < count; i++) {
4030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            SkPMColor c = shader[i];
40459f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed            if (c) {
4050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                unsigned a = SkGetPackedA32(c);
4060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                unsigned r = SkAlphaMul(SkGetPackedR32(c), scaleR);
4070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                unsigned g = SkAlphaMul(SkGetPackedG32(c), scaleG);
4080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                unsigned b = SkAlphaMul(SkGetPackedB32(c), scaleB);
4090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                c = SkPackARGB32(a, r, g, b);
4100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            }
4110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            result[i] = c;
4120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
4130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
4140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
4151cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) {
4161cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        return SkNEW_ARGS(SkLightingColorFilter_JustMul, (buffer));
4171cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
4181cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
4190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectprotected:
4200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    virtual Factory getFactory() { return CreateProc; }
4210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
4220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkLightingColorFilter_JustMul(SkFlattenableReadBuffer& buffer)
4230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        : INHERITED(buffer) {}
42435e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger
4250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectprivate:
4260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    typedef SkLightingColorFilter INHERITED;
4270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project};
4280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
4290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectclass SkLightingColorFilter_SingleMul : public SkLightingColorFilter {
4300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectpublic:
4310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkLightingColorFilter_SingleMul(SkColor mul, SkColor add)
43259f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed            : INHERITED(mul, add) {
4330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkASSERT(SkColorGetR(add) == 0);
4340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkASSERT(SkColorGetG(add) == 0);
4350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkASSERT(SkColorGetB(add) == 0);
4360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkASSERT(SkColorGetR(mul) == SkColorGetG(mul));
4370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkASSERT(SkColorGetR(mul) == SkColorGetB(mul));
4380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
43935e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger
44059f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed    virtual uint32_t getFlags() {
4410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return this->INHERITED::getFlags() | (kAlphaUnchanged_Flag | kHasFilter16_Flag);
4420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
4430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
44459f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed    virtual void filterSpan16(const uint16_t shader[], int count,
44559f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed                              uint16_t result[]) {
4460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        // all mul components are the same
4470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        unsigned scale = SkAlpha255To256(SkColorGetR(fMul));
4480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
44959f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed        if (count > 0) {
4500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            do {
4510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                *result++ = SkAlphaMulRGB16(*shader++, scale);
4520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            } while (--count > 0);
45359f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed        }
4540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
4550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
4561cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) {
4571cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        return SkNEW_ARGS(SkLightingColorFilter_SingleMul, (buffer));
4581cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
4591cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
4600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectprotected:
4610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    virtual Factory getFactory() { return CreateProc; }
4620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
4630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkLightingColorFilter_SingleMul(SkFlattenableReadBuffer& buffer)
4640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        : INHERITED(buffer) {}
4650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
4660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectprivate:
4670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    typedef SkLightingColorFilter INHERITED;
4680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project};
4690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
4700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectclass SkLightingColorFilter_NoPin : public SkLightingColorFilter {
4710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectpublic:
4720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkLightingColorFilter_NoPin(SkColor mul, SkColor add)
4730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    : INHERITED(mul, add) {}
47435e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger
47559f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed    virtual void filterSpan(const SkPMColor shader[], int count,
47659f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed                            SkPMColor result[]) {
4770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        unsigned scaleR = SkAlpha255To256(SkColorGetR(fMul));
4780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        unsigned scaleG = SkAlpha255To256(SkColorGetG(fMul));
4790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        unsigned scaleB = SkAlpha255To256(SkColorGetB(fMul));
48035e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger
4810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        unsigned addR = SkColorGetR(fAdd);
4820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        unsigned addG = SkColorGetG(fAdd);
4830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        unsigned addB = SkColorGetB(fAdd);
48435e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger
48559f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed        for (int i = 0; i < count; i++) {
4860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            SkPMColor c = shader[i];
48759f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed            if (c) {
4880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                unsigned a = SkGetPackedA32(c);
48935e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger                unsigned scaleA = SkAlpha255To256(a);
4900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                unsigned r = SkAlphaMul(SkGetPackedR32(c), scaleR) + SkAlphaMul(addR, scaleA);
4910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                unsigned g = SkAlphaMul(SkGetPackedG32(c), scaleG) + SkAlphaMul(addG, scaleA);
4920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                unsigned b = SkAlphaMul(SkGetPackedB32(c), scaleB) + SkAlphaMul(addB, scaleA);
4930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                c = SkPackARGB32(a, r, g, b);
4940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            }
4950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            result[i] = c;
4960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
4970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
49835e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger
4991cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) {
5001cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        return SkNEW_ARGS(SkLightingColorFilter_NoPin, (buffer));
5011cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
5021cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
5030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectprotected:
5040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    virtual Factory getFactory() { return CreateProc; }
50535e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger
5060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkLightingColorFilter_NoPin(SkFlattenableReadBuffer& buffer)
5070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        : INHERITED(buffer) {}
50835e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger
5090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectprivate:
5100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    typedef SkLightingColorFilter INHERITED;
5110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project};
5120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
51359f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed///////////////////////////////////////////////////////////////////////////////
5140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
5150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectclass SkSimpleColorFilter : public SkColorFilter {
5161cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerpublic:
5171cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) {
5181cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        return SkNEW(SkSimpleColorFilter);
5191cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
5201cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
5210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectprotected:
52259f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed    void filterSpan(const SkPMColor src[], int count, SkPMColor result[]) {
52359f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed        if (result != src) {
5240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            memcpy(result, src, count * sizeof(SkPMColor));
52559f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed        }
5260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
5270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
52859f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed    virtual void flatten(SkFlattenableWriteBuffer& buffer) {}
52935e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger
53059f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed    virtual Factory getFactory() {
5310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return CreateProc;
5320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
5330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
5340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project};
5350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
53659f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike ReedSkColorFilter* SkColorFilter::CreateLightingFilter(SkColor mul, SkColor add) {
5370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    mul &= 0x00FFFFFF;
5380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    add &= 0x00FFFFFF;
5390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
54059f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed    if (0xFFFFFF == mul) {
54159f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed        if (0 == add) {
5420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            return SkNEW(SkSimpleColorFilter);   // no change to the colors
54359f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed        } else {
5440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            return SkNEW_ARGS(SkLightingColorFilter_JustAdd, (mul, add));
54559f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed        }
5460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
5470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
54859f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed    if (0 == add) {
5490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (SkColorGetR(mul) == SkColorGetG(mul) &&
55059f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed                SkColorGetR(mul) == SkColorGetB(mul)) {
5510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            return SkNEW_ARGS(SkLightingColorFilter_SingleMul, (mul, add));
55259f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed        } else {
5530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            return SkNEW_ARGS(SkLightingColorFilter_JustMul, (mul, add));
5540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
5550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
5560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
5570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (SkColorGetR(mul) + SkColorGetR(add) <= 255 &&
5580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkColorGetG(mul) + SkColorGetG(add) <= 255 &&
55959f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed        SkColorGetB(mul) + SkColorGetB(add) <= 255) {
56059f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed            return SkNEW_ARGS(SkLightingColorFilter_NoPin, (mul, add));
56159f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed    }
5620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
5630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return SkNEW_ARGS(SkLightingColorFilter, (mul, add));
5640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
5650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
5661cab2921ab279367f8206cdadc9259d12e603548Derek SollenbergerSK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkColorFilter)
5671cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(Src_SkModeColorFilter)
5681cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SrcOver_SkModeColorFilter)
5691cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(Proc_SkModeColorFilter)
5701cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLightingColorFilter)
5711cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLightingColorFilter_JustAdd)
5721cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLightingColorFilter_JustMul)
5731cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLightingColorFilter_SingleMul)
5741cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLightingColorFilter_NoPin)
5751cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkSimpleColorFilter)
5761cab2921ab279367f8206cdadc9259d12e603548Derek SollenbergerSK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END
57735e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger
578