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 
16 #include "js_path.h"
17 
18 #include "native_value.h"
19 
20 #include "js_drawing_utils.h"
21 #include "matrix_napi/js_matrix.h"
22 #include "roundRect_napi/js_roundrect.h"
23 
24 #include "matrix_napi/js_matrix.h"
25 
26 namespace OHOS::Rosen {
27 namespace Drawing {
28 thread_local napi_ref JsPath::constructor_ = nullptr;
29 const std::string CLASS_NAME = "Path";
30 
31 static const napi_property_descriptor g_properties[] = {
32     DECLARE_NAPI_FUNCTION("moveTo", JsPath::MoveTo),
33     DECLARE_NAPI_FUNCTION("lineTo", JsPath::LineTo),
34     DECLARE_NAPI_FUNCTION("arcTo", JsPath::ArcTo),
35     DECLARE_NAPI_FUNCTION("quadTo", JsPath::QuadTo),
36     DECLARE_NAPI_FUNCTION("conicTo", JsPath::ConicTo),
37     DECLARE_NAPI_FUNCTION("cubicTo", JsPath::CubicTo),
38     DECLARE_NAPI_FUNCTION("rMoveTo", JsPath::RMoveTo),
39     DECLARE_NAPI_FUNCTION("rLineTo", JsPath::RLineTo),
40     DECLARE_NAPI_FUNCTION("rQuadTo", JsPath::RQuadTo),
41     DECLARE_NAPI_FUNCTION("rConicTo", JsPath::RConicTo),
42     DECLARE_NAPI_FUNCTION("rCubicTo", JsPath::RCubicTo),
43     DECLARE_NAPI_FUNCTION("addPolygon", JsPath::AddPolygon),
44     DECLARE_NAPI_FUNCTION("addOval", JsPath::AddOval),
45     DECLARE_NAPI_FUNCTION("addCircle", JsPath::AddCircle),
46     DECLARE_NAPI_FUNCTION("addArc", JsPath::AddArc),
47     DECLARE_NAPI_FUNCTION("addRect", JsPath::AddRect),
48     DECLARE_NAPI_FUNCTION("addRoundRect", JsPath::AddRoundRect),
49     DECLARE_NAPI_FUNCTION("addPath", JsPath::AddPath),
50     DECLARE_NAPI_FUNCTION("transform", JsPath::Transform),
51     DECLARE_NAPI_FUNCTION("contains", JsPath::Contains),
52     DECLARE_NAPI_FUNCTION("setFillType", JsPath::SetFillType),
53     DECLARE_NAPI_FUNCTION("getBounds", JsPath::GetBounds),
54     DECLARE_NAPI_FUNCTION("close", JsPath::Close),
55     DECLARE_NAPI_FUNCTION("offset", JsPath::Offset),
56     DECLARE_NAPI_FUNCTION("reset", JsPath::Reset),
57     DECLARE_NAPI_FUNCTION("op", JsPath::Op),
58     DECLARE_NAPI_FUNCTION("getLength", JsPath::GetLength),
59     DECLARE_NAPI_FUNCTION("getPositionAndTangent", JsPath::GetPositionAndTangent),
60     DECLARE_NAPI_FUNCTION("getMatrix", JsPath::GetMatrix),
61     DECLARE_NAPI_FUNCTION("buildFromSvgString", JsPath::BuildFromSvgString),
62     DECLARE_NAPI_FUNCTION("isClosed", JsPath::IsClosed),
63 };
64 
Init(napi_env env,napi_value exportObj)65 napi_value JsPath::Init(napi_env env, napi_value exportObj)
66 {
67     napi_value constructor = nullptr;
68     napi_status status = napi_define_class(env, CLASS_NAME.c_str(), NAPI_AUTO_LENGTH, Constructor, nullptr,
69         sizeof(g_properties) / sizeof(g_properties[0]), g_properties, &constructor);
70     if (status != napi_ok) {
71         ROSEN_LOGE("Failed to define Path class");
72         return nullptr;
73     }
74 
75     status = napi_create_reference(env, constructor, 1, &constructor_);
76     if (status != napi_ok) {
77         ROSEN_LOGE("Failed to create reference of constructor");
78         return nullptr;
79     }
80 
81     status = napi_set_named_property(env, exportObj, CLASS_NAME.c_str(), constructor);
82     if (status != napi_ok) {
83         ROSEN_LOGE("Failed to set constructor");
84         return nullptr;
85     }
86 
87     return exportObj;
88 }
89 
Constructor(napi_env env,napi_callback_info info)90 napi_value JsPath::Constructor(napi_env env, napi_callback_info info)
91 {
92     size_t argc = ARGC_ONE;
93     napi_value argv[ARGC_ONE] = {nullptr};
94     napi_value jsThis = nullptr;
95     JsPath* jsPath = nullptr;
96     napi_status status = napi_get_cb_info(env, info, &argc, argv, &jsThis, nullptr);
97     if (status != napi_ok) {
98         ROSEN_LOGE("Path::Constructor Failed to napi_get_cb_info");
99         return nullptr;
100     }
101     if (argc == ARGC_ZERO) {
102         Path* path = new Path();
103         jsPath = new JsPath(path);
104     } else if (argc == ARGC_ONE) {
105         napi_valuetype valueType = napi_undefined;
106         if (argv[0] == nullptr || napi_typeof(env, argv[0], &valueType) != napi_ok || valueType != napi_object) {
107             return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM,
108                 "JsPath::Constructor Argv[0] is invalid");
109         }
110         JsPath* path = nullptr;
111         GET_UNWRAP_PARAM(ARGC_ZERO, path);
112         Path* p = new Path(*path->GetPath());
113         jsPath = new JsPath(p);
114     } else {
115         return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Incorrect number of parameters.");
116     }
117     if (!jsPath) {
118         ROSEN_LOGE("Failed to create JsPath");
119         return nullptr;
120     }
121     status = napi_wrap(env, jsThis, jsPath,
122         JsPath::Destructor, nullptr, nullptr);
123     if (status != napi_ok) {
124         delete jsPath;
125         ROSEN_LOGE("JsPath::Constructor Failed to wrap native instance");
126         return nullptr;
127     }
128     return jsThis;
129 }
130 
Destructor(napi_env env,void * nativeObject,void * finalize)131 void JsPath::Destructor(napi_env env, void *nativeObject, void *finalize)
132 {
133     (void)finalize;
134     if (nativeObject != nullptr) {
135         JsPath *napi = reinterpret_cast<JsPath *>(nativeObject);
136         delete napi;
137     }
138 }
139 
CreateJsPath(napi_env env,Path * path)140 napi_value JsPath::CreateJsPath(napi_env env, Path* path)
141 {
142     napi_value constructor = nullptr;
143     napi_value result = nullptr;
144     napi_status status = napi_get_reference_value(env, constructor_, &constructor);
145     if (status == napi_ok) {
146         auto jsPath = new JsPath(path);
147         napi_create_object(env, &result);
148         if (result == nullptr) {
149             delete jsPath;
150             ROSEN_LOGE("JsPath::CreateJsPath Create path object failed!");
151             return nullptr;
152         }
153         status = napi_wrap(env, result, jsPath, JsPath::Destructor, nullptr, nullptr);
154         if (status != napi_ok) {
155             delete jsPath;
156             ROSEN_LOGE("JsPath::CreateJsPath failed to wrap native instance");
157             return nullptr;
158         }
159         napi_define_properties(env, result, sizeof(g_properties) / sizeof(g_properties[0]), g_properties);
160         return result;
161     }
162     return result;
163 }
164 
~JsPath()165 JsPath::~JsPath()
166 {
167     if (m_path != nullptr) {
168         delete m_path;
169         m_path = nullptr;
170     }
171 }
172 
MoveTo(napi_env env,napi_callback_info info)173 napi_value JsPath::MoveTo(napi_env env, napi_callback_info info)
174 {
175     JsPath* me = CheckParamsAndGetThis<JsPath>(env, info);
176     return (me != nullptr) ? me->OnMoveTo(env, info) : nullptr;
177 }
178 
LineTo(napi_env env,napi_callback_info info)179 napi_value JsPath::LineTo(napi_env env, napi_callback_info info)
180 {
181     JsPath* me = CheckParamsAndGetThis<JsPath>(env, info);
182     return (me != nullptr) ? me->OnLineTo(env, info) : nullptr;
183 }
184 
ArcTo(napi_env env,napi_callback_info info)185 napi_value JsPath::ArcTo(napi_env env, napi_callback_info info)
186 {
187     JsPath* me = CheckParamsAndGetThis<JsPath>(env, info);
188     return (me != nullptr) ? me->OnArcTo(env, info) : nullptr;
189 }
190 
QuadTo(napi_env env,napi_callback_info info)191 napi_value JsPath::QuadTo(napi_env env, napi_callback_info info)
192 {
193     JsPath* me = CheckParamsAndGetThis<JsPath>(env, info);
194     return (me != nullptr) ? me->OnQuadTo(env, info) : nullptr;
195 }
196 
ConicTo(napi_env env,napi_callback_info info)197 napi_value JsPath::ConicTo(napi_env env, napi_callback_info info)
198 {
199     JsPath* me = CheckParamsAndGetThis<JsPath>(env, info);
200     return (me != nullptr) ? me->OnConicTo(env, info) : nullptr;
201 }
202 
CubicTo(napi_env env,napi_callback_info info)203 napi_value JsPath::CubicTo(napi_env env, napi_callback_info info)
204 {
205     JsPath* me = CheckParamsAndGetThis<JsPath>(env, info);
206     return (me != nullptr) ? me->OnCubicTo(env, info) : nullptr;
207 }
208 
RMoveTo(napi_env env,napi_callback_info info)209 napi_value JsPath::RMoveTo(napi_env env, napi_callback_info info)
210 {
211     JsPath* me = CheckParamsAndGetThis<JsPath>(env, info);
212     return (me != nullptr) ? me->OnRMoveTo(env, info) : nullptr;
213 }
214 
RLineTo(napi_env env,napi_callback_info info)215 napi_value JsPath::RLineTo(napi_env env, napi_callback_info info)
216 {
217     JsPath* me = CheckParamsAndGetThis<JsPath>(env, info);
218     return (me != nullptr) ? me->OnRLineTo(env, info) : nullptr;
219 }
220 
RQuadTo(napi_env env,napi_callback_info info)221 napi_value JsPath::RQuadTo(napi_env env, napi_callback_info info)
222 {
223     JsPath* me = CheckParamsAndGetThis<JsPath>(env, info);
224     return (me != nullptr) ? me->OnRQuadTo(env, info) : nullptr;
225 }
226 
RConicTo(napi_env env,napi_callback_info info)227 napi_value JsPath::RConicTo(napi_env env, napi_callback_info info)
228 {
229     JsPath* me = CheckParamsAndGetThis<JsPath>(env, info);
230     return (me != nullptr) ? me->OnRConicTo(env, info) : nullptr;
231 }
232 
RCubicTo(napi_env env,napi_callback_info info)233 napi_value JsPath::RCubicTo(napi_env env, napi_callback_info info)
234 {
235     JsPath* me = CheckParamsAndGetThis<JsPath>(env, info);
236     return (me != nullptr) ? me->OnRCubicTo(env, info) : nullptr;
237 }
238 
AddPolygon(napi_env env,napi_callback_info info)239 napi_value JsPath::AddPolygon(napi_env env, napi_callback_info info)
240 {
241     JsPath* me = CheckParamsAndGetThis<JsPath>(env, info);
242     return (me != nullptr) ? me->OnAddPolygon(env, info) : nullptr;
243 }
244 
AddOval(napi_env env,napi_callback_info info)245 napi_value JsPath::AddOval(napi_env env, napi_callback_info info)
246 {
247     JsPath* me = CheckParamsAndGetThis<JsPath>(env, info);
248     return (me != nullptr) ? me->OnAddOval(env, info) : nullptr;
249 }
250 
AddCircle(napi_env env,napi_callback_info info)251 napi_value JsPath::AddCircle(napi_env env, napi_callback_info info)
252 {
253     JsPath* me = CheckParamsAndGetThis<JsPath>(env, info);
254     return (me != nullptr) ? me->OnAddCircle(env, info) : nullptr;
255 }
256 
AddArc(napi_env env,napi_callback_info info)257 napi_value JsPath::AddArc(napi_env env, napi_callback_info info)
258 {
259     JsPath* me = CheckParamsAndGetThis<JsPath>(env, info);
260     return (me != nullptr) ? me->OnAddArc(env, info) : nullptr;
261 }
262 
AddRect(napi_env env,napi_callback_info info)263 napi_value JsPath::AddRect(napi_env env, napi_callback_info info)
264 {
265     JsPath* me = CheckParamsAndGetThis<JsPath>(env, info);
266     return (me != nullptr) ? me->OnAddRect(env, info) : nullptr;
267 }
268 
AddRoundRect(napi_env env,napi_callback_info info)269 napi_value JsPath::AddRoundRect(napi_env env, napi_callback_info info)
270 {
271     JsPath* me = CheckParamsAndGetThis<JsPath>(env, info);
272     return (me != nullptr) ? me->OnAddRoundRect(env, info) : nullptr;
273 }
274 
AddPath(napi_env env,napi_callback_info info)275 napi_value JsPath::AddPath(napi_env env, napi_callback_info info)
276 {
277     JsPath* me = CheckParamsAndGetThis<JsPath>(env, info);
278     return (me != nullptr) ? me->OnAddPath(env, info) : nullptr;
279 }
280 
Transform(napi_env env,napi_callback_info info)281 napi_value JsPath::Transform(napi_env env, napi_callback_info info)
282 {
283     JsPath* me = CheckParamsAndGetThis<JsPath>(env, info);
284     return (me != nullptr) ? me->OnTransform(env, info) : nullptr;
285 }
286 
Contains(napi_env env,napi_callback_info info)287 napi_value JsPath::Contains(napi_env env, napi_callback_info info)
288 {
289     JsPath* me = CheckParamsAndGetThis<JsPath>(env, info);
290     return (me != nullptr) ? me->OnContains(env, info) : nullptr;
291 }
292 
SetFillType(napi_env env,napi_callback_info info)293 napi_value JsPath::SetFillType(napi_env env, napi_callback_info info)
294 {
295     JsPath* me = CheckParamsAndGetThis<JsPath>(env, info);
296     return (me != nullptr) ? me->OnSetFillType(env, info) : nullptr;
297 }
298 
GetBounds(napi_env env,napi_callback_info info)299 napi_value JsPath::GetBounds(napi_env env, napi_callback_info info)
300 {
301     JsPath* me = CheckParamsAndGetThis<JsPath>(env, info);
302     return (me != nullptr) ? me->OnGetBounds(env, info) : nullptr;
303 }
304 
Close(napi_env env,napi_callback_info info)305 napi_value JsPath::Close(napi_env env, napi_callback_info info)
306 {
307     JsPath* me = CheckParamsAndGetThis<JsPath>(env, info);
308     return (me != nullptr) ? me->OnClose(env, info) : nullptr;
309 }
310 
Offset(napi_env env,napi_callback_info info)311 napi_value JsPath::Offset(napi_env env, napi_callback_info info)
312 {
313     JsPath* me = CheckParamsAndGetThis<JsPath>(env, info);
314     return (me != nullptr) ? me->OnOffset(env, info) : nullptr;
315 }
316 
Reset(napi_env env,napi_callback_info info)317 napi_value JsPath::Reset(napi_env env, napi_callback_info info)
318 {
319     JsPath* me = CheckParamsAndGetThis<JsPath>(env, info);
320     return (me != nullptr) ? me->OnReset(env, info) : nullptr;
321 }
322 
GetLength(napi_env env,napi_callback_info info)323 napi_value JsPath::GetLength(napi_env env, napi_callback_info info)
324 {
325     JsPath* me = CheckParamsAndGetThis<JsPath>(env, info);
326     return (me != nullptr) ? me->OnGetLength(env, info) : nullptr;
327 }
328 
GetPositionAndTangent(napi_env env,napi_callback_info info)329 napi_value JsPath::GetPositionAndTangent(napi_env env, napi_callback_info info)
330 {
331     JsPath* me = CheckParamsAndGetThis<JsPath>(env, info);
332     return (me != nullptr) ? me->OnGetPositionAndTangent(env, info) : nullptr;
333 }
334 
GetMatrix(napi_env env,napi_callback_info info)335 napi_value JsPath::GetMatrix(napi_env env, napi_callback_info info)
336 {
337     JsPath* me = CheckParamsAndGetThis<JsPath>(env, info);
338     return (me != nullptr) ? me->OnGetMatrix(env, info) : nullptr;
339 }
340 
BuildFromSvgString(napi_env env,napi_callback_info info)341 napi_value JsPath::BuildFromSvgString(napi_env env, napi_callback_info info)
342 {
343     JsPath* me = CheckParamsAndGetThis<JsPath>(env, info);
344     return (me != nullptr) ? me->OnBuildFromSvgString(env, info) : nullptr;
345 }
346 
IsClosed(napi_env env,napi_callback_info info)347 napi_value JsPath::IsClosed(napi_env env, napi_callback_info info)
348 {
349     JsPath* me = CheckParamsAndGetThis<JsPath>(env, info);
350     return (me != nullptr) ? me->OnIsClosed(env, info) : nullptr;
351 }
352 
Op(napi_env env,napi_callback_info info)353 napi_value JsPath::Op(napi_env env, napi_callback_info info)
354 {
355     JsPath* me = CheckParamsAndGetThis<JsPath>(env, info);
356     return (me != nullptr) ? me->OnOp(env, info) : nullptr;
357 }
358 
OnMoveTo(napi_env env,napi_callback_info info)359 napi_value JsPath::OnMoveTo(napi_env env, napi_callback_info info)
360 {
361     if (m_path == nullptr) {
362         ROSEN_LOGE("JsPath::OnMoveTo path is nullptr");
363         return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
364     }
365 
366     napi_value argv[ARGC_TWO] = {nullptr};
367     CHECK_PARAM_NUMBER_WITHOUT_OPTIONAL_PARAMS(argv, ARGC_TWO);
368 
369     double x = 0.0;
370     GET_DOUBLE_PARAM(ARGC_ZERO, x);
371     double y = 0.0;
372     GET_DOUBLE_PARAM(ARGC_ONE, y);
373 
374     JS_CALL_DRAWING_FUNC(m_path->MoveTo(x, y));
375     return nullptr;
376 }
377 
OnLineTo(napi_env env,napi_callback_info info)378 napi_value JsPath::OnLineTo(napi_env env, napi_callback_info info)
379 {
380     if (m_path == nullptr) {
381         ROSEN_LOGE("JsPath::OnLineTo path is nullptr");
382         return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
383     }
384 
385     napi_value argv[ARGC_TWO] = {nullptr};
386     CHECK_PARAM_NUMBER_WITHOUT_OPTIONAL_PARAMS(argv, ARGC_TWO);
387 
388     double x = 0.0;
389     GET_DOUBLE_PARAM(ARGC_ZERO, x);
390     double y = 0.0;
391     GET_DOUBLE_PARAM(ARGC_ONE, y);
392 
393     JS_CALL_DRAWING_FUNC(m_path->LineTo(x, y));
394     return nullptr;
395 }
396 
OnArcTo(napi_env env,napi_callback_info info)397 napi_value JsPath::OnArcTo(napi_env env, napi_callback_info info)
398 {
399     if (m_path == nullptr) {
400         ROSEN_LOGE("JsPath::OnArcTo path is nullptr");
401         return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
402     }
403 
404     napi_value argv[ARGC_SIX] = {nullptr};
405     CHECK_PARAM_NUMBER_WITHOUT_OPTIONAL_PARAMS(argv, ARGC_SIX);
406 
407     double x1 = 0.0;
408     GET_DOUBLE_PARAM(ARGC_ZERO, x1);
409     double y1 = 0.0;
410     GET_DOUBLE_PARAM(ARGC_ONE, y1);
411     double x2 = 0.0;
412     GET_DOUBLE_PARAM(ARGC_TWO, x2);
413     double y2 = 0.0;
414     GET_DOUBLE_PARAM(ARGC_THREE, y2);
415     double startDeg = 0.0;
416     GET_DOUBLE_PARAM(ARGC_FOUR, startDeg);
417     double sweepDeg = 0.0;
418     GET_DOUBLE_PARAM(ARGC_FIVE, sweepDeg);
419 
420     JS_CALL_DRAWING_FUNC(m_path->ArcTo(x1, y1, x2, y2, startDeg, sweepDeg));
421     return nullptr;
422 }
423 
OnQuadTo(napi_env env,napi_callback_info info)424 napi_value JsPath::OnQuadTo(napi_env env, napi_callback_info info)
425 {
426     if (m_path == nullptr) {
427         ROSEN_LOGE("JsPath::OnQuadTo path is nullptr");
428         return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
429     }
430 
431     napi_value argv[ARGC_FOUR] = {nullptr};
432     CHECK_PARAM_NUMBER_WITHOUT_OPTIONAL_PARAMS(argv, ARGC_FOUR);
433 
434     double ctrlPtX = 0.0;
435     GET_DOUBLE_PARAM(ARGC_ZERO, ctrlPtX);
436     double ctrlPtY = 0.0;
437     GET_DOUBLE_PARAM(ARGC_ONE, ctrlPtY);
438     double endPtX = 0.0;
439     GET_DOUBLE_PARAM(ARGC_TWO, endPtX);
440     double endPtY = 0.0;
441     GET_DOUBLE_PARAM(ARGC_THREE, endPtY);
442 
443     JS_CALL_DRAWING_FUNC(m_path->QuadTo(ctrlPtX, ctrlPtY, endPtX, endPtY));
444     return nullptr;
445 }
446 
OnConicTo(napi_env env,napi_callback_info info)447 napi_value JsPath::OnConicTo(napi_env env, napi_callback_info info)
448 {
449     if (m_path == nullptr) {
450         ROSEN_LOGE("JsPath::OnConicTo path is nullptr");
451         return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
452     }
453 
454     napi_value argv[ARGC_FIVE] = { nullptr };
455     CHECK_PARAM_NUMBER_WITHOUT_OPTIONAL_PARAMS(argv, ARGC_FIVE);
456 
457     double ctrlPtX = 0.0;
458     GET_DOUBLE_PARAM(ARGC_ZERO, ctrlPtX);
459     double ctrlPtY = 0.0;
460     GET_DOUBLE_PARAM(ARGC_ONE, ctrlPtY);
461     double endPtX = 0.0;
462     GET_DOUBLE_PARAM(ARGC_TWO, endPtX);
463     double endPtY = 0.0;
464     GET_DOUBLE_PARAM(ARGC_THREE, endPtY);
465     double weight = 0.0;
466     GET_DOUBLE_PARAM(ARGC_FOUR, weight);
467 
468     m_path->ConicTo(ctrlPtX, ctrlPtY, endPtX, endPtY, weight);
469     return nullptr;
470 }
471 
OnCubicTo(napi_env env,napi_callback_info info)472 napi_value JsPath::OnCubicTo(napi_env env, napi_callback_info info)
473 {
474     if (m_path == nullptr) {
475         ROSEN_LOGE("JsPath::OnCubicTo path is nullptr");
476         return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
477     }
478 
479     napi_value argv[ARGC_SIX] = {nullptr};
480     CHECK_PARAM_NUMBER_WITHOUT_OPTIONAL_PARAMS(argv, ARGC_SIX);
481 
482     double px1 = 0.0;
483     GET_DOUBLE_PARAM(ARGC_ZERO, px1);
484     double py1 = 0.0;
485     GET_DOUBLE_PARAM(ARGC_ONE, py1);
486     double px2 = 0.0;
487     GET_DOUBLE_PARAM(ARGC_TWO, px2);
488     double py2 = 0.0;
489     GET_DOUBLE_PARAM(ARGC_THREE, py2);
490     double px3 = 0.0;
491     GET_DOUBLE_PARAM(ARGC_FOUR, px3);
492     double py3 = 0.0;
493     GET_DOUBLE_PARAM(ARGC_FIVE, py3);
494 
495     JS_CALL_DRAWING_FUNC(m_path->CubicTo(Point(px1, py1), Point(px2, py2), Point(px3, py3)));
496     return nullptr;
497 }
498 
OnRMoveTo(napi_env env,napi_callback_info info)499 napi_value JsPath::OnRMoveTo(napi_env env, napi_callback_info info)
500 {
501     if (m_path == nullptr) {
502         ROSEN_LOGE("JsPath::OnRMoveTo path is nullptr");
503         return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
504     }
505 
506     napi_value argv[ARGC_TWO] = { nullptr };
507     CHECK_PARAM_NUMBER_WITHOUT_OPTIONAL_PARAMS(argv, ARGC_TWO);
508 
509     double dx = 0.0;
510     GET_DOUBLE_PARAM(ARGC_ZERO, dx);
511     double dy = 0.0;
512     GET_DOUBLE_PARAM(ARGC_ONE, dy);
513 
514     m_path->RMoveTo(dx, dy);
515     return nullptr;
516 }
517 
OnRLineTo(napi_env env,napi_callback_info info)518 napi_value JsPath::OnRLineTo(napi_env env, napi_callback_info info)
519 {
520     if (m_path == nullptr) {
521         ROSEN_LOGE("JsPath::OnRLineTo path is nullptr");
522         return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
523     }
524 
525     napi_value argv[ARGC_TWO] = { nullptr };
526     CHECK_PARAM_NUMBER_WITHOUT_OPTIONAL_PARAMS(argv, ARGC_TWO);
527 
528     double dx = 0.0;
529     GET_DOUBLE_PARAM(ARGC_ZERO, dx);
530     double dy = 0.0;
531     GET_DOUBLE_PARAM(ARGC_ONE, dy);
532 
533     m_path->RLineTo(dx, dy);
534     return nullptr;
535 }
536 
OnRQuadTo(napi_env env,napi_callback_info info)537 napi_value JsPath::OnRQuadTo(napi_env env, napi_callback_info info)
538 {
539     if (m_path == nullptr) {
540         ROSEN_LOGE("JsPath::OnRQuadTo path is nullptr");
541         return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
542     }
543 
544     napi_value argv[ARGC_FOUR] = { nullptr };
545     CHECK_PARAM_NUMBER_WITHOUT_OPTIONAL_PARAMS(argv, ARGC_FOUR);
546 
547     double dx1 = 0.0;
548     GET_DOUBLE_PARAM(ARGC_ZERO, dx1);
549     double dy1 = 0.0;
550     GET_DOUBLE_PARAM(ARGC_ONE, dy1);
551     double dx2 = 0.0;
552     GET_DOUBLE_PARAM(ARGC_TWO, dx2);
553     double dy2 = 0.0;
554     GET_DOUBLE_PARAM(ARGC_THREE, dy2);
555 
556     m_path->RQuadTo(dx1, dy1, dx2, dy2);
557     return nullptr;
558 }
559 
OnRConicTo(napi_env env,napi_callback_info info)560 napi_value JsPath::OnRConicTo(napi_env env, napi_callback_info info)
561 {
562     if (m_path == nullptr) {
563         ROSEN_LOGE("JsPath::OnRConicTo path is nullptr");
564         return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
565     }
566 
567     napi_value argv[ARGC_FIVE] = { nullptr };
568     CHECK_PARAM_NUMBER_WITHOUT_OPTIONAL_PARAMS(argv, ARGC_FIVE);
569 
570     double ctrlPtX = 0.0;
571     GET_DOUBLE_PARAM(ARGC_ZERO, ctrlPtX);
572     double ctrlPtY = 0.0;
573     GET_DOUBLE_PARAM(ARGC_ONE, ctrlPtY);
574     double endPtX = 0.0;
575     GET_DOUBLE_PARAM(ARGC_TWO, endPtX);
576     double endPtY = 0.0;
577     GET_DOUBLE_PARAM(ARGC_THREE, endPtY);
578     double weight = 0.0;
579     GET_DOUBLE_PARAM(ARGC_FOUR, weight);
580 
581     m_path->RConicTo(ctrlPtX, ctrlPtY, endPtX, endPtY, weight);
582     return nullptr;
583 }
584 
OnRCubicTo(napi_env env,napi_callback_info info)585 napi_value JsPath::OnRCubicTo(napi_env env, napi_callback_info info)
586 {
587     if (m_path == nullptr) {
588         ROSEN_LOGE("JsPath::OnRCubicTo path is nullptr");
589         return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
590     }
591 
592     napi_value argv[ARGC_SIX] = { nullptr };
593     CHECK_PARAM_NUMBER_WITHOUT_OPTIONAL_PARAMS(argv, ARGC_SIX);
594 
595     double px1 = 0.0;
596     GET_DOUBLE_PARAM(ARGC_ZERO, px1);
597     double py1 = 0.0;
598     GET_DOUBLE_PARAM(ARGC_ONE, py1);
599     double px2 = 0.0;
600     GET_DOUBLE_PARAM(ARGC_TWO, px2);
601     double py2 = 0.0;
602     GET_DOUBLE_PARAM(ARGC_THREE, py2);
603     double px3 = 0.0;
604     GET_DOUBLE_PARAM(ARGC_FOUR, px3);
605     double py3 = 0.0;
606     GET_DOUBLE_PARAM(ARGC_FIVE, py3);
607 
608     m_path->RCubicTo(px1, py1, px2, py2, px3, py3);
609     return nullptr;
610 }
611 
OnAddPolygon(napi_env env,napi_callback_info info)612 napi_value JsPath::OnAddPolygon(napi_env env, napi_callback_info info)
613 {
614     napi_value argv[ARGC_TWO] = { nullptr };
615     CHECK_PARAM_NUMBER_WITHOUT_OPTIONAL_PARAMS(argv, ARGC_TWO);
616 
617     napi_value array = argv[ARGC_ZERO];
618     uint32_t size = 0;
619     napi_get_array_length(env, array, &size);
620     if (size == 0) {
621         return nullptr;
622     }
623     std::vector<Point> points;
624     points.reserve(size);
625     for (uint32_t i = 0; i < size; i++) {
626         napi_value tempRunBuffer = nullptr;
627         napi_get_element(env, array, i, &tempRunBuffer);
628 
629         napi_value tempValue = nullptr;
630         Point point = Point();
631         double positionX = 0.0;
632         double positionY = 0.0;
633         napi_get_named_property(env, tempRunBuffer, "x", &tempValue);
634         bool isPositionXOk = ConvertFromJsValue(env, tempValue, positionX);
635         napi_get_named_property(env, tempRunBuffer, "y", &tempValue);
636         bool isPositionYOk = ConvertFromJsValue(env, tempValue, positionY);
637         if (!(isPositionXOk && isPositionYOk)) {
638             ROSEN_LOGE("JsPath::OnAddPolygon Argv is invalid");
639             return napi_value();
640         }
641 
642         point.SetX(positionX);
643         point.SetY(positionY);
644         points.emplace_back(point);
645     }
646     if (points.size() != size) {
647         ROSEN_LOGE("JsPath::OnAddPolygon Argv is invalid");
648         return nullptr;
649     }
650 
651     bool close = false;
652     GET_BOOLEAN_PARAM(ARGC_ONE, close);
653 
654     m_path->AddPoly(points, size, close);
655     return nullptr;
656 }
657 
OnOp(napi_env env,napi_callback_info info)658 napi_value JsPath::OnOp(napi_env env, napi_callback_info info)
659 {
660     if (m_path == nullptr) {
661         ROSEN_LOGE("JsPath::OnOp path is nullptr");
662         return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
663     }
664 
665     napi_value argv[ARGC_TWO] = {nullptr};
666     CHECK_PARAM_NUMBER_WITHOUT_OPTIONAL_PARAMS(argv, ARGC_TWO);
667 
668     JsPath* jsPath = nullptr;
669     GET_UNWRAP_PARAM(ARGC_ZERO, jsPath);
670     if (jsPath->GetPath() == nullptr) {
671         ROSEN_LOGE("JsPath::OnOp path is nullptr");
672         return nullptr;
673     }
674 
675     int32_t jsPathOp = 0;
676     GET_ENUM_PARAM(ARGC_ONE, jsPathOp, 0, static_cast<int32_t>(PathOp::REVERSE_DIFFERENCE));
677     return CreateJsValue(env, m_path->Op(*m_path, *jsPath->GetPath(), static_cast<PathOp>(jsPathOp)));
678 }
679 
OnClose(napi_env env,napi_callback_info info)680 napi_value JsPath::OnClose(napi_env env, napi_callback_info info)
681 {
682     if (m_path == nullptr) {
683         ROSEN_LOGE("JsPath::OnClose path is nullptr");
684         return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
685     }
686 
687     JS_CALL_DRAWING_FUNC(m_path->Close());
688     return nullptr;
689 }
690 
OnOffset(napi_env env,napi_callback_info info)691 napi_value JsPath::OnOffset(napi_env env, napi_callback_info info)
692 {
693     if (m_path == nullptr) {
694         ROSEN_LOGE("JsPath::OnOffset path is nullptr");
695         return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
696     }
697 
698     napi_value argv[ARGC_TWO] = { nullptr };
699     CHECK_PARAM_NUMBER_WITHOUT_OPTIONAL_PARAMS(argv, ARGC_TWO);
700 
701     double dx = 0.0;
702     GET_DOUBLE_PARAM(ARGC_ZERO, dx);
703     double dy = 0.0;
704     GET_DOUBLE_PARAM(ARGC_ONE, dy);
705     Path* path = new Path();
706     m_path->Offset(path, dx, dy);
707     return CreateJsPath(env, path);
708 }
709 
OnReset(napi_env env,napi_callback_info info)710 napi_value JsPath::OnReset(napi_env env, napi_callback_info info)
711 {
712     if (m_path == nullptr) {
713         ROSEN_LOGE("JsPath::OnReset path is nullptr");
714         return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
715     }
716 
717     JS_CALL_DRAWING_FUNC(m_path->Reset());
718     return nullptr;
719 }
720 
OnGetLength(napi_env env,napi_callback_info info)721 napi_value JsPath::OnGetLength(napi_env env, napi_callback_info info)
722 {
723     if (m_path == nullptr) {
724         ROSEN_LOGE("JsPath::OnGetLength path is nullptr");
725         return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
726     }
727     napi_value argv[ARGC_ONE] = {nullptr};
728     CHECK_PARAM_NUMBER_WITHOUT_OPTIONAL_PARAMS(argv, ARGC_ONE);
729 
730     bool forceClosed = false;
731     GET_BOOLEAN_PARAM(ARGC_ZERO, forceClosed);
732     double len = m_path->GetLength(forceClosed);
733     return CreateJsNumber(env, len);
734 }
735 
OnGetPositionAndTangent(napi_env env,napi_callback_info info)736 napi_value JsPath::OnGetPositionAndTangent(napi_env env, napi_callback_info info)
737 {
738     if (m_path == nullptr) {
739         ROSEN_LOGE("JsPath::OnGetPositionAndTangent path is nullptr");
740         return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
741     }
742 
743     napi_value argv[ARGC_FOUR] = {nullptr};
744     CHECK_PARAM_NUMBER_WITHOUT_OPTIONAL_PARAMS(argv, ARGC_FOUR);
745 
746     bool forceClosed = false;
747     GET_BOOLEAN_PARAM(ARGC_ZERO, forceClosed);
748 
749     double distance = 0.0;
750     GET_DOUBLE_PARAM(ARGC_ONE, distance);
751 
752     Drawing::Point position;
753     double startPoint[ARGC_TWO] = {0};
754     if (!ConvertFromJsPoint(env, argv[ARGC_TWO], startPoint, ARGC_TWO)) {
755         return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM,
756             "Incorrect parameter2 type. The type of x, y be number.");
757     }
758     position = Drawing::Point(startPoint[ARGC_ZERO], startPoint[ARGC_ONE]);
759 
760     Drawing::Point tangent;
761     double endPoint[ARGC_TWO] = {0};
762     if (!ConvertFromJsPoint(env, argv[ARGC_THREE], endPoint, ARGC_TWO)) {
763         return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM,
764             "Incorrect parameter3 type. The type of x, y be number.");
765     }
766     tangent = Drawing::Point(endPoint[ARGC_ZERO], endPoint[ARGC_ONE]);
767 
768     bool result = m_path->GetPositionAndTangent(distance, position, tangent, forceClosed);
769     if (napi_set_named_property(env, argv[ARGC_TWO], "x", CreateJsNumber(env, position.GetX())) != napi_ok ||
770         napi_set_named_property(env, argv[ARGC_TWO], "y",  CreateJsNumber(env, position.GetY())) != napi_ok ||
771         napi_set_named_property(env, argv[ARGC_THREE], "x", CreateJsNumber(env, tangent.GetX())) != napi_ok ||
772         napi_set_named_property(env, argv[ARGC_THREE], "y", CreateJsNumber(env, tangent.GetY())) != napi_ok) {
773         return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM,
774             "JsPath::OnGetPositionAndTangent Cannot fill 'position' and 'tangent' Point type.");
775     }
776     return CreateJsValue(env, result);
777 }
778 
OnGetMatrix(napi_env env,napi_callback_info info)779 napi_value JsPath::OnGetMatrix(napi_env env, napi_callback_info info)
780 {
781     if (m_path == nullptr) {
782         ROSEN_LOGE("JsPath::OnGetMatrix path is nullptr");
783         return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
784     }
785 
786     napi_value argv[ARGC_FOUR] = {nullptr};
787     CHECK_PARAM_NUMBER_WITHOUT_OPTIONAL_PARAMS(argv, ARGC_FOUR);
788 
789     bool forceClosed = false;
790     GET_BOOLEAN_PARAM(ARGC_ZERO, forceClosed);
791 
792     double distance = 0.0;
793     GET_DOUBLE_PARAM(ARGC_ONE, distance);
794 
795     JsMatrix* jsMatrix = nullptr;
796     GET_UNWRAP_PARAM(ARGC_TWO, jsMatrix);
797 
798     if (jsMatrix->GetMatrix() == nullptr) {
799         ROSEN_LOGE("JsPath::OnGetMatrix jsMatrix is nullptr");
800         return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
801     }
802 
803     int32_t flag = 0;
804     GET_ENUM_PARAM(ARGC_THREE, flag, 0,
805         static_cast<int32_t>(PathMeasureMatrixFlags::GET_POS_AND_TAN_MATRIX));
806     bool result = m_path->GetMatrix(
807         forceClosed,
808         distance,
809         jsMatrix->GetMatrix().get(),
810         static_cast<PathMeasureMatrixFlags>(flag));
811     return CreateJsValue(env, result);
812 }
813 
OnBuildFromSvgString(napi_env env,napi_callback_info info)814 napi_value JsPath::OnBuildFromSvgString(napi_env env, napi_callback_info info)
815 {
816     if (m_path == nullptr) {
817         ROSEN_LOGE("JsPath::OnBuildFromSVGString path is nullptr");
818         return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
819     }
820 
821     napi_value argv[ARGC_ONE] = { nullptr };
822     CHECK_PARAM_NUMBER_WITHOUT_OPTIONAL_PARAMS(argv, ARGC_ONE);
823 
824     std::string str = {""};
825     if (!(ConvertFromJsValue(env, argv[ARGC_ZERO], str))) {
826         ROSEN_LOGE("JsPath::OnBuildFromSVGString Argv is invalid");
827         return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
828     }
829 
830     bool result = m_path->BuildFromSVGString(str);
831     return CreateJsValue(env, result);
832 }
833 
OnAddOval(napi_env env,napi_callback_info info)834 napi_value JsPath::OnAddOval(napi_env env, napi_callback_info info)
835 {
836     if (m_path == nullptr) {
837         ROSEN_LOGE("JsPath::OnAddOval path is nullptr");
838         return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
839     }
840 
841     size_t argc = ARGC_THREE;
842     napi_value argv[ARGC_THREE] = {nullptr};
843     CHECK_PARAM_NUMBER_WITH_OPTIONAL_PARAMS(argv, argc, ARGC_TWO, ARGC_THREE);
844 
845     Drawing::Rect drawingRect;
846     double ltrb[ARGC_FOUR] = {0};
847     if (!ConvertFromJsRect(env, argv[ARGC_ZERO], ltrb, ARGC_FOUR)) {
848         return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM,
849             "Incorrect parameter0 type. The type of left, top, right and bottom must be number.");
850     }
851     drawingRect = Drawing::Rect(ltrb[ARGC_ZERO], ltrb[ARGC_ONE], ltrb[ARGC_TWO], ltrb[ARGC_THREE]);
852 
853     int32_t start = 0;
854     GET_INT32_CHECK_GE_ZERO_PARAM(ARGC_ONE, start);
855     if (argc == ARGC_TWO) {
856         JS_CALL_DRAWING_FUNC(m_path->AddOval(drawingRect, start,
857             static_cast<PathDirection>(PathDirection::CW_DIRECTION)));
858         return nullptr;
859     }
860     int32_t jsDirection = 0;
861     GET_ENUM_PARAM(ARGC_TWO, jsDirection, 0, static_cast<int32_t>(PathDirection::CCW_DIRECTION));
862 
863     JS_CALL_DRAWING_FUNC(m_path->AddOval(drawingRect, start, static_cast<PathDirection>(jsDirection)));
864     return nullptr;
865 }
866 
OnAddCircle(napi_env env,napi_callback_info info)867 napi_value JsPath::OnAddCircle(napi_env env, napi_callback_info info)
868 {
869     if (m_path == nullptr) {
870         ROSEN_LOGE("JsPath::OnAddCircle path is nullptr");
871         return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
872     }
873 
874     size_t argc = ARGC_FOUR;
875     napi_value argv[ARGC_FOUR] = {nullptr};
876     CHECK_PARAM_NUMBER_WITH_OPTIONAL_PARAMS(argv, argc, ARGC_THREE, ARGC_FOUR);
877 
878     double px1 = 0.0;
879     GET_DOUBLE_PARAM(ARGC_ZERO, px1);
880     double py1 = 0.0;
881     GET_DOUBLE_PARAM(ARGC_ONE, py1);
882     double radius = 0.0;
883     GET_DOUBLE_PARAM(ARGC_TWO, radius);
884     if (argc == ARGC_THREE) {
885         JS_CALL_DRAWING_FUNC(m_path->AddCircle(px1, py1, radius));
886         return nullptr;
887     }
888     int32_t jsDirection = 0;
889     GET_ENUM_PARAM(ARGC_THREE, jsDirection, 0, static_cast<int32_t>(PathDirection::CCW_DIRECTION));
890 
891     JS_CALL_DRAWING_FUNC(m_path->AddCircle(px1, py1, radius, static_cast<PathDirection>(jsDirection)));
892     return nullptr;
893 }
894 
OnAddArc(napi_env env,napi_callback_info info)895 napi_value JsPath::OnAddArc(napi_env env, napi_callback_info info)
896 {
897     if (m_path == nullptr) {
898         ROSEN_LOGE("JsPath::OnAddArc path is nullptr");
899         return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
900     }
901 
902     napi_value argv[ARGC_THREE] = {nullptr};
903     CHECK_PARAM_NUMBER_WITHOUT_OPTIONAL_PARAMS(argv, ARGC_THREE);
904 
905     Drawing::Rect drawingRect;
906     double ltrb[ARGC_FOUR] = {0};
907     if (!ConvertFromJsRect(env, argv[ARGC_ZERO], ltrb, ARGC_FOUR)) {
908         return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM,
909             "Incorrect parameter0 type. The type of left, top, right and bottom must be number.");
910     }
911     drawingRect = Drawing::Rect(ltrb[ARGC_ZERO], ltrb[ARGC_ONE], ltrb[ARGC_TWO], ltrb[ARGC_THREE]);
912 
913     double startDeg = 0.0;
914     GET_DOUBLE_PARAM(ARGC_ONE, startDeg);
915     double sweepDeg = 0.0;
916     GET_DOUBLE_PARAM(ARGC_TWO, sweepDeg);
917 
918     JS_CALL_DRAWING_FUNC(m_path->AddArc(drawingRect, startDeg, sweepDeg));
919     return nullptr;
920 }
921 
OnAddRect(napi_env env,napi_callback_info info)922 napi_value JsPath::OnAddRect(napi_env env, napi_callback_info info)
923 {
924     if (m_path == nullptr) {
925         ROSEN_LOGE("JsPath::OnAddRect path is nullptr");
926         return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
927     }
928 
929     size_t argc = ARGC_TWO;
930     napi_value argv[ARGC_TWO] = {nullptr};
931     CHECK_PARAM_NUMBER_WITH_OPTIONAL_PARAMS(argv, argc, ARGC_ONE, ARGC_TWO);
932 
933     Drawing::Rect drawingRect;
934     double ltrb[ARGC_FOUR] = {0};
935     if (!ConvertFromJsRect(env, argv[ARGC_ZERO], ltrb, ARGC_FOUR)) {
936         return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM,
937             "Incorrect parameter0 type. The type of left, top, right and bottom must be number.");
938     }
939     drawingRect = Drawing::Rect(ltrb[ARGC_ZERO], ltrb[ARGC_ONE], ltrb[ARGC_TWO], ltrb[ARGC_THREE]);
940     if (argc == ARGC_ONE) {
941         JS_CALL_DRAWING_FUNC(m_path->AddRect(drawingRect));
942         return nullptr;
943     }
944     int32_t jsDirection = 0;
945     GET_ENUM_PARAM(ARGC_ONE, jsDirection, 0, static_cast<int32_t>(PathDirection::CCW_DIRECTION));
946 
947     JS_CALL_DRAWING_FUNC(m_path->AddRect(drawingRect, static_cast<PathDirection>(jsDirection)));
948     return nullptr;
949 }
950 
OnAddRoundRect(napi_env env,napi_callback_info info)951 napi_value JsPath::OnAddRoundRect(napi_env env, napi_callback_info info)
952 {
953     if (m_path == nullptr) {
954         ROSEN_LOGE("JsPath::OnAddRoundRect path is nullptr");
955         return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
956     }
957 
958     size_t argc = ARGC_TWO;
959     napi_value argv[ARGC_TWO] = {nullptr};
960     CHECK_PARAM_NUMBER_WITH_OPTIONAL_PARAMS(argv, argc, ARGC_ONE, ARGC_TWO);
961 
962     JsRoundRect* jsRoundRect = nullptr;
963     GET_UNWRAP_PARAM(ARGC_ZERO, jsRoundRect);
964     if (argc == ARGC_ONE) {
965         JS_CALL_DRAWING_FUNC(m_path->AddRoundRect(jsRoundRect->GetRoundRect()));
966         return nullptr;
967     }
968     int32_t jsDirection = 0;
969     GET_ENUM_PARAM(ARGC_ONE, jsDirection, 0, static_cast<int32_t>(PathDirection::CCW_DIRECTION));
970 
971     JS_CALL_DRAWING_FUNC(m_path->AddRoundRect(jsRoundRect->GetRoundRect(), static_cast<PathDirection>(jsDirection)));
972     return nullptr;
973 }
974 
OnAddPath(napi_env env,napi_callback_info info)975 napi_value JsPath::OnAddPath(napi_env env, napi_callback_info info)
976 {
977     if (m_path == nullptr) {
978         ROSEN_LOGE("JsPath::OnAddPath path is nullptr");
979         return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
980     }
981 
982     size_t argc = ARGC_TWO;
983     napi_value argv[ARGC_TWO] = {nullptr};
984     CHECK_PARAM_NUMBER_WITH_OPTIONAL_PARAMS(argv, argc, ARGC_ONE, ARGC_TWO);
985 
986     JsPath* jsPath = nullptr;
987     GET_UNWRAP_PARAM(ARGC_ZERO, jsPath);
988     if (jsPath->GetPath() == nullptr) {
989         ROSEN_LOGE("JsPath::OnAddPath path is nullptr");
990         return nullptr;
991     }
992     if (argc == ARGC_ONE) {
993         JS_CALL_DRAWING_FUNC(m_path->AddPath(*jsPath->GetPath(), Drawing::Matrix()));
994         return nullptr;
995     }
996     Drawing::Matrix* drawingMatrixPtr = nullptr;
997     napi_valuetype valueType = napi_undefined;
998     if (napi_typeof(env, argv[ARGC_ONE], &valueType) != napi_ok ||
999         (valueType != napi_null && valueType != napi_object)) {
1000         return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Incorrect OnAddPath parameter1 type.");
1001     }
1002     if (valueType == napi_object) {
1003         JsMatrix* jsMatrix = nullptr;
1004         GET_UNWRAP_PARAM(ARGC_ONE, jsMatrix);
1005         if (jsMatrix->GetMatrix() != nullptr) {
1006             drawingMatrixPtr = jsMatrix->GetMatrix().get();
1007         }
1008     }
1009     JS_CALL_DRAWING_FUNC(m_path->AddPath(*jsPath->GetPath(),
1010         drawingMatrixPtr ? *drawingMatrixPtr : Drawing::Matrix()));
1011     return nullptr;
1012 }
1013 
OnTransform(napi_env env,napi_callback_info info)1014 napi_value JsPath::OnTransform(napi_env env, napi_callback_info info)
1015 {
1016     if (m_path == nullptr) {
1017         ROSEN_LOGE("JsPath::OnTransform path is nullptr");
1018         return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
1019     }
1020 
1021     napi_value argv[ARGC_ONE] = {nullptr};
1022     CHECK_PARAM_NUMBER_WITHOUT_OPTIONAL_PARAMS(argv, ARGC_ONE);
1023 
1024     JsMatrix* jsMatrix = nullptr;
1025     GET_UNWRAP_PARAM(ARGC_ZERO, jsMatrix);
1026     if (jsMatrix->GetMatrix() == nullptr) {
1027         ROSEN_LOGE("JsPath::OnAddPath Matrix is nullptr");
1028         return nullptr;
1029     }
1030 
1031     JS_CALL_DRAWING_FUNC(m_path->Transform(*jsMatrix->GetMatrix()));
1032     return nullptr;
1033 }
1034 
OnContains(napi_env env,napi_callback_info info)1035 napi_value JsPath::OnContains(napi_env env, napi_callback_info info)
1036 {
1037     if (m_path == nullptr) {
1038         ROSEN_LOGE("JsPath::OnContains path is nullptr");
1039         return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
1040     }
1041 
1042     napi_value argv[ARGC_TWO] = {nullptr};
1043     CHECK_PARAM_NUMBER_WITHOUT_OPTIONAL_PARAMS(argv, ARGC_TWO);
1044 
1045     double x = 0.0;
1046     GET_DOUBLE_PARAM(ARGC_ZERO, x);
1047     double y = 0.0;
1048     GET_DOUBLE_PARAM(ARGC_ONE, y);
1049 
1050     return CreateJsValue(env, m_path->Contains(x, y));
1051 }
1052 
OnSetFillType(napi_env env,napi_callback_info info)1053 napi_value JsPath::OnSetFillType(napi_env env, napi_callback_info info)
1054 {
1055     if (m_path == nullptr) {
1056         ROSEN_LOGE("JsPath::OnSetFillType path is nullptr");
1057         return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
1058     }
1059 
1060     napi_value argv[ARGC_ONE] = {nullptr};
1061     CHECK_PARAM_NUMBER_WITHOUT_OPTIONAL_PARAMS(argv, ARGC_ONE);
1062 
1063     int32_t jsFillType = 0;
1064     GET_ENUM_PARAM(ARGC_ZERO, jsFillType, 0, static_cast<int32_t>(PathFillType::INVERSE_EVENTODD));
1065 
1066     JS_CALL_DRAWING_FUNC(m_path->SetFillStyle(static_cast<PathFillType>(jsFillType)));
1067     return nullptr;
1068 }
1069 
OnGetBounds(napi_env env,napi_callback_info info)1070 napi_value JsPath::OnGetBounds(napi_env env, napi_callback_info info)
1071 {
1072     if (m_path == nullptr) {
1073         ROSEN_LOGE("JsPath::OnGetBounds path is nullptr");
1074         return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
1075     }
1076     auto bounds = m_path->GetBounds();
1077     std::shared_ptr<Rect> rect = std::make_shared<Rect>(bounds.GetLeft(),
1078                                                         bounds.GetTop(), bounds.GetRight(), bounds.GetBottom());
1079 
1080     return GetRectAndConvertToJsValue(env, rect);
1081 }
1082 
OnIsClosed(napi_env env,napi_callback_info info)1083 napi_value JsPath::OnIsClosed(napi_env env, napi_callback_info info)
1084 {
1085     if (m_path == nullptr) {
1086         ROSEN_LOGE("JsPath::OnIsClosed path is nullptr");
1087         return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
1088     }
1089 
1090     bool result = m_path->IsClosed(false);
1091     return CreateJsValue(env, result);
1092 }
1093 
GetPath()1094 Path* JsPath::GetPath()
1095 {
1096     return m_path;
1097 }
1098 } // namespace Drawing
1099 } // namespace OHOS::Rosen
1100