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::__anon6f2d5c6d0110::PixelMapReleaseContext112 explicit PixelMapReleaseContext(std::shared_ptr<PixelMap> pixelMap) : pixelMap_(pixelMap) {}
113
~PixelMapReleaseContextOHOS::Rosen::__anon6f2d5c6d0110::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
1114 const char* currentStr = str;
1115 int32_t unicode = SkUTF::NextUTF8(¤tStr, currentStr + len);
1116 size_t byteLen = currentStr - str;
1117 if (byteLen != len) {
1118 return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM,
1119 "Parameter verification failed. Input parameter0 should be single character.");
1120 }
1121 m_canvas->DrawSingleCharacter(unicode, *font, x, y);
1122 #ifdef ROSEN_OHOS
1123 if (mPixelMap_ != nullptr) {
1124 mPixelMap_->MarkDirty();
1125 }
1126 #endif
1127 return nullptr;
1128 }
1129
DrawPixelMapMesh(napi_env env,napi_callback_info info)1130 napi_value JsCanvas::DrawPixelMapMesh(napi_env env, napi_callback_info info)
1131 {
1132 JsCanvas* me = CheckParamsAndGetThis<JsCanvas>(env, info);
1133 return (me != nullptr) ? me->OnDrawPixelMapMesh(env, info) : nullptr;
1134 }
1135
OnDrawPixelMapMesh(napi_env env,napi_callback_info info)1136 napi_value JsCanvas::OnDrawPixelMapMesh(napi_env env, napi_callback_info info)
1137 {
1138 #ifdef ROSEN_OHOS
1139 if (m_canvas == nullptr) {
1140 ROSEN_LOGE("JsCanvas::OnDrawPixelMapMesh canvas is null");
1141 return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
1142 }
1143
1144 napi_value argv[ARGC_SEVEN] = {nullptr};
1145 CHECK_PARAM_NUMBER_WITHOUT_OPTIONAL_PARAMS(argv, ARGC_SEVEN);
1146
1147 PixelMapNapi* pixelMapNapi = nullptr;
1148 GET_UNWRAP_PARAM(ARGC_ZERO, pixelMapNapi);
1149
1150 if (pixelMapNapi->GetPixelNapiInner() == nullptr) {
1151 ROSEN_LOGE("Drawing_napi::pixelMap pixelmap getPixelNapiInner is nullptr");
1152 return nullptr;
1153 }
1154 std::shared_ptr<Media::PixelMap> pixelMap = pixelMapNapi->GetPixelNapiInner();
1155
1156 int32_t column = 0;
1157 GET_INT32_CHECK_GE_ZERO_PARAM(ARGC_ONE, column);
1158 int32_t row = 0;
1159 GET_INT32_CHECK_GE_ZERO_PARAM(ARGC_TWO, row);
1160 int32_t vertOffset = 0;
1161 GET_INT32_CHECK_GE_ZERO_PARAM(ARGC_FOUR, vertOffset);
1162 int32_t colorOffset = 0;
1163 GET_INT32_CHECK_GE_ZERO_PARAM(ARGC_SIX, colorOffset);
1164
1165 if (column == 0 || row == 0) {
1166 ROSEN_LOGE("JsCanvas::OnDrawPixelMapMesh column or row is invalid");
1167 return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Invalid column or row params.");
1168 }
1169
1170 napi_value verticesArray = argv[ARGC_THREE];
1171 uint32_t verticesSize = 0;
1172 napi_get_array_length(env, verticesArray, &verticesSize);
1173 int64_t tempVerticesSize = ((column + 1) * (row + 1) + vertOffset) * 2; // x and y two coordinates
1174 if (verticesSize != tempVerticesSize) {
1175 ROSEN_LOGE("JsCanvas::OnDrawPixelMapMesh vertices are invalid");
1176 return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Incorrect parameter3 type.");
1177 }
1178
1179 auto vertices = new (std::nothrow) float[verticesSize];
1180 if (!vertices) {
1181 ROSEN_LOGE("JsCanvas::OnDrawPixelMapMesh create array with size of vertices failed");
1182 return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Size of vertices exceed memory limit.");
1183 }
1184
1185 for (uint32_t i = 0; i < verticesSize; i++) {
1186 napi_value tempVertex = nullptr;
1187 napi_get_element(env, verticesArray, i, &tempVertex);
1188 double vertex = 0.f;
1189 if (napi_get_value_double(env, tempVertex, &vertex) != napi_ok) {
1190 ROSEN_LOGE("JsCanvas::OnDrawPixelMapMesh vertex is invalid");
1191 delete []vertices;
1192 return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM,
1193 "Incorrect DrawPixelMapMesh parameter vertex type.");
1194 }
1195 vertices[i] = vertex;
1196 }
1197 float* verticesMesh = verticesSize ? (vertices + vertOffset * 2) : nullptr; // offset two coordinates
1198
1199 napi_value colorsArray = argv[ARGC_FIVE];
1200 uint32_t colorsSize = 0;
1201 napi_get_array_length(env, colorsArray, &colorsSize);
1202 int64_t tempColorsSize = (column + 1) * (row + 1) + colorOffset;
1203
1204 if (colorsSize != 0 && colorsSize != tempColorsSize) {
1205 ROSEN_LOGE("JsCanvas::OnDrawPixelMapMesh colors are invalid");
1206 delete []vertices;
1207 return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Incorrect parameter5 type.");
1208 }
1209
1210 if (colorsSize == 0) {
1211 DrawingPixelMapMesh(pixelMap, column, row, verticesMesh, nullptr, m_canvas);
1212 if (mPixelMap_ != nullptr) {
1213 mPixelMap_->MarkDirty();
1214 }
1215 delete []vertices;
1216 return nullptr;
1217 }
1218
1219 auto colors = new (std::nothrow) uint32_t[colorsSize];
1220 if (!colors) {
1221 ROSEN_LOGE("JsCanvas::OnDrawPixelMapMesh create array with size of colors failed");
1222 delete []vertices;
1223 return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Size of colors exceed memory limit.");
1224 }
1225 for (uint32_t i = 0; i < colorsSize; i++) {
1226 napi_value tempColor = nullptr;
1227 napi_get_element(env, colorsArray, i, &tempColor);
1228 uint32_t color = 0;
1229 if (napi_get_value_uint32(env, tempColor, &color) != napi_ok) {
1230 ROSEN_LOGE("JsCanvas::OnDrawPixelMapMesh color is invalid");
1231 delete []vertices;
1232 delete []colors;
1233 return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM,
1234 "Incorrect DrawPixelMapMesh parameter color type.");
1235 }
1236 colors[i] = color;
1237 }
1238 uint32_t* colorsMesh = colors + colorOffset;
1239
1240 DrawingPixelMapMesh(pixelMap, column, row, verticesMesh, colorsMesh, m_canvas);
1241 if (mPixelMap_ != nullptr) {
1242 mPixelMap_->MarkDirty();
1243 }
1244 delete []vertices;
1245 delete []colors;
1246 return nullptr;
1247 #else
1248 return nullptr;
1249 #endif
1250 }
1251
DrawRegion(napi_env env,napi_callback_info info)1252 napi_value JsCanvas::DrawRegion(napi_env env, napi_callback_info info)
1253 {
1254 JsCanvas* me = CheckParamsAndGetThis<JsCanvas>(env, info);
1255 return (me != nullptr) ? me->OnDrawRegion(env, info) : nullptr;
1256 }
1257
OnDrawRegion(napi_env env,napi_callback_info info)1258 napi_value JsCanvas::OnDrawRegion(napi_env env, napi_callback_info info)
1259 {
1260 if (m_canvas == nullptr) {
1261 ROSEN_LOGE("JsCanvas::OnDrawRegion canvas is nullptr");
1262 return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
1263 }
1264 napi_value argv[ARGC_ONE] = {nullptr};
1265 CHECK_PARAM_NUMBER_WITHOUT_OPTIONAL_PARAMS(argv, ARGC_ONE);
1266
1267 JsRegion* jsRegion = nullptr;
1268 GET_UNWRAP_PARAM(ARGC_ZERO, jsRegion);
1269 if (jsRegion->GetRegion() == nullptr) {
1270 ROSEN_LOGE("JsCanvas::OnDrawRegion region is nullptr");
1271 return nullptr;
1272 }
1273 JS_CALL_DRAWING_FUNC(m_canvas->DrawRegion(*jsRegion->GetRegion()));
1274 #ifdef ROSEN_OHOS
1275 if (mPixelMap_ != nullptr) {
1276 mPixelMap_->MarkDirty();
1277 }
1278 #endif
1279 return nullptr;
1280 }
1281
DrawBackground(napi_env env,napi_callback_info info)1282 napi_value JsCanvas::DrawBackground(napi_env env, napi_callback_info info)
1283 {
1284 JsCanvas* me = CheckParamsAndGetThis<JsCanvas>(env, info);
1285 return (me != nullptr) ? me->OnDrawBackground(env, info) : nullptr;
1286 }
1287
OnDrawBackground(napi_env env,napi_callback_info info)1288 napi_value JsCanvas::OnDrawBackground(napi_env env, napi_callback_info info)
1289 {
1290 if (m_canvas == nullptr) {
1291 ROSEN_LOGE("JsCanvas::OnDrawBackground canvas is nullptr");
1292 return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
1293 }
1294
1295 napi_value argv[ARGC_ONE] = {nullptr};
1296 CHECK_PARAM_NUMBER_WITHOUT_OPTIONAL_PARAMS(argv, ARGC_ONE);
1297
1298 JsBrush* jsBrush = nullptr;
1299 GET_UNWRAP_PARAM(ARGC_ZERO, jsBrush);
1300 if (jsBrush->GetBrush() == nullptr) {
1301 ROSEN_LOGE("JsCanvas::OnDrawBackground brush is nullptr");
1302 return nullptr;
1303 }
1304
1305 m_canvas->DrawBackground(*jsBrush->GetBrush());
1306 #ifdef ROSEN_OHOS
1307 if (mPixelMap_ != nullptr) {
1308 mPixelMap_->MarkDirty();
1309 }
1310 #endif
1311 return nullptr;
1312 }
1313
DrawRoundRect(napi_env env,napi_callback_info info)1314 napi_value JsCanvas::DrawRoundRect(napi_env env, napi_callback_info info)
1315 {
1316 JsCanvas* me = CheckParamsAndGetThis<JsCanvas>(env, info);
1317 return (me != nullptr) ? me->OnDrawRoundRect(env, info) : nullptr;
1318 }
1319
OnDrawRoundRect(napi_env env,napi_callback_info info)1320 napi_value JsCanvas::OnDrawRoundRect(napi_env env, napi_callback_info info)
1321 {
1322 if (m_canvas == nullptr) {
1323 ROSEN_LOGE("JsCanvas::OnDrawRoundRect canvas is nullptr");
1324 return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
1325 }
1326
1327 napi_value argv[ARGC_ONE] = {nullptr};
1328 CHECK_PARAM_NUMBER_WITHOUT_OPTIONAL_PARAMS(argv, ARGC_ONE);
1329
1330 JsRoundRect* jsRoundRect = nullptr;
1331 GET_UNWRAP_PARAM(ARGC_ZERO, jsRoundRect);
1332
1333 m_canvas->DrawRoundRect(jsRoundRect->GetRoundRect());
1334 #ifdef ROSEN_OHOS
1335 if (mPixelMap_ != nullptr) {
1336 mPixelMap_->MarkDirty();
1337 }
1338 #endif
1339 return nullptr;
1340 }
1341
DrawNestedRoundRect(napi_env env,napi_callback_info info)1342 napi_value JsCanvas::DrawNestedRoundRect(napi_env env, napi_callback_info info)
1343 {
1344 JsCanvas* me = CheckParamsAndGetThis<JsCanvas>(env, info);
1345 return (me != nullptr) ? me->OnDrawNestedRoundRect(env, info) : nullptr;
1346 }
1347
OnDrawNestedRoundRect(napi_env env,napi_callback_info info)1348 napi_value JsCanvas::OnDrawNestedRoundRect(napi_env env, napi_callback_info info)
1349 {
1350 if (m_canvas == nullptr) {
1351 ROSEN_LOGE("JsCanvas::OnDrawNestedRoundRect canvas is nullptr");
1352 return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
1353 }
1354
1355 napi_value argv[ARGC_TWO] = {nullptr};
1356 CHECK_PARAM_NUMBER_WITHOUT_OPTIONAL_PARAMS(argv, ARGC_TWO);
1357
1358 JsRoundRect* jsOuter = nullptr;
1359 GET_UNWRAP_PARAM(ARGC_ZERO, jsOuter);
1360
1361 JsRoundRect* jsInner = nullptr;
1362 GET_UNWRAP_PARAM(ARGC_ONE, jsInner);
1363
1364 m_canvas->DrawNestedRoundRect(jsOuter->GetRoundRect(), jsInner->GetRoundRect());
1365 #ifdef ROSEN_OHOS
1366 if (mPixelMap_ != nullptr) {
1367 mPixelMap_->MarkDirty();
1368 }
1369 #endif
1370 return nullptr;
1371 }
1372
GetTotalMatrix(napi_env env,napi_callback_info info)1373 napi_value JsCanvas::GetTotalMatrix(napi_env env, napi_callback_info info)
1374 {
1375 JsCanvas* me = CheckParamsAndGetThis<JsCanvas>(env, info);
1376 return (me != nullptr) ? me->OnGetTotalMatrix(env, info) : nullptr;
1377 }
1378
OnGetTotalMatrix(napi_env env,napi_callback_info info)1379 napi_value JsCanvas::OnGetTotalMatrix(napi_env env, napi_callback_info info)
1380 {
1381 if (m_canvas == nullptr) {
1382 ROSEN_LOGE("JsCanvas::GetTotalMatrix canvas is null");
1383 return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
1384 }
1385
1386 Matrix matrix = m_canvas->GetTotalMatrix();
1387 std::shared_ptr<Matrix> matrixPtr = std::make_shared<Matrix>(matrix);
1388
1389 return JsMatrix::CreateJsMatrix(env, matrixPtr);
1390 }
1391
AttachPen(napi_env env,napi_callback_info info)1392 napi_value JsCanvas::AttachPen(napi_env env, napi_callback_info info)
1393 {
1394 DRAWING_PERFORMANCE_TEST_JS_RETURN(nullptr);
1395 JsCanvas* me = CheckParamsAndGetThis<JsCanvas>(env, info);
1396 if (me == nullptr) {
1397 return nullptr;
1398 }
1399 Canvas* canvas = me->GetCanvas();
1400 if (canvas == nullptr) {
1401 ROSEN_LOGE("JsCanvas::AttachPen canvas is nullptr");
1402 return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
1403 }
1404
1405 napi_value argv[ARGC_ONE] = {nullptr};
1406 CHECK_PARAM_NUMBER_WITHOUT_OPTIONAL_PARAMS(argv, ARGC_ONE);
1407
1408 JsPen* jsPen = nullptr;
1409 GET_UNWRAP_PARAM(ARGC_ZERO, jsPen);
1410
1411 if (jsPen->GetPen() == nullptr) {
1412 ROSEN_LOGE("JsCanvas::AttachPen pen is nullptr");
1413 return nullptr;
1414 }
1415 DRAWING_PERFORMANCE_TEST_NAP_RETURN(nullptr);
1416 canvas->AttachPen(*jsPen->GetPen());
1417 return nullptr;
1418 }
1419
AttachBrush(napi_env env,napi_callback_info info)1420 napi_value JsCanvas::AttachBrush(napi_env env, napi_callback_info info)
1421 {
1422 DRAWING_PERFORMANCE_TEST_JS_RETURN(nullptr);
1423 JsCanvas* me = CheckParamsAndGetThis<JsCanvas>(env, info);
1424 if (me == nullptr) {
1425 return nullptr;
1426 }
1427 Canvas* canvas = me->GetCanvas();
1428 if (canvas == nullptr) {
1429 ROSEN_LOGE("JsCanvas::AttachBrush canvas is nullptr");
1430 return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
1431 }
1432
1433 napi_value argv[ARGC_ONE] = {nullptr};
1434 CHECK_PARAM_NUMBER_WITHOUT_OPTIONAL_PARAMS(argv, ARGC_ONE);
1435
1436 JsBrush* jsBrush = nullptr;
1437 GET_UNWRAP_PARAM(ARGC_ZERO, jsBrush);
1438
1439 if (jsBrush->GetBrush() == nullptr) {
1440 ROSEN_LOGE("JsCanvas::AttachBrush brush is nullptr");
1441 return nullptr;
1442 }
1443 DRAWING_PERFORMANCE_TEST_NAP_RETURN(nullptr);
1444 canvas->AttachBrush(*jsBrush->GetBrush());
1445 return nullptr;
1446 }
1447
DetachPen(napi_env env,napi_callback_info info)1448 napi_value JsCanvas::DetachPen(napi_env env, napi_callback_info info)
1449 {
1450 DRAWING_PERFORMANCE_TEST_JS_RETURN(nullptr);
1451 JsCanvas* me = CheckParamsAndGetThis<JsCanvas>(env, info);
1452 if (me == nullptr) {
1453 return nullptr;
1454 }
1455 Canvas* canvas = me->GetCanvas();
1456 if (canvas == nullptr) {
1457 ROSEN_LOGE("JsCanvas::DetachPen canvas is null");
1458 return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
1459 }
1460 DRAWING_PERFORMANCE_TEST_NAP_RETURN(nullptr);
1461 canvas->DetachPen();
1462 return nullptr;
1463 }
1464
DetachBrush(napi_env env,napi_callback_info info)1465 napi_value JsCanvas::DetachBrush(napi_env env, napi_callback_info info)
1466 {
1467 DRAWING_PERFORMANCE_TEST_JS_RETURN(nullptr);
1468 JsCanvas* me = CheckParamsAndGetThis<JsCanvas>(env, info);
1469 if (me == nullptr) {
1470 return nullptr;
1471 }
1472 Canvas* canvas = me->GetCanvas();
1473 if (canvas == nullptr) {
1474 ROSEN_LOGE("JsCanvas::DetachBrush canvas is null");
1475 return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
1476 }
1477 DRAWING_PERFORMANCE_TEST_NAP_RETURN(nullptr);
1478 canvas->DetachBrush();
1479 return nullptr;
1480 }
1481
Skew(napi_env env,napi_callback_info info)1482 napi_value JsCanvas::Skew(napi_env env, napi_callback_info info)
1483 {
1484 JsCanvas* me = CheckParamsAndGetThis<JsCanvas>(env, info);
1485 return (me != nullptr) ? me->OnSkew(env, info) : nullptr;
1486 }
1487
OnSkew(napi_env env,napi_callback_info info)1488 napi_value JsCanvas::OnSkew(napi_env env, napi_callback_info info)
1489 {
1490 if (m_canvas == nullptr) {
1491 ROSEN_LOGE("JsCanvas::OnSkew m_canvas is null");
1492 return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
1493 }
1494
1495 napi_value argv[ARGC_TWO] = {nullptr};
1496 CHECK_PARAM_NUMBER_WITHOUT_OPTIONAL_PARAMS(argv, ARGC_TWO);
1497
1498 double sx = 0.0;
1499 GET_DOUBLE_PARAM(ARGC_ZERO, sx);
1500 double sy = 0.0;
1501 GET_DOUBLE_PARAM(ARGC_ONE, sy);
1502
1503 m_canvas->Shear(sx, sy);
1504 return nullptr;
1505 }
1506
Rotate(napi_env env,napi_callback_info info)1507 napi_value JsCanvas::Rotate(napi_env env, napi_callback_info info)
1508 {
1509 JsCanvas* me = CheckParamsAndGetThis<JsCanvas>(env, info);
1510 return (me != nullptr) ? me->OnRotate(env, info) : nullptr;
1511 }
1512
OnRotate(napi_env env,napi_callback_info info)1513 napi_value JsCanvas::OnRotate(napi_env env, napi_callback_info info)
1514 {
1515 if (m_canvas == nullptr) {
1516 ROSEN_LOGE("JsCanvas::OnRotate m_canvas is null");
1517 return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
1518 }
1519
1520 napi_value argv[ARGC_THREE] = {nullptr};
1521 CHECK_PARAM_NUMBER_WITHOUT_OPTIONAL_PARAMS(argv, ARGC_THREE);
1522
1523 double degree = 0.0;
1524 GET_DOUBLE_PARAM(ARGC_ZERO, degree);
1525 double sx = 0.0;
1526 GET_DOUBLE_PARAM(ARGC_ONE, sx);
1527 double sy = 0.0;
1528 GET_DOUBLE_PARAM(ARGC_TWO, sy);
1529
1530 m_canvas->Rotate(degree, sx, sy);
1531 return nullptr;
1532 }
1533
GetSaveCount(napi_env env,napi_callback_info info)1534 napi_value JsCanvas::GetSaveCount(napi_env env, napi_callback_info info)
1535 {
1536 JsCanvas* me = CheckParamsAndGetThis<JsCanvas>(env, info);
1537 return (me != nullptr) ? me->OnGetSaveCount(env, info) : nullptr;
1538 }
1539
OnGetSaveCount(napi_env env,napi_callback_info info)1540 napi_value JsCanvas::OnGetSaveCount(napi_env env, napi_callback_info info)
1541 {
1542 if (m_canvas == nullptr) {
1543 ROSEN_LOGE("JsCanvas::OnGetSaveCount canvas is null");
1544 return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
1545 }
1546 return CreateJsNumber(env, m_canvas->GetSaveCount());
1547 }
1548
GetWidth(napi_env env,napi_callback_info info)1549 napi_value JsCanvas::GetWidth(napi_env env, napi_callback_info info)
1550 {
1551 JsCanvas* me = CheckParamsAndGetThis<JsCanvas>(env, info);
1552 return (me != nullptr) ? me->OnGetWidth(env, info) : nullptr;
1553 }
1554
OnGetWidth(napi_env env,napi_callback_info info)1555 napi_value JsCanvas::OnGetWidth(napi_env env, napi_callback_info info)
1556 {
1557 if (m_canvas == nullptr) {
1558 ROSEN_LOGE("JsCanvas::OnGetWidth canvas is null");
1559 return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
1560 }
1561 return CreateJsNumber(env, m_canvas->GetWidth());
1562 }
1563
GetHeight(napi_env env,napi_callback_info info)1564 napi_value JsCanvas::GetHeight(napi_env env, napi_callback_info info)
1565 {
1566 JsCanvas* me = CheckParamsAndGetThis<JsCanvas>(env, info);
1567 return (me != nullptr) ? me->OnGetHeight(env, info) : nullptr;
1568 }
1569
OnGetHeight(napi_env env,napi_callback_info info)1570 napi_value JsCanvas::OnGetHeight(napi_env env, napi_callback_info info)
1571 {
1572 if (m_canvas == nullptr) {
1573 ROSEN_LOGE("JsCanvas::OnGetHeight canvas is null");
1574 return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
1575 }
1576 return CreateJsNumber(env, m_canvas->GetHeight());
1577 }
1578
ClipPath(napi_env env,napi_callback_info info)1579 napi_value JsCanvas::ClipPath(napi_env env, napi_callback_info info)
1580 {
1581 JsCanvas* me = CheckParamsAndGetThis<JsCanvas>(env, info);
1582 return (me != nullptr) ? me->OnClipPath(env, info) : nullptr;
1583 }
1584
OnClipPath(napi_env env,napi_callback_info info)1585 napi_value JsCanvas::OnClipPath(napi_env env, napi_callback_info info)
1586 {
1587 if (m_canvas == nullptr) {
1588 ROSEN_LOGE("JsCanvas::OnClipPath m_canvas is nullptr");
1589 return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
1590 }
1591 size_t argc = ARGC_THREE;
1592 napi_value argv[ARGC_THREE] = {nullptr};
1593 CHECK_PARAM_NUMBER_WITH_OPTIONAL_PARAMS(argv, argc, ARGC_ONE, ARGC_THREE);
1594
1595 JsPath* jsPath = nullptr;
1596 GET_UNWRAP_PARAM(ARGC_ZERO, jsPath);
1597
1598 Path* path = jsPath->GetPath();
1599 if (path == nullptr) {
1600 ROSEN_LOGE("JsCanvas::OnClipPath path is nullptr");
1601 return nullptr;
1602 }
1603 if (argc == ARGC_ONE) {
1604 m_canvas->ClipPath(*path);
1605 return nullptr;
1606 }
1607
1608 int32_t jsClipOp = 0;
1609 GET_INT32_CHECK_GE_ZERO_PARAM(ARGC_ONE, jsClipOp);
1610
1611 if (argc == ARGC_TWO) {
1612 m_canvas->ClipPath(*path, static_cast<ClipOp>(jsClipOp));
1613 return nullptr;
1614 }
1615
1616 bool jsDoAntiAlias = false;
1617 GET_BOOLEAN_PARAM(ARGC_TWO, jsDoAntiAlias);
1618
1619 m_canvas->ClipPath(*path, static_cast<ClipOp>(jsClipOp), jsDoAntiAlias);
1620 return nullptr;
1621 }
1622
ClipRegion(napi_env env,napi_callback_info info)1623 napi_value JsCanvas::ClipRegion(napi_env env, napi_callback_info info)
1624 {
1625 JsCanvas* me = CheckParamsAndGetThis<JsCanvas>(env, info);
1626 return (me != nullptr) ? me->OnClipRegion(env, info) : nullptr;
1627 }
1628
OnClipRegion(napi_env env,napi_callback_info info)1629 napi_value JsCanvas::OnClipRegion(napi_env env, napi_callback_info info)
1630 {
1631 if (m_canvas == nullptr) {
1632 ROSEN_LOGE("JsCanvas::OnClipRegion m_canvas is nullptr");
1633 return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
1634 }
1635 size_t argc = ARGC_TWO;
1636 napi_value argv[ARGC_TWO] = {nullptr};
1637 CHECK_PARAM_NUMBER_WITH_OPTIONAL_PARAMS(argv, argc, ARGC_ONE, ARGC_TWO);
1638
1639 JsRegion* jsRegion = nullptr;
1640 GET_UNWRAP_PARAM(ARGC_ZERO, jsRegion);
1641
1642 Region* region = jsRegion->GetRegion();
1643 if (region == nullptr) {
1644 ROSEN_LOGE("JsCanvas::OnClipRegion region is nullptr");
1645 return nullptr;
1646 }
1647 if (argc == ARGC_ONE) {
1648 m_canvas->ClipRegion(*region);
1649 return nullptr;
1650 }
1651
1652 int32_t jsClipOp = 0;
1653 GET_ENUM_PARAM(ARGC_ONE, jsClipOp, 0, static_cast<int32_t>(ClipOp::INTERSECT));
1654
1655 m_canvas->ClipRegion(*region, static_cast<ClipOp>(jsClipOp));
1656 return nullptr;
1657 }
1658
Translate(napi_env env,napi_callback_info info)1659 napi_value JsCanvas::Translate(napi_env env, napi_callback_info info)
1660 {
1661 JsCanvas* me = CheckParamsAndGetThis<JsCanvas>(env, info);
1662 return (me != nullptr) ? me->OnTranslate(env, info) : nullptr;
1663 }
1664
OnTranslate(napi_env env,napi_callback_info info)1665 napi_value JsCanvas::OnTranslate(napi_env env, napi_callback_info info)
1666 {
1667 if (m_canvas == nullptr) {
1668 ROSEN_LOGE("JsCanvas::OnTranslate m_canvas is null");
1669 return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
1670 }
1671
1672 napi_value argv[ARGC_TWO] = {nullptr};
1673 CHECK_PARAM_NUMBER_WITHOUT_OPTIONAL_PARAMS(argv, ARGC_TWO);
1674
1675 double dx = 0.0;
1676 GET_DOUBLE_PARAM(ARGC_ZERO, dx);
1677 double dy = 0.0;
1678 GET_DOUBLE_PARAM(ARGC_ONE, dy);
1679
1680 m_canvas->Translate(dx, dy);
1681 return nullptr;
1682 }
1683
Save(napi_env env,napi_callback_info info)1684 napi_value JsCanvas::Save(napi_env env, napi_callback_info info)
1685 {
1686 JsCanvas* me = CheckParamsAndGetThis<JsCanvas>(env, info);
1687 return (me != nullptr) ? me->OnSave(env, info) : nullptr;
1688 }
1689
OnSave(napi_env env,napi_callback_info info)1690 napi_value JsCanvas::OnSave(napi_env env, napi_callback_info info)
1691 {
1692 if (m_canvas == nullptr) {
1693 ROSEN_LOGE("JsCanvas::OnSave canvas is null");
1694 return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
1695 }
1696 return CreateJsNumber(env, m_canvas->Save());
1697 }
1698
SaveLayer(napi_env env,napi_callback_info info)1699 napi_value JsCanvas::SaveLayer(napi_env env, napi_callback_info info)
1700 {
1701 JsCanvas* me = CheckParamsAndGetThis<JsCanvas>(env, info);
1702 return (me != nullptr) ? me->OnSaveLayer(env, info) : nullptr;
1703 }
1704
OnSaveLayer(napi_env env,napi_callback_info info)1705 napi_value JsCanvas::OnSaveLayer(napi_env env, napi_callback_info info)
1706 {
1707 if (m_canvas == nullptr) {
1708 ROSEN_LOGE("JsCanvas::OnSaveLayer canvas is null");
1709 return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
1710 }
1711 size_t argc = ARGC_TWO;
1712 napi_value argv[ARGC_TWO] = {nullptr};
1713 CHECK_PARAM_NUMBER_WITH_OPTIONAL_PARAMS(argv, argc, ARGC_ZERO, ARGC_TWO);
1714
1715 uint32_t ret = 0;
1716 if (argc == ARGC_ZERO) {
1717 ret = m_canvas->GetSaveCount();
1718 m_canvas->SaveLayer(SaveLayerOps());
1719 return CreateJsNumber(env, ret);
1720 }
1721
1722 napi_valuetype valueType = napi_undefined;
1723 if (napi_typeof(env, argv[ARGC_ZERO], &valueType) != napi_ok ||
1724 (valueType != napi_null && valueType != napi_object)) {
1725 return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Incorrect OnSaveLayer parameter0 type.");
1726 }
1727 Drawing::Rect* drawingRectPtr = nullptr;
1728 double ltrb[ARGC_FOUR] = {0};
1729 if (valueType == napi_object) {
1730 if (!ConvertFromJsRect(env, argv[ARGC_ZERO], ltrb, ARGC_FOUR)) {
1731 return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM,
1732 "Incorrect parameter0 type. The type of left, top, right and bottom must be number.");
1733 }
1734 drawingRectPtr = new Drawing::Rect(ltrb[ARGC_ZERO], ltrb[ARGC_ONE], ltrb[ARGC_TWO], ltrb[ARGC_THREE]);
1735 }
1736
1737 if (argc == ARGC_ONE) {
1738 ret = m_canvas->GetSaveCount();
1739 m_canvas->SaveLayer(SaveLayerOps(drawingRectPtr, nullptr));
1740 if (drawingRectPtr != nullptr) {
1741 delete drawingRectPtr;
1742 }
1743 return CreateJsNumber(env, ret);
1744 }
1745
1746 if (napi_typeof(env, argv[ARGC_ONE], &valueType) != napi_ok ||
1747 (valueType != napi_null && valueType != napi_object)) {
1748 if (drawingRectPtr != nullptr) {
1749 delete drawingRectPtr;
1750 }
1751 return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Incorrect OnSaveLayer parameter1 type.");
1752 }
1753 Drawing::Brush* drawingBrushPtr = nullptr;
1754 if (valueType == napi_object) {
1755 JsBrush* jsBrush = nullptr;
1756 napi_status status = napi_unwrap(env, argv[ARGC_ONE], reinterpret_cast<void**>(&jsBrush));
1757 if (status != napi_ok || jsBrush == nullptr) {
1758 if (drawingRectPtr != nullptr) {
1759 delete drawingRectPtr;
1760 }
1761 return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM,
1762 std::string("Incorrect ") + __FUNCTION__ + " parameter" + std::to_string(ARGC_ONE) + " type.");
1763 }
1764 drawingBrushPtr = jsBrush->GetBrush();
1765 }
1766 ret = m_canvas->GetSaveCount();
1767 SaveLayerOps saveLayerOps = SaveLayerOps(drawingRectPtr, drawingBrushPtr);
1768 m_canvas->SaveLayer(saveLayerOps);
1769 if (drawingRectPtr != nullptr) {
1770 delete drawingRectPtr;
1771 }
1772 return CreateJsNumber(env, ret);
1773 }
1774
RestoreToCount(napi_env env,napi_callback_info info)1775 napi_value JsCanvas::RestoreToCount(napi_env env, napi_callback_info info)
1776 {
1777 JsCanvas* me = CheckParamsAndGetThis<JsCanvas>(env, info);
1778 return (me != nullptr) ? me->OnRestoreToCount(env, info) : nullptr;
1779 }
1780
OnRestoreToCount(napi_env env,napi_callback_info info)1781 napi_value JsCanvas::OnRestoreToCount(napi_env env, napi_callback_info info)
1782 {
1783 if (m_canvas == nullptr) {
1784 ROSEN_LOGE("JsCanvas::OnRestoreToCount canvas is nullptr");
1785 return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
1786 }
1787
1788 napi_value argv[ARGC_ONE] = {nullptr};
1789 CHECK_PARAM_NUMBER_WITHOUT_OPTIONAL_PARAMS(argv, ARGC_ONE);
1790
1791 int32_t count = 0;
1792 GET_INT32_CHECK_GE_ZERO_PARAM(ARGC_ZERO, count);
1793
1794 m_canvas->RestoreToCount(count);
1795 return nullptr;
1796 }
1797
Restore(napi_env env,napi_callback_info info)1798 napi_value JsCanvas::Restore(napi_env env, napi_callback_info info)
1799 {
1800 JsCanvas* me = CheckParamsAndGetThis<JsCanvas>(env, info);
1801 return (me != nullptr) ? me->OnRestore(env, info) : nullptr;
1802 }
1803
OnRestore(napi_env env,napi_callback_info info)1804 napi_value JsCanvas::OnRestore(napi_env env, napi_callback_info info)
1805 {
1806 if (m_canvas == nullptr) {
1807 ROSEN_LOGE("JsCanvas::OnRestore m_canvas is null");
1808 return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
1809 }
1810 m_canvas->Restore();
1811 return nullptr;
1812 }
1813
ClipRect(napi_env env,napi_callback_info info)1814 napi_value JsCanvas::ClipRect(napi_env env, napi_callback_info info)
1815 {
1816 JsCanvas* me = CheckParamsAndGetThis<JsCanvas>(env, info);
1817 return (me != nullptr) ? me->OnClipRect(env, info) : nullptr;
1818 }
1819
OnClipRect(napi_env env,napi_callback_info info)1820 napi_value JsCanvas::OnClipRect(napi_env env, napi_callback_info info)
1821 {
1822 if (m_canvas == nullptr) {
1823 ROSEN_LOGE("JsCanvas::OnClipRect m_canvas is nullptr");
1824 return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
1825 }
1826 size_t argc = ARGC_THREE;
1827 napi_value argv[ARGC_THREE] = {nullptr};
1828 CHECK_PARAM_NUMBER_WITH_OPTIONAL_PARAMS(argv, argc, ARGC_ONE, ARGC_THREE);
1829
1830 double ltrb[ARGC_FOUR] = {0};
1831 if (!ConvertFromJsRect(env, argv[ARGC_ZERO], ltrb, ARGC_FOUR)) {
1832 return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM,
1833 "Incorrect parameter0 type. The type of left, top, right and bottom must be number.");
1834 }
1835 Drawing::Rect drawingRect = Drawing::Rect(ltrb[ARGC_ZERO], ltrb[ARGC_ONE], ltrb[ARGC_TWO], ltrb[ARGC_THREE]);
1836
1837 if (argc == ARGC_ONE) {
1838 m_canvas->ClipRect(drawingRect);
1839 return nullptr;
1840 }
1841
1842 int32_t clipOpInt = 0;
1843 GET_INT32_CHECK_GE_ZERO_PARAM(ARGC_ONE, clipOpInt);
1844
1845 if (argc == ARGC_TWO) {
1846 m_canvas->ClipRect(drawingRect, static_cast<ClipOp>(clipOpInt));
1847 return nullptr;
1848 }
1849
1850 bool doAntiAlias = false;
1851 GET_BOOLEAN_PARAM(ARGC_TWO, doAntiAlias);
1852
1853 m_canvas->ClipRect(drawingRect, static_cast<ClipOp>(clipOpInt), doAntiAlias);
1854 return nullptr;
1855 }
1856
ClipRoundRect(napi_env env,napi_callback_info info)1857 napi_value JsCanvas::ClipRoundRect(napi_env env, napi_callback_info info)
1858 {
1859 JsCanvas* me = CheckParamsAndGetThis<JsCanvas>(env, info);
1860 return (me != nullptr) ? me->OnClipRoundRect(env, info) : nullptr;
1861 }
1862
OnClipRoundRect(napi_env env,napi_callback_info info)1863 napi_value JsCanvas::OnClipRoundRect(napi_env env, napi_callback_info info)
1864 {
1865 if (m_canvas == nullptr) {
1866 ROSEN_LOGE("JsCanvas::OnClipRoundRect m_canvas is nullptr");
1867 return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
1868 }
1869
1870 size_t argc = ARGC_THREE;
1871 napi_value argv[ARGC_THREE] = {nullptr};
1872 CHECK_PARAM_NUMBER_WITH_OPTIONAL_PARAMS(argv, argc, ARGC_ONE, ARGC_THREE);
1873
1874 JsRoundRect* jsRoundRect = nullptr;
1875 GET_UNWRAP_PARAM(ARGC_ZERO, jsRoundRect);
1876 if (jsRoundRect == nullptr) {
1877 ROSEN_LOGE("JsCanvas::OnDrawRegion jsRoundRect is nullptr");
1878 return nullptr;
1879 }
1880
1881 if (argc == ARGC_ONE) {
1882 m_canvas->ClipRoundRect(jsRoundRect->GetRoundRect());
1883 return nullptr;
1884 }
1885
1886 int32_t clipOpInt = 0;
1887 GET_ENUM_PARAM(ARGC_ONE, clipOpInt, 0, static_cast<int32_t>(ClipOp::INTERSECT));
1888
1889 if (argc == ARGC_TWO) {
1890 m_canvas->ClipRoundRect(jsRoundRect->GetRoundRect(), static_cast<ClipOp>(clipOpInt));
1891 return nullptr;
1892 }
1893
1894 bool doAntiAlias = false;
1895 GET_BOOLEAN_PARAM(ARGC_TWO, doAntiAlias);
1896
1897 m_canvas->ClipRoundRect(jsRoundRect->GetRoundRect(), static_cast<ClipOp>(clipOpInt), doAntiAlias);
1898 return nullptr;
1899 }
1900
SetMatrix(napi_env env,napi_callback_info info)1901 napi_value JsCanvas::SetMatrix(napi_env env, napi_callback_info info)
1902 {
1903 JsCanvas* me = CheckParamsAndGetThis<JsCanvas>(env, info);
1904 return (me != nullptr) ? me->OnSetMatrix(env, info) : nullptr;
1905 }
1906
OnSetMatrix(napi_env env,napi_callback_info info)1907 napi_value JsCanvas::OnSetMatrix(napi_env env, napi_callback_info info)
1908 {
1909 if (m_canvas == nullptr) {
1910 ROSEN_LOGE("JsCanvas::OnSetMatrix canvas is nullptr");
1911 return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
1912 }
1913
1914 napi_value argv[ARGC_ONE] = {nullptr};
1915 CHECK_PARAM_NUMBER_WITHOUT_OPTIONAL_PARAMS(argv, ARGC_ONE);
1916
1917 JsMatrix* jsMatrix = nullptr;
1918 GET_UNWRAP_PARAM(ARGC_ZERO, jsMatrix);
1919
1920 if (jsMatrix->GetMatrix() == nullptr) {
1921 ROSEN_LOGE("JsCanvas::OnSetMatrix matrix is nullptr");
1922 return nullptr;
1923 }
1924
1925 JS_CALL_DRAWING_FUNC(m_canvas->SetMatrix(*jsMatrix->GetMatrix()));
1926 return nullptr;
1927 }
1928
Scale(napi_env env,napi_callback_info info)1929 napi_value JsCanvas::Scale(napi_env env, napi_callback_info info)
1930 {
1931 JsCanvas* me = CheckParamsAndGetThis<JsCanvas>(env, info);
1932 return (me != nullptr) ? me->OnScale(env, info) : nullptr;
1933 }
1934
OnScale(napi_env env,napi_callback_info info)1935 napi_value JsCanvas::OnScale(napi_env env, napi_callback_info info)
1936 {
1937 if (m_canvas == nullptr) {
1938 ROSEN_LOGE("JsCanvas::OnScale canvas is nullptr");
1939 return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
1940 }
1941
1942 napi_value argv[ARGC_TWO] = {nullptr};
1943 CHECK_PARAM_NUMBER_WITHOUT_OPTIONAL_PARAMS(argv, ARGC_TWO);
1944
1945 double sx = 0.0;
1946 GET_DOUBLE_PARAM(ARGC_ZERO, sx);
1947 double sy = 0.0;
1948 GET_DOUBLE_PARAM(ARGC_ONE, sy);
1949
1950 m_canvas->Scale(sx, sy);
1951 return nullptr;
1952 }
1953
ConcatMatrix(napi_env env,napi_callback_info info)1954 napi_value JsCanvas::ConcatMatrix(napi_env env, napi_callback_info info)
1955 {
1956 JsCanvas* me = CheckParamsAndGetThis<JsCanvas>(env, info);
1957 return (me != nullptr) ? me->OnConcatMatrix(env, info) : nullptr;
1958 }
1959
OnConcatMatrix(napi_env env,napi_callback_info info)1960 napi_value JsCanvas::OnConcatMatrix(napi_env env, napi_callback_info info)
1961 {
1962 if (m_canvas == nullptr) {
1963 ROSEN_LOGE("JsCanvas::OnConcatMatrix canvas is nullptr");
1964 return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
1965 }
1966
1967 napi_value argv[ARGC_ONE] = {nullptr};
1968 CHECK_PARAM_NUMBER_WITHOUT_OPTIONAL_PARAMS(argv, ARGC_ONE);
1969
1970 JsMatrix* jsMatrix = nullptr;
1971 GET_UNWRAP_PARAM(ARGC_ZERO, jsMatrix);
1972
1973 if (jsMatrix->GetMatrix() == nullptr) {
1974 ROSEN_LOGE("JsCanvas::OnConcatMatrix matrix is nullptr");
1975 return nullptr;
1976 }
1977
1978 JS_CALL_DRAWING_FUNC(m_canvas->ConcatMatrix(*jsMatrix->GetMatrix()));
1979 return nullptr;
1980 }
1981
IsClipEmpty(napi_env env,napi_callback_info info)1982 napi_value JsCanvas::IsClipEmpty(napi_env env, napi_callback_info info)
1983 {
1984 JsCanvas* me = CheckParamsAndGetThis<JsCanvas>(env, info);
1985 return (me != nullptr) ? me->OnIsClipEmpty(env, info) : nullptr;
1986 }
1987
OnIsClipEmpty(napi_env env,napi_callback_info info)1988 napi_value JsCanvas::OnIsClipEmpty(napi_env env, napi_callback_info info)
1989 {
1990 if (m_canvas == nullptr) {
1991 ROSEN_LOGE("JsCanvas::OnIsClipEmpty canvas is nullptr");
1992 return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
1993 }
1994
1995 return CreateJsValue(env, m_canvas->IsClipEmpty());
1996 }
1997
GetLocalClipBounds(napi_env env,napi_callback_info info)1998 napi_value JsCanvas::GetLocalClipBounds(napi_env env, napi_callback_info info)
1999 {
2000 JsCanvas* me = CheckParamsAndGetThis<JsCanvas>(env, info);
2001 return (me != nullptr) ? me->OnGetLocalClipBounds(env, info) : nullptr;
2002 }
2003
OnGetLocalClipBounds(napi_env env,napi_callback_info info)2004 napi_value JsCanvas::OnGetLocalClipBounds(napi_env env, napi_callback_info info)
2005 {
2006 if (m_canvas == nullptr) {
2007 ROSEN_LOGE("JsCanvas::OnGetLocalClipBounds canvas is nullptr");
2008 return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
2009 }
2010
2011 Rect rect = m_canvas->GetLocalClipBounds();
2012 std::shared_ptr<Rect> rectPtr = std::make_shared<Rect>(rect.GetLeft(),
2013 rect.GetTop(), rect.GetRight(), rect.GetBottom());
2014
2015 return GetRectAndConvertToJsValue(env, rectPtr);
2016 }
2017
GetCanvas()2018 Canvas* JsCanvas::GetCanvas()
2019 {
2020 return m_canvas;
2021 }
2022
ResetCanvas()2023 void JsCanvas::ResetCanvas()
2024 {
2025 m_canvas = nullptr;
2026 }
2027
ClipCanvas(float width,float height)2028 void JsCanvas::ClipCanvas(float width, float height)
2029 {
2030 if (m_canvas) {
2031 Rect rect(0, 0, width, height);
2032 JS_CALL_DRAWING_FUNC(m_canvas->ClipRect(rect));
2033 }
2034 }
2035
SaveCanvas()2036 void JsCanvas::SaveCanvas()
2037 {
2038 if (m_canvas) {
2039 JS_CALL_DRAWING_FUNC(m_canvas->Save());
2040 }
2041 }
2042
RestoreCanvas()2043 void JsCanvas::RestoreCanvas()
2044 {
2045 if (m_canvas) {
2046 JS_CALL_DRAWING_FUNC(m_canvas->Restore());
2047 }
2048 }
2049
DrawImageRect(napi_env env,napi_callback_info info)2050 napi_value JsCanvas::DrawImageRect(napi_env env, napi_callback_info info)
2051 {
2052 JsCanvas* me = CheckParamsAndGetThis<JsCanvas>(env, info);
2053 return (me != nullptr) ? me->OnDrawImageRect(env, info) : nullptr;
2054 }
2055
OnDrawImageRect(napi_env env,napi_callback_info info)2056 napi_value JsCanvas::OnDrawImageRect(napi_env env, napi_callback_info info)
2057 {
2058 #ifdef ROSEN_OHOS
2059 if (m_canvas == nullptr) {
2060 ROSEN_LOGE("JsCanvas::OnDrawImageRect canvas is nullptr");
2061 return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
2062 }
2063
2064 size_t argc = ARGC_THREE;
2065 napi_value argv[ARGC_THREE] = {nullptr};
2066 CHECK_PARAM_NUMBER_WITH_OPTIONAL_PARAMS(argv, argc, ARGC_TWO, ARGC_THREE);
2067
2068 PixelMapNapi* pixelMapNapi = nullptr;
2069 GET_UNWRAP_PARAM(ARGC_ZERO, pixelMapNapi); // arg #0: pixelmap/image
2070 auto pixel = pixelMapNapi->GetPixelNapiInner();
2071 if (pixel == nullptr) {
2072 ROSEN_LOGE("JsCanvas::OnDrawImageRect pixelmap GetPixelNapiInner is nullptr");
2073 return nullptr;
2074 }
2075
2076 double ltrb[ARGC_FOUR] = {0};
2077 if (!ConvertFromJsRect(env, argv[ARGC_ONE], ltrb, ARGC_FOUR)) { // arg #1: dstRect
2078 return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM,
2079 "Incorrect rect dst parameter type. The type of left, top, right and bottom must be number.");
2080 }
2081 Drawing::Rect dstRect = Drawing::Rect(ltrb[ARGC_ZERO], ltrb[ARGC_ONE], ltrb[ARGC_TWO], ltrb[ARGC_THREE]);
2082
2083 if (argc == ARGC_TWO) { // without (optional) arg #2: samplingOptions
2084 DRAWING_PERFORMANCE_TEST_NAP_RETURN(nullptr);
2085 if (m_canvas->GetDrawingType() == Drawing::DrawingType::RECORDING) {
2086 ExtendRecordingCanvas* canvas_ = reinterpret_cast<ExtendRecordingCanvas*>(m_canvas);
2087 Drawing::Rect srcRect(0, 0, pixel->GetWidth(), pixel->GetHeight());
2088 canvas_->DrawPixelMapRect(pixel, srcRect, dstRect, Drawing::SamplingOptions(),
2089 SrcRectConstraint::FAST_SRC_RECT_CONSTRAINT);
2090 return nullptr;
2091 }
2092 std::shared_ptr<Drawing::Image> image = ExtractDrawingImage(pixel);
2093 if (image == nullptr) {
2094 ROSEN_LOGE("JsCanvas::OnDrawImageRect image is nullptr");
2095 return nullptr;
2096 }
2097 m_canvas->DrawImageRect(*image, dstRect, Drawing::SamplingOptions());
2098 } else {
2099 JsSamplingOptions* jsSamplingOptions = nullptr;
2100 GET_UNWRAP_PARAM(ARGC_TWO, jsSamplingOptions); // (optional) arg #2: samplingOptions
2101 std::shared_ptr<SamplingOptions> samplingOptions = jsSamplingOptions->GetSamplingOptions();
2102 if (samplingOptions == nullptr) {
2103 ROSEN_LOGE("JsCanvas::OnDrawImageRect get samplingOptions is nullptr");
2104 return nullptr;
2105 }
2106 if (m_canvas->GetDrawingType() == Drawing::DrawingType::RECORDING) {
2107 ExtendRecordingCanvas* canvas_ = reinterpret_cast<ExtendRecordingCanvas*>(m_canvas);
2108 Drawing::Rect srcRect(0, 0, pixel->GetWidth(), pixel->GetHeight());
2109 canvas_->DrawPixelMapRect(pixel, srcRect, dstRect, *samplingOptions.get(),
2110 SrcRectConstraint::FAST_SRC_RECT_CONSTRAINT);
2111 return nullptr;
2112 }
2113 DRAWING_PERFORMANCE_TEST_NAP_RETURN(nullptr);
2114 std::shared_ptr<Drawing::Image> image = ExtractDrawingImage(pixel);
2115 if (image == nullptr) {
2116 ROSEN_LOGE("JsCanvas::OnDrawImageRect image is nullptr");
2117 return nullptr;
2118 }
2119 m_canvas->DrawImageRect(*image, dstRect, *samplingOptions.get());
2120 }
2121 if (mPixelMap_ != nullptr) {
2122 mPixelMap_->MarkDirty();
2123 }
2124 #endif
2125 return nullptr;
2126 }
2127
DrawImageRectWithSrc(napi_env env,napi_callback_info info)2128 napi_value JsCanvas::DrawImageRectWithSrc(napi_env env, napi_callback_info info)
2129 {
2130 JsCanvas* me = CheckParamsAndGetThis<JsCanvas>(env, info);
2131 return (me != nullptr) ? me->OnDrawImageRectWithSrc(env, info) : nullptr;
2132 }
2133
2134 #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)2135 static napi_value OnDrawingImageRectWithSrc(napi_env env, napi_value* argv, size_t argc, Canvas& canvas,
2136 const std::shared_ptr<Media::PixelMap> pixel,
2137 const Rect& srcRect, const Rect& dstRect)
2138 {
2139 if (argc == ARGC_THREE) { // without optional arg #3 (samplingOptions) and arg #4 (constraint):
2140 DRAWING_PERFORMANCE_TEST_NAP_RETURN(nullptr);
2141 if (canvas.GetDrawingType() == Drawing::DrawingType::RECORDING) {
2142 ExtendRecordingCanvas* canvas_ = reinterpret_cast<ExtendRecordingCanvas*>(&canvas);
2143 canvas_->DrawPixelMapRect(pixel, srcRect, dstRect, Drawing::SamplingOptions());
2144 return nullptr;
2145 }
2146 std::shared_ptr<Drawing::Image> image = ExtractDrawingImage(pixel);
2147 if (image == nullptr) {
2148 ROSEN_LOGE("JsCanvas::OnDrawImageRectWithSrc image is nullptr");
2149 return nullptr;
2150 }
2151 canvas.DrawImageRect(*image, srcRect, dstRect, Drawing::SamplingOptions());
2152 } else if (argc == ARGC_FOUR) { // without optional arg #4 (constraint):
2153 JsSamplingOptions* jsSamplingOptions = nullptr;
2154 GET_UNWRAP_PARAM(ARGC_THREE, jsSamplingOptions);
2155 std::shared_ptr<SamplingOptions> samplingOptions = jsSamplingOptions->GetSamplingOptions();
2156 if (samplingOptions == nullptr) {
2157 return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Incorrect samplingOptions parameter.");
2158 }
2159 if (canvas.GetDrawingType() == Drawing::DrawingType::RECORDING) {
2160 ExtendRecordingCanvas* canvas_ = reinterpret_cast<ExtendRecordingCanvas*>(&canvas);
2161 canvas_->DrawPixelMapRect(pixel, srcRect, dstRect, *samplingOptions.get());
2162 return nullptr;
2163 }
2164 DRAWING_PERFORMANCE_TEST_NAP_RETURN(nullptr);
2165 std::shared_ptr<Drawing::Image> image = ExtractDrawingImage(pixel);
2166 if (image == nullptr) {
2167 ROSEN_LOGE("JsCanvas::OnDrawImageRectWithSrc image is nullptr");
2168 return nullptr;
2169 }
2170 canvas.DrawImageRect(*image, srcRect, dstRect, *samplingOptions.get());
2171 } else if (argc == ARGC_FIVE) { // with optional arg #3 (samplingOptions) and arg #4 (constraint):
2172 JsSamplingOptions* jsSamplingOptions = nullptr;
2173 GET_UNWRAP_PARAM(ARGC_THREE, jsSamplingOptions);
2174 std::shared_ptr<SamplingOptions> samplingOptions = jsSamplingOptions->GetSamplingOptions();
2175 if (samplingOptions == nullptr) {
2176 return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Incorrect samplingOptions parameter.");
2177 }
2178 int32_t constraint = 0;
2179 GET_ENUM_PARAM(ARGC_FOUR,
2180 constraint,
2181 static_cast<int32_t>(SrcRectConstraint::STRICT_SRC_RECT_CONSTRAINT),
2182 static_cast<int32_t>(SrcRectConstraint::FAST_SRC_RECT_CONSTRAINT));
2183 if (canvas.GetDrawingType() == Drawing::DrawingType::RECORDING) {
2184 ExtendRecordingCanvas* canvas_ = reinterpret_cast<ExtendRecordingCanvas*>(&canvas);
2185 canvas_->DrawPixelMapRect(pixel, srcRect, dstRect,
2186 *samplingOptions.get(), static_cast<SrcRectConstraint>(constraint));
2187 return nullptr;
2188 }
2189 DRAWING_PERFORMANCE_TEST_NAP_RETURN(nullptr);
2190 std::shared_ptr<Drawing::Image> image = ExtractDrawingImage(pixel);
2191 if (image == nullptr) {
2192 ROSEN_LOGE("JsCanvas::OnDrawImageRectWithSrc image is nullptr");
2193 return nullptr;
2194 }
2195 canvas.DrawImageRect(*image, srcRect, dstRect,
2196 *samplingOptions.get(), static_cast<SrcRectConstraint>(constraint));
2197 } else { // argc > 5:
2198 return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "More than 5 parameters are not supported");
2199 }
2200 return nullptr;
2201 }
2202 #endif
2203
OnDrawImageRectWithSrc(napi_env env,napi_callback_info info)2204 napi_value JsCanvas::OnDrawImageRectWithSrc(napi_env env, napi_callback_info info)
2205 {
2206 #ifdef ROSEN_OHOS
2207 if (m_canvas == nullptr) {
2208 ROSEN_LOGE("JsCanvas::OnDrawImageRectWithSrc canvas is nullptr");
2209 return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
2210 }
2211
2212 size_t argc = ARGC_FIVE;
2213 napi_value argv[ARGC_FIVE] = {nullptr};
2214 CHECK_PARAM_NUMBER_WITH_OPTIONAL_PARAMS(argv, argc, ARGC_THREE, ARGC_FIVE);
2215
2216 PixelMapNapi* pixelMapNapi = nullptr;
2217 GET_UNWRAP_PARAM(ARGC_ZERO, pixelMapNapi); // arg #0: pixelmap/image
2218 auto pixel = pixelMapNapi->GetPixelNapiInner();
2219 if (pixel == nullptr) {
2220 ROSEN_LOGE("JsCanvas::OnDrawImageRectWithSrc pixelmap GetPixelNapiInner is nullptr");
2221 return nullptr;
2222 }
2223
2224 double ltrb[ARGC_FOUR] = {0};
2225 if (!ConvertFromJsRect(env, argv[ARGC_ONE], ltrb, ARGC_FOUR)) { // arg #1: srcRect
2226 return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM,
2227 "Incorrect rect src parameter type. The type of left, top, right and bottom must be number.");
2228 }
2229 Drawing::Rect srcRect = Drawing::Rect(ltrb[ARGC_ZERO], ltrb[ARGC_ONE], ltrb[ARGC_TWO], ltrb[ARGC_THREE]);
2230
2231 if (!ConvertFromJsRect(env, argv[ARGC_TWO], ltrb, ARGC_FOUR)) { // arg #2: dstRect
2232 return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM,
2233 "Incorrect rect dst parameter type. The type of left, top, right and bottom must be number.");
2234 }
2235 Drawing::Rect dstRect = Drawing::Rect(ltrb[ARGC_ZERO], ltrb[ARGC_ONE], ltrb[ARGC_TWO], ltrb[ARGC_THREE]);
2236
2237 napi_value result = OnDrawingImageRectWithSrc(env, argv, argc, *m_canvas, pixel, srcRect, dstRect);
2238 if (mPixelMap_ != nullptr) {
2239 mPixelMap_->MarkDirty();
2240 }
2241 return result;
2242 #else
2243 return nullptr;
2244 #endif
2245 }
2246
ResetMatrix(napi_env env,napi_callback_info info)2247 napi_value JsCanvas::ResetMatrix(napi_env env, napi_callback_info info)
2248 {
2249 JsCanvas* me = CheckParamsAndGetThis<JsCanvas>(env, info);
2250 return (me != nullptr) ? me->OnResetMatrix(env, info) : nullptr;
2251 }
2252
OnResetMatrix(napi_env env,napi_callback_info info)2253 napi_value JsCanvas::OnResetMatrix(napi_env env, napi_callback_info info)
2254 {
2255 if (m_canvas == nullptr) {
2256 ROSEN_LOGE("JsCanvas::OnResetMatrix m_canvas is null");
2257 return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
2258 }
2259 m_canvas->ResetMatrix();
2260 return nullptr;
2261 }
2262
2263 } // namespace Drawing
2264 } // namespace OHOS::Rosen
2265