1a3e0fd82Sopenharmony_ci/*
2a3e0fd82Sopenharmony_ci * Copyright (c) 2020-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#include "components/ui_canvas.h"
17a3e0fd82Sopenharmony_ci
18a3e0fd82Sopenharmony_ci#include "draw/clip_utils.h"
19a3e0fd82Sopenharmony_ci#include "draw/draw_arc.h"
20a3e0fd82Sopenharmony_ci#include "draw/draw_image.h"
21a3e0fd82Sopenharmony_ci#include "gfx_utils/graphic_log.h"
22a3e0fd82Sopenharmony_ci#include "render/render_buffer.h"
23a3e0fd82Sopenharmony_ci#include "render/render_pixfmt_rgba_blend.h"
24a3e0fd82Sopenharmony_ci#include "render/render_scanline.h"
25a3e0fd82Sopenharmony_ci#if ( (defined(ENABLE_CANVAS_EXTEND) && ENABLE_CANVAS_EXTEND) )
26a3e0fd82Sopenharmony_ci#include "draw/draw_canvas.h"
27a3e0fd82Sopenharmony_ci#endif
28a3e0fd82Sopenharmony_ci
29a3e0fd82Sopenharmony_cinamespace OHOS {
30a3e0fd82Sopenharmony_ciUICanvas::UICanvasPath::~UICanvasPath()
31a3e0fd82Sopenharmony_ci{
32a3e0fd82Sopenharmony_ci    points_.Clear();
33a3e0fd82Sopenharmony_ci    cmd_.Clear();
34a3e0fd82Sopenharmony_ci    arcParam_.Clear();
35a3e0fd82Sopenharmony_ci}
36a3e0fd82Sopenharmony_ci
37a3e0fd82Sopenharmony_ciBufferInfo* UICanvas::gfxMapBuffer_ = nullptr;
38a3e0fd82Sopenharmony_ci
39a3e0fd82Sopenharmony_civoid RenderSolid(const Paint& paint,
40a3e0fd82Sopenharmony_ci                 RasterizerScanlineAntialias& rasterizer,
41a3e0fd82Sopenharmony_ci                 RenderBase& renBase,
42a3e0fd82Sopenharmony_ci                 const bool& isStroke);
43a3e0fd82Sopenharmony_ci
44a3e0fd82Sopenharmony_civoid UICanvas::BeginPath()
45a3e0fd82Sopenharmony_ci{
46a3e0fd82Sopenharmony_ci#if defined(ENABLE_CANVAS_EXTEND) && ENABLE_CANVAS_EXTEND
47a3e0fd82Sopenharmony_ci    /* If the previous path is not added to the drawing linked list, it should be destroyed directly. */
48a3e0fd82Sopenharmony_ci    if (vertices_ != nullptr && vertices_->GetTotalVertices() == 0) {
49a3e0fd82Sopenharmony_ci        delete vertices_;
50a3e0fd82Sopenharmony_ci        vertices_ = nullptr;
51a3e0fd82Sopenharmony_ci    }
52a3e0fd82Sopenharmony_ci
53a3e0fd82Sopenharmony_ci    vertices_ = new UICanvasVertices();
54a3e0fd82Sopenharmony_ci    if (vertices_ == nullptr) {
55a3e0fd82Sopenharmony_ci        GRAPHIC_LOGE("new UICanvasVertices fail");
56a3e0fd82Sopenharmony_ci        return;
57a3e0fd82Sopenharmony_ci    }
58a3e0fd82Sopenharmony_ci#else
59a3e0fd82Sopenharmony_ci    if (path_ != nullptr && path_->strokeCount_ == 0) {
60a3e0fd82Sopenharmony_ci        delete path_;
61a3e0fd82Sopenharmony_ci        path_ = nullptr;
62a3e0fd82Sopenharmony_ci    }
63a3e0fd82Sopenharmony_ci
64a3e0fd82Sopenharmony_ci    path_ = new UICanvasPath();
65a3e0fd82Sopenharmony_ci    if (path_ == nullptr) {
66a3e0fd82Sopenharmony_ci        GRAPHIC_LOGE("new UICanvasPath fail");
67a3e0fd82Sopenharmony_ci        return;
68a3e0fd82Sopenharmony_ci    }
69a3e0fd82Sopenharmony_ci#endif
70a3e0fd82Sopenharmony_ci}
71a3e0fd82Sopenharmony_ci
72a3e0fd82Sopenharmony_civoid UICanvas::MoveTo(const Point& point)
73a3e0fd82Sopenharmony_ci{
74a3e0fd82Sopenharmony_ci#if defined(ENABLE_CANVAS_EXTEND) && ENABLE_CANVAS_EXTEND
75a3e0fd82Sopenharmony_ci    if (vertices_ == nullptr) {
76a3e0fd82Sopenharmony_ci        return;
77a3e0fd82Sopenharmony_ci    }
78a3e0fd82Sopenharmony_ci    vertices_->MoveTo(point.x, point.y);
79a3e0fd82Sopenharmony_ci#else
80a3e0fd82Sopenharmony_ci    if (path_ == nullptr) {
81a3e0fd82Sopenharmony_ci        return;
82a3e0fd82Sopenharmony_ci    }
83a3e0fd82Sopenharmony_ci
84a3e0fd82Sopenharmony_ci    path_->startPos_ = point;
85a3e0fd82Sopenharmony_ci    /* If the previous command is also CMD_MOVE_TO, the previous command is overwritten. */
86a3e0fd82Sopenharmony_ci    if ((path_->cmd_.Size() != 0) && (path_->cmd_.Tail()->data_ == CMD_MOVE_TO)) {
87a3e0fd82Sopenharmony_ci        path_->points_.Tail()->data_ = point;
88a3e0fd82Sopenharmony_ci        return;
89a3e0fd82Sopenharmony_ci    }
90a3e0fd82Sopenharmony_ci    path_->points_.PushBack(point);
91a3e0fd82Sopenharmony_ci    path_->cmd_.PushBack(CMD_MOVE_TO);
92a3e0fd82Sopenharmony_ci#endif
93a3e0fd82Sopenharmony_ci}
94a3e0fd82Sopenharmony_ci
95a3e0fd82Sopenharmony_civoid UICanvas::LineTo(const Point& point)
96a3e0fd82Sopenharmony_ci{
97a3e0fd82Sopenharmony_ci#if defined(ENABLE_CANVAS_EXTEND) && ENABLE_CANVAS_EXTEND
98a3e0fd82Sopenharmony_ci    if (vertices_ == nullptr) {
99a3e0fd82Sopenharmony_ci        return;
100a3e0fd82Sopenharmony_ci    }
101a3e0fd82Sopenharmony_ci    vertices_->LineTo(point.x, point.y);
102a3e0fd82Sopenharmony_ci#else
103a3e0fd82Sopenharmony_ci    if (path_ == nullptr) {
104a3e0fd82Sopenharmony_ci        return;
105a3e0fd82Sopenharmony_ci    }
106a3e0fd82Sopenharmony_ci
107a3e0fd82Sopenharmony_ci    path_->points_.PushBack(point);
108a3e0fd82Sopenharmony_ci    if (path_->cmd_.Size() == 0) {
109a3e0fd82Sopenharmony_ci        path_->startPos_ = point;
110a3e0fd82Sopenharmony_ci        path_->cmd_.PushBack(CMD_MOVE_TO);
111a3e0fd82Sopenharmony_ci    } else {
112a3e0fd82Sopenharmony_ci        path_->cmd_.PushBack(CMD_LINE_TO);
113a3e0fd82Sopenharmony_ci    }
114a3e0fd82Sopenharmony_ci#endif
115a3e0fd82Sopenharmony_ci}
116a3e0fd82Sopenharmony_ci
117a3e0fd82Sopenharmony_civoid UICanvas::ArcTo(const Point& center, uint16_t radius, int16_t startAngle, int16_t endAngle)
118a3e0fd82Sopenharmony_ci{
119a3e0fd82Sopenharmony_ci#if defined(ENABLE_CANVAS_EXTEND) && ENABLE_CANVAS_EXTEND
120a3e0fd82Sopenharmony_ci    if (vertices_ == nullptr || startAngle == endAngle) {
121a3e0fd82Sopenharmony_ci        return;
122a3e0fd82Sopenharmony_ci    }
123a3e0fd82Sopenharmony_ci    float sinma = radius * Sin(startAngle);
124a3e0fd82Sopenharmony_ci    float cosma = radius * Sin(QUARTER_IN_DEGREE - startAngle);
125a3e0fd82Sopenharmony_ci    if (vertices_->GetTotalVertices() != 0) {
126a3e0fd82Sopenharmony_ci        vertices_->LineTo(float(center.x + sinma), float(center.y - cosma));
127a3e0fd82Sopenharmony_ci    } else {
128a3e0fd82Sopenharmony_ci        vertices_->MoveTo(float(center.x + sinma), float(center.y - cosma));
129a3e0fd82Sopenharmony_ci    }
130a3e0fd82Sopenharmony_ci    if (MATH_ABS(startAngle - endAngle) < CIRCLE_IN_DEGREE) {
131a3e0fd82Sopenharmony_ci        sinma = radius * Sin(endAngle);
132a3e0fd82Sopenharmony_ci        cosma = radius * Sin(QUARTER_IN_DEGREE - endAngle);
133a3e0fd82Sopenharmony_ci    }
134a3e0fd82Sopenharmony_ci    int16_t angle = endAngle - startAngle;
135a3e0fd82Sopenharmony_ci    bool largeArcFlag = false;
136a3e0fd82Sopenharmony_ci    if (angle > SEMICIRCLE_IN_DEGREE || angle <= 0) {
137a3e0fd82Sopenharmony_ci        largeArcFlag = true;
138a3e0fd82Sopenharmony_ci    }
139a3e0fd82Sopenharmony_ci    vertices_->ArcTo(radius, radius, angle, largeArcFlag, 1, float(center.x + sinma), float(center.y - cosma));
140a3e0fd82Sopenharmony_ci#else
141a3e0fd82Sopenharmony_ci    if (path_ == nullptr) {
142a3e0fd82Sopenharmony_ci        return;
143a3e0fd82Sopenharmony_ci    }
144a3e0fd82Sopenharmony_ci
145a3e0fd82Sopenharmony_ci    /*
146a3e0fd82Sopenharmony_ci     * If there is no command before CMD_ARC, only the arc is drawn. If there is a command in front of
147a3e0fd82Sopenharmony_ci     * CMD_ARC, the start point of arc must be connected to the end point of the path.
148a3e0fd82Sopenharmony_ci     */
149a3e0fd82Sopenharmony_ci    float sinma = radius * Sin(startAngle);
150a3e0fd82Sopenharmony_ci    float cosma = radius * Sin(QUARTER_IN_DEGREE - startAngle);
151a3e0fd82Sopenharmony_ci    if (path_->cmd_.Size() != 0) {
152a3e0fd82Sopenharmony_ci        path_->points_.PushBack({MATH_ROUND(center.x + sinma), MATH_ROUND(center.y - cosma)});
153a3e0fd82Sopenharmony_ci        path_->cmd_.PushBack(CMD_LINE_TO);
154a3e0fd82Sopenharmony_ci    } else {
155a3e0fd82Sopenharmony_ci        path_->startPos_ = {MATH_ROUND(center.x + sinma), MATH_ROUND(center.y - cosma)};
156a3e0fd82Sopenharmony_ci    }
157a3e0fd82Sopenharmony_ci
158a3e0fd82Sopenharmony_ci    /* If the ARC scan range exceeds 360 degrees, the end point of the path is the position of the start angle. */
159a3e0fd82Sopenharmony_ci    if (MATH_ABS(startAngle - endAngle) < CIRCLE_IN_DEGREE) {
160a3e0fd82Sopenharmony_ci        sinma = radius * Sin(endAngle);
161a3e0fd82Sopenharmony_ci        cosma = radius * Sin(QUARTER_IN_DEGREE - endAngle);
162a3e0fd82Sopenharmony_ci    }
163a3e0fd82Sopenharmony_ci    path_->points_.PushBack({MATH_ROUND(center.x + sinma), MATH_ROUND(center.y - cosma)});
164a3e0fd82Sopenharmony_ci    path_->cmd_.PushBack(CMD_ARC);
165a3e0fd82Sopenharmony_ci
166a3e0fd82Sopenharmony_ci    SetArcParamInfo(center, radius, startAngle, endAngle);
167a3e0fd82Sopenharmony_ci#endif
168a3e0fd82Sopenharmony_ci}
169a3e0fd82Sopenharmony_ci
170a3e0fd82Sopenharmony_civoid UICanvas::SetArcParamInfo(const Point& center, uint16_t radius, int16_t startAngle, int16_t endAngle)
171a3e0fd82Sopenharmony_ci{
172a3e0fd82Sopenharmony_ci    int16_t start;
173a3e0fd82Sopenharmony_ci    int16_t end;
174a3e0fd82Sopenharmony_ci    if (startAngle > endAngle) {
175a3e0fd82Sopenharmony_ci        start = endAngle;
176a3e0fd82Sopenharmony_ci        end = startAngle;
177a3e0fd82Sopenharmony_ci    } else {
178a3e0fd82Sopenharmony_ci        start = startAngle;
179a3e0fd82Sopenharmony_ci        end = endAngle;
180a3e0fd82Sopenharmony_ci    }
181a3e0fd82Sopenharmony_ci
182a3e0fd82Sopenharmony_ci    DrawArc::GetInstance()->GetDrawRange(start, end);
183a3e0fd82Sopenharmony_ci    ArcParam param;
184a3e0fd82Sopenharmony_ci    param.center = center;
185a3e0fd82Sopenharmony_ci    param.radius = radius;
186a3e0fd82Sopenharmony_ci    param.startAngle = start;
187a3e0fd82Sopenharmony_ci    param.endAngle = end;
188a3e0fd82Sopenharmony_ci    path_->arcParam_.PushBack(param);
189a3e0fd82Sopenharmony_ci}
190a3e0fd82Sopenharmony_ci
191a3e0fd82Sopenharmony_civoid UICanvas::AddRect(const Point& point, int16_t height, int16_t width)
192a3e0fd82Sopenharmony_ci{
193a3e0fd82Sopenharmony_ci#if defined(ENABLE_CANVAS_EXTEND) && ENABLE_CANVAS_EXTEND
194a3e0fd82Sopenharmony_ci    if (vertices_ == nullptr) {
195a3e0fd82Sopenharmony_ci        return;
196a3e0fd82Sopenharmony_ci    }
197a3e0fd82Sopenharmony_ci
198a3e0fd82Sopenharmony_ci    int16_t right = static_cast<int16_t>(point.x + width);
199a3e0fd82Sopenharmony_ci    int16_t bottom = point.y + height;
200a3e0fd82Sopenharmony_ci
201a3e0fd82Sopenharmony_ci    float fRight = static_cast<float>(width) + static_cast<float>(point.x);
202a3e0fd82Sopenharmony_ci    float fBottom = static_cast<float>(height) + static_cast<float>(point.y);
203a3e0fd82Sopenharmony_ci    const int16_t setup = 3;
204a3e0fd82Sopenharmony_ci    if (fRight > INT16_MAX) {
205a3e0fd82Sopenharmony_ci        right += setup;
206a3e0fd82Sopenharmony_ci    }
207a3e0fd82Sopenharmony_ci    if (fBottom > INT16_MAX) {
208a3e0fd82Sopenharmony_ci        bottom += setup;
209a3e0fd82Sopenharmony_ci    }
210a3e0fd82Sopenharmony_ci
211a3e0fd82Sopenharmony_ci    MoveTo(point);
212a3e0fd82Sopenharmony_ci    LineTo({right, point.y});
213a3e0fd82Sopenharmony_ci    LineTo({right, bottom});
214a3e0fd82Sopenharmony_ci    LineTo({point.x, bottom});
215a3e0fd82Sopenharmony_ci#else
216a3e0fd82Sopenharmony_ci    if (path_ == nullptr) {
217a3e0fd82Sopenharmony_ci        return;
218a3e0fd82Sopenharmony_ci    }
219a3e0fd82Sopenharmony_ci
220a3e0fd82Sopenharmony_ci    MoveTo(point);
221a3e0fd82Sopenharmony_ci    LineTo({static_cast<int16_t>(point.x + width), point.y});
222a3e0fd82Sopenharmony_ci    LineTo({static_cast<int16_t>(point.x + width), static_cast<int16_t>(point.y + height)});
223a3e0fd82Sopenharmony_ci    LineTo({point.x, static_cast<int16_t>(point.y + height)});
224a3e0fd82Sopenharmony_ci
225a3e0fd82Sopenharmony_ci#endif
226a3e0fd82Sopenharmony_ci    ClosePath();
227a3e0fd82Sopenharmony_ci}
228a3e0fd82Sopenharmony_ci
229a3e0fd82Sopenharmony_civoid UICanvas::ClosePath()
230a3e0fd82Sopenharmony_ci{
231a3e0fd82Sopenharmony_ci#if defined(ENABLE_CANVAS_EXTEND) && ENABLE_CANVAS_EXTEND
232a3e0fd82Sopenharmony_ci    if (vertices_ == nullptr) {
233a3e0fd82Sopenharmony_ci        return;
234a3e0fd82Sopenharmony_ci    }
235a3e0fd82Sopenharmony_ci    vertices_->ClosePolygon();
236a3e0fd82Sopenharmony_ci#else
237a3e0fd82Sopenharmony_ci    if ((path_ == nullptr) || (path_->cmd_.Size() == 0)) {
238a3e0fd82Sopenharmony_ci        return;
239a3e0fd82Sopenharmony_ci    }
240a3e0fd82Sopenharmony_ci
241a3e0fd82Sopenharmony_ci    path_->points_.PushBack(path_->startPos_);
242a3e0fd82Sopenharmony_ci    path_->cmd_.PushBack(CMD_CLOSE);
243a3e0fd82Sopenharmony_ci#endif
244a3e0fd82Sopenharmony_ci}
245a3e0fd82Sopenharmony_ci
246a3e0fd82Sopenharmony_ciUICanvas::~UICanvas()
247a3e0fd82Sopenharmony_ci{
248a3e0fd82Sopenharmony_ci    if ((path_ != nullptr) && (path_->strokeCount_ == 0)) {
249a3e0fd82Sopenharmony_ci        delete path_;
250a3e0fd82Sopenharmony_ci        path_ = nullptr;
251a3e0fd82Sopenharmony_ci    }
252a3e0fd82Sopenharmony_ci    void* param = nullptr;
253a3e0fd82Sopenharmony_ci    ListNode<DrawCmd>* curDraw = drawCmdList_.Begin();
254a3e0fd82Sopenharmony_ci    for (; curDraw != drawCmdList_.End(); curDraw = curDraw->next_) {
255a3e0fd82Sopenharmony_ci        param = curDraw->data_.param;
256a3e0fd82Sopenharmony_ci        curDraw->data_.DeleteParam(param);
257a3e0fd82Sopenharmony_ci        curDraw->data_.param = nullptr;
258a3e0fd82Sopenharmony_ci    }
259a3e0fd82Sopenharmony_ci    drawCmdList_.Clear();
260a3e0fd82Sopenharmony_ci    if (vertices_ != nullptr) {
261a3e0fd82Sopenharmony_ci        delete vertices_;
262a3e0fd82Sopenharmony_ci        vertices_ = nullptr;
263a3e0fd82Sopenharmony_ci    }
264a3e0fd82Sopenharmony_ci    DestroyMapBufferInfo();
265a3e0fd82Sopenharmony_ci}
266a3e0fd82Sopenharmony_ci
267a3e0fd82Sopenharmony_civoid UICanvas::Clear()
268a3e0fd82Sopenharmony_ci{
269a3e0fd82Sopenharmony_ci    if ((path_ != nullptr) && (path_->strokeCount_ == 0)) {
270a3e0fd82Sopenharmony_ci        delete path_;
271a3e0fd82Sopenharmony_ci        path_ = nullptr;
272a3e0fd82Sopenharmony_ci    }
273a3e0fd82Sopenharmony_ci    void* param = nullptr;
274a3e0fd82Sopenharmony_ci    ListNode<DrawCmd>* curDraw = drawCmdList_.Begin();
275a3e0fd82Sopenharmony_ci    for (; curDraw != drawCmdList_.End(); curDraw = curDraw->next_) {
276a3e0fd82Sopenharmony_ci        param = curDraw->data_.param;
277a3e0fd82Sopenharmony_ci        curDraw->data_.DeleteParam(param);
278a3e0fd82Sopenharmony_ci        curDraw->data_.param = nullptr;
279a3e0fd82Sopenharmony_ci    }
280a3e0fd82Sopenharmony_ci    drawCmdList_.Clear();
281a3e0fd82Sopenharmony_ci    if (vertices_ != nullptr) {
282a3e0fd82Sopenharmony_ci        delete vertices_;
283a3e0fd82Sopenharmony_ci        vertices_ = nullptr;
284a3e0fd82Sopenharmony_ci    }
285a3e0fd82Sopenharmony_ci    Invalidate();
286a3e0fd82Sopenharmony_ci}
287a3e0fd82Sopenharmony_ci
288a3e0fd82Sopenharmony_civoid UICanvas::DeleteImageParam(void* param)
289a3e0fd82Sopenharmony_ci{
290a3e0fd82Sopenharmony_ci    ImageParam* imageParam = static_cast<ImageParam*>(param);
291a3e0fd82Sopenharmony_ci    if (imageParam->image != nullptr) {
292a3e0fd82Sopenharmony_ci        delete imageParam->image;
293a3e0fd82Sopenharmony_ci        imageParam->image = nullptr;
294a3e0fd82Sopenharmony_ci    }
295a3e0fd82Sopenharmony_ci    delete imageParam;
296a3e0fd82Sopenharmony_ci    imageParam = nullptr;
297a3e0fd82Sopenharmony_ci}
298a3e0fd82Sopenharmony_ci
299a3e0fd82Sopenharmony_civoid UICanvas::DeletePathParam(void* param)
300a3e0fd82Sopenharmony_ci{
301a3e0fd82Sopenharmony_ci    PathParam* pathParam = static_cast<PathParam*>(param);
302a3e0fd82Sopenharmony_ci#if defined(ENABLE_CANVAS_EXTEND) && ENABLE_CANVAS_EXTEND
303a3e0fd82Sopenharmony_ci    if (pathParam->vertices != nullptr) {
304a3e0fd82Sopenharmony_ci        pathParam->vertices->FreeAll();
305a3e0fd82Sopenharmony_ci        pathParam->vertices = nullptr;
306a3e0fd82Sopenharmony_ci    }
307a3e0fd82Sopenharmony_ci    if (pathParam->imageParam != nullptr) {
308a3e0fd82Sopenharmony_ci        DeleteImageParam(pathParam->imageParam);
309a3e0fd82Sopenharmony_ci    }
310a3e0fd82Sopenharmony_ci#else
311a3e0fd82Sopenharmony_ci    pathParam->path->strokeCount_--;
312a3e0fd82Sopenharmony_ci    if (pathParam->path->strokeCount_ == 0) {
313a3e0fd82Sopenharmony_ci        delete pathParam->path;
314a3e0fd82Sopenharmony_ci    }
315a3e0fd82Sopenharmony_ci#endif
316a3e0fd82Sopenharmony_ci    delete pathParam;
317a3e0fd82Sopenharmony_ci    pathParam = nullptr;
318a3e0fd82Sopenharmony_ci}
319a3e0fd82Sopenharmony_ci
320a3e0fd82Sopenharmony_civoid UICanvas::DrawLine(const Point& endPoint, const Paint& paint)
321a3e0fd82Sopenharmony_ci{
322a3e0fd82Sopenharmony_ci    DrawLine(startPoint_, endPoint, paint);
323a3e0fd82Sopenharmony_ci}
324a3e0fd82Sopenharmony_ci
325a3e0fd82Sopenharmony_civoid UICanvas::DrawLine(const Point& startPoint, const Point& endPoint, const Paint& paint)
326a3e0fd82Sopenharmony_ci{
327a3e0fd82Sopenharmony_ci    LineParam* lineParam = new LineParam;
328a3e0fd82Sopenharmony_ci    if (lineParam == nullptr) {
329a3e0fd82Sopenharmony_ci        GRAPHIC_LOGE("new LineParam fail");
330a3e0fd82Sopenharmony_ci        return;
331a3e0fd82Sopenharmony_ci    }
332a3e0fd82Sopenharmony_ci    lineParam->start = startPoint;
333a3e0fd82Sopenharmony_ci    lineParam->end = endPoint;
334a3e0fd82Sopenharmony_ci
335a3e0fd82Sopenharmony_ci    DrawCmd cmd;
336a3e0fd82Sopenharmony_ci    cmd.paint = paint;
337a3e0fd82Sopenharmony_ci    cmd.param = lineParam;
338a3e0fd82Sopenharmony_ci    cmd.DeleteParam = DeleteLineParam;
339a3e0fd82Sopenharmony_ci    cmd.DrawGraphics = DoDrawLine;
340a3e0fd82Sopenharmony_ci    drawCmdList_.PushBack(cmd);
341a3e0fd82Sopenharmony_ci
342a3e0fd82Sopenharmony_ci    Invalidate();
343a3e0fd82Sopenharmony_ci    SetStartPosition(endPoint);
344a3e0fd82Sopenharmony_ci}
345a3e0fd82Sopenharmony_ci
346a3e0fd82Sopenharmony_civoid UICanvas::DrawCurve(const Point& control1, const Point& control2, const Point& endPoint, const Paint& paint)
347a3e0fd82Sopenharmony_ci{
348a3e0fd82Sopenharmony_ci    DrawCurve(startPoint_, control1, control2, endPoint, paint);
349a3e0fd82Sopenharmony_ci}
350a3e0fd82Sopenharmony_ci
351a3e0fd82Sopenharmony_civoid UICanvas::DrawCurve(const Point& startPoint,
352a3e0fd82Sopenharmony_ci                         const Point& control1,
353a3e0fd82Sopenharmony_ci                         const Point& control2,
354a3e0fd82Sopenharmony_ci                         const Point& endPoint,
355a3e0fd82Sopenharmony_ci                         const Paint& paint)
356a3e0fd82Sopenharmony_ci{
357a3e0fd82Sopenharmony_ci    CurveParam* curveParam = new CurveParam;
358a3e0fd82Sopenharmony_ci    if (curveParam == nullptr) {
359a3e0fd82Sopenharmony_ci        GRAPHIC_LOGE("new CurveParam fail");
360a3e0fd82Sopenharmony_ci        return;
361a3e0fd82Sopenharmony_ci    }
362a3e0fd82Sopenharmony_ci    curveParam->start = startPoint;
363a3e0fd82Sopenharmony_ci    curveParam->control1 = control1;
364a3e0fd82Sopenharmony_ci    curveParam->control2 = control2;
365a3e0fd82Sopenharmony_ci    curveParam->end = endPoint;
366a3e0fd82Sopenharmony_ci
367a3e0fd82Sopenharmony_ci    DrawCmd cmd;
368a3e0fd82Sopenharmony_ci    cmd.paint = paint;
369a3e0fd82Sopenharmony_ci    if (paint.GetStrokeWidth() > MAX_CURVE_WIDTH) {
370a3e0fd82Sopenharmony_ci        cmd.paint.SetStrokeWidth(MAX_CURVE_WIDTH);
371a3e0fd82Sopenharmony_ci    }
372a3e0fd82Sopenharmony_ci    cmd.param = curveParam;
373a3e0fd82Sopenharmony_ci    cmd.DeleteParam = DeleteCurveParam;
374a3e0fd82Sopenharmony_ci    cmd.DrawGraphics = DoDrawCurve;
375a3e0fd82Sopenharmony_ci    drawCmdList_.PushBack(cmd);
376a3e0fd82Sopenharmony_ci
377a3e0fd82Sopenharmony_ci    Invalidate();
378a3e0fd82Sopenharmony_ci    SetStartPosition(endPoint);
379a3e0fd82Sopenharmony_ci}
380a3e0fd82Sopenharmony_ci
381a3e0fd82Sopenharmony_civoid UICanvas::DrawRect(const Point& startPoint, int16_t height, int16_t width, const Paint& paint)
382a3e0fd82Sopenharmony_ci{
383a3e0fd82Sopenharmony_ci#if defined(ENABLE_CANVAS_EXTEND) && ENABLE_CANVAS_EXTEND
384a3e0fd82Sopenharmony_ci    SetDrawLinePath(startPoint, height, width, paint);
385a3e0fd82Sopenharmony_ci#else
386a3e0fd82Sopenharmony_ci    if (static_cast<uint8_t>(paint.GetStyle()) & Paint::PaintStyle::STROKE_STYLE) {
387a3e0fd82Sopenharmony_ci        RectParam* rectParam = new RectParam;
388a3e0fd82Sopenharmony_ci        if (rectParam == nullptr) {
389a3e0fd82Sopenharmony_ci            GRAPHIC_LOGE("new RectParam fail");
390a3e0fd82Sopenharmony_ci            return;
391a3e0fd82Sopenharmony_ci        }
392a3e0fd82Sopenharmony_ci        rectParam->start = startPoint;
393a3e0fd82Sopenharmony_ci        rectParam->height = height;
394a3e0fd82Sopenharmony_ci        rectParam->width = width;
395a3e0fd82Sopenharmony_ci
396a3e0fd82Sopenharmony_ci        DrawCmd cmd;
397a3e0fd82Sopenharmony_ci        cmd.paint = paint;
398a3e0fd82Sopenharmony_ci        cmd.param = rectParam;
399a3e0fd82Sopenharmony_ci        cmd.DeleteParam = DeleteRectParam;
400a3e0fd82Sopenharmony_ci        cmd.DrawGraphics = DoDrawRect;
401a3e0fd82Sopenharmony_ci        drawCmdList_.PushBack(cmd);
402a3e0fd82Sopenharmony_ci    }
403a3e0fd82Sopenharmony_ci
404a3e0fd82Sopenharmony_ci    if (static_cast<uint8_t>(paint.GetStyle()) & Paint::PaintStyle::FILL_STYLE) {
405a3e0fd82Sopenharmony_ci        RectParam* rectParam = new RectParam;
406a3e0fd82Sopenharmony_ci        if (rectParam == nullptr) {
407a3e0fd82Sopenharmony_ci            GRAPHIC_LOGE("new RectParam fail");
408a3e0fd82Sopenharmony_ci            return;
409a3e0fd82Sopenharmony_ci        }
410a3e0fd82Sopenharmony_ci        rectParam->start = startPoint;
411a3e0fd82Sopenharmony_ci        rectParam->height = height;
412a3e0fd82Sopenharmony_ci        rectParam->width = width;
413a3e0fd82Sopenharmony_ci
414a3e0fd82Sopenharmony_ci        DrawCmd cmd;
415a3e0fd82Sopenharmony_ci        cmd.paint = paint;
416a3e0fd82Sopenharmony_ci        cmd.param = rectParam;
417a3e0fd82Sopenharmony_ci        cmd.DeleteParam = DeleteRectParam;
418a3e0fd82Sopenharmony_ci        cmd.DrawGraphics = DoFillRect;
419a3e0fd82Sopenharmony_ci        drawCmdList_.PushBack(cmd);
420a3e0fd82Sopenharmony_ci    }
421a3e0fd82Sopenharmony_ci#endif
422a3e0fd82Sopenharmony_ci    Invalidate();
423a3e0fd82Sopenharmony_ci}
424a3e0fd82Sopenharmony_ci
425a3e0fd82Sopenharmony_ci#if defined(ENABLE_CANVAS_EXTEND) && ENABLE_CANVAS_EXTEND
426a3e0fd82Sopenharmony_civoid UICanvas::SetDrawLinePath(const Point& startPoint, int16_t height, int16_t width, const Paint& paint)
427a3e0fd82Sopenharmony_ci{
428a3e0fd82Sopenharmony_ci    if (!paint.GetChangeFlag()) {
429a3e0fd82Sopenharmony_ci        if (static_cast<uint8_t>(paint.GetStyle()) & Paint::PaintStyle::STROKE_STYLE) {
430a3e0fd82Sopenharmony_ci            DrawRectSetCmd(startPoint, height, width, paint, Paint::PaintStyle::STROKE_STYLE);
431a3e0fd82Sopenharmony_ci        }
432a3e0fd82Sopenharmony_ci
433a3e0fd82Sopenharmony_ci        if (static_cast<uint8_t>(paint.GetStyle()) & Paint::PaintStyle::FILL_STYLE) {
434a3e0fd82Sopenharmony_ci            DrawRectSetCmd(startPoint, height, width, paint, Paint::PaintStyle::FILL_STYLE);
435a3e0fd82Sopenharmony_ci        }
436a3e0fd82Sopenharmony_ci    } else {
437a3e0fd82Sopenharmony_ci        BeginPath();
438a3e0fd82Sopenharmony_ci        MoveTo(startPoint);
439a3e0fd82Sopenharmony_ci        LineTo({static_cast<int16_t>(startPoint.x + width), startPoint.y});
440a3e0fd82Sopenharmony_ci        LineTo({static_cast<int16_t>(startPoint.x + width), static_cast<int16_t>(startPoint.y + height)});
441a3e0fd82Sopenharmony_ci        LineTo({startPoint.x, static_cast<int16_t>(startPoint.y + height)});
442a3e0fd82Sopenharmony_ci        ClosePath();
443a3e0fd82Sopenharmony_ci        FillPath(paint);
444a3e0fd82Sopenharmony_ci        DrawPath(paint);
445a3e0fd82Sopenharmony_ci    }
446a3e0fd82Sopenharmony_ci}
447a3e0fd82Sopenharmony_ci#endif
448a3e0fd82Sopenharmony_ci
449a3e0fd82Sopenharmony_civoid UICanvas::DrawRectSetCmd(const Point& startPoint, int16_t height, int16_t width, const Paint& paint,
450a3e0fd82Sopenharmony_ci                              Paint::PaintStyle paintStyle)
451a3e0fd82Sopenharmony_ci{
452a3e0fd82Sopenharmony_ci    RectParam* rectParam = new RectParam;
453a3e0fd82Sopenharmony_ci    if (rectParam == nullptr) {
454a3e0fd82Sopenharmony_ci        GRAPHIC_LOGE("new RectParam fail");
455a3e0fd82Sopenharmony_ci        return;
456a3e0fd82Sopenharmony_ci    }
457a3e0fd82Sopenharmony_ci    rectParam->start = startPoint;
458a3e0fd82Sopenharmony_ci    rectParam->height = height;
459a3e0fd82Sopenharmony_ci    rectParam->width = width;
460a3e0fd82Sopenharmony_ci
461a3e0fd82Sopenharmony_ci    DrawCmd cmd;
462a3e0fd82Sopenharmony_ci    cmd.paint = paint;
463a3e0fd82Sopenharmony_ci    cmd.param = rectParam;
464a3e0fd82Sopenharmony_ci    cmd.DeleteParam = DeleteRectParam;
465a3e0fd82Sopenharmony_ci    if (paintStyle == Paint::PaintStyle::STROKE_STYLE) {
466a3e0fd82Sopenharmony_ci        cmd.DrawGraphics = DoDrawRect;
467a3e0fd82Sopenharmony_ci    } else if (paintStyle == Paint::PaintStyle::FILL_STYLE) {
468a3e0fd82Sopenharmony_ci        cmd.DrawGraphics = DoFillRect;
469a3e0fd82Sopenharmony_ci    }
470a3e0fd82Sopenharmony_ci    drawCmdList_.PushBack(cmd);
471a3e0fd82Sopenharmony_ci}
472a3e0fd82Sopenharmony_ci
473a3e0fd82Sopenharmony_ci#if defined(ENABLE_CANVAS_EXTEND) && ENABLE_CANVAS_EXTEND
474a3e0fd82Sopenharmony_civoid UICanvas::StrokeRect(const Point& startPoint, int16_t height, int16_t width, const Paint& paint)
475a3e0fd82Sopenharmony_ci{
476a3e0fd82Sopenharmony_ci    if (!paint.GetChangeFlag()) {
477a3e0fd82Sopenharmony_ci        RectParam* rectParam = new RectParam;
478a3e0fd82Sopenharmony_ci        if (rectParam == nullptr) {
479a3e0fd82Sopenharmony_ci            GRAPHIC_LOGE("new RectParam fail");
480a3e0fd82Sopenharmony_ci            return;
481a3e0fd82Sopenharmony_ci        }
482a3e0fd82Sopenharmony_ci        rectParam->start = startPoint;
483a3e0fd82Sopenharmony_ci        rectParam->height = height;
484a3e0fd82Sopenharmony_ci        rectParam->width = width;
485a3e0fd82Sopenharmony_ci
486a3e0fd82Sopenharmony_ci        DrawCmd cmd;
487a3e0fd82Sopenharmony_ci        cmd.paint = paint;
488a3e0fd82Sopenharmony_ci        cmd.param = rectParam;
489a3e0fd82Sopenharmony_ci        cmd.DeleteParam = DeleteRectParam;
490a3e0fd82Sopenharmony_ci        cmd.DrawGraphics = DoDrawRect;
491a3e0fd82Sopenharmony_ci        drawCmdList_.PushBack(cmd);
492a3e0fd82Sopenharmony_ci    } else {
493a3e0fd82Sopenharmony_ci        BeginPath();
494a3e0fd82Sopenharmony_ci        MoveTo(startPoint);
495a3e0fd82Sopenharmony_ci        LineTo({static_cast<int16_t>(startPoint.x + width), startPoint.y});
496a3e0fd82Sopenharmony_ci        LineTo({static_cast<int16_t>(startPoint.x + width), static_cast<int16_t>(startPoint.y + height)});
497a3e0fd82Sopenharmony_ci        LineTo({startPoint.x, static_cast<int16_t>(startPoint.y + height)});
498a3e0fd82Sopenharmony_ci        ClosePath();
499a3e0fd82Sopenharmony_ci        DrawPath(paint);
500a3e0fd82Sopenharmony_ci    }
501a3e0fd82Sopenharmony_ci    SetStartPosition(startPoint);
502a3e0fd82Sopenharmony_ci}
503a3e0fd82Sopenharmony_ci
504a3e0fd82Sopenharmony_civoid UICanvas::ClearRect(const Point& startPoint, int16_t height, int16_t width)
505a3e0fd82Sopenharmony_ci{
506a3e0fd82Sopenharmony_ci    Paint paint;
507a3e0fd82Sopenharmony_ci    paint.SetFillColor(this->style_->bgColor_);
508a3e0fd82Sopenharmony_ci    paint.SetStyle(Paint::FILL_STYLE);
509a3e0fd82Sopenharmony_ci    BeginPath();
510a3e0fd82Sopenharmony_ci    MoveTo(startPoint);
511a3e0fd82Sopenharmony_ci    LineTo({static_cast<int16_t>(startPoint.x + width), startPoint.y});
512a3e0fd82Sopenharmony_ci    LineTo({static_cast<int16_t>(startPoint.x + width), static_cast<int16_t>(startPoint.y + height)});
513a3e0fd82Sopenharmony_ci    LineTo({startPoint.x, static_cast<int16_t>(startPoint.y + height)});
514a3e0fd82Sopenharmony_ci    ClosePath();
515a3e0fd82Sopenharmony_ci    FillPath(paint);
516a3e0fd82Sopenharmony_ci}
517a3e0fd82Sopenharmony_ci#endif
518a3e0fd82Sopenharmony_ci
519a3e0fd82Sopenharmony_civoid UICanvas::DrawCircle(const Point& center, uint16_t radius, const Paint& paint)
520a3e0fd82Sopenharmony_ci{
521a3e0fd82Sopenharmony_ci#if defined(ENABLE_CANVAS_EXTEND) && ENABLE_CANVAS_EXTEND
522a3e0fd82Sopenharmony_ci    if (paint.GetChangeFlag()) {
523a3e0fd82Sopenharmony_ci#if defined(GRAPHIC_ENABLE_BEZIER_ARC_FLAG) && GRAPHIC_ENABLE_BEZIER_ARC_FLAG
524a3e0fd82Sopenharmony_ci        if (vertices_ == nullptr) {
525a3e0fd82Sopenharmony_ci            vertices_ = new UICanvasVertices();
526a3e0fd82Sopenharmony_ci        }
527a3e0fd82Sopenharmony_ci        vertices_->RemoveAll();
528a3e0fd82Sopenharmony_ci        BezierArc arc(center.x, center.y, radius, radius, 0, TWO_TIMES * PI);
529a3e0fd82Sopenharmony_ci        vertices_->ConcatPath(arc, 0);
530a3e0fd82Sopenharmony_ci        vertices_->ClosePolygon();
531a3e0fd82Sopenharmony_ci        if (static_cast<uint8_t>(paint.GetStyle()) & Paint::PaintStyle::STROKE_STYLE) {
532a3e0fd82Sopenharmony_ci            DrawPath(paint);
533a3e0fd82Sopenharmony_ci        }
534a3e0fd82Sopenharmony_ci        if (static_cast<uint8_t>(paint.GetStyle()) & Paint::PaintStyle::FILL_STYLE) {
535a3e0fd82Sopenharmony_ci            FillPath(paint);
536a3e0fd82Sopenharmony_ci        }
537a3e0fd82Sopenharmony_ci#endif
538a3e0fd82Sopenharmony_ci    } else {
539a3e0fd82Sopenharmony_ci        CircleParam* circleParam = new CircleParam;
540a3e0fd82Sopenharmony_ci        if (circleParam == nullptr) {
541a3e0fd82Sopenharmony_ci            GRAPHIC_LOGE("new CircleParam fail");
542a3e0fd82Sopenharmony_ci            return;
543a3e0fd82Sopenharmony_ci        }
544a3e0fd82Sopenharmony_ci        circleParam->center = center;
545a3e0fd82Sopenharmony_ci        circleParam->radius = radius;
546a3e0fd82Sopenharmony_ci
547a3e0fd82Sopenharmony_ci        DrawCmd cmd;
548a3e0fd82Sopenharmony_ci        cmd.paint = paint;
549a3e0fd82Sopenharmony_ci        cmd.param = circleParam;
550a3e0fd82Sopenharmony_ci        cmd.DeleteParam = DeleteCircleParam;
551a3e0fd82Sopenharmony_ci        cmd.DrawGraphics = DoDrawCircle;
552a3e0fd82Sopenharmony_ci        drawCmdList_.PushBack(cmd);
553a3e0fd82Sopenharmony_ci    }
554a3e0fd82Sopenharmony_ci#else
555a3e0fd82Sopenharmony_ci    CircleParam* circleParam = new CircleParam;
556a3e0fd82Sopenharmony_ci    if (circleParam == nullptr) {
557a3e0fd82Sopenharmony_ci        GRAPHIC_LOGE("new CircleParam fail");
558a3e0fd82Sopenharmony_ci        return;
559a3e0fd82Sopenharmony_ci    }
560a3e0fd82Sopenharmony_ci    circleParam->center = center;
561a3e0fd82Sopenharmony_ci    circleParam->radius = radius;
562a3e0fd82Sopenharmony_ci
563a3e0fd82Sopenharmony_ci    DrawCmd cmd;
564a3e0fd82Sopenharmony_ci    cmd.paint = paint;
565a3e0fd82Sopenharmony_ci    cmd.param = circleParam;
566a3e0fd82Sopenharmony_ci    cmd.DeleteParam = DeleteCircleParam;
567a3e0fd82Sopenharmony_ci    cmd.DrawGraphics = DoDrawCircle;
568a3e0fd82Sopenharmony_ci    drawCmdList_.PushBack(cmd);
569a3e0fd82Sopenharmony_ci#endif
570a3e0fd82Sopenharmony_ci    Invalidate();
571a3e0fd82Sopenharmony_ci}
572a3e0fd82Sopenharmony_ci
573a3e0fd82Sopenharmony_civoid UICanvas::DrawSector(const Point& center,
574a3e0fd82Sopenharmony_ci                          uint16_t radius,
575a3e0fd82Sopenharmony_ci                          int16_t startAngle,
576a3e0fd82Sopenharmony_ci                          int16_t endAngle,
577a3e0fd82Sopenharmony_ci                          const Paint& paint)
578a3e0fd82Sopenharmony_ci{
579a3e0fd82Sopenharmony_ci#if defined(ENABLE_CANVAS_EXTEND) && ENABLE_CANVAS_EXTEND
580a3e0fd82Sopenharmony_ci    BeginPath();
581a3e0fd82Sopenharmony_ci    MoveTo(center);
582a3e0fd82Sopenharmony_ci    ArcTo(center, radius, startAngle, endAngle);
583a3e0fd82Sopenharmony_ci    ClosePath();
584a3e0fd82Sopenharmony_ci    if (static_cast<uint8_t>(paint.GetStyle()) & Paint::PaintStyle::STROKE_STYLE) {
585a3e0fd82Sopenharmony_ci        DrawPath(paint);
586a3e0fd82Sopenharmony_ci    }
587a3e0fd82Sopenharmony_ci    if (static_cast<uint8_t>(paint.GetStyle()) & Paint::PaintStyle::FILL_STYLE) {
588a3e0fd82Sopenharmony_ci        FillPath(paint);
589a3e0fd82Sopenharmony_ci    }
590a3e0fd82Sopenharmony_ci#else
591a3e0fd82Sopenharmony_ci    if (static_cast<uint8_t>(paint.GetStyle()) & Paint::PaintStyle::FILL_STYLE) {
592a3e0fd82Sopenharmony_ci        Paint innerPaint = paint;
593a3e0fd82Sopenharmony_ci        innerPaint.SetStyle(Paint::PaintStyle::STROKE_STYLE);
594a3e0fd82Sopenharmony_ci        innerPaint.SetStrokeWidth(radius);
595a3e0fd82Sopenharmony_ci        innerPaint.SetStrokeColor(paint.GetFillColor());
596a3e0fd82Sopenharmony_ci        radius >>= 1;
597a3e0fd82Sopenharmony_ci        DrawArc(center, radius, startAngle, endAngle, innerPaint);
598a3e0fd82Sopenharmony_ci    }
599a3e0fd82Sopenharmony_ci#endif
600a3e0fd82Sopenharmony_ci}
601a3e0fd82Sopenharmony_ci
602a3e0fd82Sopenharmony_civoid UICanvas::DrawArc(const Point& center, uint16_t radius, int16_t startAngle,
603a3e0fd82Sopenharmony_ci                       int16_t endAngle, const Paint& paint)
604a3e0fd82Sopenharmony_ci{
605a3e0fd82Sopenharmony_ci    if (static_cast<uint8_t>(paint.GetStyle()) & Paint::PaintStyle::STROKE_STYLE) {
606a3e0fd82Sopenharmony_ci#if defined(ENABLE_CANVAS_EXTEND) && ENABLE_CANVAS_EXTEND
607a3e0fd82Sopenharmony_ci        if (paint.GetChangeFlag()) {
608a3e0fd82Sopenharmony_ci            ArcTo(center, radius, startAngle, endAngle);
609a3e0fd82Sopenharmony_ci            DrawPath(paint);
610a3e0fd82Sopenharmony_ci        } else
611a3e0fd82Sopenharmony_ci#endif
612a3e0fd82Sopenharmony_ci        {
613a3e0fd82Sopenharmony_ci            ArcParam* arcParam = new ArcParam;
614a3e0fd82Sopenharmony_ci            if (arcParam == nullptr) {
615a3e0fd82Sopenharmony_ci                GRAPHIC_LOGE("new ArcParam fail");
616a3e0fd82Sopenharmony_ci                return;
617a3e0fd82Sopenharmony_ci            }
618a3e0fd82Sopenharmony_ci            arcParam->center = center;
619a3e0fd82Sopenharmony_ci            arcParam->radius = radius;
620a3e0fd82Sopenharmony_ci
621a3e0fd82Sopenharmony_ci            int16_t start;
622a3e0fd82Sopenharmony_ci            int16_t end;
623a3e0fd82Sopenharmony_ci            if (startAngle > endAngle) {
624a3e0fd82Sopenharmony_ci                start = endAngle;
625a3e0fd82Sopenharmony_ci                end = startAngle;
626a3e0fd82Sopenharmony_ci            } else {
627a3e0fd82Sopenharmony_ci                start = startAngle;
628a3e0fd82Sopenharmony_ci                end = endAngle;
629a3e0fd82Sopenharmony_ci            }
630a3e0fd82Sopenharmony_ci
631a3e0fd82Sopenharmony_ci            DrawArc::GetInstance()->GetDrawRange(start, end);
632a3e0fd82Sopenharmony_ci            arcParam->startAngle = start;
633a3e0fd82Sopenharmony_ci            arcParam->endAngle = end;
634a3e0fd82Sopenharmony_ci
635a3e0fd82Sopenharmony_ci            DrawCmd cmd;
636a3e0fd82Sopenharmony_ci            cmd.paint = paint;
637a3e0fd82Sopenharmony_ci            cmd.param = arcParam;
638a3e0fd82Sopenharmony_ci            cmd.DeleteParam = DeleteArcParam;
639a3e0fd82Sopenharmony_ci            cmd.DrawGraphics = DoDrawArc;
640a3e0fd82Sopenharmony_ci            drawCmdList_.PushBack(cmd);
641a3e0fd82Sopenharmony_ci        }
642a3e0fd82Sopenharmony_ci        Invalidate();
643a3e0fd82Sopenharmony_ci    }
644a3e0fd82Sopenharmony_ci}
645a3e0fd82Sopenharmony_ci
646a3e0fd82Sopenharmony_civoid UICanvas::DrawLabel(const Point& startPoint,
647a3e0fd82Sopenharmony_ci                         const char* text,
648a3e0fd82Sopenharmony_ci                         uint16_t maxWidth,
649a3e0fd82Sopenharmony_ci                         const FontStyle& fontStyle,
650a3e0fd82Sopenharmony_ci                         const Paint& paint)
651a3e0fd82Sopenharmony_ci{
652a3e0fd82Sopenharmony_ci    if (text == nullptr) {
653a3e0fd82Sopenharmony_ci        return;
654a3e0fd82Sopenharmony_ci    }
655a3e0fd82Sopenharmony_ci    if (static_cast<uint8_t>(paint.GetStyle()) & Paint::PaintStyle::FILL_STYLE) {
656a3e0fd82Sopenharmony_ci        UILabel* label = new UILabel();
657a3e0fd82Sopenharmony_ci        if (label == nullptr) {
658a3e0fd82Sopenharmony_ci            GRAPHIC_LOGE("new UILabel fail");
659a3e0fd82Sopenharmony_ci            return;
660a3e0fd82Sopenharmony_ci        }
661a3e0fd82Sopenharmony_ci        label->SetLineBreakMode(UILabel::LINE_BREAK_CLIP);
662a3e0fd82Sopenharmony_ci        label->SetPosition(startPoint.x, startPoint.y);
663a3e0fd82Sopenharmony_ci        label->SetWidth(maxWidth);
664a3e0fd82Sopenharmony_ci        label->SetHeight(GetHeight());
665a3e0fd82Sopenharmony_ci        label->SetText(text);
666a3e0fd82Sopenharmony_ci        label->SetFont(fontStyle.fontName, fontStyle.fontSize);
667a3e0fd82Sopenharmony_ci        label->SetAlign(fontStyle.align);
668a3e0fd82Sopenharmony_ci        label->SetDirect(fontStyle.direct);
669a3e0fd82Sopenharmony_ci        label->SetStyle(STYLE_LETTER_SPACE, fontStyle.letterSpace);
670a3e0fd82Sopenharmony_ci        label->SetStyle(STYLE_TEXT_COLOR, paint.GetFillColor().full);
671a3e0fd82Sopenharmony_ci        label->SetStyle(STYLE_TEXT_OPA, paint.GetOpacity());
672a3e0fd82Sopenharmony_ci
673a3e0fd82Sopenharmony_ci        DrawCmd cmd;
674a3e0fd82Sopenharmony_ci        cmd.param = label;
675a3e0fd82Sopenharmony_ci        cmd.DeleteParam = DeleteLabel;
676a3e0fd82Sopenharmony_ci        cmd.DrawGraphics = DoDrawLabel;
677a3e0fd82Sopenharmony_ci        drawCmdList_.PushBack(cmd);
678a3e0fd82Sopenharmony_ci
679a3e0fd82Sopenharmony_ci        Invalidate();
680a3e0fd82Sopenharmony_ci    }
681a3e0fd82Sopenharmony_ci}
682a3e0fd82Sopenharmony_ci#if defined(GRAPHIC_ENABLE_DRAW_IMAGE_FLAG) && GRAPHIC_ENABLE_DRAW_IMAGE_FLAG
683a3e0fd82Sopenharmony_civoid UICanvas::DrawImage(const Point &startPoint, const char* image, const Paint& paint)
684a3e0fd82Sopenharmony_ci{
685a3e0fd82Sopenharmony_ci    if (image == nullptr) {
686a3e0fd82Sopenharmony_ci        return;
687a3e0fd82Sopenharmony_ci    }
688a3e0fd82Sopenharmony_ci    if (static_cast<uint8_t>(paint.GetStyle()) & Paint::PaintStyle::FILL_STYLE) {
689a3e0fd82Sopenharmony_ci        UIExtendImageView* imageView = new UIExtendImageView();
690a3e0fd82Sopenharmony_ci        if (imageView == nullptr) {
691a3e0fd82Sopenharmony_ci            GRAPHIC_LOGE("new UIImageView fail");
692a3e0fd82Sopenharmony_ci            return;
693a3e0fd82Sopenharmony_ci        }
694a3e0fd82Sopenharmony_ci        imageView->SetCanvas(this);
695a3e0fd82Sopenharmony_ci        imageView->SetPosition(startPoint.x, startPoint.y);
696a3e0fd82Sopenharmony_ci        imageView->SetSrc(image);
697a3e0fd82Sopenharmony_ci
698a3e0fd82Sopenharmony_ci        DrawCmd cmd;
699a3e0fd82Sopenharmony_ci        cmd.paint = paint;
700a3e0fd82Sopenharmony_ci        cmd.param = imageView;
701a3e0fd82Sopenharmony_ci        cmd.DeleteParam = DeleteImageView;
702a3e0fd82Sopenharmony_ci        cmd.DrawGraphics = DoDrawImage;
703a3e0fd82Sopenharmony_ci        drawCmdList_.PushBack(cmd);
704a3e0fd82Sopenharmony_ci
705a3e0fd82Sopenharmony_ci        Invalidate();
706a3e0fd82Sopenharmony_ci        SetStartPosition(startPoint);
707a3e0fd82Sopenharmony_ci    }
708a3e0fd82Sopenharmony_ci}
709a3e0fd82Sopenharmony_ci
710a3e0fd82Sopenharmony_civoid UICanvas::DrawImage(const Point& startPoint, const char* image,
711a3e0fd82Sopenharmony_ci                         const Paint& paint, int16_t width, int16_t height)
712a3e0fd82Sopenharmony_ci{
713a3e0fd82Sopenharmony_ci    if (image == nullptr) {
714a3e0fd82Sopenharmony_ci        return;
715a3e0fd82Sopenharmony_ci    }
716a3e0fd82Sopenharmony_ci    if (static_cast<uint8_t>(paint.GetStyle()) & Paint::PaintStyle::FILL_STYLE) {
717a3e0fd82Sopenharmony_ci        UIExtendImageView* imageView = new UIExtendImageView();
718a3e0fd82Sopenharmony_ci        if (imageView == nullptr) {
719a3e0fd82Sopenharmony_ci            GRAPHIC_LOGE("new UIImageView fail");
720a3e0fd82Sopenharmony_ci            return;
721a3e0fd82Sopenharmony_ci        }
722a3e0fd82Sopenharmony_ci        imageView->SetCanvas(this);
723a3e0fd82Sopenharmony_ci        imageView->SetPosition(startPoint.x, startPoint.y);
724a3e0fd82Sopenharmony_ci        imageView->SetSrc(image);
725a3e0fd82Sopenharmony_ci        float scaleX = 1.0;
726a3e0fd82Sopenharmony_ci        float scaleY = 1.0;
727a3e0fd82Sopenharmony_ci        if (width > 0 && imageView->GetWidth() > 0) {
728a3e0fd82Sopenharmony_ci            scaleX = (float)width / (float)imageView->GetWidth();
729a3e0fd82Sopenharmony_ci        }
730a3e0fd82Sopenharmony_ci        if (height > 0 && imageView->GetHeight() > 0) {
731a3e0fd82Sopenharmony_ci            scaleY = (float)height / (float)imageView->GetHeight();
732a3e0fd82Sopenharmony_ci        }
733a3e0fd82Sopenharmony_ci        DrawCmd cmd;
734a3e0fd82Sopenharmony_ci        cmd.paint = paint;
735a3e0fd82Sopenharmony_ci        cmd.paint.Scale(scaleX, scaleY);
736a3e0fd82Sopenharmony_ci        cmd.param = imageView;
737a3e0fd82Sopenharmony_ci        cmd.DeleteParam = DeleteImageView;
738a3e0fd82Sopenharmony_ci        cmd.DrawGraphics = DoDrawImage;
739a3e0fd82Sopenharmony_ci        drawCmdList_.PushBack(cmd);
740a3e0fd82Sopenharmony_ci
741a3e0fd82Sopenharmony_ci        Invalidate();
742a3e0fd82Sopenharmony_ci        SetStartPosition(startPoint);
743a3e0fd82Sopenharmony_ci    }
744a3e0fd82Sopenharmony_ci
745a3e0fd82Sopenharmony_ci    Invalidate();
746a3e0fd82Sopenharmony_ci    SetStartPosition(startPoint);
747a3e0fd82Sopenharmony_ci}
748a3e0fd82Sopenharmony_ci#endif
749a3e0fd82Sopenharmony_ci
750a3e0fd82Sopenharmony_ci#if defined(ENABLE_CANVAS_EXTEND) && ENABLE_CANVAS_EXTEND
751a3e0fd82Sopenharmony_ci#if defined(GRAPHIC_ENABLE_PATTERN_FILL_FLAG) && GRAPHIC_ENABLE_PATTERN_FILL_FLAG
752a3e0fd82Sopenharmony_civoid SetImageParamInfo(ImageParam* imageParam, const Paint& paint, PathParam* pathParam)
753a3e0fd82Sopenharmony_ci{
754a3e0fd82Sopenharmony_ci    imageParam->image->SetSrc(paint.GetPatternImage());
755a3e0fd82Sopenharmony_ci    ImageHeader header = {0};
756a3e0fd82Sopenharmony_ci    imageParam->image->GetHeader(header);
757a3e0fd82Sopenharmony_ci    imageParam->start = {0, 0};
758a3e0fd82Sopenharmony_ci    imageParam->height = header.height;
759a3e0fd82Sopenharmony_ci    imageParam->width = header.width;
760a3e0fd82Sopenharmony_ci
761a3e0fd82Sopenharmony_ci    pathParam->imageParam = imageParam;
762a3e0fd82Sopenharmony_ci}
763a3e0fd82Sopenharmony_ci#endif
764a3e0fd82Sopenharmony_ci#endif
765a3e0fd82Sopenharmony_ci
766a3e0fd82Sopenharmony_civoid UICanvas::DrawPath(const Paint& paint)
767a3e0fd82Sopenharmony_ci{
768a3e0fd82Sopenharmony_ci#if defined(ENABLE_CANVAS_EXTEND) && ENABLE_CANVAS_EXTEND
769a3e0fd82Sopenharmony_ci    if (vertices_ == nullptr) {
770a3e0fd82Sopenharmony_ci        return;
771a3e0fd82Sopenharmony_ci    }
772a3e0fd82Sopenharmony_ci
773a3e0fd82Sopenharmony_ci    PathParam* pathParam = new PathParam;
774a3e0fd82Sopenharmony_ci    if (pathParam == nullptr) {
775a3e0fd82Sopenharmony_ci        GRAPHIC_LOGE("new LineParam fail");
776a3e0fd82Sopenharmony_ci        return;
777a3e0fd82Sopenharmony_ci    }
778a3e0fd82Sopenharmony_ci
779a3e0fd82Sopenharmony_ci    pathParam->vertices = vertices_;
780a3e0fd82Sopenharmony_ci    pathParam->isStroke = true;
781a3e0fd82Sopenharmony_ci#if defined(GRAPHIC_ENABLE_PATTERN_FILL_FLAG) && GRAPHIC_ENABLE_PATTERN_FILL_FLAG
782a3e0fd82Sopenharmony_ci    if (paint.GetStyle() == Paint::PATTERN) {
783a3e0fd82Sopenharmony_ci        ImageParam* imageParam = new ImageParam;
784a3e0fd82Sopenharmony_ci        if (imageParam == nullptr) {
785a3e0fd82Sopenharmony_ci            GRAPHIC_LOGE("new ImageParam fail");
786a3e0fd82Sopenharmony_ci            return;
787a3e0fd82Sopenharmony_ci        }
788a3e0fd82Sopenharmony_ci
789a3e0fd82Sopenharmony_ci        imageParam->image = new Image();
790a3e0fd82Sopenharmony_ci        if (imageParam->image == nullptr) {
791a3e0fd82Sopenharmony_ci            delete imageParam;
792a3e0fd82Sopenharmony_ci            imageParam = nullptr;
793a3e0fd82Sopenharmony_ci            return;
794a3e0fd82Sopenharmony_ci        }
795a3e0fd82Sopenharmony_ci
796a3e0fd82Sopenharmony_ci        SetImageParamInfo(imageParam, paint, pathParam);
797a3e0fd82Sopenharmony_ci    }
798a3e0fd82Sopenharmony_ci#endif
799a3e0fd82Sopenharmony_ci#else
800a3e0fd82Sopenharmony_ci    if ((path_ == nullptr) || (path_->cmd_.Size() == 0)) {
801a3e0fd82Sopenharmony_ci        return;
802a3e0fd82Sopenharmony_ci    }
803a3e0fd82Sopenharmony_ci
804a3e0fd82Sopenharmony_ci    path_->strokeCount_++;
805a3e0fd82Sopenharmony_ci    PathParam* pathParam = new PathParam;
806a3e0fd82Sopenharmony_ci    if (pathParam == nullptr) {
807a3e0fd82Sopenharmony_ci        GRAPHIC_LOGE("new PathParam fail");
808a3e0fd82Sopenharmony_ci        return;
809a3e0fd82Sopenharmony_ci    }
810a3e0fd82Sopenharmony_ci    pathParam->path = path_;
811a3e0fd82Sopenharmony_ci    pathParam->count = path_->cmd_.Size();
812a3e0fd82Sopenharmony_ci#endif
813a3e0fd82Sopenharmony_ci    DrawCmd cmd;
814a3e0fd82Sopenharmony_ci    cmd.paint = paint;
815a3e0fd82Sopenharmony_ci    cmd.param = pathParam;
816a3e0fd82Sopenharmony_ci    cmd.DeleteParam = DeletePathParam;
817a3e0fd82Sopenharmony_ci    cmd.DrawGraphics = DoDrawPath;
818a3e0fd82Sopenharmony_ci    drawCmdList_.PushBack(cmd);
819a3e0fd82Sopenharmony_ci    Invalidate();
820a3e0fd82Sopenharmony_ci}
821a3e0fd82Sopenharmony_ci
822a3e0fd82Sopenharmony_ci#if defined(ENABLE_CANVAS_EXTEND) && ENABLE_CANVAS_EXTEND
823a3e0fd82Sopenharmony_civoid UICanvas::FillPath(const Paint& paint)
824a3e0fd82Sopenharmony_ci{
825a3e0fd82Sopenharmony_ci    if (vertices_ == nullptr) {
826a3e0fd82Sopenharmony_ci        return;
827a3e0fd82Sopenharmony_ci    }
828a3e0fd82Sopenharmony_ci
829a3e0fd82Sopenharmony_ci    PathParam* pathParam = new PathParam;
830a3e0fd82Sopenharmony_ci    if (pathParam == nullptr) {
831a3e0fd82Sopenharmony_ci        GRAPHIC_LOGE("new LineParam fail");
832a3e0fd82Sopenharmony_ci        return;
833a3e0fd82Sopenharmony_ci    }
834a3e0fd82Sopenharmony_ci
835a3e0fd82Sopenharmony_ci    pathParam->vertices = vertices_;
836a3e0fd82Sopenharmony_ci    pathParam->isStroke = false;
837a3e0fd82Sopenharmony_ci#if defined(GRAPHIC_ENABLE_PATTERN_FILL_FLAG) && GRAPHIC_ENABLE_PATTERN_FILL_FLAG
838a3e0fd82Sopenharmony_ci    if (paint.GetStyle() == Paint::PATTERN) {
839a3e0fd82Sopenharmony_ci        ImageParam* imageParam = new ImageParam;
840a3e0fd82Sopenharmony_ci        if (imageParam == nullptr) {
841a3e0fd82Sopenharmony_ci            GRAPHIC_LOGE("new ImageParam fail");
842a3e0fd82Sopenharmony_ci            return;
843a3e0fd82Sopenharmony_ci        }
844a3e0fd82Sopenharmony_ci
845a3e0fd82Sopenharmony_ci        imageParam->image = new Image();
846a3e0fd82Sopenharmony_ci        if (imageParam->image == nullptr) {
847a3e0fd82Sopenharmony_ci            delete imageParam;
848a3e0fd82Sopenharmony_ci            imageParam = nullptr;
849a3e0fd82Sopenharmony_ci            return;
850a3e0fd82Sopenharmony_ci        }
851a3e0fd82Sopenharmony_ci
852a3e0fd82Sopenharmony_ci        SetImageParamInfo(imageParam, paint, pathParam);
853a3e0fd82Sopenharmony_ci    }
854a3e0fd82Sopenharmony_ci#endif
855a3e0fd82Sopenharmony_ci    DrawCmd cmd;
856a3e0fd82Sopenharmony_ci    cmd.paint = paint;
857a3e0fd82Sopenharmony_ci    cmd.param = pathParam;
858a3e0fd82Sopenharmony_ci    cmd.DeleteParam = DeletePathParam;
859a3e0fd82Sopenharmony_ci    cmd.DrawGraphics = DoFillPath;
860a3e0fd82Sopenharmony_ci    drawCmdList_.PushBack(cmd);
861a3e0fd82Sopenharmony_ci    Invalidate();
862a3e0fd82Sopenharmony_ci}
863a3e0fd82Sopenharmony_ci#endif
864a3e0fd82Sopenharmony_ci
865a3e0fd82Sopenharmony_civoid UICanvas::OnDraw(BufferInfo& gfxDstBuffer, const Rect& invalidatedArea)
866a3e0fd82Sopenharmony_ci{
867a3e0fd82Sopenharmony_ci    Rect rect = GetOrigRect();
868a3e0fd82Sopenharmony_ci    BaseGfxEngine::GetInstance()->DrawRect(gfxDstBuffer, rect, invalidatedArea, *style_, opaScale_);
869a3e0fd82Sopenharmony_ci
870a3e0fd82Sopenharmony_ci    void* param = nullptr;
871a3e0fd82Sopenharmony_ci    ListNode<DrawCmd>* curDraw = drawCmdList_.Begin();
872a3e0fd82Sopenharmony_ci    Rect coords = GetOrigRect();
873a3e0fd82Sopenharmony_ci    Rect trunc = invalidatedArea;
874a3e0fd82Sopenharmony_ci    if (!trunc.Intersect(trunc, coords)) {
875a3e0fd82Sopenharmony_ci        return;
876a3e0fd82Sopenharmony_ci    }
877a3e0fd82Sopenharmony_ci#if defined(ENABLE_CANVAS_EXTEND) && ENABLE_CANVAS_EXTEND
878a3e0fd82Sopenharmony_ci    bool haveComposite = false;
879a3e0fd82Sopenharmony_ci    for (; curDraw != drawCmdList_.End(); curDraw = curDraw->next_) {
880a3e0fd82Sopenharmony_ci        if (curDraw->data_.paint.HaveComposite()) {
881a3e0fd82Sopenharmony_ci            haveComposite = true;
882a3e0fd82Sopenharmony_ci            break;
883a3e0fd82Sopenharmony_ci        }
884a3e0fd82Sopenharmony_ci    }
885a3e0fd82Sopenharmony_ci
886a3e0fd82Sopenharmony_ci    if (haveComposite) {
887a3e0fd82Sopenharmony_ci        OnBlendDraw(gfxDstBuffer, trunc);
888a3e0fd82Sopenharmony_ci    } else
889a3e0fd82Sopenharmony_ci#endif
890a3e0fd82Sopenharmony_ci    {
891a3e0fd82Sopenharmony_ci        curDraw = drawCmdList_.Begin();
892a3e0fd82Sopenharmony_ci        for (; curDraw != drawCmdList_.End(); curDraw = curDraw->next_) {
893a3e0fd82Sopenharmony_ci            param = curDraw->data_.param;
894a3e0fd82Sopenharmony_ci            curDraw->data_.DrawGraphics(gfxDstBuffer, param, curDraw->data_.paint, rect, trunc, *style_);
895a3e0fd82Sopenharmony_ci        }
896a3e0fd82Sopenharmony_ci    }
897a3e0fd82Sopenharmony_ci}
898a3e0fd82Sopenharmony_ci
899a3e0fd82Sopenharmony_ci#if defined(ENABLE_CANVAS_EXTEND) && ENABLE_CANVAS_EXTEND
900a3e0fd82Sopenharmony_civoid OnBlendDrawPattern(ListNode<UICanvas::DrawCmd>* curDraw,
901a3e0fd82Sopenharmony_ci                        UICanvas::DrawCmd& drawCmd,
902a3e0fd82Sopenharmony_ci                        Rect& rect,
903a3e0fd82Sopenharmony_ci                        const Rect& trunc,
904a3e0fd82Sopenharmony_ci                        RasterizerScanlineAntialias& blendRasterizer,
905a3e0fd82Sopenharmony_ci                        RasterizerScanlineAntialias& rasterizer,
906a3e0fd82Sopenharmony_ci                        RenderBase& renBase,
907a3e0fd82Sopenharmony_ci                        TransAffine& transform,
908a3e0fd82Sopenharmony_ci                        PathParam* pathParamBlend)
909a3e0fd82Sopenharmony_ci{
910a3e0fd82Sopenharmony_ci#if defined(GRAPHIC_ENABLE_PATTERN_FILL_FLAG) && GRAPHIC_ENABLE_PATTERN_FILL_FLAG
911a3e0fd82Sopenharmony_ci    if (curDraw->data_.paint.GetStyle() == Paint::PATTERN) {
912a3e0fd82Sopenharmony_ci        if (curDraw->data_.param == nullptr) {
913a3e0fd82Sopenharmony_ci            return;
914a3e0fd82Sopenharmony_ci        }
915a3e0fd82Sopenharmony_ci        PathParam* pathParam = static_cast<PathParam*>(curDraw->data_.param);
916a3e0fd82Sopenharmony_ci        ImageParam* imageParam = static_cast<ImageParam*>(pathParam->imageParam);
917a3e0fd82Sopenharmony_ci        if (imageParam->image == nullptr) {
918a3e0fd82Sopenharmony_ci            return;
919a3e0fd82Sopenharmony_ci        }
920a3e0fd82Sopenharmony_ci        FillPatternRgba spanPattern(imageParam->image->GetImageInfo(), curDraw->data_.paint.GetPatternRepeatMode(),
921a3e0fd82Sopenharmony_ci                                    rect.GetLeft(), rect.GetTop());
922a3e0fd82Sopenharmony_ci        UICanvas::BlendRaster(drawCmd.paint, drawCmd.param, blendRasterizer, rasterizer, renBase, transform,
923a3e0fd82Sopenharmony_ci                              spanPattern, trunc, pathParamBlend->isStroke);
924a3e0fd82Sopenharmony_ci    }
925a3e0fd82Sopenharmony_ci#endif
926a3e0fd82Sopenharmony_ci}
927a3e0fd82Sopenharmony_ci
928a3e0fd82Sopenharmony_civoid OnBlendDrawGradient(ListNode<UICanvas::DrawCmd>* curDraw,
929a3e0fd82Sopenharmony_ci                         UICanvas::DrawCmd& drawCmd,
930a3e0fd82Sopenharmony_ci                         const Rect& trunc,
931a3e0fd82Sopenharmony_ci                         RasterizerScanlineAntialias& blendRasterizer,
932a3e0fd82Sopenharmony_ci                         RasterizerScanlineAntialias& rasterizer,
933a3e0fd82Sopenharmony_ci                         RenderBase& renBase,
934a3e0fd82Sopenharmony_ci                         TransAffine& transform,
935a3e0fd82Sopenharmony_ci                         PathParam* pathParamBlend)
936a3e0fd82Sopenharmony_ci{
937a3e0fd82Sopenharmony_ci#if defined(GRAPHIC_ENABLE_GRADIENT_FILL_FLAG) && GRAPHIC_ENABLE_GRADIENT_FILL_FLAG
938a3e0fd82Sopenharmony_ci    if (curDraw->data_.paint.GetStyle() == Paint::GRADIENT) {
939a3e0fd82Sopenharmony_ci        TransAffine gradientMatrix;
940a3e0fd82Sopenharmony_ci        FillInterpolator interpolatorType(gradientMatrix);
941a3e0fd82Sopenharmony_ci        FillGradientLut gradientColorMode;
942a3e0fd82Sopenharmony_ci        DrawCanvas::BuildGradientColor(curDraw->data_.paint, gradientColorMode);
943a3e0fd82Sopenharmony_ci        if (curDraw->data_.paint.GetGradient() == Paint::Linear) {
944a3e0fd82Sopenharmony_ci            float distance = 0;
945a3e0fd82Sopenharmony_ci            DrawCanvas::BuildLineGradientMatrix(drawCmd.paint, gradientMatrix, transform, distance);
946a3e0fd82Sopenharmony_ci            GradientLinearCalculate gradientLinearCalculate;
947a3e0fd82Sopenharmony_ci            FillGradient span(interpolatorType, gradientLinearCalculate, gradientColorMode, 0, distance);
948a3e0fd82Sopenharmony_ci            UICanvas::BlendRaster(drawCmd.paint, drawCmd.param, blendRasterizer, rasterizer, renBase,
949a3e0fd82Sopenharmony_ci                                  transform, span, trunc, pathParamBlend->isStroke);
950a3e0fd82Sopenharmony_ci        }
951a3e0fd82Sopenharmony_ci        if (curDraw->data_.paint.GetGradient() == Paint::Radial) {
952a3e0fd82Sopenharmony_ci            Paint::RadialGradientPoint radialPoint = drawCmd.paint.GetRadialGradientPoint();
953a3e0fd82Sopenharmony_ci            float startRadius = 0;
954a3e0fd82Sopenharmony_ci            float endRadius = 0;
955a3e0fd82Sopenharmony_ci            DrawCanvas::BuildRadialGradientMatrix(drawCmd.paint, gradientMatrix, transform, startRadius, endRadius);
956a3e0fd82Sopenharmony_ci            GradientRadialCalculate gradientRadialCalculate(endRadius, radialPoint.x0 - radialPoint.x1,
957a3e0fd82Sopenharmony_ci                                                            radialPoint.y0 - radialPoint.y1);
958a3e0fd82Sopenharmony_ci            FillGradient span(interpolatorType, gradientRadialCalculate, gradientColorMode, startRadius, endRadius);
959a3e0fd82Sopenharmony_ci            UICanvas::BlendRaster(drawCmd.paint, drawCmd.param, blendRasterizer, rasterizer, renBase,
960a3e0fd82Sopenharmony_ci                                  transform, span, trunc, pathParamBlend->isStroke);
961a3e0fd82Sopenharmony_ci        }
962a3e0fd82Sopenharmony_ci    }
963a3e0fd82Sopenharmony_ci#endif
964a3e0fd82Sopenharmony_ci}
965a3e0fd82Sopenharmony_ci
966a3e0fd82Sopenharmony_civoid UICanvas::OnBlendDraw(BufferInfo& gfxDstBuffer, const Rect& trunc)
967a3e0fd82Sopenharmony_ci{
968a3e0fd82Sopenharmony_ci    Rect rect = GetOrigRect();
969a3e0fd82Sopenharmony_ci    RenderBuffer renderBuffer;
970a3e0fd82Sopenharmony_ci    TransAffine transform;
971a3e0fd82Sopenharmony_ci    ListNode<DrawCmd>* curDrawEnd = drawCmdList_.Begin();
972a3e0fd82Sopenharmony_ci    RasterizerScanlineAntialias blendRasterizer;
973a3e0fd82Sopenharmony_ci    DrawCmd drawCmd;
974a3e0fd82Sopenharmony_ci    int count = 0;
975a3e0fd82Sopenharmony_ci    for (; curDrawEnd != drawCmdList_.End(); curDrawEnd = curDrawEnd->next_) {
976a3e0fd82Sopenharmony_ci        if (curDrawEnd->data_.paint.HaveComposite()) {
977a3e0fd82Sopenharmony_ci            drawCmd = curDrawEnd->data_;
978a3e0fd82Sopenharmony_ci            count++;
979a3e0fd82Sopenharmony_ci        }
980a3e0fd82Sopenharmony_ci    }
981a3e0fd82Sopenharmony_ci    if (drawCmd.param == nullptr) {
982a3e0fd82Sopenharmony_ci        return;
983a3e0fd82Sopenharmony_ci    }
984a3e0fd82Sopenharmony_ci    PathParam* pathParamBlend = static_cast<PathParam*>(drawCmd.param);
985a3e0fd82Sopenharmony_ci    ListNode<DrawCmd>* curDraw = drawCmdList_.Begin();
986a3e0fd82Sopenharmony_ci    DrawCanvas::InitRenderAndTransform(gfxDstBuffer, renderBuffer, rect, transform, *style_, curDraw->data_.paint);
987a3e0fd82Sopenharmony_ci    DrawCanvas::SetRasterizer(*pathParamBlend->vertices, drawCmd.paint, blendRasterizer, transform,
988a3e0fd82Sopenharmony_ci                              pathParamBlend->isStroke);
989a3e0fd82Sopenharmony_ci    RasterizerScanlineAntialias scanline;
990a3e0fd82Sopenharmony_ci    RenderPixfmtRgbaBlend pixFormat(renderBuffer);
991a3e0fd82Sopenharmony_ci    RenderBase renBase(pixFormat);
992a3e0fd82Sopenharmony_ci    renBase.ResetClipping(true);
993a3e0fd82Sopenharmony_ci    renBase.ClipBox(trunc.GetLeft(), trunc.GetTop(), trunc.GetRight(), trunc.GetBottom());
994a3e0fd82Sopenharmony_ci    for (; curDraw != drawCmdList_.End(); curDraw = curDraw->next_) {
995a3e0fd82Sopenharmony_ci        if (curDraw->data_.paint.HaveComposite()) {
996a3e0fd82Sopenharmony_ci            drawCmd = curDraw->data_;
997a3e0fd82Sopenharmony_ci            count--;
998a3e0fd82Sopenharmony_ci        }
999a3e0fd82Sopenharmony_ci        if (count <= 0) {
1000a3e0fd82Sopenharmony_ci            continue;
1001a3e0fd82Sopenharmony_ci        }
1002a3e0fd82Sopenharmony_ci        RasterizerScanlineAntialias rasterizer;
1003a3e0fd82Sopenharmony_ci        if (curDraw->data_.param == nullptr) {
1004a3e0fd82Sopenharmony_ci            continue;
1005a3e0fd82Sopenharmony_ci        }
1006a3e0fd82Sopenharmony_ci        PathParam* pathParam = static_cast<PathParam*>(curDraw->data_.param);
1007a3e0fd82Sopenharmony_ci#if defined(GRAPHIC_ENABLE_BLUR_EFFECT_FLAG) && GRAPHIC_ENABLE_BLUR_EFFECT_FLAG
1008a3e0fd82Sopenharmony_ci        if (curDraw->data_.paint.HaveShadow()) {
1009a3e0fd82Sopenharmony_ci            DrawCanvas::DoDrawShadow(gfxDstBuffer, curDraw->data_.param, curDraw->data_.paint, rect, trunc, *style_,
1010a3e0fd82Sopenharmony_ci                                     pathParam->isStroke);
1011a3e0fd82Sopenharmony_ci        }
1012a3e0fd82Sopenharmony_ci#endif
1013a3e0fd82Sopenharmony_ci        DrawCanvas::InitRenderAndTransform(gfxDstBuffer, renderBuffer, rect, transform, *style_, curDraw->data_.paint);
1014a3e0fd82Sopenharmony_ci        rasterizer.ClipBox(0, 0, gfxDstBuffer.width, gfxDstBuffer.height);
1015a3e0fd82Sopenharmony_ci        DrawCanvas::SetRasterizer(*pathParam->vertices, curDraw->data_.paint, rasterizer, transform,
1016a3e0fd82Sopenharmony_ci                                  pathParam->isStroke);
1017a3e0fd82Sopenharmony_ci        if (IsSoild(curDraw->data_.paint)) {
1018a3e0fd82Sopenharmony_ci            Rgba8T color;
1019a3e0fd82Sopenharmony_ci            DrawCanvas::RenderBlendSolid(curDraw->data_.paint, color, pathParam->isStroke);
1020a3e0fd82Sopenharmony_ci            SpanSoildColor spanSoildColor(color);
1021a3e0fd82Sopenharmony_ci            BlendRaster(drawCmd.paint, drawCmd.param, blendRasterizer, rasterizer, renBase, transform,
1022a3e0fd82Sopenharmony_ci                        spanSoildColor, rect, pathParamBlend->isStroke);
1023a3e0fd82Sopenharmony_ci        }
1024a3e0fd82Sopenharmony_ci
1025a3e0fd82Sopenharmony_ci        OnBlendDrawGradient(curDraw, drawCmd, trunc, blendRasterizer,
1026a3e0fd82Sopenharmony_ci                            rasterizer, renBase, transform, pathParamBlend);
1027a3e0fd82Sopenharmony_ci
1028a3e0fd82Sopenharmony_ci        OnBlendDrawPattern(curDraw, drawCmd, rect, trunc, blendRasterizer,
1029a3e0fd82Sopenharmony_ci                           rasterizer, renBase, transform, pathParamBlend);
1030a3e0fd82Sopenharmony_ci    }
1031a3e0fd82Sopenharmony_ci}
1032a3e0fd82Sopenharmony_ci#endif
1033a3e0fd82Sopenharmony_ci
1034a3e0fd82Sopenharmony_civoid UICanvas::GetAbsolutePosition(const Point& prePoint, const Rect& rect, const Style& style, Point& point)
1035a3e0fd82Sopenharmony_ci{
1036a3e0fd82Sopenharmony_ci    point.x = prePoint.x + rect.GetLeft() + style.paddingLeft_ + style.borderWidth_;
1037a3e0fd82Sopenharmony_ci    point.y = prePoint.y + rect.GetTop() + style.paddingTop_ + style.borderWidth_;
1038a3e0fd82Sopenharmony_ci}
1039a3e0fd82Sopenharmony_ci
1040a3e0fd82Sopenharmony_civoid UICanvas::DoDrawLine(BufferInfo& gfxDstBuffer,
1041a3e0fd82Sopenharmony_ci                          void* param,
1042a3e0fd82Sopenharmony_ci                          const Paint& paint,
1043a3e0fd82Sopenharmony_ci                          const Rect& rect,
1044a3e0fd82Sopenharmony_ci                          const Rect& invalidatedArea,
1045a3e0fd82Sopenharmony_ci                          const Style& style)
1046a3e0fd82Sopenharmony_ci{
1047a3e0fd82Sopenharmony_ci    if (param == nullptr) {
1048a3e0fd82Sopenharmony_ci        return;
1049a3e0fd82Sopenharmony_ci    }
1050a3e0fd82Sopenharmony_ci    LineParam* lineParam = static_cast<LineParam*>(param);
1051a3e0fd82Sopenharmony_ci    Point start;
1052a3e0fd82Sopenharmony_ci    Point end;
1053a3e0fd82Sopenharmony_ci    GetAbsolutePosition(lineParam->start, rect, style, start);
1054a3e0fd82Sopenharmony_ci    GetAbsolutePosition(lineParam->end, rect, style, end);
1055a3e0fd82Sopenharmony_ci
1056a3e0fd82Sopenharmony_ci    BaseGfxEngine::GetInstance()->DrawLine(gfxDstBuffer, start, end, invalidatedArea, paint.GetStrokeWidth(),
1057a3e0fd82Sopenharmony_ci                                           paint.GetStrokeColor(), paint.GetOpacity());
1058a3e0fd82Sopenharmony_ci}
1059a3e0fd82Sopenharmony_ci
1060a3e0fd82Sopenharmony_civoid UICanvas::DoDrawCurve(BufferInfo& gfxDstBuffer,
1061a3e0fd82Sopenharmony_ci                           void* param,
1062a3e0fd82Sopenharmony_ci                           const Paint& paint,
1063a3e0fd82Sopenharmony_ci                           const Rect& rect,
1064a3e0fd82Sopenharmony_ci                           const Rect& invalidatedArea,
1065a3e0fd82Sopenharmony_ci                           const Style& style)
1066a3e0fd82Sopenharmony_ci{
1067a3e0fd82Sopenharmony_ci    if (param == nullptr) {
1068a3e0fd82Sopenharmony_ci        return;
1069a3e0fd82Sopenharmony_ci    }
1070a3e0fd82Sopenharmony_ci    CurveParam* curveParam = static_cast<CurveParam*>(param);
1071a3e0fd82Sopenharmony_ci    Point start;
1072a3e0fd82Sopenharmony_ci    Point end;
1073a3e0fd82Sopenharmony_ci    Point control1;
1074a3e0fd82Sopenharmony_ci    Point control2;
1075a3e0fd82Sopenharmony_ci    GetAbsolutePosition(curveParam->start, rect, style, start);
1076a3e0fd82Sopenharmony_ci    GetAbsolutePosition(curveParam->end, rect, style, end);
1077a3e0fd82Sopenharmony_ci    GetAbsolutePosition(curveParam->control1, rect, style, control1);
1078a3e0fd82Sopenharmony_ci    GetAbsolutePosition(curveParam->control2, rect, style, control2);
1079a3e0fd82Sopenharmony_ci
1080a3e0fd82Sopenharmony_ci    BaseGfxEngine::GetInstance()->DrawCubicBezier(gfxDstBuffer,
1081a3e0fd82Sopenharmony_ci                                                  start,
1082a3e0fd82Sopenharmony_ci                                                  control1,
1083a3e0fd82Sopenharmony_ci                                                  control2,
1084a3e0fd82Sopenharmony_ci                                                  end,
1085a3e0fd82Sopenharmony_ci                                                  invalidatedArea,
1086a3e0fd82Sopenharmony_ci                                                  paint.GetStrokeWidth(),
1087a3e0fd82Sopenharmony_ci                                                  paint.GetStrokeColor(),
1088a3e0fd82Sopenharmony_ci                                                  paint.GetOpacity());
1089a3e0fd82Sopenharmony_ci}
1090a3e0fd82Sopenharmony_ci
1091a3e0fd82Sopenharmony_civoid UICanvas::DoDrawRect(BufferInfo& gfxDstBuffer,
1092a3e0fd82Sopenharmony_ci                          void* param,
1093a3e0fd82Sopenharmony_ci                          const Paint& paint,
1094a3e0fd82Sopenharmony_ci                          const Rect& rect,
1095a3e0fd82Sopenharmony_ci                          const Rect& invalidatedArea,
1096a3e0fd82Sopenharmony_ci                          const Style& style)
1097a3e0fd82Sopenharmony_ci{
1098a3e0fd82Sopenharmony_ci    if (param == nullptr) {
1099a3e0fd82Sopenharmony_ci        return;
1100a3e0fd82Sopenharmony_ci    }
1101a3e0fd82Sopenharmony_ci    RectParam* rectParam = static_cast<RectParam*>(param);
1102a3e0fd82Sopenharmony_ci    Style drawStyle = StyleDefault::GetDefaultStyle();
1103a3e0fd82Sopenharmony_ci    drawStyle.bgColor_ = paint.GetStrokeColor();
1104a3e0fd82Sopenharmony_ci    drawStyle.bgOpa_ = paint.GetOpacity();
1105a3e0fd82Sopenharmony_ci    drawStyle.borderRadius_ = 0;
1106a3e0fd82Sopenharmony_ci
1107a3e0fd82Sopenharmony_ci    int16_t lineWidth = static_cast<int16_t>(paint.GetStrokeWidth());
1108a3e0fd82Sopenharmony_ci    Point start;
1109a3e0fd82Sopenharmony_ci    GetAbsolutePosition(rectParam->start, rect, style, start);
1110a3e0fd82Sopenharmony_ci
1111a3e0fd82Sopenharmony_ci    int16_t x = start.x - lineWidth / 2; // 2: half
1112a3e0fd82Sopenharmony_ci    int16_t y = start.y - lineWidth / 2; // 2: half
1113a3e0fd82Sopenharmony_ci    Rect coords;
1114a3e0fd82Sopenharmony_ci    BaseGfxEngine* baseGfxEngine = BaseGfxEngine::GetInstance();
1115a3e0fd82Sopenharmony_ci    if ((rectParam->height <= lineWidth) || (rectParam->width <= lineWidth)) {
1116a3e0fd82Sopenharmony_ci        coords.SetPosition(x, y);
1117a3e0fd82Sopenharmony_ci        coords.SetHeight(rectParam->height + lineWidth);
1118a3e0fd82Sopenharmony_ci        coords.SetWidth(rectParam->width + lineWidth);
1119a3e0fd82Sopenharmony_ci        baseGfxEngine->DrawRect(gfxDstBuffer, coords, invalidatedArea, drawStyle, OPA_OPAQUE);
1120a3e0fd82Sopenharmony_ci        return;
1121a3e0fd82Sopenharmony_ci    }
1122a3e0fd82Sopenharmony_ci
1123a3e0fd82Sopenharmony_ci    coords.SetPosition(x, y);
1124a3e0fd82Sopenharmony_ci    coords.SetHeight(lineWidth);
1125a3e0fd82Sopenharmony_ci    coords.SetWidth(rectParam->width);
1126a3e0fd82Sopenharmony_ci    baseGfxEngine->DrawRect(gfxDstBuffer, coords, invalidatedArea, drawStyle, OPA_OPAQUE);
1127a3e0fd82Sopenharmony_ci
1128a3e0fd82Sopenharmony_ci    coords.SetPosition(x + rectParam->width, y);
1129a3e0fd82Sopenharmony_ci    coords.SetHeight(rectParam->height);
1130a3e0fd82Sopenharmony_ci    coords.SetWidth(lineWidth);
1131a3e0fd82Sopenharmony_ci    baseGfxEngine->DrawRect(gfxDstBuffer, coords, invalidatedArea, drawStyle, OPA_OPAQUE);
1132a3e0fd82Sopenharmony_ci
1133a3e0fd82Sopenharmony_ci    coords.SetPosition(x, y + lineWidth);
1134a3e0fd82Sopenharmony_ci    coords.SetHeight(rectParam->height);
1135a3e0fd82Sopenharmony_ci    coords.SetWidth(lineWidth);
1136a3e0fd82Sopenharmony_ci    baseGfxEngine->DrawRect(gfxDstBuffer, coords, invalidatedArea, drawStyle, OPA_OPAQUE);
1137a3e0fd82Sopenharmony_ci
1138a3e0fd82Sopenharmony_ci    coords.SetPosition(x + lineWidth, y + rectParam->height);
1139a3e0fd82Sopenharmony_ci    coords.SetHeight(lineWidth);
1140a3e0fd82Sopenharmony_ci    coords.SetWidth(rectParam->width);
1141a3e0fd82Sopenharmony_ci    baseGfxEngine->DrawRect(gfxDstBuffer, coords, invalidatedArea, drawStyle, OPA_OPAQUE);
1142a3e0fd82Sopenharmony_ci}
1143a3e0fd82Sopenharmony_ci
1144a3e0fd82Sopenharmony_civoid UICanvas::DoFillRect(BufferInfo& gfxDstBuffer,
1145a3e0fd82Sopenharmony_ci                          void* param,
1146a3e0fd82Sopenharmony_ci                          const Paint& paint,
1147a3e0fd82Sopenharmony_ci                          const Rect& rect,
1148a3e0fd82Sopenharmony_ci                          const Rect& invalidatedArea,
1149a3e0fd82Sopenharmony_ci                          const Style& style)
1150a3e0fd82Sopenharmony_ci{
1151a3e0fd82Sopenharmony_ci    if (param == nullptr) {
1152a3e0fd82Sopenharmony_ci        return;
1153a3e0fd82Sopenharmony_ci    }
1154a3e0fd82Sopenharmony_ci    RectParam* rectParam = static_cast<RectParam*>(param);
1155a3e0fd82Sopenharmony_ci    uint8_t enableStroke = static_cast<uint8_t>(paint.GetStyle()) & Paint::PaintStyle::STROKE_STYLE;
1156a3e0fd82Sopenharmony_ci    int16_t lineWidth = enableStroke ? paint.GetStrokeWidth() : 0;
1157a3e0fd82Sopenharmony_ci    if ((rectParam->height <= lineWidth) || (rectParam->width <= lineWidth)) {
1158a3e0fd82Sopenharmony_ci        return;
1159a3e0fd82Sopenharmony_ci    }
1160a3e0fd82Sopenharmony_ci    Point start;
1161a3e0fd82Sopenharmony_ci    GetAbsolutePosition(rectParam->start, rect, style, start);
1162a3e0fd82Sopenharmony_ci
1163a3e0fd82Sopenharmony_ci    Rect coords;
1164a3e0fd82Sopenharmony_ci    coords.SetPosition(start.x + (lineWidth + 1) / 2, start.y + (lineWidth + 1) / 2); // 2: half
1165a3e0fd82Sopenharmony_ci    coords.SetHeight(rectParam->height - lineWidth);
1166a3e0fd82Sopenharmony_ci    coords.SetWidth(rectParam->width - lineWidth);
1167a3e0fd82Sopenharmony_ci
1168a3e0fd82Sopenharmony_ci    Style drawStyle = StyleDefault::GetDefaultStyle();
1169a3e0fd82Sopenharmony_ci    drawStyle.bgColor_ = paint.GetFillColor();
1170a3e0fd82Sopenharmony_ci    drawStyle.bgOpa_ = paint.GetOpacity();
1171a3e0fd82Sopenharmony_ci    drawStyle.borderRadius_ = 0;
1172a3e0fd82Sopenharmony_ci    BaseGfxEngine::GetInstance()->DrawRect(gfxDstBuffer, coords, invalidatedArea, drawStyle, OPA_OPAQUE);
1173a3e0fd82Sopenharmony_ci}
1174a3e0fd82Sopenharmony_ci
1175a3e0fd82Sopenharmony_civoid UICanvas::DoDrawCircle(BufferInfo& gfxDstBuffer,
1176a3e0fd82Sopenharmony_ci                            void* param,
1177a3e0fd82Sopenharmony_ci                            const Paint& paint,
1178a3e0fd82Sopenharmony_ci                            const Rect& rect,
1179a3e0fd82Sopenharmony_ci                            const Rect& invalidatedArea,
1180a3e0fd82Sopenharmony_ci                            const Style& style)
1181a3e0fd82Sopenharmony_ci{
1182a3e0fd82Sopenharmony_ci    if (param == nullptr) {
1183a3e0fd82Sopenharmony_ci        return;
1184a3e0fd82Sopenharmony_ci    }
1185a3e0fd82Sopenharmony_ci    CircleParam* circleParam = static_cast<CircleParam*>(param);
1186a3e0fd82Sopenharmony_ci
1187a3e0fd82Sopenharmony_ci    Style drawStyle = StyleDefault::GetDefaultStyle();
1188a3e0fd82Sopenharmony_ci    drawStyle.lineOpa_ = paint.GetOpacity();
1189a3e0fd82Sopenharmony_ci
1190a3e0fd82Sopenharmony_ci    ArcInfo arcInfo = {{0}};
1191a3e0fd82Sopenharmony_ci    arcInfo.imgPos = {0, 0};
1192a3e0fd82Sopenharmony_ci    arcInfo.startAngle = 0;
1193a3e0fd82Sopenharmony_ci    arcInfo.endAngle = CIRCLE_IN_DEGREE;
1194a3e0fd82Sopenharmony_ci    GetAbsolutePosition(circleParam->center, rect, style, arcInfo.center);
1195a3e0fd82Sopenharmony_ci    uint8_t enableStroke = static_cast<uint8_t>(paint.GetStyle()) & Paint::PaintStyle::STROKE_STYLE;
1196a3e0fd82Sopenharmony_ci    uint16_t halfLineWidth = enableStroke ? (paint.GetStrokeWidth() >> 1) : 0;
1197a3e0fd82Sopenharmony_ci    BaseGfxEngine* baseGfxEngine = BaseGfxEngine::GetInstance();
1198a3e0fd82Sopenharmony_ci    if (static_cast<uint8_t>(paint.GetStyle()) & Paint::PaintStyle::FILL_STYLE) {
1199a3e0fd82Sopenharmony_ci        arcInfo.radius = circleParam->radius - halfLineWidth;
1200a3e0fd82Sopenharmony_ci        drawStyle.lineWidth_ = arcInfo.radius;
1201a3e0fd82Sopenharmony_ci        drawStyle.lineColor_ = paint.GetFillColor();
1202a3e0fd82Sopenharmony_ci        baseGfxEngine->DrawArc(gfxDstBuffer, arcInfo, invalidatedArea, drawStyle, OPA_OPAQUE,
1203a3e0fd82Sopenharmony_ci                               CapType::CAP_NONE);
1204a3e0fd82Sopenharmony_ci    }
1205a3e0fd82Sopenharmony_ci
1206a3e0fd82Sopenharmony_ci    if (enableStroke) {
1207a3e0fd82Sopenharmony_ci        arcInfo.radius = circleParam->radius + halfLineWidth - 1;
1208a3e0fd82Sopenharmony_ci        drawStyle.lineWidth_ = static_cast<int16_t>(paint.GetStrokeWidth());
1209a3e0fd82Sopenharmony_ci        drawStyle.lineColor_ = paint.GetStrokeColor();
1210a3e0fd82Sopenharmony_ci        baseGfxEngine->DrawArc(gfxDstBuffer, arcInfo, invalidatedArea, drawStyle, OPA_OPAQUE,
1211a3e0fd82Sopenharmony_ci                               CapType::CAP_NONE);
1212a3e0fd82Sopenharmony_ci    }
1213a3e0fd82Sopenharmony_ci}
1214a3e0fd82Sopenharmony_ci
1215a3e0fd82Sopenharmony_civoid UICanvas::DoDrawArc(BufferInfo& gfxDstBuffer,
1216a3e0fd82Sopenharmony_ci                         void* param,
1217a3e0fd82Sopenharmony_ci                         const Paint& paint,
1218a3e0fd82Sopenharmony_ci                         const Rect& rect,
1219a3e0fd82Sopenharmony_ci                         const Rect& invalidatedArea,
1220a3e0fd82Sopenharmony_ci                         const Style& style)
1221a3e0fd82Sopenharmony_ci{
1222a3e0fd82Sopenharmony_ci    if (param == nullptr) {
1223a3e0fd82Sopenharmony_ci        return;
1224a3e0fd82Sopenharmony_ci    }
1225a3e0fd82Sopenharmony_ci    ArcParam* arcParam = static_cast<ArcParam*>(param);
1226a3e0fd82Sopenharmony_ci
1227a3e0fd82Sopenharmony_ci    ArcInfo arcInfo = {{0}};
1228a3e0fd82Sopenharmony_ci    arcInfo.imgPos = {0, 0};
1229a3e0fd82Sopenharmony_ci    arcInfo.startAngle = arcParam->startAngle;
1230a3e0fd82Sopenharmony_ci    arcInfo.endAngle = arcParam->endAngle;
1231a3e0fd82Sopenharmony_ci    Style drawStyle = StyleDefault::GetDefaultStyle();
1232a3e0fd82Sopenharmony_ci    drawStyle.lineWidth_ = static_cast<int16_t>(paint.GetStrokeWidth());
1233a3e0fd82Sopenharmony_ci    drawStyle.lineColor_ = paint.GetStrokeColor();
1234a3e0fd82Sopenharmony_ci    drawStyle.lineOpa_ = paint.GetOpacity();
1235a3e0fd82Sopenharmony_ci    arcInfo.radius = arcParam->radius + ((paint.GetStrokeWidth() + 1) >> 1);
1236a3e0fd82Sopenharmony_ci
1237a3e0fd82Sopenharmony_ci    GetAbsolutePosition(arcParam->center, rect, style, arcInfo.center);
1238a3e0fd82Sopenharmony_ci    BaseGfxEngine::GetInstance()->DrawArc(gfxDstBuffer, arcInfo, invalidatedArea, drawStyle, OPA_OPAQUE,
1239a3e0fd82Sopenharmony_ci                                          CapType::CAP_NONE);
1240a3e0fd82Sopenharmony_ci}
1241a3e0fd82Sopenharmony_ci#if defined(GRAPHIC_ENABLE_DRAW_IMAGE_FLAG) && GRAPHIC_ENABLE_DRAW_IMAGE_FLAG
1242a3e0fd82Sopenharmony_civoid UICanvas::DoDrawImage(BufferInfo& gfxDstBuffer,
1243a3e0fd82Sopenharmony_ci                           void* param,
1244a3e0fd82Sopenharmony_ci                           const Paint& paint,
1245a3e0fd82Sopenharmony_ci                           const Rect& rect,
1246a3e0fd82Sopenharmony_ci                           const Rect& invalidatedArea,
1247a3e0fd82Sopenharmony_ci                           const Style& style)
1248a3e0fd82Sopenharmony_ci{
1249a3e0fd82Sopenharmony_ci    if (param == nullptr) {
1250a3e0fd82Sopenharmony_ci        return;
1251a3e0fd82Sopenharmony_ci    }
1252a3e0fd82Sopenharmony_ci    UIImageView* imageView = static_cast<UIImageView*>(param);
1253a3e0fd82Sopenharmony_ci    Point startPos = {imageView->GetX(), imageView->GetY()};
1254a3e0fd82Sopenharmony_ci    Point start;
1255a3e0fd82Sopenharmony_ci    GetAbsolutePosition({startPos.x, startPos.y}, rect, style, start);
1256a3e0fd82Sopenharmony_ci    imageView->SetPosition(start.x, start.y);
1257a3e0fd82Sopenharmony_ci    if (!paint.GetTransAffine().IsIdentity()) {
1258a3e0fd82Sopenharmony_ci        float angle = paint.GetRotateAngle();
1259a3e0fd82Sopenharmony_ci        imageView->Rotate(MATH_ROUND(angle), Vector2<float>(0, 0));
1260a3e0fd82Sopenharmony_ci        imageView->Translate(Vector3<int16_t>(paint.GetTranslateX(), paint.GetTranslateY(), 1));
1261a3e0fd82Sopenharmony_ci        Vector2<float> scale(static_cast<float>(paint.GetScaleX()), static_cast<float>(paint.GetScaleY()));
1262a3e0fd82Sopenharmony_ci        imageView->Scale(scale, Vector2<float>(0, 0));
1263a3e0fd82Sopenharmony_ci    }
1264a3e0fd82Sopenharmony_ci    imageView->OnDraw(gfxDstBuffer, invalidatedArea);
1265a3e0fd82Sopenharmony_ci    imageView->SetPosition(startPos.x, startPos.y);
1266a3e0fd82Sopenharmony_ci}
1267a3e0fd82Sopenharmony_ci#endif
1268a3e0fd82Sopenharmony_ci
1269a3e0fd82Sopenharmony_civoid UICanvas::DoDrawLabel(BufferInfo& gfxDstBuffer,
1270a3e0fd82Sopenharmony_ci                           void* param,
1271a3e0fd82Sopenharmony_ci                           const Paint& paint,
1272a3e0fd82Sopenharmony_ci                           const Rect& rect,
1273a3e0fd82Sopenharmony_ci                           const Rect& invalidatedArea,
1274a3e0fd82Sopenharmony_ci                           const Style& style)
1275a3e0fd82Sopenharmony_ci{
1276a3e0fd82Sopenharmony_ci    if (param == nullptr) {
1277a3e0fd82Sopenharmony_ci        return;
1278a3e0fd82Sopenharmony_ci    }
1279a3e0fd82Sopenharmony_ci    UILabel* label = static_cast<UILabel*>(param);
1280a3e0fd82Sopenharmony_ci    Point startPos = {label->GetX(), label->GetY()};
1281a3e0fd82Sopenharmony_ci    Point start;
1282a3e0fd82Sopenharmony_ci    GetAbsolutePosition({startPos.x, startPos.y}, rect, style, start);
1283a3e0fd82Sopenharmony_ci    label->SetPosition(start.x, start.y);
1284a3e0fd82Sopenharmony_ci    label->OnDraw(gfxDstBuffer, invalidatedArea);
1285a3e0fd82Sopenharmony_ci    label->SetPosition(startPos.x, startPos.y);
1286a3e0fd82Sopenharmony_ci}
1287a3e0fd82Sopenharmony_ci
1288a3e0fd82Sopenharmony_civoid UICanvas::DoDrawLineJoin(BufferInfo& gfxDstBuffer,
1289a3e0fd82Sopenharmony_ci                              const Point& center,
1290a3e0fd82Sopenharmony_ci                              const Rect& invalidatedArea,
1291a3e0fd82Sopenharmony_ci                              const Paint& paint)
1292a3e0fd82Sopenharmony_ci{
1293a3e0fd82Sopenharmony_ci    ArcInfo arcinfo = {{0}};
1294a3e0fd82Sopenharmony_ci    arcinfo.center = center;
1295a3e0fd82Sopenharmony_ci    arcinfo.imgPos = {0, 0};
1296a3e0fd82Sopenharmony_ci    arcinfo.radius = (paint.GetStrokeWidth() + 1) >> 1;
1297a3e0fd82Sopenharmony_ci    arcinfo.startAngle = 0;
1298a3e0fd82Sopenharmony_ci    arcinfo.endAngle = CIRCLE_IN_DEGREE;
1299a3e0fd82Sopenharmony_ci
1300a3e0fd82Sopenharmony_ci    Style style;
1301a3e0fd82Sopenharmony_ci    style.lineColor_ = paint.GetStrokeColor();
1302a3e0fd82Sopenharmony_ci    style.lineWidth_ = static_cast<int16_t>(paint.GetStrokeWidth());
1303a3e0fd82Sopenharmony_ci    style.lineOpa_ = OPA_OPAQUE;
1304a3e0fd82Sopenharmony_ci    BaseGfxEngine::GetInstance()->DrawArc(gfxDstBuffer, arcinfo, invalidatedArea,
1305a3e0fd82Sopenharmony_ci                                          style, OPA_OPAQUE, CapType::CAP_NONE);
1306a3e0fd82Sopenharmony_ci}
1307a3e0fd82Sopenharmony_ci
1308a3e0fd82Sopenharmony_civoid UICanvas::DoDrawPath(BufferInfo& gfxDstBuffer,
1309a3e0fd82Sopenharmony_ci                          void* param,
1310a3e0fd82Sopenharmony_ci                          const Paint& paint,
1311a3e0fd82Sopenharmony_ci                          const Rect& rect,
1312a3e0fd82Sopenharmony_ci                          const Rect& invalidatedArea,
1313a3e0fd82Sopenharmony_ci                          const Style& style)
1314a3e0fd82Sopenharmony_ci{
1315a3e0fd82Sopenharmony_ci#if defined(ENABLE_CANVAS_EXTEND) && ENABLE_CANVAS_EXTEND
1316a3e0fd82Sopenharmony_ci    BaseGfxEngine::GetInstance()->DrawPath(gfxDstBuffer, param, paint, rect, invalidatedArea, style);
1317a3e0fd82Sopenharmony_ci#else
1318a3e0fd82Sopenharmony_ci    if (param == nullptr) {
1319a3e0fd82Sopenharmony_ci        return;
1320a3e0fd82Sopenharmony_ci    }
1321a3e0fd82Sopenharmony_ci    PathParam* pathParam = static_cast<PathParam*>(param);
1322a3e0fd82Sopenharmony_ci    const UICanvasPath* path = pathParam->path;
1323a3e0fd82Sopenharmony_ci    if (path == nullptr) {
1324a3e0fd82Sopenharmony_ci        return;
1325a3e0fd82Sopenharmony_ci    }
1326a3e0fd82Sopenharmony_ci    Point pathEnd = {COORD_MIN, COORD_MIN};
1327a3e0fd82Sopenharmony_ci
1328a3e0fd82Sopenharmony_ci    ListNode<Point>* pointIter = path->points_.Begin();
1329a3e0fd82Sopenharmony_ci    ListNode<ArcParam>* arcIter = path->arcParam_.Begin();
1330a3e0fd82Sopenharmony_ci    ListNode<PathCmd>* iter = path->cmd_.Begin();
1331a3e0fd82Sopenharmony_ci    for (uint16_t i = 0; (i < pathParam->count) && (iter != path->cmd_.End()); i++, iter = iter->next_) {
1332a3e0fd82Sopenharmony_ci        switch (iter->data_) {
1333a3e0fd82Sopenharmony_ci            case CMD_MOVE_TO: {
1334a3e0fd82Sopenharmony_ci                pointIter = pointIter->next_;
1335a3e0fd82Sopenharmony_ci                break;
1336a3e0fd82Sopenharmony_ci            }
1337a3e0fd82Sopenharmony_ci            case CMD_LINE_TO: {
1338a3e0fd82Sopenharmony_ci                Point start = pointIter->prev_->data_;
1339a3e0fd82Sopenharmony_ci                Point end = pointIter->data_;
1340a3e0fd82Sopenharmony_ci                pointIter = pointIter->next_;
1341a3e0fd82Sopenharmony_ci                if ((start.x == end.x) && (start.y == end.y)) {
1342a3e0fd82Sopenharmony_ci                    break;
1343a3e0fd82Sopenharmony_ci                }
1344a3e0fd82Sopenharmony_ci
1345a3e0fd82Sopenharmony_ci                GetAbsolutePosition(start, rect, style, start);
1346a3e0fd82Sopenharmony_ci                GetAbsolutePosition(end, rect, style, end);
1347a3e0fd82Sopenharmony_ci                BaseGfxEngine::GetInstance()->DrawLine(gfxDstBuffer, start, end, invalidatedArea,
1348a3e0fd82Sopenharmony_ci                                                       paint.GetStrokeWidth(), paint.GetStrokeColor(), OPA_OPAQUE);
1349a3e0fd82Sopenharmony_ci                if ((pathEnd.x == start.x) && (pathEnd.y == start.y)) {
1350a3e0fd82Sopenharmony_ci                    DoDrawLineJoin(gfxDstBuffer, start, invalidatedArea, paint);
1351a3e0fd82Sopenharmony_ci                }
1352a3e0fd82Sopenharmony_ci                pathEnd = end;
1353a3e0fd82Sopenharmony_ci                break;
1354a3e0fd82Sopenharmony_ci            }
1355a3e0fd82Sopenharmony_ci            case CMD_ARC: {
1356a3e0fd82Sopenharmony_ci                ArcInfo arcInfo = {{0}};
1357a3e0fd82Sopenharmony_ci                arcInfo.imgPos = Point{0, 0};
1358a3e0fd82Sopenharmony_ci                arcInfo.startAngle = arcIter->data_.startAngle;
1359a3e0fd82Sopenharmony_ci                arcInfo.endAngle = arcIter->data_.endAngle;
1360a3e0fd82Sopenharmony_ci                Style drawStyle = StyleDefault::GetDefaultStyle();
1361a3e0fd82Sopenharmony_ci                drawStyle.lineWidth_ = static_cast<int16_t>(paint.GetStrokeWidth());
1362a3e0fd82Sopenharmony_ci                drawStyle.lineColor_ = paint.GetStrokeColor();
1363a3e0fd82Sopenharmony_ci                drawStyle.lineOpa_ = OPA_OPAQUE;
1364a3e0fd82Sopenharmony_ci                arcInfo.radius = arcIter->data_.radius + ((paint.GetStrokeWidth() + 1) >> 1);
1365a3e0fd82Sopenharmony_ci
1366a3e0fd82Sopenharmony_ci                GetAbsolutePosition(arcIter->data_.center, rect, style, arcInfo.center);
1367a3e0fd82Sopenharmony_ci                BaseGfxEngine::GetInstance()->DrawArc(gfxDstBuffer, arcInfo, invalidatedArea, drawStyle, OPA_OPAQUE,
1368a3e0fd82Sopenharmony_ci                                                      CapType::CAP_NONE);
1369a3e0fd82Sopenharmony_ci                if (pointIter != path->points_.Begin()) {
1370a3e0fd82Sopenharmony_ci                    DoDrawLineJoin(gfxDstBuffer, pathEnd, invalidatedArea, paint);
1371a3e0fd82Sopenharmony_ci                }
1372a3e0fd82Sopenharmony_ci
1373a3e0fd82Sopenharmony_ci                GetAbsolutePosition(pointIter->data_, rect, style, pathEnd);
1374a3e0fd82Sopenharmony_ci                pointIter = pointIter->next_;
1375a3e0fd82Sopenharmony_ci                arcIter = arcIter->next_;
1376a3e0fd82Sopenharmony_ci                break;
1377a3e0fd82Sopenharmony_ci            }
1378a3e0fd82Sopenharmony_ci            case CMD_CLOSE: {
1379a3e0fd82Sopenharmony_ci                Point start = pointIter->prev_->data_;
1380a3e0fd82Sopenharmony_ci                Point end = pointIter->data_;
1381a3e0fd82Sopenharmony_ci                GetAbsolutePosition(start, rect, style, start);
1382a3e0fd82Sopenharmony_ci                GetAbsolutePosition(end, rect, style, end);
1383a3e0fd82Sopenharmony_ci                if ((start.x != end.x) || (start.y != end.y)) {
1384a3e0fd82Sopenharmony_ci                    BaseGfxEngine::GetInstance()->DrawLine(gfxDstBuffer, start, end, invalidatedArea,
1385a3e0fd82Sopenharmony_ci                                                           paint.GetStrokeWidth(), paint.GetStrokeColor(), OPA_OPAQUE);
1386a3e0fd82Sopenharmony_ci                    if ((pathEnd.x == start.x) && (pathEnd.y == start.y)) {
1387a3e0fd82Sopenharmony_ci                        DoDrawLineJoin(gfxDstBuffer, start, invalidatedArea, paint);
1388a3e0fd82Sopenharmony_ci                    }
1389a3e0fd82Sopenharmony_ci                    pathEnd = end;
1390a3e0fd82Sopenharmony_ci                }
1391a3e0fd82Sopenharmony_ci
1392a3e0fd82Sopenharmony_ci                if ((pathEnd.x == end.x) && (pathEnd.y == end.y)) {
1393a3e0fd82Sopenharmony_ci                    DoDrawLineJoin(gfxDstBuffer, end, invalidatedArea, paint);
1394a3e0fd82Sopenharmony_ci                }
1395a3e0fd82Sopenharmony_ci                pointIter = pointIter->next_;
1396a3e0fd82Sopenharmony_ci                break;
1397a3e0fd82Sopenharmony_ci            }
1398a3e0fd82Sopenharmony_ci            default:
1399a3e0fd82Sopenharmony_ci                break;
1400a3e0fd82Sopenharmony_ci        }
1401a3e0fd82Sopenharmony_ci    }
1402a3e0fd82Sopenharmony_ci#endif
1403a3e0fd82Sopenharmony_ci}
1404a3e0fd82Sopenharmony_ci
1405a3e0fd82Sopenharmony_civoid UICanvas::DoFillPath(BufferInfo& gfxDstBuffer,
1406a3e0fd82Sopenharmony_ci                          void* param,
1407a3e0fd82Sopenharmony_ci                          const Paint& paint,
1408a3e0fd82Sopenharmony_ci                          const Rect& rect,
1409a3e0fd82Sopenharmony_ci                          const Rect& invalidatedArea,
1410a3e0fd82Sopenharmony_ci                          const Style& style)
1411a3e0fd82Sopenharmony_ci{
1412a3e0fd82Sopenharmony_ci    BaseGfxEngine::GetInstance()->FillPath(gfxDstBuffer, param, paint, rect, invalidatedArea, style);
1413a3e0fd82Sopenharmony_ci}
1414a3e0fd82Sopenharmony_ci
1415a3e0fd82Sopenharmony_ci#if defined(GRAPHIC_ENABLE_DRAW_TEXT_FLAG) && GRAPHIC_ENABLE_DRAW_TEXT_FLAG
1416a3e0fd82Sopenharmony_civoid UICanvas::StrokeText(const char* text, const Point& point, const FontStyle& fontStyle, const Paint& paint)
1417a3e0fd82Sopenharmony_ci{
1418a3e0fd82Sopenharmony_ci    if (text == nullptr) {
1419a3e0fd82Sopenharmony_ci        return;
1420a3e0fd82Sopenharmony_ci    }
1421a3e0fd82Sopenharmony_ci    if (static_cast<uint8_t>(paint.GetStyle()) & Paint::PaintStyle::FILL_STYLE) {
1422a3e0fd82Sopenharmony_ci        TextParam* textParam = new TextParam;
1423a3e0fd82Sopenharmony_ci        if (textParam == nullptr) {
1424a3e0fd82Sopenharmony_ci            GRAPHIC_LOGE("new TextParam fail");
1425a3e0fd82Sopenharmony_ci            return;
1426a3e0fd82Sopenharmony_ci        }
1427a3e0fd82Sopenharmony_ci        textParam->text = text;
1428a3e0fd82Sopenharmony_ci        textParam->fontStyle = fontStyle;
1429a3e0fd82Sopenharmony_ci        textParam->fontOpa = paint.GetOpacity();
1430a3e0fd82Sopenharmony_ci        textParam->fontColor = paint.GetFillColor();
1431a3e0fd82Sopenharmony_ci        textParam->position = point;
1432a3e0fd82Sopenharmony_ci        DrawCmd cmd;
1433a3e0fd82Sopenharmony_ci        cmd.param = textParam;
1434a3e0fd82Sopenharmony_ci        cmd.DeleteParam = DeleteTextParam;
1435a3e0fd82Sopenharmony_ci        cmd.DrawGraphics = DoDrawText;
1436a3e0fd82Sopenharmony_ci        cmd.paint = paint;
1437a3e0fd82Sopenharmony_ci        drawCmdList_.PushBack(cmd);
1438a3e0fd82Sopenharmony_ci        Invalidate();
1439a3e0fd82Sopenharmony_ci        SetStartPosition(point);
1440a3e0fd82Sopenharmony_ci    }
1441a3e0fd82Sopenharmony_ci}
1442a3e0fd82Sopenharmony_ci#endif
1443a3e0fd82Sopenharmony_ci
1444a3e0fd82Sopenharmony_ciPoint UICanvas::MeasureText(const char* text, const FontStyle& fontStyle)
1445a3e0fd82Sopenharmony_ci{
1446a3e0fd82Sopenharmony_ci    Text* textCompent = new Text;
1447a3e0fd82Sopenharmony_ci    textCompent->SetText(text);
1448a3e0fd82Sopenharmony_ci    textCompent->SetFont(fontStyle.fontName, fontStyle.fontSize);
1449a3e0fd82Sopenharmony_ci    textCompent->SetDirect(static_cast<UITextLanguageDirect>(fontStyle.direct));
1450a3e0fd82Sopenharmony_ci    textCompent->SetAlign(static_cast<UITextLanguageAlignment>(fontStyle.align));
1451a3e0fd82Sopenharmony_ci    Style drawStyle;
1452a3e0fd82Sopenharmony_ci    drawStyle.SetStyle(STYLE_LETTER_SPACE, fontStyle.letterSpace);
1453a3e0fd82Sopenharmony_ci    textCompent->ReMeasureTextSize(this->GetRect(), drawStyle);
1454a3e0fd82Sopenharmony_ci    Point textSize = textCompent->GetTextSize();
1455a3e0fd82Sopenharmony_ci    delete textCompent;
1456a3e0fd82Sopenharmony_ci    return textSize;
1457a3e0fd82Sopenharmony_ci}
1458a3e0fd82Sopenharmony_ci
1459a3e0fd82Sopenharmony_civoid UICanvas::BlitMapBuffer(BufferInfo &gfxDstBuffer, BufferInfo& gfxMapBuffer, Rect& textRect,
1460a3e0fd82Sopenharmony_ci                             TransformMap& transMap, const Rect& invalidatedArea)
1461a3e0fd82Sopenharmony_ci{
1462a3e0fd82Sopenharmony_ci    Rect invalidRect = textRect;
1463a3e0fd82Sopenharmony_ci    transMap.SetTransMapRect(textRect);
1464a3e0fd82Sopenharmony_ci    if (invalidRect.Intersect(invalidRect, transMap.GetBoxRect())) {
1465a3e0fd82Sopenharmony_ci        uint8_t pxSize = DrawUtils::GetPxSizeByColorMode(gfxDstBuffer.mode);
1466a3e0fd82Sopenharmony_ci        ImageInfo imageInfo;
1467a3e0fd82Sopenharmony_ci        imageInfo.header.colorMode = gfxDstBuffer.mode;
1468a3e0fd82Sopenharmony_ci        imageInfo.dataSize = gfxMapBuffer.width * gfxMapBuffer.height *
1469a3e0fd82Sopenharmony_ci                DrawUtils::GetByteSizeByColorMode(gfxDstBuffer.mode);
1470a3e0fd82Sopenharmony_ci        imageInfo.header.width = gfxMapBuffer.width;
1471a3e0fd82Sopenharmony_ci        imageInfo.header.height = gfxMapBuffer.height;
1472a3e0fd82Sopenharmony_ci        imageInfo.header.reserved = 0;
1473a3e0fd82Sopenharmony_ci        uint8_t* addr = reinterpret_cast<uint8_t*>(gfxMapBuffer.virAddr);
1474a3e0fd82Sopenharmony_ci        imageInfo.data = addr;
1475a3e0fd82Sopenharmony_ci        TransformDataInfo imageTranDataInfo = {imageInfo.header, imageInfo.data, pxSize,
1476a3e0fd82Sopenharmony_ci                                               BlurLevel::LEVEL0, TransformAlgorithm::BILINEAR};
1477a3e0fd82Sopenharmony_ci        BaseGfxEngine::GetInstance()->DrawTransform(gfxDstBuffer, invalidatedArea, {0, 0}, Color::Black(),
1478a3e0fd82Sopenharmony_ci                                                    OPA_OPAQUE, transMap, imageTranDataInfo);
1479a3e0fd82Sopenharmony_ci    }
1480a3e0fd82Sopenharmony_ci}
1481a3e0fd82Sopenharmony_ci
1482a3e0fd82Sopenharmony_ci#if defined(GRAPHIC_ENABLE_DRAW_TEXT_FLAG) && GRAPHIC_ENABLE_DRAW_TEXT_FLAG
1483a3e0fd82Sopenharmony_civoid UICanvas::DoDrawText(BufferInfo& gfxDstBuffer,
1484a3e0fd82Sopenharmony_ci                          void* param,
1485a3e0fd82Sopenharmony_ci                          const Paint& paint,
1486a3e0fd82Sopenharmony_ci                          const Rect& rect,
1487a3e0fd82Sopenharmony_ci                          const Rect& invalidatedArea,
1488a3e0fd82Sopenharmony_ci                          const Style& style)
1489a3e0fd82Sopenharmony_ci{
1490a3e0fd82Sopenharmony_ci    TextParam* textParam = static_cast<TextParam*>(param);
1491a3e0fd82Sopenharmony_ci    if (textParam == nullptr) {
1492a3e0fd82Sopenharmony_ci        return;
1493a3e0fd82Sopenharmony_ci    }
1494a3e0fd82Sopenharmony_ci    if (textParam->fontStyle.fontSize <= 0) {
1495a3e0fd82Sopenharmony_ci        return;
1496a3e0fd82Sopenharmony_ci    }
1497a3e0fd82Sopenharmony_ci    Text* text = textParam->textComment;
1498a3e0fd82Sopenharmony_ci    text->SetText(textParam->text);
1499a3e0fd82Sopenharmony_ci    text->SetFont(textParam->fontStyle.fontName, textParam->fontStyle.fontSize);
1500a3e0fd82Sopenharmony_ci    text->SetDirect(static_cast<UITextLanguageDirect>(textParam->fontStyle.direct));
1501a3e0fd82Sopenharmony_ci    text->SetAlign(static_cast<UITextLanguageAlignment>(textParam->fontStyle.align));
1502a3e0fd82Sopenharmony_ci
1503a3e0fd82Sopenharmony_ci    Point start;
1504a3e0fd82Sopenharmony_ci    Rect textRect = invalidatedArea;
1505a3e0fd82Sopenharmony_ci    GetAbsolutePosition(textParam->position, rect, style, start);
1506a3e0fd82Sopenharmony_ci    textRect.SetPosition(start.x, start.y);
1507a3e0fd82Sopenharmony_ci    Style drawStyle = style;
1508a3e0fd82Sopenharmony_ci    drawStyle.textColor_ = textParam->fontColor;
1509a3e0fd82Sopenharmony_ci    drawStyle.lineColor_ = textParam->fontColor;
1510a3e0fd82Sopenharmony_ci    drawStyle.bgColor_ = textParam->fontColor;
1511a3e0fd82Sopenharmony_ci    drawStyle.SetStyle(STYLE_LETTER_SPACE, textParam->fontStyle.letterSpace);
1512a3e0fd82Sopenharmony_ci    text->ReMeasureTextSize(textRect, drawStyle);
1513a3e0fd82Sopenharmony_ci    if (text->GetTextSize().x == 0 || text->GetTextSize().y == 0) {
1514a3e0fd82Sopenharmony_ci        return;
1515a3e0fd82Sopenharmony_ci    }
1516a3e0fd82Sopenharmony_ci    textRect.SetWidth(text->GetTextSize().x + 1);
1517a3e0fd82Sopenharmony_ci    textRect.SetHeight(text->GetTextSize().y + 1);
1518a3e0fd82Sopenharmony_ci    OpacityType opa = DrawUtils::GetMixOpacity(textParam->fontOpa, style.bgOpa_);
1519a3e0fd82Sopenharmony_ci    if (!paint.GetTransAffine().IsIdentity()) {
1520a3e0fd82Sopenharmony_ci        Rect textImageRect(0, 0, textRect.GetWidth(), textRect.GetHeight());
1521a3e0fd82Sopenharmony_ci        BufferInfo* mapBufferInfo = UpdateMapBufferInfo(gfxDstBuffer, textImageRect);
1522a3e0fd82Sopenharmony_ci        text->OnDraw(*mapBufferInfo, textImageRect, textImageRect, textImageRect, 0, drawStyle,
1523a3e0fd82Sopenharmony_ci                     Text::TEXT_ELLIPSIS_END_INV, opa);
1524a3e0fd82Sopenharmony_ci        TransformMap trans;
1525a3e0fd82Sopenharmony_ci        trans.SetTransMapRect(textRect);
1526a3e0fd82Sopenharmony_ci        trans.Scale(Vector2<float>(static_cast<float>(paint.GetScaleX()), static_cast<float>(paint.GetScaleY())),
1527a3e0fd82Sopenharmony_ci                    Vector2<float>(0, 0));
1528a3e0fd82Sopenharmony_ci        float angle = paint.GetRotateAngle();
1529a3e0fd82Sopenharmony_ci        trans.Rotate(MATH_ROUND(angle),  Vector2<float>(0, 0));
1530a3e0fd82Sopenharmony_ci        trans.Translate(Vector2<int16_t>(paint.GetTranslateX(), paint.GetTranslateY()));
1531a3e0fd82Sopenharmony_ci        BlitMapBuffer(gfxDstBuffer, *mapBufferInfo, textRect, trans, invalidatedArea);
1532a3e0fd82Sopenharmony_ci    } else {
1533a3e0fd82Sopenharmony_ci        text->OnDraw(gfxDstBuffer, invalidatedArea, textRect, textRect, 0,
1534a3e0fd82Sopenharmony_ci                     drawStyle, Text::TEXT_ELLIPSIS_END_INV, opa);
1535a3e0fd82Sopenharmony_ci    }
1536a3e0fd82Sopenharmony_ci}
1537a3e0fd82Sopenharmony_ci#endif
1538a3e0fd82Sopenharmony_ci
1539a3e0fd82Sopenharmony_civoid UICanvas::InitGfxMapBuffer(const BufferInfo& srcBuff, const Rect& rect)
1540a3e0fd82Sopenharmony_ci{
1541a3e0fd82Sopenharmony_ci    gfxMapBuffer_ = new BufferInfo();
1542a3e0fd82Sopenharmony_ci    gfxMapBuffer_->rect = rect;
1543a3e0fd82Sopenharmony_ci    gfxMapBuffer_->mode = srcBuff.mode;
1544a3e0fd82Sopenharmony_ci    gfxMapBuffer_->color = srcBuff.color;
1545a3e0fd82Sopenharmony_ci    gfxMapBuffer_->width = static_cast<uint16_t>(rect.GetWidth());
1546a3e0fd82Sopenharmony_ci    gfxMapBuffer_->height = static_cast<uint16_t>(rect.GetHeight());
1547a3e0fd82Sopenharmony_ci    uint8_t destByteSize = DrawUtils::GetByteSizeByColorMode(srcBuff.mode);
1548a3e0fd82Sopenharmony_ci    gfxMapBuffer_->stride = static_cast<int32_t>(gfxMapBuffer_->width) * static_cast<int32_t>(destByteSize);
1549a3e0fd82Sopenharmony_ci    uint32_t buffSize = gfxMapBuffer_->height * gfxMapBuffer_->stride;
1550a3e0fd82Sopenharmony_ci    BaseGfxEngine* baseGfxEngine = BaseGfxEngine::GetInstance();
1551a3e0fd82Sopenharmony_ci    gfxMapBuffer_->virAddr = baseGfxEngine->AllocBuffer(buffSize, BUFFER_MAP_SURFACE);
1552a3e0fd82Sopenharmony_ci    gfxMapBuffer_->phyAddr = gfxMapBuffer_->virAddr;
1553a3e0fd82Sopenharmony_ci
1554a3e0fd82Sopenharmony_ci    errno_t err = memset_s(gfxMapBuffer_->virAddr, buffSize, 0, buffSize);
1555a3e0fd82Sopenharmony_ci    if (err != EOK) {
1556a3e0fd82Sopenharmony_ci        baseGfxEngine->FreeBuffer(static_cast<uint8_t*>(gfxMapBuffer_->virAddr), BUFFER_MAP_SURFACE);
1557a3e0fd82Sopenharmony_ci        GRAPHIC_LOGE("memset_s gfxMapBuffer_ fail");
1558a3e0fd82Sopenharmony_ci        return;
1559a3e0fd82Sopenharmony_ci    }
1560a3e0fd82Sopenharmony_ci}
1561a3e0fd82Sopenharmony_ci
1562a3e0fd82Sopenharmony_ciBufferInfo* UICanvas::UpdateMapBufferInfo(const BufferInfo& srcBuff, const Rect& rect)
1563a3e0fd82Sopenharmony_ci{
1564a3e0fd82Sopenharmony_ci    if (gfxMapBuffer_ == nullptr) {
1565a3e0fd82Sopenharmony_ci        InitGfxMapBuffer(srcBuff, rect);
1566a3e0fd82Sopenharmony_ci        return gfxMapBuffer_;
1567a3e0fd82Sopenharmony_ci    }
1568a3e0fd82Sopenharmony_ci
1569a3e0fd82Sopenharmony_ci    if (rect.GetWidth() != gfxMapBuffer_->width ||
1570a3e0fd82Sopenharmony_ci        rect.GetHeight() != gfxMapBuffer_->height ||
1571a3e0fd82Sopenharmony_ci        srcBuff.mode != gfxMapBuffer_->mode) {
1572a3e0fd82Sopenharmony_ci        DestroyMapBufferInfo();
1573a3e0fd82Sopenharmony_ci        InitGfxMapBuffer(srcBuff, rect);
1574a3e0fd82Sopenharmony_ci    } else {
1575a3e0fd82Sopenharmony_ci        uint32_t buffSize = gfxMapBuffer_->height * gfxMapBuffer_->stride;
1576a3e0fd82Sopenharmony_ci        errno_t err = memset_s(gfxMapBuffer_->virAddr, buffSize, 0, buffSize);
1577a3e0fd82Sopenharmony_ci        if (err != EOK) {
1578a3e0fd82Sopenharmony_ci            BaseGfxEngine::GetInstance()->FreeBuffer(static_cast<uint8_t*>(gfxMapBuffer_->virAddr), BUFFER_MAP_SURFACE);
1579a3e0fd82Sopenharmony_ci            GRAPHIC_LOGE("memset_s gfxMapBuffer_ fail");
1580a3e0fd82Sopenharmony_ci        }
1581a3e0fd82Sopenharmony_ci    }
1582a3e0fd82Sopenharmony_ci    return gfxMapBuffer_;
1583a3e0fd82Sopenharmony_ci}
1584a3e0fd82Sopenharmony_ci
1585a3e0fd82Sopenharmony_civoid UICanvas::DestroyMapBufferInfo()
1586a3e0fd82Sopenharmony_ci{
1587a3e0fd82Sopenharmony_ci    if (gfxMapBuffer_ != nullptr) {
1588a3e0fd82Sopenharmony_ci        BaseGfxEngine::GetInstance()->FreeBuffer(static_cast<uint8_t*>(gfxMapBuffer_->virAddr), BUFFER_MAP_SURFACE);
1589a3e0fd82Sopenharmony_ci        gfxMapBuffer_->virAddr = nullptr;
1590a3e0fd82Sopenharmony_ci        gfxMapBuffer_->phyAddr = nullptr;
1591a3e0fd82Sopenharmony_ci        delete gfxMapBuffer_;
1592a3e0fd82Sopenharmony_ci        gfxMapBuffer_ = nullptr;
1593a3e0fd82Sopenharmony_ci    }
1594a3e0fd82Sopenharmony_ci}
1595a3e0fd82Sopenharmony_ci
1596a3e0fd82Sopenharmony_ci#if defined(ENABLE_CANVAS_EXTEND) && ENABLE_CANVAS_EXTEND
1597a3e0fd82Sopenharmony_civoid UICanvas::BlendRaster(const Paint& paint,
1598a3e0fd82Sopenharmony_ci                           void* param,
1599a3e0fd82Sopenharmony_ci                           RasterizerScanlineAntialias& blendRasterizer,
1600a3e0fd82Sopenharmony_ci                           RasterizerScanlineAntialias& rasterizer,
1601a3e0fd82Sopenharmony_ci                           RenderBase& renBase,
1602a3e0fd82Sopenharmony_ci                           TransAffine& transform,
1603a3e0fd82Sopenharmony_ci                           SpanBase& spanGen,
1604a3e0fd82Sopenharmony_ci                           const Rect& rect,
1605a3e0fd82Sopenharmony_ci                           bool isStroke)
1606a3e0fd82Sopenharmony_ci{
1607a3e0fd82Sopenharmony_ci    TransAffine gradientMatrixBlend;
1608a3e0fd82Sopenharmony_ci    GeometryScanline scanline1;
1609a3e0fd82Sopenharmony_ci    GeometryScanline scanline2;
1610a3e0fd82Sopenharmony_ci    FillBase allocator1;
1611a3e0fd82Sopenharmony_ci
1612a3e0fd82Sopenharmony_ci    if (IsSoild(paint)) {
1613a3e0fd82Sopenharmony_ci        Rgba8T blendColor;
1614a3e0fd82Sopenharmony_ci        DrawCanvas::RenderBlendSolid(paint, blendColor, isStroke);
1615a3e0fd82Sopenharmony_ci        SpanSoildColor spanBlendSoildColor(blendColor);
1616a3e0fd82Sopenharmony_ci        BlendScanLine(paint.GetGlobalCompositeOperation(), blendRasterizer, rasterizer,
1617a3e0fd82Sopenharmony_ci                      scanline1, scanline2, renBase, allocator1, spanBlendSoildColor, spanGen);
1618a3e0fd82Sopenharmony_ci    }
1619a3e0fd82Sopenharmony_ci#if defined(GRAPHIC_ENABLE_GRADIENT_FILL_FLAG) && GRAPHIC_ENABLE_GRADIENT_FILL_FLAG
1620a3e0fd82Sopenharmony_ci    FillInterpolator interpolatorTypeBlend(gradientMatrixBlend);
1621a3e0fd82Sopenharmony_ci    FillGradientLut gradientColorModeBlend;
1622a3e0fd82Sopenharmony_ci    if (paint.GetStyle() == Paint::GRADIENT) {
1623a3e0fd82Sopenharmony_ci        DrawCanvas::BuildGradientColor(paint, gradientColorModeBlend);
1624a3e0fd82Sopenharmony_ci        if (paint.GetGradient() == Paint::Linear) {
1625a3e0fd82Sopenharmony_ci            float distance = 0;
1626a3e0fd82Sopenharmony_ci            DrawCanvas::BuildLineGradientMatrix(paint, gradientMatrixBlend, transform, distance);
1627a3e0fd82Sopenharmony_ci            GradientLinearCalculate gradientLinearCalculate;
1628a3e0fd82Sopenharmony_ci            FillGradient span(interpolatorTypeBlend, gradientLinearCalculate,
1629a3e0fd82Sopenharmony_ci                                    gradientColorModeBlend, 0, distance);
1630a3e0fd82Sopenharmony_ci            BlendScanLine(paint.GetGlobalCompositeOperation(), blendRasterizer, rasterizer,
1631a3e0fd82Sopenharmony_ci                          scanline1, scanline2, renBase, allocator1, span, spanGen);
1632a3e0fd82Sopenharmony_ci        } else if (paint.GetGradient() == Paint::Radial) {
1633a3e0fd82Sopenharmony_ci            Paint::RadialGradientPoint radialPoint = paint.GetRadialGradientPoint();
1634a3e0fd82Sopenharmony_ci            float startRadius = 0;
1635a3e0fd82Sopenharmony_ci            float endRadius = 0;
1636a3e0fd82Sopenharmony_ci            DrawCanvas::BuildRadialGradientMatrix(paint, gradientMatrixBlend, transform, startRadius, endRadius);
1637a3e0fd82Sopenharmony_ci            GradientRadialCalculate gradientRadialCalculate(endRadius, radialPoint.x0 - radialPoint.x1,
1638a3e0fd82Sopenharmony_ci                                                            radialPoint.y0 - radialPoint.y1);
1639a3e0fd82Sopenharmony_ci            FillGradient span(interpolatorTypeBlend, gradientRadialCalculate, gradientColorModeBlend,
1640a3e0fd82Sopenharmony_ci                                    startRadius, endRadius);
1641a3e0fd82Sopenharmony_ci            BlendScanLine(paint.GetGlobalCompositeOperation(), blendRasterizer, rasterizer,
1642a3e0fd82Sopenharmony_ci                          scanline1, scanline2, renBase, allocator1, span, spanGen);
1643a3e0fd82Sopenharmony_ci        }
1644a3e0fd82Sopenharmony_ci    }
1645a3e0fd82Sopenharmony_ci#endif
1646a3e0fd82Sopenharmony_ci#if defined(GRAPHIC_ENABLE_PATTERN_FILL_FLAG) && GRAPHIC_ENABLE_PATTERN_FILL_FLAG
1647a3e0fd82Sopenharmony_ci    if (paint.GetStyle() == Paint::PATTERN) {
1648a3e0fd82Sopenharmony_ci        if (param == nullptr) {
1649a3e0fd82Sopenharmony_ci            return;
1650a3e0fd82Sopenharmony_ci        }
1651a3e0fd82Sopenharmony_ci
1652a3e0fd82Sopenharmony_ci        PathParam* pathParam = static_cast<PathParam*>(param);
1653a3e0fd82Sopenharmony_ci
1654a3e0fd82Sopenharmony_ci        ImageParam* imageParam = static_cast<ImageParam*>(pathParam->imageParam);
1655a3e0fd82Sopenharmony_ci
1656a3e0fd82Sopenharmony_ci        if (imageParam->image == nullptr) {
1657a3e0fd82Sopenharmony_ci            return;
1658a3e0fd82Sopenharmony_ci        }
1659a3e0fd82Sopenharmony_ci        FillPatternRgba spanPattern(imageParam->image->GetImageInfo(), paint.GetPatternRepeatMode(), rect.GetLeft(),
1660a3e0fd82Sopenharmony_ci                                    rect.GetTop());
1661a3e0fd82Sopenharmony_ci        BlendScanLine(paint.GetGlobalCompositeOperation(), blendRasterizer, rasterizer,
1662a3e0fd82Sopenharmony_ci                      scanline1, scanline2, renBase, allocator1, spanPattern, spanGen);
1663a3e0fd82Sopenharmony_ci    }
1664a3e0fd82Sopenharmony_ci#endif
1665a3e0fd82Sopenharmony_ci}
1666a3e0fd82Sopenharmony_ci#endif // ENABLE_CANVAS_EXTEND
1667a3e0fd82Sopenharmony_ci} // namespace OHOS
1668