• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_canvas.h"
17 
18 #include <mutex>
19 
20 #ifdef USE_M133_SKIA
21 #include "src/base/SkUTF.h"
22 #else
23 #include "src/utils/SkUTF.h"
24 #endif
25 
26 #if defined(ROSEN_OHOS) || defined(ROSEN_ARKUI_X)
27 #include "pixel_map_napi.h"
28 #endif
29 #include "native_value.h"
30 #include "draw/canvas.h"
31 #include "draw/path.h"
32 #include "image/image.h"
33 #include "render/rs_pixel_map_shader.h"
34 #include "text/text.h"
35 #include "text/text_blob.h"
36 #include "utils/point.h"
37 #include "utils/rect.h"
38 #include "utils/sampling_options.h"
39 #include "utils/vertices.h"
40 
41 #include "brush_napi/js_brush.h"
42 #include "font_napi/js_font.h"
43 #include "lattice_napi/js_lattice.h"
44 #include "matrix_napi/js_matrix.h"
45 #include "pen_napi/js_pen.h"
46 #include "path_napi/js_path.h"
47 #include "region_napi/js_region.h"
48 #include "sampling_options_napi/js_sampling_options.h"
49 #include "text_blob_napi/js_text_blob.h"
50 #include "roundRect_napi/js_roundrect.h"
51 #include "js_drawing_utils.h"
52 #include "utils/performanceCaculate.h"
53 #if defined(OHOS_PLATFORM) || defined(ROSEN_ARKUI_X)
54 #include "pipeline/rs_recording_canvas.h"
55 #endif
56 
57 namespace OHOS::Rosen {
58 #if defined(ROSEN_OHOS) || defined(ROSEN_ARKUI_X)
59 using namespace Media;
60 namespace {
DrawingPixelMapMesh(std::shared_ptr<Media::PixelMap> pixelMap,int column,int row,float * vertices,uint32_t * colors,Drawing::Canvas * m_canvas)61 void DrawingPixelMapMesh(std::shared_ptr<Media::PixelMap> pixelMap, int column, int row,
62     float* vertices, uint32_t* colors, Drawing::Canvas* m_canvas)
63 {
64     const int vertCounts = (column + 1) * (row + 1);
65     int32_t size = 6; // triangle * 2
66     const int indexCount = column * row * size;
67     uint32_t flags = Drawing::BuilderFlags::HAS_TEXCOORDS_BUILDER_FLAG;
68     if (colors) {
69         flags |= Drawing::BuilderFlags::HAS_COLORS_BUILDER_FLAG;
70     }
71     Drawing::Vertices::Builder builder(Drawing::VertexMode::TRIANGLES_VERTEXMODE, vertCounts, indexCount, flags);
72     if (memcpy_s(builder.Positions(), vertCounts * sizeof(Drawing::Point),
73         vertices, vertCounts * sizeof(Drawing::Point)) != 0) {
74         ROSEN_LOGE("Drawing_napi::DrawingPixelMapMesh memcpy points failed");
75         return;
76     }
77     int32_t colorSize = 4; // size of color
78     if (colors && (memcpy_s(builder.Colors(), vertCounts * colorSize, colors, vertCounts * colorSize) != 0)) {
79         ROSEN_LOGE("Drawing_napi::DrawingPixelMapMesh memcpy colors failed");
80         return;
81     }
82     Drawing::Point* texsPoint = builder.TexCoords();
83     uint16_t* indices = builder.Indices();
84     if (!texsPoint || !indices) {
85         ROSEN_LOGE("Drawing_napi::textPoint or indices is nullptr");
86         return;
87     }
88 
89     const float height = static_cast<float>(pixelMap->GetHeight());
90     const float width = static_cast<float>(pixelMap->GetWidth());
91 
92     if (column == 0 || row == 0) {
93         ROSEN_LOGE("Drawing_napi::DrawingPixelMapMesh column or row is invalid");
94         return;
95     }
96     const float dy = height / row;
97     const float dx = width / column;
98 
99     Drawing::Point* texsPit = texsPoint;
100     float y = 0;
101     for (int i = 0; i <= row; i++) {
102         if (i == row) {
103             y = height;
104         }
105         float x = 0;
106         for (int j = 0; j < column; j++) {
107             texsPit->Set(x, y);
108             texsPit += 1;
109             x += dx;
110         }
111         texsPit->Set(width, y);
112         texsPit += 1;
113         y += dy;
114     }
115 
116     uint16_t* dexIndices = indices;
117     int indexIndices = 0;
118     for (int i = 0; i < row; i++) {
119         for (int j = 0; j < column; j++) {
120             *dexIndices++ = indexIndices;
121             *dexIndices++ = indexIndices + column + 1;
122             *dexIndices++ = indexIndices + column + 2; // 2 means the third index of the triangle
123 
124             *dexIndices++ = indexIndices;
125             *dexIndices++ = indexIndices + column + 2; // 2 means the third index of the triangle
126             *dexIndices++ = indexIndices + 1;
127 
128             indexIndices += 1;
129         }
130         indexIndices += 1;
131     }
132 
133     if (!m_canvas->GetMutableBrush().IsValid()) {
134         ROSEN_LOGE("Drawing_napi::DrawingPixelMapMesh paint is invalid");
135         return;
136     }
137     if (m_canvas->GetDrawingType() != Drawing::DrawingType::RECORDING) {
138         std::shared_ptr<Drawing::Image> image = Drawing::ExtractDrawingImage(pixelMap);
139         if (image == nullptr) {
140             ROSEN_LOGE("Drawing_napi::DrawingPixelMapMesh image is nullptr");
141             return;
142         }
143         auto shader = Drawing::ShaderEffect::CreateImageShader(*image,
144             Drawing::TileMode::CLAMP, Drawing::TileMode::CLAMP, Drawing::SamplingOptions(), Drawing::Matrix());
145         m_canvas->GetMutableBrush().SetShaderEffect(shader);
146     } else {
147         auto shader = Drawing::ShaderEffect::CreateExtendShader(std::make_shared<RSPixelMapShader>(pixelMap,
148             Drawing::TileMode::CLAMP, Drawing::TileMode::CLAMP, Drawing::SamplingOptions(), Drawing::Matrix()));
149         m_canvas->GetMutableBrush().SetShaderEffect(shader);
150     }
151     JS_CALL_DRAWING_FUNC(
152         m_canvas->DrawVertices(*builder.Detach(), Drawing::BlendMode::MODULATE));
153 }
154 }
155 #endif
156 
157 namespace Drawing {
158 thread_local napi_ref JsCanvas::constructor_ = nullptr;
159 static std::mutex g_constructorInitMutex;
160 const std::string CLASS_NAME = "Canvas";
161 
162 static const napi_property_descriptor g_properties[] = {
163     DECLARE_NAPI_FUNCTION("clear", JsCanvas::Clear),
164     DECLARE_NAPI_FUNCTION("drawArc", JsCanvas::DrawArc),
165     DECLARE_NAPI_FUNCTION("drawArcWithCenter", JsCanvas::DrawArcWithCenter),
166     DECLARE_NAPI_FUNCTION("drawRect", JsCanvas::DrawRect),
167     DECLARE_NAPI_FUNCTION("drawCircle", JsCanvas::DrawCircle),
168     DECLARE_NAPI_FUNCTION("drawImage", JsCanvas::DrawImage),
169     DECLARE_NAPI_FUNCTION("drawImageLattice", JsCanvas::DrawImageLattice),
170     DECLARE_NAPI_FUNCTION("drawImageNine", JsCanvas::DrawImageNine),
171     DECLARE_NAPI_FUNCTION("drawImageRect", JsCanvas::DrawImageRect),
172     DECLARE_NAPI_FUNCTION("drawImageRectWithSrc", JsCanvas::DrawImageRectWithSrc),
173     DECLARE_NAPI_FUNCTION("drawColor", JsCanvas::DrawColor),
174     DECLARE_NAPI_FUNCTION("drawOval", JsCanvas::DrawOval),
175     DECLARE_NAPI_FUNCTION("drawPoint", JsCanvas::DrawPoint),
176     DECLARE_NAPI_FUNCTION("drawPoints", JsCanvas::DrawPoints),
177     DECLARE_NAPI_FUNCTION("drawPath", JsCanvas::DrawPath),
178     DECLARE_NAPI_FUNCTION("drawLine", JsCanvas::DrawLine),
179     DECLARE_NAPI_FUNCTION("drawTextBlob", JsCanvas::DrawText),
180     DECLARE_NAPI_FUNCTION("drawSingleCharacter", JsCanvas::DrawSingleCharacter),
181     DECLARE_NAPI_FUNCTION("drawSingleCharacterWithFeatures", JsCanvas::DrawSingleCharacterWithFeatures),
182     DECLARE_NAPI_FUNCTION("getTotalMatrix", JsCanvas::GetTotalMatrix),
183     DECLARE_NAPI_FUNCTION("getLocalClipBounds", JsCanvas::GetLocalClipBounds),
184     DECLARE_NAPI_FUNCTION("drawPixelMapMesh", JsCanvas::DrawPixelMapMesh),
185     DECLARE_NAPI_FUNCTION("drawRegion", JsCanvas::DrawRegion),
186     DECLARE_NAPI_FUNCTION("drawShadow", JsCanvas::DrawShadow),
187     DECLARE_NAPI_FUNCTION("drawBackground", JsCanvas::DrawBackground),
188     DECLARE_NAPI_FUNCTION("drawRoundRect", JsCanvas::DrawRoundRect),
189     DECLARE_NAPI_FUNCTION("drawNestedRoundRect", JsCanvas::DrawNestedRoundRect),
190     DECLARE_NAPI_FUNCTION("attachPen", JsCanvas::AttachPen),
191     DECLARE_NAPI_FUNCTION("attachBrush", JsCanvas::AttachBrush),
192     DECLARE_NAPI_FUNCTION("detachPen", JsCanvas::DetachPen),
193     DECLARE_NAPI_FUNCTION("detachBrush", JsCanvas::DetachBrush),
194     DECLARE_NAPI_FUNCTION("skew", JsCanvas::Skew),
195     DECLARE_NAPI_FUNCTION("rotate", JsCanvas::Rotate),
196     DECLARE_NAPI_FUNCTION("getSaveCount", JsCanvas::GetSaveCount),
197     DECLARE_NAPI_FUNCTION("getWidth", JsCanvas::GetWidth),
198     DECLARE_NAPI_FUNCTION("getHeight", JsCanvas::GetHeight),
199     DECLARE_NAPI_FUNCTION("save", JsCanvas::Save),
200     DECLARE_NAPI_FUNCTION("saveLayer", JsCanvas::SaveLayer),
201     DECLARE_NAPI_FUNCTION("restore", JsCanvas::Restore),
202     DECLARE_NAPI_FUNCTION("restoreToCount", JsCanvas::RestoreToCount),
203     DECLARE_NAPI_FUNCTION("scale", JsCanvas::Scale),
204     DECLARE_NAPI_FUNCTION("clipPath", JsCanvas::ClipPath),
205     DECLARE_NAPI_FUNCTION("clipRegion", JsCanvas::ClipRegion),
206     DECLARE_NAPI_FUNCTION("clipRect", JsCanvas::ClipRect),
207     DECLARE_NAPI_FUNCTION("concatMatrix", JsCanvas::ConcatMatrix),
208     DECLARE_NAPI_FUNCTION("clipRoundRect", JsCanvas::ClipRoundRect),
209     DECLARE_NAPI_FUNCTION("setMatrix", JsCanvas::SetMatrix),
210     DECLARE_NAPI_FUNCTION("resetMatrix", JsCanvas::ResetMatrix),
211     DECLARE_NAPI_FUNCTION("translate", JsCanvas::Translate),
212     DECLARE_NAPI_FUNCTION("isClipEmpty", JsCanvas::IsClipEmpty),
213     DECLARE_NAPI_FUNCTION("quickRejectPath", JsCanvas::QuickRejectPath),
214     DECLARE_NAPI_FUNCTION("quickRejectRect", JsCanvas::QuickRejectRect),
215 };
216 
Constructor(napi_env env,napi_callback_info info)217 napi_value JsCanvas::Constructor(napi_env env, napi_callback_info info)
218 {
219     DRAWING_PERFORMANCE_START_CACULATE;
220     napi_value jsThis = nullptr;
221     size_t argc = ARGC_ONE;
222     napi_value argv[ARGC_ONE] = {nullptr};
223     napi_status status = napi_get_cb_info(env, info, &argc, argv, &jsThis, nullptr);
224     if (status != napi_ok) {
225         ROSEN_LOGE("Drawing_napi: failed to napi_get_cb_info");
226         return nullptr;
227     }
228 
229 #if defined(ROSEN_OHOS) || defined(ROSEN_ARKUI_X)
230     CHECK_PARAM_NUMBER_WITHOUT_OPTIONAL_PARAMS(argv, ARGC_ONE);
231 
232     PixelMapNapi* pixelMapNapi = nullptr;
233     GET_UNWRAP_PARAM(ARGC_ZERO, pixelMapNapi);
234 
235     if (pixelMapNapi->GetPixelNapiInner() == nullptr) {
236         return nullptr;
237     }
238 
239     Bitmap bitmap;
240     if (!ExtracetDrawingBitmap(pixelMapNapi->GetPixelNapiInner(), bitmap)) {
241         return nullptr;
242     }
243 
244     Canvas* canvas = new Canvas();
245     canvas->Bind(bitmap);
246     JsCanvas *jsCanvas = new JsCanvas(canvas, true);
247     jsCanvas->mPixelMap_ = pixelMapNapi->GetPixelNapiInner();
248     status = napi_wrap(env, jsThis, jsCanvas, JsCanvas::Destructor, nullptr, nullptr);
249     if (status != napi_ok) {
250         delete jsCanvas;
251         ROSEN_LOGE("Drawing_napi: Failed to wrap native instance");
252         return nullptr;
253     }
254     return jsThis;
255 #else
256     return nullptr;
257 #endif
258 }
259 
CreateConstructor(napi_env env)260 bool JsCanvas::CreateConstructor(napi_env env)
261 {
262     napi_value constructor = nullptr;
263     napi_status status = napi_define_class(env, CLASS_NAME.c_str(), NAPI_AUTO_LENGTH, Constructor, nullptr,
264         sizeof(g_properties) / sizeof(g_properties[0]), g_properties, &constructor);
265     if (status != napi_ok) {
266         ROSEN_LOGE("Drawing_napi: CreateConstructor Failed, define class fail");
267         return false;
268     }
269 
270     status = napi_create_reference(env, constructor, 1, &constructor_);
271     if (status != napi_ok) {
272         ROSEN_LOGE("Drawing_napi: CreateConstructor Failed, create reference fail");
273         return false;
274     }
275     return true;
276 }
277 
CreateJsCanvas(napi_env env,Canvas * canvas)278 napi_value JsCanvas::CreateJsCanvas(napi_env env, Canvas* canvas)
279 {
280     napi_value constructor = nullptr;
281     napi_value result = nullptr;
282 
283     {
284         std::lock_guard<std::mutex> lock(g_constructorInitMutex);
285         if (!constructor_) {
286             if (!CreateConstructor(env)) {
287                 ROSEN_LOGE("Drawing_napi: CreateConstructor Failed");
288                 return nullptr;
289             }
290         }
291     }
292 
293     napi_status status = napi_get_reference_value(env, constructor_, &constructor);
294     if (status != napi_ok) {
295         ROSEN_LOGE("Drawing_napi: CreateJsCanvas napi_get_reference_value failed");
296         return nullptr;
297     }
298 
299     if (canvas == nullptr) {
300         ROSEN_LOGE("Drawing_napi: canvas is nullptr");
301         return nullptr;
302     }
303     JsCanvas *jsCanvas = new JsCanvas(canvas);
304     napi_create_object(env, &result);
305     if (result == nullptr) {
306         delete jsCanvas;
307         ROSEN_LOGE("jsCanvas::CreateJsCanvas Create canvas object failed!");
308         return nullptr;
309     }
310     status = napi_wrap(env, result, jsCanvas, JsCanvas::Destructor, nullptr, nullptr);
311     if (status != napi_ok) {
312         delete jsCanvas;
313         ROSEN_LOGE("Drawing_napi: Failed to wrap native instance");
314         return nullptr;
315     }
316     napi_define_properties(env, result, sizeof(g_properties) / sizeof(g_properties[0]), g_properties);
317     return result;
318 }
319 
Destructor(napi_env env,void * nativeObject,void * finalize)320 void JsCanvas::Destructor(napi_env env, void *nativeObject, void *finalize)
321 {
322     DRAWING_PERFORMANCE_STOP_CACULATE;
323     (void)finalize;
324     if (nativeObject != nullptr) {
325         JsCanvas *napi = reinterpret_cast<JsCanvas *>(nativeObject);
326         delete napi;
327     }
328 }
329 
Init(napi_env env,napi_value exportObj)330 napi_value JsCanvas::Init(napi_env env, napi_value exportObj)
331 {
332     {
333         std::lock_guard<std::mutex> lock(g_constructorInitMutex);
334         if (!constructor_) {
335             if (!CreateConstructor(env)) {
336                 ROSEN_LOGE("Drawing_napi: CreateConstructor Failed");
337                 return nullptr;
338             }
339         }
340     }
341 
342     napi_value constructor = nullptr;
343     napi_status status = napi_get_reference_value(env, constructor_, &constructor);
344     if (status != napi_ok) {
345         ROSEN_LOGE("Drawing_napi: napi_get_reference_value failed");
346         return nullptr;
347     }
348 
349     status = napi_set_named_property(env, exportObj, CLASS_NAME.c_str(), constructor);
350     if (status != napi_ok) {
351         ROSEN_LOGE("Drawing_napi: Failed to set constructor");
352         return nullptr;
353     }
354     return exportObj;
355 }
356 
~JsCanvas()357 JsCanvas::~JsCanvas()
358 {
359     if (owned_) {
360         delete m_canvas;
361     }
362     m_canvas = nullptr;
363 }
364 
Clear(napi_env env,napi_callback_info info)365 napi_value JsCanvas::Clear(napi_env env, napi_callback_info info)
366 {
367     JsCanvas* me = CheckParamsAndGetThis<JsCanvas>(env, info);
368     return (me != nullptr) ? me->OnClear(env, info) : nullptr;
369 }
370 
OnClear(napi_env env,napi_callback_info info)371 napi_value JsCanvas::OnClear(napi_env env, napi_callback_info info)
372 {
373     if (m_canvas == nullptr) {
374         ROSEN_LOGE("JsCanvas::OnClear canvas is null");
375         return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
376     }
377 
378     napi_value argv[ARGC_ONE] = {nullptr};
379     CHECK_PARAM_NUMBER_WITHOUT_OPTIONAL_PARAMS(argv, ARGC_ONE);
380 
381     ColorQuad color;
382     if (!ConvertFromAdaptHexJsColor(env, argv[ARGC_ZERO], color)) {
383         ROSEN_LOGE("JsCanvas::OnClear Argv[0] is invalid");
384         return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM,
385             "Parameter verification failed. The range of color channels must be [0, 255].");
386     }
387 
388     JS_CALL_DRAWING_FUNC(m_canvas->Clear(color));
389 #if defined(ROSEN_OHOS) || defined(ROSEN_ARKUI_X)
390     if (mPixelMap_ != nullptr) {
391         mPixelMap_->MarkDirty();
392     }
393 #endif
394     return nullptr;
395 }
396 
DrawShadow(napi_env env,napi_callback_info info)397 napi_value JsCanvas::DrawShadow(napi_env env, napi_callback_info info)
398 {
399     JsCanvas* me = CheckParamsAndGetThis<JsCanvas>(env, info);
400     return (me != nullptr) ? me->OnDrawShadow(env, info) : nullptr;
401 }
402 
OnDrawShadow(napi_env env,napi_callback_info info)403 napi_value JsCanvas::OnDrawShadow(napi_env env, napi_callback_info info)
404 {
405     if (m_canvas == nullptr) {
406         ROSEN_LOGE("JsCanvas::OnDrawShadow canvas is null.");
407         return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
408     }
409     napi_value argv[ARGC_SEVEN] = { nullptr };
410     CHECK_PARAM_NUMBER_WITHOUT_OPTIONAL_PARAMS(argv, ARGC_SEVEN);
411     JsPath* jsPath = nullptr;
412     GET_UNWRAP_PARAM(ARGC_ZERO, jsPath);
413 
414     Point3 offset;
415     Point3 lightPos;
416     if (!ConvertFromJsPoint3d(env, argv[ARGC_ONE], offset) || !ConvertFromJsPoint3d(env, argv[ARGC_TWO], lightPos)) {
417         ROSEN_LOGE("JsCanvas::OnDrawShadow argv[ARGC_ONE] or argv[ARGC_TWO] is invalid.");
418         return nullptr;
419     }
420 
421     double lightRadius = 0.0f;
422     GET_DOUBLE_PARAM(ARGC_THREE, lightRadius);
423 
424     ColorQuad ambientColor;
425     ColorQuad spotColor;
426     if (!ConvertFromAdaptHexJsColor(env, argv[ARGC_FOUR], ambientColor) ||
427         !ConvertFromAdaptHexJsColor(env, argv[ARGC_FIVE], spotColor)) {
428         ROSEN_LOGE("JsCanvas::OnDrawShadow argv[ARGC_FOUR] or argv[ARGC_FIVE] is invalid.");
429         return nullptr;
430     }
431 
432     int32_t shadowFlag = 0;
433     GET_ENUM_PARAM(ARGC_SIX, shadowFlag, 0, static_cast<int32_t>(ShadowFlags::ALL));
434     OHOS::Rosen::Drawing::ShadowFlags shadowFlags = static_cast<OHOS::Rosen::Drawing::ShadowFlags>(shadowFlag);
435     if (!ConvertFromJsShadowFlag(env, argv[ARGC_SIX], shadowFlags)) {
436         ROSEN_LOGE("JsCanvas::OnDrawShadow argv[ARGC_SIX] is invalid.");
437         return nullptr;
438     }
439     if (jsPath->GetPath() == nullptr) {
440         ROSEN_LOGE("JsCanvas::OnDrawShadow GetPath is nullptr.");
441         return nullptr;
442     }
443 
444     m_canvas->DrawShadow(*jsPath->GetPath(), offset, lightPos, lightRadius, ambientColor, spotColor,
445         static_cast<ShadowFlags>(shadowFlag));
446 #if defined(ROSEN_OHOS) || defined(ROSEN_ARKUI_X)
447     if (mPixelMap_ != nullptr) {
448         mPixelMap_->MarkDirty();
449     }
450 #endif
451     return nullptr;
452 }
453 
DrawArc(napi_env env,napi_callback_info info)454 napi_value JsCanvas::DrawArc(napi_env env, napi_callback_info info)
455 {
456     JsCanvas* me = CheckParamsAndGetThis<JsCanvas>(env, info);
457     return (me != nullptr) ? me->OnDrawArc(env, info) : nullptr;
458 }
459 
OnDrawArc(napi_env env,napi_callback_info info)460 napi_value JsCanvas::OnDrawArc(napi_env env, napi_callback_info info)
461 {
462     if (m_canvas == nullptr) {
463         ROSEN_LOGE("JsCanvas::OnDrawArc canvas is null");
464         return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
465     }
466 
467     napi_value argv[ARGC_THREE] = {nullptr};
468     CHECK_PARAM_NUMBER_WITHOUT_OPTIONAL_PARAMS(argv, ARGC_THREE);
469 
470     double ltrb[ARGC_FOUR] = {0};
471     if (!ConvertFromJsRect(env, argv[ARGC_ZERO], ltrb, ARGC_FOUR)) {
472         return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM,
473             "Incorrect parameter0 type. The type of left, top, right and bottom must be number.");
474     }
475     Drawing::Rect drawingRect = Drawing::Rect(ltrb[ARGC_ZERO], ltrb[ARGC_ONE], ltrb[ARGC_TWO], ltrb[ARGC_THREE]);
476 
477     double startAngle = 0.0;
478     GET_DOUBLE_PARAM(ARGC_ONE, startAngle);
479     double sweepAngle = 0.0;
480     GET_DOUBLE_PARAM(ARGC_TWO, sweepAngle);
481 
482     JS_CALL_DRAWING_FUNC(m_canvas->DrawArc(drawingRect, startAngle, sweepAngle));
483 #if defined(ROSEN_OHOS) || defined(ROSEN_ARKUI_X)
484     if (mPixelMap_ != nullptr) {
485         mPixelMap_->MarkDirty();
486     }
487 #endif
488     return nullptr;
489 }
490 
DrawArcWithCenter(napi_env env,napi_callback_info info)491 napi_value JsCanvas::DrawArcWithCenter(napi_env env, napi_callback_info info)
492 {
493     DRAWING_PERFORMANCE_TEST_JS_RETURN(nullptr);
494     JsCanvas* me = CheckParamsAndGetThis<JsCanvas>(env, info);
495     return (me != nullptr) ? me->OnDrawArcWithCenter(env, info) : nullptr;
496 }
497 
OnDrawArcWithCenter(napi_env env,napi_callback_info info)498 napi_value JsCanvas::OnDrawArcWithCenter(napi_env env, napi_callback_info info)
499 {
500     if (m_canvas == nullptr) {
501         ROSEN_LOGE("JsCanvas::OnDrawArcWithCenter canvas is null");
502         return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
503     }
504 
505     napi_value argv[ARGC_FOUR] = {nullptr};
506     CHECK_PARAM_NUMBER_WITHOUT_OPTIONAL_PARAMS(argv, ARGC_FOUR);
507 
508     double ltrb[ARGC_FOUR] = {0};
509     if (!ConvertFromJsRect(env, argv[ARGC_ZERO], ltrb, ARGC_FOUR)) {
510         return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM,
511             "Incorrect parameter0 type. The type of left, top, right and bottom must be number.");
512     }
513     Drawing::Rect drawingRect = Drawing::Rect(ltrb[ARGC_ZERO], ltrb[ARGC_ONE], ltrb[ARGC_TWO], ltrb[ARGC_THREE]);
514 
515     double startAngle = 0.0;
516     GET_DOUBLE_PARAM(ARGC_ONE, startAngle);
517     double sweepAngle = 0.0;
518     GET_DOUBLE_PARAM(ARGC_TWO, sweepAngle);
519     bool jsUseCenter = false;
520     GET_BOOLEAN_PARAM(ARGC_THREE, jsUseCenter);
521 
522     DRAWING_PERFORMANCE_TEST_NAP_RETURN(nullptr);
523     if (jsUseCenter) {
524         JS_CALL_DRAWING_FUNC(m_canvas->DrawPie(drawingRect, startAngle, sweepAngle));
525     } else {
526         JS_CALL_DRAWING_FUNC(m_canvas->DrawArc(drawingRect, startAngle, sweepAngle));
527     }
528 #if defined(ROSEN_OHOS) || defined(ROSEN_ARKUI_X)
529     if (mPixelMap_ != nullptr) {
530         mPixelMap_->MarkDirty();
531     }
532 #endif
533     return nullptr;
534 }
535 
DrawRect(napi_env env,napi_callback_info info)536 napi_value JsCanvas::DrawRect(napi_env env, napi_callback_info info)
537 {
538     DRAWING_PERFORMANCE_TEST_JS_RETURN(nullptr);
539     JsCanvas* me = CheckParamsAndGetThis<JsCanvas>(env, info);
540     return (me != nullptr) ? me->OnDrawRect(env, info) : nullptr;
541 }
542 
OnDrawRect(napi_env env,napi_callback_info info)543 napi_value JsCanvas::OnDrawRect(napi_env env, napi_callback_info info)
544 {
545     if (m_canvas == nullptr) {
546         ROSEN_LOGE("JsCanvas::OnDrawRect canvas is nullptr");
547         return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
548     }
549 
550     size_t argc = ARGC_FOUR;
551     napi_value argv[ARGC_FOUR] = {nullptr};
552     CHECK_PARAM_NUMBER_WITH_OPTIONAL_PARAMS(argv, argc, ARGC_ONE, ARGC_FOUR);
553     Drawing::Rect drawingRect;
554     if (argc == ARGC_ONE) {
555         double ltrb[ARGC_FOUR] = {0};
556         if (!ConvertFromJsRect(env, argv[ARGC_ZERO], ltrb, ARGC_FOUR)) {
557             return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM,
558                 "Incorrect parameter0 type. The type of left, top, right and bottom must be number.");
559         }
560 
561         drawingRect = Drawing::Rect(ltrb[ARGC_ZERO], ltrb[ARGC_ONE], ltrb[ARGC_TWO], ltrb[ARGC_THREE]);
562     } else if (argc == ARGC_FOUR) {
563         double left = 0.0;
564         GET_DOUBLE_PARAM(ARGC_ZERO, left);
565         double top = 0.0;
566         GET_DOUBLE_PARAM(ARGC_ONE, top);
567         double right = 0.0;
568         GET_DOUBLE_PARAM(ARGC_TWO, right);
569         double bottom = 0.0;
570         GET_DOUBLE_PARAM(ARGC_THREE, bottom);
571         drawingRect = Drawing::Rect(left, top, right, bottom);
572     } else {
573         return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
574     }
575 
576     DRAWING_PERFORMANCE_TEST_NAP_RETURN(nullptr);
577     m_canvas->DrawRect(drawingRect);
578 #if defined(ROSEN_OHOS) || defined(ROSEN_ARKUI_X)
579     if (mPixelMap_ != nullptr) {
580         mPixelMap_->MarkDirty();
581     }
582 #endif
583     return nullptr;
584 }
585 
QuickRejectPath(napi_env env,napi_callback_info info)586 napi_value JsCanvas::QuickRejectPath(napi_env env, napi_callback_info info)
587 {
588     DRAWING_PERFORMANCE_TEST_JS_RETURN(nullptr);
589     JsCanvas* me = CheckParamsAndGetThis<JsCanvas>(env, info);
590     return (me != nullptr) ? me->OnQuickRejectPath(env, info) : nullptr;
591 }
592 
OnQuickRejectPath(napi_env env,napi_callback_info info)593 napi_value JsCanvas::OnQuickRejectPath(napi_env env, napi_callback_info info)
594 {
595     if (m_canvas == nullptr) {
596         ROSEN_LOGE("JsCanvas::OnQuickRejectPath canvas is nullptr");
597         return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
598     }
599 
600     napi_value argv[ARGC_ONE] = {nullptr};
601     CHECK_PARAM_NUMBER_WITHOUT_OPTIONAL_PARAMS(argv, ARGC_ONE);
602 
603     JsPath* jsPath = nullptr;
604     GET_UNWRAP_PARAM(ARGC_ZERO, jsPath);
605 
606     if (jsPath == nullptr || jsPath->GetPath() == nullptr) {
607         ROSEN_LOGE("JsCanvas::OnQuickRejectPath path is nullptr");
608         return nullptr;
609     }
610 
611     DRAWING_PERFORMANCE_TEST_NAP_RETURN(nullptr);
612     return CreateJsValue(env, m_canvas->QuickReject(*jsPath->GetPath()));
613 }
614 
QuickRejectRect(napi_env env,napi_callback_info info)615 napi_value JsCanvas::QuickRejectRect(napi_env env, napi_callback_info info)
616 {
617     DRAWING_PERFORMANCE_TEST_JS_RETURN(nullptr);
618     JsCanvas* me = CheckParamsAndGetThis<JsCanvas>(env, info);
619     return (me != nullptr) ? me->OnQuickRejectRect(env, info) : nullptr;
620 }
621 
OnQuickRejectRect(napi_env env,napi_callback_info info)622 napi_value JsCanvas::OnQuickRejectRect(napi_env env, napi_callback_info info)
623 {
624     if (m_canvas == nullptr) {
625         ROSEN_LOGE("JsCanvas::OnQuickRejectRect canvas is nullptr");
626         return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
627     }
628 
629     napi_value argv[ARGC_ONE] = { nullptr };
630     CHECK_PARAM_NUMBER_WITHOUT_OPTIONAL_PARAMS(argv, ARGC_ONE);
631 
632     double ltrb[ARGC_FOUR] = {0};
633     if (!ConvertFromJsRect(env, argv[ARGC_ZERO], ltrb, ARGC_FOUR)) {
634         return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM,
635             "Incorrect parameter0 type. The type of left, top, right and bottom must be number.");
636     }
637     Drawing::Rect drawingRect = Drawing::Rect(ltrb[ARGC_ZERO], ltrb[ARGC_ONE], ltrb[ARGC_TWO], ltrb[ARGC_THREE]);
638 
639     DRAWING_PERFORMANCE_TEST_NAP_RETURN(nullptr);
640     return CreateJsValue(env, m_canvas->QuickReject(drawingRect));
641 }
642 
DrawCircle(napi_env env,napi_callback_info info)643 napi_value JsCanvas::DrawCircle(napi_env env, napi_callback_info info)
644 {
645     DRAWING_PERFORMANCE_TEST_JS_RETURN(nullptr);
646     JsCanvas* me = CheckParamsAndGetThis<JsCanvas>(env, info);
647     return (me != nullptr) ? me->OnDrawCircle(env, info) : nullptr;
648 }
649 
OnDrawCircle(napi_env env,napi_callback_info info)650 napi_value JsCanvas::OnDrawCircle(napi_env env, napi_callback_info info)
651 {
652     if (m_canvas == nullptr) {
653         ROSEN_LOGE("JsCanvas::OnDrawCircle canvas is null");
654         return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
655     }
656 
657     napi_value argv[ARGC_THREE] = {nullptr};
658     CHECK_PARAM_NUMBER_WITHOUT_OPTIONAL_PARAMS(argv, ARGC_THREE);
659 
660     double x = 0.0;
661     GET_DOUBLE_PARAM(ARGC_ZERO, x);
662     double y = 0.0;
663     GET_DOUBLE_PARAM(ARGC_ONE, y);
664     double radius = 0.0;
665     GET_DOUBLE_PARAM(ARGC_TWO, radius);
666 
667     Drawing::Point centerPt = Drawing::Point(x, y);
668     DRAWING_PERFORMANCE_TEST_NAP_RETURN(nullptr);
669     m_canvas->DrawCircle(centerPt, radius);
670 #if defined(ROSEN_OHOS) || defined(ROSEN_ARKUI_X)
671     if (mPixelMap_ != nullptr) {
672         mPixelMap_->MarkDirty();
673     }
674 #endif
675     return nullptr;
676 }
677 
DrawImage(napi_env env,napi_callback_info info)678 napi_value JsCanvas::DrawImage(napi_env env, napi_callback_info info)
679 {
680     DRAWING_PERFORMANCE_TEST_JS_RETURN(nullptr);
681     JsCanvas* me = CheckParamsAndGetThis<JsCanvas>(env, info);
682     return (me != nullptr) ? me->OnDrawImage(env, info) : nullptr;
683 }
684 
OnDrawImage(napi_env env,napi_callback_info info)685 napi_value JsCanvas::OnDrawImage(napi_env env, napi_callback_info info)
686 {
687 #if defined(ROSEN_OHOS) || defined(ROSEN_ARKUI_X)
688     if (m_canvas == nullptr) {
689         ROSEN_LOGE("JsCanvas::OnDrawImage canvas is nullptr");
690         return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
691     }
692     size_t argc = ARGC_FOUR;
693     napi_value argv[ARGC_FOUR] = {nullptr};
694     CHECK_PARAM_NUMBER_WITH_OPTIONAL_PARAMS(argv, argc, ARGC_THREE, ARGC_FOUR);
695 
696     double px = 0.0;
697     GET_DOUBLE_PARAM(ARGC_ONE, px);
698     double py = 0.0;
699     GET_DOUBLE_PARAM(ARGC_TWO, py);
700     PixelMapNapi* pixelMapNapi = nullptr;
701     GET_UNWRAP_PARAM(ARGC_ZERO, pixelMapNapi);
702 
703     auto pixel = pixelMapNapi->GetPixelNapiInner();
704     if (pixel == nullptr) {
705         ROSEN_LOGE("JsCanvas::OnDrawImage pixelmap GetPixelNapiInner is nullptr");
706         return nullptr;
707     }
708 
709     std::shared_ptr<Drawing::Image> image = ExtractDrawingImage(pixel);
710     if (image == nullptr) {
711         ROSEN_LOGE("JsCanvas::OnDrawImage image is nullptr");
712         return nullptr;
713     }
714 
715     if (argc == ARGC_THREE) {
716         DRAWING_PERFORMANCE_TEST_NAP_RETURN(nullptr);
717         if (m_canvas->GetDrawingType() == Drawing::DrawingType::RECORDING) {
718             ExtendRecordingCanvas* canvas_ = reinterpret_cast<ExtendRecordingCanvas*>(m_canvas);
719             Drawing::Rect src(0, 0, pixel->GetWidth(), pixel->GetHeight());
720             Drawing::Rect dst(px, py, px + pixel->GetWidth(), py + pixel->GetHeight());
721             canvas_->DrawPixelMapRect(pixel, src, dst, Drawing::SamplingOptions());
722             return nullptr;
723         }
724         m_canvas->DrawImage(*image, px, py, Drawing::SamplingOptions());
725     } else {
726         JsSamplingOptions* jsSamplingOptions = nullptr;
727         GET_UNWRAP_PARAM(ARGC_THREE, jsSamplingOptions);
728 
729         std::shared_ptr<SamplingOptions> samplingOptions = jsSamplingOptions->GetSamplingOptions();
730         if (samplingOptions == nullptr) {
731             ROSEN_LOGE("JsCanvas::OnDrawImage get samplingOptions is nullptr");
732             return nullptr;
733         }
734         if (m_canvas->GetDrawingType() == Drawing::DrawingType::RECORDING) {
735             ExtendRecordingCanvas* canvas_ = reinterpret_cast<ExtendRecordingCanvas*>(m_canvas);
736             Drawing::Rect src(0, 0, pixel->GetWidth(), pixel->GetHeight());
737             Drawing::Rect dst(px, py, px + pixel->GetWidth(), py + pixel->GetHeight());
738             canvas_->DrawPixelMapRect(pixel, src, dst, *samplingOptions.get());
739             return nullptr;
740         }
741         DRAWING_PERFORMANCE_TEST_NAP_RETURN(nullptr);
742         m_canvas->DrawImage(*image, px, py, *samplingOptions.get());
743     }
744 
745     if (mPixelMap_ != nullptr) {
746         mPixelMap_->MarkDirty();
747     }
748 #endif
749     return nullptr;
750 }
751 
DrawColor(napi_env env,napi_callback_info info)752 napi_value JsCanvas::DrawColor(napi_env env, napi_callback_info info)
753 {
754     DRAWING_PERFORMANCE_TEST_JS_RETURN(nullptr);
755     JsCanvas* me = CheckParamsAndGetThis<JsCanvas>(env, info);
756     return (me != nullptr) ? me->OnDrawColor(env, info) : nullptr;
757 }
758 
OnDrawColor(napi_env env,napi_callback_info info)759 napi_value JsCanvas::OnDrawColor(napi_env env, napi_callback_info info)
760 {
761     if (m_canvas == nullptr) {
762         ROSEN_LOGE("JsCanvas::OnDrawColor canvas is nullptr");
763         return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
764     }
765 
766     size_t argc = ARGC_FIVE;
767     napi_value argv[ARGC_FIVE] = {nullptr};
768     CHECK_PARAM_NUMBER_WITH_OPTIONAL_PARAMS(argv, argc, ARGC_ONE, ARGC_FIVE);
769 
770     if (argc == ARGC_ONE || argc == ARGC_TWO) {
771         ColorQuad color;
772         if (!ConvertFromAdaptHexJsColor(env, argv[ARGC_ZERO], color)) {
773             ROSEN_LOGE("JsCanvas::OnDrawColor Argv[0] is invalid");
774             return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM,
775                 "Parameter verification failed. The range of color channels must be [0, 255].");
776         }
777         if (argc == ARGC_ONE) {
778             DRAWING_PERFORMANCE_TEST_NAP_RETURN(nullptr);
779             m_canvas->DrawColor(color);
780         } else {
781             int32_t jsMode = 0;
782             GET_ENUM_PARAM(ARGC_ONE, jsMode, 0, static_cast<int32_t>(BlendMode::LUMINOSITY));
783             DRAWING_PERFORMANCE_TEST_NAP_RETURN(nullptr);
784             m_canvas->DrawColor(color, static_cast<BlendMode>(jsMode));
785         }
786     } else if (argc == ARGC_FOUR || argc == ARGC_FIVE) {
787         int32_t alpha = 0;
788         GET_COLOR_PARAM(ARGC_ZERO, alpha);
789         int32_t red = 0;
790         GET_COLOR_PARAM(ARGC_ONE, red);
791         int32_t green = 0;
792         GET_COLOR_PARAM(ARGC_TWO, green);
793         int32_t blue = 0;
794         GET_COLOR_PARAM(ARGC_THREE, blue);
795         auto color = Color::ColorQuadSetARGB(alpha, red, green, blue);
796         if (argc == ARGC_FOUR) {
797             DRAWING_PERFORMANCE_TEST_NAP_RETURN(nullptr);
798             m_canvas->DrawColor(color);
799         } else {
800             int32_t jsMode = 0;
801             GET_ENUM_PARAM(ARGC_FOUR, jsMode, 0, static_cast<int32_t>(BlendMode::LUMINOSITY));
802             DRAWING_PERFORMANCE_TEST_NAP_RETURN(nullptr);
803             m_canvas->DrawColor(color, static_cast<BlendMode>(jsMode));
804         }
805     } else {
806         return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
807     }
808 
809 #if defined(ROSEN_OHOS) || defined(ROSEN_ARKUI_X)
810     if (mPixelMap_ != nullptr) {
811         mPixelMap_->MarkDirty();
812     }
813 #endif
814     return nullptr;
815 }
816 
DrawOval(napi_env env,napi_callback_info info)817 napi_value JsCanvas::DrawOval(napi_env env, napi_callback_info info)
818 {
819     JsCanvas* me = CheckParamsAndGetThis<JsCanvas>(env, info);
820     return (me != nullptr) ? me->OnDrawOval(env, info) : nullptr;
821 }
822 
OnDrawOval(napi_env env,napi_callback_info info)823 napi_value JsCanvas::OnDrawOval(napi_env env, napi_callback_info info)
824 {
825     if (m_canvas == nullptr) {
826         ROSEN_LOGE("JsCanvas::OnDrawOval canvas is null");
827         return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
828     }
829     napi_value argv[ARGC_ONE] = {nullptr};
830     CHECK_PARAM_NUMBER_WITHOUT_OPTIONAL_PARAMS(argv, ARGC_ONE);
831 
832     double ltrb[ARGC_FOUR] = {0};
833     if (!ConvertFromJsRect(env, argv[ARGC_ZERO], ltrb, ARGC_FOUR)) {
834         return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM,
835             "Incorrect parameter0 type. The type of left, top, right and bottom must be number.");
836     }
837     Drawing::Rect drawingRect = Drawing::Rect(ltrb[ARGC_ZERO], ltrb[ARGC_ONE], ltrb[ARGC_TWO], ltrb[ARGC_THREE]);
838 
839     JS_CALL_DRAWING_FUNC(m_canvas->DrawOval(drawingRect));
840 #if defined(ROSEN_OHOS) || defined(ROSEN_ARKUI_X)
841     if (mPixelMap_ != nullptr) {
842         mPixelMap_->MarkDirty();
843     }
844 #endif
845     return nullptr;
846 }
847 
DrawPoint(napi_env env,napi_callback_info info)848 napi_value JsCanvas::DrawPoint(napi_env env, napi_callback_info info)
849 {
850     DRAWING_PERFORMANCE_TEST_JS_RETURN(nullptr);
851     JsCanvas* me = CheckParamsAndGetThis<JsCanvas>(env, info);
852     return (me != nullptr) ? me->OnDrawPoint(env, info) : nullptr;
853 }
854 
OnDrawPoint(napi_env env,napi_callback_info info)855 napi_value JsCanvas::OnDrawPoint(napi_env env, napi_callback_info info)
856 {
857     if (m_canvas == nullptr) {
858         ROSEN_LOGE("JsCanvas::OnDrawPoint canvas is nullptr");
859         return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
860     }
861 
862     napi_value argv[ARGC_TWO] = {nullptr};
863     CHECK_PARAM_NUMBER_WITHOUT_OPTIONAL_PARAMS(argv, ARGC_TWO);
864 
865     double px = 0.0;
866     GET_DOUBLE_PARAM(ARGC_ZERO, px);
867     double py = 0.0;
868     GET_DOUBLE_PARAM(ARGC_ONE, py);
869 
870     DRAWING_PERFORMANCE_TEST_NAP_RETURN(nullptr);
871     m_canvas->DrawPoint(Point(px, py));
872 #if defined(ROSEN_OHOS) || defined(ROSEN_ARKUI_X)
873     if (mPixelMap_ != nullptr) {
874         mPixelMap_->MarkDirty();
875     }
876 #endif
877     return nullptr;
878 }
879 
OnMakePoints(napi_env & env,Point * point,uint32_t size,napi_value & array)880 static bool OnMakePoints(napi_env& env, Point* point, uint32_t size, napi_value& array)
881 {
882     if (size > MAX_ELEMENTSIZE) {
883         ROSEN_LOGE("JsTextBlob::OnMakePoints size exceeds the upper limit");
884         return false;
885     }
886     for (uint32_t i = 0; i < size; i++) {
887         napi_value tempNumber = nullptr;
888         napi_get_element(env, array, i, &tempNumber);
889         napi_value tempValue = nullptr;
890         double pointX = 0.0;
891         double pointY = 0.0;
892         napi_get_named_property(env, tempNumber, "x", &tempValue);
893         bool isPointXOk = ConvertFromJsValue(env, tempValue, pointX);
894         napi_get_named_property(env, tempNumber, "y", &tempValue);
895         bool isPointYOk = ConvertFromJsValue(env, tempValue, pointY);
896         if (!(isPointXOk && isPointYOk)) {
897             return false;
898         }
899         point[i] = Point(pointX, pointY);
900     }
901     return true;
902 }
903 
DrawPoints(napi_env env,napi_callback_info info)904 napi_value JsCanvas::DrawPoints(napi_env env, napi_callback_info info)
905 {
906     JsCanvas* me = CheckParamsAndGetThis<JsCanvas>(env, info);
907     return (me != nullptr) ? me->OnDrawPoints(env, info) : nullptr;
908 }
909 
OnDrawPoints(napi_env env,napi_callback_info info)910 napi_value JsCanvas::OnDrawPoints(napi_env env, napi_callback_info info)
911 {
912     if (m_canvas == nullptr) {
913         ROSEN_LOGE("JsCanvas::OnDrawPoints canvas is nullptr");
914         return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
915     }
916     size_t argc = ARGC_TWO;
917     napi_value argv[ARGC_TWO] = {nullptr};
918     CHECK_PARAM_NUMBER_WITH_OPTIONAL_PARAMS(argv, argc, ARGC_ONE, ARGC_TWO);
919     napi_value array = argv[ARGC_ZERO];
920     uint32_t size = 0;
921     if (napi_get_array_length(env, array, &size) != napi_ok || (size == 0)) {
922         return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Incorrect src array size.");
923     }
924     if (argc == ARGC_ONE) {
925         Point* points = new(std::nothrow) Point[size];
926         if (points == nullptr) {
927             return nullptr;
928         }
929         if (!OnMakePoints(env, points, size, array)) {
930             delete [] points;
931             ROSEN_LOGE("JsCanvas::OnDrawPoints Argv[ARGC_ZERO] is invalid");
932             return nullptr;
933         }
934         JS_CALL_DRAWING_FUNC(m_canvas->DrawPoints(PointMode::POINTS_POINTMODE, size, points));
935 #if defined(ROSEN_OHOS) || defined(ROSEN_ARKUI_X)
936         if (mPixelMap_ != nullptr) {
937             mPixelMap_->MarkDirty();
938         }
939 #endif
940         delete [] points;
941         return nullptr;
942     }
943 
944     int32_t pointMode = 0;
945     GET_ENUM_PARAM(ARGC_ONE, pointMode, 0, static_cast<int32_t>(PointMode::POLYGON_POINTMODE));
946     Point* points = new(std::nothrow) Point[size];
947     if (points == nullptr) {
948         return nullptr;
949     }
950     if (!OnMakePoints(env, points, size, array)) {
951         delete [] points;
952         ROSEN_LOGE("JsCanvas::OnDrawPoints Argv[ARGC_ZERO] is invalid");
953         return nullptr;
954     }
955     JS_CALL_DRAWING_FUNC(m_canvas->DrawPoints(static_cast<PointMode>(pointMode), size, points));
956 #if defined(ROSEN_OHOS) || defined(ROSEN_ARKUI_X)
957     if (mPixelMap_ != nullptr) {
958         mPixelMap_->MarkDirty();
959     }
960 #endif
961     delete [] points;
962     return nullptr;
963 }
964 
DrawPath(napi_env env,napi_callback_info info)965 napi_value JsCanvas::DrawPath(napi_env env, napi_callback_info info)
966 {
967     DRAWING_PERFORMANCE_TEST_JS_RETURN(nullptr);
968     JsCanvas* me = CheckParamsAndGetThis<JsCanvas>(env, info);
969     return (me != nullptr) ? me->OnDrawPath(env, info) : nullptr;
970 }
971 
OnDrawPath(napi_env env,napi_callback_info info)972 napi_value JsCanvas::OnDrawPath(napi_env env, napi_callback_info info)
973 {
974     if (m_canvas == nullptr) {
975         ROSEN_LOGE("JsCanvas::OnDrawPath canvas is nullptr");
976         return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
977     }
978 
979     napi_value argv[ARGC_ONE] = {nullptr};
980     CHECK_PARAM_NUMBER_WITHOUT_OPTIONAL_PARAMS(argv, ARGC_ONE);
981 
982     JsPath* jsPath = nullptr;
983     GET_UNWRAP_PARAM(ARGC_ZERO, jsPath);
984 
985     if (jsPath->GetPath() == nullptr) {
986         ROSEN_LOGE("JsCanvas::OnDrawPath path is nullptr");
987         return nullptr;
988     }
989 
990     DRAWING_PERFORMANCE_TEST_NAP_RETURN(nullptr);
991     m_canvas->DrawPath(*jsPath->GetPath());
992 #if defined(ROSEN_OHOS) || defined(ROSEN_ARKUI_X)
993     if (mPixelMap_ != nullptr) {
994         mPixelMap_->MarkDirty();
995     }
996 #endif
997     return nullptr;
998 }
999 
DrawLine(napi_env env,napi_callback_info info)1000 napi_value JsCanvas::DrawLine(napi_env env, napi_callback_info info)
1001 {
1002     DRAWING_PERFORMANCE_TEST_JS_RETURN(nullptr);
1003     JsCanvas* me = CheckParamsAndGetThis<JsCanvas>(env, info);
1004     return (me != nullptr) ? me->OnDrawLine(env, info) : nullptr;
1005 }
1006 
OnDrawLine(napi_env env,napi_callback_info info)1007 napi_value JsCanvas::OnDrawLine(napi_env env, napi_callback_info info)
1008 {
1009     if (m_canvas == nullptr) {
1010         ROSEN_LOGE("JsCanvas::OnDrawLine canvas is nullptr");
1011         return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
1012     }
1013 
1014     napi_value argv[ARGC_FOUR] = {nullptr};
1015     CHECK_PARAM_NUMBER_WITHOUT_OPTIONAL_PARAMS(argv, ARGC_FOUR);
1016 
1017     double startPx = 0.0;
1018     GET_DOUBLE_PARAM(ARGC_ZERO, startPx);
1019     double startPy = 0.0;
1020     GET_DOUBLE_PARAM(ARGC_ONE, startPy);
1021     double endPx = 0.0;
1022     GET_DOUBLE_PARAM(ARGC_TWO, endPx);
1023     double endPy = 0.0;
1024     GET_DOUBLE_PARAM(ARGC_THREE, endPy);
1025 
1026     DRAWING_PERFORMANCE_TEST_NAP_RETURN(nullptr);
1027     m_canvas->DrawLine(Point(startPx, startPy), Point(endPx, endPy));
1028 #if defined(ROSEN_OHOS) || defined(ROSEN_ARKUI_X)
1029     if (mPixelMap_ != nullptr) {
1030         mPixelMap_->MarkDirty();
1031     }
1032 #endif
1033     return nullptr;
1034 }
1035 
DrawText(napi_env env,napi_callback_info info)1036 napi_value JsCanvas::DrawText(napi_env env, napi_callback_info info)
1037 {
1038     DRAWING_PERFORMANCE_TEST_JS_RETURN(nullptr);
1039     JsCanvas* me = CheckParamsAndGetThis<JsCanvas>(env, info);
1040     return (me != nullptr) ? me->OnDrawText(env, info) : nullptr;
1041 }
1042 
OnDrawText(napi_env env,napi_callback_info info)1043 napi_value JsCanvas::OnDrawText(napi_env env, napi_callback_info info)
1044 {
1045     if (m_canvas == nullptr) {
1046         ROSEN_LOGE("JsCanvas::OnDrawText canvas is null");
1047         return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
1048     }
1049 
1050     napi_value argv[ARGC_THREE] = {nullptr};
1051     CHECK_PARAM_NUMBER_WITHOUT_OPTIONAL_PARAMS(argv, ARGC_THREE);
1052 
1053     JsTextBlob* jsTextBlob = nullptr;
1054     GET_UNWRAP_PARAM(ARGC_ZERO, jsTextBlob);
1055     double x = 0.0;
1056     GET_DOUBLE_PARAM(ARGC_ONE, x);
1057     double y = 0.0;
1058     GET_DOUBLE_PARAM(ARGC_TWO, y);
1059 
1060     DRAWING_PERFORMANCE_TEST_NAP_RETURN(nullptr);
1061     m_canvas->DrawTextBlob(jsTextBlob->GetTextBlob().get(), x, y);
1062 #if defined(ROSEN_OHOS) || defined(ROSEN_ARKUI_X)
1063     if (mPixelMap_ != nullptr) {
1064         mPixelMap_->MarkDirty();
1065     }
1066 #endif
1067     return nullptr;
1068 }
1069 
DrawSingleCharacter(napi_env env,napi_callback_info info)1070 napi_value JsCanvas::DrawSingleCharacter(napi_env env, napi_callback_info info)
1071 {
1072     DRAWING_PERFORMANCE_TEST_JS_RETURN(nullptr);
1073     JsCanvas* me = CheckParamsAndGetThis<JsCanvas>(env, info);
1074     return (me != nullptr) ? me->OnDrawSingleCharacter(env, info) : nullptr;
1075 }
1076 
OnDrawSingleCharacter(napi_env env,napi_callback_info info)1077 napi_value JsCanvas::OnDrawSingleCharacter(napi_env env, napi_callback_info info)
1078 {
1079     if (m_canvas == nullptr) {
1080         ROSEN_LOGE("JsCanvas::OnDrawSingleCharacter canvas is null");
1081         return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
1082     }
1083     napi_value argv[ARGC_FOUR] = {nullptr};
1084     CHECK_PARAM_NUMBER_WITHOUT_OPTIONAL_PARAMS(argv, ARGC_FOUR);
1085     size_t len = 0;
1086     if (napi_get_value_string_utf8(env, argv[ARGC_ZERO], nullptr, 0, &len) != napi_ok) {
1087         return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Incorrect parameter0 type.");
1088     }
1089     if (len == 0 || len > 4) { // 4 is the maximum length of a character encoded in UTF8.
1090         return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM,
1091             "Parameter verification failed. Input parameter0 should be single character.");
1092     }
1093     char str[len + 1];
1094     if (napi_get_value_string_utf8(env, argv[ARGC_ZERO], str, len + 1, &len) != napi_ok) {
1095         return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Incorrect parameter0 type.");
1096     }
1097     JsFont* jsFont = nullptr;
1098     GET_UNWRAP_PARAM(ARGC_ONE, jsFont);
1099     double x = 0.0;
1100     GET_DOUBLE_PARAM(ARGC_TWO, x);
1101     double y = 0.0;
1102     GET_DOUBLE_PARAM(ARGC_THREE, y);
1103     std::shared_ptr<Font> font = jsFont->GetFont();
1104     if (font == nullptr) {
1105         ROSEN_LOGE("JsCanvas::OnDrawSingleCharacter font is nullptr");
1106         return nullptr;
1107     }
1108     const char* currentStr = str;
1109     int32_t unicode = SkUTF::NextUTF8(&currentStr, currentStr + len);
1110     std::shared_ptr<Font> themeFont = MatchThemeFont(font, unicode);
1111     if (themeFont != nullptr) {
1112         font = themeFont;
1113     }
1114     size_t byteLen = currentStr - str;
1115     if (byteLen != len) {
1116         return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM,
1117             "Parameter verification failed. Input parameter0 should be single character.");
1118     }
1119     m_canvas->DrawSingleCharacter(unicode, *font, x, y);
1120 #if defined(ROSEN_OHOS) || defined(ROSEN_ARKUI_X)
1121     if (mPixelMap_ != nullptr) {
1122         mPixelMap_->MarkDirty();
1123     }
1124 #endif
1125     return nullptr;
1126 }
1127 
DrawSingleCharacterWithFeatures(napi_env env,napi_callback_info info)1128 napi_value JsCanvas::DrawSingleCharacterWithFeatures(napi_env env, napi_callback_info info)
1129 {
1130     DRAWING_PERFORMANCE_TEST_JS_RETURN(nullptr);
1131     JsCanvas* me = CheckParamsAndGetThis<JsCanvas>(env, info);
1132     return (me != nullptr) ? me->OnDrawSingleCharacterWithFeatures(env, info) : nullptr;
1133 }
1134 
OnDrawSingleCharacterWithFeatures(napi_env env,napi_callback_info info)1135 napi_value JsCanvas::OnDrawSingleCharacterWithFeatures(napi_env env, napi_callback_info info)
1136 {
1137     if (m_canvas == nullptr) {
1138         return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
1139     }
1140 
1141     napi_value argv[ARGC_FIVE] = {nullptr};
1142     CHECK_PARAM_NUMBER_WITHOUT_OPTIONAL_PARAMS(argv, ARGC_FIVE);
1143 
1144     size_t len = 0;
1145     if (napi_get_value_string_utf8(env, argv[ARGC_ZERO], nullptr, 0, &len) != napi_ok) {
1146         return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Incorrect parameter0 type.");
1147     }
1148     if (len == 0 || len > 4) { // 4 is the maximum length of a character encoded in UTF8.
1149         return NapiThrowError(env, DrawingErrorCode::ERROR_PARAM_VERIFICATION_FAILED,
1150             "Input parameter0 should be single character.");
1151     }
1152     std::vector<char> strBuffer(len + 1);
1153     if (napi_get_value_string_utf8(env, argv[ARGC_ZERO], strBuffer.data(), len + 1, &len) != napi_ok) {
1154         return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Invalid parameter0 type.");
1155     }
1156     strBuffer[len] = 0;
1157 
1158     const char* currentPtr = strBuffer.data();
1159     const char* endPtr = strBuffer.data() + len;
1160     int32_t unicode = SkUTF::NextUTF8(&currentPtr, endPtr);
1161     size_t byteLen = currentPtr - strBuffer.data();
1162     if (byteLen != len) {
1163         return NapiThrowError(env, DrawingErrorCode::ERROR_PARAM_VERIFICATION_FAILED,
1164             "Parameter verification failed. Input parameter0 should be single character.");
1165     }
1166 
1167     JsFont* jsFont = nullptr;
1168     GET_UNWRAP_PARAM(ARGC_ONE, jsFont);
1169 
1170     double x = 0.0;
1171     GET_DOUBLE_PARAM(ARGC_TWO, x);
1172 
1173     double y = 0.0;
1174     GET_DOUBLE_PARAM(ARGC_THREE, y);
1175 
1176     std::shared_ptr<Font> font = jsFont->GetFont();
1177     if (font == nullptr) {
1178         ROSEN_LOGE("JsCanvas::OnDrawSingleCharacterWithFeatures font is nullptr");
1179         return nullptr;
1180     }
1181 
1182     std::shared_ptr<Font> themeFont = MatchThemeFont(font, unicode);
1183     if (themeFont != nullptr) {
1184         font = themeFont;
1185     }
1186 
1187     napi_value array = argv[ARGC_FOUR];
1188     uint32_t size = 0;
1189     if (napi_get_array_length(env, array, &size) != napi_ok) {
1190         return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Invalid src array");
1191     }
1192 
1193     std::shared_ptr<DrawingFontFeatures> featuresPtr = std::make_shared<DrawingFontFeatures>();
1194     MakeFontFeaturesFromJsArray(env, featuresPtr, size, array);
1195     m_canvas->DrawSingleCharacterWithFeatures(strBuffer.data(), *font, x, y, featuresPtr);
1196 #ifdef ROSEN_OHOS
1197     if (mPixelMap_ != nullptr) {
1198         mPixelMap_->MarkDirty();
1199     }
1200 #endif
1201     return nullptr;
1202 }
1203 
DrawPixelMapMesh(napi_env env,napi_callback_info info)1204 napi_value JsCanvas::DrawPixelMapMesh(napi_env env, napi_callback_info info)
1205 {
1206     JsCanvas* me = CheckParamsAndGetThis<JsCanvas>(env, info);
1207     return (me != nullptr) ? me->OnDrawPixelMapMesh(env, info) : nullptr;
1208 }
1209 
OnDrawPixelMapMesh(napi_env env,napi_callback_info info)1210 napi_value JsCanvas::OnDrawPixelMapMesh(napi_env env, napi_callback_info info)
1211 {
1212 #if defined(ROSEN_OHOS) || defined(ROSEN_ARKUI_X)
1213     if (m_canvas == nullptr) {
1214         ROSEN_LOGE("JsCanvas::OnDrawPixelMapMesh canvas is null");
1215         return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
1216     }
1217 
1218     napi_value argv[ARGC_SEVEN] = {nullptr};
1219     CHECK_PARAM_NUMBER_WITHOUT_OPTIONAL_PARAMS(argv, ARGC_SEVEN);
1220 
1221     PixelMapNapi* pixelMapNapi = nullptr;
1222     GET_UNWRAP_PARAM(ARGC_ZERO, pixelMapNapi);
1223 
1224     if (pixelMapNapi->GetPixelNapiInner() == nullptr) {
1225         ROSEN_LOGE("Drawing_napi::pixelMap pixelmap getPixelNapiInner is nullptr");
1226         return nullptr;
1227     }
1228     std::shared_ptr<Media::PixelMap> pixelMap = pixelMapNapi->GetPixelNapiInner();
1229 
1230     int32_t column = 0;
1231     GET_INT32_CHECK_GE_ZERO_PARAM(ARGC_ONE, column);
1232     int32_t row = 0;
1233     GET_INT32_CHECK_GE_ZERO_PARAM(ARGC_TWO, row);
1234     int32_t vertOffset = 0;
1235     GET_INT32_CHECK_GE_ZERO_PARAM(ARGC_FOUR, vertOffset);
1236     int32_t colorOffset = 0;
1237     GET_INT32_CHECK_GE_ZERO_PARAM(ARGC_SIX, colorOffset);
1238 
1239     if (column == 0 || row == 0) {
1240         ROSEN_LOGE("JsCanvas::OnDrawPixelMapMesh column or row is invalid");
1241         return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Invalid column or row params.");
1242     }
1243 
1244     napi_value verticesArray = argv[ARGC_THREE];
1245     uint32_t verticesSize = 0;
1246     napi_get_array_length(env, verticesArray, &verticesSize);
1247     int64_t tempVerticesSize = ((column + 1) * (row + 1) + vertOffset) * 2; // x and y two coordinates
1248     if (verticesSize != tempVerticesSize) {
1249         ROSEN_LOGE("JsCanvas::OnDrawPixelMapMesh vertices are invalid");
1250         return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Incorrect parameter3 type.");
1251     }
1252 
1253     auto vertices = new (std::nothrow) float[verticesSize];
1254     if (!vertices) {
1255         ROSEN_LOGE("JsCanvas::OnDrawPixelMapMesh create array with size of vertices failed");
1256         return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Size of vertices exceed memory limit.");
1257     }
1258 
1259     for (uint32_t i = 0; i < verticesSize; i++) {
1260         napi_value tempVertex = nullptr;
1261         napi_get_element(env, verticesArray, i, &tempVertex);
1262         double vertex = 0.f;
1263         if (napi_get_value_double(env, tempVertex, &vertex) != napi_ok) {
1264             ROSEN_LOGE("JsCanvas::OnDrawPixelMapMesh vertex is invalid");
1265             delete []vertices;
1266             return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM,
1267                 "Incorrect DrawPixelMapMesh parameter vertex type.");
1268         }
1269         vertices[i] = vertex;
1270     }
1271     float* verticesMesh = verticesSize ? (vertices + vertOffset * 2) : nullptr; // offset two coordinates
1272 
1273     napi_value colorsArray = argv[ARGC_FIVE];
1274     uint32_t colorsSize = 0;
1275     napi_get_array_length(env, colorsArray, &colorsSize);
1276     int64_t tempColorsSize = (column + 1) * (row + 1) + colorOffset;
1277 
1278     if (colorsSize != 0 && colorsSize != tempColorsSize) {
1279         ROSEN_LOGE("JsCanvas::OnDrawPixelMapMesh colors are invalid");
1280         delete []vertices;
1281         return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Incorrect parameter5 type.");
1282     }
1283 
1284     if (colorsSize == 0) {
1285         DrawingPixelMapMesh(pixelMap, column, row, verticesMesh, nullptr, m_canvas);
1286         if (mPixelMap_ != nullptr) {
1287             mPixelMap_->MarkDirty();
1288         }
1289         delete []vertices;
1290         return nullptr;
1291     }
1292 
1293     auto colors = new (std::nothrow) uint32_t[colorsSize];
1294     if (!colors) {
1295         ROSEN_LOGE("JsCanvas::OnDrawPixelMapMesh create array with size of colors failed");
1296         delete []vertices;
1297         return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Size of colors exceed memory limit.");
1298     }
1299     for (uint32_t i = 0; i < colorsSize; i++) {
1300         napi_value tempColor = nullptr;
1301         napi_get_element(env, colorsArray, i, &tempColor);
1302         uint32_t color = 0;
1303         if (napi_get_value_uint32(env, tempColor, &color) != napi_ok) {
1304             ROSEN_LOGE("JsCanvas::OnDrawPixelMapMesh color is invalid");
1305             delete []vertices;
1306             delete []colors;
1307             return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM,
1308                 "Incorrect DrawPixelMapMesh parameter color type.");
1309         }
1310         colors[i] = color;
1311     }
1312     uint32_t* colorsMesh = colors + colorOffset;
1313 
1314     DrawingPixelMapMesh(pixelMap, column, row, verticesMesh, colorsMesh, m_canvas);
1315     if (mPixelMap_ != nullptr) {
1316         mPixelMap_->MarkDirty();
1317     }
1318     delete []vertices;
1319     delete []colors;
1320     return nullptr;
1321 #else
1322     return nullptr;
1323 #endif
1324 }
1325 
DrawRegion(napi_env env,napi_callback_info info)1326 napi_value JsCanvas::DrawRegion(napi_env env, napi_callback_info info)
1327 {
1328     JsCanvas* me = CheckParamsAndGetThis<JsCanvas>(env, info);
1329     return (me != nullptr) ? me->OnDrawRegion(env, info) : nullptr;
1330 }
1331 
OnDrawRegion(napi_env env,napi_callback_info info)1332 napi_value JsCanvas::OnDrawRegion(napi_env env, napi_callback_info info)
1333 {
1334     if (m_canvas == nullptr) {
1335         ROSEN_LOGE("JsCanvas::OnDrawRegion canvas is nullptr");
1336         return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
1337     }
1338     napi_value argv[ARGC_ONE] = {nullptr};
1339     CHECK_PARAM_NUMBER_WITHOUT_OPTIONAL_PARAMS(argv, ARGC_ONE);
1340 
1341     JsRegion* jsRegion = nullptr;
1342     GET_UNWRAP_PARAM(ARGC_ZERO, jsRegion);
1343     if (jsRegion->GetRegion() == nullptr) {
1344         ROSEN_LOGE("JsCanvas::OnDrawRegion region is nullptr");
1345         return nullptr;
1346     }
1347     JS_CALL_DRAWING_FUNC(m_canvas->DrawRegion(*jsRegion->GetRegion()));
1348 #if defined(ROSEN_OHOS) || defined(ROSEN_ARKUI_X)
1349     if (mPixelMap_ != nullptr) {
1350         mPixelMap_->MarkDirty();
1351     }
1352 #endif
1353     return nullptr;
1354 }
1355 
DrawBackground(napi_env env,napi_callback_info info)1356 napi_value JsCanvas::DrawBackground(napi_env env, napi_callback_info info)
1357 {
1358     JsCanvas* me = CheckParamsAndGetThis<JsCanvas>(env, info);
1359     return (me != nullptr) ? me->OnDrawBackground(env, info) : nullptr;
1360 }
1361 
OnDrawBackground(napi_env env,napi_callback_info info)1362 napi_value JsCanvas::OnDrawBackground(napi_env env, napi_callback_info info)
1363 {
1364     if (m_canvas == nullptr) {
1365         ROSEN_LOGE("JsCanvas::OnDrawBackground canvas is nullptr");
1366         return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
1367     }
1368 
1369     napi_value argv[ARGC_ONE] = {nullptr};
1370     CHECK_PARAM_NUMBER_WITHOUT_OPTIONAL_PARAMS(argv, ARGC_ONE);
1371 
1372     JsBrush* jsBrush = nullptr;
1373     GET_UNWRAP_PARAM(ARGC_ZERO, jsBrush);
1374     if (jsBrush->GetBrush() == nullptr) {
1375         ROSEN_LOGE("JsCanvas::OnDrawBackground brush is nullptr");
1376         return nullptr;
1377     }
1378 
1379     m_canvas->DrawBackground(*jsBrush->GetBrush());
1380 #if defined(ROSEN_OHOS) || defined(ROSEN_ARKUI_X)
1381     if (mPixelMap_ != nullptr) {
1382         mPixelMap_->MarkDirty();
1383     }
1384 #endif
1385     return nullptr;
1386 }
1387 
DrawRoundRect(napi_env env,napi_callback_info info)1388 napi_value JsCanvas::DrawRoundRect(napi_env env, napi_callback_info info)
1389 {
1390     JsCanvas* me = CheckParamsAndGetThis<JsCanvas>(env, info);
1391     return (me != nullptr) ? me->OnDrawRoundRect(env, info) : nullptr;
1392 }
1393 
OnDrawRoundRect(napi_env env,napi_callback_info info)1394 napi_value JsCanvas::OnDrawRoundRect(napi_env env, napi_callback_info info)
1395 {
1396     if (m_canvas == nullptr) {
1397         ROSEN_LOGE("JsCanvas::OnDrawRoundRect canvas is nullptr");
1398         return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
1399     }
1400 
1401     napi_value argv[ARGC_ONE] = {nullptr};
1402     CHECK_PARAM_NUMBER_WITHOUT_OPTIONAL_PARAMS(argv, ARGC_ONE);
1403 
1404     JsRoundRect* jsRoundRect = nullptr;
1405     GET_UNWRAP_PARAM(ARGC_ZERO, jsRoundRect);
1406 
1407     m_canvas->DrawRoundRect(jsRoundRect->GetRoundRect());
1408 #if defined(ROSEN_OHOS) || defined(ROSEN_ARKUI_X)
1409     if (mPixelMap_ != nullptr) {
1410         mPixelMap_->MarkDirty();
1411     }
1412 #endif
1413     return nullptr;
1414 }
1415 
DrawNestedRoundRect(napi_env env,napi_callback_info info)1416 napi_value JsCanvas::DrawNestedRoundRect(napi_env env, napi_callback_info info)
1417 {
1418     JsCanvas* me = CheckParamsAndGetThis<JsCanvas>(env, info);
1419     return (me != nullptr) ? me->OnDrawNestedRoundRect(env, info) : nullptr;
1420 }
1421 
OnDrawNestedRoundRect(napi_env env,napi_callback_info info)1422 napi_value JsCanvas::OnDrawNestedRoundRect(napi_env env, napi_callback_info info)
1423 {
1424     if (m_canvas == nullptr) {
1425         ROSEN_LOGE("JsCanvas::OnDrawNestedRoundRect canvas is nullptr");
1426         return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
1427     }
1428 
1429     napi_value argv[ARGC_TWO] = {nullptr};
1430     CHECK_PARAM_NUMBER_WITHOUT_OPTIONAL_PARAMS(argv, ARGC_TWO);
1431 
1432     JsRoundRect* jsOuter = nullptr;
1433     GET_UNWRAP_PARAM(ARGC_ZERO, jsOuter);
1434 
1435     JsRoundRect* jsInner = nullptr;
1436     GET_UNWRAP_PARAM(ARGC_ONE, jsInner);
1437 
1438     m_canvas->DrawNestedRoundRect(jsOuter->GetRoundRect(), jsInner->GetRoundRect());
1439 #if defined(ROSEN_OHOS) || defined(ROSEN_ARKUI_X)
1440     if (mPixelMap_ != nullptr) {
1441         mPixelMap_->MarkDirty();
1442     }
1443 #endif
1444     return nullptr;
1445 }
1446 
GetTotalMatrix(napi_env env,napi_callback_info info)1447 napi_value JsCanvas::GetTotalMatrix(napi_env env, napi_callback_info info)
1448 {
1449     JsCanvas* me = CheckParamsAndGetThis<JsCanvas>(env, info);
1450     return (me != nullptr) ? me->OnGetTotalMatrix(env, info) : nullptr;
1451 }
1452 
OnGetTotalMatrix(napi_env env,napi_callback_info info)1453 napi_value JsCanvas::OnGetTotalMatrix(napi_env env, napi_callback_info info)
1454 {
1455     if (m_canvas == nullptr) {
1456         ROSEN_LOGE("JsCanvas::GetTotalMatrix canvas is null");
1457         return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
1458     }
1459 
1460     Matrix matrix = m_canvas->GetTotalMatrix();
1461     std::shared_ptr<Matrix> matrixPtr = std::make_shared<Matrix>(matrix);
1462 
1463     return JsMatrix::CreateJsMatrix(env, matrixPtr);
1464 }
1465 
AttachPen(napi_env env,napi_callback_info info)1466 napi_value JsCanvas::AttachPen(napi_env env, napi_callback_info info)
1467 {
1468     DRAWING_PERFORMANCE_TEST_JS_RETURN(nullptr);
1469     JsCanvas* me = CheckParamsAndGetThis<JsCanvas>(env, info);
1470     if (me == nullptr) {
1471         return nullptr;
1472     }
1473     Canvas* canvas = me->GetCanvas();
1474     if (canvas == nullptr) {
1475         ROSEN_LOGE("JsCanvas::AttachPen canvas is nullptr");
1476         return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
1477     }
1478 
1479     napi_value argv[ARGC_ONE] = {nullptr};
1480     CHECK_PARAM_NUMBER_WITHOUT_OPTIONAL_PARAMS(argv, ARGC_ONE);
1481 
1482     JsPen* jsPen = nullptr;
1483     GET_UNWRAP_PARAM(ARGC_ZERO, jsPen);
1484 
1485     if (jsPen->GetPen() == nullptr) {
1486         ROSEN_LOGE("JsCanvas::AttachPen pen is nullptr");
1487         return nullptr;
1488     }
1489     DRAWING_PERFORMANCE_TEST_NAP_RETURN(nullptr);
1490     canvas->AttachPen(*jsPen->GetPen());
1491     return nullptr;
1492 }
1493 
AttachBrush(napi_env env,napi_callback_info info)1494 napi_value JsCanvas::AttachBrush(napi_env env, napi_callback_info info)
1495 {
1496     DRAWING_PERFORMANCE_TEST_JS_RETURN(nullptr);
1497     JsCanvas* me = CheckParamsAndGetThis<JsCanvas>(env, info);
1498     if (me == nullptr) {
1499         return nullptr;
1500     }
1501     Canvas* canvas = me->GetCanvas();
1502     if (canvas == nullptr) {
1503         ROSEN_LOGE("JsCanvas::AttachBrush canvas is nullptr");
1504         return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
1505     }
1506 
1507     napi_value argv[ARGC_ONE] = {nullptr};
1508     CHECK_PARAM_NUMBER_WITHOUT_OPTIONAL_PARAMS(argv, ARGC_ONE);
1509 
1510     JsBrush* jsBrush = nullptr;
1511     GET_UNWRAP_PARAM(ARGC_ZERO, jsBrush);
1512 
1513     if (jsBrush->GetBrush() == nullptr) {
1514         ROSEN_LOGE("JsCanvas::AttachBrush brush is nullptr");
1515         return nullptr;
1516     }
1517     DRAWING_PERFORMANCE_TEST_NAP_RETURN(nullptr);
1518     canvas->AttachBrush(*jsBrush->GetBrush());
1519     return nullptr;
1520 }
1521 
DetachPen(napi_env env,napi_callback_info info)1522 napi_value JsCanvas::DetachPen(napi_env env, napi_callback_info info)
1523 {
1524     DRAWING_PERFORMANCE_TEST_JS_RETURN(nullptr);
1525     JsCanvas* me = CheckParamsAndGetThis<JsCanvas>(env, info);
1526     if (me == nullptr) {
1527         return nullptr;
1528     }
1529     Canvas* canvas = me->GetCanvas();
1530     if (canvas == nullptr) {
1531         ROSEN_LOGE("JsCanvas::DetachPen canvas is null");
1532         return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
1533     }
1534     DRAWING_PERFORMANCE_TEST_NAP_RETURN(nullptr);
1535     canvas->DetachPen();
1536     return nullptr;
1537 }
1538 
DetachBrush(napi_env env,napi_callback_info info)1539 napi_value JsCanvas::DetachBrush(napi_env env, napi_callback_info info)
1540 {
1541     DRAWING_PERFORMANCE_TEST_JS_RETURN(nullptr);
1542     JsCanvas* me = CheckParamsAndGetThis<JsCanvas>(env, info);
1543     if (me == nullptr) {
1544         return nullptr;
1545     }
1546     Canvas* canvas = me->GetCanvas();
1547     if (canvas == nullptr) {
1548         ROSEN_LOGE("JsCanvas::DetachBrush canvas is null");
1549         return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
1550     }
1551     DRAWING_PERFORMANCE_TEST_NAP_RETURN(nullptr);
1552     canvas->DetachBrush();
1553     return nullptr;
1554 }
1555 
Skew(napi_env env,napi_callback_info info)1556 napi_value JsCanvas::Skew(napi_env env, napi_callback_info info)
1557 {
1558     JsCanvas* me = CheckParamsAndGetThis<JsCanvas>(env, info);
1559     return (me != nullptr) ? me->OnSkew(env, info) : nullptr;
1560 }
1561 
OnSkew(napi_env env,napi_callback_info info)1562 napi_value JsCanvas::OnSkew(napi_env env, napi_callback_info info)
1563 {
1564     if (m_canvas == nullptr) {
1565         ROSEN_LOGE("JsCanvas::OnSkew m_canvas is null");
1566         return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
1567     }
1568 
1569     napi_value argv[ARGC_TWO] = {nullptr};
1570     CHECK_PARAM_NUMBER_WITHOUT_OPTIONAL_PARAMS(argv, ARGC_TWO);
1571 
1572     double sx = 0.0;
1573     GET_DOUBLE_PARAM(ARGC_ZERO, sx);
1574     double sy = 0.0;
1575     GET_DOUBLE_PARAM(ARGC_ONE, sy);
1576 
1577     m_canvas->Shear(sx, sy);
1578     return nullptr;
1579 }
1580 
Rotate(napi_env env,napi_callback_info info)1581 napi_value JsCanvas::Rotate(napi_env env, napi_callback_info info)
1582 {
1583     JsCanvas* me = CheckParamsAndGetThis<JsCanvas>(env, info);
1584     return (me != nullptr) ? me->OnRotate(env, info) : nullptr;
1585 }
1586 
OnRotate(napi_env env,napi_callback_info info)1587 napi_value JsCanvas::OnRotate(napi_env env, napi_callback_info info)
1588 {
1589     if (m_canvas == nullptr) {
1590         ROSEN_LOGE("JsCanvas::OnRotate m_canvas is null");
1591         return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
1592     }
1593 
1594     napi_value argv[ARGC_THREE] = {nullptr};
1595     CHECK_PARAM_NUMBER_WITHOUT_OPTIONAL_PARAMS(argv, ARGC_THREE);
1596 
1597     double degree = 0.0;
1598     GET_DOUBLE_PARAM(ARGC_ZERO, degree);
1599     double sx = 0.0;
1600     GET_DOUBLE_PARAM(ARGC_ONE, sx);
1601     double sy = 0.0;
1602     GET_DOUBLE_PARAM(ARGC_TWO, sy);
1603 
1604     m_canvas->Rotate(degree, sx, sy);
1605     return nullptr;
1606 }
1607 
GetSaveCount(napi_env env,napi_callback_info info)1608 napi_value JsCanvas::GetSaveCount(napi_env env, napi_callback_info info)
1609 {
1610     JsCanvas* me = CheckParamsAndGetThis<JsCanvas>(env, info);
1611     return (me != nullptr) ? me->OnGetSaveCount(env, info) : nullptr;
1612 }
1613 
OnGetSaveCount(napi_env env,napi_callback_info info)1614 napi_value JsCanvas::OnGetSaveCount(napi_env env, napi_callback_info info)
1615 {
1616     if (m_canvas == nullptr) {
1617         ROSEN_LOGE("JsCanvas::OnGetSaveCount canvas is null");
1618         return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
1619     }
1620     return CreateJsNumber(env, m_canvas->GetSaveCount());
1621 }
1622 
GetWidth(napi_env env,napi_callback_info info)1623 napi_value JsCanvas::GetWidth(napi_env env, napi_callback_info info)
1624 {
1625     JsCanvas* me = CheckParamsAndGetThis<JsCanvas>(env, info);
1626     return (me != nullptr) ? me->OnGetWidth(env, info) : nullptr;
1627 }
1628 
OnGetWidth(napi_env env,napi_callback_info info)1629 napi_value JsCanvas::OnGetWidth(napi_env env, napi_callback_info info)
1630 {
1631     if (m_canvas == nullptr) {
1632         ROSEN_LOGE("JsCanvas::OnGetWidth canvas is null");
1633         return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
1634     }
1635     return CreateJsNumber(env, m_canvas->GetWidth());
1636 }
1637 
GetHeight(napi_env env,napi_callback_info info)1638 napi_value JsCanvas::GetHeight(napi_env env, napi_callback_info info)
1639 {
1640     JsCanvas* me = CheckParamsAndGetThis<JsCanvas>(env, info);
1641     return (me != nullptr) ? me->OnGetHeight(env, info) : nullptr;
1642 }
1643 
OnGetHeight(napi_env env,napi_callback_info info)1644 napi_value JsCanvas::OnGetHeight(napi_env env, napi_callback_info info)
1645 {
1646     if (m_canvas == nullptr) {
1647         ROSEN_LOGE("JsCanvas::OnGetHeight canvas is null");
1648         return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
1649     }
1650     return CreateJsNumber(env, m_canvas->GetHeight());
1651 }
1652 
ClipPath(napi_env env,napi_callback_info info)1653 napi_value JsCanvas::ClipPath(napi_env env, napi_callback_info info)
1654 {
1655     JsCanvas* me = CheckParamsAndGetThis<JsCanvas>(env, info);
1656     return (me != nullptr) ? me->OnClipPath(env, info) : nullptr;
1657 }
1658 
OnClipPath(napi_env env,napi_callback_info info)1659 napi_value JsCanvas::OnClipPath(napi_env env, napi_callback_info info)
1660 {
1661     if (m_canvas == nullptr) {
1662         ROSEN_LOGE("JsCanvas::OnClipPath m_canvas is nullptr");
1663         return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
1664     }
1665     size_t argc = ARGC_THREE;
1666     napi_value argv[ARGC_THREE] = {nullptr};
1667     CHECK_PARAM_NUMBER_WITH_OPTIONAL_PARAMS(argv, argc, ARGC_ONE, ARGC_THREE);
1668 
1669     JsPath* jsPath = nullptr;
1670     GET_UNWRAP_PARAM(ARGC_ZERO, jsPath);
1671 
1672     Path* path = jsPath->GetPath();
1673     if (path == nullptr) {
1674         ROSEN_LOGE("JsCanvas::OnClipPath path is nullptr");
1675         return nullptr;
1676     }
1677     if (argc == ARGC_ONE) {
1678         m_canvas->ClipPath(*path);
1679         return nullptr;
1680     }
1681 
1682     int32_t jsClipOp = 0;
1683     GET_INT32_CHECK_GE_ZERO_PARAM(ARGC_ONE, jsClipOp);
1684 
1685     if (argc == ARGC_TWO) {
1686         m_canvas->ClipPath(*path, static_cast<ClipOp>(jsClipOp));
1687         return nullptr;
1688     }
1689 
1690     bool jsDoAntiAlias = false;
1691     GET_BOOLEAN_PARAM(ARGC_TWO, jsDoAntiAlias);
1692 
1693     m_canvas->ClipPath(*path, static_cast<ClipOp>(jsClipOp), jsDoAntiAlias);
1694     return nullptr;
1695 }
1696 
ClipRegion(napi_env env,napi_callback_info info)1697 napi_value JsCanvas::ClipRegion(napi_env env, napi_callback_info info)
1698 {
1699     JsCanvas* me = CheckParamsAndGetThis<JsCanvas>(env, info);
1700     return (me != nullptr) ? me->OnClipRegion(env, info) : nullptr;
1701 }
1702 
OnClipRegion(napi_env env,napi_callback_info info)1703 napi_value JsCanvas::OnClipRegion(napi_env env, napi_callback_info info)
1704 {
1705     if (m_canvas == nullptr) {
1706         ROSEN_LOGE("JsCanvas::OnClipRegion m_canvas is nullptr");
1707         return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
1708     }
1709     size_t argc = ARGC_TWO;
1710     napi_value argv[ARGC_TWO] = {nullptr};
1711     CHECK_PARAM_NUMBER_WITH_OPTIONAL_PARAMS(argv, argc, ARGC_ONE, ARGC_TWO);
1712 
1713     JsRegion* jsRegion = nullptr;
1714     GET_UNWRAP_PARAM(ARGC_ZERO, jsRegion);
1715 
1716     Region* region = jsRegion->GetRegion();
1717     if (region == nullptr) {
1718         ROSEN_LOGE("JsCanvas::OnClipRegion region is nullptr");
1719         return nullptr;
1720     }
1721     if (argc == ARGC_ONE) {
1722         m_canvas->ClipRegion(*region);
1723         return nullptr;
1724     }
1725 
1726     int32_t jsClipOp = 0;
1727     GET_ENUM_PARAM(ARGC_ONE, jsClipOp, 0, static_cast<int32_t>(ClipOp::INTERSECT));
1728 
1729     m_canvas->ClipRegion(*region, static_cast<ClipOp>(jsClipOp));
1730     return nullptr;
1731 }
1732 
Translate(napi_env env,napi_callback_info info)1733 napi_value JsCanvas::Translate(napi_env env, napi_callback_info info)
1734 {
1735     JsCanvas* me = CheckParamsAndGetThis<JsCanvas>(env, info);
1736     return (me != nullptr) ? me->OnTranslate(env, info) : nullptr;
1737 }
1738 
OnTranslate(napi_env env,napi_callback_info info)1739 napi_value JsCanvas::OnTranslate(napi_env env, napi_callback_info info)
1740 {
1741     if (m_canvas == nullptr) {
1742         ROSEN_LOGE("JsCanvas::OnTranslate m_canvas is null");
1743         return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
1744     }
1745 
1746     napi_value argv[ARGC_TWO] = {nullptr};
1747     CHECK_PARAM_NUMBER_WITHOUT_OPTIONAL_PARAMS(argv, ARGC_TWO);
1748 
1749     double dx = 0.0;
1750     GET_DOUBLE_PARAM(ARGC_ZERO, dx);
1751     double dy = 0.0;
1752     GET_DOUBLE_PARAM(ARGC_ONE, dy);
1753 
1754     m_canvas->Translate(dx, dy);
1755     return nullptr;
1756 }
1757 
Save(napi_env env,napi_callback_info info)1758 napi_value JsCanvas::Save(napi_env env, napi_callback_info info)
1759 {
1760     JsCanvas* me = CheckParamsAndGetThis<JsCanvas>(env, info);
1761     return (me != nullptr) ? me->OnSave(env, info) : nullptr;
1762 }
1763 
OnSave(napi_env env,napi_callback_info info)1764 napi_value JsCanvas::OnSave(napi_env env, napi_callback_info info)
1765 {
1766     if (m_canvas == nullptr) {
1767         ROSEN_LOGE("JsCanvas::OnSave canvas is null");
1768         return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
1769     }
1770     return CreateJsNumber(env, m_canvas->Save());
1771 }
1772 
SaveLayer(napi_env env,napi_callback_info info)1773 napi_value JsCanvas::SaveLayer(napi_env env, napi_callback_info info)
1774 {
1775     JsCanvas* me = CheckParamsAndGetThis<JsCanvas>(env, info);
1776     return (me != nullptr) ? me->OnSaveLayer(env, info) : nullptr;
1777 }
1778 
OnSaveLayer(napi_env env,napi_callback_info info)1779 napi_value JsCanvas::OnSaveLayer(napi_env env, napi_callback_info info)
1780 {
1781     if (m_canvas == nullptr) {
1782         ROSEN_LOGE("JsCanvas::OnSaveLayer canvas is null");
1783         return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
1784     }
1785     size_t argc = ARGC_TWO;
1786     napi_value argv[ARGC_TWO] = {nullptr};
1787     CHECK_PARAM_NUMBER_WITH_OPTIONAL_PARAMS(argv, argc, ARGC_ZERO, ARGC_TWO);
1788 
1789     uint32_t ret = 0;
1790     if (argc == ARGC_ZERO) {
1791         ret = m_canvas->GetSaveCount();
1792         m_canvas->SaveLayer(SaveLayerOps());
1793         return CreateJsNumber(env, ret);
1794     }
1795 
1796     napi_valuetype valueType = napi_undefined;
1797     if (napi_typeof(env, argv[ARGC_ZERO], &valueType) != napi_ok ||
1798         (valueType != napi_null && valueType != napi_object)) {
1799         return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Incorrect OnSaveLayer parameter0 type.");
1800     }
1801     Drawing::Rect* drawingRectPtr = nullptr;
1802     double ltrb[ARGC_FOUR] = {0};
1803     if (valueType == napi_object) {
1804         if (!ConvertFromJsRect(env, argv[ARGC_ZERO], ltrb, ARGC_FOUR)) {
1805             return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM,
1806                 "Incorrect parameter0 type. The type of left, top, right and bottom must be number.");
1807         }
1808         drawingRectPtr = new Drawing::Rect(ltrb[ARGC_ZERO], ltrb[ARGC_ONE], ltrb[ARGC_TWO], ltrb[ARGC_THREE]);
1809     }
1810 
1811     if (argc == ARGC_ONE) {
1812         ret = m_canvas->GetSaveCount();
1813         m_canvas->SaveLayer(SaveLayerOps(drawingRectPtr, nullptr));
1814         if (drawingRectPtr != nullptr) {
1815             delete drawingRectPtr;
1816         }
1817         return CreateJsNumber(env, ret);
1818     }
1819 
1820     if (napi_typeof(env, argv[ARGC_ONE], &valueType) != napi_ok ||
1821         (valueType != napi_null && valueType != napi_object)) {
1822         if (drawingRectPtr != nullptr) {
1823             delete drawingRectPtr;
1824         }
1825         return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Incorrect OnSaveLayer parameter1 type.");
1826     }
1827     Drawing::Brush* drawingBrushPtr = nullptr;
1828     if (valueType == napi_object) {
1829         JsBrush* jsBrush = nullptr;
1830         napi_status status = napi_unwrap(env, argv[ARGC_ONE], reinterpret_cast<void**>(&jsBrush));
1831         if (status != napi_ok || jsBrush == nullptr) {
1832             if (drawingRectPtr != nullptr) {
1833                 delete drawingRectPtr;
1834             }
1835             return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM,
1836                 std::string("Incorrect ") + __FUNCTION__ + " parameter" + std::to_string(ARGC_ONE) + " type.");
1837         }
1838         drawingBrushPtr = jsBrush->GetBrush();
1839     }
1840     ret = m_canvas->GetSaveCount();
1841     SaveLayerOps saveLayerOps = SaveLayerOps(drawingRectPtr, drawingBrushPtr);
1842     m_canvas->SaveLayer(saveLayerOps);
1843     if (drawingRectPtr != nullptr) {
1844         delete drawingRectPtr;
1845     }
1846     return CreateJsNumber(env, ret);
1847 }
1848 
RestoreToCount(napi_env env,napi_callback_info info)1849 napi_value JsCanvas::RestoreToCount(napi_env env, napi_callback_info info)
1850 {
1851     JsCanvas* me = CheckParamsAndGetThis<JsCanvas>(env, info);
1852     return (me != nullptr) ? me->OnRestoreToCount(env, info) : nullptr;
1853 }
1854 
OnRestoreToCount(napi_env env,napi_callback_info info)1855 napi_value JsCanvas::OnRestoreToCount(napi_env env, napi_callback_info info)
1856 {
1857     if (m_canvas == nullptr) {
1858         ROSEN_LOGE("JsCanvas::OnRestoreToCount canvas is nullptr");
1859         return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
1860     }
1861 
1862     napi_value argv[ARGC_ONE] = {nullptr};
1863     CHECK_PARAM_NUMBER_WITHOUT_OPTIONAL_PARAMS(argv, ARGC_ONE);
1864 
1865     int32_t count = 0;
1866     GET_INT32_CHECK_GE_ZERO_PARAM(ARGC_ZERO, count);
1867 
1868     m_canvas->RestoreToCount(count);
1869     return nullptr;
1870 }
1871 
Restore(napi_env env,napi_callback_info info)1872 napi_value JsCanvas::Restore(napi_env env, napi_callback_info info)
1873 {
1874     JsCanvas* me = CheckParamsAndGetThis<JsCanvas>(env, info);
1875     return (me != nullptr) ? me->OnRestore(env, info) : nullptr;
1876 }
1877 
OnRestore(napi_env env,napi_callback_info info)1878 napi_value JsCanvas::OnRestore(napi_env env, napi_callback_info info)
1879 {
1880     if (m_canvas == nullptr) {
1881         ROSEN_LOGE("JsCanvas::OnRestore m_canvas is null");
1882         return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
1883     }
1884     m_canvas->Restore();
1885     return nullptr;
1886 }
1887 
ClipRect(napi_env env,napi_callback_info info)1888 napi_value JsCanvas::ClipRect(napi_env env, napi_callback_info info)
1889 {
1890     JsCanvas* me = CheckParamsAndGetThis<JsCanvas>(env, info);
1891     return (me != nullptr) ? me->OnClipRect(env, info) : nullptr;
1892 }
1893 
OnClipRect(napi_env env,napi_callback_info info)1894 napi_value JsCanvas::OnClipRect(napi_env env, napi_callback_info info)
1895 {
1896     if (m_canvas == nullptr) {
1897         ROSEN_LOGE("JsCanvas::OnClipRect m_canvas is nullptr");
1898         return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
1899     }
1900     size_t argc = ARGC_THREE;
1901     napi_value argv[ARGC_THREE] = {nullptr};
1902     CHECK_PARAM_NUMBER_WITH_OPTIONAL_PARAMS(argv, argc, ARGC_ONE, ARGC_THREE);
1903 
1904     double ltrb[ARGC_FOUR] = {0};
1905     if (!ConvertFromJsRect(env, argv[ARGC_ZERO], ltrb, ARGC_FOUR)) {
1906         return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM,
1907             "Incorrect parameter0 type. The type of left, top, right and bottom must be number.");
1908     }
1909     Drawing::Rect drawingRect = Drawing::Rect(ltrb[ARGC_ZERO], ltrb[ARGC_ONE], ltrb[ARGC_TWO], ltrb[ARGC_THREE]);
1910 
1911     if (argc == ARGC_ONE) {
1912         m_canvas->ClipRect(drawingRect);
1913         return nullptr;
1914     }
1915 
1916     int32_t clipOpInt = 0;
1917     GET_INT32_CHECK_GE_ZERO_PARAM(ARGC_ONE, clipOpInt);
1918 
1919     if (argc == ARGC_TWO) {
1920         m_canvas->ClipRect(drawingRect, static_cast<ClipOp>(clipOpInt));
1921         return nullptr;
1922     }
1923 
1924     bool doAntiAlias = false;
1925     GET_BOOLEAN_PARAM(ARGC_TWO, doAntiAlias);
1926 
1927     m_canvas->ClipRect(drawingRect, static_cast<ClipOp>(clipOpInt), doAntiAlias);
1928     return nullptr;
1929 }
1930 
ClipRoundRect(napi_env env,napi_callback_info info)1931 napi_value JsCanvas::ClipRoundRect(napi_env env, napi_callback_info info)
1932 {
1933     JsCanvas* me = CheckParamsAndGetThis<JsCanvas>(env, info);
1934     return (me != nullptr) ? me->OnClipRoundRect(env, info) : nullptr;
1935 }
1936 
OnClipRoundRect(napi_env env,napi_callback_info info)1937 napi_value JsCanvas::OnClipRoundRect(napi_env env, napi_callback_info info)
1938 {
1939     if (m_canvas == nullptr) {
1940         ROSEN_LOGE("JsCanvas::OnClipRoundRect m_canvas is nullptr");
1941         return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
1942     }
1943 
1944     size_t argc = ARGC_THREE;
1945     napi_value argv[ARGC_THREE] = {nullptr};
1946     CHECK_PARAM_NUMBER_WITH_OPTIONAL_PARAMS(argv, argc, ARGC_ONE, ARGC_THREE);
1947 
1948     JsRoundRect* jsRoundRect = nullptr;
1949     GET_UNWRAP_PARAM(ARGC_ZERO, jsRoundRect);
1950     if (jsRoundRect == nullptr) {
1951         ROSEN_LOGE("JsCanvas::OnDrawRegion jsRoundRect is nullptr");
1952         return nullptr;
1953     }
1954 
1955     if (argc == ARGC_ONE) {
1956         m_canvas->ClipRoundRect(jsRoundRect->GetRoundRect());
1957         return nullptr;
1958     }
1959 
1960     int32_t clipOpInt = 0;
1961     GET_ENUM_PARAM(ARGC_ONE, clipOpInt, 0, static_cast<int32_t>(ClipOp::INTERSECT));
1962 
1963     if (argc == ARGC_TWO) {
1964         m_canvas->ClipRoundRect(jsRoundRect->GetRoundRect(), static_cast<ClipOp>(clipOpInt));
1965         return nullptr;
1966     }
1967 
1968     bool doAntiAlias = false;
1969     GET_BOOLEAN_PARAM(ARGC_TWO, doAntiAlias);
1970 
1971     m_canvas->ClipRoundRect(jsRoundRect->GetRoundRect(), static_cast<ClipOp>(clipOpInt), doAntiAlias);
1972     return nullptr;
1973 }
1974 
SetMatrix(napi_env env,napi_callback_info info)1975 napi_value JsCanvas::SetMatrix(napi_env env, napi_callback_info info)
1976 {
1977     JsCanvas* me = CheckParamsAndGetThis<JsCanvas>(env, info);
1978     return (me != nullptr) ? me->OnSetMatrix(env, info) : nullptr;
1979 }
1980 
OnSetMatrix(napi_env env,napi_callback_info info)1981 napi_value JsCanvas::OnSetMatrix(napi_env env, napi_callback_info info)
1982 {
1983     if (m_canvas == nullptr) {
1984         ROSEN_LOGE("JsCanvas::OnSetMatrix canvas is nullptr");
1985         return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
1986     }
1987 
1988     napi_value argv[ARGC_ONE] = {nullptr};
1989     CHECK_PARAM_NUMBER_WITHOUT_OPTIONAL_PARAMS(argv, ARGC_ONE);
1990 
1991     JsMatrix* jsMatrix = nullptr;
1992     GET_UNWRAP_PARAM(ARGC_ZERO, jsMatrix);
1993 
1994     if (jsMatrix->GetMatrix() == nullptr) {
1995         ROSEN_LOGE("JsCanvas::OnSetMatrix matrix is nullptr");
1996         return nullptr;
1997     }
1998 
1999     JS_CALL_DRAWING_FUNC(m_canvas->SetMatrix(*jsMatrix->GetMatrix()));
2000     return nullptr;
2001 }
2002 
Scale(napi_env env,napi_callback_info info)2003 napi_value JsCanvas::Scale(napi_env env, napi_callback_info info)
2004 {
2005     JsCanvas* me = CheckParamsAndGetThis<JsCanvas>(env, info);
2006     return (me != nullptr) ? me->OnScale(env, info) : nullptr;
2007 }
2008 
OnScale(napi_env env,napi_callback_info info)2009 napi_value JsCanvas::OnScale(napi_env env, napi_callback_info info)
2010 {
2011     if (m_canvas == nullptr) {
2012         ROSEN_LOGE("JsCanvas::OnScale canvas is nullptr");
2013         return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
2014     }
2015 
2016     napi_value argv[ARGC_TWO] = {nullptr};
2017     CHECK_PARAM_NUMBER_WITHOUT_OPTIONAL_PARAMS(argv, ARGC_TWO);
2018 
2019     double sx = 0.0;
2020     GET_DOUBLE_PARAM(ARGC_ZERO, sx);
2021     double sy = 0.0;
2022     GET_DOUBLE_PARAM(ARGC_ONE, sy);
2023 
2024     m_canvas->Scale(sx, sy);
2025     return nullptr;
2026 }
2027 
ConcatMatrix(napi_env env,napi_callback_info info)2028 napi_value JsCanvas::ConcatMatrix(napi_env env, napi_callback_info info)
2029 {
2030     JsCanvas* me = CheckParamsAndGetThis<JsCanvas>(env, info);
2031     return (me != nullptr) ? me->OnConcatMatrix(env, info) : nullptr;
2032 }
2033 
OnConcatMatrix(napi_env env,napi_callback_info info)2034 napi_value JsCanvas::OnConcatMatrix(napi_env env, napi_callback_info info)
2035 {
2036     if (m_canvas == nullptr) {
2037         ROSEN_LOGE("JsCanvas::OnConcatMatrix canvas is nullptr");
2038         return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
2039     }
2040 
2041     napi_value argv[ARGC_ONE] = {nullptr};
2042     CHECK_PARAM_NUMBER_WITHOUT_OPTIONAL_PARAMS(argv, ARGC_ONE);
2043 
2044     JsMatrix* jsMatrix = nullptr;
2045     GET_UNWRAP_PARAM(ARGC_ZERO, jsMatrix);
2046 
2047     if (jsMatrix->GetMatrix() == nullptr) {
2048         ROSEN_LOGE("JsCanvas::OnConcatMatrix matrix is nullptr");
2049         return nullptr;
2050     }
2051 
2052     JS_CALL_DRAWING_FUNC(m_canvas->ConcatMatrix(*jsMatrix->GetMatrix()));
2053     return nullptr;
2054 }
2055 
IsClipEmpty(napi_env env,napi_callback_info info)2056 napi_value JsCanvas::IsClipEmpty(napi_env env, napi_callback_info info)
2057 {
2058     JsCanvas* me = CheckParamsAndGetThis<JsCanvas>(env, info);
2059     return (me != nullptr) ? me->OnIsClipEmpty(env, info) : nullptr;
2060 }
2061 
OnIsClipEmpty(napi_env env,napi_callback_info info)2062 napi_value JsCanvas::OnIsClipEmpty(napi_env env, napi_callback_info info)
2063 {
2064     if (m_canvas == nullptr) {
2065         ROSEN_LOGE("JsCanvas::OnIsClipEmpty canvas is nullptr");
2066         return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
2067     }
2068 
2069     return CreateJsValue(env, m_canvas->IsClipEmpty());
2070 }
2071 
GetLocalClipBounds(napi_env env,napi_callback_info info)2072 napi_value JsCanvas::GetLocalClipBounds(napi_env env, napi_callback_info info)
2073 {
2074     JsCanvas* me = CheckParamsAndGetThis<JsCanvas>(env, info);
2075     return (me != nullptr) ? me->OnGetLocalClipBounds(env, info) : nullptr;
2076 }
2077 
OnGetLocalClipBounds(napi_env env,napi_callback_info info)2078 napi_value JsCanvas::OnGetLocalClipBounds(napi_env env, napi_callback_info info)
2079 {
2080     if (m_canvas == nullptr) {
2081         ROSEN_LOGE("JsCanvas::OnGetLocalClipBounds canvas is nullptr");
2082         return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
2083     }
2084     return GetRectAndConvertToJsValue(env, m_canvas->GetLocalClipBounds());
2085 }
2086 
GetCanvas()2087 Canvas* JsCanvas::GetCanvas()
2088 {
2089     return m_canvas;
2090 }
2091 
ResetCanvas()2092 void JsCanvas::ResetCanvas()
2093 {
2094     m_canvas = nullptr;
2095 }
2096 
ClipCanvas(float width,float height)2097 void JsCanvas::ClipCanvas(float width, float height)
2098 {
2099     if (m_canvas) {
2100         Rect rect(0, 0, width, height);
2101         JS_CALL_DRAWING_FUNC(m_canvas->ClipRect(rect));
2102     }
2103 }
2104 
SaveCanvas()2105 void JsCanvas::SaveCanvas()
2106 {
2107     if (m_canvas) {
2108         JS_CALL_DRAWING_FUNC(m_canvas->Save());
2109     }
2110 }
2111 
RestoreCanvas()2112 void JsCanvas::RestoreCanvas()
2113 {
2114     if (m_canvas) {
2115         JS_CALL_DRAWING_FUNC(m_canvas->Restore());
2116     }
2117 }
2118 
DrawImageNine(napi_env env,napi_callback_info info)2119 napi_value JsCanvas::DrawImageNine(napi_env env, napi_callback_info info)
2120 {
2121     DRAWING_PERFORMANCE_TEST_JS_RETURN(nullptr);
2122     JsCanvas* me = CheckParamsAndGetThis<JsCanvas>(env, info);
2123     return (me != nullptr) ? me->OnDrawImageNine(env, info) : nullptr;
2124 }
2125 
OnDrawImageNine(napi_env env,napi_callback_info info)2126 napi_value JsCanvas::OnDrawImageNine(napi_env env, napi_callback_info info)
2127 {
2128 #if defined(ROSEN_OHOS) || defined(ROSEN_ARKUI_X)
2129     if (m_canvas == nullptr) {
2130         ROSEN_LOGE("JsCanvas::OnDrawImageNine canvas is null");
2131         return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
2132     }
2133 
2134     napi_value argv[ARGC_FOUR] = { nullptr };
2135     CHECK_PARAM_NUMBER_WITHOUT_OPTIONAL_PARAMS(argv, ARGC_FOUR);
2136 
2137     PixelMapNapi* pixelMapNapi = nullptr;
2138     GET_UNWRAP_PARAM(ARGC_ZERO, pixelMapNapi); // arg #0: pixelmap/image
2139     auto pixel = pixelMapNapi->GetPixelNapiInner();
2140     if (pixel == nullptr) {
2141         ROSEN_LOGE("JsCanvas::OnDrawImageNine pixelmap GetPixelNapiInner is nullptr");
2142         return nullptr;
2143     }
2144 
2145     double ltrb[ARGC_FOUR] = {0};
2146     if (!ConvertFromJsRect(env, argv[ARGC_ONE], ltrb, ARGC_FOUR)) { // arg #1: centerRect
2147         return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM,
2148             "Incorrect rect src parameter type. The type of left, top, right and bottom must be number.");
2149     }
2150     Drawing::RectI centerRectI = Drawing::RectI(ltrb[ARGC_ZERO], ltrb[ARGC_ONE], ltrb[ARGC_TWO], ltrb[ARGC_THREE]);
2151 
2152     if (!ConvertFromJsRect(env, argv[ARGC_TWO], ltrb, ARGC_FOUR)) { // arg #2: dstRect
2153         return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM,
2154             "Incorrect rect dst parameter type. The type of left, top, right and bottom must be number.");
2155     }
2156     Drawing::Rect dstRect = Drawing::Rect(ltrb[ARGC_ZERO], ltrb[ARGC_ONE], ltrb[ARGC_TWO], ltrb[ARGC_THREE]);
2157 
2158     int32_t filterMode = 0;
2159     GET_ENUM_PARAM(ARGC_THREE, filterMode, 0, static_cast<int32_t>(FilterMode::LINEAR));
2160 
2161     if (m_canvas->GetDrawingType() == Drawing::DrawingType::RECORDING) {
2162         ExtendRecordingCanvas* canvas_ = reinterpret_cast<ExtendRecordingCanvas*>(m_canvas);
2163         canvas_->DrawPixelMapNine(pixel, centerRectI, dstRect, static_cast<FilterMode>(filterMode));
2164         return nullptr;
2165     }
2166     DRAWING_PERFORMANCE_TEST_NAP_RETURN(nullptr);
2167     std::shared_ptr<Drawing::Image> image = ExtractDrawingImage(pixel);
2168     JS_CALL_DRAWING_FUNC(m_canvas->DrawImageNine(image.get(),
2169         centerRectI, dstRect, static_cast<FilterMode>(filterMode), nullptr));
2170     if (mPixelMap_ != nullptr) {
2171         mPixelMap_->MarkDirty();
2172     }
2173 #endif
2174     return nullptr;
2175 }
2176 
DrawImageLattice(napi_env env,napi_callback_info info)2177 napi_value JsCanvas::DrawImageLattice(napi_env env, napi_callback_info info)
2178 {
2179     DRAWING_PERFORMANCE_TEST_JS_RETURN(nullptr);
2180     JsCanvas* me = CheckParamsAndGetThis<JsCanvas>(env, info);
2181     return (me != nullptr) ? me->OnDrawImageLattice(env, info) : nullptr;
2182 }
2183 
OnDrawImageLattice(napi_env env,napi_callback_info info)2184 napi_value JsCanvas::OnDrawImageLattice(napi_env env, napi_callback_info info)
2185 {
2186 #if defined(ROSEN_OHOS) || defined(ROSEN_ARKUI_X)
2187     if (m_canvas == nullptr) {
2188         ROSEN_LOGE("JsCanvas::OnDrawImageLattice canvas is null");
2189         return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
2190     }
2191 
2192     napi_value argv[ARGC_FOUR] = { nullptr };
2193     CHECK_PARAM_NUMBER_WITHOUT_OPTIONAL_PARAMS(argv, ARGC_FOUR);
2194 
2195     PixelMapNapi* pixelMapNapi = nullptr;
2196     GET_UNWRAP_PARAM(ARGC_ZERO, pixelMapNapi); // arg #0: pixelmap/image
2197     auto pixel = pixelMapNapi->GetPixelNapiInner();
2198     if (pixel == nullptr) {
2199         ROSEN_LOGE("JsCanvas::OnDrawImageLattice pixelmap GetPixelNapiInner is nullptr");
2200         return nullptr;
2201     }
2202 
2203     JsLattice* jsLattice = nullptr;
2204     GET_UNWRAP_PARAM(ARGC_ONE, jsLattice);
2205     std::shared_ptr<Lattice> lattice = jsLattice->GetLattice();
2206     if (lattice == nullptr) {
2207         ROSEN_LOGE("JsCanvas::OnDrawImageLattice lattice is nullptr");
2208         return nullptr;
2209     }
2210 
2211     double ltrb[ARGC_FOUR] = {0};
2212     if (!ConvertFromJsRect(env, argv[ARGC_TWO], ltrb, ARGC_FOUR)) { // arg #2: dstRect
2213         return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM,
2214             "Incorrect rect dst parameter type. The type of left, top, right and bottom must be number.");
2215     }
2216     Drawing::Rect dstRect = Drawing::Rect(ltrb[ARGC_ZERO], ltrb[ARGC_ONE], ltrb[ARGC_TWO], ltrb[ARGC_THREE]);
2217 
2218     int32_t filterMode = 0;
2219     GET_ENUM_PARAM(ARGC_THREE, filterMode, 0, static_cast<int32_t>(FilterMode::LINEAR));
2220 
2221     if (m_canvas->GetDrawingType() == Drawing::DrawingType::RECORDING) {
2222         ExtendRecordingCanvas* canvas_ = reinterpret_cast<ExtendRecordingCanvas*>(m_canvas);
2223         canvas_->DrawPixelMapLattice(pixel, *lattice, dstRect, static_cast<FilterMode>(filterMode));
2224         return nullptr;
2225     }
2226     DRAWING_PERFORMANCE_TEST_NAP_RETURN(nullptr);
2227     std::shared_ptr<Drawing::Image> image = ExtractDrawingImage(pixel);
2228     JS_CALL_DRAWING_FUNC(m_canvas->DrawImageLattice(image.get(),
2229         *lattice, dstRect, static_cast<FilterMode>(filterMode)));
2230     if (mPixelMap_ != nullptr) {
2231         mPixelMap_->MarkDirty();
2232     }
2233 #endif
2234     return nullptr;
2235 }
2236 
DrawImageRect(napi_env env,napi_callback_info info)2237 napi_value JsCanvas::DrawImageRect(napi_env env, napi_callback_info info)
2238 {
2239     JsCanvas* me = CheckParamsAndGetThis<JsCanvas>(env, info);
2240     return (me != nullptr) ? me->OnDrawImageRect(env, info) : nullptr;
2241 }
2242 
OnDrawImageRect(napi_env env,napi_callback_info info)2243 napi_value JsCanvas::OnDrawImageRect(napi_env env, napi_callback_info info)
2244 {
2245 #if defined(ROSEN_OHOS) || defined(ROSEN_ARKUI_X)
2246     if (m_canvas == nullptr) {
2247         ROSEN_LOGE("JsCanvas::OnDrawImageRect canvas is nullptr");
2248         return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
2249     }
2250 
2251     size_t argc = ARGC_THREE;
2252     napi_value argv[ARGC_THREE] = {nullptr};
2253     CHECK_PARAM_NUMBER_WITH_OPTIONAL_PARAMS(argv, argc, ARGC_TWO, ARGC_THREE);
2254 
2255     PixelMapNapi* pixelMapNapi = nullptr;
2256     GET_UNWRAP_PARAM(ARGC_ZERO, pixelMapNapi); // arg #0: pixelmap/image
2257     auto pixel = pixelMapNapi->GetPixelNapiInner();
2258     if (pixel == nullptr) {
2259         ROSEN_LOGE("JsCanvas::OnDrawImageRect pixelmap GetPixelNapiInner is nullptr");
2260         return nullptr;
2261     }
2262 
2263     double ltrb[ARGC_FOUR] = {0};
2264     if (!ConvertFromJsRect(env, argv[ARGC_ONE], ltrb, ARGC_FOUR)) { // arg #1: dstRect
2265         return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM,
2266             "Incorrect rect dst parameter type. The type of left, top, right and bottom must be number.");
2267     }
2268     Drawing::Rect dstRect = Drawing::Rect(ltrb[ARGC_ZERO], ltrb[ARGC_ONE], ltrb[ARGC_TWO], ltrb[ARGC_THREE]);
2269 
2270     if (argc == ARGC_TWO) { // without (optional) arg #2: samplingOptions
2271         DRAWING_PERFORMANCE_TEST_NAP_RETURN(nullptr);
2272         if (m_canvas->GetDrawingType() == Drawing::DrawingType::RECORDING) {
2273             ExtendRecordingCanvas* canvas_ = reinterpret_cast<ExtendRecordingCanvas*>(m_canvas);
2274             Drawing::Rect srcRect(0, 0, pixel->GetWidth(), pixel->GetHeight());
2275             canvas_->DrawPixelMapRect(pixel, srcRect, dstRect, Drawing::SamplingOptions(),
2276                 SrcRectConstraint::FAST_SRC_RECT_CONSTRAINT);
2277             return nullptr;
2278         }
2279         std::shared_ptr<Drawing::Image> image = ExtractDrawingImage(pixel);
2280         if (image == nullptr) {
2281             ROSEN_LOGE("JsCanvas::OnDrawImageRect image is nullptr");
2282             return nullptr;
2283         }
2284         m_canvas->DrawImageRect(*image, dstRect, Drawing::SamplingOptions());
2285     } else {
2286         JsSamplingOptions* jsSamplingOptions = nullptr;
2287         GET_UNWRAP_PARAM(ARGC_TWO, jsSamplingOptions); // (optional) arg #2: samplingOptions
2288         std::shared_ptr<SamplingOptions> samplingOptions = jsSamplingOptions->GetSamplingOptions();
2289         if (samplingOptions == nullptr) {
2290             ROSEN_LOGE("JsCanvas::OnDrawImageRect get samplingOptions is nullptr");
2291             return nullptr;
2292         }
2293         if (m_canvas->GetDrawingType() == Drawing::DrawingType::RECORDING) {
2294             ExtendRecordingCanvas* canvas_ = reinterpret_cast<ExtendRecordingCanvas*>(m_canvas);
2295             Drawing::Rect srcRect(0, 0, pixel->GetWidth(), pixel->GetHeight());
2296             canvas_->DrawPixelMapRect(pixel, srcRect, dstRect, *samplingOptions.get(),
2297                 SrcRectConstraint::FAST_SRC_RECT_CONSTRAINT);
2298             return nullptr;
2299         }
2300         DRAWING_PERFORMANCE_TEST_NAP_RETURN(nullptr);
2301         std::shared_ptr<Drawing::Image> image = ExtractDrawingImage(pixel);
2302         if (image == nullptr) {
2303             ROSEN_LOGE("JsCanvas::OnDrawImageRect image is nullptr");
2304             return nullptr;
2305         }
2306         m_canvas->DrawImageRect(*image, dstRect, *samplingOptions.get());
2307     }
2308     if (mPixelMap_ != nullptr) {
2309         mPixelMap_->MarkDirty();
2310     }
2311 #endif
2312     return nullptr;
2313 }
2314 
DrawImageRectWithSrc(napi_env env,napi_callback_info info)2315 napi_value JsCanvas::DrawImageRectWithSrc(napi_env env, napi_callback_info info)
2316 {
2317     JsCanvas* me = CheckParamsAndGetThis<JsCanvas>(env, info);
2318     return (me != nullptr) ? me->OnDrawImageRectWithSrc(env, info) : nullptr;
2319 }
2320 
2321 #if defined(ROSEN_OHOS) || defined(ROSEN_ARKUI_X)
OnDrawingImageRectWithSrc(napi_env env,napi_value * argv,size_t argc,Canvas & canvas,const std::shared_ptr<Media::PixelMap> pixel,const Rect & srcRect,const Rect & dstRect)2322 static napi_value OnDrawingImageRectWithSrc(napi_env env, napi_value* argv, size_t argc, Canvas& canvas,
2323                                             const std::shared_ptr<Media::PixelMap> pixel,
2324                                             const Rect& srcRect, const Rect& dstRect)
2325 {
2326     if (argc == ARGC_THREE) { // without optional arg #3 (samplingOptions) and arg #4 (constraint):
2327         DRAWING_PERFORMANCE_TEST_NAP_RETURN(nullptr);
2328         if (canvas.GetDrawingType() == Drawing::DrawingType::RECORDING) {
2329             ExtendRecordingCanvas* canvas_ = reinterpret_cast<ExtendRecordingCanvas*>(&canvas);
2330             canvas_->DrawPixelMapRect(pixel, srcRect, dstRect, Drawing::SamplingOptions());
2331             return nullptr;
2332         }
2333         std::shared_ptr<Drawing::Image> image = ExtractDrawingImage(pixel);
2334         if (image == nullptr) {
2335             ROSEN_LOGE("JsCanvas::OnDrawImageRectWithSrc image is nullptr");
2336             return nullptr;
2337         }
2338         canvas.DrawImageRect(*image, srcRect, dstRect, Drawing::SamplingOptions());
2339     } else if (argc == ARGC_FOUR) { // without optional arg #4 (constraint):
2340         JsSamplingOptions* jsSamplingOptions = nullptr;
2341         GET_UNWRAP_PARAM(ARGC_THREE, jsSamplingOptions);
2342         std::shared_ptr<SamplingOptions> samplingOptions = jsSamplingOptions->GetSamplingOptions();
2343         if (samplingOptions == nullptr) {
2344             return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Incorrect samplingOptions parameter.");
2345         }
2346         if (canvas.GetDrawingType() == Drawing::DrawingType::RECORDING) {
2347             ExtendRecordingCanvas* canvas_ = reinterpret_cast<ExtendRecordingCanvas*>(&canvas);
2348             canvas_->DrawPixelMapRect(pixel, srcRect, dstRect, *samplingOptions.get());
2349             return nullptr;
2350         }
2351         DRAWING_PERFORMANCE_TEST_NAP_RETURN(nullptr);
2352         std::shared_ptr<Drawing::Image> image = ExtractDrawingImage(pixel);
2353         if (image == nullptr) {
2354             ROSEN_LOGE("JsCanvas::OnDrawImageRectWithSrc image is nullptr");
2355             return nullptr;
2356         }
2357         canvas.DrawImageRect(*image, srcRect, dstRect, *samplingOptions.get());
2358     } else if (argc == ARGC_FIVE) {  // with optional arg #3 (samplingOptions) and arg #4 (constraint):
2359         JsSamplingOptions* jsSamplingOptions = nullptr;
2360         GET_UNWRAP_PARAM(ARGC_THREE, jsSamplingOptions);
2361         std::shared_ptr<SamplingOptions> samplingOptions = jsSamplingOptions->GetSamplingOptions();
2362         if (samplingOptions == nullptr) {
2363             return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Incorrect samplingOptions parameter.");
2364         }
2365         int32_t constraint = 0;
2366         GET_ENUM_PARAM(ARGC_FOUR,
2367             constraint,
2368             static_cast<int32_t>(SrcRectConstraint::STRICT_SRC_RECT_CONSTRAINT),
2369             static_cast<int32_t>(SrcRectConstraint::FAST_SRC_RECT_CONSTRAINT));
2370         if (canvas.GetDrawingType() == Drawing::DrawingType::RECORDING) {
2371             ExtendRecordingCanvas* canvas_ = reinterpret_cast<ExtendRecordingCanvas*>(&canvas);
2372             canvas_->DrawPixelMapRect(pixel, srcRect, dstRect,
2373                 *samplingOptions.get(), static_cast<SrcRectConstraint>(constraint));
2374             return nullptr;
2375         }
2376         DRAWING_PERFORMANCE_TEST_NAP_RETURN(nullptr);
2377         std::shared_ptr<Drawing::Image> image = ExtractDrawingImage(pixel);
2378         if (image == nullptr) {
2379             ROSEN_LOGE("JsCanvas::OnDrawImageRectWithSrc image is nullptr");
2380             return nullptr;
2381         }
2382         canvas.DrawImageRect(*image, srcRect, dstRect,
2383             *samplingOptions.get(), static_cast<SrcRectConstraint>(constraint));
2384     } else { // argc > 5:
2385         return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "More than 5 parameters are not supported");
2386     }
2387     return nullptr;
2388 }
2389 #endif
2390 
OnDrawImageRectWithSrc(napi_env env,napi_callback_info info)2391 napi_value JsCanvas::OnDrawImageRectWithSrc(napi_env env, napi_callback_info info)
2392 {
2393 #if defined(ROSEN_OHOS) || defined(ROSEN_ARKUI_X)
2394     if (m_canvas == nullptr) {
2395         ROSEN_LOGE("JsCanvas::OnDrawImageRectWithSrc canvas is nullptr");
2396         return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
2397     }
2398 
2399     size_t argc = ARGC_FIVE;
2400     napi_value argv[ARGC_FIVE] = {nullptr};
2401     CHECK_PARAM_NUMBER_WITH_OPTIONAL_PARAMS(argv, argc, ARGC_THREE, ARGC_FIVE);
2402 
2403     PixelMapNapi* pixelMapNapi = nullptr;
2404     GET_UNWRAP_PARAM(ARGC_ZERO, pixelMapNapi); // arg #0: pixelmap/image
2405     auto pixel = pixelMapNapi->GetPixelNapiInner();
2406     if (pixel == nullptr) {
2407         ROSEN_LOGE("JsCanvas::OnDrawImageRectWithSrc pixelmap GetPixelNapiInner is nullptr");
2408         return nullptr;
2409     }
2410 
2411     double ltrb[ARGC_FOUR] = {0};
2412     if (!ConvertFromJsRect(env, argv[ARGC_ONE], ltrb, ARGC_FOUR)) { // arg #1: srcRect
2413         return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM,
2414             "Incorrect rect src parameter type. The type of left, top, right and bottom must be number.");
2415     }
2416     Drawing::Rect srcRect = Drawing::Rect(ltrb[ARGC_ZERO], ltrb[ARGC_ONE], ltrb[ARGC_TWO], ltrb[ARGC_THREE]);
2417 
2418     if (!ConvertFromJsRect(env, argv[ARGC_TWO], ltrb, ARGC_FOUR)) { // arg #2: dstRect
2419         return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM,
2420             "Incorrect rect dst parameter type. The type of left, top, right and bottom must be number.");
2421     }
2422     Drawing::Rect dstRect = Drawing::Rect(ltrb[ARGC_ZERO], ltrb[ARGC_ONE], ltrb[ARGC_TWO], ltrb[ARGC_THREE]);
2423 
2424     napi_value result = OnDrawingImageRectWithSrc(env, argv, argc, *m_canvas, pixel, srcRect, dstRect);
2425     if (mPixelMap_ != nullptr) {
2426         mPixelMap_->MarkDirty();
2427     }
2428     return result;
2429 #else
2430     return nullptr;
2431 #endif
2432 }
2433 
ResetMatrix(napi_env env,napi_callback_info info)2434 napi_value JsCanvas::ResetMatrix(napi_env env, napi_callback_info info)
2435 {
2436     JsCanvas* me = CheckParamsAndGetThis<JsCanvas>(env, info);
2437     return (me != nullptr) ? me->OnResetMatrix(env, info) : nullptr;
2438 }
2439 
OnResetMatrix(napi_env env,napi_callback_info info)2440 napi_value JsCanvas::OnResetMatrix(napi_env env, napi_callback_info info)
2441 {
2442     if (m_canvas == nullptr) {
2443         ROSEN_LOGE("JsCanvas::OnResetMatrix m_canvas is null");
2444         return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
2445     }
2446     m_canvas->ResetMatrix();
2447     return nullptr;
2448 }
2449 
2450 } // namespace Drawing
2451 } // namespace OHOS::Rosen
2452