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