1a3e0fd82Sopenharmony_ci/*
2a3e0fd82Sopenharmony_ci * Copyright (c) 2022 Huawei Device Co., Ltd.
3a3e0fd82Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4a3e0fd82Sopenharmony_ci * you may not use this file except in compliance with the License.
5a3e0fd82Sopenharmony_ci * You may obtain a copy of the License at
6a3e0fd82Sopenharmony_ci *
7a3e0fd82Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8a3e0fd82Sopenharmony_ci *
9a3e0fd82Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10a3e0fd82Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11a3e0fd82Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12a3e0fd82Sopenharmony_ci * See the License for the specific language governing permissions and
13a3e0fd82Sopenharmony_ci * limitations under the License.
14a3e0fd82Sopenharmony_ci */
15a3e0fd82Sopenharmony_ci
16a3e0fd82Sopenharmony_ci#ifndef GRAPHIC_LITE_DRAW_CANVAS_H
17a3e0fd82Sopenharmony_ci#define GRAPHIC_LITE_DRAW_CANVAS_H
18a3e0fd82Sopenharmony_ci
19a3e0fd82Sopenharmony_ci#include "common/image.h"
20a3e0fd82Sopenharmony_ci#include "gfx_utils/diagram/common/paint.h"
21a3e0fd82Sopenharmony_ci#include "gfx_utils/diagram/depiction/depict_dash.h"
22a3e0fd82Sopenharmony_ci#include "gfx_utils/diagram/depiction/depict_stroke.h"
23a3e0fd82Sopenharmony_ci#include "gfx_utils/diagram/rasterizer/rasterizer_scanline_antialias.h"
24a3e0fd82Sopenharmony_ci#include "gfx_utils/diagram/spancolorfill/fill_gradient_lut.h"
25a3e0fd82Sopenharmony_ci
26a3e0fd82Sopenharmony_cinamespace OHOS {
27a3e0fd82Sopenharmony_ci
28a3e0fd82Sopenharmony_ci#if defined(ENABLE_CANVAS_EXTEND) && ENABLE_CANVAS_EXTEND
29a3e0fd82Sopenharmony_cistruct ImageParam : public HeapBase {
30a3e0fd82Sopenharmony_ci    Point start;
31a3e0fd82Sopenharmony_ci    uint16_t height;
32a3e0fd82Sopenharmony_ci    uint16_t width;
33a3e0fd82Sopenharmony_ci    int16_t newWidth;
34a3e0fd82Sopenharmony_ci    int16_t newHeight;
35a3e0fd82Sopenharmony_ci    Image* image;
36a3e0fd82Sopenharmony_ci};
37a3e0fd82Sopenharmony_ci
38a3e0fd82Sopenharmony_cistruct PathParam : public HeapBase {
39a3e0fd82Sopenharmony_ci    UICanvasVertices* vertices;
40a3e0fd82Sopenharmony_ci    ImageParam* imageParam = nullptr;
41a3e0fd82Sopenharmony_ci    bool isStroke;
42a3e0fd82Sopenharmony_ci};
43a3e0fd82Sopenharmony_ci#endif
44a3e0fd82Sopenharmony_ci
45a3e0fd82Sopenharmony_ciclass RenderBuffer;
46a3e0fd82Sopenharmony_ciclass RenderBase;
47a3e0fd82Sopenharmony_ciclass DrawCanvas : public HeapBase {
48a3e0fd82Sopenharmony_cipublic:
49a3e0fd82Sopenharmony_ci#if defined(ENABLE_CANVAS_EXTEND) && ENABLE_CANVAS_EXTEND
50a3e0fd82Sopenharmony_ci    static void DoRender(BufferInfo& gfxDstBuffer,
51a3e0fd82Sopenharmony_ci                         void* param,
52a3e0fd82Sopenharmony_ci                         const Paint& paint,
53a3e0fd82Sopenharmony_ci                         const Rect& rect,
54a3e0fd82Sopenharmony_ci                         const Rect& invalidatedArea,
55a3e0fd82Sopenharmony_ci                         const Style& style,
56a3e0fd82Sopenharmony_ci                         const bool& isStroke);
57a3e0fd82Sopenharmony_ci
58a3e0fd82Sopenharmony_ci#if defined(GRAPHIC_ENABLE_SHADOW_EFFECT_FLAG) && GRAPHIC_ENABLE_SHADOW_EFFECT_FLAG
59a3e0fd82Sopenharmony_ci    static void DoDrawShadow(BufferInfo& gfxDstBuffer,
60a3e0fd82Sopenharmony_ci                             void* param,
61a3e0fd82Sopenharmony_ci                             const Paint& paint,
62a3e0fd82Sopenharmony_ci                             const Rect& rect,
63a3e0fd82Sopenharmony_ci                             const Rect& invalidatedArea,
64a3e0fd82Sopenharmony_ci                             const Style& style,
65a3e0fd82Sopenharmony_ci                             const bool& isStroke);
66a3e0fd82Sopenharmony_ci#endif
67a3e0fd82Sopenharmony_ci#endif
68a3e0fd82Sopenharmony_ci    static void InitRenderAndTransform(BufferInfo& gfxDstBuffer,
69a3e0fd82Sopenharmony_ci                                       RenderBuffer& renderBuffer,
70a3e0fd82Sopenharmony_ci                                       const Rect& rect,
71a3e0fd82Sopenharmony_ci                                       TransAffine& transform,
72a3e0fd82Sopenharmony_ci                                       const Style& style,
73a3e0fd82Sopenharmony_ci                                       const Paint& paint);
74a3e0fd82Sopenharmony_ci
75a3e0fd82Sopenharmony_ci    static void SetRasterizer(UICanvasVertices& vertices,
76a3e0fd82Sopenharmony_ci                              const Paint& paint,
77a3e0fd82Sopenharmony_ci                              RasterizerScanlineAntialias& rasterizer,
78a3e0fd82Sopenharmony_ci                              TransAffine& transform,
79a3e0fd82Sopenharmony_ci                              const bool& isStroke);
80a3e0fd82Sopenharmony_ci
81a3e0fd82Sopenharmony_ci#if defined(GRAPHIC_ENABLE_GRADIENT_FILL_FLAG) && GRAPHIC_ENABLE_GRADIENT_FILL_FLAG
82a3e0fd82Sopenharmony_ci    /**
83a3e0fd82Sopenharmony_ci     * Render gradient
84a3e0fd82Sopenharmony_ci     */
85a3e0fd82Sopenharmony_ci    static void RenderGradient(const Paint& paint,
86a3e0fd82Sopenharmony_ci                               RasterizerScanlineAntialias& rasterizer,
87a3e0fd82Sopenharmony_ci                               TransAffine& transform,
88a3e0fd82Sopenharmony_ci                               RenderBase& renBase,
89a3e0fd82Sopenharmony_ci                               RenderBuffer& renderBuffer,
90a3e0fd82Sopenharmony_ci                               FillBase& allocator,
91a3e0fd82Sopenharmony_ci                               const Rect& invalidatedArea);
92a3e0fd82Sopenharmony_ci
93a3e0fd82Sopenharmony_ci    static void BuildGradientColor(const Paint& paint, FillGradientLut& gradientColorMode);
94a3e0fd82Sopenharmony_ci
95a3e0fd82Sopenharmony_ci    static void BuildLineGradientMatrix(const Paint& paint,
96a3e0fd82Sopenharmony_ci                                        TransAffine& gradientMatrix,
97a3e0fd82Sopenharmony_ci                                        TransAffine& transform,
98a3e0fd82Sopenharmony_ci                                        float& distance)
99a3e0fd82Sopenharmony_ci    {
100a3e0fd82Sopenharmony_ci        Paint::LinearGradientPoint linearPoint = paint.GetLinearGradientPoint();
101a3e0fd82Sopenharmony_ci        float angle = FastAtan2F(linearPoint.y1 - linearPoint.y0, linearPoint.x1 - linearPoint.x0);
102a3e0fd82Sopenharmony_ci        gradientMatrix.Reset();
103a3e0fd82Sopenharmony_ci        gradientMatrix *= TransAffine::TransAffineRotation(angle);
104a3e0fd82Sopenharmony_ci        gradientMatrix *= TransAffine::TransAffineTranslation(linearPoint.x0, linearPoint.y0);
105a3e0fd82Sopenharmony_ci        gradientMatrix *= transform;
106a3e0fd82Sopenharmony_ci        gradientMatrix.Invert();
107a3e0fd82Sopenharmony_ci        distance = Sqrt((linearPoint.x1 - linearPoint.x0) * (linearPoint.x1 - linearPoint.x0) +
108a3e0fd82Sopenharmony_ci                        (linearPoint.y1 - linearPoint.y0) * (linearPoint.y1 - linearPoint.y0));
109a3e0fd82Sopenharmony_ci    }
110a3e0fd82Sopenharmony_ci
111a3e0fd82Sopenharmony_ci    static void BuildRadialGradientMatrix(const Paint& paint,
112a3e0fd82Sopenharmony_ci                                          TransAffine& gradientMatrix,
113a3e0fd82Sopenharmony_ci                                          TransAffine& transform,
114a3e0fd82Sopenharmony_ci                                          float& startRadius,
115a3e0fd82Sopenharmony_ci                                          float& endRadius);
116a3e0fd82Sopenharmony_ci#endif // GRAPHIC_ENABLE_GRADIENT_FILL_FLAG
117a3e0fd82Sopenharmony_ci
118a3e0fd82Sopenharmony_ci#if defined(GRAPHIC_ENABLE_PATTERN_FILL_FLAG) && GRAPHIC_ENABLE_PATTERN_FILL_FLAG
119a3e0fd82Sopenharmony_ci#if defined(ENABLE_CANVAS_EXTEND) && ENABLE_CANVAS_EXTEND
120a3e0fd82Sopenharmony_ci    /**
121a3e0fd82Sopenharmony_ci     * Render pattern mode
122a3e0fd82Sopenharmony_ci     */
123a3e0fd82Sopenharmony_ci    static void RenderPattern(const Paint& paint,
124a3e0fd82Sopenharmony_ci                              void* param,
125a3e0fd82Sopenharmony_ci                              RasterizerScanlineAntialias& rasterizer,
126a3e0fd82Sopenharmony_ci                              RenderBase& renBase,
127a3e0fd82Sopenharmony_ci                              FillBase& allocator,
128a3e0fd82Sopenharmony_ci                              const Rect& rect);
129a3e0fd82Sopenharmony_ci#endif
130a3e0fd82Sopenharmony_ci#endif // GRAPHIC_ENABLE_PATTERN_FILL_FLAG
131a3e0fd82Sopenharmony_ci
132a3e0fd82Sopenharmony_ci    static void ChangeColor(Rgba8T& color, ColorType colorType, uint8_t alpha)
133a3e0fd82Sopenharmony_ci    {
134a3e0fd82Sopenharmony_ci        color.red = colorType.red;
135a3e0fd82Sopenharmony_ci        color.green = colorType.green;
136a3e0fd82Sopenharmony_ci        color.blue = colorType.blue;
137a3e0fd82Sopenharmony_ci        color.alpha = alpha;
138a3e0fd82Sopenharmony_ci    }
139a3e0fd82Sopenharmony_ci
140a3e0fd82Sopenharmony_ci    static void RenderBlendSolid(const Paint& paint, Rgba8T& color, const bool& isStroke)
141a3e0fd82Sopenharmony_ci    {
142a3e0fd82Sopenharmony_ci        if (isStroke) {
143a3e0fd82Sopenharmony_ci            if (paint.GetStyle() == Paint::STROKE_STYLE || paint.GetStyle() == Paint::STROKE_FILL_STYLE) {
144a3e0fd82Sopenharmony_ci                ChangeColor(color, paint.GetStrokeColor(),
145a3e0fd82Sopenharmony_ci                            static_cast<uint8_t>(paint.GetStrokeColor().alpha * paint.GetGlobalAlpha()));
146a3e0fd82Sopenharmony_ci            }
147a3e0fd82Sopenharmony_ci        } else {
148a3e0fd82Sopenharmony_ci            if (paint.GetStyle() == Paint::FILL_STYLE || paint.GetStyle() == Paint::STROKE_FILL_STYLE) {
149a3e0fd82Sopenharmony_ci                ChangeColor(color, paint.GetFillColor(),
150a3e0fd82Sopenharmony_ci                            static_cast<uint8_t>(paint.GetFillColor().alpha * paint.GetGlobalAlpha()));
151a3e0fd82Sopenharmony_ci            }
152a3e0fd82Sopenharmony_ci        }
153a3e0fd82Sopenharmony_ci    }
154a3e0fd82Sopenharmony_ci
155a3e0fd82Sopenharmony_ci    /**
156a3e0fd82Sopenharmony_ci     * Assembly parameter setting lineweight,LineCap,LineJoin
157a3e0fd82Sopenharmony_ci     */
158a3e0fd82Sopenharmony_ci    template <class LineStyle> static void LineStyleCalc(DepictStroke<LineStyle>& strokeLineStyle, const Paint& paint)
159a3e0fd82Sopenharmony_ci    {
160a3e0fd82Sopenharmony_ci        strokeLineStyle.SetWidth(paint.GetStrokeWidth()); // Line style related
161a3e0fd82Sopenharmony_ci#if defined(GRAPHIC_ENABLE_LINECAP_FLAG) && GRAPHIC_ENABLE_LINECAP_FLAG
162a3e0fd82Sopenharmony_ci        strokeLineStyle.SetLineCap(paint.GetLineCap());
163a3e0fd82Sopenharmony_ci#endif
164a3e0fd82Sopenharmony_ci#if defined(GRAPHIC_ENABLE_LINEJOIN_FLAG) && GRAPHIC_ENABLE_LINEJOIN_FLAG
165a3e0fd82Sopenharmony_ci        strokeLineStyle.SetLineJoin(paint.GetLineJoin());
166a3e0fd82Sopenharmony_ci        if (paint.GetMiterLimit() > 0) {
167a3e0fd82Sopenharmony_ci            strokeLineStyle.SetMiterLimit(paint.GetMiterLimit());
168a3e0fd82Sopenharmony_ci        }
169a3e0fd82Sopenharmony_ci#endif
170a3e0fd82Sopenharmony_ci    };
171a3e0fd82Sopenharmony_ci
172a3e0fd82Sopenharmony_ci#if defined(GRAPHIC_ENABLE_DASH_GENERATE_FLAG) && GRAPHIC_ENABLE_DASH_GENERATE_FLAG
173a3e0fd82Sopenharmony_ci    /**
174a3e0fd82Sopenharmony_ci     * Set linedash style
175a3e0fd82Sopenharmony_ci     */
176a3e0fd82Sopenharmony_ci    static void LineDashStyleCalc(DepictDash& dashStyle, const Paint& paint)
177a3e0fd82Sopenharmony_ci    {
178a3e0fd82Sopenharmony_ci        for (uint32_t i = 0; i < paint.GetLineDashCount(); i += TWO_STEP) {
179a3e0fd82Sopenharmony_ci            dashStyle.AddDash(paint.GetLineDash()[i], paint.GetLineDash()[i + 1]);
180a3e0fd82Sopenharmony_ci        }
181a3e0fd82Sopenharmony_ci        dashStyle.DashStart(paint.GetLineDashOffset());
182a3e0fd82Sopenharmony_ci    };
183a3e0fd82Sopenharmony_ci#endif
184a3e0fd82Sopenharmony_ci};
185a3e0fd82Sopenharmony_ci} // namespace OHOS
186a3e0fd82Sopenharmony_ci#endif // GRAPHIC_LITE_DRAW_CANVAS_H
187