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 "napi_common.h"
17
18 namespace OHOS::Rosen {
BindNativeFunction(napi_env env,napi_value object,const char * name,const char * moduleName,napi_callback func)19 void BindNativeFunction(napi_env env, napi_value object, const char* name, const char* moduleName, napi_callback func)
20 {
21 std::string fullName;
22 if (moduleName) {
23 fullName = moduleName;
24 fullName += '.';
25 }
26 fullName += name;
27 napi_value funcValue = nullptr;
28 napi_create_function(env, fullName.c_str(), fullName.size(), func, nullptr, &funcValue);
29 napi_set_named_property(env, object, fullName.c_str(), funcValue);
30 }
31
CreateJsError(napi_env env,int32_t errCode,const std::string & message)32 napi_value CreateJsError(napi_env env, int32_t errCode, const std::string& message)
33 {
34 napi_value result = nullptr;
35 napi_create_error(env, CreateJsValue(env, errCode), CreateJsValue(env, message), &result);
36 return result;
37 }
38
NapiThrowError(napi_env env,TextErrorCode err,const std::string & message)39 napi_value NapiThrowError(napi_env env, TextErrorCode err, const std::string& message)
40 {
41 napi_throw(env, CreateJsError(env, static_cast<int32_t>(err), message));
42 return NapiGetUndefined(env);
43 }
44
OnMakeFontFamilies(napi_env & env,napi_value jsValue,std::vector<std::string> & fontFamilies)45 bool OnMakeFontFamilies(napi_env& env, napi_value jsValue, std::vector<std::string> &fontFamilies)
46 {
47 if (jsValue == nullptr) {
48 return false;
49 }
50 uint32_t size = 0;
51 napi_get_array_length(env, jsValue, &size);
52 if (size == 0) {
53 return false;
54 }
55 for (uint32_t i = 0; i < size; i++) {
56 napi_value tempStr = nullptr;
57 napi_get_element(env, jsValue, i, &tempStr);
58 std::string text = "";
59 if (ConvertFromJsValue(env, tempStr, text)) {
60 fontFamilies.push_back(text);
61 }
62 }
63 return true;
64 }
65
SetColorFromJS(napi_env env,napi_value argValue,const std::string & str,Drawing::Color & colorSrc)66 bool SetColorFromJS(napi_env env, napi_value argValue, const std::string& str, Drawing::Color& colorSrc)
67 {
68 napi_value tempValue = nullptr;
69 napi_value tempValueChild = nullptr;
70 napi_get_named_property(env, argValue, str.c_str(), &tempValue);
71 if (tempValue == nullptr) {
72 return false;
73 }
74 int32_t alpha = 0;
75 int32_t red = 0;
76 int32_t green = 0;
77 int32_t blue = 0;
78 napi_get_named_property(env, tempValue, "alpha", &tempValueChild);
79 bool isAlphaOk = ConvertClampFromJsValue(env, tempValueChild, alpha, 0, Drawing::Color::RGB_MAX);
80 napi_get_named_property(env, tempValue, "red", &tempValueChild);
81 bool isRedOk = ConvertClampFromJsValue(env, tempValueChild, red, 0, Drawing::Color::RGB_MAX);
82 napi_get_named_property(env, tempValue, "green", &tempValueChild);
83 bool isGreenOk = ConvertClampFromJsValue(env, tempValueChild, green, 0, Drawing::Color::RGB_MAX);
84 napi_get_named_property(env, tempValue, "blue", &tempValueChild);
85 bool isBlueOk = ConvertClampFromJsValue(env, tempValueChild, blue, 0, Drawing::Color::RGB_MAX);
86 if (isAlphaOk && isRedOk && isGreenOk && isBlueOk) {
87 Drawing::Color color(Drawing::Color::ColorQuadSetARGB(alpha, red, green, blue));
88 colorSrc = color;
89 return true;
90 }
91 return false;
92 }
93
GetDecorationFromJS(napi_env env,napi_value argValue,const std::string & str,TextStyle & textStyle)94 bool GetDecorationFromJS(napi_env env, napi_value argValue, const std::string& str, TextStyle& textStyle)
95 {
96 if (argValue == nullptr) {
97 return false;
98 }
99 napi_value tempValue = nullptr;
100 napi_get_named_property(env, argValue, str.c_str(), &tempValue);
101 if (tempValue == nullptr) {
102 return false;
103 }
104
105 napi_value tempValueChild = nullptr;
106 napi_get_named_property(env, tempValue, "textDecoration", &tempValueChild);
107 uint32_t textDecoration = 0;
108 if (tempValueChild != nullptr && napi_get_value_uint32(env, tempValueChild, &textDecoration) == napi_ok) {
109 textStyle.decoration = TextDecoration(textDecoration);
110 }
111
112 SetColorFromJS(env, tempValue, "color", textStyle.decorationColor);
113
114 tempValueChild = nullptr;
115 napi_get_named_property(env, tempValue, "decorationStyle", &tempValueChild);
116 uint32_t decorationStyle = 0;
117 if (tempValueChild != nullptr && napi_get_value_uint32(env, tempValueChild, &decorationStyle) == napi_ok) {
118 textStyle.decorationStyle = TextDecorationStyle(decorationStyle);
119 }
120 SetDoubleValueFromJS(env, tempValue, "decorationThicknessScale", textStyle.decorationThicknessScale);
121 return true;
122 }
123
GetNamePropertyFromJS(napi_env env,napi_value argValue,const std::string & str,napi_value & propertyValue)124 bool GetNamePropertyFromJS(napi_env env, napi_value argValue, const std::string& str, napi_value& propertyValue)
125 {
126 bool result = false;
127 if (napi_has_named_property(env, argValue, str.c_str(), &result) != napi_ok || (!result)) {
128 return false;
129 }
130
131 if (napi_get_named_property(env, argValue, str.c_str(), &propertyValue) != napi_ok) {
132 return false;
133 }
134
135 return true;
136 }
137
ReceiveFontFeature(napi_env env,napi_value argValue,TextStyle & textStyle)138 void ReceiveFontFeature(napi_env env, napi_value argValue, TextStyle& textStyle)
139 {
140 napi_value allFeatureValue = nullptr;
141 napi_get_named_property(env, argValue, "fontFeatures", &allFeatureValue);
142 uint32_t arrayLength = 0;
143 if (napi_get_array_length(env, allFeatureValue, &arrayLength) != napi_ok ||
144 !arrayLength) {
145 TEXT_LOGE("The parameter of font features is unvaild");
146 return;
147 }
148
149 for (uint32_t further = 0; further < arrayLength; further++) {
150 napi_value singleElementValue;
151 if (napi_get_element(env, allFeatureValue, further, &singleElementValue) != napi_ok) {
152 TEXT_LOGE("This parameter of the font features is unvaild");
153 break;
154 }
155 napi_value featureElement;
156 std::string name;
157 if (napi_get_named_property(env, singleElementValue, "name", &featureElement) != napi_ok ||
158 !ConvertFromJsValue(env, featureElement, name)) {
159 TEXT_LOGE("This time that the name of parameter in font features is unvaild");
160 break;
161 }
162
163 int value = 0;
164 if (napi_get_named_property(env, singleElementValue, "value", &featureElement) != napi_ok ||
165 !ConvertFromJsValue(env, featureElement, value)) {
166 TEXT_LOGE("This time that the value of parameter in font features is unvaild");
167 break;
168 }
169 textStyle.fontFeatures.SetFeature(name, value);
170 }
171 return;
172 }
173
ReceiveFontVariation(napi_env env,napi_value argValue,TextStyle & textStyle)174 void ReceiveFontVariation(napi_env env, napi_value argValue, TextStyle& textStyle)
175 {
176 napi_value allVariationValue = nullptr;
177 napi_get_named_property(env, argValue, "fontVariations", &allVariationValue);
178 uint32_t arrayLength = 0;
179 if (napi_get_array_length(env, allVariationValue, &arrayLength) != napi_ok ||
180 !arrayLength) {
181 TEXT_LOGE("The parameter of font variations is unvaild");
182 return;
183 }
184
185 for (uint32_t further = 0; further < arrayLength; further++) {
186 napi_value singleElementValue;
187 if (napi_get_element(env, allVariationValue, further, &singleElementValue) != napi_ok) {
188 TEXT_LOGE("This parameter of the font variations is unvaild");
189 break;
190 }
191 napi_value variationElement;
192 std::string axis;
193 if (napi_get_named_property(env, singleElementValue, "axis", &variationElement) != napi_ok ||
194 !ConvertFromJsValue(env, variationElement, axis)) {
195 TEXT_LOGE("This time that the axis of parameter in font variations is unvaild");
196 break;
197 }
198
199 int value = 0;
200 if (napi_get_named_property(env, singleElementValue, "value", &variationElement) != napi_ok ||
201 !ConvertFromJsValue(env, variationElement, value)) {
202 TEXT_LOGE("This time that the value of parameter in font variations is unvaild");
203 break;
204 }
205 textStyle.fontVariations.SetAxisValue(axis, value);
206 }
207 return;
208 }
209
SetTextStyleBaseType(napi_env env,napi_value argValue,TextStyle & textStyle)210 void SetTextStyleBaseType(napi_env env, napi_value argValue, TextStyle& textStyle)
211 {
212 SetDoubleValueFromJS(env, argValue, "letterSpacing", textStyle.letterSpacing);
213 SetDoubleValueFromJS(env, argValue, "wordSpacing", textStyle.wordSpacing);
214 SetDoubleValueFromJS(env, argValue, "baselineShift", textStyle.baseLineShift);
215 SetDoubleValueFromJS(env, argValue, "heightScale", textStyle.heightScale);
216 SetBoolValueFromJS(env, argValue, "halfLeading", textStyle.halfLeading);
217 SetBoolValueFromJS(env, argValue, "heightOnly", textStyle.heightOnly);
218
219 textStyle.heightScale = textStyle.heightScale < 0 ? 0 : textStyle.heightScale;
220 }
221
ScanShadowValue(napi_env env,napi_value allShadowValue,uint32_t arrayLength,TextStyle & textStyle)222 void ScanShadowValue(napi_env env, napi_value allShadowValue, uint32_t arrayLength, TextStyle& textStyle)
223 {
224 textStyle.shadows.clear();
225 for (uint32_t further = 0; further < arrayLength; further++) {
226 napi_value element;
227 Drawing::Color colorSrc = OHOS::Rosen::Drawing::Color::COLOR_BLACK;
228 Drawing::Point offset(0, 0);
229 double runTimeRadius = 0;
230 if (napi_get_element(env, allShadowValue, further, &element) != napi_ok) {
231 TEXT_LOGE("The parameter of as private text-shadow is unvaild");
232 return;
233 }
234 SetColorFromJS(env, element, "color", colorSrc);
235
236 napi_value pointValue = nullptr;
237 if (napi_get_named_property(env, element, "point", &pointValue) != napi_ok) {
238 TEXT_LOGE("The parameter of as private point is unvaild");
239 return;
240 }
241 GetPointFromJsValue(env, pointValue, offset);
242
243 napi_value radius = nullptr;
244 if (napi_get_named_property(env, element, "blurRadius", &radius) != napi_ok ||
245 napi_get_value_double(env, radius, &runTimeRadius) != napi_ok) {
246 TEXT_LOGE("The parameter of as private blur radius is unvaild");
247 return;
248 }
249 textStyle.shadows.emplace_back(TextShadow(colorSrc, offset, runTimeRadius));
250 }
251 return;
252 }
253
SetTextShadowProperty(napi_env env,napi_value argValue,TextStyle & textStyle)254 void SetTextShadowProperty(napi_env env, napi_value argValue, TextStyle& textStyle)
255 {
256 napi_value allShadowValue = nullptr;
257 if (!GetNamePropertyFromJS(env, argValue, "textShadows", allShadowValue)) {
258 return;
259 }
260
261 uint32_t arrayLength = 0;
262 if (napi_get_array_length(env, allShadowValue, &arrayLength) != napi_ok) {
263 TEXT_LOGE("The parameter of text shadow is not array");
264 return;
265 }
266 ScanShadowValue(env, allShadowValue, arrayLength, textStyle);
267 return;
268 }
269
ParsePartTextStyle(napi_env env,napi_value argValue,TextStyle & textStyle)270 void ParsePartTextStyle(napi_env env, napi_value argValue, TextStyle& textStyle)
271 {
272 napi_value tempValue = nullptr;
273 napi_get_named_property(env, argValue, "fontWeight", &tempValue);
274 uint32_t fontWeight = 0;
275 if (tempValue != nullptr && napi_get_value_uint32(env, tempValue, &fontWeight) == napi_ok) {
276 textStyle.fontWeight = FontWeight(fontWeight);
277 }
278 napi_get_named_property(env, argValue, "fontStyle", &tempValue);
279 uint32_t fontStyle = 0;
280 if (tempValue != nullptr && napi_get_value_uint32(env, tempValue, &fontStyle) == napi_ok) {
281 textStyle.fontStyle = FontStyle(fontStyle);
282
283 // Let OBLIQUE be equal to ITALIC, it's a temp modify.
284 if (textStyle.fontStyle == FontStyle::OBLIQUE) {
285 textStyle.fontStyle = FontStyle::ITALIC;
286 }
287 }
288 napi_get_named_property(env, argValue, "baseline", &tempValue);
289 uint32_t baseline = 0;
290 if (tempValue != nullptr && napi_get_value_uint32(env, tempValue, &baseline) == napi_ok) {
291 textStyle.baseline = TextBaseline(baseline);
292 }
293 SetDoubleValueFromJS(env, argValue, "fontSize", textStyle.fontSize);
294
295 std::vector<std::string> fontFamilies;
296 napi_get_named_property(env, argValue, "fontFamilies", &tempValue);
297 if (tempValue != nullptr && OnMakeFontFamilies(env, tempValue, fontFamilies)) {
298 textStyle.fontFamilies = fontFamilies;
299 }
300 GetDecorationFromJS(env, argValue, "decoration", textStyle);
301 SetTextStyleBaseType(env, argValue, textStyle);
302 ReceiveFontFeature(env, argValue, textStyle);
303 ReceiveFontVariation(env, argValue, textStyle);
304 napi_get_named_property(env, argValue, "ellipsis", &tempValue);
305 std::string text = "";
306 if (tempValue != nullptr && ConvertFromJsValue(env, tempValue, text)) {
307 textStyle.ellipsis = Str8ToStr16(text);
308 }
309 napi_get_named_property(env, argValue, "ellipsisMode", &tempValue);
310 uint32_t ellipsisModal = 0;
311 if (tempValue != nullptr && napi_get_value_uint32(env, tempValue, &ellipsisModal)== napi_ok) {
312 textStyle.ellipsisModal = EllipsisModal(ellipsisModal);
313 }
314 napi_get_named_property(env, argValue, "locale", &tempValue);
315 std::string textLocale = "";
316 if (tempValue != nullptr && ConvertFromJsValue(env, tempValue, textLocale)) {
317 textStyle.locale = textLocale;
318 }
319 }
320
GetTextStyleFromJS(napi_env env,napi_value argValue,TextStyle & textStyle)321 bool GetTextStyleFromJS(napi_env env, napi_value argValue, TextStyle& textStyle)
322 {
323 napi_valuetype valueType = napi_undefined;
324 if (argValue == nullptr || napi_typeof(env, argValue, &valueType) != napi_ok || valueType != napi_object) {
325 return false;
326 }
327 SetColorFromJS(env, argValue, "color", textStyle.color);
328 ParsePartTextStyle(env, argValue, textStyle);
329 SetTextShadowProperty(env, argValue, textStyle);
330 SetRectStyleFromJS(env, argValue, textStyle.backgroundRect);
331 return true;
332 }
333
GetParagraphStyleFromJS(napi_env env,napi_value argValue,TypographyStyle & pographyStyle)334 bool GetParagraphStyleFromJS(napi_env env, napi_value argValue, TypographyStyle& pographyStyle)
335 {
336 if (argValue == nullptr) {
337 return false;
338 }
339 napi_value tempValue = nullptr;
340 napi_get_named_property(env, argValue, "textStyle", &tempValue);
341 TextStyle textStyle;
342 if (tempValue != nullptr && GetTextStyleFromJS(env, tempValue, textStyle)) {
343 pographyStyle.SetTextStyle(textStyle);
344 }
345 tempValue = nullptr;
346 napi_get_named_property(env, argValue, "textDirection", &tempValue);
347 uint32_t textDirection = 0;
348 if (tempValue != nullptr && napi_get_value_uint32(env, tempValue, &textDirection) == napi_ok) {
349 pographyStyle.textDirection = TextDirection(textDirection);
350 }
351 tempValue = nullptr;
352 napi_get_named_property(env, argValue, "align", &tempValue);
353 uint32_t align = 0;
354 if (tempValue != nullptr && napi_get_value_uint32(env, tempValue, &align) == napi_ok) {
355 pographyStyle.textAlign = TextAlign(align);
356 }
357 tempValue = nullptr;
358 napi_get_named_property(env, argValue, "wordBreak", &tempValue);
359 uint32_t wordBreak = 0;
360 if (tempValue != nullptr && napi_get_value_uint32(env, tempValue, &wordBreak) == napi_ok) {
361 pographyStyle.wordBreakType = WordBreakType(wordBreak);
362 }
363 tempValue = nullptr;
364 napi_get_named_property(env, argValue, "maxLines", &tempValue);
365 int64_t maxLines = 0;
366 if (tempValue != nullptr && napi_get_value_int64(env, tempValue, &maxLines) == napi_ok) {
367 pographyStyle.maxLines = maxLines < 0 ? 0 : maxLines;
368 }
369 tempValue = nullptr;
370 napi_get_named_property(env, argValue, "breakStrategy", &tempValue);
371 uint32_t breakStrategy = 0;
372 if (tempValue != nullptr && napi_get_value_uint32(env, tempValue, &breakStrategy) == napi_ok) {
373 pographyStyle.breakStrategy = BreakStrategy(breakStrategy);
374 }
375
376 napi_value strutStyleValue = nullptr;
377 if (GetNamePropertyFromJS(env, argValue, "strutStyle", strutStyleValue)) {
378 SetStrutStyleFromJS(env, strutStyleValue, pographyStyle);
379 }
380
381 pographyStyle.ellipsis = textStyle.ellipsis;
382 pographyStyle.ellipsisModal = textStyle.ellipsisModal;
383
384 SetEnumValueFromJS(env, argValue, "textHeightBehavior", pographyStyle.textHeightBehavior);
385
386 return true;
387 }
388
GetPlaceholderSpanFromJS(napi_env env,napi_value argValue,PlaceholderSpan & placeholderSpan)389 bool GetPlaceholderSpanFromJS(napi_env env, napi_value argValue, PlaceholderSpan& placeholderSpan)
390 {
391 if (argValue == nullptr) {
392 return false;
393 }
394 napi_value tempValue = nullptr;
395 napi_get_named_property(env, argValue, "width", &tempValue);
396 double width = 0;
397 if (tempValue != nullptr && napi_get_value_double(env, tempValue, &width) == napi_ok) {
398 placeholderSpan.width = width;
399 } else {
400 return false;
401 }
402 tempValue = nullptr;
403 napi_get_named_property(env, argValue, "height", &tempValue);
404 double height = 0;
405 if (tempValue != nullptr && napi_get_value_double(env, tempValue, &height) == napi_ok) {
406 placeholderSpan.height = height;
407 } else {
408 return false;
409 }
410 tempValue = nullptr;
411 napi_get_named_property(env, argValue, "align", &tempValue);
412 uint32_t align = 0;
413 if (tempValue != nullptr && napi_get_value_uint32(env, tempValue, &align) == napi_ok) {
414 placeholderSpan.alignment = PlaceholderVerticalAlignment(align);
415 } else {
416 return false;
417 }
418 tempValue = nullptr;
419 napi_get_named_property(env, argValue, "baseline", &tempValue);
420 uint32_t baseline = 0;
421 if (tempValue != nullptr && napi_get_value_uint32(env, tempValue, &baseline) == napi_ok) {
422 placeholderSpan.baseline = TextBaseline(baseline);
423 } else {
424 return false;
425 }
426 tempValue = nullptr;
427 napi_get_named_property(env, argValue, "baselineOffset", &tempValue);
428 double baselineOffset = 0;
429 if (tempValue != nullptr && napi_get_value_double(env, tempValue, &baselineOffset) == napi_ok) {
430 placeholderSpan.baselineOffset = baselineOffset;
431 } else {
432 return false;
433 }
434 return true;
435 }
436
GetParamLen(napi_env env,napi_value param)437 size_t GetParamLen(napi_env env, napi_value param)
438 {
439 size_t buffSize = 0;
440 napi_status status = napi_get_value_string_utf8(env, param, nullptr, 0, &buffSize);
441 if (status != napi_ok || buffSize == 0) {
442 return 0;
443 }
444 return buffSize;
445 }
446
GetFontMetricsFromJS(napi_env env,napi_value argValue,Drawing::FontMetrics & fontMetrics)447 bool GetFontMetricsFromJS(napi_env env, napi_value argValue, Drawing::FontMetrics& fontMetrics)
448 {
449 if (argValue == nullptr) {
450 return false;
451 }
452 napi_value tempValue = nullptr;
453 napi_get_named_property(env, argValue, "flags", &tempValue);
454 uint32_t flags = 0;
455 if (tempValue != nullptr && napi_get_value_uint32(env, tempValue, &flags) == napi_ok) {
456 fontMetrics.fFlags = Drawing::FontMetrics::FontMetricsFlags(flags);
457 }
458 SetFontMetricsFloatValueFromJS(env, argValue, "top", fontMetrics.fTop);
459 SetFontMetricsFloatValueFromJS(env, argValue, "ascent", fontMetrics.fAscent);
460 SetFontMetricsFloatValueFromJS(env, argValue, "descent", fontMetrics.fDescent);
461 SetFontMetricsFloatValueFromJS(env, argValue, "bottom", fontMetrics.fBottom);
462 SetFontMetricsFloatValueFromJS(env, argValue, "leading", fontMetrics.fLeading);
463 SetFontMetricsFloatValueFromJS(env, argValue, "avgCharWidth", fontMetrics.fAvgCharWidth);
464 SetFontMetricsFloatValueFromJS(env, argValue, "maxCharWidth", fontMetrics.fMaxCharWidth);
465 SetFontMetricsFloatValueFromJS(env, argValue, "xMin", fontMetrics.fXMin);
466 SetFontMetricsFloatValueFromJS(env, argValue, "xMax", fontMetrics.fXMax);
467 SetFontMetricsFloatValueFromJS(env, argValue, "xHeight", fontMetrics.fXHeight);
468 SetFontMetricsFloatValueFromJS(env, argValue, "capHeight", fontMetrics.fCapHeight);
469 SetFontMetricsFloatValueFromJS(env, argValue, "underlineThickness", fontMetrics.fUnderlineThickness);
470 SetFontMetricsFloatValueFromJS(env, argValue, "underlinePosition", fontMetrics.fUnderlinePosition);
471 SetFontMetricsFloatValueFromJS(env, argValue, "strikethroughThickness", fontMetrics.fStrikeoutThickness);
472 SetFontMetricsFloatValueFromJS(env, argValue, "strikethroughPosition", fontMetrics.fStrikeoutPosition);
473 return true;
474 }
475
GetRunMetricsFromJS(napi_env env,napi_value argValue,RunMetrics & runMetrics)476 bool GetRunMetricsFromJS(napi_env env, napi_value argValue, RunMetrics& runMetrics)
477 {
478 if (argValue == nullptr) {
479 return false;
480 }
481 napi_value tempValue = nullptr;
482 napi_get_named_property(env, argValue, "textStyle", &tempValue);
483 OHOS::Rosen::TextStyle tempTextStyle;
484 if (tempValue != nullptr && GetTextStyleFromJS(env, tempValue, tempTextStyle)) {
485 runMetrics.textStyle = &tempTextStyle;
486 }
487
488 napi_get_named_property(env, argValue, "fontMetrics", &tempValue);
489 Drawing::FontMetrics tempFontMetrics;
490 if (tempValue != nullptr && GetFontMetricsFromJS(env, tempValue, tempFontMetrics)) {
491 runMetrics.fontMetrics = tempFontMetrics;
492 }
493 return true;
494 }
495
SetStrutStyleFromJS(napi_env env,napi_value strutStyleValue,TypographyStyle & typographyStyle)496 bool SetStrutStyleFromJS(napi_env env, napi_value strutStyleValue, TypographyStyle& typographyStyle)
497 {
498 napi_valuetype valueType = napi_undefined;
499 if (strutStyleValue == nullptr || napi_typeof(env, strutStyleValue, &valueType) != napi_ok ||
500 valueType != napi_object) {
501 TEXT_LOGE("Invalid strut style value");
502 return false;
503 }
504
505 napi_value tempValue = nullptr;
506 if (GetNamePropertyFromJS(env, strutStyleValue, "fontFamilies", tempValue)) {
507 std::vector<std::string> fontFamilies;
508 if (tempValue != nullptr && OnMakeFontFamilies(env, tempValue, fontFamilies)) {
509 typographyStyle.lineStyleFontFamilies = fontFamilies;
510 }
511 }
512
513 SetEnumValueFromJS(env, strutStyleValue, "fontStyle", typographyStyle.lineStyleFontStyle);
514 SetEnumValueFromJS(env, strutStyleValue, "fontWidth", typographyStyle.lineStyleFontWidth);
515 SetEnumValueFromJS(env, strutStyleValue, "fontWeight", typographyStyle.lineStyleFontWeight);
516
517 SetDoubleValueFromJS(env, strutStyleValue, "fontSize", typographyStyle.lineStyleFontSize);
518 SetDoubleValueFromJS(env, strutStyleValue, "height", typographyStyle.lineStyleHeightScale);
519 SetDoubleValueFromJS(env, strutStyleValue, "leading", typographyStyle.lineStyleSpacingScale);
520
521 SetBoolValueFromJS(env, strutStyleValue, "forceHeight", typographyStyle.lineStyleOnly);
522 SetBoolValueFromJS(env, strutStyleValue, "enabled", typographyStyle.useLineStyle);
523 SetBoolValueFromJS(env, strutStyleValue, "heightOverride", typographyStyle.lineStyleHeightOnly);
524 SetBoolValueFromJS(env, strutStyleValue, "halfLeading", typographyStyle.lineStyleHalfLeading);
525 return true;
526 }
527
SetRectStyleFromJS(napi_env env,napi_value argValue,RectStyle & rectStyle)528 void SetRectStyleFromJS(napi_env env, napi_value argValue, RectStyle& rectStyle)
529 {
530 if (!argValue) {
531 return;
532 }
533
534 napi_value tempValue = nullptr;
535 if (!GetNamePropertyFromJS(env, argValue, "backgroundRect", tempValue)) {
536 return;
537 }
538
539 Drawing::Color color;
540 SetColorFromJS(env, tempValue, "color", color);
541 rectStyle.color = color.CastToColorQuad();
542 SetDoubleValueFromJS(env, tempValue, "leftTopRadius", rectStyle.leftTopRadius);
543 SetDoubleValueFromJS(env, tempValue, "rightTopRadius", rectStyle.rightTopRadius);
544 SetDoubleValueFromJS(env, tempValue, "rightBottomRadius", rectStyle.rightBottomRadius);
545 SetDoubleValueFromJS(env, tempValue, "leftBottomRadius", rectStyle.leftBottomRadius);
546 }
547
CreateLineMetricsJsValue(napi_env env,OHOS::Rosen::LineMetrics & lineMetrics)548 napi_value CreateLineMetricsJsValue(napi_env env, OHOS::Rosen::LineMetrics& lineMetrics)
549 {
550 napi_value objValue = nullptr;
551 napi_create_object(env, &objValue);
552 if (objValue != nullptr) {
553 napi_set_named_property(env, objValue, "startIndex", CreateJsNumber(env, (uint32_t)lineMetrics.startIndex));
554 napi_set_named_property(env, objValue, "endIndex", CreateJsNumber(env, (uint32_t)lineMetrics.endIndex));
555 napi_set_named_property(env, objValue, "ascent", CreateJsNumber(env, lineMetrics.ascender));
556 napi_set_named_property(env, objValue, "descent", CreateJsNumber(env, lineMetrics.descender));
557 napi_set_named_property(env, objValue, "height", CreateJsNumber(env, lineMetrics.height));
558 napi_set_named_property(env, objValue, "width", CreateJsNumber(env, lineMetrics.width));
559 napi_set_named_property(env, objValue, "left", CreateJsNumber(env, lineMetrics.x));
560 napi_set_named_property(env, objValue, "baseline", CreateJsNumber(env, lineMetrics.baseline));
561 napi_set_named_property(env, objValue, "lineNumber", CreateJsNumber(env, lineMetrics.lineNumber));
562 napi_set_named_property(env, objValue, "topHeight", CreateJsNumber(env, lineMetrics.y));
563 napi_set_named_property(env, objValue, "runMetrics", ConvertMapToNapiMap(env, lineMetrics.runMetrics));
564 }
565 return objValue;
566 }
567
CreateTextStyleJsValue(napi_env env,TextStyle textStyle)568 napi_value CreateTextStyleJsValue(napi_env env, TextStyle textStyle)
569 {
570 napi_value objValue = nullptr;
571 napi_create_object(env, &objValue);
572 if (objValue != nullptr) {
573 napi_set_named_property(env, objValue, "decoration", CreateJsNumber(
574 env, static_cast<uint32_t>(textStyle.decoration)));
575 napi_set_named_property(env, objValue, "color", CreateJsNumber(env,
576 (uint32_t)textStyle.color.CastToColorQuad()));
577 napi_set_named_property(env, objValue, "fontWeight", CreateJsNumber(
578 env, static_cast<uint32_t>(textStyle.fontWeight)));
579 napi_set_named_property(env, objValue, "fontStyle", CreateJsNumber(
580 env, static_cast<uint32_t>(textStyle.fontStyle)));
581 napi_set_named_property(env, objValue, "baseline", CreateJsNumber(
582 env, static_cast<uint32_t>(textStyle.baseline)));
583 napi_set_named_property(env, objValue, "fontFamilies", CreateArrayStringJsValue(env, textStyle.fontFamilies));
584 napi_set_named_property(env, objValue, "fontSize", CreateJsNumber(env, textStyle.fontSize));
585 napi_set_named_property(env, objValue, "letterSpacing", CreateJsNumber(env, textStyle.letterSpacing));
586 napi_set_named_property(env, objValue, "wordSpacing", CreateJsNumber(env, textStyle.wordSpacing));
587 napi_set_named_property(env, objValue, "heightScale", CreateJsNumber(env, textStyle.heightScale));
588 napi_set_named_property(env, objValue, "halfLeading", CreateJsValue(env, textStyle.halfLeading));
589 napi_set_named_property(env, objValue, "heightOnly", CreateJsValue(env, textStyle.heightOnly));
590 napi_set_named_property(env, objValue, "ellipsis", CreateStringJsValue(env, textStyle.ellipsis));
591 napi_set_named_property(env, objValue, "ellipsisMode", CreateJsNumber(
592 env, static_cast<uint32_t>(textStyle.ellipsisModal)));
593 napi_set_named_property(env, objValue, "locale", CreateJsValue(env, textStyle.locale));
594 }
595 return objValue;
596 }
597
598 struct NapiMap {
599 napi_value instance;
600 napi_value set_function;
601 };
602
CreateNapiMap(napi_env env)603 static NapiMap CreateNapiMap(napi_env env)
604 {
605 NapiMap res = {nullptr, nullptr};
606 napi_valuetype value_type;
607
608 napi_value global = nullptr;
609 if (napi_get_global(env, &global) != napi_ok || !global) {
610 return res;
611 }
612
613 napi_value constructor = nullptr;
614 if (napi_get_named_property(env, global, "Map", &constructor) != napi_ok || !constructor) {
615 return res;
616 }
617
618 if (napi_typeof(env, constructor, &value_type) != napi_ok || value_type != napi_valuetype::napi_function) {
619 return res;
620 }
621
622 napi_value map_instance = nullptr;
623 if (napi_new_instance(env, constructor, 0, nullptr, &map_instance) != napi_ok || !map_instance) {
624 return res;
625 }
626
627 napi_value map_set = nullptr;
628 if (napi_get_named_property(env, map_instance, "set", &map_set) != napi_ok || !map_set) {
629 return res;
630 }
631 if (napi_typeof(env, map_set, &value_type) != napi_ok || value_type != napi_valuetype::napi_function) {
632 return res;
633 }
634
635 res.instance = map_instance;
636 res.set_function = map_set;
637
638 return res;
639 }
640
NapiMapSet(napi_env env,NapiMap & map,uint32_t key,const RunMetrics & runMetrics)641 static bool NapiMapSet(napi_env env, NapiMap& map, uint32_t key, const RunMetrics& runMetrics)
642 {
643 napi_value keyValue = nullptr;
644 keyValue = CreateJsNumber(env, key);
645 napi_value runMetricsValue = nullptr;
646 runMetricsValue = CreateRunMetricsJsValue(env, runMetrics);
647 if (!keyValue || !runMetricsValue) {
648 return false;
649 }
650 napi_value args[2] = {keyValue, runMetricsValue};
651 napi_status status = napi_call_function(env, map.instance, map.set_function, 2, args, nullptr);
652 if (status != napi_ok) {
653 return false;
654 }
655 return true;
656 }
657
ConvertMapToNapiMap(napi_env env,const std::map<size_t,RunMetrics> & map)658 napi_value ConvertMapToNapiMap(napi_env env, const std::map<size_t, RunMetrics>& map)
659 {
660 auto mapReturn = CreateNapiMap(env);
661 for (const auto &[key, val] : map) {
662 NapiMapSet(env, mapReturn, static_cast<uint32_t>(key), val);
663 }
664 return mapReturn.instance;
665 }
666
CreateFontMetricsJsValue(napi_env env,Drawing::FontMetrics & fontMetrics)667 napi_value CreateFontMetricsJsValue(napi_env env, Drawing::FontMetrics& fontMetrics)
668 {
669 napi_value objValue = nullptr;
670 napi_create_object(env, &objValue);
671 if (objValue != nullptr) {
672 napi_set_named_property(env, objValue, "flags", CreateJsNumber(env, fontMetrics.fFlags));
673 napi_set_named_property(env, objValue, "top", CreateJsNumber(env, fontMetrics.fTop)); // float type
674 napi_set_named_property(env, objValue, "ascent", CreateJsNumber(env, fontMetrics.fAscent));
675 napi_set_named_property(env, objValue, "descent", CreateJsNumber(env, fontMetrics.fDescent));
676 napi_set_named_property(env, objValue, "bottom", CreateJsNumber(env, fontMetrics.fBottom));
677 napi_set_named_property(env, objValue, "leading", CreateJsNumber(env, fontMetrics.fLeading));
678 napi_set_named_property(env, objValue, "avgCharWidth", CreateJsNumber(env, fontMetrics.fAvgCharWidth));
679 napi_set_named_property(env, objValue, "maxCharWidth", CreateJsNumber(env, fontMetrics.fMaxCharWidth));
680 napi_set_named_property(env, objValue, "xMin", CreateJsNumber(env, fontMetrics.fXMin));
681 napi_set_named_property(env, objValue, "xMax", CreateJsNumber(env, fontMetrics.fXMax));
682 napi_set_named_property(env, objValue, "xHeight", CreateJsNumber(env, fontMetrics.fXHeight));
683 napi_set_named_property(env, objValue, "capHeight", CreateJsNumber(env, fontMetrics.fCapHeight));
684 napi_set_named_property(env, objValue, "underlineThickness", CreateJsNumber(env,
685 fontMetrics.fUnderlineThickness));
686 napi_set_named_property(env, objValue, "underlinePosition", CreateJsNumber(env,
687 fontMetrics.fUnderlinePosition));
688 napi_set_named_property(env, objValue, "strikethroughThickness", CreateJsNumber(env,
689 fontMetrics.fStrikeoutThickness));
690 napi_set_named_property(env, objValue, "strikethroughPosition", CreateJsNumber(env,
691 fontMetrics.fStrikeoutPosition));
692 }
693 return objValue;
694 }
695 } // namespace OHOS::Rosen
696