• 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 #include <cstdint>
17 
18 #include "napi_common.h"
19 #include "text_style.h"
20 
21 namespace OHOS::Rosen {
BindNativeFunction(napi_env env,napi_value object,const char * name,const char * moduleName,napi_callback func)22 void BindNativeFunction(napi_env env, napi_value object, const char* name, const char* moduleName, napi_callback func)
23 {
24     std::string fullName;
25     if (moduleName) {
26         fullName = moduleName;
27         fullName += '.';
28     }
29     fullName += name;
30     napi_value funcValue = nullptr;
31     napi_create_function(env, fullName.c_str(), fullName.size(), func, nullptr, &funcValue);
32     napi_set_named_property(env, object, fullName.c_str(), funcValue);
33 }
34 
CreateJsError(napi_env env,int32_t errCode,const std::string & message)35 napi_value CreateJsError(napi_env env, int32_t errCode, const std::string& message)
36 {
37     napi_value result = nullptr;
38     napi_create_error(env, CreateJsValue(env, errCode), CreateJsValue(env, message), &result);
39     return result;
40 }
41 
NapiThrowError(napi_env env,TextErrorCode err,const std::string & message)42 napi_value NapiThrowError(napi_env env, TextErrorCode err, const std::string& message)
43 {
44     napi_throw(env, CreateJsError(env, static_cast<int32_t>(err), message));
45     return NapiGetUndefined(env);
46 }
47 
OnMakeFontFamilies(napi_env & env,napi_value jsValue,std::vector<std::string> & fontFamilies)48 bool OnMakeFontFamilies(napi_env& env, napi_value jsValue, std::vector<std::string> &fontFamilies)
49 {
50     if (jsValue == nullptr) {
51         return false;
52     }
53     uint32_t size = 0;
54     napi_get_array_length(env, jsValue, &size);
55     if (size == 0) {
56         return false;
57     }
58     for (uint32_t i = 0; i < size; i++) {
59         napi_value tempStr = nullptr;
60         napi_get_element(env, jsValue, i, &tempStr);
61         std::string text = "";
62         if (ConvertFromJsValue(env, tempStr, text)) {
63             fontFamilies.push_back(text);
64         }
65     }
66     return true;
67 }
68 
SetColorFromJS(napi_env env,napi_value argValue,const std::string & str,Drawing::Color & colorSrc)69 bool SetColorFromJS(napi_env env, napi_value argValue, const std::string& str, Drawing::Color& colorSrc)
70 {
71     napi_value tempValue = nullptr;
72     napi_get_named_property(env, argValue, str.c_str(), &tempValue);
73     return SetColorFromJS(env, tempValue, colorSrc);
74 }
75 
SetColorFromJS(napi_env env,napi_value argValue,Drawing::Color & colorSrc)76 bool SetColorFromJS(napi_env env, napi_value argValue, Drawing::Color& colorSrc)
77 {
78     napi_value tempValueChild = nullptr;
79     if (argValue == nullptr) {
80         return false;
81     }
82 
83     int32_t alpha = 0;
84     int32_t red = 0;
85     int32_t green = 0;
86     int32_t blue = 0;
87     napi_get_named_property(env, argValue, "alpha", &tempValueChild);
88     bool isAlphaOk = ConvertClampFromJsValue(env, tempValueChild, alpha, 0, Drawing::Color::RGB_MAX);
89     napi_get_named_property(env, argValue, "red", &tempValueChild);
90     bool isRedOk = ConvertClampFromJsValue(env, tempValueChild, red, 0, Drawing::Color::RGB_MAX);
91     napi_get_named_property(env, argValue, "green", &tempValueChild);
92     bool isGreenOk = ConvertClampFromJsValue(env, tempValueChild, green, 0, Drawing::Color::RGB_MAX);
93     napi_get_named_property(env, argValue, "blue", &tempValueChild);
94     bool isBlueOk = ConvertClampFromJsValue(env, tempValueChild, blue, 0, Drawing::Color::RGB_MAX);
95     if (isAlphaOk && isRedOk && isGreenOk && isBlueOk) {
96         Drawing::Color color(Drawing::Color::ColorQuadSetARGB(alpha, red, green, blue));
97         colorSrc = color;
98         return true;
99     }
100     return false;
101 }
102 
GetDecorationFromJS(napi_env env,napi_value argValue,const std::string & str,TextStyle & textStyle)103 bool GetDecorationFromJS(napi_env env, napi_value argValue, const std::string& str, TextStyle& textStyle)
104 {
105     if (argValue == nullptr) {
106         return false;
107     }
108     napi_value tempValue = nullptr;
109     napi_get_named_property(env, argValue, str.c_str(), &tempValue);
110     if (tempValue == nullptr) {
111         return false;
112     }
113 
114     napi_value tempValueChild = nullptr;
115     napi_get_named_property(env, tempValue, "textDecoration", &tempValueChild);
116     uint32_t textDecoration = 0;
117     if (tempValueChild != nullptr && napi_get_value_uint32(env, tempValueChild, &textDecoration) == napi_ok) {
118         textStyle.decoration = TextDecoration(textDecoration);
119     }
120 
121     SetColorFromJS(env, tempValue, "color", textStyle.decorationColor);
122 
123     tempValueChild = nullptr;
124     napi_get_named_property(env, tempValue, "decorationStyle", &tempValueChild);
125     uint32_t decorationStyle = 0;
126     if (tempValueChild != nullptr && napi_get_value_uint32(env, tempValueChild, &decorationStyle) == napi_ok) {
127         textStyle.decorationStyle = TextDecorationStyle(decorationStyle);
128     }
129     SetDoubleValueFromJS(env, tempValue, "decorationThicknessScale", textStyle.decorationThicknessScale);
130     return true;
131 }
132 
GetDecorationFromJSForUpdate(napi_env env,napi_value argValue,TextStyle & textStyle)133 bool GetDecorationFromJSForUpdate(napi_env env, napi_value argValue, TextStyle& textStyle)
134 {
135     if (argValue == nullptr) {
136         return false;
137     }
138 
139     napi_value tempValueChild = nullptr;
140     napi_get_named_property(env, argValue, "textDecoration", &tempValueChild);
141     uint32_t textDecoration = 0;
142     if (tempValueChild != nullptr && napi_get_value_uint32(env, tempValueChild, &textDecoration) == napi_ok) {
143         textStyle.decoration = TextDecoration(textDecoration);
144         textStyle.relayoutChangeBitmap.set(static_cast<size_t>(RelayoutTextStyleAttribute::DECORATION));
145     }
146 
147     if (SetColorFromJS(env, argValue, "color", textStyle.decorationColor)) {
148         textStyle.relayoutChangeBitmap.set(static_cast<size_t>(RelayoutTextStyleAttribute::DECORATION_COLOR));
149     }
150 
151     tempValueChild = nullptr;
152     napi_get_named_property(env, argValue, "decorationStyle", &tempValueChild);
153     uint32_t decorationStyle = 0;
154     if (tempValueChild != nullptr && napi_get_value_uint32(env, tempValueChild, &decorationStyle) == napi_ok) {
155         textStyle.decorationStyle = TextDecorationStyle(decorationStyle);
156         textStyle.relayoutChangeBitmap.set(static_cast<size_t>(RelayoutTextStyleAttribute::DECORATION_STYLE));
157     }
158 
159     tempValueChild = nullptr;
160     napi_get_named_property(env, argValue, "decorationThicknessScale", &tempValueChild);
161     double decorationThicknessScale = 1.0;
162     if (tempValueChild != nullptr && napi_get_value_double(env, tempValueChild, &decorationThicknessScale) == napi_ok) {
163         textStyle.decorationThicknessScale = decorationThicknessScale;
164         textStyle.relayoutChangeBitmap.set(static_cast<size_t>(RelayoutTextStyleAttribute::DECORATION_THICKNESS_SCALE));
165     }
166     return true;
167 }
168 
GetNamePropertyFromJS(napi_env env,napi_value argValue,const std::string & str,napi_value & propertyValue)169 bool GetNamePropertyFromJS(napi_env env, napi_value argValue, const std::string& str, napi_value& propertyValue)
170 {
171     bool result = false;
172     if (napi_has_named_property(env, argValue, str.c_str(), &result) != napi_ok || (!result)) {
173         return false;
174     }
175 
176     if (napi_get_named_property(env, argValue, str.c_str(), &propertyValue) != napi_ok) {
177         return false;
178     }
179 
180     return true;
181 }
182 
ReceiveFontFeature(napi_env env,napi_value argValue,TextStyle & textStyle)183 void ReceiveFontFeature(napi_env env, napi_value argValue, TextStyle& textStyle)
184 {
185     napi_value allFeatureValue = nullptr;
186     napi_get_named_property(env, argValue, "fontFeatures", &allFeatureValue);
187     uint32_t arrayLength = 0;
188     if (napi_get_array_length(env, allFeatureValue, &arrayLength) != napi_ok ||
189         !arrayLength) {
190         TEXT_LOGD("Failed to get font feature");
191         return;
192     }
193 
194     for (uint32_t further = 0; further < arrayLength; further++) {
195         napi_value singleElementValue;
196         if (napi_get_element(env, allFeatureValue, further, &singleElementValue) != napi_ok) {
197             TEXT_LOGE("Failed to get font feature");
198             break;
199         }
200         napi_value featureElement;
201         std::string name;
202         if (napi_get_named_property(env, singleElementValue, "name", &featureElement) != napi_ok ||
203             !ConvertFromJsValue(env, featureElement, name)) {
204             TEXT_LOGE("Failed to get name");
205             break;
206         }
207 
208         int value = 0;
209         if (napi_get_named_property(env, singleElementValue, "value", &featureElement) != napi_ok ||
210             !ConvertFromJsValue(env, featureElement, value)) {
211             TEXT_LOGE("Failed to get value");
212             break;
213         }
214         textStyle.fontFeatures.SetFeature(name, value);
215     }
216     return;
217 }
218 
ReceiveFontVariation(napi_env env,napi_value argValue,TextStyle & textStyle)219 void ReceiveFontVariation(napi_env env, napi_value argValue, TextStyle& textStyle)
220 {
221     napi_value allVariationValue = nullptr;
222     napi_get_named_property(env, argValue, "fontVariations", &allVariationValue);
223     uint32_t arrayLength = 0;
224     auto status = napi_get_array_length(env, allVariationValue, &arrayLength);
225     if ((status != napi_ok) || (arrayLength == 0)) {
226         TEXT_LOGD("Failed to get variations, ret %{public}d", static_cast<int>(status));
227         return;
228     }
229 
230     for (uint32_t further = 0; further < arrayLength; further++) {
231         napi_value singleElementValue;
232         status = napi_get_element(env, allVariationValue, further, &singleElementValue);
233         if (status != napi_ok) {
234             TEXT_LOGE("Failed to get variation, ret %{public}d", static_cast<int>(status));
235             break;
236         }
237         napi_value variationElement;
238         std::string axis;
239         status = napi_get_named_property(env, singleElementValue, "axis", &variationElement);
240         if ((status != napi_ok) || !ConvertFromJsValue(env, variationElement, axis)) {
241             TEXT_LOGE("Failed to get axis, ret %{public}d", static_cast<int>(status));
242             break;
243         }
244 
245         int value = 0;
246         status = napi_get_named_property(env, singleElementValue, "value", &variationElement);
247         if ((status != napi_ok) || !ConvertFromJsValue(env, variationElement, value)) {
248             TEXT_LOGE("Failed to get value, ret %{public}d", static_cast<int>(status));
249             break;
250         }
251         textStyle.fontVariations.SetAxisValue(axis, value);
252     }
253     return;
254 }
255 
SetTextStyleBaseType(napi_env env,napi_value argValue,TextStyle & textStyle)256 void SetTextStyleBaseType(napi_env env, napi_value argValue, TextStyle& textStyle)
257 {
258     SetDoubleValueFromJS(env, argValue, "letterSpacing", textStyle.letterSpacing);
259     SetDoubleValueFromJS(env, argValue, "wordSpacing", textStyle.wordSpacing);
260     SetDoubleValueFromJS(env, argValue, "baselineShift", textStyle.baseLineShift);
261     SetDoubleValueFromJS(env, argValue, "heightScale", textStyle.heightScale);
262     SetBoolValueFromJS(env, argValue, "halfLeading", textStyle.halfLeading);
263     SetBoolValueFromJS(env, argValue, "heightOnly", textStyle.heightOnly);
264 
265     textStyle.heightScale = textStyle.heightScale < 0 ? 0 : textStyle.heightScale;
266 }
267 
SetTextStyleFontType(napi_env env,napi_value argValue,TextStyle & textStyle)268 void SetTextStyleFontType(napi_env env, napi_value argValue, TextStyle& textStyle)
269 {
270     napi_value tempValue = nullptr;
271     napi_get_named_property(env, argValue, "fontWeight", &tempValue);
272     uint32_t fontWeight = 0;
273     if (tempValue != nullptr && napi_get_value_uint32(env, tempValue, &fontWeight) == napi_ok) {
274         textStyle.fontWeight = FontWeight(fontWeight);
275     }
276 
277     napi_get_named_property(env, argValue, "fontStyle", &tempValue);
278     uint32_t fontStyle = 0;
279     if (tempValue != nullptr && napi_get_value_uint32(env, tempValue, &fontStyle) == napi_ok) {
280         textStyle.fontStyle = FontStyle(fontStyle);
281         // Let OBLIQUE be equal to ITALIC, it's a temp modify.
282         if (textStyle.fontStyle == FontStyle::OBLIQUE) {
283             textStyle.fontStyle = FontStyle::ITALIC;
284         }
285     }
286 
287     SetDoubleValueFromJS(env, argValue, "fontSize", textStyle.fontSize);
288 
289     std::vector<std::string> fontFamilies;
290     napi_get_named_property(env, argValue, "fontFamilies", &tempValue);
291     if (tempValue != nullptr && OnMakeFontFamilies(env, tempValue, fontFamilies)) {
292         textStyle.fontFamilies = fontFamilies;
293     }
294 }
295 
ScanShadowValue(napi_env env,napi_value allShadowValue,uint32_t arrayLength,TextStyle & textStyle)296 void ScanShadowValue(napi_env env, napi_value allShadowValue, uint32_t arrayLength, TextStyle& textStyle)
297 {
298     textStyle.shadows.clear();
299     for (uint32_t further = 0; further < arrayLength; further++) {
300         napi_value element;
301         Drawing::Color colorSrc = OHOS::Rosen::Drawing::Color::COLOR_BLACK;
302         Drawing::Point offset(0, 0);
303         double runTimeRadius = 0;
304         auto status = napi_get_element(env, allShadowValue, further, &element);
305         if (status != napi_ok) {
306             TEXT_LOGE("Failed to get shadow, ret %{public}d", static_cast<int>(status));
307             return;
308         }
309         SetColorFromJS(env, element, "color", colorSrc);
310 
311         napi_value pointValue = nullptr;
312         status = napi_get_named_property(env, element, "point", &pointValue);
313         if (status != napi_ok) {
314             TEXT_LOGE("Failed to get point, ret %{public}d", static_cast<int>(status));
315             return;
316         }
317         GetPointFromJsValue(env, pointValue, offset);
318 
319         napi_value radius = nullptr;
320         status = napi_get_named_property(env, element, "blurRadius", &radius);
321         if (status != napi_ok) {
322             TEXT_LOGE("Failed to get blur radius, ret %{public}d", static_cast<int>(status));
323             return;
324         }
325         status = napi_get_value_double(env, radius, &runTimeRadius);
326         if (status != napi_ok) {
327             TEXT_LOGE("Failed to get radius, ret %{public}d", static_cast<int>(status));
328             return;
329         }
330         textStyle.shadows.emplace_back(TextShadow(colorSrc, offset, runTimeRadius));
331     }
332     return;
333 }
334 
SetTextShadowProperty(napi_env env,napi_value argValue,TextStyle & textStyle)335 void SetTextShadowProperty(napi_env env, napi_value argValue, TextStyle& textStyle)
336 {
337     napi_value allShadowValue = nullptr;
338     if (!GetNamePropertyFromJS(env, argValue, "textShadows", allShadowValue)) {
339         return;
340     }
341 
342     uint32_t arrayLength = 0;
343     auto status = napi_get_array_length(env, allShadowValue, &arrayLength);
344     if (status != napi_ok) {
345         TEXT_LOGE("Failed to get shadow array length, ret %{public}d", static_cast<int>(status));
346         return;
347     }
348     ScanShadowValue(env, allShadowValue, arrayLength, textStyle);
349     return;
350 }
351 
ParsePartTextStyle(napi_env env,napi_value argValue,TextStyle & textStyle)352 void ParsePartTextStyle(napi_env env, napi_value argValue, TextStyle& textStyle)
353 {
354     napi_value tempValue = nullptr;
355     napi_get_named_property(env, argValue, "baseline", &tempValue);
356     uint32_t baseline = 0;
357     if (tempValue != nullptr && napi_get_value_uint32(env, tempValue, &baseline) == napi_ok) {
358         textStyle.baseline = TextBaseline(baseline);
359     }
360 
361     GetDecorationFromJS(env, argValue, "decoration", textStyle);
362     SetTextStyleBaseType(env, argValue, textStyle);
363     SetTextStyleFontType(env, argValue, textStyle);
364     ReceiveFontFeature(env, argValue, textStyle);
365     ReceiveFontVariation(env, argValue, textStyle);
366     napi_get_named_property(env, argValue, "ellipsis", &tempValue);
367     std::string text = "";
368     if (tempValue != nullptr && ConvertFromJsValue(env, tempValue, text)) {
369         textStyle.ellipsis = Str8ToStr16(text);
370     }
371     napi_get_named_property(env, argValue, "ellipsisMode", &tempValue);
372     uint32_t ellipsisModal = 0;
373     if (tempValue != nullptr && napi_get_value_uint32(env, tempValue, &ellipsisModal)== napi_ok) {
374         textStyle.ellipsisModal = EllipsisModal(ellipsisModal);
375     }
376     napi_get_named_property(env, argValue, "locale", &tempValue);
377     std::string textLocale = "";
378     if (tempValue != nullptr && ConvertFromJsValue(env, tempValue, textLocale)) {
379         textStyle.locale = textLocale;
380     }
381     napi_get_named_property(env, argValue, "badgeType", &tempValue);
382     size_t textBadgeType = 0;
383     if (tempValue != nullptr && ConvertFromJsValue(env, tempValue, textBadgeType)) {
384         textStyle.badgeType = static_cast<TextBadgeType>(textBadgeType);
385     }
386 }
387 
GetTextStyleFromJS(napi_env env,napi_value argValue,TextStyle & textStyle)388 bool GetTextStyleFromJS(napi_env env, napi_value argValue, TextStyle& textStyle)
389 {
390     napi_valuetype valueType = napi_undefined;
391     if (argValue == nullptr || napi_typeof(env, argValue, &valueType) != napi_ok || valueType != napi_object) {
392         return false;
393     }
394     SetColorFromJS(env, argValue, "color", textStyle.color);
395     ParsePartTextStyle(env, argValue, textStyle);
396     SetTextShadowProperty(env, argValue, textStyle);
397     SetRectStyleFromJS(env, argValue, textStyle.backgroundRect);
398     return true;
399 }
400 
SetAlignValueForParagraphStyle(napi_env env,napi_value argValue,TypographyStyle & pographyStyle)401 static void SetAlignValueForParagraphStyle(napi_env env, napi_value argValue, TypographyStyle& pographyStyle)
402 {
403     if (argValue == nullptr) {
404         return;
405     }
406     napi_value tempValue = nullptr;
407     napi_get_named_property(env, argValue, "align", &tempValue);
408     uint32_t align = 0;
409     if (tempValue != nullptr && napi_get_value_uint32(env, tempValue, &align) == napi_ok) {
410         pographyStyle.textAlign = TextAlign(align);
411     }
412 }
413 
GetParagraphStyleFromJS(napi_env env,napi_value argValue,TypographyStyle & pographyStyle)414 bool GetParagraphStyleFromJS(napi_env env, napi_value argValue, TypographyStyle& pographyStyle)
415 {
416     if (argValue == nullptr) {
417         return false;
418     }
419     napi_value tempValue = nullptr;
420     napi_get_named_property(env, argValue, "textStyle", &tempValue);
421     TextStyle textStyle;
422     if (tempValue != nullptr && GetTextStyleFromJS(env, tempValue, textStyle)) {
423         pographyStyle.SetTextStyle(textStyle);
424     }
425     tempValue = nullptr;
426     napi_get_named_property(env, argValue, "textDirection", &tempValue);
427     uint32_t textDirection = 0;
428     if (tempValue != nullptr && napi_get_value_uint32(env, tempValue, &textDirection) == napi_ok) {
429         pographyStyle.textDirection = TextDirection(textDirection);
430     }
431     SetAlignValueForParagraphStyle(env, argValue, pographyStyle);
432     tempValue = nullptr;
433     napi_get_named_property(env, argValue, "wordBreak", &tempValue);
434     uint32_t wordBreak = 0;
435     if (tempValue != nullptr && napi_get_value_uint32(env, tempValue, &wordBreak) == napi_ok) {
436         pographyStyle.wordBreakType = WordBreakType(wordBreak);
437     }
438     tempValue = nullptr;
439     napi_get_named_property(env, argValue, "maxLines", &tempValue);
440     int64_t maxLines = 0;
441     if (tempValue != nullptr && napi_get_value_int64(env, tempValue, &maxLines) == napi_ok) {
442         pographyStyle.maxLines = maxLines < 0 ? 0 : maxLines;
443     }
444     tempValue = nullptr;
445     napi_get_named_property(env, argValue, "breakStrategy", &tempValue);
446     uint32_t breakStrategy = 0;
447     if (tempValue != nullptr && napi_get_value_uint32(env, tempValue, &breakStrategy) == napi_ok) {
448         pographyStyle.breakStrategy = BreakStrategy(breakStrategy);
449     }
450 
451     napi_value strutStyleValue = nullptr;
452     if (GetNamePropertyFromJS(env, argValue, "strutStyle", strutStyleValue)) {
453         SetStrutStyleFromJS(env, strutStyleValue, pographyStyle);
454     }
455 
456     pographyStyle.ellipsis = textStyle.ellipsis;
457     pographyStyle.ellipsisModal = textStyle.ellipsisModal;
458 
459     napi_get_named_property(env, argValue, "tab", &tempValue);
460     TextTab textTab;
461     if (tempValue != nullptr && GetTextTabFromJS(env, tempValue, textTab)) {
462         pographyStyle.tab = textTab;
463     }
464     HandleExtentParagraphStyleProperties(env, argValue, pographyStyle);
465     return true;
466 }
467 
HandleExtentParagraphStyleProperties(napi_env env,napi_value argValue,TypographyStyle & pographyStyle)468 void HandleExtentParagraphStyleProperties(napi_env env, napi_value argValue, TypographyStyle& pographyStyle)
469 {
470     SetEnumValueFromJS(env, argValue, "textHeightBehavior", pographyStyle.textHeightBehavior);
471     SetBoolValueFromJS(env, argValue, "trailingSpaceOptimized", pographyStyle.isTrailingSpaceOptimized);
472     SetBoolValueFromJS(env, argValue, "autoSpace", pographyStyle.enableAutoSpace);
473     SetEnumValueFromJS(env, argValue, "verticalAlign", pographyStyle.verticalAlignment);
474 }
475 
GetPlaceholderSpanFromJS(napi_env env,napi_value argValue,PlaceholderSpan & placeholderSpan)476 bool GetPlaceholderSpanFromJS(napi_env env, napi_value argValue, PlaceholderSpan& placeholderSpan)
477 {
478     if (argValue == nullptr) {
479         return false;
480     }
481     napi_value tempValue = nullptr;
482     napi_get_named_property(env, argValue, "width", &tempValue);
483     double width = 0;
484     if (tempValue != nullptr && napi_get_value_double(env, tempValue, &width) == napi_ok) {
485         placeholderSpan.width = width;
486     } else {
487         return false;
488     }
489     tempValue = nullptr;
490     napi_get_named_property(env, argValue, "height", &tempValue);
491     double height = 0;
492     if (tempValue != nullptr && napi_get_value_double(env, tempValue, &height) == napi_ok) {
493         placeholderSpan.height = height;
494     } else {
495         return false;
496     }
497     tempValue = nullptr;
498     napi_get_named_property(env, argValue, "align", &tempValue);
499     uint32_t align = 0;
500     if (tempValue != nullptr && napi_get_value_uint32(env, tempValue, &align) == napi_ok) {
501         placeholderSpan.alignment = PlaceholderVerticalAlignment(align);
502     } else {
503         return false;
504     }
505     tempValue = nullptr;
506     napi_get_named_property(env, argValue, "baseline", &tempValue);
507     uint32_t baseline = 0;
508     if (tempValue != nullptr && napi_get_value_uint32(env, tempValue, &baseline) == napi_ok) {
509         placeholderSpan.baseline = TextBaseline(baseline);
510     } else {
511         return false;
512     }
513     tempValue = nullptr;
514     napi_get_named_property(env, argValue, "baselineOffset", &tempValue);
515     double baselineOffset = 0;
516     if (tempValue != nullptr && napi_get_value_double(env, tempValue, &baselineOffset) == napi_ok) {
517         placeholderSpan.baselineOffset = baselineOffset;
518     } else {
519         return false;
520     }
521     return true;
522 }
523 
GetParamLen(napi_env env,napi_value param)524 size_t GetParamLen(napi_env env, napi_value param)
525 {
526     size_t buffSize = 0;
527     napi_status status = napi_get_value_string_utf8(env, param, nullptr, 0, &buffSize);
528     if (status != napi_ok || buffSize == 0) {
529         return 0;
530     }
531     return buffSize;
532 }
533 
GetFontMetricsFromJS(napi_env env,napi_value argValue,Drawing::FontMetrics & fontMetrics)534 bool GetFontMetricsFromJS(napi_env env, napi_value argValue, Drawing::FontMetrics& fontMetrics)
535 {
536     if (argValue == nullptr) {
537         return false;
538     }
539     napi_value tempValue = nullptr;
540     napi_get_named_property(env, argValue, "flags", &tempValue);
541     uint32_t flags = 0;
542     if (tempValue != nullptr && napi_get_value_uint32(env, tempValue, &flags) == napi_ok) {
543         fontMetrics.fFlags = Drawing::FontMetrics::FontMetricsFlags(flags);
544     }
545     SetFontMetricsFloatValueFromJS(env, argValue, "top", fontMetrics.fTop);
546     SetFontMetricsFloatValueFromJS(env, argValue, "ascent", fontMetrics.fAscent);
547     SetFontMetricsFloatValueFromJS(env, argValue, "descent", fontMetrics.fDescent);
548     SetFontMetricsFloatValueFromJS(env, argValue, "bottom", fontMetrics.fBottom);
549     SetFontMetricsFloatValueFromJS(env, argValue, "leading", fontMetrics.fLeading);
550     SetFontMetricsFloatValueFromJS(env, argValue, "avgCharWidth", fontMetrics.fAvgCharWidth);
551     SetFontMetricsFloatValueFromJS(env, argValue, "maxCharWidth", fontMetrics.fMaxCharWidth);
552     SetFontMetricsFloatValueFromJS(env, argValue, "xMin", fontMetrics.fXMin);
553     SetFontMetricsFloatValueFromJS(env, argValue, "xMax", fontMetrics.fXMax);
554     SetFontMetricsFloatValueFromJS(env, argValue, "xHeight", fontMetrics.fXHeight);
555     SetFontMetricsFloatValueFromJS(env, argValue, "capHeight", fontMetrics.fCapHeight);
556     SetFontMetricsFloatValueFromJS(env, argValue, "underlineThickness", fontMetrics.fUnderlineThickness);
557     SetFontMetricsFloatValueFromJS(env, argValue, "underlinePosition", fontMetrics.fUnderlinePosition);
558     SetFontMetricsFloatValueFromJS(env, argValue, "strikethroughThickness", fontMetrics.fStrikeoutThickness);
559     SetFontMetricsFloatValueFromJS(env, argValue, "strikethroughPosition", fontMetrics.fStrikeoutPosition);
560     return true;
561 }
562 
SetStrutStyleFromJS(napi_env env,napi_value strutStyleValue,TypographyStyle & typographyStyle)563 bool SetStrutStyleFromJS(napi_env env, napi_value strutStyleValue, TypographyStyle& typographyStyle)
564 {
565     napi_valuetype valueType = napi_undefined;
566     if (strutStyleValue == nullptr || napi_typeof(env, strutStyleValue, &valueType) != napi_ok ||
567         valueType != napi_object) {
568         TEXT_LOGE("Invalid strut style value");
569         return false;
570     }
571 
572     napi_value tempValue = nullptr;
573     if (GetNamePropertyFromJS(env, strutStyleValue, "fontFamilies", tempValue)) {
574         std::vector<std::string> fontFamilies;
575         if (tempValue != nullptr && OnMakeFontFamilies(env, tempValue, fontFamilies)) {
576             typographyStyle.lineStyleFontFamilies = fontFamilies;
577         }
578     }
579 
580     SetEnumValueFromJS(env, strutStyleValue, "fontStyle", typographyStyle.lineStyleFontStyle);
581     SetEnumValueFromJS(env, strutStyleValue, "fontWidth", typographyStyle.lineStyleFontWidth);
582     SetEnumValueFromJS(env, strutStyleValue, "fontWeight", typographyStyle.lineStyleFontWeight);
583 
584     SetDoubleValueFromJS(env, strutStyleValue, "fontSize", typographyStyle.lineStyleFontSize);
585     SetDoubleValueFromJS(env, strutStyleValue, "height", typographyStyle.lineStyleHeightScale);
586     SetDoubleValueFromJS(env, strutStyleValue, "leading", typographyStyle.lineStyleSpacingScale);
587 
588     SetBoolValueFromJS(env, strutStyleValue, "forceHeight", typographyStyle.lineStyleOnly);
589     SetBoolValueFromJS(env, strutStyleValue, "enabled", typographyStyle.useLineStyle);
590     SetBoolValueFromJS(env, strutStyleValue, "heightOverride", typographyStyle.lineStyleHeightOnly);
591     SetBoolValueFromJS(env, strutStyleValue, "halfLeading", typographyStyle.lineStyleHalfLeading);
592     return true;
593 }
594 
SetRectStyleFromJS(napi_env env,napi_value argValue,RectStyle & rectStyle)595 void SetRectStyleFromJS(napi_env env, napi_value argValue, RectStyle& rectStyle)
596 {
597     if (!argValue) {
598         return;
599     }
600 
601     napi_value tempValue = nullptr;
602     if (!GetNamePropertyFromJS(env, argValue, "backgroundRect", tempValue)) {
603         return;
604     }
605 
606     Drawing::Color color;
607     SetColorFromJS(env, tempValue, "color", color);
608     rectStyle.color = color.CastToColorQuad();
609     SetDoubleValueFromJS(env, tempValue, "leftTopRadius", rectStyle.leftTopRadius);
610     SetDoubleValueFromJS(env, tempValue, "rightTopRadius", rectStyle.rightTopRadius);
611     SetDoubleValueFromJS(env, tempValue, "rightBottomRadius", rectStyle.rightBottomRadius);
612     SetDoubleValueFromJS(env, tempValue, "leftBottomRadius", rectStyle.leftBottomRadius);
613 }
614 
CreateLineMetricsJsValue(napi_env env,OHOS::Rosen::LineMetrics & lineMetrics)615 napi_value CreateLineMetricsJsValue(napi_env env, OHOS::Rosen::LineMetrics& lineMetrics)
616 {
617     napi_value objValue = nullptr;
618     napi_create_object(env, &objValue);
619     if (objValue != nullptr) {
620         napi_set_named_property(env, objValue, "startIndex", CreateJsNumber(env, (uint32_t)lineMetrics.startIndex));
621         napi_set_named_property(env, objValue, "endIndex", CreateJsNumber(env, (uint32_t)lineMetrics.endIndex));
622         napi_set_named_property(env, objValue, "ascent", CreateJsNumber(env, lineMetrics.ascender));
623         napi_set_named_property(env, objValue, "descent", CreateJsNumber(env, lineMetrics.descender));
624         napi_set_named_property(env, objValue, "height", CreateJsNumber(env, lineMetrics.height));
625         napi_set_named_property(env, objValue, "width", CreateJsNumber(env, lineMetrics.width));
626         napi_set_named_property(env, objValue, "left", CreateJsNumber(env, lineMetrics.x));
627         napi_set_named_property(env, objValue, "baseline", CreateJsNumber(env, lineMetrics.baseline));
628         napi_set_named_property(env, objValue, "lineNumber", CreateJsNumber(env, lineMetrics.lineNumber));
629         napi_set_named_property(env, objValue, "topHeight", CreateJsNumber(env, lineMetrics.y));
630         napi_set_named_property(env, objValue, "runMetrics", ConvertMapToNapiMap(env, lineMetrics.runMetrics));
631     }
632     return objValue;
633 }
634 
CreateShadowArrayJsValue(napi_env env,const std::vector<TextShadow> & textShadows)635 napi_value CreateShadowArrayJsValue(napi_env env, const std::vector<TextShadow>& textShadows)
636 {
637     napi_value jsArray = nullptr;
638     napi_status arrayStatus = napi_create_array_with_length(env, textShadows.size(), &jsArray);
639     if (arrayStatus != napi_ok) {
640         TEXT_LOGE("Failed to create text Shadows array, ret %{public}d", arrayStatus);
641         return nullptr;
642     }
643     size_t index = 0;
644     for (const auto& shadow : textShadows) {
645         if (!shadow.HasShadow()) {
646             continue;
647         }
648         napi_value shadowObj = nullptr;
649         napi_status status = napi_create_object(env, &shadowObj);
650         if (status != napi_ok) {
651             TEXT_LOGE("Failed to create shadow object, ret %{public}d", status);
652             continue;
653         }
654         napi_set_named_property(
655             env, shadowObj, "color", CreateJsNumber(env, (uint32_t)shadow.color.CastToColorQuad()));
656         napi_set_named_property(
657             env, shadowObj, "point", CreatePointJsValue(env, (OHOS::Rosen::Drawing::PointF)shadow.offset));
658         napi_set_named_property(env, shadowObj, "blurRadius", CreateJsNumber(env, shadow.blurRadius));
659         status = napi_set_element(env, jsArray, index, shadowObj);
660         if (status != napi_ok) {
661             TEXT_LOGE("Failed to set shadow in textShadows, ret %{public}d", status);
662             continue;
663         }
664         index++;
665     }
666 
667     return jsArray;
668 }
669 
CreatePointJsValue(napi_env env,const OHOS::Rosen::Drawing::PointF & point)670 napi_value CreatePointJsValue(napi_env env, const OHOS::Rosen::Drawing::PointF& point)
671 {
672     napi_value objValue = nullptr;
673     napi_create_object(env, &objValue);
674     if (objValue != nullptr) {
675         napi_set_named_property(env, objValue, "x", CreateJsNumber(env, point.GetX()));
676         napi_set_named_property(env, objValue, "y", CreateJsNumber(env, point.GetY()));
677     }
678     return objValue;
679 }
680 
CreateRectStyleJsValue(napi_env env,RectStyle & rectStyle)681 napi_value CreateRectStyleJsValue(napi_env env, RectStyle& rectStyle)
682 {
683     napi_value objValue = nullptr;
684     napi_create_object(env, &objValue);
685     if (objValue != nullptr) {
686         napi_set_named_property(env, objValue, "color", CreateJsNumber(env, (uint32_t)rectStyle.color));
687         napi_set_named_property(env, objValue, "leftTopRadius", CreateJsNumber(env, rectStyle.leftTopRadius));
688         napi_set_named_property(env, objValue, "rightTopRadius", CreateJsNumber(env, rectStyle.rightTopRadius));
689         napi_set_named_property(env, objValue, "rightBottomRadius", CreateJsNumber(env, rectStyle.rightBottomRadius));
690         napi_set_named_property(env, objValue, "leftBottomRadius", CreateJsNumber(env, rectStyle.leftBottomRadius));
691     }
692     return objValue;
693 }
694 
CreateFontFeatureArrayJsValue(napi_env env,const FontFeatures & fontFeatures)695 napi_value CreateFontFeatureArrayJsValue(napi_env env, const FontFeatures& fontFeatures)
696 {
697     napi_value jsArray;
698     napi_status arrayStatus = napi_create_array(env, &jsArray);
699     if (arrayStatus != napi_ok) {
700         TEXT_LOGE("Failed to create fontFeature array, ret %{public}d", arrayStatus);
701         return nullptr;
702     }
703     const std::vector<std::pair<std::string, int>>& featureSet = fontFeatures.GetFontFeatures();
704     for (size_t i = 0; i < featureSet.size(); ++i) {
705         const auto& feature = featureSet[i];
706         napi_value jsObject;
707         napi_status status = napi_create_object(env, &jsObject);
708         if (status != napi_ok) {
709             TEXT_LOGE("Failed to create fontFeature, ret %{public}d", status);
710             continue;
711         }
712         napi_set_named_property(env, jsObject, "name", CreateStringJsValue(env, Str8ToStr16(feature.first)));
713         napi_set_named_property(env, jsObject, "value", CreateJsNumber(env, feature.second));
714         status = napi_set_element(env, jsArray, i, jsObject);
715         if (status != napi_ok) {
716             TEXT_LOGE("Failed to set fontFeature, ret %{public}d", status);
717             continue;
718         }
719     }
720 
721     return jsArray;
722 }
723 
CreateDecrationJsValue(napi_env env,TextStyle textStyle)724 napi_value CreateDecrationJsValue(napi_env env, TextStyle textStyle)
725 {
726     napi_value objValue = nullptr;
727     napi_create_object(env, &objValue);
728     if (objValue != nullptr) {
729         napi_set_named_property(
730             env, objValue, "textDecoration", CreateJsNumber(env, static_cast<uint32_t>(textStyle.decoration)));
731         napi_set_named_property(
732             env, objValue, "color", CreateJsNumber(env, (uint32_t)textStyle.decorationColor.CastToColorQuad()));
733         napi_set_named_property(
734             env, objValue, "decorationStyle", CreateJsNumber(env, static_cast<uint32_t>(textStyle.decorationStyle)));
735         napi_set_named_property(
736             env, objValue, "decorationThicknessScale", CreateJsNumber(env, textStyle.decorationThicknessScale));
737     }
738 
739     return objValue;
740 }
741 
CreateTextStyleJsValue(napi_env env,TextStyle textStyle)742 napi_value CreateTextStyleJsValue(napi_env env, TextStyle textStyle)
743 {
744     napi_value objValue = nullptr;
745     napi_create_object(env, &objValue);
746     if (objValue != nullptr) {
747         napi_set_named_property(env, objValue, "decoration", CreateDecrationJsValue(env, textStyle));
748         napi_set_named_property(env, objValue, "color", CreateJsNumber(env,
749             (uint32_t)textStyle.color.CastToColorQuad()));
750         napi_set_named_property(env, objValue, "fontWeight", CreateJsNumber(
751             env, static_cast<uint32_t>(textStyle.fontWeight)));
752         napi_set_named_property(env, objValue, "fontStyle", CreateJsNumber(
753             env, static_cast<uint32_t>(textStyle.fontStyle)));
754         napi_set_named_property(env, objValue, "baseline", CreateJsNumber(
755             env, static_cast<uint32_t>(textStyle.baseline)));
756         napi_set_named_property(env, objValue, "fontFamilies", CreateArrayStringJsValue(env, textStyle.fontFamilies));
757         napi_set_named_property(env, objValue, "fontSize", CreateJsNumber(env, textStyle.fontSize));
758         napi_set_named_property(env, objValue, "letterSpacing", CreateJsNumber(env, textStyle.letterSpacing));
759         napi_set_named_property(env, objValue, "wordSpacing", CreateJsNumber(env, textStyle.wordSpacing));
760         napi_set_named_property(env, objValue, "heightScale", CreateJsNumber(env, textStyle.heightScale));
761         napi_set_named_property(env, objValue, "halfLeading", CreateJsValue(env, textStyle.halfLeading));
762         napi_set_named_property(env, objValue, "heightOnly", CreateJsValue(env, textStyle.heightOnly));
763         napi_set_named_property(env, objValue, "ellipsis", CreateStringJsValue(env, textStyle.ellipsis));
764         napi_set_named_property(env, objValue, "ellipsisMode", CreateJsNumber(
765             env, static_cast<uint32_t>(textStyle.ellipsisModal)));
766         napi_set_named_property(env, objValue, "locale", CreateJsValue(env, textStyle.locale));
767         napi_set_named_property(env, objValue, "baselineShift", CreateJsNumber(env, textStyle.baseLineShift));
768         napi_set_named_property(env, objValue, "backgroundRect", CreateRectStyleJsValue(env, textStyle.backgroundRect));
769         napi_set_named_property(env, objValue, "textShadows", CreateShadowArrayJsValue(env, textStyle.shadows));
770         napi_set_named_property(
771             env, objValue, "fontFeatures", CreateFontFeatureArrayJsValue(env, textStyle.fontFeatures));
772         napi_set_named_property(env, objValue, "badgeType", CreateJsNumber(
773             env, static_cast<uint32_t>(textStyle.badgeType)));
774     }
775     return objValue;
776 }
777 
778 struct NapiMap {
779     napi_value instance;
780     napi_value set_function;
781 };
782 
CreateNapiMap(napi_env env)783 static NapiMap CreateNapiMap(napi_env env)
784 {
785     NapiMap res = {nullptr, nullptr};
786     napi_valuetype value_type;
787 
788     napi_value global = nullptr;
789     if (napi_get_global(env, &global) != napi_ok || !global) {
790         return res;
791     }
792 
793     napi_value constructor = nullptr;
794     if (napi_get_named_property(env, global, "Map", &constructor) != napi_ok || !constructor) {
795         return res;
796     }
797 
798     if (napi_typeof(env, constructor, &value_type) != napi_ok || value_type != napi_valuetype::napi_function) {
799         return res;
800     }
801 
802     napi_value map_instance = nullptr;
803     if (napi_new_instance(env, constructor, 0, nullptr, &map_instance) != napi_ok || !map_instance) {
804         return res;
805     }
806 
807     napi_value map_set = nullptr;
808     if (napi_get_named_property(env, map_instance, "set", &map_set) != napi_ok || !map_set) {
809         return res;
810     }
811     if (napi_typeof(env, map_set, &value_type) != napi_ok || value_type != napi_valuetype::napi_function) {
812         return res;
813     }
814 
815     res.instance = map_instance;
816     res.set_function = map_set;
817 
818     return res;
819 }
820 
NapiMapSet(napi_env env,NapiMap & map,uint32_t key,const RunMetrics & runMetrics)821 static bool NapiMapSet(napi_env env, NapiMap& map, uint32_t key, const RunMetrics& runMetrics)
822 {
823     napi_value keyValue = nullptr;
824     keyValue = CreateJsNumber(env, key);
825     napi_value runMetricsValue = nullptr;
826     runMetricsValue = CreateRunMetricsJsValue(env, runMetrics);
827     if (!keyValue || !runMetricsValue) {
828         return false;
829     }
830     napi_value args[2] = {keyValue, runMetricsValue};
831     napi_status status = napi_call_function(env, map.instance, map.set_function, 2, args, nullptr);
832     if (status != napi_ok) {
833         return false;
834     }
835     return true;
836 }
837 
ConvertMapToNapiMap(napi_env env,const std::map<size_t,RunMetrics> & map)838 napi_value ConvertMapToNapiMap(napi_env env, const std::map<size_t, RunMetrics>& map)
839 {
840     auto mapReturn = CreateNapiMap(env);
841     for (const auto &[key, val] : map) {
842         NapiMapSet(env, mapReturn, static_cast<uint32_t>(key), val);
843     }
844     return mapReturn.instance;
845 }
846 
CreateFontMetricsJsValue(napi_env env,Drawing::FontMetrics & fontMetrics)847 napi_value CreateFontMetricsJsValue(napi_env env, Drawing::FontMetrics& fontMetrics)
848 {
849     napi_value objValue = nullptr;
850     napi_create_object(env, &objValue);
851     if (objValue != nullptr) {
852         napi_set_named_property(env, objValue, "flags", CreateJsNumber(env, fontMetrics.fFlags));
853         napi_set_named_property(env, objValue, "top", CreateJsNumber(env, fontMetrics.fTop)); // float type
854         napi_set_named_property(env, objValue, "ascent", CreateJsNumber(env, fontMetrics.fAscent));
855         napi_set_named_property(env, objValue, "descent", CreateJsNumber(env, fontMetrics.fDescent));
856         napi_set_named_property(env, objValue, "bottom", CreateJsNumber(env, fontMetrics.fBottom));
857         napi_set_named_property(env, objValue, "leading", CreateJsNumber(env, fontMetrics.fLeading));
858         napi_set_named_property(env, objValue, "avgCharWidth", CreateJsNumber(env, fontMetrics.fAvgCharWidth));
859         napi_set_named_property(env, objValue, "maxCharWidth", CreateJsNumber(env, fontMetrics.fMaxCharWidth));
860         napi_set_named_property(env, objValue, "xMin", CreateJsNumber(env, fontMetrics.fXMin));
861         napi_set_named_property(env, objValue, "xMax", CreateJsNumber(env, fontMetrics.fXMax));
862         napi_set_named_property(env, objValue, "xHeight", CreateJsNumber(env, fontMetrics.fXHeight));
863         napi_set_named_property(env, objValue, "capHeight", CreateJsNumber(env, fontMetrics.fCapHeight));
864         napi_set_named_property(env, objValue, "underlineThickness", CreateJsNumber(env,
865             fontMetrics.fUnderlineThickness));
866         napi_set_named_property(env, objValue, "underlinePosition", CreateJsNumber(env,
867             fontMetrics.fUnderlinePosition));
868         napi_set_named_property(env, objValue, "strikethroughThickness", CreateJsNumber(env,
869             fontMetrics.fStrikeoutThickness));
870         napi_set_named_property(env, objValue, "strikethroughPosition", CreateJsNumber(env,
871             fontMetrics.fStrikeoutPosition));
872     }
873     return objValue;
874 }
875 
GetFontMetricsAndConvertToJsValue(napi_env env,Drawing::FontMetrics * metrics)876 napi_value GetFontMetricsAndConvertToJsValue(napi_env env, Drawing::FontMetrics* metrics)
877 {
878     napi_value objValue = nullptr;
879     napi_create_object(env, &objValue);
880     if (metrics != nullptr && objValue != nullptr) {
881         napi_set_named_property(env, objValue, "top", CreateJsNumber(env, metrics->fTop));
882         napi_set_named_property(env, objValue, "ascent", CreateJsNumber(env, metrics->fAscent));
883         napi_set_named_property(env, objValue, "descent", CreateJsNumber(env, metrics->fDescent));
884         napi_set_named_property(env, objValue, "bottom", CreateJsNumber(env, metrics->fBottom));
885         napi_set_named_property(env, objValue, "leading", CreateJsNumber(env, metrics->fLeading));
886         napi_set_named_property(env, objValue, "flags", CreateJsNumber(env, metrics->fFlags));
887         napi_set_named_property(env, objValue, "avgCharWidth", CreateJsNumber(env, metrics->fAvgCharWidth));
888         napi_set_named_property(env, objValue, "maxCharWidth", CreateJsNumber(env, metrics->fMaxCharWidth));
889         napi_set_named_property(env, objValue, "xMin", CreateJsNumber(env, metrics->fXMin));
890         napi_set_named_property(env, objValue, "xMax", CreateJsNumber(env, metrics->fXMax));
891         napi_set_named_property(env, objValue, "xHeight", CreateJsNumber(env, metrics->fXHeight));
892         napi_set_named_property(env, objValue, "capHeight", CreateJsNumber(env, metrics->fCapHeight));
893         napi_set_named_property(env, objValue, "underlineThickness", CreateJsNumber(env,
894             metrics->fUnderlineThickness));
895         napi_set_named_property(env, objValue, "underlinePosition", CreateJsNumber(env,
896             metrics->fUnderlinePosition));
897         napi_set_named_property(env, objValue, "strikethroughThickness", CreateJsNumber(env,
898             metrics->fStrikeoutThickness));
899         napi_set_named_property(env, objValue, "strikethroughPosition", CreateJsNumber(env,
900             metrics->fStrikeoutPosition));
901     }
902     return objValue;
903 }
904 
GetTextTabFromJS(napi_env env,napi_value argValue,TextTab & tab)905 bool GetTextTabFromJS(napi_env env, napi_value argValue, TextTab& tab)
906 {
907     if (argValue == nullptr) {
908         return false;
909     }
910     napi_value tempValue = nullptr;
911     if (napi_get_named_property(env, argValue, "alignment", &tempValue) != napi_ok) {
912         TEXT_LOGE("Failed to get alignment");
913         return false;
914     }
915     uint32_t align = 0;
916     if (tempValue != nullptr && napi_get_value_uint32(env, tempValue, &align) == napi_ok) {
917         TextAlign textAlign;
918         switch (TextAlign(align)) {
919             case TextAlign::LEFT: {
920                 textAlign = TextAlign::LEFT;
921                 break;
922             }
923             case TextAlign::RIGHT: {
924                 textAlign = TextAlign::RIGHT;
925                 break;
926             }
927             case TextAlign::CENTER: {
928                 textAlign = TextAlign::CENTER;
929                 break;
930             }
931             default: {
932                 textAlign = TextAlign::LEFT;
933                 break;
934             }
935         }
936         tab.alignment = textAlign;
937     } else {
938         TEXT_LOGE("Invalid alignment");
939         return false;
940     }
941 
942     double location = 0;
943     if (napi_get_named_property(env, argValue, "location", &tempValue) != napi_ok) {
944         return false;
945     }
946     if (tempValue != nullptr && napi_get_value_double(env, tempValue, &location) == napi_ok) {
947         tab.location = location;
948     } else {
949         TEXT_LOGE("Invalid location");
950         return false;
951     }
952     return true;
953 }
954 
NapiValueTypeIsValid(napi_env env,napi_value argValue)955 bool NapiValueTypeIsValid(napi_env env, napi_value argValue)
956 {
957     napi_valuetype valueType;
958     if (napi_typeof(env, argValue, &valueType) != napi_ok || valueType == napi_null || valueType == napi_undefined) {
959         TEXT_LOGE("Invalid value type %{public}d", static_cast<int32_t>(valueType));
960         return false;
961     }
962     return true;
963 }
964 
GetTypographicBoundsAndConvertToJsValue(napi_env env,float ascent,float descent,float leading,float width)965 napi_value GetTypographicBoundsAndConvertToJsValue(napi_env env, float ascent,
966     float descent, float leading, float width)
967 {
968     napi_value objValue = nullptr;
969     napi_create_object(env, &objValue);
970     if (objValue != nullptr) {
971         napi_status status = napi_set_named_property(env, objValue, "ascent", CreateJsNumber(env, ascent));
972         if (status != napi_ok) {
973             TEXT_LOGE("Failed to set named property, ret %{public}d", status);
974             return nullptr;
975         }
976         status = napi_set_named_property(env, objValue, "descent", CreateJsNumber(env, descent));
977         if (status != napi_ok) {
978             TEXT_LOGE("Failed to set named property, ret %{public}d", status);
979             return nullptr;
980         }
981         status = napi_set_named_property(env, objValue, "leading", CreateJsNumber(env, leading));
982         if (status != napi_ok) {
983             TEXT_LOGE("Failed to set named property, ret %{public}d", status);
984             return nullptr;
985         }
986         status = napi_set_named_property(env, objValue, "width", CreateJsNumber(env, width));
987         if (status != napi_ok) {
988             TEXT_LOGE("Failed to set named property, ret %{public}d", status);
989             return nullptr;
990         }
991     }
992     return objValue;
993 }
994 
GetStartEndParams(napi_env env,napi_value arg,int64_t & start,int64_t & end)995 bool GetStartEndParams(napi_env env, napi_value arg, int64_t &start, int64_t &end)
996 {
997     napi_valuetype valueType = napi_undefined;
998     if (arg == nullptr || napi_typeof(env, arg, &valueType) != napi_ok || valueType != napi_object) {
999         TEXT_LOGE("Invalid arg");
1000         return false;
1001     }
1002 
1003     napi_value tempValue = nullptr;
1004     auto status = napi_get_named_property(env, arg, "start", &tempValue);
1005     if (status != napi_ok) {
1006         TEXT_LOGE("Failed to get start, ret %{public}d", static_cast<int>(status));
1007         return false;
1008     }
1009     bool isStartOk = ConvertFromJsValue(env, tempValue, start);
1010 
1011     status = napi_get_named_property(env, arg, "end", &tempValue);
1012     if (status != napi_ok) {
1013         TEXT_LOGE("Failed to get end, ret %{public}d", static_cast<int>(status));
1014         return false;
1015     }
1016     bool isEndOk = ConvertFromJsValue(env, tempValue, end);
1017     if (!isStartOk || !isEndOk || start < 0 || end < 0) {
1018         TEXT_LOGE("Invalid parameter, is start %{public}d, is end %{public}d, start %{public}" PRId64
1019         ", end %{public}" PRId64, isStartOk, isEndOk, start, end);
1020         return false;
1021     }
1022 
1023     return true;
1024 }
1025 } // namespace OHOS::Rosen
1026