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