11cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
20910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project/*
31cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * Copyright 2006 The Android Open Source Project
40910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project *
51cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * Use of this source code is governed by a BSD-style license that can be
61cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * found in the LICENSE file.
70910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project */
80910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
91cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#ifndef SkColorFilter_DEFINED
110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#define SkColorFilter_DEFINED
120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkColor.h"
140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkFlattenable.h"
1559f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed#include "SkXfermode.h"
160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1735e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenbergerclass SK_API SkColorFilter : public SkFlattenable {
180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectpublic:
1935e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger    /**
2035e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger     *  If the filter can be represented by a source color plus Mode, this
2135e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger     *  returns true, and sets (if not NULL) the color and mode appropriately.
2235e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger     *  If not, this returns false and ignores the parameters.
2335e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger     */
2435e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger    virtual bool asColorMode(SkColor* color, SkXfermode::Mode* mode);
2535e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger
261cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    /**
271cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger     *  If the filter can be represented by a 5x4 matrix, this
281cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger     *  returns true, and sets the matrix appropriately.
291cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger     *  If not, this returns false and ignores the parameter.
301cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger     */
311cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    virtual bool asColorMatrix(SkScalar matrix[20]);
321cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
331cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    /**
341cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger     *  If the filter can be represented by per-component table, return true,
351cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger     *  and if table is not null, copy the bitmap containing the table into it.
361cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger     *
371cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger     *  The table bitmap will be in SkBitmap::kA8_Config. Each row corresponding
381cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger     *  to each component in ARGB order. e.g. row[0] == alpha, row[1] == red,
391cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger     *  etc. To transform a color, you (logically) perform the following:
401cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger     *
411cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger     *      a' = *table.getAddr8(a, 0);
421cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger     *      r' = *table.getAddr8(r, 1);
431cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger     *      g' = *table.getAddr8(g, 2);
441cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger     *      b' = *table.getAddr8(b, 3);
451cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger     *
461cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger     *  The original component value is the horizontal index for a given row,
471cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger     *  and the stored value at that index is the new value for that component.
481cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger     */
491cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    virtual bool asComponentTable(SkBitmap* table);
501cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    /** Called with a scanline of colors, as if there was a shader installed.
520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        The implementation writes out its filtered version into result[].
530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        Note: shader and result may be the same buffer.
540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        @param src      array of colors, possibly generated by a shader
550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        @param count    the number of entries in the src[] and result[] arrays
560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        @param result   written by the filter
570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    */
580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    virtual void filterSpan(const SkPMColor src[], int count,
590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                            SkPMColor result[]) = 0;
600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    /** Called with a scanline of colors, as if there was a shader installed.
610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        The implementation writes out its filtered version into result[].
620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        Note: shader and result may be the same buffer.
630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        @param src      array of colors, possibly generated by a shader
640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        @param count    the number of entries in the src[] and result[] arrays
650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        @param result   written by the filter
660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    */
670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    virtual void filterSpan16(const uint16_t shader[], int count,
680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                              uint16_t result[]);
690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    enum Flags {
710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        /** If set the filter methods will not change the alpha channel of the
720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            colors.
730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        */
740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        kAlphaUnchanged_Flag = 0x01,
750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        /** If set, this subclass implements filterSpan16(). If this flag is
760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            set, then kAlphaUnchanged_Flag must also be set.
770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        */
780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        kHasFilter16_Flag    = 0x02
790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    };
800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    /** Returns the flags for this filter. Override in subclasses to return
820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        custom flags.
830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    */
840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    virtual uint32_t getFlags() { return 0; }
850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
8635e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger    /**
8735e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger     *  Apply this colorfilter to the specified SkColor. This routine handles
8835e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger     *  converting to SkPMColor, calling the filter, and then converting back
8935e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger     *  to SkColor. This method is not virtual, but will call filterSpan()
9035e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger     *   which is virtual.
9135e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger     */
9235e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger    SkColor filterColor(SkColor);
9335e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger
9435e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger
9559f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed    /** Create a colorfilter that uses the specified color and mode.
9659f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed        If the Mode is DST, this function will return NULL (since that
970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        mode will have no effect on the result).
9859f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed        @param c    The source color used with the specified mode
9959f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed        @param mode The xfermode mode that is applied to each color in
1000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                        the colorfilter's filterSpan[16,32] methods
10159f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed        @return colorfilter object that applies the src color and mode,
10259f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed                    or NULL if the mode will have no effect.
1030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    */
10459f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed    static SkColorFilter* CreateModeFilter(SkColor c, SkXfermode::Mode mode);
1050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    /** Create a colorfilter that calls through to the specified procs to
1070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        filter the colors. The SkXfermodeProc parameter must be non-null, but
1080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        the SkXfermodeProc16 is optional, and may be null.
1090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    */
11059f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed    static SkColorFilter* CreateProcFilter(SkColor srcColor,
11159f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed                                           SkXfermodeProc proc,
11259f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed                                           SkXfermodeProc16 proc16 = NULL);
1130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    /** Create a colorfilter that multiplies the RGB channels by one color, and
1150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        then adds a second color, pinning the result for each component to
1160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        [0..255]. The alpha components of the mul and add arguments
1170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        are ignored.
1180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    */
1190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    static SkColorFilter* CreateLightingFilter(SkColor mul, SkColor add);
1201cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
1211cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SK_DECLARE_FLATTENABLE_REGISTRAR()
1220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectprotected:
1230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkColorFilter() {}
1240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkColorFilter(SkFlattenableReadBuffer& rb) : INHERITED(rb) {}
12535e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger
1260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectprivate:
1270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    typedef SkFlattenable INHERITED;
1280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project};
1290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkShader.h"
1310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectclass SkFilterShader : public SkShader {
1330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectpublic:
1340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkFilterShader(SkShader* shader, SkColorFilter* filter);
1350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    virtual ~SkFilterShader();
1360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    // override
1380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    virtual uint32_t getFlags();
1390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    virtual bool setContext(const SkBitmap& device, const SkPaint& paint,
1400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                            const SkMatrix& matrix);
1410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    virtual void shadeSpan(int x, int y, SkPMColor result[], int count);
1420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    virtual void shadeSpan16(int x, int y, uint16_t result[], int count);
1430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    virtual void beginSession();
1440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    virtual void endSession();
14535e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger
1460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectprotected:
1470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkFilterShader(SkFlattenableReadBuffer& );
1481cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    virtual void flatten(SkFlattenableWriteBuffer& ) SK_OVERRIDE;
1491cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    virtual Factory getFactory() SK_OVERRIDE { return CreateProc; }
1500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectprivate:
15135e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger    static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) {
1520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return SkNEW_ARGS(SkFilterShader, (buffer)); }
1530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkShader*       fShader;
1540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkColorFilter*  fFilter;
15535e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger
1560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    typedef SkShader INHERITED;
1570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project};
1580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#endif
160