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