1/*
2 * Copyright (c) 2022 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 GRAPHIC_LITE_DRAW_CANVAS_H
17#define GRAPHIC_LITE_DRAW_CANVAS_H
18
19#include "common/image.h"
20#include "gfx_utils/diagram/common/paint.h"
21#include "gfx_utils/diagram/depiction/depict_dash.h"
22#include "gfx_utils/diagram/depiction/depict_stroke.h"
23#include "gfx_utils/diagram/rasterizer/rasterizer_scanline_antialias.h"
24#include "gfx_utils/diagram/spancolorfill/fill_gradient_lut.h"
25
26namespace OHOS {
27
28#if defined(ENABLE_CANVAS_EXTEND) && ENABLE_CANVAS_EXTEND
29struct ImageParam : public HeapBase {
30    Point start;
31    uint16_t height;
32    uint16_t width;
33    int16_t newWidth;
34    int16_t newHeight;
35    Image* image;
36};
37
38struct PathParam : public HeapBase {
39    UICanvasVertices* vertices;
40    ImageParam* imageParam = nullptr;
41    bool isStroke;
42};
43#endif
44
45class RenderBuffer;
46class RenderBase;
47class DrawCanvas : public HeapBase {
48public:
49#if defined(ENABLE_CANVAS_EXTEND) && ENABLE_CANVAS_EXTEND
50    static void DoRender(BufferInfo& gfxDstBuffer,
51                         void* param,
52                         const Paint& paint,
53                         const Rect& rect,
54                         const Rect& invalidatedArea,
55                         const Style& style,
56                         const bool& isStroke);
57
58#if defined(GRAPHIC_ENABLE_SHADOW_EFFECT_FLAG) && GRAPHIC_ENABLE_SHADOW_EFFECT_FLAG
59    static void DoDrawShadow(BufferInfo& gfxDstBuffer,
60                             void* param,
61                             const Paint& paint,
62                             const Rect& rect,
63                             const Rect& invalidatedArea,
64                             const Style& style,
65                             const bool& isStroke);
66#endif
67#endif
68    static void InitRenderAndTransform(BufferInfo& gfxDstBuffer,
69                                       RenderBuffer& renderBuffer,
70                                       const Rect& rect,
71                                       TransAffine& transform,
72                                       const Style& style,
73                                       const Paint& paint);
74
75    static void SetRasterizer(UICanvasVertices& vertices,
76                              const Paint& paint,
77                              RasterizerScanlineAntialias& rasterizer,
78                              TransAffine& transform,
79                              const bool& isStroke);
80
81#if defined(GRAPHIC_ENABLE_GRADIENT_FILL_FLAG) && GRAPHIC_ENABLE_GRADIENT_FILL_FLAG
82    /**
83     * Render gradient
84     */
85    static void RenderGradient(const Paint& paint,
86                               RasterizerScanlineAntialias& rasterizer,
87                               TransAffine& transform,
88                               RenderBase& renBase,
89                               RenderBuffer& renderBuffer,
90                               FillBase& allocator,
91                               const Rect& invalidatedArea);
92
93    static void BuildGradientColor(const Paint& paint, FillGradientLut& gradientColorMode);
94
95    static void BuildLineGradientMatrix(const Paint& paint,
96                                        TransAffine& gradientMatrix,
97                                        TransAffine& transform,
98                                        float& distance)
99    {
100        Paint::LinearGradientPoint linearPoint = paint.GetLinearGradientPoint();
101        float angle = FastAtan2F(linearPoint.y1 - linearPoint.y0, linearPoint.x1 - linearPoint.x0);
102        gradientMatrix.Reset();
103        gradientMatrix *= TransAffine::TransAffineRotation(angle);
104        gradientMatrix *= TransAffine::TransAffineTranslation(linearPoint.x0, linearPoint.y0);
105        gradientMatrix *= transform;
106        gradientMatrix.Invert();
107        distance = Sqrt((linearPoint.x1 - linearPoint.x0) * (linearPoint.x1 - linearPoint.x0) +
108                        (linearPoint.y1 - linearPoint.y0) * (linearPoint.y1 - linearPoint.y0));
109    }
110
111    static void BuildRadialGradientMatrix(const Paint& paint,
112                                          TransAffine& gradientMatrix,
113                                          TransAffine& transform,
114                                          float& startRadius,
115                                          float& endRadius);
116#endif // GRAPHIC_ENABLE_GRADIENT_FILL_FLAG
117
118#if defined(GRAPHIC_ENABLE_PATTERN_FILL_FLAG) && GRAPHIC_ENABLE_PATTERN_FILL_FLAG
119#if defined(ENABLE_CANVAS_EXTEND) && ENABLE_CANVAS_EXTEND
120    /**
121     * Render pattern mode
122     */
123    static void RenderPattern(const Paint& paint,
124                              void* param,
125                              RasterizerScanlineAntialias& rasterizer,
126                              RenderBase& renBase,
127                              FillBase& allocator,
128                              const Rect& rect);
129#endif
130#endif // GRAPHIC_ENABLE_PATTERN_FILL_FLAG
131
132    static void ChangeColor(Rgba8T& color, ColorType colorType, uint8_t alpha)
133    {
134        color.red = colorType.red;
135        color.green = colorType.green;
136        color.blue = colorType.blue;
137        color.alpha = alpha;
138    }
139
140    static void RenderBlendSolid(const Paint& paint, Rgba8T& color, const bool& isStroke)
141    {
142        if (isStroke) {
143            if (paint.GetStyle() == Paint::STROKE_STYLE || paint.GetStyle() == Paint::STROKE_FILL_STYLE) {
144                ChangeColor(color, paint.GetStrokeColor(),
145                            static_cast<uint8_t>(paint.GetStrokeColor().alpha * paint.GetGlobalAlpha()));
146            }
147        } else {
148            if (paint.GetStyle() == Paint::FILL_STYLE || paint.GetStyle() == Paint::STROKE_FILL_STYLE) {
149                ChangeColor(color, paint.GetFillColor(),
150                            static_cast<uint8_t>(paint.GetFillColor().alpha * paint.GetGlobalAlpha()));
151            }
152        }
153    }
154
155    /**
156     * Assembly parameter setting lineweight,LineCap,LineJoin
157     */
158    template <class LineStyle> static void LineStyleCalc(DepictStroke<LineStyle>& strokeLineStyle, const Paint& paint)
159    {
160        strokeLineStyle.SetWidth(paint.GetStrokeWidth()); // Line style related
161#if defined(GRAPHIC_ENABLE_LINECAP_FLAG) && GRAPHIC_ENABLE_LINECAP_FLAG
162        strokeLineStyle.SetLineCap(paint.GetLineCap());
163#endif
164#if defined(GRAPHIC_ENABLE_LINEJOIN_FLAG) && GRAPHIC_ENABLE_LINEJOIN_FLAG
165        strokeLineStyle.SetLineJoin(paint.GetLineJoin());
166        if (paint.GetMiterLimit() > 0) {
167            strokeLineStyle.SetMiterLimit(paint.GetMiterLimit());
168        }
169#endif
170    };
171
172#if defined(GRAPHIC_ENABLE_DASH_GENERATE_FLAG) && GRAPHIC_ENABLE_DASH_GENERATE_FLAG
173    /**
174     * Set linedash style
175     */
176    static void LineDashStyleCalc(DepictDash& dashStyle, const Paint& paint)
177    {
178        for (uint32_t i = 0; i < paint.GetLineDashCount(); i += TWO_STEP) {
179            dashStyle.AddDash(paint.GetLineDash()[i], paint.GetLineDash()[i + 1]);
180        }
181        dashStyle.DashStart(paint.GetLineDashOffset());
182    };
183#endif
184};
185} // namespace OHOS
186#endif // GRAPHIC_LITE_DRAW_CANVAS_H
187