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