1f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
2f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger/*
3f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger * Copyright 2006 The Android Open Source Project
4f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger *
5f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger * Use of this source code is governed by a BSD-style license that can be
6f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger * found in the LICENSE file.
7f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger */
8f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
9f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
10f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger#ifndef SkColorFilter_DEFINED
11f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger#define SkColorFilter_DEFINED
12f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
13f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger#include "SkColor.h"
14f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger#include "SkFlattenable.h"
15f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger#include "SkXfermode.h"
16f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
17f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerclass SK_API SkColorFilter : public SkFlattenable {
18f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerpublic:
19f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    /**
20f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger     *  If the filter can be represented by a source color plus Mode, this
21f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger     *  returns true, and sets (if not NULL) the color and mode appropriately.
22f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger     *  If not, this returns false and ignores the parameters.
23f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger     */
24f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    virtual bool asColorMode(SkColor* color, SkXfermode::Mode* mode);
25f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
26f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    /**
27f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger     *  If the filter can be represented by a 5x4 matrix, this
28f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger     *  returns true, and sets the matrix appropriately.
29f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger     *  If not, this returns false and ignores the parameter.
30f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger     */
31f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    virtual bool asColorMatrix(SkScalar matrix[20]);
32f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
33f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    /**
34f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger     *  If the filter can be represented by per-component table, return true,
35f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger     *  and if table is not null, copy the bitmap containing the table into it.
36f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger     *
37f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger     *  The table bitmap will be in SkBitmap::kA8_Config. Each row corresponding
38f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger     *  to each component in ARGB order. e.g. row[0] == alpha, row[1] == red,
39f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger     *  etc. To transform a color, you (logically) perform the following:
40f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger     *
41f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger     *      a' = *table.getAddr8(a, 0);
42f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger     *      r' = *table.getAddr8(r, 1);
43f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger     *      g' = *table.getAddr8(g, 2);
44f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger     *      b' = *table.getAddr8(b, 3);
45f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger     *
46f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger     *  The original component value is the horizontal index for a given row,
47f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger     *  and the stored value at that index is the new value for that component.
48f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger     */
49f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    virtual bool asComponentTable(SkBitmap* table);
50f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
51f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    /** Called with a scanline of colors, as if there was a shader installed.
52f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        The implementation writes out its filtered version into result[].
53f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        Note: shader and result may be the same buffer.
54f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        @param src      array of colors, possibly generated by a shader
55f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        @param count    the number of entries in the src[] and result[] arrays
56f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        @param result   written by the filter
57f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    */
58f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    virtual void filterSpan(const SkPMColor src[], int count,
59f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger                            SkPMColor result[]) = 0;
60f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    /** Called with a scanline of colors, as if there was a shader installed.
61f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        The implementation writes out its filtered version into result[].
62f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        Note: shader and result may be the same buffer.
63f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        @param src      array of colors, possibly generated by a shader
64f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        @param count    the number of entries in the src[] and result[] arrays
65f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        @param result   written by the filter
66f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    */
67f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    virtual void filterSpan16(const uint16_t shader[], int count,
68f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger                              uint16_t result[]);
69f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
70f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    enum Flags {
71f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        /** If set the filter methods will not change the alpha channel of the
72f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            colors.
73f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        */
74f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        kAlphaUnchanged_Flag = 0x01,
75f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        /** If set, this subclass implements filterSpan16(). If this flag is
76f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            set, then kAlphaUnchanged_Flag must also be set.
77f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        */
78f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        kHasFilter16_Flag    = 0x02
79f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    };
80f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
81f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    /** Returns the flags for this filter. Override in subclasses to return
82f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        custom flags.
83f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    */
84f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    virtual uint32_t getFlags() { return 0; }
85f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
86f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    /**
87f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger     *  Apply this colorfilter to the specified SkColor. This routine handles
88f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger     *  converting to SkPMColor, calling the filter, and then converting back
89f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger     *  to SkColor. This method is not virtual, but will call filterSpan()
90f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger     *   which is virtual.
91f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger     */
92f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    SkColor filterColor(SkColor);
93f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
94f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
95f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    /** Create a colorfilter that uses the specified color and mode.
96f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        If the Mode is DST, this function will return NULL (since that
97f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        mode will have no effect on the result).
98f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        @param c    The source color used with the specified mode
99f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        @param mode The xfermode mode that is applied to each color in
100f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger                        the colorfilter's filterSpan[16,32] methods
101f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        @return colorfilter object that applies the src color and mode,
102f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger                    or NULL if the mode will have no effect.
103f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    */
104f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    static SkColorFilter* CreateModeFilter(SkColor c, SkXfermode::Mode mode);
105f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
106f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    /** Create a colorfilter that calls through to the specified procs to
107f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        filter the colors. The SkXfermodeProc parameter must be non-null, but
108f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        the SkXfermodeProc16 is optional, and may be null.
109f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    */
110f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    static SkColorFilter* CreateProcFilter(SkColor srcColor,
111f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger                                           SkXfermodeProc proc,
112f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger                                           SkXfermodeProc16 proc16 = NULL);
113f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
114f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    /** Create a colorfilter that multiplies the RGB channels by one color, and
115f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        then adds a second color, pinning the result for each component to
116f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        [0..255]. The alpha components of the mul and add arguments
117f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        are ignored.
118f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    */
119f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    static SkColorFilter* CreateLightingFilter(SkColor mul, SkColor add);
120f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
121f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    SK_DECLARE_FLATTENABLE_REGISTRAR()
122f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerprotected:
123f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    SkColorFilter() {}
124f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    SkColorFilter(SkFlattenableReadBuffer& rb) : INHERITED(rb) {}
125f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
126f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerprivate:
127f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    typedef SkFlattenable INHERITED;
128f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger};
129f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
130f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger#include "SkShader.h"
131f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
132f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerclass SkFilterShader : public SkShader {
133f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerpublic:
134f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    SkFilterShader(SkShader* shader, SkColorFilter* filter);
135f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    virtual ~SkFilterShader();
136f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
137f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    // override
138f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    virtual uint32_t getFlags();
139f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    virtual bool setContext(const SkBitmap& device, const SkPaint& paint,
140f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger                            const SkMatrix& matrix);
141f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    virtual void shadeSpan(int x, int y, SkPMColor result[], int count);
142f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    virtual void shadeSpan16(int x, int y, uint16_t result[], int count);
143f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    virtual void beginSession();
144f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    virtual void endSession();
145f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
146f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerprotected:
147f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    SkFilterShader(SkFlattenableReadBuffer& );
148f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    virtual void flatten(SkFlattenableWriteBuffer& ) SK_OVERRIDE;
149f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    virtual Factory getFactory() SK_OVERRIDE { return CreateProc; }
150f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerprivate:
151f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) {
152f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        return SkNEW_ARGS(SkFilterShader, (buffer)); }
153f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    SkShader*       fShader;
154f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    SkColorFilter*  fFilter;
155f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
156f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    typedef SkShader INHERITED;
157f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger};
158f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
159f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger#endif
160