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