blob: 2a886bc8ebb7e4673778688c4cc9b1e63e26112a [file] [log] [blame]
epoger@google.comec3ed6a2011-07-28 14:26:00 +00001
reed@android.com8a1c16f2008-12-17 15:59:43 +00002/*
epoger@google.comec3ed6a2011-07-28 14:26:00 +00003 * Copyright 2006 The Android Open Source Project
reed@android.com8a1c16f2008-12-17 15:59:43 +00004 *
epoger@google.comec3ed6a2011-07-28 14:26:00 +00005 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
reed@android.com8a1c16f2008-12-17 15:59:43 +00007 */
8
epoger@google.comec3ed6a2011-07-28 14:26:00 +00009
reed@android.com8a1c16f2008-12-17 15:59:43 +000010#ifndef SkColorFilter_DEFINED
11#define SkColorFilter_DEFINED
12
13#include "SkColor.h"
14#include "SkFlattenable.h"
reed@android.com845fdac2009-06-23 03:01:32 +000015#include "SkXfermode.h"
reed@android.com8a1c16f2008-12-17 15:59:43 +000016
bsalomon@google.com8c3ff172011-04-15 15:42:24 +000017class SK_API SkColorFilter : public SkFlattenable {
reed@android.com8a1c16f2008-12-17 15:59:43 +000018public:
reed@google.com43c50c82011-04-14 15:50:52 +000019 /**
20 * If the filter can be represented by a source color plus Mode, this
21 * returns true, and sets (if not NULL) the color and mode appropriately.
22 * If not, this returns false and ignores the parameters.
23 */
24 virtual bool asColorMode(SkColor* color, SkXfermode::Mode* mode);
25
senorblanco@chromium.orge5ff3ce2011-12-20 20:58:18 +000026 /**
27 * If the filter can be represented by a 5x4 matrix, this
28 * returns true, and sets the matrix appropriately.
29 * If not, this returns false and ignores the parameter.
30 */
31 virtual bool asColorMatrix(SkScalar matrix[20]);
32
reed@google.com71918402012-01-05 17:24:35 +000033 /**
34 * If the filter can be represented by per-component table, return true,
35 * and if table is not null, copy the bitmap containing the table into it.
36 *
37 * The table bitmap will be in SkBitmap::kA8_Config. Each row corresponding
38 * to each component in ARGB order. e.g. row[0] == alpha, row[1] == red,
39 * etc. To transform a color, you (logically) perform the following:
40 *
41 * a' = *table.getAddr8(a, 0);
42 * r' = *table.getAddr8(r, 1);
43 * g' = *table.getAddr8(g, 2);
44 * b' = *table.getAddr8(b, 3);
45 *
46 * The original component value is the horizontal index for a given row,
47 * and the stored value at that index is the new value for that component.
48 */
49 virtual bool asComponentTable(SkBitmap* table);
50
reed@android.com8a1c16f2008-12-17 15:59:43 +000051 /** Called with a scanline of colors, as if there was a shader installed.
52 The implementation writes out its filtered version into result[].
53 Note: shader and result may be the same buffer.
54 @param src array of colors, possibly generated by a shader
55 @param count the number of entries in the src[] and result[] arrays
56 @param result written by the filter
57 */
58 virtual void filterSpan(const SkPMColor src[], int count,
59 SkPMColor result[]) = 0;
60 /** Called with a scanline of colors, as if there was a shader installed.
61 The implementation writes out its filtered version into result[].
62 Note: shader and result may be the same buffer.
63 @param src array of colors, possibly generated by a shader
64 @param count the number of entries in the src[] and result[] arrays
65 @param result written by the filter
66 */
67 virtual void filterSpan16(const uint16_t shader[], int count,
68 uint16_t result[]);
69
70 enum Flags {
71 /** If set the filter methods will not change the alpha channel of the
72 colors.
73 */
74 kAlphaUnchanged_Flag = 0x01,
75 /** If set, this subclass implements filterSpan16(). If this flag is
76 set, then kAlphaUnchanged_Flag must also be set.
77 */
78 kHasFilter16_Flag = 0x02
79 };
80
81 /** Returns the flags for this filter. Override in subclasses to return
82 custom flags.
83 */
84 virtual uint32_t getFlags() { return 0; }
85
reed@google.com6b7aee32011-04-19 18:36:09 +000086 /**
87 * Apply this colorfilter to the specified SkColor. This routine handles
88 * converting to SkPMColor, calling the filter, and then converting back
89 * to SkColor. This method is not virtual, but will call filterSpan()
90 * which is virtual.
91 */
92 SkColor filterColor(SkColor);
tomhudson@google.com1447c6f2011-04-27 14:09:52 +000093
94
reed@android.com845fdac2009-06-23 03:01:32 +000095 /** Create a colorfilter that uses the specified color and mode.
96 If the Mode is DST, this function will return NULL (since that
reed@android.com8a1c16f2008-12-17 15:59:43 +000097 mode will have no effect on the result).
reed@android.com845fdac2009-06-23 03:01:32 +000098 @param c The source color used with the specified mode
99 @param mode The xfermode mode that is applied to each color in
reed@android.com8a1c16f2008-12-17 15:59:43 +0000100 the colorfilter's filterSpan[16,32] methods
reed@android.com845fdac2009-06-23 03:01:32 +0000101 @return colorfilter object that applies the src color and mode,
102 or NULL if the mode will have no effect.
reed@android.com8a1c16f2008-12-17 15:59:43 +0000103 */
reed@android.com845fdac2009-06-23 03:01:32 +0000104 static SkColorFilter* CreateModeFilter(SkColor c, SkXfermode::Mode mode);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000105
106 /** Create a colorfilter that calls through to the specified procs to
107 filter the colors. The SkXfermodeProc parameter must be non-null, but
108 the SkXfermodeProc16 is optional, and may be null.
109 */
reed@android.com845fdac2009-06-23 03:01:32 +0000110 static SkColorFilter* CreateProcFilter(SkColor srcColor,
111 SkXfermodeProc proc,
112 SkXfermodeProc16 proc16 = NULL);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000113
114 /** Create a colorfilter that multiplies the RGB channels by one color, and
115 then adds a second color, pinning the result for each component to
116 [0..255]. The alpha components of the mul and add arguments
117 are ignored.
118 */
119 static SkColorFilter* CreateLightingFilter(SkColor mul, SkColor add);
caryclark@google.comd26147a2011-12-15 14:16:43 +0000120
djsollen@google.coma2ca41e2012-03-23 19:00:34 +0000121 SK_DECLARE_FLATTENABLE_REGISTRAR_GROUP()
reed@android.com8a1c16f2008-12-17 15:59:43 +0000122protected:
123 SkColorFilter() {}
124 SkColorFilter(SkFlattenableReadBuffer& rb) : INHERITED(rb) {}
tomhudson@google.com1447c6f2011-04-27 14:09:52 +0000125
reed@android.com8a1c16f2008-12-17 15:59:43 +0000126private:
127 typedef SkFlattenable INHERITED;
128};
129
130#include "SkShader.h"
131
132class SkFilterShader : public SkShader {
133public:
134 SkFilterShader(SkShader* shader, SkColorFilter* filter);
135 virtual ~SkFilterShader();
136
137 // override
138 virtual uint32_t getFlags();
139 virtual bool setContext(const SkBitmap& device, const SkPaint& paint,
140 const SkMatrix& matrix);
141 virtual void shadeSpan(int x, int y, SkPMColor result[], int count);
142 virtual void shadeSpan16(int x, int y, uint16_t result[], int count);
143 virtual void beginSession();
144 virtual void endSession();
tomhudson@google.com1447c6f2011-04-27 14:09:52 +0000145
djsollen@google.comba28d032012-03-26 17:57:35 +0000146 SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkFilterShader)
147
reed@android.com8a1c16f2008-12-17 15:59:43 +0000148protected:
149 SkFilterShader(SkFlattenableReadBuffer& );
tomhudson@google.com13413042011-10-03 16:01:10 +0000150 virtual void flatten(SkFlattenableWriteBuffer& ) SK_OVERRIDE;
djsollen@google.comba28d032012-03-26 17:57:35 +0000151
reed@android.com8a1c16f2008-12-17 15:59:43 +0000152private:
reed@android.com8a1c16f2008-12-17 15:59:43 +0000153 SkShader* fShader;
154 SkColorFilter* fFilter;
tomhudson@google.com1447c6f2011-04-27 14:09:52 +0000155
reed@android.com8a1c16f2008-12-17 15:59:43 +0000156 typedef SkShader INHERITED;
157};
158
159#endif