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