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