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(¤tStr, 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