• 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 #ifdef ROSEN_OHOS
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 #ifdef ROSEN_OHOS
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 #ifdef ROSEN_OHOS
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 #ifdef ROSEN_OHOS
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     std::shared_ptr<AbilityRuntime::ApplicationContext> context =
162         AbilityRuntime::ApplicationContext::GetApplicationContext();
163     if (context == nullptr) {
164         ROSEN_LOGE("JsTool::Failed to get application context");
165         return nullptr;
166     }
167     auto resourceManager = context->GetResourceManager();
168     if (resourceManager == nullptr) {
169         ROSEN_LOGE("JsTool::Failed to get resource manager");
170         return nullptr;
171     }
172     return resourceManager;
173 }
174 
GetResourceInfo(napi_env env,napi_value value,ResourceInfo & info)175 bool JsTool::GetResourceInfo(napi_env env, napi_value value, ResourceInfo& info)
176 {
177     napi_valuetype valueType = napi_undefined;
178     napi_typeof(env, value, &valueType);
179     if (valueType != napi_object) {
180         ROSEN_LOGE("JsTool::GetResourceInfo the value is not object!");
181         return false;
182     }
183 
184     napi_value idNApi = nullptr;
185     napi_value typeNApi = nullptr;
186     napi_value paramsNApi = nullptr;
187     napi_get_named_property(env, value, "id", &idNApi);
188     napi_get_named_property(env, value, "type", &typeNApi);
189     napi_get_named_property(env, value, "params", &paramsNApi);
190 
191     napi_typeof(env, idNApi, &valueType);
192     if (valueType != napi_number) {
193         ROSEN_LOGE("JsTool::GetResourceInfo id is not number!");
194         return false;
195     }
196     napi_get_value_int32(env, idNApi, &info.resId);
197 
198     napi_typeof(env, typeNApi, &valueType);
199     if (valueType != napi_number) {
200         ROSEN_LOGE("JsTool::GetResourceInfo type is not number!");
201         return false;
202     }
203     napi_get_value_int32(env, typeNApi, &info.type);
204 
205     return GetResourceInfoParams(env, info, paramsNApi);
206 }
207 
GetResourceInfoParams(napi_env env,ResourceInfo & info,napi_value paramsNApi)208 bool JsTool::GetResourceInfoParams(napi_env env, ResourceInfo& info, napi_value paramsNApi)
209 {
210     napi_valuetype valueType = napi_undefined;
211     bool isArray = false;
212     if (napi_is_array(env, paramsNApi, &isArray) != napi_ok) {
213         ROSEN_LOGE("JsTool::Failed to get array type");
214         return false;
215     }
216     if (!isArray) {
217         ROSEN_LOGE("JsTool::Invalid array type");
218         return false;
219     }
220 
221     // Here we use 'for' to get all params
222     uint32_t arrayLength = 0;
223     napi_get_array_length(env, paramsNApi, &arrayLength);
224     for (uint32_t i = 0; i < arrayLength; i++) {
225         size_t ret = 0;
226         napi_value indexValue = nullptr;
227         napi_get_element(env, paramsNApi, i, &indexValue);
228         napi_typeof(env, indexValue, &valueType);
229         if (valueType == napi_string) {
230             size_t strlen = GetParamLen(env, indexValue) + 1;
231             std::unique_ptr<char[]> indexStr = std::make_unique<char[]>(strlen);
232             napi_get_value_string_utf8(env, indexValue, indexStr.get(), strlen, &ret);
233             info.params.emplace_back(indexStr.get());
234         } else if (valueType == napi_number) {
235             int32_t num = 0;
236             napi_get_value_int32(env, indexValue, &num);
237             info.params.emplace_back(std::to_string(num));
238         } else {
239             ROSEN_LOGE("JsTool::Invalid value type %{public}d", valueType);
240             return false;
241         }
242     }
243 
244     return true;
245 }
246 
GetResourceRawFileDataBuffer(std::unique_ptr<uint8_t[]> && buffer,size_t & len,ResourceInfo & info)247 bool JsTool::GetResourceRawFileDataBuffer(std::unique_ptr<uint8_t[]>&& buffer, size_t& len, ResourceInfo& info)
248 {
249     auto resourceManager = GetResourceManager();
250     if (resourceManager == nullptr) {
251         ROSEN_LOGE("JsTool::Failed to get resourceManager, resourceManager is nullptr");
252         return false;
253     }
254     if (info.type != static_cast<int32_t>(ResourceType::RAWFILE)) {
255         ROSEN_LOGE("JsTool::Invalid resource type %{public}d", info.type);
256         return false;
257     }
258 
259     int32_t state = 0;
260 
261     if (info.params.empty()) {
262         ROSEN_LOGE("JsTool::Failed to get RawFile resource, RawFile is null");
263         return false;
264     }
265 
266     state = resourceManager->GetRawFileFromHap(info.params[0], len, buffer);
267     if (state >= GLOBAL_ERROR || state < 0) {
268         ROSEN_LOGE("JsTool::Failed to get Rawfile buffer");
269         return false;
270     }
271     return true;
272 }
273 
GetColorNumberResult(uint32_t origin)274 uint32_t JsTool::GetColorNumberResult(uint32_t origin)
275 {
276     uint32_t result = origin;
277     if ((origin >> COLOR_OFFSET_ALPHA) == 0) {
278         result = origin | COLOR_DEFAULT_ALPHA;
279     }
280     return result;
281 }
282 
FastCheckColorType(const std::string & colorStr,const std::string & expectPrefix,const std::vector<size_t> & expectLengths)283 bool JsTool::FastCheckColorType(const std::string& colorStr, const std::string& expectPrefix,
284     const std::vector<size_t>& expectLengths)
285 {
286     // Check whether the beginning of colorStr is expectPrefix
287     // and whether the length of colorStr is in expectLengths.
288     if (colorStr.rfind(expectPrefix, 0) != 0) {
289         return false;
290     }
291     // if expectLengths is null that we do not check length.
292     if (expectLengths.size() == 0) {
293         return true;
294     }
295     return std::find(expectLengths.begin(), expectLengths.end(), colorStr.size()) != expectLengths.end();
296 }
297 
HandleIncorrectColor(const std::string & newColorStr)298 uint32_t JsTool::HandleIncorrectColor(const std::string& newColorStr)
299 {
300     errno = 0;
301     char* end = nullptr;
302     uint32_t value = strtoul(newColorStr.c_str(), &end, COLOR_STRING_FORMAT);
303     if (errno == ERANGE) {
304         ROSEN_LOGE("JsTool::HandleIncorrectColor %{public}s is out of range.", newColorStr.c_str());
305     }
306     if (value == 0 && end == newColorStr.c_str()) {
307         ROSEN_LOGE("JsTool::HandleIncorrectColor input can not be converted to number, use default :0x0");
308     }
309     return value;
310 }
311 
HandleRGBValue(int value,int & result)312 bool JsTool::HandleRGBValue(int value, int& result)
313 {
314     if (value < 0) {
315         return false;
316     }
317     result = value > Color::RGB_MAX ? Color::RGB_MAX : value;
318     return true;
319 }
320 
IsOpacityValid(double value)321 bool JsTool::IsOpacityValid(double value)
322 {
323     return value >= 0 && value <= 1.0;
324 }
325 
MatchColorWithMagic(std::string & colorStr,uint32_t & result)326 bool JsTool::MatchColorWithMagic(std::string& colorStr, uint32_t& result)
327 {
328     // This function we match string like "#FF0000" or "#FF0000FF" to get hexnumber
329     // Check whether the beginning of the string is "#" and whether the length of the string is vaild.
330     if (!FastCheckColorType(colorStr, "#", EXPECT_MAGIC_COLOR_LENGTHS)) {
331         ROSEN_LOGE("JsTool::MatchColorWithMagic colorString is invalid");
332         return false;
333     }
334     // Remove "#"
335     colorStr.erase(0, 1);
336 
337     // Check whether the remaining part of the string is hexnumber
338     if (!std::regex_match(colorStr, HEX_PATTERN)) {
339         ROSEN_LOGE("JsTool::MatchColorWithMagic colorString is invalid hexnub");
340         return false;
341     }
342 
343     result = HandleIncorrectColor(colorStr);
344     // If string is "#FF0000" that has not Alpha, set Alpha is "FF"
345     if (colorStr.length() < COLOR_STRING_SIZE_STANDARD) {
346         result |= COLOR_DEFAULT_ALPHA;
347     }
348     return true;
349 }
350 
MatchColorWithMagicMini(std::string & colorStr,uint32_t & result)351 bool JsTool::MatchColorWithMagicMini(std::string& colorStr, uint32_t& result)
352 {
353     // This function we match string like "#FF0000" or "#FF0000FF" to get hexnumber
354     // Check whether the beginning of the string is "#" and whether the length of the string is vaild.
355     if (!FastCheckColorType(colorStr, "#", EXPECT_MAGIC_MINI_COLOR_LENGTHS)) {
356         ROSEN_LOGE("JsTool::MatchColorWithMagicMini colorString is invalid");
357         return false;
358     }
359     // Remove "#"
360     colorStr.erase(0, 1);
361 
362     // Check whether the remaining part of the string is hexnumber
363     if (!std::regex_match(colorStr, HEX_PATTERN)) {
364         ROSEN_LOGE("JsTool::MatchColorWithMagicMini colorString is invalid hexnub");
365         return false;
366     }
367 
368     // "#F00" is the abbreviation of "#FF0000", every will be used twice to make origin string
369     std::string newColorStr;
370     for (auto& c : colorStr) {
371         newColorStr += c;
372         newColorStr += c;
373     }
374     result = HandleIncorrectColor(newColorStr);
375     // If string is "#FF0000" that has not Alpha, set Alpha is "FF"
376     if (newColorStr.length() < COLOR_STRING_SIZE_STANDARD) {
377         result |= COLOR_DEFAULT_ALPHA;
378     }
379     return true;
380 }
381 
MatchColorWithRGB(const std::string & colorStr,uint32_t & result)382 bool JsTool::MatchColorWithRGB(const std::string& colorStr, uint32_t& result)
383 {
384     // This function we match string like "rgb(255,0,0)" to get hexnumber
385     // Check whether the beginning of the string is "rgb(".
386     if (!FastCheckColorType(colorStr, "rgb(", {})) {
387         ROSEN_LOGE("JsTool::MatchColorWithRGB colorString is invalid");
388         return false;
389     }
390 
391     // Using regular expressions to obtain the value of RGB
392     std::smatch matches;
393     if (std::regex_match(colorStr, matches, COLOR_WITH_RGB) && matches.size() == RGB_SUB_MATCH_SIZE) {
394         int redInt = 0;
395         int greenInt = 0;
396         int blueInt = 0;
397         if (!HandleRGBValue(std::stoi(matches[ARGC_ONE]), redInt) ||
398             !HandleRGBValue(std::stoi(matches[ARGC_TWO]), greenInt) ||
399             !HandleRGBValue(std::stoi(matches[ARGC_THREE]), blueInt)) {
400             ROSEN_LOGE("JsTool::MatchColorWithRGB colorStringNub is invalid");
401             return false;
402         }
403 
404         auto red = static_cast<uint8_t>(redInt);
405         auto green = static_cast<uint8_t>(greenInt);
406         auto blue = static_cast<uint8_t>(blueInt);
407         result = COLOR_DEFAULT_ALPHA | (red << COLOR_OFFSET_RED) | (green << COLOR_OFFSET_GREEN) | blue;
408         return true;
409     }
410     return false;
411 }
412 
MatchColorWithRGBA(const std::string & colorStr,uint32_t & result)413 bool JsTool::MatchColorWithRGBA(const std::string& colorStr, uint32_t& result)
414 {
415     // This function we match string like "rgba(255,0,0,0.5)" to get hexnumber
416     // Check whether the beginning of the string is "rgba(".
417     if (!FastCheckColorType(colorStr, "rgba(", {})) {
418         ROSEN_LOGE("JsTool::MatchColorWithRGBA colorString is invalid");
419         return false;
420     }
421 
422     // Using regular expressions to obtain the value of RGBA
423     std::smatch matches;
424     if (std::regex_match(colorStr, matches, COLOR_WITH_RGBA) && matches.size() == RGBA_SUB_MATCH_SIZE) {
425         int redInt = 0;
426         int greenInt = 0;
427         int blueInt = 0;
428         auto opacityDouble = std::stod(matches[ARGC_FOUR]);
429         if (!HandleRGBValue(std::stoi(matches[ARGC_ONE]), redInt) ||
430             !HandleRGBValue(std::stoi(matches[ARGC_TWO]), greenInt) ||
431             !HandleRGBValue(std::stoi(matches[ARGC_THREE]), blueInt) ||
432             !IsOpacityValid(opacityDouble)) {
433             ROSEN_LOGE("JsTool::MatchColorWithRGBA colorStringNub is invalid");
434             return false;
435         }
436 
437         auto red = static_cast<uint8_t>(redInt);
438         auto green = static_cast<uint8_t>(greenInt);
439         auto blue = static_cast<uint8_t>(blueInt);
440         uint8_t alpha = static_cast<uint8_t>(round(static_cast<double>(opacityDouble) * 0xff));
441         result = (alpha << COLOR_OFFSET_ALPHA) | (red << COLOR_OFFSET_RED) | (green << COLOR_OFFSET_GREEN) | blue;
442         return true;
443     }
444     return false;
445 }
446 
GetColorStringResult(std::string colorStr,uint32_t & result)447 bool JsTool::GetColorStringResult(std::string colorStr, uint32_t& result)
448 {
449     if (colorStr.empty()) {
450         ROSEN_LOGE("JsTool::GetColorStringResult string is empty");
451         return false;
452     }
453 
454     // e.g: Remove ' ' that change "rgb(255, 0, 0)" to "rgb(255,0,0)"
455     colorStr.erase(std::remove(colorStr.begin(), colorStr.end(), ' '), colorStr.end());
456 
457     return (MatchColorWithMagic(colorStr, result) || MatchColorWithMagicMini(colorStr, result) ||
458             MatchColorWithRGB(colorStr, result) || MatchColorWithRGBA(colorStr, result));
459 }
460 
GetColorObjectResult(napi_env env,napi_value value,uint32_t & result)461 bool JsTool::GetColorObjectResult(napi_env env, napi_value value, uint32_t& result)
462 {
463     ResourceInfo info;
464     if (!GetResourceInfo(env, value, info)) {
465         ROSEN_LOGE("JsTool::GetColorObjectResult GetResourceInfo failed!");
466         return false;
467     }
468 
469     auto resourceManager = GetResourceManager();
470     if (resourceManager == nullptr) {
471         ROSEN_LOGE("JsTool::GetColorObjectResult resourceManager is nullptr!");
472         return false;
473     }
474 
475     if (info.type == static_cast<int32_t>(ResourceType::STRING)) {
476         std::string colorStr = "";
477         int32_t state = resourceManager->GetStringById(static_cast<uint32_t>(info.resId), colorStr);
478         if (state >= GLOBAL_ERROR || state < 0) {
479             ROSEN_LOGE("JsTool::GetColorObjectResult failed to get colorString!");
480             return false;
481         }
482         if (!GetColorStringResult(colorStr, result)) {
483             ROSEN_LOGE("JsTool::GetColorObjectResult failed to GetColorStringResult!");
484             return false;
485         }
486     } else if (info.type == static_cast<int32_t>(ResourceType::INTEGER)) {
487         int colorResult = 0;
488         int32_t state = resourceManager->GetIntegerById(static_cast<uint32_t>(info.resId), colorResult);
489         if (state >= GLOBAL_ERROR || state < 0) {
490             ROSEN_LOGE("JsTool::GetColorObjectResult failed to get colorInt!");
491             return false;
492         }
493         result = GetColorNumberResult(colorResult);
494     } else if (info.type == static_cast<int32_t>(ResourceType::COLOR)) {
495         int32_t state = resourceManager->GetColorById(static_cast<uint32_t>(info.resId), result);
496         if (state >= GLOBAL_ERROR || state < 0) {
497             ROSEN_LOGE("JsTool::GetColorObjectResult failed to get colorColor!");
498             return false;
499         }
500     } else {
501         ROSEN_LOGE("JsTool::GetColorObjectResult invalid Resource type!");
502         return false;
503     }
504     return true;
505 }
506 
GetResourceColor(napi_env env,napi_value res,uint32_t & result)507 bool JsTool::GetResourceColor(napi_env env, napi_value res, uint32_t& result)
508 {
509     napi_valuetype valueType = napi_undefined;
510     napi_typeof(env, res, &valueType);
511     if (valueType == napi_string) {
512         size_t len = 0;
513         napi_get_value_string_utf8(env, res, nullptr, 0, &len);
514         char* str = new(std::nothrow) char[len + 1];
515         if (!str) {
516             ROSEN_LOGE("JsTool::GetResourceColor memory is insufficient and failed to apply");
517             return false;
518         }
519         napi_get_value_string_utf8(env, res, str, len + 1, &len);
520         std::string colorStr(str, len);
521         delete[] str;
522         if (!GetColorStringResult(colorStr, result)) {
523             ROSEN_LOGE("JsTool::GetResourceColor failed to GetColorStringResult!");
524             return false;
525         }
526     } else if (valueType == napi_number) {
527         uint32_t colorNumber = 0;
528         napi_get_value_uint32(env, res, &colorNumber);
529         result = GetColorNumberResult(colorNumber);
530     } else if (valueType == napi_object) {
531         if (!GetColorObjectResult(env, res, result)) {
532             ROSEN_LOGE("JsTool::GetResourceColor failed to GetColorObjectResult!");
533             return false;
534         }
535     } else {
536         ROSEN_LOGE("JsTool::GetResourceColor invalid ResourceColor type!");
537         return false;
538     }
539     return true;
540 }
541 #endif
542 } // namespace Drawing
543 } // namespace OHOS::Rosen