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