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 #if defined(ROSEN_OHOS) || defined(ROSEN_ARKUI_X)
17 #include <regex>
18 #include "ability.h"
19 #endif
20
21 #include "js_drawing_utils.h"
22 #include "js_tool.h"
23
24
25 namespace OHOS::Rosen {
26 namespace Drawing {
27 thread_local napi_ref JsTool::constructor_ = nullptr;
28 const std::string CLASS_NAME = "Tool";
29 #if defined(ROSEN_OHOS) || defined(ROSEN_ARKUI_X)
30 const int32_t GLOBAL_ERROR = 10000;
31 // The expectLength of regex match of "rgb(255,0,0)". The elements:0 is the string, 1 is r, 2 is g, 3 is b.
32 constexpr uint32_t RGB_SUB_MATCH_SIZE = 4;
33 // The expectLength of regex match of "rgba(255,0,0,0.5)". The elements:0 is the string, 1 is r, 2 is g, 3 is b, 4 is a.
34 constexpr uint32_t RGBA_SUB_MATCH_SIZE = 7;
35 // The length of standard color, the length of str is must like "FF00FF00" which length is 8.
36 constexpr uint32_t COLOR_STRING_SIZE_STANDARD = 8;
37 constexpr uint32_t COLOR_OFFSET_GREEN = 8;
38 constexpr uint32_t COLOR_OFFSET_RED = 16;
39 // The string will be parsed in hexadecimal format during the conversion
40 constexpr uint32_t COLOR_STRING_FORMAT = 16;
41 constexpr uint32_t COLOR_OFFSET_ALPHA = 24;
42 constexpr uint32_t COLOR_DEFAULT_ALPHA = 0xFF000000;
43 const std::vector<size_t> EXPECT_MAGIC_COLOR_LENGTHS = {7, 9};
44 const std::vector<size_t> EXPECT_MAGIC_MINI_COLOR_LENGTHS = {4, 5};
45 const std::regex COLOR_WITH_RGB(R"(rgb\(([+]?[0-9]+)\,([+]?[0-9]+)\,([+]?[0-9]+)\))", std::regex::icase);
46 const std::regex COLOR_WITH_RGBA(R"(rgba\(([+]?[0-9]+)\,([+]?[0-9]+)\,([+]?[0-9]+)\,((0|1)(\.\d+)?)\))",
47 std::regex::icase);
48 const std::regex HEX_PATTERN("^[0-9a-fA-F]+$");
49 #endif
Init(napi_env env,napi_value exportObj)50 napi_value JsTool::Init(napi_env env, napi_value exportObj)
51 {
52 napi_property_descriptor properties[] = {
53 DECLARE_NAPI_STATIC_FUNCTION("makeColorFromResourceColor", JsTool::makeColorFromResourceColor),
54 };
55
56 napi_value constructor = nullptr;
57 napi_status status = napi_define_class(env, CLASS_NAME.c_str(), NAPI_AUTO_LENGTH, Constructor, nullptr,
58 sizeof(properties) / sizeof(properties[0]), properties, &constructor);
59 if (status != napi_ok) {
60 ROSEN_LOGE("JsTool::Init failed to define Tool class");
61 return nullptr;
62 }
63
64 status = napi_create_reference(env, constructor, 1, &constructor_);
65 if (status != napi_ok) {
66 ROSEN_LOGE("JsTool::Init Failed to create reference of constructor");
67 return nullptr;
68 }
69
70 status = napi_set_named_property(env, exportObj, CLASS_NAME.c_str(), constructor);
71 if (status != napi_ok) {
72 ROSEN_LOGE("JsTool::Init Failed to set constructor");
73 return nullptr;
74 }
75
76 return exportObj;
77 }
78
Constructor(napi_env env,napi_callback_info info)79 napi_value JsTool::Constructor(napi_env env, napi_callback_info info)
80 {
81 size_t argCount = 0;
82 napi_value jsThis = nullptr;
83 napi_status status = napi_get_cb_info(env, info, &argCount, nullptr, &jsThis, nullptr);
84 if (status != napi_ok) {
85 ROSEN_LOGE("JsTool::Constructor failed to napi_get_cb_info");
86 return nullptr;
87 }
88
89 JsTool* jsTool = new JsTool();
90 if (jsTool == nullptr) {
91 ROSEN_LOGE("JsTool::Constructor jsTool is nullptr");
92 return nullptr;
93 }
94
95 status = napi_wrap(env, jsThis, jsTool, JsTool::Destructor, nullptr, nullptr);
96 if (status != napi_ok) {
97 delete jsTool;
98 ROSEN_LOGE("JsTool::Constructor Failed to wrap native instance");
99 return nullptr;
100 }
101 return jsThis;
102 }
103
Destructor(napi_env env,void * nativeObject,void * finalize)104 void JsTool::Destructor(napi_env env, void *nativeObject, void *finalize)
105 {
106 (void)finalize;
107 if (nativeObject != nullptr) {
108 JsTool *napi = reinterpret_cast<JsTool *>(nativeObject);
109 delete napi;
110 }
111 }
112
JsTool()113 JsTool::JsTool() {}
114
~JsTool()115 JsTool::~JsTool() {}
116
makeColorFromResourceColor(napi_env env,napi_callback_info info)117 napi_value JsTool::makeColorFromResourceColor(napi_env env, napi_callback_info info)
118 {
119 #if defined(ROSEN_OHOS) || defined(ROSEN_ARKUI_X)
120 size_t argc = ARGC_ONE;
121 napi_value argv[ARGC_ONE] = {nullptr};
122 CHECK_PARAM_NUMBER_WITH_OPTIONAL_PARAMS(argv, argc, ARGC_ONE, ARGC_ONE);
123
124 uint32_t colorNumber = 0;
125 if (!GetResourceColor(env, argv[ARGC_ZERO], colorNumber)) {
126 ROSEN_LOGE("JsTool::makeColorFromResourceColor failed to get colorNumber!");
127 return nullptr;
128 }
129
130 napi_value objColor = nullptr;
131 napi_create_object(env, &objColor);
132 if (objColor == nullptr) {
133 ROSEN_LOGE("JsTool::makeColorFromResourceColor failed to create color!");
134 return nullptr;
135 }
136
137 napi_set_named_property(env, objColor, "alpha", CreateJsNumber(env, (colorNumber >> COLOR_OFFSET_ALPHA) & 0xFF));
138 napi_set_named_property(env, objColor, "red", CreateJsNumber(env, (colorNumber >> COLOR_OFFSET_RED) & 0xFF));
139 napi_set_named_property(env, objColor, "green", CreateJsNumber(env, (colorNumber >> COLOR_OFFSET_GREEN) & 0xFF));
140 napi_set_named_property(env, objColor, "blue", CreateJsNumber(env, colorNumber & 0xFF));
141
142 return objColor;
143 #else
144 return nullptr;
145 #endif
146 }
147
148 #if defined(ROSEN_OHOS) || defined(ROSEN_ARKUI_X)
GetParamLen(napi_env env,napi_value param)149 size_t JsTool::GetParamLen(napi_env env, napi_value param)
150 {
151 size_t buffSize = 0;
152 napi_status status = napi_get_value_string_utf8(env, param, nullptr, 0, &buffSize);
153 if (status != napi_ok || buffSize == 0) {
154 return 0;
155 }
156 return buffSize;
157 }
158
GetResourceManager()159 std::shared_ptr<Global::Resource::ResourceManager> JsTool::GetResourceManager()
160 {
161 #ifdef ROSEN_OHOS
162 std::shared_ptr<AbilityRuntime::ApplicationContext> context =
163 AbilityRuntime::ApplicationContext::GetApplicationContext();
164 #else
165 std::shared_ptr<AbilityRuntime::Platform::ApplicationContext> context =
166 AbilityRuntime::Platform::ApplicationContext::GetApplicationContext();
167 #endif
168 if (context == nullptr) {
169 ROSEN_LOGE("JsTool::Failed to get application context");
170 return nullptr;
171 }
172 auto resourceManager = context->GetResourceManager();
173 if (resourceManager == nullptr) {
174 ROSEN_LOGE("JsTool::Failed to get resource manager");
175 return nullptr;
176 }
177 return resourceManager;
178 }
179
GetResourceInfo(napi_env env,napi_value value,ResourceInfo & info)180 bool JsTool::GetResourceInfo(napi_env env, napi_value value, ResourceInfo& info)
181 {
182 napi_valuetype valueType = napi_undefined;
183 napi_typeof(env, value, &valueType);
184 if (valueType != napi_object) {
185 ROSEN_LOGE("JsTool::GetResourceInfo the value is not object!");
186 return false;
187 }
188
189 napi_value idNApi = nullptr;
190 napi_value typeNApi = nullptr;
191 napi_value paramsNApi = nullptr;
192 napi_get_named_property(env, value, "id", &idNApi);
193 napi_get_named_property(env, value, "type", &typeNApi);
194 napi_get_named_property(env, value, "params", ¶msNApi);
195
196 napi_typeof(env, idNApi, &valueType);
197 if (valueType != napi_number) {
198 ROSEN_LOGE("JsTool::GetResourceInfo id is not number!");
199 return false;
200 }
201 napi_get_value_int32(env, idNApi, &info.resId);
202
203 napi_typeof(env, typeNApi, &valueType);
204 if (valueType != napi_number) {
205 ROSEN_LOGE("JsTool::GetResourceInfo type is not number!");
206 return false;
207 }
208 napi_get_value_int32(env, typeNApi, &info.type);
209
210 return GetResourceInfoParams(env, info, paramsNApi);
211 }
212
GetResourceInfoParams(napi_env env,ResourceInfo & info,napi_value paramsNApi)213 bool JsTool::GetResourceInfoParams(napi_env env, ResourceInfo& info, napi_value paramsNApi)
214 {
215 napi_valuetype valueType = napi_undefined;
216 bool isArray = false;
217 if (napi_is_array(env, paramsNApi, &isArray) != napi_ok) {
218 ROSEN_LOGE("JsTool::Failed to get array type");
219 return false;
220 }
221 if (!isArray) {
222 ROSEN_LOGE("JsTool::Invalid array type");
223 return false;
224 }
225
226 // Here we use 'for' to get all params
227 uint32_t arrayLength = 0;
228 napi_get_array_length(env, paramsNApi, &arrayLength);
229 for (uint32_t i = 0; i < arrayLength; i++) {
230 size_t ret = 0;
231 napi_value indexValue = nullptr;
232 napi_get_element(env, paramsNApi, i, &indexValue);
233 napi_typeof(env, indexValue, &valueType);
234 if (valueType == napi_string) {
235 size_t strlen = GetParamLen(env, indexValue) + 1;
236 std::unique_ptr<char[]> indexStr = std::make_unique<char[]>(strlen);
237 napi_get_value_string_utf8(env, indexValue, indexStr.get(), strlen, &ret);
238 info.params.emplace_back(indexStr.get());
239 } else if (valueType == napi_number) {
240 int32_t num = 0;
241 napi_get_value_int32(env, indexValue, &num);
242 info.params.emplace_back(std::to_string(num));
243 } else {
244 ROSEN_LOGE("JsTool::Invalid value type %{public}d", valueType);
245 return false;
246 }
247 }
248
249 return true;
250 }
251
GetResourceRawFileDataBuffer(std::unique_ptr<uint8_t[]> && buffer,size_t & len,ResourceInfo & info)252 bool JsTool::GetResourceRawFileDataBuffer(std::unique_ptr<uint8_t[]>&& buffer, size_t& len, ResourceInfo& info)
253 {
254 auto resourceManager = GetResourceManager();
255 if (resourceManager == nullptr) {
256 ROSEN_LOGE("JsTool::Failed to get resourceManager, resourceManager is nullptr");
257 return false;
258 }
259 if (info.type != static_cast<int32_t>(ResourceType::RAWFILE)) {
260 ROSEN_LOGE("JsTool::Invalid resource type %{public}d", info.type);
261 return false;
262 }
263
264 int32_t state = 0;
265
266 if (info.params.empty()) {
267 ROSEN_LOGE("JsTool::Failed to get RawFile resource, RawFile is null");
268 return false;
269 }
270
271 state = resourceManager->GetRawFileFromHap(info.params[0], len, buffer);
272 if (state >= GLOBAL_ERROR || state < 0) {
273 ROSEN_LOGE("JsTool::Failed to get Rawfile buffer");
274 return false;
275 }
276 return true;
277 }
278
GetColorNumberResult(uint32_t origin)279 uint32_t JsTool::GetColorNumberResult(uint32_t origin)
280 {
281 uint32_t result = origin;
282 if ((origin >> COLOR_OFFSET_ALPHA) == 0) {
283 result = origin | COLOR_DEFAULT_ALPHA;
284 }
285 return result;
286 }
287
FastCheckColorType(const std::string & colorStr,const std::string & expectPrefix,const std::vector<size_t> & expectLengths)288 bool JsTool::FastCheckColorType(const std::string& colorStr, const std::string& expectPrefix,
289 const std::vector<size_t>& expectLengths)
290 {
291 // Check whether the beginning of colorStr is expectPrefix
292 // and whether the length of colorStr is in expectLengths.
293 if (colorStr.rfind(expectPrefix, 0) != 0) {
294 return false;
295 }
296 // if expectLengths is null that we do not check length.
297 if (expectLengths.size() == 0) {
298 return true;
299 }
300 return std::find(expectLengths.begin(), expectLengths.end(), colorStr.size()) != expectLengths.end();
301 }
302
HandleIncorrectColor(const std::string & newColorStr)303 uint32_t JsTool::HandleIncorrectColor(const std::string& newColorStr)
304 {
305 errno = 0;
306 char* end = nullptr;
307 uint32_t value = strtoul(newColorStr.c_str(), &end, COLOR_STRING_FORMAT);
308 if (errno == ERANGE) {
309 ROSEN_LOGE("JsTool::HandleIncorrectColor %{public}s is out of range.", newColorStr.c_str());
310 }
311 if (value == 0 && end == newColorStr.c_str()) {
312 ROSEN_LOGE("JsTool::HandleIncorrectColor input can not be converted to number, use default :0x0");
313 }
314 return value;
315 }
316
HandleRGBValue(int value,int & result)317 bool JsTool::HandleRGBValue(int value, int& result)
318 {
319 if (value < 0) {
320 return false;
321 }
322 result = value > Color::RGB_MAX ? Color::RGB_MAX : value;
323 return true;
324 }
325
IsOpacityValid(double value)326 bool JsTool::IsOpacityValid(double value)
327 {
328 return value >= 0 && value <= 1.0;
329 }
330
MatchColorWithMagic(std::string & colorStr,uint32_t & result)331 bool JsTool::MatchColorWithMagic(std::string& colorStr, uint32_t& result)
332 {
333 // This function we match string like "#FF0000" or "#FF0000FF" to get hexnumber
334 // Check whether the beginning of the string is "#" and whether the length of the string is vaild.
335 if (!FastCheckColorType(colorStr, "#", EXPECT_MAGIC_COLOR_LENGTHS)) {
336 ROSEN_LOGE("JsTool::MatchColorWithMagic colorString is invalid");
337 return false;
338 }
339 // Remove "#"
340 colorStr.erase(0, 1);
341
342 // Check whether the remaining part of the string is hexnumber
343 if (!std::regex_match(colorStr, HEX_PATTERN)) {
344 ROSEN_LOGE("JsTool::MatchColorWithMagic colorString is invalid hexnub");
345 return false;
346 }
347
348 result = HandleIncorrectColor(colorStr);
349 // If string is "#FF0000" that has not Alpha, set Alpha is "FF"
350 if (colorStr.length() < COLOR_STRING_SIZE_STANDARD) {
351 result |= COLOR_DEFAULT_ALPHA;
352 }
353 return true;
354 }
355
MatchColorWithMagicMini(std::string & colorStr,uint32_t & result)356 bool JsTool::MatchColorWithMagicMini(std::string& colorStr, uint32_t& result)
357 {
358 // This function we match string like "#FF0000" or "#FF0000FF" to get hexnumber
359 // Check whether the beginning of the string is "#" and whether the length of the string is vaild.
360 if (!FastCheckColorType(colorStr, "#", EXPECT_MAGIC_MINI_COLOR_LENGTHS)) {
361 ROSEN_LOGE("JsTool::MatchColorWithMagicMini colorString is invalid");
362 return false;
363 }
364 // Remove "#"
365 colorStr.erase(0, 1);
366
367 // Check whether the remaining part of the string is hexnumber
368 if (!std::regex_match(colorStr, HEX_PATTERN)) {
369 ROSEN_LOGE("JsTool::MatchColorWithMagicMini colorString is invalid hexnub");
370 return false;
371 }
372
373 // "#F00" is the abbreviation of "#FF0000", every will be used twice to make origin string
374 std::string newColorStr;
375 for (auto& c : colorStr) {
376 newColorStr += c;
377 newColorStr += c;
378 }
379 result = HandleIncorrectColor(newColorStr);
380 // If string is "#FF0000" that has not Alpha, set Alpha is "FF"
381 if (newColorStr.length() < COLOR_STRING_SIZE_STANDARD) {
382 result |= COLOR_DEFAULT_ALPHA;
383 }
384 return true;
385 }
386
MatchColorWithRGB(const std::string & colorStr,uint32_t & result)387 bool JsTool::MatchColorWithRGB(const std::string& colorStr, uint32_t& result)
388 {
389 // This function we match string like "rgb(255,0,0)" to get hexnumber
390 // Check whether the beginning of the string is "rgb(".
391 if (!FastCheckColorType(colorStr, "rgb(", {})) {
392 ROSEN_LOGE("JsTool::MatchColorWithRGB colorString is invalid");
393 return false;
394 }
395
396 // Using regular expressions to obtain the value of RGB
397 std::smatch matches;
398 if (std::regex_match(colorStr, matches, COLOR_WITH_RGB) && matches.size() == RGB_SUB_MATCH_SIZE) {
399 int redInt = 0;
400 int greenInt = 0;
401 int blueInt = 0;
402 if (!HandleRGBValue(std::stoi(matches[ARGC_ONE]), redInt) ||
403 !HandleRGBValue(std::stoi(matches[ARGC_TWO]), greenInt) ||
404 !HandleRGBValue(std::stoi(matches[ARGC_THREE]), blueInt)) {
405 ROSEN_LOGE("JsTool::MatchColorWithRGB colorStringNub is invalid");
406 return false;
407 }
408
409 auto red = static_cast<uint8_t>(redInt);
410 auto green = static_cast<uint8_t>(greenInt);
411 auto blue = static_cast<uint8_t>(blueInt);
412 result = COLOR_DEFAULT_ALPHA | (red << COLOR_OFFSET_RED) | (green << COLOR_OFFSET_GREEN) | blue;
413 return true;
414 }
415 return false;
416 }
417
MatchColorWithRGBA(const std::string & colorStr,uint32_t & result)418 bool JsTool::MatchColorWithRGBA(const std::string& colorStr, uint32_t& result)
419 {
420 // This function we match string like "rgba(255,0,0,0.5)" to get hexnumber
421 // Check whether the beginning of the string is "rgba(".
422 if (!FastCheckColorType(colorStr, "rgba(", {})) {
423 ROSEN_LOGE("JsTool::MatchColorWithRGBA colorString is invalid");
424 return false;
425 }
426
427 // Using regular expressions to obtain the value of RGBA
428 std::smatch matches;
429 if (std::regex_match(colorStr, matches, COLOR_WITH_RGBA) && matches.size() == RGBA_SUB_MATCH_SIZE) {
430 int redInt = 0;
431 int greenInt = 0;
432 int blueInt = 0;
433 auto opacityDouble = std::stod(matches[ARGC_FOUR]);
434 if (!HandleRGBValue(std::stoi(matches[ARGC_ONE]), redInt) ||
435 !HandleRGBValue(std::stoi(matches[ARGC_TWO]), greenInt) ||
436 !HandleRGBValue(std::stoi(matches[ARGC_THREE]), blueInt) ||
437 !IsOpacityValid(opacityDouble)) {
438 ROSEN_LOGE("JsTool::MatchColorWithRGBA colorStringNub is invalid");
439 return false;
440 }
441
442 auto red = static_cast<uint8_t>(redInt);
443 auto green = static_cast<uint8_t>(greenInt);
444 auto blue = static_cast<uint8_t>(blueInt);
445 uint8_t alpha = static_cast<uint8_t>(round(static_cast<double>(opacityDouble) * 0xff));
446 result = (alpha << COLOR_OFFSET_ALPHA) | (red << COLOR_OFFSET_RED) | (green << COLOR_OFFSET_GREEN) | blue;
447 return true;
448 }
449 return false;
450 }
451
GetColorStringResult(std::string colorStr,uint32_t & result)452 bool JsTool::GetColorStringResult(std::string colorStr, uint32_t& result)
453 {
454 if (colorStr.empty()) {
455 ROSEN_LOGE("JsTool::GetColorStringResult string is empty");
456 return false;
457 }
458
459 // e.g: Remove ' ' that change "rgb(255, 0, 0)" to "rgb(255,0,0)"
460 colorStr.erase(std::remove(colorStr.begin(), colorStr.end(), ' '), colorStr.end());
461
462 return (MatchColorWithMagic(colorStr, result) || MatchColorWithMagicMini(colorStr, result) ||
463 MatchColorWithRGB(colorStr, result) || MatchColorWithRGBA(colorStr, result));
464 }
465
GetColorObjectResult(napi_env env,napi_value value,uint32_t & result)466 bool JsTool::GetColorObjectResult(napi_env env, napi_value value, uint32_t& result)
467 {
468 ResourceInfo info;
469 if (!GetResourceInfo(env, value, info)) {
470 ROSEN_LOGE("JsTool::GetColorObjectResult GetResourceInfo failed!");
471 return false;
472 }
473
474 auto resourceManager = GetResourceManager();
475 if (resourceManager == nullptr) {
476 ROSEN_LOGE("JsTool::GetColorObjectResult resourceManager is nullptr!");
477 return false;
478 }
479
480 if (info.type == static_cast<int32_t>(ResourceType::STRING)) {
481 std::string colorStr = "";
482 int32_t state = resourceManager->GetStringById(static_cast<uint32_t>(info.resId), colorStr);
483 if (state >= GLOBAL_ERROR || state < 0) {
484 ROSEN_LOGE("JsTool::GetColorObjectResult failed to get colorString!");
485 return false;
486 }
487 if (!GetColorStringResult(colorStr, result)) {
488 ROSEN_LOGE("JsTool::GetColorObjectResult failed to GetColorStringResult!");
489 return false;
490 }
491 } else if (info.type == static_cast<int32_t>(ResourceType::INTEGER)) {
492 int colorResult = 0;
493 int32_t state = resourceManager->GetIntegerById(static_cast<uint32_t>(info.resId), colorResult);
494 if (state >= GLOBAL_ERROR || state < 0) {
495 ROSEN_LOGE("JsTool::GetColorObjectResult failed to get colorInt!");
496 return false;
497 }
498 result = GetColorNumberResult(colorResult);
499 } else if (info.type == static_cast<int32_t>(ResourceType::COLOR)) {
500 int32_t state = resourceManager->GetColorById(static_cast<uint32_t>(info.resId), result);
501 if (state >= GLOBAL_ERROR || state < 0) {
502 ROSEN_LOGE("JsTool::GetColorObjectResult failed to get colorColor!");
503 return false;
504 }
505 } else {
506 ROSEN_LOGE("JsTool::GetColorObjectResult invalid Resource type!");
507 return false;
508 }
509 return true;
510 }
511
GetResourceColor(napi_env env,napi_value res,uint32_t & result)512 bool JsTool::GetResourceColor(napi_env env, napi_value res, uint32_t& result)
513 {
514 napi_valuetype valueType = napi_undefined;
515 napi_typeof(env, res, &valueType);
516 if (valueType == napi_string) {
517 size_t len = 0;
518 napi_get_value_string_utf8(env, res, nullptr, 0, &len);
519 char* str = new(std::nothrow) char[len + 1];
520 if (!str) {
521 ROSEN_LOGE("JsTool::GetResourceColor memory is insufficient and failed to apply");
522 return false;
523 }
524 napi_get_value_string_utf8(env, res, str, len + 1, &len);
525 std::string colorStr(str, len);
526 delete[] str;
527 if (!GetColorStringResult(colorStr, result)) {
528 ROSEN_LOGE("JsTool::GetResourceColor failed to GetColorStringResult!");
529 return false;
530 }
531 } else if (valueType == napi_number) {
532 uint32_t colorNumber = 0;
533 napi_get_value_uint32(env, res, &colorNumber);
534 result = GetColorNumberResult(colorNumber);
535 } else if (valueType == napi_object) {
536 if (!GetColorObjectResult(env, res, result)) {
537 ROSEN_LOGE("JsTool::GetResourceColor failed to GetColorObjectResult!");
538 return false;
539 }
540 } else {
541 ROSEN_LOGE("JsTool::GetResourceColor invalid ResourceColor type!");
542 return false;
543 }
544 return true;
545 }
546 #endif
547 } // namespace Drawing
548 } // namespace OHOS::Rosen