1 /*
2  * Copyright (c) 2021 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #ifndef BRUSH_H
17 #define BRUSH_H
18 
19 #include "draw/color.h"
20 #include "effect/color_space.h"
21 #include "effect/blender.h"
22 #include "effect/blur_draw_looper.h"
23 #include "effect/filter.h"
24 #include "effect/shader_effect.h"
25 #include "utils/drawing_macros.h"
26 #include "utils/rect.h"
27 
28 namespace OHOS {
29 namespace Rosen {
30 namespace Drawing {
31 class DRAWING_API Brush {
32 public:
33     Brush() noexcept;
34     Brush(const Brush& b) noexcept = default;
35     Brush(const Color& c) noexcept;
36     Brush(const std::shared_ptr<ShaderEffect> e) noexcept;
37     Brush(int rgba) noexcept;
38 
~Brush()39     ~Brush() {}
40 
41     /**
42      * @brief Retrieves alpha and RGB, unpremultiplied, packed into 32 bits.
43      * @return unpremultiplied ARGB.
44      */
45     const Color& GetColor() const;
46 
47     /**
48      * @brief Sets alpha and RGB used when stroking and filling. The color is a 32-bit value,
49      *        unpremultiplied, packing 8-bit components for alpha, red, blue, and green.
50      * @param color    unpremultiplied ARGB
51      */
52     void SetColor(const Color& c);
53 
54     /**
55      * @brief Sets alpha and RGB used when stroking and filling. The color is a 32-bit value,
56      *        unpremultiplied, packing 8-bit components for alpha, red, blue, and green.
57      * @param color    unpremultiplied ARGB
58      */
59     void SetColor(uint32_t c);
60 
61     /**
62      * @brief Sets color used when drawing solid fills. The color components range from 0 to 255.
63      *        The color is unpremultiplied; alpha sets the transparency independent of RGB.
64      * @param a    amount of alpha, from fully transparent (0) to fully opaque (255)
65      * @param r    amount of red, from no red (0) to full red (255)
66      * @param g    amount of green, from no green (0) to full green (255)
67      * @param b    amount of blue, from no blue (0) to full blue (255)
68      */
69     void SetARGB(int a, int r, int g, int b);
70 
71     /**
72      * @brief Retrieves alpha and RGB, unpremultiplied, as four floating point values. RGB are
73      *        extended sRGB values (sRGB gamut, and encoded with the sRGB transfer function).
74      * @return unpremultiplied RGBA
75      */
76     const Color4f& GetColor4f();
77 
78     /**
79      * @brief Retrieves a shared pointer to color space of current Brush.
80      * @return a shared pointer to color space of current Brush
81      */
GetColorSpace()82     const std::shared_ptr<ColorSpace> GetColorSpace() const { return colorSpace_; }
83 
84     /**
85      * @brief Retrieves a pointer to color space of current Brush.
86      * @return a pointer to color space of current Brush
87      */
GetColorSpacePtr()88     const ColorSpace* GetColorSpacePtr() const { return colorSpace_.get(); }
89 
90     /**
91      * @brief Sets alpha and RGB used when stroking and filling. The color is four floating
92      *        point values, unpremultiplied. The color values are interpreted as being in
93      *        the s. If s is nullptr, then color is assumed to be in the sRGB color space.
94      * @param color    unpremultiplied ARGB
95      * @param s        ColorSpace describing the encoding of color
96      */
97     void SetColor(const Color4f& cf, std::shared_ptr<ColorSpace> s);
98 
99     /**
100      * @brief Helper that scales the alpha by 255.
101      * @return alpha scaled 255
102      */
GetAlpha()103     inline uint32_t GetAlpha() const
104     {
105         return color_.GetAlpha();
106     }
107 
108     /**
109      * @brief Retrieves alpha from the color used when stroking and filling.
110      * @return alpha ranging from zero, fully transparent, to 255, fully opaque
111      */
GetAlphaF()112     inline scalar GetAlphaF() const
113     {
114         return color_.GetAlphaF();
115     }
116 
117     /**
118      * @brief Helper that accepts an int between 0 and 255, and divides it by 255.0.
119      * @param a    An int between 0 and 255
120      */
121     void SetAlpha(uint32_t a);
122 
123     /**
124      * @brief Replaces alpha, leaving RGB unchanged.
125      *        An out of range value triggers an assert in the debug build.
126      *        a is a value from 0.0 to 1.0. a set to zero makes color fully transparent; a set to
127      *        1.0 makes color fully opaque.
128      * @param a    alpha component of color
129      */
130     void SetAlphaF(scalar a);
131 
132     /**
133      * @brief Queries the blender.
134      * @return the blender represented as a BlendMode
135      */
GetBlendMode()136     const BlendMode& GetBlendMode() const { return blendMode_; }
137 
138     /**
139      * @brief Sets a blender that implements the specified blendmode enum.
140      * @param mode  the BlendMode used to set the blender
141      */
142     void SetBlendMode(const BlendMode& mode);
143 
144     /**
145      * @brief Sets Filter to filter.
146      * @param filter  Filter to apply to subsequent draw
147      */
148     void SetFilter(const Filter& filter);
149 
150     /**
151      * @brief Returns Filter if set, ot nullptr.
152      * @return Filter if previously set, nullptr otherwise
153      */
154     const Filter& GetFilter() const;
155 
156     /**
157      * @brief Queries the existance of filter.
158      * @return true if the Brush has a filter, otherwise false
159      */
HasFilter()160     bool HasFilter() const { return hasFilter_; }
161 
162     /**
163      * @brief Sets optional colors used when filling a path, such as a gradient.
164      * @param e  how geometry is filled with color
165      */
166     void SetShaderEffect(std::shared_ptr<ShaderEffect> e);
167 
168     /**
169      * @brief Returns optional colors used when filling a path, such as a gradient.
170      * @return ShaderEffect if previously set, nullptr otherwise
171      */
GetShaderEffect()172     const std::shared_ptr<ShaderEffect> GetShaderEffect() const { return shaderEffect_; }
173 
174     /**
175      * @brief Returns optional colors used when filling a path, such as a gradient.
176      * @return ShaderEffect if previously set, nullptr otherwise
177      */
GetShaderEffectPtr()178     const ShaderEffect* GetShaderEffectPtr() const { return shaderEffect_.get(); }
179 
180     /**
181      * @brief Sets the current blender, increasing its refcnt, and if a blender is already
182      *        present, decreasing that object's refcnt.
183      * @param blender  Blender used to set
184      */
185     void SetBlender(std::shared_ptr<Blender> blender);
186 
187     /**
188      * @brief Returns the user-supplied blend function, if one has been set.
189      * @return the Blender assigned to this Brush, otherwise nullptr
190      */
GetBlender()191     const std::shared_ptr<Blender> GetBlender() const { return blender_; }
192 
193     /**
194      * @brief Sets the blenderEnabled flag, which determines whether the blender is used.
195      * @param blenderEnabled  whether the blender is used.
196      */
197     void SetBlenderEnabled(bool blenderEnabled);
198 
199     /**
200      * @brief Returns the blenderEnabled flag, which determines whether the blender is used.
201      * @return the blenderEnabled flag, whether the blender is used.
202      */
GetBlenderEnabled()203     bool GetBlenderEnabled() const { return blenderEnabled_; };
204 
205     /**
206      * @brief Returns the user-supplied blend function, if one has been set.
207      * @return the Blender assigned to this Brush, otherwise nullptr
208      */
GetBlenderPtr()209     const Blender* GetBlenderPtr() const { return blender_.get(); }
210 
211     /**
212      * @brief Returns true if pixels on the active edges of Path may be drawn with partial transparency.
213      * @return antialiasing state
214      */
IsAntiAlias()215     bool IsAntiAlias() const { return antiAlias_; }
216 
217     /**
218      * @brief Requests, but does not require, that edge pixels draw opaque or with
219      *        partial transparency.
220      * @param aa setting for antialiasing
221      */
222     void SetAntiAlias(bool aa);
223 
224     /**
225      * @brief Returns true if Brush does not include elements requiring extensive computation
226      *        to compute bounds of drawn geometry. For instance, Brush with PathEffect
227      *        always returns false.
228      * @return true if Brush allows for fast computation of bounds
229      */
230     bool CanComputeFastBounds();
231 
232     /**
233      * @brief Only call this if CanComputeFastBounds() returned true. This takes a
234      *        raw rectangle (the raw bounds of a shape), and adjusts it for stylistic
235      *        effects in the Brush (e.g. stroking). If needed, it uses the storage
236      *        parameter. It returns the adjusted bounds that can then be used
237      *        for CoreCanvas::QuickReject tests.
238      *
239      *        The returned Rect will either be orig or storage, thus the caller
240      *        should not rely on storage being set to the result, but should always
241      *        use the returned value. It is legal for orig and storage to be the same Rect.
242      * @param orig     geometry modified by Brush when drawn
243      * @param storage  computed bounds of geometry; may not be nullptr
244      * @return         fast computed bounds
245      */
246     const Rect& ComputeFastBounds(const Rect& orig, Rect* storage);
247 
248     /**
249      * @brief Queries Whether the current blender can be represented as a BlendMode enum or not.
250      * @return true if can be represented, otherwise false
251      */
252     bool AsBlendMode();
253 
254     /**
255      * @brief Sets all Brush contents to their initial values. This is equivalent to replacing
256      *        Brush with the result of Brush().
257      */
258     void Reset();
259 
260     /**
261      * @brief Sets BlurDrawLooper, it will generate two draw operations, which may affect performance.
262      */
263     void SetLooper(std::shared_ptr<BlurDrawLooper> blurDrawLooper);
264 
265     /**
266      * @brief Gets BlurDrawLooper.
267      */
268     std::shared_ptr<BlurDrawLooper> GetLooper() const;
269 
270     friend DRAWING_API bool operator==(const Brush& b1, const Brush& b2);
271     friend DRAWING_API bool operator!=(const Brush& b1, const Brush& b2);
272 
273     void Dump(std::string& out) const;
274 
275 private:
276     Color color_;
277     BlendMode blendMode_;
278     Filter filter_;
279     std::shared_ptr<ColorSpace> colorSpace_;
280     std::shared_ptr<ShaderEffect> shaderEffect_;
281     std::shared_ptr<Blender> blender_;
282     std::shared_ptr<BlurDrawLooper> blurDrawLooper_;
283 
284     bool antiAlias_;
285     bool blenderEnabled_ = true;
286     bool hasFilter_ = false;
287 };
288 } // namespace Drawing
289 } // namespace Rosen
290 } // namespace OHOS
291 #endif