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