• 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 "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     if (argValue == nullptr) {
324         return false;
325     }
326     SetColorFromJS(env, argValue, "color", textStyle.color);
327     ParsePartTextStyle(env, argValue, textStyle);
328     SetTextShadowProperty(env, argValue, textStyle);
329     SetRectStyleFromJS(env, argValue, textStyle.backgroundRect);
330     return true;
331 }
332 
GetParagraphStyleFromJS(napi_env env,napi_value argValue,TypographyStyle & pographyStyle)333 bool GetParagraphStyleFromJS(napi_env env, napi_value argValue, TypographyStyle& pographyStyle)
334 {
335     if (argValue == nullptr) {
336         return false;
337     }
338     napi_value tempValue = nullptr;
339     napi_get_named_property(env, argValue, "textStyle", &tempValue);
340     TextStyle textStyle;
341     if (tempValue != nullptr && GetTextStyleFromJS(env, tempValue, textStyle)) {
342         pographyStyle.SetTextStyle(textStyle);
343     }
344     tempValue = nullptr;
345     napi_get_named_property(env, argValue, "textDirection", &tempValue);
346     uint32_t textDirection = 0;
347     if (tempValue != nullptr && napi_get_value_uint32(env, tempValue, &textDirection) == napi_ok) {
348         pographyStyle.textDirection = TextDirection(textDirection);
349     }
350     tempValue = nullptr;
351     napi_get_named_property(env, argValue, "align", &tempValue);
352     uint32_t align = 0;
353     if (tempValue != nullptr && napi_get_value_uint32(env, tempValue, &align) == napi_ok) {
354         pographyStyle.textAlign = TextAlign(align);
355     }
356     tempValue = nullptr;
357     napi_get_named_property(env, argValue, "wordBreak", &tempValue);
358     uint32_t wordBreak = 0;
359     if (tempValue != nullptr && napi_get_value_uint32(env, tempValue, &wordBreak) == napi_ok) {
360         pographyStyle.wordBreakType = WordBreakType(wordBreak);
361     }
362     tempValue = nullptr;
363     napi_get_named_property(env, argValue, "maxLines", &tempValue);
364     int64_t maxLines = 0;
365     if (tempValue != nullptr && napi_get_value_int64(env, tempValue, &maxLines) == napi_ok) {
366         pographyStyle.maxLines = maxLines < 0 ? 0 : maxLines;
367     }
368     tempValue = nullptr;
369     napi_get_named_property(env, argValue, "breakStrategy", &tempValue);
370     uint32_t breakStrategy = 0;
371     if (tempValue != nullptr && napi_get_value_uint32(env, tempValue, &breakStrategy) == napi_ok) {
372         pographyStyle.breakStrategy = BreakStrategy(breakStrategy);
373     }
374 
375     napi_value strutStyleValue = nullptr;
376     if (GetNamePropertyFromJS(env, argValue, "strutStyle", strutStyleValue)) {
377         SetStrutStyleFromJS(env, strutStyleValue, pographyStyle);
378     }
379 
380     pographyStyle.ellipsis = textStyle.ellipsis;
381     pographyStyle.ellipsisModal = textStyle.ellipsisModal;
382 
383     SetEnumValueFromJS(env, argValue, "textHeightBehavior", pographyStyle.textHeightBehavior);
384 
385     return true;
386 }
387 
GetPlaceholderSpanFromJS(napi_env env,napi_value argValue,PlaceholderSpan & placeholderSpan)388 bool GetPlaceholderSpanFromJS(napi_env env, napi_value argValue, PlaceholderSpan& placeholderSpan)
389 {
390     if (argValue == nullptr) {
391         return false;
392     }
393     napi_value tempValue = nullptr;
394     napi_get_named_property(env, argValue, "width", &tempValue);
395     double width = 0;
396     if (tempValue != nullptr && napi_get_value_double(env, tempValue, &width) == napi_ok) {
397         placeholderSpan.width = width;
398     } else {
399         return false;
400     }
401     tempValue = nullptr;
402     napi_get_named_property(env, argValue, "height", &tempValue);
403     double height = 0;
404     if (tempValue != nullptr && napi_get_value_double(env, tempValue, &height) == napi_ok) {
405         placeholderSpan.height = height;
406     } else {
407         return false;
408     }
409     tempValue = nullptr;
410     napi_get_named_property(env, argValue, "align", &tempValue);
411     uint32_t align = 0;
412     if (tempValue != nullptr && napi_get_value_uint32(env, tempValue, &align) == napi_ok) {
413         placeholderSpan.alignment = PlaceholderVerticalAlignment(align);
414     } else {
415         return false;
416     }
417     tempValue = nullptr;
418     napi_get_named_property(env, argValue, "baseline", &tempValue);
419     uint32_t baseline = 0;
420     if (tempValue != nullptr && napi_get_value_uint32(env, tempValue, &baseline) == napi_ok) {
421         placeholderSpan.baseline = TextBaseline(baseline);
422     } else {
423         return false;
424     }
425     tempValue = nullptr;
426     napi_get_named_property(env, argValue, "baselineOffset", &tempValue);
427     double baselineOffset = 0;
428     if (tempValue != nullptr && napi_get_value_double(env, tempValue, &baselineOffset) == napi_ok) {
429         placeholderSpan.baselineOffset = baselineOffset;
430     } else {
431         return false;
432     }
433     return true;
434 }
435 
GetParamLen(napi_env env,napi_value param)436 size_t GetParamLen(napi_env env, napi_value param)
437 {
438     size_t buffSize = 0;
439     napi_status status = napi_get_value_string_utf8(env, param, nullptr, 0, &buffSize);
440     if (status != napi_ok || buffSize == 0) {
441         return 0;
442     }
443     return buffSize;
444 }
445 
GetFontMetricsFromJS(napi_env env,napi_value argValue,Drawing::FontMetrics & fontMetrics)446 bool GetFontMetricsFromJS(napi_env env, napi_value argValue, Drawing::FontMetrics& fontMetrics)
447 {
448     if (argValue == nullptr) {
449         return false;
450     }
451     napi_value tempValue = nullptr;
452     napi_get_named_property(env, argValue, "flags", &tempValue);
453     uint32_t flags = 0;
454     if (tempValue != nullptr && napi_get_value_uint32(env, tempValue, &flags) == napi_ok) {
455         fontMetrics.fFlags = Drawing::FontMetrics::FontMetricsFlags(flags);
456     }
457     SetFontMetricsFloatValueFromJS(env, argValue, "top", fontMetrics.fTop);
458     SetFontMetricsFloatValueFromJS(env, argValue, "ascent", fontMetrics.fAscent);
459     SetFontMetricsFloatValueFromJS(env, argValue, "descent", fontMetrics.fDescent);
460     SetFontMetricsFloatValueFromJS(env, argValue, "bottom", fontMetrics.fBottom);
461     SetFontMetricsFloatValueFromJS(env, argValue, "leading", fontMetrics.fLeading);
462     SetFontMetricsFloatValueFromJS(env, argValue, "avgCharWidth", fontMetrics.fAvgCharWidth);
463     SetFontMetricsFloatValueFromJS(env, argValue, "maxCharWidth", fontMetrics.fMaxCharWidth);
464     SetFontMetricsFloatValueFromJS(env, argValue, "xMin", fontMetrics.fXMin);
465     SetFontMetricsFloatValueFromJS(env, argValue, "xMax", fontMetrics.fXMax);
466     SetFontMetricsFloatValueFromJS(env, argValue, "xHeight", fontMetrics.fXHeight);
467     SetFontMetricsFloatValueFromJS(env, argValue, "capHeight", fontMetrics.fCapHeight);
468     SetFontMetricsFloatValueFromJS(env, argValue, "underlineThickness", fontMetrics.fUnderlineThickness);
469     SetFontMetricsFloatValueFromJS(env, argValue, "underlinePosition", fontMetrics.fUnderlinePosition);
470     SetFontMetricsFloatValueFromJS(env, argValue, "strikethroughThickness", fontMetrics.fStrikeoutThickness);
471     SetFontMetricsFloatValueFromJS(env, argValue, "strikethroughPosition", fontMetrics.fStrikeoutPosition);
472     return true;
473 }
474 
GetRunMetricsFromJS(napi_env env,napi_value argValue,RunMetrics & runMetrics)475 bool GetRunMetricsFromJS(napi_env env, napi_value argValue, RunMetrics& runMetrics)
476 {
477     if (argValue == nullptr) {
478         return false;
479     }
480     napi_value tempValue = nullptr;
481     napi_get_named_property(env, argValue, "textStyle", &tempValue);
482     OHOS::Rosen::TextStyle tempTextStyle;
483     if (tempValue != nullptr && GetTextStyleFromJS(env, tempValue, tempTextStyle)) {
484         runMetrics.textStyle = &tempTextStyle;
485     }
486 
487     napi_get_named_property(env, argValue, "fontMetrics", &tempValue);
488     Drawing::FontMetrics tempFontMetrics;
489     if (tempValue != nullptr && GetFontMetricsFromJS(env, tempValue, tempFontMetrics)) {
490         runMetrics.fontMetrics = tempFontMetrics;
491     }
492     return true;
493 }
494 
SetStrutStyleFromJS(napi_env env,napi_value strutStyleValue,TypographyStyle & typographyStyle)495 void SetStrutStyleFromJS(napi_env env, napi_value strutStyleValue, TypographyStyle& typographyStyle)
496 {
497     napi_value tempValue = nullptr;
498     if (GetNamePropertyFromJS(env, strutStyleValue, "fontFamilies", tempValue)) {
499         std::vector<std::string> fontFamilies;
500         if (tempValue != nullptr && OnMakeFontFamilies(env, tempValue, fontFamilies)) {
501             typographyStyle.lineStyleFontFamilies = fontFamilies;
502         }
503     }
504 
505     SetEnumValueFromJS(env, strutStyleValue, "fontStyle", typographyStyle.lineStyleFontStyle);
506     SetEnumValueFromJS(env, strutStyleValue, "fontWidth", typographyStyle.lineStyleFontWidth);
507     SetEnumValueFromJS(env, strutStyleValue, "fontWeight", typographyStyle.lineStyleFontWeight);
508 
509     SetDoubleValueFromJS(env, strutStyleValue, "fontSize", typographyStyle.lineStyleFontSize);
510     SetDoubleValueFromJS(env, strutStyleValue, "height", typographyStyle.lineStyleHeightScale);
511     SetDoubleValueFromJS(env, strutStyleValue, "leading", typographyStyle.lineStyleSpacingScale);
512 
513     SetBoolValueFromJS(env, strutStyleValue, "forceHeight", typographyStyle.lineStyleOnly);
514     SetBoolValueFromJS(env, strutStyleValue, "enabled", typographyStyle.useLineStyle);
515     SetBoolValueFromJS(env, strutStyleValue, "heightOverride", typographyStyle.lineStyleHeightOnly);
516     SetBoolValueFromJS(env, strutStyleValue, "halfLeading", typographyStyle.lineStyleHalfLeading);
517 }
518 
SetRectStyleFromJS(napi_env env,napi_value argValue,RectStyle & rectStyle)519 void SetRectStyleFromJS(napi_env env, napi_value argValue, RectStyle& rectStyle)
520 {
521     if (!argValue) {
522         return;
523     }
524 
525     napi_value tempValue = nullptr;
526     if (!GetNamePropertyFromJS(env, argValue, "backgroundRect", tempValue)) {
527         return;
528     }
529 
530     Drawing::Color color;
531     SetColorFromJS(env, tempValue, "color", color);
532     rectStyle.color = color.CastToColorQuad();
533     SetDoubleValueFromJS(env, tempValue, "leftTopRadius", rectStyle.leftTopRadius);
534     SetDoubleValueFromJS(env, tempValue, "rightTopRadius", rectStyle.rightTopRadius);
535     SetDoubleValueFromJS(env, tempValue, "rightBottomRadius", rectStyle.rightBottomRadius);
536     SetDoubleValueFromJS(env, tempValue, "leftBottomRadius", rectStyle.leftBottomRadius);
537 }
538 
CreateLineMetricsJsValue(napi_env env,OHOS::Rosen::LineMetrics & lineMetrics)539 napi_value CreateLineMetricsJsValue(napi_env env, OHOS::Rosen::LineMetrics& lineMetrics)
540 {
541     napi_value objValue = nullptr;
542     napi_create_object(env, &objValue);
543     if (objValue != nullptr) {
544         napi_set_named_property(env, objValue, "startIndex", CreateJsNumber(env, (uint32_t)lineMetrics.startIndex));
545         napi_set_named_property(env, objValue, "endIndex", CreateJsNumber(env, (uint32_t)lineMetrics.endIndex));
546         napi_set_named_property(env, objValue, "ascent", CreateJsNumber(env, lineMetrics.ascender));
547         napi_set_named_property(env, objValue, "descent", CreateJsNumber(env, lineMetrics.descender));
548         napi_set_named_property(env, objValue, "height", CreateJsNumber(env, lineMetrics.height));
549         napi_set_named_property(env, objValue, "width", CreateJsNumber(env, lineMetrics.width));
550         napi_set_named_property(env, objValue, "left", CreateJsNumber(env, lineMetrics.x));
551         napi_set_named_property(env, objValue, "baseline", CreateJsNumber(env, lineMetrics.baseline));
552         napi_set_named_property(env, objValue, "lineNumber", CreateJsNumber(env, lineMetrics.lineNumber));
553         napi_set_named_property(env, objValue, "topHeight", CreateJsNumber(env, lineMetrics.y));
554         napi_set_named_property(env, objValue, "runMetrics", ConvertMapToNapiMap(env, lineMetrics.runMetrics));
555     }
556     return objValue;
557 }
558 
CreateTextStyleJsValue(napi_env env,TextStyle textStyle)559 napi_value CreateTextStyleJsValue(napi_env env, TextStyle textStyle)
560 {
561     napi_value objValue = nullptr;
562     napi_create_object(env, &objValue);
563     if (objValue != nullptr) {
564         napi_set_named_property(env, objValue, "decoration", CreateJsNumber(
565             env, static_cast<uint32_t>(textStyle.decoration)));
566         napi_set_named_property(env, objValue, "color", CreateJsNumber(env,
567             (uint32_t)textStyle.color.CastToColorQuad()));
568         napi_set_named_property(env, objValue, "fontWeight", CreateJsNumber(
569             env, static_cast<uint32_t>(textStyle.fontWeight)));
570         napi_set_named_property(env, objValue, "fontStyle", CreateJsNumber(
571             env, static_cast<uint32_t>(textStyle.fontStyle)));
572         napi_set_named_property(env, objValue, "baseline", CreateJsNumber(
573             env, static_cast<uint32_t>(textStyle.baseline)));
574         napi_set_named_property(env, objValue, "fontFamilies", CreateArrayStringJsValue(env, textStyle.fontFamilies));
575         napi_set_named_property(env, objValue, "fontSize", CreateJsNumber(env, textStyle.fontSize));
576         napi_set_named_property(env, objValue, "letterSpacing", CreateJsNumber(env, textStyle.letterSpacing));
577         napi_set_named_property(env, objValue, "wordSpacing", CreateJsNumber(env, textStyle.wordSpacing));
578         napi_set_named_property(env, objValue, "heightScale", CreateJsNumber(env, textStyle.heightScale));
579         napi_set_named_property(env, objValue, "halfLeading", CreateJsValue(env, textStyle.halfLeading));
580         napi_set_named_property(env, objValue, "heightOnly", CreateJsValue(env, textStyle.heightOnly));
581         napi_set_named_property(env, objValue, "ellipsis", CreateStringJsValue(env, textStyle.ellipsis));
582         napi_set_named_property(env, objValue, "ellipsisMode", CreateJsNumber(
583             env, static_cast<uint32_t>(textStyle.ellipsisModal)));
584         napi_set_named_property(env, objValue, "locale", CreateJsValue(env, textStyle.locale));
585     }
586     return objValue;
587 }
588 
589 struct NapiMap {
590     napi_value instance;
591     napi_value set_function;
592 };
593 
CreateNapiMap(napi_env env)594 static NapiMap CreateNapiMap(napi_env env)
595 {
596     NapiMap res = {nullptr, nullptr};
597     napi_valuetype value_type;
598 
599     napi_value global = nullptr;
600     if (napi_get_global(env, &global) != napi_ok || !global) {
601         return res;
602     }
603 
604     napi_value constructor = nullptr;
605     if (napi_get_named_property(env, global, "Map", &constructor) != napi_ok || !constructor) {
606         return res;
607     }
608 
609     if (napi_typeof(env, constructor, &value_type) != napi_ok || value_type != napi_valuetype::napi_function) {
610         return res;
611     }
612 
613     napi_value map_instance = nullptr;
614     if (napi_new_instance(env, constructor, 0, nullptr, &map_instance) != napi_ok || !map_instance) {
615         return res;
616     }
617 
618     napi_value map_set = nullptr;
619     if (napi_get_named_property(env, map_instance, "set", &map_set) != napi_ok || !map_set) {
620         return res;
621     }
622     if (napi_typeof(env, map_set, &value_type) != napi_ok || value_type != napi_valuetype::napi_function) {
623         return res;
624     }
625 
626     res.instance = map_instance;
627     res.set_function = map_set;
628 
629     return res;
630 }
631 
NapiMapSet(napi_env env,NapiMap & map,uint32_t key,const RunMetrics & runMetrics)632 static bool NapiMapSet(napi_env env, NapiMap& map, uint32_t key, const RunMetrics& runMetrics)
633 {
634     napi_value keyValue = nullptr;
635     keyValue = CreateJsNumber(env, key);
636     napi_value runMetricsValue = nullptr;
637     runMetricsValue = CreateRunMetricsJsValue(env, runMetrics);
638     if (!keyValue || !runMetricsValue) {
639         return false;
640     }
641     napi_value args[2] = {keyValue, runMetricsValue};
642     napi_status status = napi_call_function(env, map.instance, map.set_function, 2, args, nullptr);
643     if (status != napi_ok) {
644         return false;
645     }
646     return true;
647 }
648 
ConvertMapToNapiMap(napi_env env,const std::map<size_t,RunMetrics> & map)649 napi_value ConvertMapToNapiMap(napi_env env, const std::map<size_t, RunMetrics>& map)
650 {
651     auto mapReturn = CreateNapiMap(env);
652     for (const auto &[key, val] : map) {
653         NapiMapSet(env, mapReturn, static_cast<uint32_t>(key), val);
654     }
655     return mapReturn.instance;
656 }
657 
CreateFontMetricsJsValue(napi_env env,Drawing::FontMetrics & fontMetrics)658 napi_value CreateFontMetricsJsValue(napi_env env, Drawing::FontMetrics& fontMetrics)
659 {
660     napi_value objValue = nullptr;
661     napi_create_object(env, &objValue);
662     if (objValue != nullptr) {
663         napi_set_named_property(env, objValue, "flags", CreateJsNumber(env, fontMetrics.fFlags));
664         napi_set_named_property(env, objValue, "top", CreateJsNumber(env, fontMetrics.fTop)); // float type
665         napi_set_named_property(env, objValue, "ascent", CreateJsNumber(env, fontMetrics.fAscent));
666         napi_set_named_property(env, objValue, "descent", CreateJsNumber(env, fontMetrics.fDescent));
667         napi_set_named_property(env, objValue, "bottom", CreateJsNumber(env, fontMetrics.fBottom));
668         napi_set_named_property(env, objValue, "leading", CreateJsNumber(env, fontMetrics.fLeading));
669         napi_set_named_property(env, objValue, "avgCharWidth", CreateJsNumber(env, fontMetrics.fAvgCharWidth));
670         napi_set_named_property(env, objValue, "maxCharWidth", CreateJsNumber(env, fontMetrics.fMaxCharWidth));
671         napi_set_named_property(env, objValue, "xMin", CreateJsNumber(env, fontMetrics.fXMin));
672         napi_set_named_property(env, objValue, "xMax", CreateJsNumber(env, fontMetrics.fXMax));
673         napi_set_named_property(env, objValue, "xHeight", CreateJsNumber(env, fontMetrics.fXHeight));
674         napi_set_named_property(env, objValue, "capHeight", CreateJsNumber(env, fontMetrics.fCapHeight));
675         napi_set_named_property(env, objValue, "underlineThickness", CreateJsNumber(env,
676             fontMetrics.fUnderlineThickness));
677         napi_set_named_property(env, objValue, "underlinePosition", CreateJsNumber(env,
678             fontMetrics.fUnderlinePosition));
679         napi_set_named_property(env, objValue, "strikethroughThickness", CreateJsNumber(env,
680             fontMetrics.fStrikeoutThickness));
681         napi_set_named_property(env, objValue, "strikethroughPosition", CreateJsNumber(env,
682             fontMetrics.fStrikeoutPosition));
683     }
684     return objValue;
685 }
686 } // namespace OHOS::Rosen
687