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