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/SkColor.h" |
12 | #include "include/core/SkFlattenable.h" |
13 | #include "include/core/SkRefCnt.h" |
14 | #include "include/private/base/SkAPI.h" |
15 | |
16 | #include <cstddef> |
17 | #include <cstdint> |
18 | |
19 | class SkColorMatrix; |
20 | class SkColorSpace; |
21 | class SkColorTable; |
22 | |
23 | enum class SkBlendMode; |
24 | struct SkDeserialProcs; |
25 | |
26 | /** |
27 | * ColorFilters are optional objects in the drawing pipeline. When present in |
28 | * a paint, they are called with the "src" colors, and return new colors, which |
29 | * are then passed onto the next stage (either ImageFilter or Xfermode). |
30 | * |
31 | * All subclasses are required to be reentrant-safe : it must be legal to share |
32 | * the same instance between several threads. |
33 | */ |
34 | class SK_API SkColorFilter : public SkFlattenable { |
35 | public: |
36 | /** If the filter can be represented by a source color plus Mode, this |
37 | * returns true, and sets (if not NULL) the color and mode appropriately. |
38 | * If not, this returns false and ignores the parameters. |
39 | */ |
40 | bool asAColorMode(SkColor* color, SkBlendMode* mode) const; |
41 | |
42 | /** If the filter can be represented by a 5x4 matrix, this |
43 | * returns true, and sets the matrix appropriately. |
44 | * If not, this returns false and ignores the parameter. |
45 | */ |
46 | bool asAColorMatrix(float matrix[20]) const; |
47 | |
48 | // Returns true if the filter is guaranteed to never change the alpha of a color it filters. |
49 | bool isAlphaUnchanged() const; |
50 | |
51 | SkColor filterColor(SkColor) const; |
52 | |
53 | /** |
54 | * Converts the src color (in src colorspace), into the dst colorspace, |
55 | * then applies this filter to it, returning the filtered color in the dst colorspace. |
56 | */ |
57 | SkColor4f filterColor4f(const SkColor4f& srcColor, SkColorSpace* srcCS, |
58 | SkColorSpace* dstCS) const; |
59 | |
60 | /** Construct a colorfilter whose effect is to first apply the inner filter and then apply |
61 | * this filter, applied to the output of the inner filter. |
62 | * |
63 | * result = this(inner(...)) |
64 | */ |
65 | sk_sp<SkColorFilter> makeComposed(sk_sp<SkColorFilter> inner) const; |
66 | |
67 | static sk_sp<SkColorFilter> Deserialize(const void* data, size_t size, |
68 | const SkDeserialProcs* procs = nullptr); |
69 | |
70 | private: |
71 | SkColorFilter() = default; |
72 | friend class SkColorFilterBase; |
73 | |
74 | using INHERITED = SkFlattenable; |
75 | }; |
76 | |
77 | class SK_API SkColorFilters { |
78 | public: |
79 | static sk_sp<SkColorFilter> Compose(sk_sp<SkColorFilter> outer, sk_sp<SkColorFilter> inner) { |
80 | return outer ? outer->makeComposed(inner) : inner; |
81 | } |
82 | |
83 | // Blends between the constant color (src) and input color (dst) based on the SkBlendMode. |
84 | // If the color space is null, the constant color is assumed to be defined in sRGB. |
85 | static sk_sp<SkColorFilter> Blend(const SkColor4f& c, sk_sp<SkColorSpace>, SkBlendMode mode); |
86 | static sk_sp<SkColorFilter> Blend(SkColor c, SkBlendMode mode); |
87 | |
88 | static sk_sp<SkColorFilter> Matrix(const SkColorMatrix&); |
89 | static sk_sp<SkColorFilter> Matrix(const float rowMajor[20]); |
90 | |
91 | // A version of Matrix which operates in HSLA space instead of RGBA. |
92 | // I.e. HSLA-to-RGBA(Matrix(RGBA-to-HSLA(input))). |
93 | static sk_sp<SkColorFilter> HSLAMatrix(const SkColorMatrix&); |
94 | static sk_sp<SkColorFilter> HSLAMatrix(const float rowMajor[20]); |
95 | |
96 | static sk_sp<SkColorFilter> LinearToSRGBGamma(); |
97 | static sk_sp<SkColorFilter> SRGBToLinearGamma(); |
98 | static sk_sp<SkColorFilter> Lerp(float t, sk_sp<SkColorFilter> dst, sk_sp<SkColorFilter> src); |
99 | |
100 | /** |
101 | * Create a table colorfilter, copying the table into the filter, and |
102 | * applying it to all 4 components. |
103 | * a' = table[a]; |
104 | * r' = table[r]; |
105 | * g' = table[g]; |
106 | * b' = table[b]; |
107 | * Components are operated on in unpremultiplied space. If the incomming |
108 | * colors are premultiplied, they are temporarily unpremultiplied, then |
109 | * the table is applied, and then the result is remultiplied. |
110 | */ |
111 | static sk_sp<SkColorFilter> Table(const uint8_t table[256]); |
112 | |
113 | /** |
114 | * Create a table colorfilter, with a different table for each |
115 | * component [A, R, G, B]. If a given table is NULL, then it is |
116 | * treated as identity, with the component left unchanged. If a table |
117 | * is not null, then its contents are copied into the filter. |
118 | */ |
119 | static sk_sp<SkColorFilter> TableARGB(const uint8_t tableA[256], |
120 | const uint8_t tableR[256], |
121 | const uint8_t tableG[256], |
122 | const uint8_t tableB[256]); |
123 | |
124 | /** |
125 | * Create a table colorfilter that holds a ref to the shared color table. |
126 | */ |
127 | static sk_sp<SkColorFilter> Table(sk_sp<SkColorTable> table); |
128 | |
129 | /** |
130 | * Create a colorfilter that multiplies the RGB channels by one color, and |
131 | * then adds a second color, pinning the result for each component to |
132 | * [0..255]. The alpha components of the mul and add arguments |
133 | * are ignored. |
134 | */ |
135 | static sk_sp<SkColorFilter> Lighting(SkColor mul, SkColor add); |
136 | |
137 | private: |
138 | SkColorFilters() = delete; |
139 | }; |
140 | |
141 | #endif |
142 | |