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 "include/core/SkBlendMode.h"
12 #include "include/core/SkColor.h"
13 #include "include/core/SkFlattenable.h"
14 #include "include/core/SkRefCnt.h"
15 
16 class GrColorInfo;
17 class GrFragmentProcessor;
18 class GrRecordingContext;
19 class SkBitmap;
20 class SkColorMatrix;
21 class SkColorSpace;
22 struct SkStageRec;
23 class SkString;
24 
25 /**
26  *  ColorFilters are optional objects in the drawing pipeline. When present in
27  *  a paint, they are called with the "src" colors, and return new colors, which
28  *  are then passed onto the next stage (either ImageFilter or Xfermode).
29  *
30  *  All subclasses are required to be reentrant-safe : it must be legal to share
31  *  the same instance between several threads.
32  */
33 class SK_API SkColorFilter : public SkFlattenable {
34 public:
35     // DEPRECATED. skbug.com/8941
36 
asColorMode(SkColor * color,SkBlendMode * mode)37     bool asColorMode(SkColor* color, SkBlendMode* mode) const {
38         return this->onAsAColorMode(color, mode);
39     }
40 
41     /** If the filter can be represented by a source color plus Mode, this
42      *  returns true, and sets (if not NULL) the color and mode appropriately.
43      *  If not, this returns false and ignores the parameters.
44      */
asAColorMode(SkColor * color,SkBlendMode * mode)45     bool asAColorMode(SkColor* color, SkBlendMode* mode) const {
46         return this->onAsAColorMode(color, mode);
47     }
48 
49     /** If the filter can be represented by a 5x4 matrix, this
50      *  returns true, and sets the matrix appropriately.
51      *  If not, this returns false and ignores the parameter.
52      */
asAColorMatrix(float matrix[20])53     bool asAColorMatrix(float matrix[20]) const {
54         return this->onAsAColorMatrix(matrix);
55     }
56 
57     bool appendStages(const SkStageRec& rec, bool shaderIsOpaque) const;
58 
59     enum Flags {
60         /** If set the filter methods will not change the alpha channel of the colors.
61         */
62         kAlphaUnchanged_Flag = 1 << 0,
63     };
64 
65     /** Returns the flags for this filter. Override in subclasses to return custom flags.
66     */
getFlags()67     virtual uint32_t getFlags() const { return 0; }
68 
69     SkColor filterColor(SkColor) const;
70 
71     /**
72      * Converts the src color (in src colorspace), into the dst colorspace,
73      * then applies this filter to it, returning the filtered color in the dst colorspace.
74      */
75     SkColor4f filterColor4f(const SkColor4f& srcColor, SkColorSpace* srcCS,
76                             SkColorSpace* dstCS) const;
77 
78     /** Construct a colorfilter whose effect is to first apply the inner filter and then apply
79      *  this filter, applied to the output of the inner filter.
80      *
81      *  result = this(inner(...))
82      *
83      *  Due to internal limits, it is possible that this will return NULL, so the caller must
84      *  always check.
85      */
86     sk_sp<SkColorFilter> makeComposed(sk_sp<SkColorFilter> inner) const;
87 
88 #if SK_SUPPORT_GPU
89     /**
90      *  A subclass may implement this factory function to work with the GPU backend. It returns
91      *  a GrFragmentProcessor that implemets the color filter in GPU shader code.
92      *
93      *  The fragment processor receives a premultiplied input color and produces a premultiplied
94      *  output color.
95      *
96      *  A null return indicates that the color filter isn't implemented for the GPU backend.
97      */
98     virtual std::unique_ptr<GrFragmentProcessor> asFragmentProcessor(
99             GrRecordingContext*, const GrColorInfo& dstColorInfo) const;
100 #endif
101 
affectsTransparentBlack()102     bool affectsTransparentBlack() const {
103         return this->filterColor(SK_ColorTRANSPARENT) != SK_ColorTRANSPARENT;
104     }
105 
106     static void RegisterFlattenables();
107 
GetFlattenableType()108     static SkFlattenable::Type GetFlattenableType() {
109         return kSkColorFilter_Type;
110     }
111 
getFlattenableType()112     SkFlattenable::Type getFlattenableType() const override {
113         return kSkColorFilter_Type;
114     }
115 
116     static sk_sp<SkColorFilter> Deserialize(const void* data, size_t size,
117                                           const SkDeserialProcs* procs = nullptr) {
118         return sk_sp<SkColorFilter>(static_cast<SkColorFilter*>(
119                                   SkFlattenable::Deserialize(
120                                   kSkColorFilter_Type, data, size, procs).release()));
121     }
122 
123 protected:
SkColorFilter()124     SkColorFilter() {}
125 
126     virtual bool onAsAColorMatrix(float[20]) const;
127     virtual bool onAsAColorMode(SkColor* color, SkBlendMode* bmode) const;
128 
129 private:
130     /*
131      *  Returns 1 if this is a single filter (not a composition of other filters), otherwise it
132      *  reutrns the number of leaf-node filters in a composition. This should be the same value
133      *  as the number of GrFragmentProcessors returned by asFragmentProcessors's array parameter.
134      *
135      *  e.g. compose(filter, compose(compose(filter, filter), filter)) --> 4
136      */
privateComposedFilterCount()137     virtual int privateComposedFilterCount() const { return 1; }
138 
139     virtual bool onAppendStages(const SkStageRec& rec, bool shaderIsOpaque) const = 0;
140 
141     friend class SkComposeColorFilter;
142 
143     typedef SkFlattenable INHERITED;
144 };
145 
146 class SK_API SkColorFilters {
147 public:
Compose(sk_sp<SkColorFilter> outer,sk_sp<SkColorFilter> inner)148     static sk_sp<SkColorFilter> Compose(sk_sp<SkColorFilter> outer, sk_sp<SkColorFilter> inner) {
149         return outer ? outer->makeComposed(inner) : inner;
150     }
151     static sk_sp<SkColorFilter> Blend(SkColor c, SkBlendMode mode);
152     static sk_sp<SkColorFilter> Matrix(const SkColorMatrix&);
153     static sk_sp<SkColorFilter> Matrix(const float rowMajor[20]);
154 
155     // A version of Matrix which operates in HSLA space instead of RGBA.
156     // I.e. HSLA-to-RGBA(Matrix(RGBA-to-HSLA(input))).
157     static sk_sp<SkColorFilter> HSLAMatrix(const float rowMajor[20]);
158 
159     static sk_sp<SkColorFilter> LinearToSRGBGamma();
160     static sk_sp<SkColorFilter> SRGBToLinearGamma();
161     static sk_sp<SkColorFilter> Lerp(float t, sk_sp<SkColorFilter> dst, sk_sp<SkColorFilter> src);
162 
163 private:
164     SkColorFilters() = delete;
165 };
166 
167 #endif
168