• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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", &paramsNApi);
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