180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/*
380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Copyright 2006 The Android Open Source Project
480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *
580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Use of this source code is governed by a BSD-style license that can be
680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * found in the LICENSE file.
780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */
880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
1080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#ifndef SkColorFilter_DEFINED
1180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#define SkColorFilter_DEFINED
1280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
1380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkColor.h"
1480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkFlattenable.h"
1580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkXfermode.h"
1680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
1780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruclass SkBitmap;
18d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenbergerclass GrEffectRef;
19363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenbergerclass GrContext;
2080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
2180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruclass SK_API SkColorFilter : public SkFlattenable {
2280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querupublic:
2380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SK_DECLARE_INST_COUNT(SkColorFilter)
2480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
2580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    /**
2680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     *  If the filter can be represented by a source color plus Mode, this
2780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     *  returns true, and sets (if not NULL) the color and mode appropriately.
2880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     *  If not, this returns false and ignores the parameters.
2980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     */
30363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger    virtual bool asColorMode(SkColor* color, SkXfermode::Mode* mode) const;
3180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
3280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    /**
3380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     *  If the filter can be represented by a 5x4 matrix, this
3480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     *  returns true, and sets the matrix appropriately.
3580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     *  If not, this returns false and ignores the parameter.
3680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     */
37363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger    virtual bool asColorMatrix(SkScalar matrix[20]) const;
3880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
3980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    /**
4080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     *  If the filter can be represented by per-component table, return true,
4180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     *  and if table is not null, copy the bitmap containing the table into it.
4280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     *
4380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     *  The table bitmap will be in SkBitmap::kA8_Config. Each row corresponding
4480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     *  to each component in ARGB order. e.g. row[0] == alpha, row[1] == red,
4580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     *  etc. To transform a color, you (logically) perform the following:
4680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     *
4780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     *      a' = *table.getAddr8(a, 0);
4880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     *      r' = *table.getAddr8(r, 1);
4980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     *      g' = *table.getAddr8(g, 2);
5080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     *      b' = *table.getAddr8(b, 3);
5180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     *
5280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     *  The original component value is the horizontal index for a given row,
5380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     *  and the stored value at that index is the new value for that component.
5480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     */
55363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger    virtual bool asComponentTable(SkBitmap* table) const;
5680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
5780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    /** Called with a scanline of colors, as if there was a shader installed.
5880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        The implementation writes out its filtered version into result[].
5980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        Note: shader and result may be the same buffer.
6080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        @param src      array of colors, possibly generated by a shader
6180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        @param count    the number of entries in the src[] and result[] arrays
6280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        @param result   written by the filter
6380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    */
6480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    virtual void filterSpan(const SkPMColor src[], int count,
65363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger                            SkPMColor result[]) const = 0;
6680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    /** Called with a scanline of colors, as if there was a shader installed.
6780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        The implementation writes out its filtered version into result[].
6880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        Note: shader and result may be the same buffer.
6980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        @param src      array of colors, possibly generated by a shader
7080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        @param count    the number of entries in the src[] and result[] arrays
7180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        @param result   written by the filter
7280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    */
7380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    virtual void filterSpan16(const uint16_t shader[], int count,
74363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger                              uint16_t result[]) const;
7580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
7680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    enum Flags {
7780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        /** If set the filter methods will not change the alpha channel of the
7880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            colors.
7980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        */
8080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        kAlphaUnchanged_Flag = 0x01,
8180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        /** If set, this subclass implements filterSpan16(). If this flag is
8280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            set, then kAlphaUnchanged_Flag must also be set.
8380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        */
8480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        kHasFilter16_Flag    = 0x02
8580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    };
8680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
8780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    /** Returns the flags for this filter. Override in subclasses to return
8880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        custom flags.
8980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    */
90363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger    virtual uint32_t getFlags() const { return 0; }
9180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
9280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    /**
9380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     *  Apply this colorfilter to the specified SkColor. This routine handles
9480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     *  converting to SkPMColor, calling the filter, and then converting back
9580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     *  to SkColor. This method is not virtual, but will call filterSpan()
9680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     *   which is virtual.
9780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     */
98363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger    SkColor filterColor(SkColor) const;
9980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
10080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    /** Create a colorfilter that uses the specified color and mode.
10180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        If the Mode is DST, this function will return NULL (since that
10280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        mode will have no effect on the result).
10380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        @param c    The source color used with the specified mode
10480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        @param mode The xfermode mode that is applied to each color in
10580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                        the colorfilter's filterSpan[16,32] methods
10680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        @return colorfilter object that applies the src color and mode,
10780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                    or NULL if the mode will have no effect.
10880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    */
10980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    static SkColorFilter* CreateModeFilter(SkColor c, SkXfermode::Mode mode);
11080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
11180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    /** Create a colorfilter that multiplies the RGB channels by one color, and
11280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        then adds a second color, pinning the result for each component to
11380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        [0..255]. The alpha components of the mul and add arguments
11480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        are ignored.
11580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    */
11680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    static SkColorFilter* CreateLightingFilter(SkColor mul, SkColor add);
11780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
118363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger    /** A subclass may implement this factory function to work with the GPU backend. If the return
119363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger        is non-NULL then the caller owns a ref on the returned object.
120363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger     */
121d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    virtual GrEffectRef* asNewEffect(GrContext*) const;
122363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger
123779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger    SkDEVCODE(virtual void toString(SkString* str) const = 0;)
124779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger
12580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SK_DECLARE_FLATTENABLE_REGISTRAR_GROUP()
12680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruprotected:
12780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkColorFilter() {}
12880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkColorFilter(SkFlattenableReadBuffer& rb) : INHERITED(rb) {}
12980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
13080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruprivate:
13180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    typedef SkFlattenable INHERITED;
13280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru};
13380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
13480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif
135