1 /*
2  * Copyright (c) 2024 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 #include "core/interfaces/native/node/canvas_rendering_context_2d_modifier.h"
16 
17 #include <string>
18 
19 #include "base/log/log.h"
20 #include "base/memory/ace_type.h"
21 #include "base/utils/macros.h"
22 #include "core/components/common/properties/color.h"
23 #include "core/components_ng/base/frame_node.h"
24 #include "core/components_ng/pattern/canvas/canvas_renderer_type.h"
25 #include "core/components_ng/pattern/canvas/canvas_model_ng.h"
26 
27 namespace OHOS::Ace::NG {
28 
SetCanvasBeginPath(ArkUINodeHandle node)29 void SetCanvasBeginPath(ArkUINodeHandle node)
30 {
31     TAG_LOGD(AceLogTag::ACE_CANVAS_COMPONENT, "Arkoala SetCanvasBeginPath:node:%{public}p", node);
32     auto* frameNode = reinterpret_cast<FrameNode*>(node);
33     CHECK_NULL_VOID(frameNode);
34     RefPtr<AceType> pattern = CanvasModelNG::GetCanvasPattern(frameNode);
35     auto canvasPattern = AceType::DynamicCast<NG::CanvasPattern>(pattern);
36     CHECK_NULL_VOID(canvasPattern);
37     canvasPattern->BeginPath();
38 }
39 
SetCanvasClosePath(ArkUINodeHandle node)40 void SetCanvasClosePath(ArkUINodeHandle node)
41 {
42     TAG_LOGD(AceLogTag::ACE_CANVAS_COMPONENT, "Arkoala SetCanvasClosePath:node:%{public}p", node);
43     auto* frameNode = reinterpret_cast<FrameNode*>(node);
44     CHECK_NULL_VOID(frameNode);
45     RefPtr<AceType> pattern = CanvasModelNG::GetCanvasPattern(frameNode);
46     auto canvasPattern = AceType::DynamicCast<NG::CanvasPattern>(pattern);
47     CHECK_NULL_VOID(canvasPattern);
48     canvasPattern->ClosePath();
49 }
50 
SetCanvasFill(ArkUINodeHandle node,const char * value)51 void SetCanvasFill(ArkUINodeHandle node, const char *value)
52 {
53     TAG_LOGD(AceLogTag::ACE_CANVAS_COMPONENT, "Arkoala SetCanvasFill:node:%{public}p, value: %{public}s", node, value);
54     auto* frameNode = reinterpret_cast<FrameNode*>(node);
55     CHECK_NULL_VOID(frameNode);
56     RefPtr<AceType> pattern = CanvasModelNG::GetCanvasPattern(frameNode);
57     auto canvasPattern = AceType::DynamicCast<NG::CanvasPattern>(pattern);
58     CHECK_NULL_VOID(canvasPattern);
59     std::string ruleStr(value);
60     CanvasFillRule fillRule = CanvasFillRule::NONZERO;
61     if (ruleStr == "nonezero") {
62         fillRule = CanvasFillRule::NONZERO;
63     } else if (ruleStr == "evenodd") {
64         fillRule = CanvasFillRule::EVENODD;
65     }
66     canvasPattern->UpdateFillRuleForPath(fillRule);
67     canvasPattern->Fill();
68 }
69 
SetCanvasMoveTo(ArkUINodeHandle node,float x,float y)70 void SetCanvasMoveTo(ArkUINodeHandle node, float x, float y)
71 {
72     TAG_LOGD(AceLogTag::ACE_CANVAS_COMPONENT, "Arkoala SetCanvasMoveTo:node:%{public}p, x: %{public}f, y: %{public}f",
73         node, x, y);
74     auto* frameNode = reinterpret_cast<FrameNode*>(node);
75     CHECK_NULL_VOID(frameNode);
76     RefPtr<AceType> pattern = CanvasModelNG::GetCanvasPattern(frameNode);
77     auto canvasPattern = AceType::DynamicCast<NG::CanvasPattern>(pattern);
78     CHECK_NULL_VOID(canvasPattern);
79     canvasPattern->MoveTo(x, y);
80 }
81 
SetCanvasArc(ArkUINodeHandle node,ArkUICanvasArcOptions * options)82 void SetCanvasArc(ArkUINodeHandle node, ArkUICanvasArcOptions *options)
83 {
84     CHECK_NULL_VOID(options);
85     TAG_LOGD(AceLogTag::ACE_CANVAS_COMPONENT, "Arkoala SetCanvasArc:node:%{public}p, x: %{public}f, y: %{public}f, \
86         radius: %{public}f, startAngle: %{public}f, endAngle: %{public}f", node, options->x, options->y,
87         options->radius, options->startAngle, options->endAngle);
88     auto* frameNode = reinterpret_cast<FrameNode*>(node);
89     CHECK_NULL_VOID(frameNode);
90     RefPtr<AceType> pattern = CanvasModelNG::GetCanvasPattern(frameNode);
91     auto canvasPattern = AceType::DynamicCast<NG::CanvasPattern>(pattern);
92     CHECK_NULL_VOID(canvasPattern);
93     ArcParam param;
94     param.x = Dimension(options->x, DimensionUnit::VP).ConvertToPx();
95     param.y = Dimension(options->y, DimensionUnit::VP).ConvertToPx();
96     param.radius = Dimension(options->radius, DimensionUnit::VP).ConvertToPx();
97     param.startAngle = options->startAngle;
98     param.endAngle = options->endAngle;
99     param.anticlockwise = static_cast<bool>(options->counterclockwise);
100     canvasPattern->Arc(param);
101 }
102 
SetCanvasLineTo(ArkUINodeHandle node,float x,float y)103 void SetCanvasLineTo(ArkUINodeHandle node, float x, float y)
104 {
105     TAG_LOGD(AceLogTag::ACE_CANVAS_COMPONENT, "Arkoala SetCanvasLineTo:node:%{public}p, x: %{public}f, y: %{public}f",
106         node, x, y);
107     auto* frameNode = reinterpret_cast<FrameNode*>(node);
108     CHECK_NULL_VOID(frameNode);
109     RefPtr<AceType> pattern = CanvasModelNG::GetCanvasPattern(frameNode);
110     auto canvasPattern = AceType::DynamicCast<NG::CanvasPattern>(pattern);
111     CHECK_NULL_VOID(canvasPattern);
112     canvasPattern->LineTo(
113         Dimension(x, DimensionUnit::VP).ConvertToPx(),
114         Dimension(y, DimensionUnit::VP).ConvertToPx()
115     );
116 }
117 
SetCanvasStrokeStyle(ArkUINodeHandle node,int color)118 void SetCanvasStrokeStyle(ArkUINodeHandle node, int color)
119 {
120     TAG_LOGD(AceLogTag::ACE_CANVAS_COMPONENT, "Arkoala SetCanvasStrokStyle:node:%{public}p, color: %{public}d",
121         node, color);
122     auto* frameNode = reinterpret_cast<FrameNode*>(node);
123     CHECK_NULL_VOID(frameNode);
124     RefPtr<AceType> pattern = CanvasModelNG::GetCanvasPattern(frameNode);
125     auto canvasPattern = AceType::DynamicCast<NG::CanvasPattern>(pattern);
126     CHECK_NULL_VOID(canvasPattern);
127     canvasPattern->UpdateStrokeColor(Color(color));
128 }
129 
GetCanvasStrokeStyle(ArkUINodeHandle node)130 ArkUI_Int32 GetCanvasStrokeStyle(ArkUINodeHandle node)
131 {
132     TAG_LOGD(AceLogTag::ACE_CANVAS_COMPONENT, "Arkoala GetCanvasStrokeStyle STUB");
133     return 0xff000000;
134 }
135 
SetCanvasLineWidth(ArkUINodeHandle node,float width)136 void SetCanvasLineWidth(ArkUINodeHandle node, float width)
137 {
138     TAG_LOGD(AceLogTag::ACE_CANVAS_COMPONENT, "Arkoala SetCanvasStrokStyle:node:%{public}p, width: %{public}f",
139         node, width);
140     auto* frameNode = reinterpret_cast<FrameNode*>(node);
141     CHECK_NULL_VOID(frameNode);
142     RefPtr<AceType> pattern = CanvasModelNG::GetCanvasPattern(frameNode);
143     auto canvasPattern = AceType::DynamicCast<NG::CanvasPattern>(pattern);
144     CHECK_NULL_VOID(canvasPattern);
145     canvasPattern->UpdateLineWidth(Dimension(width, DimensionUnit::VP).ConvertToPx());
146 }
147 
GetCanvasLineWidth(ArkUINodeHandle node)148 ArkUI_Float32 GetCanvasLineWidth(ArkUINodeHandle node)
149 {
150     TAG_LOGD(AceLogTag::ACE_CANVAS_COMPONENT, "Arkoala GetCanvasLineWidth STUB");
151     return 0xff000000;
152 }
153 
SetCanvasStroke(ArkUINodeHandle node)154 void SetCanvasStroke(ArkUINodeHandle node)
155 {
156     TAG_LOGD(AceLogTag::ACE_CANVAS_COMPONENT, "Arkoala SetCanvasStroke:node:%{public}p", node);
157     auto* frameNode = reinterpret_cast<FrameNode*>(node);
158     CHECK_NULL_VOID(frameNode);
159     RefPtr<AceType> pattern = CanvasModelNG::GetCanvasPattern(frameNode);
160     auto canvasPattern = AceType::DynamicCast<NG::CanvasPattern>(pattern);
161     CHECK_NULL_VOID(canvasPattern);
162     canvasPattern->Stroke();
163 }
164 
SetCanvasAntiAlias(ArkUINodeHandle node,ArkUI_Bool antialias)165 void SetCanvasAntiAlias(ArkUINodeHandle node, ArkUI_Bool antialias)
166 {
167     TAG_LOGD(AceLogTag::ACE_CANVAS_COMPONENT, "Arkoala SetCanvasAntiAlias:node:%{public}p, antialias:%{public}d",
168         node, antialias);
169     auto* frameNode = reinterpret_cast<FrameNode*>(node);
170     CHECK_NULL_VOID(frameNode);
171     RefPtr<AceType> pattern = CanvasModelNG::GetCanvasPattern(frameNode);
172     auto canvasPattern = AceType::DynamicCast<NG::CanvasPattern>(pattern);
173     CHECK_NULL_VOID(canvasPattern);
174     canvasPattern->SetAntiAlias(static_cast<bool>(antialias));
175 }
176 
SetCanvasFillColor(ArkUINodeHandle node,int color)177 void SetCanvasFillColor(ArkUINodeHandle node, int color)
178 {
179     TAG_LOGD(AceLogTag::ACE_CANVAS_COMPONENT, "Arkoala SetCanvasFillColor:node:%{public}p, color: %{public}d",
180         node, color);
181     auto* frameNode = reinterpret_cast<FrameNode*>(node);
182     CHECK_NULL_VOID(frameNode);
183     RefPtr<AceType> pattern = CanvasModelNG::GetCanvasPattern(frameNode);
184     auto canvasPattern = AceType::DynamicCast<NG::CanvasPattern>(pattern);
185     CHECK_NULL_VOID(canvasPattern);
186     canvasPattern->UpdateFillColor(Color(color));
187 }
188 
GetCanvasFillColor(ArkUINodeHandle node)189 ArkUI_Int32 GetCanvasFillColor(ArkUINodeHandle node)
190 {
191     TAG_LOGD(AceLogTag::ACE_CANVAS_COMPONENT, "Arkoala GetCanvasFillColor STUB");
192     return 0xff000000;
193 }
194 
SetCanvasGlobalAlpha(ArkUINodeHandle node,float alpha)195 void SetCanvasGlobalAlpha(ArkUINodeHandle node, float alpha)
196 {
197     TAG_LOGD(AceLogTag::ACE_CANVAS_COMPONENT, "Arkoala SetCanvasGlobalAlpha");
198     auto* frameNode = reinterpret_cast<FrameNode*>(node);
199     CHECK_NULL_VOID(frameNode);
200     RefPtr<AceType> pattern = CanvasModelNG::GetCanvasPattern(frameNode);
201     auto canvasPattern = AceType::DynamicCast<NG::CanvasPattern>(pattern);
202     CHECK_NULL_VOID(canvasPattern);
203     canvasPattern->UpdateGlobalAlpha(alpha);
204 }
205 
GetCanvasGlobalAlpha(ArkUINodeHandle node)206 ArkUI_Float32 GetCanvasGlobalAlpha(ArkUINodeHandle node)
207 {
208     TAG_LOGD(AceLogTag::ACE_CANVAS_COMPONENT, "Arkoala GetCanvasGlobalAlpha STUB");
209     return 0;
210 }
211 
SetCanvasFillRect(ArkUINodeHandle node,float x,float y,float w,float h)212 void SetCanvasFillRect(ArkUINodeHandle node, float x, float y, float w, float h)
213 {
214     TAG_LOGD(AceLogTag::ACE_CANVAS_COMPONENT, "Arkoala SetCanvasFillRect 1:node:%{public}p, x: %{public}f, \
215         y: %{public}f, w: %{public}f, h: %{public}f", node, x, y, w, h);
216     auto* frameNode = reinterpret_cast<FrameNode*>(node);
217     CHECK_NULL_VOID(frameNode);
218     RefPtr<AceType> pattern = CanvasModelNG::GetCanvasPattern(frameNode);
219     auto canvasPattern = AceType::DynamicCast<NG::CanvasPattern>(pattern);
220     CHECK_NULL_VOID(canvasPattern);
221     canvasPattern->FillRect({
222         Dimension(x, DimensionUnit::VP).ConvertToPx(),
223         Dimension(y, DimensionUnit::VP).ConvertToPx(),
224         Dimension(w, DimensionUnit::VP).ConvertToPx(),
225         Dimension(h, DimensionUnit::VP).ConvertToPx()
226     });
227 }
228 
SetCanvasFillText(ArkUINodeHandle node,const char * value,float x,float y,float maxWidth)229 void SetCanvasFillText(ArkUINodeHandle node, const char *value, float x, float y, float maxWidth)
230 {
231     TAG_LOGD(AceLogTag::ACE_CANVAS_COMPONENT, "Arkoala SetCanvasFillText:node:%{public}p, value:%{public}s, \
232         x: %{public}f, y: %{public}f, maxWith: %{public}f", node, value, x, y, maxWidth);
233     auto* frameNode = reinterpret_cast<FrameNode*>(node);
234     CHECK_NULL_VOID(frameNode);
235     RefPtr<AceType> pattern = CanvasModelNG::GetCanvasPattern(frameNode);
236     auto canvasPattern = AceType::DynamicCast<NG::CanvasPattern>(pattern);
237     CHECK_NULL_VOID(canvasPattern);
238     std::string text(value);
239     canvasPattern->FillText(text,
240         Dimension(x, DimensionUnit::VP).ConvertToPx(),
241         Dimension(y, DimensionUnit::VP).ConvertToPx(),
242         Dimension(maxWidth, DimensionUnit::VP).ConvertToPx()
243     );
244 }
245 
246 namespace NodeModifier {
GetCanvasRenderingContext2DModifier()247 const ArkUICanvasRenderingContext2DModifier* GetCanvasRenderingContext2DModifier()
248 {
249     static const ArkUICanvasRenderingContext2DModifier modifier = {
250         nullptr,
251         SetCanvasBeginPath,
252         SetCanvasClosePath,
253         SetCanvasFill,
254         SetCanvasMoveTo,
255         SetCanvasArc,
256         SetCanvasLineTo,
257         SetCanvasStrokeStyle,
258         GetCanvasStrokeStyle,
259         SetCanvasLineWidth,
260         GetCanvasLineWidth,
261         SetCanvasStroke,
262         SetCanvasAntiAlias,
263         SetCanvasFillColor,
264         GetCanvasFillColor,
265         SetCanvasGlobalAlpha,
266         GetCanvasGlobalAlpha,
267         SetCanvasFillRect,
268         SetCanvasFillText,
269     };
270     return &modifier;
271 }
272 
GetCJUICanvasRenderingContext2DModifier()273 const CJUICanvasRenderingContext2DModifier* GetCJUICanvasRenderingContext2DModifier()
274 {
275     static const CJUICanvasRenderingContext2DModifier modifier = {
276         nullptr,
277         SetCanvasBeginPath,
278         SetCanvasClosePath,
279         SetCanvasFill,
280         SetCanvasMoveTo,
281         SetCanvasArc,
282         SetCanvasLineTo,
283         SetCanvasStrokeStyle,
284         GetCanvasStrokeStyle,
285         SetCanvasLineWidth,
286         GetCanvasLineWidth,
287         SetCanvasStroke,
288         SetCanvasAntiAlias,
289         SetCanvasFillColor,
290         GetCanvasFillColor,
291         SetCanvasGlobalAlpha,
292         GetCanvasGlobalAlpha,
293         SetCanvasFillRect,
294         SetCanvasFillText,
295     };
296     return &modifier;
297 }
298 } // namespace NodeModifier
299 } // namespace OHOS::Ace::NG
300