• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2020-2021 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 #include "common/image.h"
18 #include "draw/draw_arc.h"
19 #include "draw/draw_image.h"
20 #include "engines/gfx/gfx_engine_manager.h"
21 #include "gfx_utils/graphic_log.h"
22 
23 namespace OHOS {
~UICanvasPath()24 UICanvas::UICanvasPath::~UICanvasPath()
25 {
26     points_.Clear();
27     cmd_.Clear();
28     arcParam_.Clear();
29 }
30 
BeginPath()31 void UICanvas::BeginPath()
32 {
33     /* If the previous path is not added to the drawing linked list, it should be destroyed directly. */
34     if (path_ != nullptr && path_->strokeCount_ == 0) {
35         delete path_;
36         path_ = nullptr;
37     }
38 
39     path_ = new UICanvasPath();
40     if (path_ == nullptr) {
41         GRAPHIC_LOGE("new UICanvasPath fail");
42         return;
43     }
44 }
45 
MoveTo(const Point & point)46 void UICanvas::MoveTo(const Point& point)
47 {
48     if (path_ == nullptr) {
49         return;
50     }
51 
52     path_->startPos_ = point;
53     /* If the previous command is also CMD_MOVE_TO, the previous command is overwritten. */
54     if ((path_->cmd_.Size() != 0) && (path_->cmd_.Tail()->data_ == CMD_MOVE_TO)) {
55         path_->points_.Tail()->data_ = point;
56         return;
57     }
58     path_->points_.PushBack(point);
59     path_->cmd_.PushBack(CMD_MOVE_TO);
60 }
61 
LineTo(const Point & point)62 void UICanvas::LineTo(const Point& point)
63 {
64     if (path_ == nullptr) {
65         return;
66     }
67 
68     path_->points_.PushBack(point);
69     if (path_->cmd_.Size() == 0) {
70         path_->startPos_ = point;
71         path_->cmd_.PushBack(CMD_MOVE_TO);
72     } else {
73         path_->cmd_.PushBack(CMD_LINE_TO);
74     }
75 }
76 
ArcTo(const Point & center,uint16_t radius,int16_t startAngle,int16_t endAngle)77 void UICanvas::ArcTo(const Point& center, uint16_t radius, int16_t startAngle, int16_t endAngle)
78 {
79     if (path_ == nullptr) {
80         return;
81     }
82 
83     /*
84      * If there is no command before CMD_ARC, only the arc is drawn. If there is a command in front of
85      * CMD_ARC, the start point of arc must be connected to the end point of the path.
86      */
87     float sinma = radius * Sin(startAngle);
88     float cosma = radius * Sin(QUARTER_IN_DEGREE - startAngle);
89     if (path_->cmd_.Size() != 0) {
90         path_->points_.PushBack({MATH_ROUND(center.x + sinma), MATH_ROUND(center.y - cosma)});
91         path_->cmd_.PushBack(CMD_LINE_TO);
92     } else {
93         path_->startPos_ = {MATH_ROUND(center.x + sinma), MATH_ROUND(center.y - cosma)};
94     }
95 
96     /* If the ARC scan range exceeds 360 degrees, the end point of the path is the position of the start angle. */
97     if (MATH_ABS(startAngle - endAngle) < CIRCLE_IN_DEGREE) {
98         sinma = radius * Sin(endAngle);
99         cosma = radius * Sin(QUARTER_IN_DEGREE - endAngle);
100     }
101     path_->points_.PushBack({MATH_ROUND(center.x + sinma), MATH_ROUND(center.y - cosma)});
102     path_->cmd_.PushBack(CMD_ARC);
103 
104     int16_t start;
105     int16_t end;
106     if (startAngle > endAngle) {
107         start = endAngle;
108         end = startAngle;
109     } else {
110         start = startAngle;
111         end = endAngle;
112     }
113 
114     DrawArc::GetInstance()->GetDrawRange(start, end);
115     ArcParam param;
116     param.center = center;
117     param.radius = radius;
118     param.startAngle = start;
119     param.endAngle = end;
120     path_->arcParam_.PushBack(param);
121 }
122 
AddRect(const Point & point,int16_t height,int16_t width)123 void UICanvas::AddRect(const Point& point, int16_t height, int16_t width)
124 {
125     if (path_ == nullptr) {
126         return;
127     }
128 
129     MoveTo(point);
130     LineTo({static_cast<int16_t>(point.x + width), point.y});
131     LineTo({static_cast<int16_t>(point.x + width), static_cast<int16_t>(point.y + height)});
132     LineTo({point.x, static_cast<int16_t>(point.y + height)});
133     ClosePath();
134 }
135 
ClosePath()136 void UICanvas::ClosePath()
137 {
138     if ((path_ == nullptr) || (path_->cmd_.Size() == 0)) {
139         return;
140     }
141 
142     path_->points_.PushBack(path_->startPos_);
143     path_->cmd_.PushBack(CMD_CLOSE);
144 }
145 
~UICanvas()146 UICanvas::~UICanvas()
147 {
148     if ((path_ != nullptr) && (path_->strokeCount_ == 0)) {
149         delete path_;
150         path_ = nullptr;
151     }
152 
153     void* param = nullptr;
154     ListNode<DrawCmd>* curDraw = drawCmdList_.Begin();
155     for (; curDraw != drawCmdList_.End(); curDraw = curDraw->next_) {
156         param = curDraw->data_.param;
157         curDraw->data_.DeleteParam(param);
158         curDraw->data_.param = nullptr;
159     }
160     drawCmdList_.Clear();
161 }
162 
Clear()163 void UICanvas::Clear()
164 {
165     if ((path_ != nullptr) && (path_->strokeCount_ == 0)) {
166         delete path_;
167         path_ = nullptr;
168     }
169 
170     void* param = nullptr;
171     ListNode<DrawCmd>* curDraw = drawCmdList_.Begin();
172     for (; curDraw != drawCmdList_.End(); curDraw = curDraw->next_) {
173         param = curDraw->data_.param;
174         curDraw->data_.DeleteParam(param);
175         curDraw->data_.param = nullptr;
176     }
177     drawCmdList_.Clear();
178     Invalidate();
179 }
180 
DrawLine(const Point & endPoint,const Paint & paint)181 void UICanvas::DrawLine(const Point& endPoint, const Paint& paint)
182 {
183     DrawLine(startPoint_, endPoint, paint);
184 }
185 
DrawLine(const Point & startPoint,const Point & endPoint,const Paint & paint)186 void UICanvas::DrawLine(const Point& startPoint, const Point& endPoint, const Paint& paint)
187 {
188     LineParam* lineParam = new LineParam;
189     if (lineParam == nullptr) {
190         GRAPHIC_LOGE("new LineParam fail");
191         return;
192     }
193     lineParam->start = startPoint;
194     lineParam->end = endPoint;
195 
196     DrawCmd cmd;
197     cmd.paint = paint;
198     cmd.param = lineParam;
199     cmd.DeleteParam = DeleteLineParam;
200     cmd.DrawGraphics = DoDrawLine;
201     drawCmdList_.PushBack(cmd);
202 
203     Invalidate();
204     SetStartPosition(endPoint);
205 }
206 
DrawCurve(const Point & control1,const Point & control2,const Point & endPoint,const Paint & paint)207 void UICanvas::DrawCurve(const Point& control1, const Point& control2, const Point& endPoint, const Paint& paint)
208 {
209     DrawCurve(startPoint_, control1, control2, endPoint, paint);
210 }
211 
DrawCurve(const Point & startPoint,const Point & control1,const Point & control2,const Point & endPoint,const Paint & paint)212 void UICanvas::DrawCurve(const Point& startPoint,
213                          const Point& control1,
214                          const Point& control2,
215                          const Point& endPoint,
216                          const Paint& paint)
217 {
218     CurveParam* curveParam = new CurveParam;
219     if (curveParam == nullptr) {
220         GRAPHIC_LOGE("new CurveParam fail");
221         return;
222     }
223     curveParam->start = startPoint;
224     curveParam->control1 = control1;
225     curveParam->control2 = control2;
226     curveParam->end = endPoint;
227 
228     DrawCmd cmd;
229     cmd.paint = paint;
230     if (paint.GetStrokeWidth() > MAX_CURVE_WIDTH) {
231         cmd.paint.SetStrokeWidth(MAX_CURVE_WIDTH);
232     }
233     cmd.param = curveParam;
234     cmd.DeleteParam = DeleteCurveParam;
235     cmd.DrawGraphics = DoDrawCurve;
236     drawCmdList_.PushBack(cmd);
237 
238     Invalidate();
239     SetStartPosition(endPoint);
240 }
241 
DrawRect(const Point & startPoint,int16_t height,int16_t width,const Paint & paint)242 void UICanvas::DrawRect(const Point& startPoint, int16_t height, int16_t width, const Paint& paint)
243 {
244     if (static_cast<uint8_t>(paint.GetStyle()) & Paint::PaintStyle::STROKE_STYLE) {
245         RectParam* rectParam = new RectParam;
246         if (rectParam == nullptr) {
247             GRAPHIC_LOGE("new RectParam fail");
248             return;
249         }
250         rectParam->start = startPoint;
251         rectParam->height = height;
252         rectParam->width = width;
253 
254         DrawCmd cmd;
255         cmd.paint = paint;
256         cmd.param = rectParam;
257         cmd.DeleteParam = DeleteRectParam;
258         cmd.DrawGraphics = DoDrawRect;
259         drawCmdList_.PushBack(cmd);
260     }
261 
262     if (static_cast<uint8_t>(paint.GetStyle()) & Paint::PaintStyle::FILL_STYLE) {
263         RectParam* rectParam = new RectParam;
264         if (rectParam == nullptr) {
265             GRAPHIC_LOGE("new RectParam fail");
266             return;
267         }
268         rectParam->start = startPoint;
269         rectParam->height = height;
270         rectParam->width = width;
271 
272         DrawCmd cmd;
273         cmd.paint = paint;
274         cmd.param = rectParam;
275         cmd.DeleteParam = DeleteRectParam;
276         cmd.DrawGraphics = DoFillRect;
277         drawCmdList_.PushBack(cmd);
278     }
279 
280     Invalidate();
281 }
282 
DrawCircle(const Point & center,uint16_t radius,const Paint & paint)283 void UICanvas::DrawCircle(const Point& center, uint16_t radius, const Paint& paint)
284 {
285     CircleParam* circleParam = new CircleParam;
286     if (circleParam == nullptr) {
287         GRAPHIC_LOGE("new CircleParam fail");
288         return;
289     }
290     circleParam->center = center;
291     circleParam->radius = radius;
292 
293     DrawCmd cmd;
294     cmd.paint = paint;
295     cmd.param = circleParam;
296     cmd.DeleteParam = DeleteCircleParam;
297     cmd.DrawGraphics = DoDrawCircle;
298     drawCmdList_.PushBack(cmd);
299 
300     Invalidate();
301 }
302 
DrawSector(const Point & center,uint16_t radius,int16_t startAngle,int16_t endAngle,const Paint & paint)303 void UICanvas::DrawSector(const Point& center,
304                           uint16_t radius,
305                           int16_t startAngle,
306                           int16_t endAngle,
307                           const Paint& paint)
308 {
309     if (static_cast<uint8_t>(paint.GetStyle()) & Paint::PaintStyle::FILL_STYLE) {
310         Paint innerPaint = paint;
311         innerPaint.SetStyle(Paint::PaintStyle::STROKE_STYLE);
312         innerPaint.SetStrokeWidth(radius);
313         innerPaint.SetStrokeColor(paint.GetFillColor());
314         radius >>= 1;
315         DrawArc(center, radius, startAngle, endAngle, innerPaint);
316     }
317 }
318 
DrawArc(const Point & center,uint16_t radius,int16_t startAngle,int16_t endAngle,const Paint & paint)319 void UICanvas::DrawArc(const Point& center, uint16_t radius, int16_t startAngle, int16_t endAngle, const Paint& paint)
320 {
321     if (static_cast<uint8_t>(paint.GetStyle()) & Paint::PaintStyle::STROKE_STYLE) {
322         ArcParam* arcParam = new ArcParam;
323         if (arcParam == nullptr) {
324             GRAPHIC_LOGE("new ArcParam fail");
325             return;
326         }
327         arcParam->center = center;
328         arcParam->radius = radius;
329 
330         int16_t start;
331         int16_t end;
332         if (startAngle > endAngle) {
333             start = endAngle;
334             end = startAngle;
335         } else {
336             start = startAngle;
337             end = endAngle;
338         }
339 
340         DrawArc::GetInstance()->GetDrawRange(start, end);
341         arcParam->startAngle = start;
342         arcParam->endAngle = end;
343 
344         DrawCmd cmd;
345         cmd.paint = paint;
346         cmd.param = arcParam;
347         cmd.DeleteParam = DeleteArcParam;
348         cmd.DrawGraphics = DoDrawArc;
349         drawCmdList_.PushBack(cmd);
350 
351         Invalidate();
352     }
353 }
354 
DrawLabel(const Point & startPoint,const char * text,uint16_t maxWidth,const FontStyle & fontStyle,const Paint & paint)355 void UICanvas::DrawLabel(const Point& startPoint,
356                          const char* text,
357                          uint16_t maxWidth,
358                          const FontStyle& fontStyle,
359                          const Paint& paint)
360 {
361     if (text == nullptr) {
362         return;
363     }
364     if (static_cast<uint8_t>(paint.GetStyle()) & Paint::PaintStyle::FILL_STYLE) {
365         UILabel* label = new UILabel();
366         if (label == nullptr) {
367             GRAPHIC_LOGE("new UILabel fail");
368             return;
369         }
370         label->SetLineBreakMode(UILabel::LINE_BREAK_CLIP);
371         label->SetPosition(startPoint.x, startPoint.y);
372         label->SetWidth(maxWidth);
373         label->SetHeight(GetHeight());
374         label->SetText(text);
375         label->SetFont(fontStyle.fontName, fontStyle.fontSize);
376         label->SetAlign(fontStyle.align);
377         label->SetDirect(fontStyle.direct);
378         label->SetStyle(STYLE_LETTER_SPACE, fontStyle.letterSpace);
379         label->SetStyle(STYLE_TEXT_COLOR, paint.GetFillColor().full);
380         label->SetStyle(STYLE_TEXT_OPA, paint.GetOpacity());
381 
382         DrawCmd cmd;
383         cmd.param = label;
384         cmd.DeleteParam = DeleteLabel;
385         cmd.DrawGraphics = DoDrawLabel;
386         drawCmdList_.PushBack(cmd);
387 
388         Invalidate();
389     }
390 }
391 
DrawImage(const Point & startPoint,const char * image,const Paint & paint)392 void UICanvas::DrawImage(const Point& startPoint, const char* image, const Paint& paint)
393 {
394     if (image == nullptr) {
395         return;
396     }
397 
398     ImageParam* imageParam = new ImageParam;
399     if (imageParam == nullptr) {
400         GRAPHIC_LOGE("new ImageParam fail");
401         return;
402     }
403     imageParam->image = new Image();
404     if (imageParam->image == nullptr) {
405         delete imageParam;
406         imageParam = nullptr;
407         return;
408     }
409 
410     imageParam->image->SetSrc(image);
411     ImageHeader header = {0};
412     imageParam->image->GetHeader(header);
413     imageParam->start = startPoint;
414     imageParam->height = header.height;
415     imageParam->width = header.width;
416 
417     DrawCmd cmd;
418     cmd.paint = paint;
419     cmd.param = imageParam;
420     cmd.DeleteParam = DeleteImageParam;
421     cmd.DrawGraphics = DoDrawImage;
422     drawCmdList_.PushBack(cmd);
423 
424     Invalidate();
425 }
426 
DrawPath(const Paint & paint)427 void UICanvas::DrawPath(const Paint& paint)
428 {
429     if ((path_ == nullptr) || (path_->cmd_.Size() == 0)) {
430         return;
431     }
432 
433     path_->strokeCount_++;
434     PathParam* param = new PathParam;
435     if (param == nullptr) {
436         GRAPHIC_LOGE("new PathParam fail");
437         return;
438     }
439     param->path = path_;
440     param->count = path_->cmd_.Size();
441 
442     DrawCmd cmd;
443     cmd.paint = paint;
444     cmd.param = param;
445     cmd.DeleteParam = DeletePathParam;
446     cmd.DrawGraphics = DoDrawPath;
447     drawCmdList_.PushBack(cmd);
448     Invalidate();
449 }
450 
OnDraw(BufferInfo & gfxDstBuffer,const Rect & invalidatedArea)451 void UICanvas::OnDraw(BufferInfo& gfxDstBuffer, const Rect& invalidatedArea)
452 {
453     Rect rect = GetOrigRect();
454     BaseGfxEngine::GetInstance()->DrawRect(gfxDstBuffer, rect, invalidatedArea, *style_, opaScale_);
455 
456     void* param = nullptr;
457     ListNode<DrawCmd>* curDraw = drawCmdList_.Begin();
458     Rect coords = GetOrigRect();
459     Rect trunc = invalidatedArea;
460     if (trunc.Intersect(trunc, coords)) {
461         for (; curDraw != drawCmdList_.End(); curDraw = curDraw->next_) {
462             param = curDraw->data_.param;
463             curDraw->data_.DrawGraphics(gfxDstBuffer, param, curDraw->data_.paint, rect, trunc, *style_);
464         }
465     }
466 }
467 
GetAbsolutePosition(const Point & prePoint,const Rect & rect,const Style & style,Point & point)468 void UICanvas::GetAbsolutePosition(const Point& prePoint, const Rect& rect, const Style& style, Point& point)
469 {
470     point.x = prePoint.x + rect.GetLeft() + style.paddingLeft_ + style.borderWidth_;
471     point.y = prePoint.y + rect.GetTop() + style.paddingTop_ + style.borderWidth_;
472 }
473 
DoDrawLine(BufferInfo & gfxDstBuffer,void * param,const Paint & paint,const Rect & rect,const Rect & invalidatedArea,const Style & style)474 void UICanvas::DoDrawLine(BufferInfo& gfxDstBuffer,
475                           void* param,
476                           const Paint& paint,
477                           const Rect& rect,
478                           const Rect& invalidatedArea,
479                           const Style& style)
480 {
481     if (param == nullptr) {
482         return;
483     }
484     LineParam* lineParam = static_cast<LineParam*>(param);
485     Point start;
486     Point end;
487     GetAbsolutePosition(lineParam->start, rect, style, start);
488     GetAbsolutePosition(lineParam->end, rect, style, end);
489 
490     BaseGfxEngine::GetInstance()->DrawLine(gfxDstBuffer, start, end, invalidatedArea, paint.GetStrokeWidth(),
491                                            paint.GetStrokeColor(), paint.GetOpacity());
492 }
493 
DoDrawCurve(BufferInfo & gfxDstBuffer,void * param,const Paint & paint,const Rect & rect,const Rect & invalidatedArea,const Style & style)494 void UICanvas::DoDrawCurve(BufferInfo& gfxDstBuffer,
495                            void* param,
496                            const Paint& paint,
497                            const Rect& rect,
498                            const Rect& invalidatedArea,
499                            const Style& style)
500 {
501     if (param == nullptr) {
502         return;
503     }
504     CurveParam* curveParam = static_cast<CurveParam*>(param);
505     Point start;
506     Point end;
507     Point control1;
508     Point control2;
509     GetAbsolutePosition(curveParam->start, rect, style, start);
510     GetAbsolutePosition(curveParam->end, rect, style, end);
511     GetAbsolutePosition(curveParam->control1, rect, style, control1);
512     GetAbsolutePosition(curveParam->control2, rect, style, control2);
513 
514     BaseGfxEngine::GetInstance()->DrawCubicBezier(gfxDstBuffer, start, control1, control2, end, invalidatedArea,
515                                                   paint.GetStrokeWidth(), paint.GetStrokeColor(), paint.GetOpacity());
516 }
517 
DoDrawRect(BufferInfo & gfxDstBuffer,void * param,const Paint & paint,const Rect & rect,const Rect & invalidatedArea,const Style & style)518 void UICanvas::DoDrawRect(BufferInfo& gfxDstBuffer,
519                           void* param,
520                           const Paint& paint,
521                           const Rect& rect,
522                           const Rect& invalidatedArea,
523                           const Style& style)
524 {
525     if (param == nullptr) {
526         return;
527     }
528     RectParam* rectParam = static_cast<RectParam*>(param);
529     Style drawStyle = StyleDefault::GetDefaultStyle();
530     drawStyle.bgColor_ = paint.GetStrokeColor();
531     drawStyle.bgOpa_ = paint.GetOpacity();
532     drawStyle.borderRadius_ = 0;
533 
534     int16_t lineWidth = static_cast<int16_t>(paint.GetStrokeWidth());
535     Point start;
536     GetAbsolutePosition(rectParam->start, rect, style, start);
537 
538     int16_t x = start.x - lineWidth / 2; // 2: half
539     int16_t y = start.y - lineWidth / 2; // 2: half
540     Rect coords;
541     if ((rectParam->height <= lineWidth) || (rectParam->width <= lineWidth)) {
542         coords.SetPosition(x, y);
543         coords.SetHeight(rectParam->height + lineWidth);
544         coords.SetWidth(rectParam->width + lineWidth);
545         BaseGfxEngine::GetInstance()->DrawRect(gfxDstBuffer, coords, invalidatedArea, drawStyle, OPA_OPAQUE);
546         return;
547     }
548 
549     coords.SetPosition(x, y);
550     coords.SetHeight(lineWidth);
551     coords.SetWidth(rectParam->width);
552     BaseGfxEngine::GetInstance()->DrawRect(gfxDstBuffer, coords, invalidatedArea, drawStyle, OPA_OPAQUE);
553 
554     coords.SetPosition(x + rectParam->width, y);
555     coords.SetHeight(rectParam->height);
556     coords.SetWidth(lineWidth);
557     BaseGfxEngine::GetInstance()->DrawRect(gfxDstBuffer, coords, invalidatedArea, drawStyle, OPA_OPAQUE);
558 
559     coords.SetPosition(x, y + lineWidth);
560     coords.SetHeight(rectParam->height);
561     coords.SetWidth(lineWidth);
562     BaseGfxEngine::GetInstance()->DrawRect(gfxDstBuffer, coords, invalidatedArea, drawStyle, OPA_OPAQUE);
563 
564     coords.SetPosition(x + lineWidth, y + rectParam->height);
565     coords.SetHeight(lineWidth);
566     coords.SetWidth(rectParam->width);
567     BaseGfxEngine::GetInstance()->DrawRect(gfxDstBuffer, coords, invalidatedArea, drawStyle, OPA_OPAQUE);
568 }
569 
DoFillRect(BufferInfo & gfxDstBuffer,void * param,const Paint & paint,const Rect & rect,const Rect & invalidatedArea,const Style & style)570 void UICanvas::DoFillRect(BufferInfo& gfxDstBuffer,
571                           void* param,
572                           const Paint& paint,
573                           const Rect& rect,
574                           const Rect& invalidatedArea,
575                           const Style& style)
576 {
577     if (param == nullptr) {
578         return;
579     }
580     RectParam* rectParam = static_cast<RectParam*>(param);
581     uint8_t enableStroke = static_cast<uint8_t>(paint.GetStyle()) & Paint::PaintStyle::STROKE_STYLE;
582     int16_t lineWidth = enableStroke ? paint.GetStrokeWidth() : 0;
583     if ((rectParam->height <= lineWidth) || (rectParam->width <= lineWidth)) {
584         return;
585     }
586     Point start;
587     GetAbsolutePosition(rectParam->start, rect, style, start);
588 
589     Rect coords;
590     coords.SetPosition(start.x + (lineWidth + 1) / 2, start.y + (lineWidth + 1) / 2); // 2: half
591     coords.SetHeight(rectParam->height - lineWidth);
592     coords.SetWidth(rectParam->width - lineWidth);
593 
594     Style drawStyle = StyleDefault::GetDefaultStyle();
595     drawStyle.bgColor_ = paint.GetFillColor();
596     drawStyle.bgOpa_ = paint.GetOpacity();
597     drawStyle.borderRadius_ = 0;
598     BaseGfxEngine::GetInstance()->DrawRect(gfxDstBuffer, coords, invalidatedArea, drawStyle, OPA_OPAQUE);
599 }
600 
DoDrawCircle(BufferInfo & gfxDstBuffer,void * param,const Paint & paint,const Rect & rect,const Rect & invalidatedArea,const Style & style)601 void UICanvas::DoDrawCircle(BufferInfo& gfxDstBuffer,
602                             void* param,
603                             const Paint& paint,
604                             const Rect& rect,
605                             const Rect& invalidatedArea,
606                             const Style& style)
607 {
608     if (param == nullptr) {
609         return;
610     }
611     CircleParam* circleParam = static_cast<CircleParam*>(param);
612 
613     Style drawStyle = StyleDefault::GetDefaultStyle();
614     drawStyle.lineOpa_ = paint.GetOpacity();
615 
616     ArcInfo arcInfo = {{0}};
617     arcInfo.imgPos = Point{0, 0};
618     arcInfo.startAngle = 0;
619     arcInfo.endAngle = CIRCLE_IN_DEGREE;
620     GetAbsolutePosition(circleParam->center, rect, style, arcInfo.center);
621     uint8_t enableStroke = static_cast<uint8_t>(paint.GetStyle()) & Paint::PaintStyle::STROKE_STYLE;
622     uint16_t halfLineWidth = enableStroke ? (paint.GetStrokeWidth() >> 1) : 0;
623     if (static_cast<uint8_t>(paint.GetStyle()) & Paint::PaintStyle::FILL_STYLE) {
624         arcInfo.radius = circleParam->radius - halfLineWidth;
625         drawStyle.lineWidth_ = arcInfo.radius;
626         drawStyle.lineColor_ = paint.GetFillColor();
627         BaseGfxEngine::GetInstance()->DrawArc(gfxDstBuffer, arcInfo, invalidatedArea, drawStyle, OPA_OPAQUE,
628                                               CapType::CAP_NONE);
629     }
630 
631     if (enableStroke) {
632         arcInfo.radius = circleParam->radius + halfLineWidth - 1;
633         drawStyle.lineWidth_ = static_cast<int16_t>(paint.GetStrokeWidth());
634         drawStyle.lineColor_ = paint.GetStrokeColor();
635         BaseGfxEngine::GetInstance()->DrawArc(gfxDstBuffer, arcInfo, invalidatedArea, drawStyle, OPA_OPAQUE,
636                                               CapType::CAP_NONE);
637     }
638 }
639 
DoDrawArc(BufferInfo & gfxDstBuffer,void * param,const Paint & paint,const Rect & rect,const Rect & invalidatedArea,const Style & style)640 void UICanvas::DoDrawArc(BufferInfo& gfxDstBuffer,
641                          void* param,
642                          const Paint& paint,
643                          const Rect& rect,
644                          const Rect& invalidatedArea,
645                          const Style& style)
646 {
647     if (param == nullptr) {
648         return;
649     }
650     ArcParam* arcParam = static_cast<ArcParam*>(param);
651 
652     ArcInfo arcInfo = {{0}};
653     arcInfo.imgPos = Point{0, 0};
654     arcInfo.startAngle = arcParam->startAngle;
655     arcInfo.endAngle = arcParam->endAngle;
656     Style drawStyle = StyleDefault::GetDefaultStyle();
657     drawStyle.lineWidth_ = static_cast<int16_t>(paint.GetStrokeWidth());
658     drawStyle.lineColor_ = paint.GetStrokeColor();
659     drawStyle.lineOpa_ = paint.GetOpacity();
660     arcInfo.radius = arcParam->radius + ((paint.GetStrokeWidth() + 1) >> 1);
661 
662     GetAbsolutePosition(arcParam->center, rect, style, arcInfo.center);
663     BaseGfxEngine::GetInstance()->DrawArc(gfxDstBuffer, arcInfo, invalidatedArea, drawStyle, OPA_OPAQUE,
664                                           CapType::CAP_NONE);
665 }
666 
DoDrawImage(BufferInfo & gfxDstBuffer,void * param,const Paint & paint,const Rect & rect,const Rect & invalidatedArea,const Style & style)667 void UICanvas::DoDrawImage(BufferInfo& gfxDstBuffer,
668                            void* param,
669                            const Paint& paint,
670                            const Rect& rect,
671                            const Rect& invalidatedArea,
672                            const Style& style)
673 {
674     if (param == nullptr) {
675         return;
676     }
677     ImageParam* imageParam = static_cast<ImageParam*>(param);
678 
679     if (imageParam->image == nullptr) {
680         return;
681     }
682 
683     Point start;
684     GetAbsolutePosition(imageParam->start, rect, style, start);
685 
686     Rect cordsTmp;
687     cordsTmp.SetPosition(start.x, start.y);
688     cordsTmp.SetHeight(imageParam->height);
689     cordsTmp.SetWidth(imageParam->width);
690     DrawImage::DrawCommon(gfxDstBuffer, cordsTmp, invalidatedArea,
691                           imageParam->image->GetPath(), style, paint.GetOpacity());
692 }
693 
DoDrawLabel(BufferInfo & gfxDstBuffer,void * param,const Paint & paint,const Rect & rect,const Rect & invalidatedArea,const Style & style)694 void UICanvas::DoDrawLabel(BufferInfo& gfxDstBuffer,
695                            void* param,
696                            const Paint& paint,
697                            const Rect& rect,
698                            const Rect& invalidatedArea,
699                            const Style& style)
700 {
701     if (param == nullptr) {
702         return;
703     }
704     UILabel* label = static_cast<UILabel*>(param);
705     Point startPos = {label->GetX(), label->GetY()};
706     Point start;
707     GetAbsolutePosition({startPos.x, startPos.y}, rect, style, start);
708     label->SetPosition(start.x, start.y);
709     label->OnDraw(gfxDstBuffer, invalidatedArea);
710     label->SetPosition(startPos.x, startPos.y);
711 }
712 
DoDrawLineJoin(BufferInfo & gfxDstBuffer,const Point & center,const Rect & invalidatedArea,const Paint & paint)713 void UICanvas::DoDrawLineJoin(BufferInfo& gfxDstBuffer,
714                               const Point& center,
715                               const Rect& invalidatedArea,
716                               const Paint& paint)
717 {
718     ArcInfo arcinfo = {{0}};
719     arcinfo.center = center;
720     arcinfo.imgPos = Point{0, 0};
721     arcinfo.radius = (paint.GetStrokeWidth() + 1) >> 1;
722     arcinfo.startAngle = 0;
723     arcinfo.endAngle = CIRCLE_IN_DEGREE;
724 
725     Style style;
726     style.lineColor_ = paint.GetStrokeColor();
727     style.lineWidth_ = static_cast<int16_t>(paint.GetStrokeWidth());
728     style.lineOpa_ = OPA_OPAQUE;
729     BaseGfxEngine::GetInstance()->DrawArc(gfxDstBuffer, arcinfo, invalidatedArea, style, OPA_OPAQUE,
730                                           CapType::CAP_NONE);
731 }
732 
DoDrawPath(BufferInfo & gfxDstBuffer,void * param,const Paint & paint,const Rect & rect,const Rect & invalidatedArea,const Style & style)733 void UICanvas::DoDrawPath(BufferInfo& gfxDstBuffer,
734                           void* param,
735                           const Paint& paint,
736                           const Rect& rect,
737                           const Rect& invalidatedArea,
738                           const Style& style)
739 {
740     if (param == nullptr) {
741         return;
742     }
743     PathParam* pathParam = static_cast<PathParam*>(param);
744     const UICanvasPath* path = pathParam->path;
745     if (path == nullptr) {
746         return;
747     }
748     Point pathEnd = {COORD_MIN, COORD_MIN};
749 
750     ListNode<Point>* pointIter = path->points_.Begin();
751     ListNode<ArcParam>* arcIter = path->arcParam_.Begin();
752     ListNode<PathCmd>* iter = path->cmd_.Begin();
753     for (uint16_t i = 0; (i < pathParam->count) && (iter != path->cmd_.End()); i++, iter = iter->next_) {
754         switch (iter->data_) {
755             case CMD_MOVE_TO: {
756                 pointIter = pointIter->next_;
757                 break;
758             }
759             case CMD_LINE_TO: {
760                 Point start = pointIter->prev_->data_;
761                 Point end = pointIter->data_;
762                 pointIter = pointIter->next_;
763                 if ((start.x == end.x) && (start.y == end.y)) {
764                     break;
765                 }
766 
767                 GetAbsolutePosition(start, rect, style, start);
768                 GetAbsolutePosition(end, rect, style, end);
769                 BaseGfxEngine::GetInstance()->DrawLine(gfxDstBuffer, start, end, invalidatedArea,
770                                                        paint.GetStrokeWidth(), paint.GetStrokeColor(), OPA_OPAQUE);
771                 if ((pathEnd.x == start.x) && (pathEnd.y == start.y)) {
772                     DoDrawLineJoin(gfxDstBuffer, start, invalidatedArea, paint);
773                 }
774                 pathEnd = end;
775                 break;
776             }
777             case CMD_ARC: {
778                 ArcInfo arcInfo = {{0}};
779                 arcInfo.imgPos = Point{0, 0};
780                 arcInfo.startAngle = arcIter->data_.startAngle;
781                 arcInfo.endAngle = arcIter->data_.endAngle;
782                 Style drawStyle = StyleDefault::GetDefaultStyle();
783                 drawStyle.lineWidth_ = static_cast<int16_t>(paint.GetStrokeWidth());
784                 drawStyle.lineColor_ = paint.GetStrokeColor();
785                 drawStyle.lineOpa_ = OPA_OPAQUE;
786                 arcInfo.radius = arcIter->data_.radius + ((paint.GetStrokeWidth() + 1) >> 1);
787 
788                 GetAbsolutePosition(arcIter->data_.center, rect, style, arcInfo.center);
789                 BaseGfxEngine::GetInstance()->DrawArc(gfxDstBuffer, arcInfo, invalidatedArea, drawStyle, OPA_OPAQUE,
790                                                       CapType::CAP_NONE);
791                 if (pointIter != path->points_.Begin()) {
792                     DoDrawLineJoin(gfxDstBuffer, pathEnd, invalidatedArea, paint);
793                 }
794 
795                 GetAbsolutePosition(pointIter->data_, rect, style, pathEnd);
796                 pointIter = pointIter->next_;
797                 arcIter = arcIter->next_;
798                 break;
799             }
800             case CMD_CLOSE: {
801                 Point start = pointIter->prev_->data_;
802                 Point end = pointIter->data_;
803                 GetAbsolutePosition(start, rect, style, start);
804                 GetAbsolutePosition(end, rect, style, end);
805                 if ((start.x != end.x) || (start.y != end.y)) {
806                     BaseGfxEngine::GetInstance()->DrawLine(gfxDstBuffer, start, end, invalidatedArea,
807                                                            paint.GetStrokeWidth(), paint.GetStrokeColor(), OPA_OPAQUE);
808                     if ((pathEnd.x == start.x) && (pathEnd.y == start.y)) {
809                         DoDrawLineJoin(gfxDstBuffer, start, invalidatedArea, paint);
810                     }
811                     pathEnd = end;
812                 }
813 
814                 if ((pathEnd.x == end.x) && (pathEnd.y == end.y)) {
815                     DoDrawLineJoin(gfxDstBuffer, end, invalidatedArea, paint);
816                 }
817                 pointIter = pointIter->next_;
818                 break;
819             }
820             default:
821                 break;
822         }
823     }
824 }
825 } // namespace OHOS