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