Line data Source code
1 : /*
2 : * Copyright 2006 The Android Open Source Project
3 : *
4 : * Use of this source code is governed by a BSD-style license that can be
5 : * found in the LICENSE file.
6 : */
7 :
8 : #ifndef SkColorFilter_DEFINED
9 : #define SkColorFilter_DEFINED
10 :
11 : #include "SkBlendMode.h"
12 : #include "SkColor.h"
13 : #include "SkFlattenable.h"
14 : #include "SkRefCnt.h"
15 :
16 : class GrContext;
17 : class GrFragmentProcessor;
18 : class SkArenaAlloc;
19 : class SkBitmap;
20 : class SkColorSpace;
21 : class SkRasterPipeline;
22 :
23 : /**
24 : * ColorFilters are optional objects in the drawing pipeline. When present in
25 : * a paint, they are called with the "src" colors, and return new colors, which
26 : * are then passed onto the next stage (either ImageFilter or Xfermode).
27 : *
28 : * All subclasses are required to be reentrant-safe : it must be legal to share
29 : * the same instance between several threads.
30 : */
31 0 : class SK_API SkColorFilter : public SkFlattenable {
32 : public:
33 : /**
34 : * If the filter can be represented by a source color plus Mode, this
35 : * returns true, and sets (if not NULL) the color and mode appropriately.
36 : * If not, this returns false and ignores the parameters.
37 : */
38 : virtual bool asColorMode(SkColor* color, SkBlendMode* bmode) const;
39 :
40 : /**
41 : * If the filter can be represented by a 5x4 matrix, this
42 : * returns true, and sets the matrix appropriately.
43 : * If not, this returns false and ignores the parameter.
44 : */
45 : virtual bool asColorMatrix(SkScalar matrix[20]) const;
46 :
47 : /**
48 : * If the filter can be represented by per-component table, return true,
49 : * and if table is not null, copy the bitmap containing the table into it.
50 : *
51 : * The table bitmap will be in SkBitmap::kA8_Config. Each row corresponding
52 : * to each component in ARGB order. e.g. row[0] == alpha, row[1] == red,
53 : * etc. To transform a color, you (logically) perform the following:
54 : *
55 : * a' = *table.getAddr8(a, 0);
56 : * r' = *table.getAddr8(r, 1);
57 : * g' = *table.getAddr8(g, 2);
58 : * b' = *table.getAddr8(b, 3);
59 : *
60 : * The original component value is the horizontal index for a given row,
61 : * and the stored value at that index is the new value for that component.
62 : */
63 : virtual bool asComponentTable(SkBitmap* table) const;
64 :
65 : /** Called with a scanline of colors, as if there was a shader installed.
66 : The implementation writes out its filtered version into result[].
67 : Note: shader and result may be the same buffer.
68 : @param src array of colors, possibly generated by a shader
69 : @param count the number of entries in the src[] and result[] arrays
70 : @param result written by the filter
71 : */
72 : virtual void filterSpan(const SkPMColor src[], int count, SkPMColor result[]) const = 0;
73 :
74 : virtual void filterSpan4f(const SkPM4f src[], int count, SkPM4f result[]) const;
75 :
76 : bool appendStages(SkRasterPipeline*, SkColorSpace*, SkArenaAlloc*,
77 : bool shaderIsOpaque) const;
78 :
79 : enum Flags {
80 : /** If set the filter methods will not change the alpha channel of the colors.
81 : */
82 : kAlphaUnchanged_Flag = 1 << 0,
83 : };
84 :
85 : /** Returns the flags for this filter. Override in subclasses to return custom flags.
86 : */
87 0 : virtual uint32_t getFlags() const { return 0; }
88 :
89 : /**
90 : * If this subclass can optimally createa composition with the inner filter, return it as
91 : * a new filter (which the caller must unref() when it is done). If no such optimization
92 : * is known, return NULL.
93 : *
94 : * e.g. result(color) == this_filter(inner(color))
95 : */
96 0 : virtual sk_sp<SkColorFilter> makeComposed(sk_sp<SkColorFilter>) const { return nullptr; }
97 :
98 : /**
99 : * Apply this colorfilter to the specified SkColor. This routine handles
100 : * converting to SkPMColor, calling the filter, and then converting back
101 : * to SkColor. This method is not virtual, but will call filterSpan()
102 : * which is virtual.
103 : */
104 : SkColor filterColor(SkColor) const;
105 :
106 : /**
107 : * Filters a single color.
108 : */
109 : SkColor4f filterColor4f(const SkColor4f&) const;
110 :
111 : /** Create a colorfilter that uses the specified color and mode.
112 : If the Mode is DST, this function will return NULL (since that
113 : mode will have no effect on the result).
114 : @param c The source color used with the specified mode
115 : @param mode The blend that is applied to each color in
116 : the colorfilter's filterSpan[16,32] methods
117 : @return colorfilter object that applies the src color and mode,
118 : or NULL if the mode will have no effect.
119 : */
120 : static sk_sp<SkColorFilter> MakeModeFilter(SkColor c, SkBlendMode mode);
121 :
122 : /** Construct a colorfilter whose effect is to first apply the inner filter and then apply
123 : * the outer filter to the result of the inner's.
124 : * The reference counts for outer and inner are incremented.
125 : *
126 : * Due to internal limits, it is possible that this will return NULL, so the caller must
127 : * always check.
128 : */
129 : static sk_sp<SkColorFilter> MakeComposeFilter(sk_sp<SkColorFilter> outer,
130 : sk_sp<SkColorFilter> inner);
131 :
132 : /** Construct a color filter that transforms a color by a 4x5 matrix. The matrix is in row-
133 : * major order and the translation column is specified in unnormalized, 0...255, space.
134 : */
135 : static sk_sp<SkColorFilter> MakeMatrixFilterRowMajor255(const SkScalar array[20]);
136 :
137 : #if SK_SUPPORT_GPU
138 : /**
139 : * A subclass may implement this factory function to work with the GPU backend. It returns
140 : * a GrFragmentProcessor that implemets the color filter in GPU shader code.
141 : *
142 : * The fragment processor receives a premultiplied input color and produces a premultiplied
143 : * output color.
144 : *
145 : * A null return indicates that the color filter isn't implemented for the GPU backend.
146 : */
147 : virtual sk_sp<GrFragmentProcessor> asFragmentProcessor(GrContext*,
148 : SkColorSpace* dstColorSpace) const;
149 : #endif
150 :
151 0 : bool affectsTransparentBlack() const {
152 0 : return this->filterColor(0) != 0;
153 : }
154 :
155 : SK_TO_STRING_PUREVIRT()
156 :
157 : SK_DECLARE_FLATTENABLE_REGISTRAR_GROUP()
158 0 : SK_DEFINE_FLATTENABLE_TYPE(SkColorFilter)
159 :
160 : protected:
161 0 : SkColorFilter() {}
162 :
163 : virtual bool onAppendStages(SkRasterPipeline*, SkColorSpace*, SkArenaAlloc*,
164 : bool shaderIsOpaque) const;
165 :
166 : private:
167 : /*
168 : * Returns 1 if this is a single filter (not a composition of other filters), otherwise it
169 : * reutrns the number of leaf-node filters in a composition. This should be the same value
170 : * as the number of GrFragmentProcessors returned by asFragmentProcessors's array parameter.
171 : *
172 : * e.g. compose(filter, compose(compose(filter, filter), filter)) --> 4
173 : */
174 0 : virtual int privateComposedFilterCount() const { return 1; }
175 : friend class SkComposeColorFilter;
176 :
177 : typedef SkFlattenable INHERITED;
178 : };
179 :
180 : #endif
|