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