mirror of
https://github.com/openharmony/graphic_ui.git
synced 2026-06-30 23:17:56 -04:00
807 lines
26 KiB
C++
Executable File
807 lines
26 KiB
C++
Executable File
/*
|
|
* Copyright (c) 2020-2021 Huawei Device Co., Ltd.
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
#include "components/ui_canvas.h"
|
|
#include "common/image.h"
|
|
#include "draw/draw_arc.h"
|
|
#include "draw/draw_curve.h"
|
|
#include "draw/draw_image.h"
|
|
#include "draw/draw_line.h"
|
|
#include "draw/draw_rect.h"
|
|
#include "graphic_log.h"
|
|
|
|
namespace OHOS {
|
|
UICanvas::UICanvasPath::~UICanvasPath()
|
|
{
|
|
points_.Clear();
|
|
cmd_.Clear();
|
|
arcParam_.Clear();
|
|
}
|
|
|
|
void UICanvas::BeginPath()
|
|
{
|
|
/* If the previous path is not added to the drawing linked list, it should be destroyed directly. */
|
|
if (path_ != nullptr && path_->strokeCount_ == 0) {
|
|
delete path_;
|
|
path_ = nullptr;
|
|
}
|
|
|
|
path_ = new UICanvasPath();
|
|
if (path_ == nullptr) {
|
|
GRAPHIC_LOGE("new UICanvasPath fail");
|
|
return;
|
|
}
|
|
}
|
|
|
|
void UICanvas::MoveTo(const Point& point)
|
|
{
|
|
if (path_ == nullptr) {
|
|
return;
|
|
}
|
|
|
|
path_->startPos_ = point;
|
|
/* If the previous command is also CMD_MOVE_TO, the previous command is overwritten. */
|
|
if ((path_->cmd_.Size() != 0) && (path_->cmd_.Tail()->data_ == CMD_MOVE_TO)) {
|
|
path_->points_.Tail()->data_ = point;
|
|
return;
|
|
}
|
|
path_->points_.PushBack(point);
|
|
path_->cmd_.PushBack(CMD_MOVE_TO);
|
|
}
|
|
|
|
void UICanvas::LineTo(const Point& point)
|
|
{
|
|
if (path_ == nullptr) {
|
|
return;
|
|
}
|
|
|
|
path_->points_.PushBack(point);
|
|
if (path_->cmd_.Size() == 0) {
|
|
path_->startPos_ = point;
|
|
path_->cmd_.PushBack(CMD_MOVE_TO);
|
|
} else {
|
|
path_->cmd_.PushBack(CMD_LINE_TO);
|
|
}
|
|
}
|
|
|
|
void UICanvas::ArcTo(const Point& center, uint16_t radius, int16_t startAngle, int16_t endAngle)
|
|
{
|
|
if (path_ == nullptr) {
|
|
return;
|
|
}
|
|
|
|
/*
|
|
* If there is no command before CMD_ARC, only the arc is drawn. If there is a command in front of
|
|
* CMD_ARC, the start point of arc must be connected to the end point of the path.
|
|
*/
|
|
float sinma = radius * Sin(startAngle);
|
|
float cosma = radius * Sin(QUARTER_IN_DEGREE - startAngle);
|
|
if (path_->cmd_.Size() != 0) {
|
|
path_->points_.PushBack({MATH_ROUND(center.x + sinma), MATH_ROUND(center.y - cosma)});
|
|
path_->cmd_.PushBack(CMD_LINE_TO);
|
|
} else {
|
|
path_->startPos_ = {MATH_ROUND(center.x + sinma), MATH_ROUND(center.y - cosma)};
|
|
}
|
|
|
|
/* If the ARC scan range exceeds 360 degrees, the end point of the path is the position of the start angle. */
|
|
if (MATH_ABS(startAngle - endAngle) < CIRCLE_IN_DEGREE) {
|
|
sinma = radius * Sin(endAngle);
|
|
cosma = radius * Sin(QUARTER_IN_DEGREE - endAngle);
|
|
}
|
|
path_->points_.PushBack({MATH_ROUND(center.x + sinma), MATH_ROUND(center.y - cosma)});
|
|
path_->cmd_.PushBack(CMD_ARC);
|
|
|
|
int16_t start;
|
|
int16_t end;
|
|
if (startAngle > endAngle) {
|
|
start = endAngle;
|
|
end = startAngle;
|
|
} else {
|
|
start = startAngle;
|
|
end = endAngle;
|
|
}
|
|
|
|
DrawArc::GetInstance()->GetDrawRange(start, end);
|
|
ArcParam param;
|
|
param.center = center;
|
|
param.radius = radius;
|
|
param.startAngle = start;
|
|
param.endAngle = end;
|
|
path_->arcParam_.PushBack(param);
|
|
}
|
|
|
|
void UICanvas::AddRect(const Point& point, int16_t height, int16_t width)
|
|
{
|
|
if (path_ == nullptr) {
|
|
return;
|
|
}
|
|
|
|
MoveTo(point);
|
|
LineTo({static_cast<int16_t>(point.x + width), point.y});
|
|
LineTo({static_cast<int16_t>(point.x + width), static_cast<int16_t>(point.y + height)});
|
|
LineTo({point.x, static_cast<int16_t>(point.y + height)});
|
|
ClosePath();
|
|
}
|
|
|
|
void UICanvas::ClosePath()
|
|
{
|
|
if ((path_ == nullptr) || (path_->cmd_.Size() == 0)) {
|
|
return;
|
|
}
|
|
|
|
path_->points_.PushBack(path_->startPos_);
|
|
path_->cmd_.PushBack(CMD_CLOSE);
|
|
}
|
|
|
|
UICanvas::~UICanvas()
|
|
{
|
|
if ((path_ != nullptr) && (path_->strokeCount_ == 0)) {
|
|
delete path_;
|
|
path_ = nullptr;
|
|
}
|
|
|
|
void* param = nullptr;
|
|
ListNode<DrawCmd>* curDraw = drawCmdList_.Begin();
|
|
for (; curDraw != drawCmdList_.End(); curDraw = curDraw->next_) {
|
|
param = curDraw->data_.param;
|
|
curDraw->data_.DeleteParam(param);
|
|
curDraw->data_.param = nullptr;
|
|
}
|
|
drawCmdList_.Clear();
|
|
}
|
|
|
|
void UICanvas::Clear()
|
|
{
|
|
if ((path_ != nullptr) && (path_->strokeCount_ == 0)) {
|
|
delete path_;
|
|
path_ = nullptr;
|
|
}
|
|
|
|
void* param = nullptr;
|
|
ListNode<DrawCmd>* curDraw = drawCmdList_.Begin();
|
|
for (; curDraw != drawCmdList_.End(); curDraw = curDraw->next_) {
|
|
param = curDraw->data_.param;
|
|
curDraw->data_.DeleteParam(param);
|
|
curDraw->data_.param = nullptr;
|
|
}
|
|
drawCmdList_.Clear();
|
|
Invalidate();
|
|
}
|
|
|
|
void UICanvas::DrawLine(const Point& endPoint, const Paint& paint)
|
|
{
|
|
DrawLine(startPoint_, endPoint, paint);
|
|
}
|
|
|
|
void UICanvas::DrawLine(const Point& startPoint, const Point& endPoint, const Paint& paint)
|
|
{
|
|
LineParam* lineParam = new LineParam;
|
|
if (lineParam == nullptr) {
|
|
GRAPHIC_LOGE("new LineParam fail");
|
|
return;
|
|
}
|
|
lineParam->start = startPoint;
|
|
lineParam->end = endPoint;
|
|
|
|
DrawCmd cmd;
|
|
cmd.paint = paint;
|
|
cmd.param = lineParam;
|
|
cmd.DeleteParam = DeleteLineParam;
|
|
cmd.DrawGraphics = DoDrawLine;
|
|
drawCmdList_.PushBack(cmd);
|
|
|
|
Invalidate();
|
|
SetStartPosition(endPoint);
|
|
}
|
|
|
|
void UICanvas::DrawCurve(const Point& control1, const Point& control2, const Point& endPoint, const Paint& paint)
|
|
{
|
|
DrawCurve(startPoint_, control1, control2, endPoint, paint);
|
|
}
|
|
|
|
void UICanvas::DrawCurve(const Point& startPoint,
|
|
const Point& control1,
|
|
const Point& control2,
|
|
const Point& endPoint,
|
|
const Paint& paint)
|
|
{
|
|
CurveParam* curveParam = new CurveParam;
|
|
if (curveParam == nullptr) {
|
|
GRAPHIC_LOGE("new CurveParam fail");
|
|
return;
|
|
}
|
|
curveParam->start = startPoint;
|
|
curveParam->control1 = control1;
|
|
curveParam->control2 = control2;
|
|
curveParam->end = endPoint;
|
|
|
|
DrawCmd cmd;
|
|
cmd.paint = paint;
|
|
if (paint.GetStrokeWidth() > MAX_CURVE_WIDTH) {
|
|
cmd.paint.SetStrokeWidth(MAX_CURVE_WIDTH);
|
|
}
|
|
cmd.param = curveParam;
|
|
cmd.DeleteParam = DeleteCurveParam;
|
|
cmd.DrawGraphics = DoDrawCurve;
|
|
drawCmdList_.PushBack(cmd);
|
|
|
|
Invalidate();
|
|
SetStartPosition(endPoint);
|
|
}
|
|
|
|
void UICanvas::DrawRect(const Point& startPoint, int16_t height, int16_t width, const Paint& paint)
|
|
{
|
|
if (static_cast<uint8_t>(paint.GetStyle()) & Paint::PaintStyle::STROKE_STYLE) {
|
|
RectParam* rectParam = new RectParam;
|
|
if (rectParam == nullptr) {
|
|
GRAPHIC_LOGE("new RectParam fail");
|
|
return;
|
|
}
|
|
rectParam->start = startPoint;
|
|
rectParam->height = height;
|
|
rectParam->width = width;
|
|
|
|
DrawCmd cmd;
|
|
cmd.paint = paint;
|
|
cmd.param = rectParam;
|
|
cmd.DeleteParam = DeleteRectParam;
|
|
cmd.DrawGraphics = DoDrawRect;
|
|
drawCmdList_.PushBack(cmd);
|
|
}
|
|
|
|
if (static_cast<uint8_t>(paint.GetStyle()) & Paint::PaintStyle::FILL_STYLE) {
|
|
RectParam* rectParam = new RectParam;
|
|
if (rectParam == nullptr) {
|
|
GRAPHIC_LOGE("new RectParam fail");
|
|
return;
|
|
}
|
|
rectParam->start = startPoint;
|
|
rectParam->height = height;
|
|
rectParam->width = width;
|
|
|
|
DrawCmd cmd;
|
|
cmd.paint = paint;
|
|
cmd.param = rectParam;
|
|
cmd.DeleteParam = DeleteRectParam;
|
|
cmd.DrawGraphics = DoFillRect;
|
|
drawCmdList_.PushBack(cmd);
|
|
}
|
|
|
|
Invalidate();
|
|
}
|
|
|
|
void UICanvas::DrawCircle(const Point& center, uint16_t radius, const Paint& paint)
|
|
{
|
|
CircleParam* circleParam = new CircleParam;
|
|
if (circleParam == nullptr) {
|
|
GRAPHIC_LOGE("new CircleParam fail");
|
|
return;
|
|
}
|
|
circleParam->center = center;
|
|
circleParam->radius = radius;
|
|
|
|
DrawCmd cmd;
|
|
cmd.paint = paint;
|
|
cmd.param = circleParam;
|
|
cmd.DeleteParam = DeleteCircleParam;
|
|
cmd.DrawGraphics = DoDrawCircle;
|
|
drawCmdList_.PushBack(cmd);
|
|
|
|
Invalidate();
|
|
}
|
|
|
|
void UICanvas::DrawSector(const Point& center,
|
|
uint16_t radius,
|
|
int16_t startAngle,
|
|
int16_t endAngle,
|
|
const Paint& paint)
|
|
{
|
|
if (static_cast<uint8_t>(paint.GetStyle()) & Paint::PaintStyle::FILL_STYLE) {
|
|
Paint innerPaint = paint;
|
|
innerPaint.SetStyle(Paint::PaintStyle::STROKE_STYLE);
|
|
innerPaint.SetStrokeWidth(radius);
|
|
innerPaint.SetStrokeColor(paint.GetFillColor());
|
|
radius >>= 1;
|
|
DrawArc(center, radius, startAngle, endAngle, innerPaint);
|
|
}
|
|
}
|
|
|
|
void UICanvas::DrawArc(const Point& center, uint16_t radius, int16_t startAngle, int16_t endAngle, const Paint& paint)
|
|
{
|
|
if (static_cast<uint8_t>(paint.GetStyle()) & Paint::PaintStyle::STROKE_STYLE) {
|
|
ArcParam* arcParam = new ArcParam;
|
|
if (arcParam == nullptr) {
|
|
GRAPHIC_LOGE("new ArcParam fail");
|
|
return;
|
|
}
|
|
arcParam->center = center;
|
|
arcParam->radius = radius;
|
|
|
|
int16_t start;
|
|
int16_t end;
|
|
if (startAngle > endAngle) {
|
|
start = endAngle;
|
|
end = startAngle;
|
|
} else {
|
|
start = startAngle;
|
|
end = endAngle;
|
|
}
|
|
|
|
DrawArc::GetInstance()->GetDrawRange(start, end);
|
|
arcParam->startAngle = start;
|
|
arcParam->endAngle = end;
|
|
|
|
DrawCmd cmd;
|
|
cmd.paint = paint;
|
|
cmd.param = arcParam;
|
|
cmd.DeleteParam = DeleteArcParam;
|
|
cmd.DrawGraphics = DoDrawArc;
|
|
drawCmdList_.PushBack(cmd);
|
|
|
|
Invalidate();
|
|
}
|
|
}
|
|
|
|
void UICanvas::DrawLabel(const Point& startPoint,
|
|
const char* text,
|
|
uint16_t maxWidth,
|
|
const FontStyle& fontStyle,
|
|
const Paint& paint)
|
|
{
|
|
if (text == nullptr) {
|
|
return;
|
|
}
|
|
if (static_cast<uint8_t>(paint.GetStyle()) & Paint::PaintStyle::FILL_STYLE) {
|
|
UILabel* label = new UILabel();
|
|
if (label == nullptr) {
|
|
GRAPHIC_LOGE("new UILabel fail");
|
|
return;
|
|
}
|
|
label->SetLineBreakMode(UILabel::LINE_BREAK_CLIP);
|
|
label->SetPosition(startPoint.x, startPoint.y);
|
|
label->SetWidth(maxWidth);
|
|
label->SetHeight(GetHeight());
|
|
label->SetText(text);
|
|
label->SetFont(fontStyle.fontName, fontStyle.fontSize);
|
|
label->SetAlign(fontStyle.align);
|
|
label->SetDirect(fontStyle.direct);
|
|
label->SetStyle(STYLE_LETTER_SPACE, fontStyle.letterSpace);
|
|
label->SetStyle(STYLE_TEXT_COLOR, paint.GetFillColor().full);
|
|
label->SetStyle(STYLE_TEXT_OPA, paint.GetOpacity());
|
|
|
|
DrawCmd cmd;
|
|
cmd.param = label;
|
|
cmd.DeleteParam = DeleteLabel;
|
|
cmd.DrawGraphics = DoDrawLabel;
|
|
drawCmdList_.PushBack(cmd);
|
|
|
|
Invalidate();
|
|
}
|
|
}
|
|
|
|
void UICanvas::DrawImage(const Point& startPoint, const char* image, const Paint& paint)
|
|
{
|
|
if (image == nullptr) {
|
|
return;
|
|
}
|
|
|
|
ImageParam* imageParam = new ImageParam;
|
|
if (imageParam == nullptr) {
|
|
GRAPHIC_LOGE("new ImageParam fail");
|
|
return;
|
|
}
|
|
imageParam->image = new Image();
|
|
if (imageParam->image == nullptr) {
|
|
delete imageParam;
|
|
imageParam = nullptr;
|
|
return;
|
|
}
|
|
|
|
imageParam->image->SetSrc(image);
|
|
ImageHeader header = {0};
|
|
imageParam->image->GetHeader(header);
|
|
imageParam->start = startPoint;
|
|
imageParam->height = header.height;
|
|
imageParam->width = header.width;
|
|
|
|
DrawCmd cmd;
|
|
cmd.paint = paint;
|
|
cmd.param = imageParam;
|
|
cmd.DeleteParam = DeleteImageParam;
|
|
cmd.DrawGraphics = DoDrawImage;
|
|
drawCmdList_.PushBack(cmd);
|
|
|
|
Invalidate();
|
|
}
|
|
|
|
void UICanvas::DrawPath(const Paint& paint)
|
|
{
|
|
if ((path_ == nullptr) || (path_->cmd_.Size() == 0)) {
|
|
return;
|
|
}
|
|
|
|
path_->strokeCount_++;
|
|
PathParam* param = new PathParam;
|
|
if (param == nullptr) {
|
|
GRAPHIC_LOGE("new PathParam fail");
|
|
return;
|
|
}
|
|
param->path = path_;
|
|
param->count = path_->cmd_.Size();
|
|
|
|
DrawCmd cmd;
|
|
cmd.paint = paint;
|
|
cmd.param = param;
|
|
cmd.DeleteParam = DeletePathParam;
|
|
cmd.DrawGraphics = DoDrawPath;
|
|
drawCmdList_.PushBack(cmd);
|
|
Invalidate();
|
|
}
|
|
|
|
void UICanvas::OnDraw(const Rect& invalidatedArea)
|
|
{
|
|
Rect rect = GetOrigRect();
|
|
DrawRect::Draw(rect, invalidatedArea, *style_, opaScale_);
|
|
|
|
void* param = nullptr;
|
|
ListNode<DrawCmd>* curDraw = drawCmdList_.Begin();
|
|
Rect coords = GetOrigRect();
|
|
Rect trunc = invalidatedArea;
|
|
if (trunc.Intersect(trunc, coords)) {
|
|
for (; curDraw != drawCmdList_.End(); curDraw = curDraw->next_) {
|
|
param = curDraw->data_.param;
|
|
curDraw->data_.DrawGraphics(param, curDraw->data_.paint, rect, trunc, *style_);
|
|
}
|
|
}
|
|
}
|
|
|
|
void UICanvas::GetAbsolutePosition(const Point& prePoint, const Rect& rect, const Style& style, Point& point)
|
|
{
|
|
point.x = prePoint.x + rect.GetLeft() + style.paddingLeft_ + style.borderWidth_;
|
|
point.y = prePoint.y + rect.GetTop() + style.paddingTop_ + style.borderWidth_;
|
|
}
|
|
|
|
void UICanvas::DoDrawLine(void* param,
|
|
const Paint& paint,
|
|
const Rect& rect,
|
|
const Rect& invalidatedArea,
|
|
const Style& style)
|
|
{
|
|
if (param == nullptr) {
|
|
return;
|
|
}
|
|
LineParam* lineParam = static_cast<LineParam*>(param);
|
|
Point start;
|
|
Point end;
|
|
GetAbsolutePosition(lineParam->start, rect, style, start);
|
|
GetAbsolutePosition(lineParam->end, rect, style, end);
|
|
|
|
DrawLine::Draw(start, end, invalidatedArea, paint.GetStrokeWidth(), paint.GetStrokeColor(), paint.GetOpacity());
|
|
}
|
|
|
|
void UICanvas::DoDrawCurve(void* param,
|
|
const Paint& paint,
|
|
const Rect& rect,
|
|
const Rect& invalidatedArea,
|
|
const Style& style)
|
|
{
|
|
if (param == nullptr) {
|
|
return;
|
|
}
|
|
CurveParam* curveParam = static_cast<CurveParam*>(param);
|
|
Point start;
|
|
Point end;
|
|
Point control1;
|
|
Point control2;
|
|
GetAbsolutePosition(curveParam->start, rect, style, start);
|
|
GetAbsolutePosition(curveParam->end, rect, style, end);
|
|
GetAbsolutePosition(curveParam->control1, rect, style, control1);
|
|
GetAbsolutePosition(curveParam->control2, rect, style, control2);
|
|
|
|
DrawCurve::DrawCubicBezier(start, control1, control2, end, invalidatedArea, paint.GetStrokeWidth(),
|
|
paint.GetStrokeColor(), paint.GetOpacity());
|
|
}
|
|
|
|
void UICanvas::DoDrawRect(void* param,
|
|
const Paint& paint,
|
|
const Rect& rect,
|
|
const Rect& invalidatedArea,
|
|
const Style& style)
|
|
{
|
|
if (param == nullptr) {
|
|
return;
|
|
}
|
|
RectParam* rectParam = static_cast<RectParam*>(param);
|
|
Style drawStyle = StyleDefault::GetDefaultStyle();
|
|
drawStyle.bgColor_ = paint.GetStrokeColor();
|
|
drawStyle.bgOpa_ = paint.GetOpacity();
|
|
drawStyle.borderRadius_ = 0;
|
|
|
|
int16_t lineWidth = static_cast<int16_t>(paint.GetStrokeWidth());
|
|
Point start;
|
|
GetAbsolutePosition(rectParam->start, rect, style, start);
|
|
|
|
int16_t x = start.x - lineWidth / 2; // 2: half
|
|
int16_t y = start.y - lineWidth / 2; // 2: half
|
|
Rect coords;
|
|
if ((rectParam->height <= lineWidth) || (rectParam->width <= lineWidth)) {
|
|
coords.SetPosition(x, y);
|
|
coords.SetHeight(rectParam->height + lineWidth);
|
|
coords.SetWidth(rectParam->width + lineWidth);
|
|
DrawRect::Draw(coords, invalidatedArea, drawStyle, OPA_OPAQUE);
|
|
return;
|
|
}
|
|
|
|
coords.SetPosition(x, y);
|
|
coords.SetHeight(lineWidth);
|
|
coords.SetWidth(rectParam->width);
|
|
DrawRect::Draw(coords, invalidatedArea, drawStyle, OPA_OPAQUE);
|
|
|
|
coords.SetPosition(x + rectParam->width, y);
|
|
coords.SetHeight(rectParam->height);
|
|
coords.SetWidth(lineWidth);
|
|
DrawRect::Draw(coords, invalidatedArea, drawStyle, OPA_OPAQUE);
|
|
|
|
coords.SetPosition(x, y + lineWidth);
|
|
coords.SetHeight(rectParam->height);
|
|
coords.SetWidth(lineWidth);
|
|
DrawRect::Draw(coords, invalidatedArea, drawStyle, OPA_OPAQUE);
|
|
|
|
coords.SetPosition(x + lineWidth, y + rectParam->height);
|
|
coords.SetHeight(lineWidth);
|
|
coords.SetWidth(rectParam->width);
|
|
DrawRect::Draw(coords, invalidatedArea, drawStyle, OPA_OPAQUE);
|
|
}
|
|
|
|
void UICanvas::DoFillRect(void* param,
|
|
const Paint& paint,
|
|
const Rect& rect,
|
|
const Rect& invalidatedArea,
|
|
const Style& style)
|
|
{
|
|
if (param == nullptr) {
|
|
return;
|
|
}
|
|
RectParam* rectParam = static_cast<RectParam*>(param);
|
|
uint8_t enableStroke = static_cast<uint8_t>(paint.GetStyle()) & Paint::PaintStyle::STROKE_STYLE;
|
|
int16_t lineWidth = enableStroke ? paint.GetStrokeWidth() : 0;
|
|
if ((rectParam->height <= lineWidth) || (rectParam->width <= lineWidth)) {
|
|
return;
|
|
}
|
|
Point start;
|
|
GetAbsolutePosition(rectParam->start, rect, style, start);
|
|
|
|
Rect coords;
|
|
coords.SetPosition(start.x + (lineWidth + 1) / 2, start.y + (lineWidth + 1) / 2); // 2: half
|
|
coords.SetHeight(rectParam->height - lineWidth);
|
|
coords.SetWidth(rectParam->width - lineWidth);
|
|
|
|
Style drawStyle = StyleDefault::GetDefaultStyle();
|
|
drawStyle.bgColor_ = paint.GetFillColor();
|
|
drawStyle.bgOpa_ = paint.GetOpacity();
|
|
drawStyle.borderRadius_ = 0;
|
|
DrawRect::Draw(coords, invalidatedArea, drawStyle, OPA_OPAQUE);
|
|
}
|
|
|
|
void UICanvas::DoDrawCircle(void* param,
|
|
const Paint& paint,
|
|
const Rect& rect,
|
|
const Rect& invalidatedArea,
|
|
const Style& style)
|
|
{
|
|
if (param == nullptr) {
|
|
return;
|
|
}
|
|
CircleParam* circleParam = static_cast<CircleParam*>(param);
|
|
|
|
Style drawStyle = StyleDefault::GetDefaultStyle();
|
|
drawStyle.lineOpa_ = paint.GetOpacity();
|
|
|
|
ArcInfo arcInfo = {{0}};
|
|
arcInfo.imgPos = Point{0, 0};
|
|
arcInfo.startAngle = 0;
|
|
arcInfo.endAngle = CIRCLE_IN_DEGREE;
|
|
GetAbsolutePosition(circleParam->center, rect, style, arcInfo.center);
|
|
uint8_t enableStroke = static_cast<uint8_t>(paint.GetStyle()) & Paint::PaintStyle::STROKE_STYLE;
|
|
uint16_t halfLineWidth = enableStroke ? (paint.GetStrokeWidth() >> 1) : 0;
|
|
if (static_cast<uint8_t>(paint.GetStyle()) & Paint::PaintStyle::FILL_STYLE) {
|
|
arcInfo.radius = circleParam->radius - halfLineWidth;
|
|
drawStyle.lineWidth_ = arcInfo.radius;
|
|
drawStyle.lineColor_ = paint.GetFillColor();
|
|
DrawArc::GetInstance()->Draw(arcInfo, invalidatedArea, drawStyle, OPA_OPAQUE, CapType::CAP_NONE);
|
|
}
|
|
|
|
if (enableStroke) {
|
|
arcInfo.radius = circleParam->radius + halfLineWidth - 1;
|
|
drawStyle.lineWidth_ = static_cast<int16_t>(paint.GetStrokeWidth());
|
|
drawStyle.lineColor_ = paint.GetStrokeColor();
|
|
DrawArc::GetInstance()->Draw(arcInfo, invalidatedArea, drawStyle, OPA_OPAQUE, CapType::CAP_NONE);
|
|
}
|
|
}
|
|
|
|
void UICanvas::DoDrawArc(void* param,
|
|
const Paint& paint,
|
|
const Rect& rect,
|
|
const Rect& invalidatedArea,
|
|
const Style& style)
|
|
{
|
|
if (param == nullptr) {
|
|
return;
|
|
}
|
|
ArcParam* arcParam = static_cast<ArcParam*>(param);
|
|
|
|
ArcInfo arcInfo = {{0}};
|
|
arcInfo.imgPos = Point{0, 0};
|
|
arcInfo.startAngle = arcParam->startAngle;
|
|
arcInfo.endAngle = arcParam->endAngle;
|
|
Style drawStyle = StyleDefault::GetDefaultStyle();
|
|
drawStyle.lineWidth_ = static_cast<int16_t>(paint.GetStrokeWidth());
|
|
drawStyle.lineColor_ = paint.GetStrokeColor();
|
|
drawStyle.lineOpa_ = paint.GetOpacity();
|
|
arcInfo.radius = arcParam->radius + ((paint.GetStrokeWidth() + 1) >> 1);
|
|
|
|
GetAbsolutePosition(arcParam->center, rect, style, arcInfo.center);
|
|
DrawArc::GetInstance()->Draw(arcInfo, invalidatedArea, drawStyle, OPA_OPAQUE, CapType::CAP_NONE);
|
|
}
|
|
|
|
void UICanvas::DoDrawImage(void* param,
|
|
const Paint& paint,
|
|
const Rect& rect,
|
|
const Rect& invalidatedArea,
|
|
const Style& style)
|
|
{
|
|
if (param == nullptr) {
|
|
return;
|
|
}
|
|
ImageParam* imageParam = static_cast<ImageParam*>(param);
|
|
|
|
if (imageParam->image == nullptr) {
|
|
return;
|
|
}
|
|
|
|
Point start;
|
|
GetAbsolutePosition(imageParam->start, rect, style, start);
|
|
|
|
Rect cordsTmp;
|
|
cordsTmp.SetPosition(start.x, start.y);
|
|
cordsTmp.SetHeight(imageParam->height);
|
|
cordsTmp.SetWidth(imageParam->width);
|
|
DrawImage::DrawCommon(cordsTmp, invalidatedArea, imageParam->image->GetPath(), style, paint.GetOpacity());
|
|
}
|
|
|
|
void UICanvas::DoDrawLabel(void* param,
|
|
const Paint& paint,
|
|
const Rect& rect,
|
|
const Rect& invalidatedArea,
|
|
const Style& style)
|
|
{
|
|
if (param == nullptr) {
|
|
return;
|
|
}
|
|
UILabel* label = static_cast<UILabel*>(param);
|
|
Point startPos = {label->GetX(), label->GetY()};
|
|
Point start;
|
|
GetAbsolutePosition({startPos.x, startPos.y}, rect, style, start);
|
|
label->SetPosition(start.x, start.y);
|
|
label->OnDraw(invalidatedArea);
|
|
label->SetPosition(startPos.x, startPos.y);
|
|
}
|
|
|
|
void UICanvas::DoDrawLineJoin(const Point& center, const Rect& invalidatedArea, const Paint& paint)
|
|
{
|
|
ArcInfo arcinfo = {{0}};
|
|
arcinfo.center = center;
|
|
arcinfo.imgPos = Point{0, 0};
|
|
arcinfo.radius = (paint.GetStrokeWidth() + 1) >> 1;
|
|
arcinfo.startAngle = 0;
|
|
arcinfo.endAngle = CIRCLE_IN_DEGREE;
|
|
|
|
Style style;
|
|
style.lineColor_ = paint.GetStrokeColor();
|
|
style.lineWidth_ = static_cast<int16_t>(paint.GetStrokeWidth());
|
|
style.lineOpa_ = OPA_OPAQUE;
|
|
DrawArc::GetInstance()->Draw(arcinfo, invalidatedArea, style, OPA_OPAQUE, CapType::CAP_NONE);
|
|
}
|
|
|
|
void UICanvas::DoDrawPath(void* param,
|
|
const Paint& paint,
|
|
const Rect& rect,
|
|
const Rect& invalidatedArea,
|
|
const Style& style)
|
|
{
|
|
if (param == nullptr) {
|
|
return;
|
|
}
|
|
PathParam* pathParam = static_cast<PathParam*>(param);
|
|
const UICanvasPath* path = pathParam->path;
|
|
if (path == nullptr) {
|
|
return;
|
|
}
|
|
Point pathEnd = {COORD_MIN, COORD_MIN};
|
|
|
|
ListNode<Point>* pointIter = path->points_.Begin();
|
|
ListNode<ArcParam>* arcIter = path->arcParam_.Begin();
|
|
ListNode<PathCmd>* iter = path->cmd_.Begin();
|
|
for (uint16_t i = 0; (i < pathParam->count) && (iter != path->cmd_.End()); i++, iter = iter->next_) {
|
|
switch (iter->data_) {
|
|
case CMD_MOVE_TO: {
|
|
pointIter = pointIter->next_;
|
|
break;
|
|
}
|
|
case CMD_LINE_TO: {
|
|
Point start = pointIter->prev_->data_;
|
|
Point end = pointIter->data_;
|
|
pointIter = pointIter->next_;
|
|
if ((start.x == end.x) && (start.y == end.y)) {
|
|
break;
|
|
}
|
|
|
|
GetAbsolutePosition(start, rect, style, start);
|
|
GetAbsolutePosition(end, rect, style, end);
|
|
DrawLine::Draw(start, end, invalidatedArea, paint.GetStrokeWidth(), paint.GetStrokeColor(), OPA_OPAQUE);
|
|
if ((pathEnd.x == start.x) && (pathEnd.y == start.y)) {
|
|
DoDrawLineJoin(start, invalidatedArea, paint);
|
|
}
|
|
pathEnd = end;
|
|
break;
|
|
}
|
|
case CMD_ARC: {
|
|
ArcInfo arcInfo = {{0}};
|
|
arcInfo.imgPos = Point{0, 0};
|
|
arcInfo.startAngle = arcIter->data_.startAngle;
|
|
arcInfo.endAngle = arcIter->data_.endAngle;
|
|
Style drawStyle = StyleDefault::GetDefaultStyle();
|
|
drawStyle.lineWidth_ = static_cast<int16_t>(paint.GetStrokeWidth());
|
|
drawStyle.lineColor_ = paint.GetStrokeColor();
|
|
drawStyle.lineOpa_ = OPA_OPAQUE;
|
|
arcInfo.radius = arcIter->data_.radius + ((paint.GetStrokeWidth() + 1) >> 1);
|
|
|
|
GetAbsolutePosition(arcIter->data_.center, rect, style, arcInfo.center);
|
|
DrawArc::GetInstance()->Draw(arcInfo, invalidatedArea, drawStyle, OPA_OPAQUE, CapType::CAP_NONE);
|
|
if (pointIter != path->points_.Begin()) {
|
|
DoDrawLineJoin(pathEnd, invalidatedArea, paint);
|
|
}
|
|
|
|
GetAbsolutePosition(pointIter->data_, rect, style, pathEnd);
|
|
pointIter = pointIter->next_;
|
|
arcIter = arcIter->next_;
|
|
break;
|
|
}
|
|
case CMD_CLOSE: {
|
|
Point start = pointIter->prev_->data_;
|
|
Point end = pointIter->data_;
|
|
GetAbsolutePosition(start, rect, style, start);
|
|
GetAbsolutePosition(end, rect, style, end);
|
|
if ((start.x != end.x) || (start.y != end.y)) {
|
|
DrawLine::Draw(start, end, invalidatedArea, paint.GetStrokeWidth(), paint.GetStrokeColor(),
|
|
OPA_OPAQUE);
|
|
if ((pathEnd.x == start.x) && (pathEnd.y == start.y)) {
|
|
DoDrawLineJoin(start, invalidatedArea, paint);
|
|
}
|
|
pathEnd = end;
|
|
}
|
|
|
|
if ((pathEnd.x == end.x) && (pathEnd.y == end.y)) {
|
|
DoDrawLineJoin(end, invalidatedArea, paint);
|
|
}
|
|
pointIter = pointIter->next_;
|
|
break;
|
|
}
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
} // namespace OHOS
|