• 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 "js_paragraph.h"
17 #include <cmath>
18 #include "canvas_napi/js_canvas.h"
19 #include "draw/canvas.h"
20 #include "napi_async_work.h"
21 #include "napi_common.h"
22 #include "paragraph_builder_napi/js_paragraph_builder.h"
23 #include "path_napi/js_path.h"
24 #include "recording/recording_canvas.h"
25 #include "text_line_napi/js_text_line.h"
26 #include "text_style.h"
27 #include "typography_style.h"
28 #include "utils/text_log.h"
29 
30 namespace OHOS::Rosen {
31 namespace {
32 const std::string CLASS_NAME = "Paragraph";
33 }
34 
35 std::mutex JsParagraph::constructorMutex_;
36 thread_local napi_ref JsParagraph::constructor_ = nullptr;
37 
Constructor(napi_env env,napi_callback_info info)38 napi_value JsParagraph::Constructor(napi_env env, napi_callback_info info)
39 {
40     napi_value jsThis = nullptr;
41     size_t argc = ARGC_ONE;
42     napi_value argv[ARGC_ONE] = {nullptr};
43     napi_status status = napi_get_cb_info(env, info, &argc, argv, &jsThis, nullptr);
44     if (status != napi_ok) {
45         TEXT_LOGE("Failed to get parameter, ret %{public}d", status);
46         return nullptr;
47     }
48 
49     void* nativePointer = nullptr;
50     if (!(argv[0] != nullptr && napi_get_value_external(env, argv[0], &nativePointer) == napi_ok)) {
51         TEXT_LOGE("Failed to convert");
52         return nullptr;
53     }
54 
55     std::shared_ptr<Typography> typography(static_cast<Typography*>(nativePointer));
56     if (typography == nullptr) {
57         TEXT_LOGE("Null typography");
58         return nullptr;
59     }
60 
61     JsParagraph* jsParagraph = new (std::nothrow) JsParagraph(typography);
62     if (jsParagraph == nullptr) {
63         return nullptr;
64     }
65 
66     status = napi_wrap(env, jsThis, jsParagraph,
67         JsParagraph::Destructor, nullptr, nullptr);
68     if (status != napi_ok) {
69         delete jsParagraph;
70         TEXT_LOGE("Failed to wrap paragraph, ret %{public}d", status);
71         return nullptr;
72     }
73     return jsThis;
74 }
75 
Init(napi_env env,napi_value exportObj)76 napi_value JsParagraph::Init(napi_env env, napi_value exportObj)
77 {
78     if (!CreateConstructor(env)) {
79         TEXT_LOGE("Failed to create constructor");
80         return nullptr;
81     }
82     napi_value constructor = nullptr;
83     napi_status status = napi_get_reference_value(env, constructor_, &constructor);
84     if (status != napi_ok) {
85         TEXT_LOGE("Failed to get reference, ret %{public}d", status);
86         return nullptr;
87     }
88 
89     status = napi_set_named_property(env, exportObj, CLASS_NAME.c_str(), constructor);
90     if (status != napi_ok) {
91         TEXT_LOGE("Failed to set named property, ret %{public}d", status);
92         return nullptr;
93     }
94     return exportObj;
95 }
96 
CreateConstructor(napi_env env)97 bool JsParagraph::CreateConstructor(napi_env env)
98 {
99     std::lock_guard<std::mutex> lock(constructorMutex_);
100     if (constructor_) {
101         return true;
102     }
103     napi_property_descriptor properties[] = {
104         DECLARE_NAPI_FUNCTION("layoutSync", JsParagraph::Layout),
105         DECLARE_NAPI_FUNCTION("paint", JsParagraph::Paint),
106         DECLARE_NAPI_FUNCTION("paintOnPath", JsParagraph::PaintOnPath),
107         DECLARE_NAPI_FUNCTION("getMaxWidth", JsParagraph::GetMaxWidth),
108         DECLARE_NAPI_FUNCTION("getHeight", JsParagraph::GetHeight),
109         DECLARE_NAPI_FUNCTION("getLongestLine", JsParagraph::GetLongestLine),
110         DECLARE_NAPI_FUNCTION("getLongestLineWithIndent", JsParagraph::GetLongestLineWithIndent),
111         DECLARE_NAPI_FUNCTION("getMinIntrinsicWidth", JsParagraph::GetMinIntrinsicWidth),
112         DECLARE_NAPI_FUNCTION("getMaxIntrinsicWidth", JsParagraph::GetMaxIntrinsicWidth),
113         DECLARE_NAPI_FUNCTION("getAlphabeticBaseline", JsParagraph::GetAlphabeticBaseline),
114         DECLARE_NAPI_FUNCTION("getIdeographicBaseline", JsParagraph::GetIdeographicBaseline),
115         DECLARE_NAPI_FUNCTION("getRectsForRange", JsParagraph::GetRectsForRange),
116         DECLARE_NAPI_FUNCTION("getRectsForPlaceholders", JsParagraph::GetRectsForPlaceholders),
117         DECLARE_NAPI_FUNCTION("getGlyphPositionAtCoordinate", JsParagraph::GetGlyphPositionAtCoordinate),
118         DECLARE_NAPI_FUNCTION("getWordBoundary", JsParagraph::GetWordBoundary),
119         DECLARE_NAPI_FUNCTION("getLineCount", JsParagraph::GetLineCount),
120         DECLARE_NAPI_FUNCTION("getLineHeight", JsParagraph::GetLineHeight),
121         DECLARE_NAPI_FUNCTION("getLineWidth", JsParagraph::GetLineWidth),
122         DECLARE_NAPI_FUNCTION("didExceedMaxLines", JsParagraph::DidExceedMaxLines),
123         DECLARE_NAPI_FUNCTION("getTextLines", JsParagraph::GetTextLines),
124         DECLARE_NAPI_FUNCTION("getActualTextRange", JsParagraph::GetActualTextRange),
125         DECLARE_NAPI_FUNCTION("getLineMetrics", JsParagraph::GetLineMetrics),
126         DECLARE_NAPI_FUNCTION("getFontMetricsByTextStyle", JsParagraph::GetFontMetricsByTextStyle),
127         DECLARE_NAPI_FUNCTION("getLineFontMetrics", JsParagraph::GetLineFontMetrics),
128         DECLARE_NAPI_FUNCTION("layout", JsParagraph::LayoutAsync),
129         DECLARE_NAPI_FUNCTION("isStrutStyleEqual", JsParagraph::IsStrutStyleEqual),
130         DECLARE_NAPI_FUNCTION("updateColor", JsParagraph::UpdateColor),
131         DECLARE_NAPI_FUNCTION("updateDecoration", JsParagraph::UpdateDecoration),
132     };
133     napi_value constructor = nullptr;
134     napi_status status = napi_define_class(env, CLASS_NAME.c_str(), NAPI_AUTO_LENGTH, Constructor, nullptr,
135         sizeof(properties) / sizeof(properties[0]), properties, &constructor);
136     if (status != napi_ok) {
137         TEXT_LOGE("Failed to define paragraph class, ret %{public}d", status);
138         return false;
139     }
140     status = napi_create_reference(env, constructor, 1, &constructor_);
141     if (status != napi_ok) {
142         TEXT_LOGE("Failed to create reference, ret %{public}d", status);
143         return false;
144     }
145     return true;
146 }
147 
Destructor(napi_env env,void * nativeObject,void * finalize)148 void JsParagraph::Destructor(napi_env env, void *nativeObject, void *finalize)
149 {
150     (void)finalize;
151     if (nativeObject != nullptr) {
152         JsParagraph *napi = reinterpret_cast<JsParagraph *>(nativeObject);
153         delete napi;
154     }
155 }
156 
Layout(napi_env env,napi_callback_info info)157 napi_value JsParagraph::Layout(napi_env env, napi_callback_info info)
158 {
159     JsParagraph* me = CheckParamsAndGetThis<JsParagraph>(env, info);
160     return (me != nullptr) ? me->OnLayout(env, info) : nullptr;
161 }
162 
OnLayout(napi_env env,napi_callback_info info)163 napi_value JsParagraph::OnLayout(napi_env env, napi_callback_info info)
164 {
165     if (paragraph_ == nullptr) {
166         TEXT_LOGE("Null paragraph");
167         return NapiThrowError(env, TextErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
168     }
169     size_t argc = ARGC_ONE;
170     napi_value argv[ARGC_ONE] = {nullptr};
171     napi_status status = napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
172     if (status != napi_ok || argc < ARGC_ONE) {
173         TEXT_LOGE("Failed to get parameter, argc %{public}zu, ret %{public}d", argc, status);
174         return NapiThrowError(env, TextErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
175     }
176     double width = 0.0;
177     if (!(argv[0] != nullptr && ConvertFromJsValue(env, argv[0], width))) {
178         TEXT_LOGE("Failed to convert");
179         return NapiGetUndefined(env);
180     }
181 
182     paragraph_->Layout(width);
183     return NapiGetUndefined(env);
184 }
185 
Paint(napi_env env,napi_callback_info info)186 napi_value JsParagraph::Paint(napi_env env, napi_callback_info info)
187 {
188     JsParagraph* me = CheckParamsAndGetThis<JsParagraph>(env, info);
189     return (me != nullptr) ? me->OnPaint(env, info) : nullptr;
190 }
191 
OnPaint(napi_env env,napi_callback_info info)192 napi_value JsParagraph::OnPaint(napi_env env, napi_callback_info info)
193 {
194     if (paragraph_ == nullptr) {
195         TEXT_LOGE("Null paragraph");
196         return NapiThrowError(env, TextErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
197     }
198     size_t argc = ARGC_THREE;
199     napi_value argv[ARGC_THREE] = {nullptr};
200     napi_status status = napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
201     if (status != napi_ok || argc < ARGC_THREE) {
202         TEXT_LOGE("Failed to get parameter, argc %{public}zu, ret %{public}d", argc, status);
203         return NapiThrowError(env, TextErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
204     }
205     if (argv[0] == nullptr) {
206         TEXT_LOGE("Null argv[0]");
207         return NapiGetUndefined(env);
208     }
209     Drawing::JsCanvas* jsCanvas = nullptr;
210     double x = 0.0;
211     double y = 0.0;
212     napi_unwrap(env, argv[0], reinterpret_cast<void **>(&jsCanvas));
213     if (!jsCanvas || !jsCanvas->GetCanvas() ||
214         !(argv[ARGC_ONE] != nullptr && ConvertFromJsValue(env, argv[ARGC_ONE], x) &&
215          argv[ARGC_TWO] != nullptr && ConvertFromJsValue(env, argv[ARGC_TWO], y))) {
216         TEXT_LOGE("Failed to get paint parameter");
217         return NapiGetUndefined(env);
218     }
219     paragraph_->Paint(jsCanvas->GetCanvas(), x, y);
220 
221     return NapiGetUndefined(env);
222 }
223 
PaintOnPath(napi_env env,napi_callback_info info)224 napi_value JsParagraph::PaintOnPath(napi_env env, napi_callback_info info)
225 {
226     JsParagraph* me = CheckParamsAndGetThis<JsParagraph>(env, info);
227     return (me != nullptr) ? me->OnPaintOnPath(env, info) : nullptr;
228 }
229 
OnPaintOnPath(napi_env env,napi_callback_info info)230 napi_value JsParagraph::OnPaintOnPath(napi_env env, napi_callback_info info)
231 {
232     if (paragraph_ == nullptr) {
233         TEXT_LOGE("Null paragraph");
234         return NapiThrowError(env, TextErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
235     }
236     size_t argc = ARGC_FOUR;
237     napi_value argv[ARGC_FOUR] = { nullptr };
238     napi_status status = napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
239     if (status != napi_ok || argc < ARGC_FOUR) {
240         TEXT_LOGE("Failed to get parameter, argc %{public}zu, ret %{public}d", argc, status);
241         return NapiThrowError(env, TextErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
242     }
243     Drawing::JsCanvas* jsCanvas = nullptr;
244     Drawing::JsPath* jsPath = nullptr;
245     double hOffset = 0.0;
246     double vOffset = 0.0;
247     napi_unwrap(env, argv[0], reinterpret_cast<void**>(&jsCanvas));
248     GET_UNWRAP_PARAM(ARGC_ONE, jsPath);
249     if (!jsCanvas || !jsCanvas->GetCanvas() || !jsPath || !jsPath->GetPath() ||
250         !(ConvertFromJsValue(env, argv[ARGC_TWO], hOffset) && ConvertFromJsValue(env, argv[ARGC_THREE], vOffset))) {
251         TEXT_LOGE("Failed to get paint parameter");
252         return NapiGetUndefined(env);
253     }
254     paragraph_->Paint(jsCanvas->GetCanvas(), jsPath->GetPath(), hOffset, vOffset);
255 
256     return NapiGetUndefined(env);
257 }
258 
GetMaxWidth(napi_env env,napi_callback_info info)259 napi_value JsParagraph::GetMaxWidth(napi_env env, napi_callback_info info)
260 {
261     JsParagraph* me = CheckParamsAndGetThis<JsParagraph>(env, info);
262     return (me != nullptr) ? me->OnGetMaxWidth(env, info) : nullptr;
263 }
264 
OnGetMaxWidth(napi_env env,napi_callback_info info)265 napi_value JsParagraph::OnGetMaxWidth(napi_env env, napi_callback_info info)
266 {
267     if (paragraph_ == nullptr) {
268         TEXT_LOGE("Null paragraph");
269         return NapiThrowError(env, TextErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
270     }
271     double maxWidth = paragraph_->GetMaxWidth();
272     return CreateJsNumber(env, maxWidth);
273 }
274 
GetHeight(napi_env env,napi_callback_info info)275 napi_value JsParagraph::GetHeight(napi_env env, napi_callback_info info)
276 {
277     JsParagraph* me = CheckParamsAndGetThis<JsParagraph>(env, info);
278     return (me != nullptr) ? me->OnGetHeight(env, info) : nullptr;
279 }
280 
OnGetHeight(napi_env env,napi_callback_info info)281 napi_value JsParagraph::OnGetHeight(napi_env env, napi_callback_info info)
282 {
283     if (paragraph_ == nullptr) {
284         TEXT_LOGE("Null paragraph");
285         return NapiThrowError(env, TextErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
286     }
287     double height = paragraph_->GetHeight();
288     return CreateJsNumber(env, height);
289 }
290 
GetLongestLine(napi_env env,napi_callback_info info)291 napi_value JsParagraph::GetLongestLine(napi_env env, napi_callback_info info)
292 {
293     JsParagraph* me = CheckParamsAndGetThis<JsParagraph>(env, info);
294     return (me != nullptr) ? me->OnGetLongestLine(env, info) : nullptr;
295 }
296 
OnGetLongestLine(napi_env env,napi_callback_info info)297 napi_value JsParagraph::OnGetLongestLine(napi_env env, napi_callback_info info)
298 {
299     if (paragraph_ == nullptr) {
300         TEXT_LOGE("Null paragraph");
301         return NapiThrowError(env, TextErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
302     }
303     double longestLine = paragraph_->GetActualWidth();
304     return CreateJsNumber(env, longestLine);
305 }
306 
GetLongestLineWithIndent(napi_env env,napi_callback_info info)307 napi_value JsParagraph::GetLongestLineWithIndent(napi_env env, napi_callback_info info)
308 {
309     JsParagraph* me = CheckParamsAndGetThis<JsParagraph>(env, info);
310     return (me != nullptr) ? me->OnGetLongestLineWithIndent(env, info) : nullptr;
311 }
312 
OnGetLongestLineWithIndent(napi_env env,napi_callback_info info)313 napi_value JsParagraph::OnGetLongestLineWithIndent(napi_env env, napi_callback_info info)
314 {
315     if (paragraph_ == nullptr) {
316         TEXT_LOGE("Null paragraph");
317         return NapiThrowError(env, TextErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
318     }
319     double longestLine = paragraph_->GetLongestLineWithIndent();
320     return CreateJsNumber(env, longestLine);
321 }
322 
GetMinIntrinsicWidth(napi_env env,napi_callback_info info)323 napi_value JsParagraph::GetMinIntrinsicWidth(napi_env env, napi_callback_info info)
324 {
325     JsParagraph* me = CheckParamsAndGetThis<JsParagraph>(env, info);
326     return (me != nullptr) ? me->OnGetMinIntrinsicWidth(env, info) : nullptr;
327 }
328 
OnGetMinIntrinsicWidth(napi_env env,napi_callback_info info)329 napi_value JsParagraph::OnGetMinIntrinsicWidth(napi_env env, napi_callback_info info)
330 {
331     if (paragraph_ == nullptr) {
332         TEXT_LOGE("Null paragraph");
333         return NapiThrowError(env, TextErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
334     }
335     double minIntrinsicWidth = paragraph_->GetMinIntrinsicWidth();
336     return CreateJsNumber(env, minIntrinsicWidth);
337 }
338 
GetMaxIntrinsicWidth(napi_env env,napi_callback_info info)339 napi_value JsParagraph::GetMaxIntrinsicWidth(napi_env env, napi_callback_info info)
340 {
341     JsParagraph* me = CheckParamsAndGetThis<JsParagraph>(env, info);
342     return (me != nullptr) ? me->OnGetMaxIntrinsicWidth(env, info) : nullptr;
343 }
344 
OnGetMaxIntrinsicWidth(napi_env env,napi_callback_info info)345 napi_value JsParagraph::OnGetMaxIntrinsicWidth(napi_env env, napi_callback_info info)
346 {
347     if (paragraph_ == nullptr) {
348         TEXT_LOGE("Null paragraph");
349         return NapiThrowError(env, TextErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
350     }
351     double maxIntrinsicWidth = paragraph_->GetMaxIntrinsicWidth();
352     return CreateJsNumber(env, maxIntrinsicWidth);
353 }
354 
GetAlphabeticBaseline(napi_env env,napi_callback_info info)355 napi_value JsParagraph::GetAlphabeticBaseline(napi_env env, napi_callback_info info)
356 {
357     JsParagraph* me = CheckParamsAndGetThis<JsParagraph>(env, info);
358     return (me != nullptr) ? me->OnGetAlphabeticBaseline(env, info) : nullptr;
359 }
360 
OnGetAlphabeticBaseline(napi_env env,napi_callback_info info)361 napi_value JsParagraph::OnGetAlphabeticBaseline(napi_env env, napi_callback_info info)
362 {
363     if (paragraph_ == nullptr) {
364         TEXT_LOGE("Null paragraph");
365         return NapiThrowError(env, TextErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
366     }
367     double alphabeticBaseline = paragraph_->GetAlphabeticBaseline();
368     return CreateJsNumber(env, alphabeticBaseline);
369 }
370 
GetIdeographicBaseline(napi_env env,napi_callback_info info)371 napi_value JsParagraph::GetIdeographicBaseline(napi_env env, napi_callback_info info)
372 {
373     JsParagraph* me = CheckParamsAndGetThis<JsParagraph>(env, info);
374     return (me != nullptr) ? me->OnGetIdeographicBaseline(env, info) : nullptr;
375 }
376 
OnGetIdeographicBaseline(napi_env env,napi_callback_info info)377 napi_value JsParagraph::OnGetIdeographicBaseline(napi_env env, napi_callback_info info)
378 {
379     if (paragraph_ == nullptr) {
380         TEXT_LOGE("Null paragraph");
381         return NapiThrowError(env, TextErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
382     }
383     double ideographicBaseline = paragraph_->GetIdeographicBaseline();
384     return CreateJsNumber(env, ideographicBaseline);
385 }
386 
GetRectsForRange(napi_env env,napi_callback_info info)387 napi_value JsParagraph::GetRectsForRange(napi_env env, napi_callback_info info)
388 {
389     JsParagraph* me = CheckParamsAndGetThis<JsParagraph>(env, info);
390     return (me != nullptr) ? me->OnGetRectsForRange(env, info) : nullptr;
391 }
392 
OnGetRectsForRange(napi_env env,napi_callback_info info)393 napi_value JsParagraph::OnGetRectsForRange(napi_env env, napi_callback_info info)
394 {
395     if (paragraph_ == nullptr) {
396         TEXT_LOGE("Null paragraph");
397         return NapiThrowError(env, TextErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
398     }
399     size_t argc = ARGC_THREE;
400     napi_value argv[ARGC_THREE] = {nullptr};
401     napi_status status = napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
402     if (status != napi_ok || argc < ARGC_THREE) {
403         TEXT_LOGE("Failed to get parameter, argc %{public}zu, ret %{public}d", argc, status);
404         return NapiThrowError(env, TextErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
405     }
406     napi_valuetype valueType = napi_undefined;
407     if (argv[0] == nullptr || napi_typeof(env, argv[0], &valueType) != napi_ok || valueType != napi_object) {
408         TEXT_LOGE("Invalid argv[0]");
409         return NapiGetUndefined(env);
410     }
411     napi_value tempValue = nullptr;
412     size_t start = 0;
413     size_t end = 0;
414     TextRectWidthStyle wstyle;
415     TextRectHeightStyle hstyle;
416     napi_get_named_property(env, argv[0], "start", &tempValue);
417     if (tempValue == nullptr) {
418         TEXT_LOGE("Failed to get start property");
419         return NapiGetUndefined(env);
420     }
421     bool isStartOk = ConvertFromJsValue(env, tempValue, start);
422     tempValue = nullptr;
423     napi_get_named_property(env, argv[0], "end", &tempValue);
424     if (tempValue == nullptr) {
425         TEXT_LOGE("Failed to get end property");
426         return NapiGetUndefined(env);
427     }
428     bool isEndOk = ConvertFromJsValue(env, tempValue, end);
429     if (!(isStartOk && isEndOk && argv[ARGC_ONE] != nullptr && ConvertFromJsValue(env, argv[ARGC_ONE], wstyle) &&
430         argv[ARGC_TWO] != nullptr && ConvertFromJsValue(env, argv[ARGC_TWO], hstyle))) {
431         TEXT_LOGE("Failed to convert, start ok:%{public}d, end ok:%{public}d", isStartOk, isEndOk);
432         return NapiGetUndefined(env);
433     }
434     std::vector<TextRect> rectsForRange = paragraph_->GetTextRectsByBoundary(start, end, hstyle, wstyle);
435     napi_value returnrectsForRange = nullptr;
436     NAPI_CALL(env, napi_create_array(env, &returnrectsForRange));
437     int num = static_cast<int>(rectsForRange.size());
438     for (int index = 0; index < num; ++index) {
439         napi_value tempValue2 = CreateTextRectJsValue(env, rectsForRange[index]);
440         NAPI_CALL(env, napi_set_element(env, returnrectsForRange, index, tempValue2));
441     }
442     return returnrectsForRange;
443 }
444 
GetRectsForPlaceholders(napi_env env,napi_callback_info info)445 napi_value JsParagraph::GetRectsForPlaceholders(napi_env env, napi_callback_info info)
446 {
447     JsParagraph* me = CheckParamsAndGetThis<JsParagraph>(env, info);
448     return (me != nullptr) ? me->OnGetRectsForPlaceholders(env, info) : nullptr;
449 }
450 
OnGetRectsForPlaceholders(napi_env env,napi_callback_info info)451 napi_value JsParagraph::OnGetRectsForPlaceholders(napi_env env, napi_callback_info info)
452 {
453     if (paragraph_ == nullptr) {
454         TEXT_LOGE("Null paragraph");
455         return NapiThrowError(env, TextErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
456     }
457     std::vector<TextRect> rectsForPlaceholders = paragraph_->GetTextRectsOfPlaceholders();
458     napi_value returnPlaceholders = nullptr;
459     NAPI_CALL(env, napi_create_array(env, &returnPlaceholders));
460     int num = static_cast<int>(rectsForPlaceholders.size());
461     for (int index = 0; index < num; ++index) {
462         napi_value tempValue = CreateTextRectJsValue(env, rectsForPlaceholders[index]);
463         if (tempValue != nullptr) {
464             NAPI_CALL(env, napi_set_element(env, returnPlaceholders, index, tempValue));
465         }
466     }
467     return returnPlaceholders;
468 }
469 
GetGlyphPositionAtCoordinate(napi_env env,napi_callback_info info)470 napi_value JsParagraph::GetGlyphPositionAtCoordinate(napi_env env, napi_callback_info info)
471 {
472     JsParagraph* me = CheckParamsAndGetThis<JsParagraph>(env, info);
473     return (me != nullptr) ? me->OnGetGlyphPositionAtCoordinate(env, info) : nullptr;
474 }
475 
OnGetGlyphPositionAtCoordinate(napi_env env,napi_callback_info info)476 napi_value JsParagraph::OnGetGlyphPositionAtCoordinate(napi_env env, napi_callback_info info)
477 {
478     if (paragraph_ == nullptr) {
479         TEXT_LOGE("Null paragraph");
480         return NapiThrowError(env, TextErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
481     }
482     size_t argc = ARGC_TWO;
483     napi_value argv[ARGC_TWO] = {nullptr};
484     napi_status status = napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
485     if (status != napi_ok || argc < ARGC_TWO) {
486         TEXT_LOGE("Failed to get parameter, arg %{public}zu, ret %{public}d", argc, status);
487         return NapiThrowError(env, TextErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
488     }
489     double dx = 0.0;
490     double dy = 0.0;
491     if (!(argv[0] != nullptr && ConvertFromJsValue(env, argv[0], dx) && argv[1] != nullptr &&
492         ConvertFromJsValue(env, argv[1], dy))) {
493         TEXT_LOGE("Failed to convert");
494         return NapiGetUndefined(env);
495     }
496     IndexAndAffinity positionWithAffinity = paragraph_->GetGlyphIndexByCoordinate(dx, dy);
497     return GetPositionWithAffinityAndConvertToJsValue(env, &positionWithAffinity);
498 }
499 
GetWordBoundary(napi_env env,napi_callback_info info)500 napi_value JsParagraph::GetWordBoundary(napi_env env, napi_callback_info info)
501 {
502     JsParagraph* me = CheckParamsAndGetThis<JsParagraph>(env, info);
503     return (me != nullptr) ? me->OnGetWordBoundary(env, info) : nullptr;
504 }
505 
OnGetWordBoundary(napi_env env,napi_callback_info info)506 napi_value JsParagraph::OnGetWordBoundary(napi_env env, napi_callback_info info)
507 {
508     if (paragraph_ == nullptr) {
509         TEXT_LOGE("Null paragraph");
510         return NapiThrowError(env, TextErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
511     }
512     size_t argc = ARGC_ONE;
513     napi_value argv[ARGC_ONE] = {nullptr};
514     napi_status status = napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
515     if (status != napi_ok || argc < ARGC_ONE) {
516         TEXT_LOGE("Failed to get parameter, argc %{public}zu, ret %{public}d", argc, status);
517         return NapiThrowError(env, TextErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
518     }
519     size_t offset = 0;
520     if (!(argv[0] != nullptr && ConvertFromJsValue(env, argv[0], offset))) {
521         TEXT_LOGE("Failed to convert");
522         return NapiGetUndefined(env);
523     }
524     Boundary range = paragraph_->GetWordBoundaryByIndex(offset);
525     return GetRangeAndConvertToJsValue(env, &range);
526 }
527 
GetLineCount(napi_env env,napi_callback_info info)528 napi_value JsParagraph::GetLineCount(napi_env env, napi_callback_info info)
529 {
530     JsParagraph* me = CheckParamsAndGetThis<JsParagraph>(env, info);
531     return (me != nullptr) ? me->OnGetLineCount(env, info) : nullptr;
532 }
533 
OnGetLineCount(napi_env env,napi_callback_info info)534 napi_value JsParagraph::OnGetLineCount(napi_env env, napi_callback_info info)
535 {
536     if (paragraph_ == nullptr) {
537         TEXT_LOGE("Null paragraph");
538         return NapiThrowError(env, TextErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
539     }
540     size_t lineCount = static_cast<size_t>(paragraph_->GetLineCount());
541     return CreateJsNumber(env, lineCount);
542 }
543 
GetLineHeight(napi_env env,napi_callback_info info)544 napi_value JsParagraph::GetLineHeight(napi_env env, napi_callback_info info)
545 {
546     JsParagraph* me = CheckParamsAndGetThis<JsParagraph>(env, info);
547     return (me != nullptr) ? me->OnGetLineHeight(env, info) : nullptr;
548 }
549 
OnGetLineHeight(napi_env env,napi_callback_info info)550 napi_value JsParagraph::OnGetLineHeight(napi_env env, napi_callback_info info)
551 {
552     if (paragraph_ == nullptr) {
553         TEXT_LOGE("Null paragraph");
554         return NapiThrowError(env, TextErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
555     }
556     size_t argc = ARGC_ONE;
557     napi_value argv[ARGC_ONE] = {nullptr};
558     napi_status status = napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
559     if (status != napi_ok || argc < ARGC_ONE) {
560         TEXT_LOGE("Failed to get parameter, argc %{public}zu, ret %{public}d", argc, status);
561         return NapiThrowError(env, TextErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
562     }
563     int lineNumber = 0;
564     if (!(argv[0] != nullptr && ConvertFromJsValue(env, argv[0], lineNumber))) {
565         TEXT_LOGE("Failed to convert");
566         return NapiGetUndefined(env);
567     }
568     double lineHeight = paragraph_->GetLineHeight(lineNumber);
569     return CreateJsNumber(env, lineHeight);
570 }
571 
GetLineWidth(napi_env env,napi_callback_info info)572 napi_value JsParagraph::GetLineWidth(napi_env env, napi_callback_info info)
573 {
574     JsParagraph* me = CheckParamsAndGetThis<JsParagraph>(env, info);
575     return (me != nullptr) ? me->OnGetLineWidth(env, info) : nullptr;
576 }
577 
OnGetLineWidth(napi_env env,napi_callback_info info)578 napi_value JsParagraph::OnGetLineWidth(napi_env env, napi_callback_info info)
579 {
580     if (paragraph_ == nullptr) {
581         TEXT_LOGE("Null paragraph");
582         return NapiThrowError(env, TextErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
583     }
584     size_t argc = ARGC_ONE;
585     napi_value argv[ARGC_ONE] = {nullptr};
586     napi_status status = napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
587     if (status != napi_ok || argc < ARGC_ONE) {
588         TEXT_LOGE("Failed to get parameter, argc %{public}zu, ret %{public}d", argc, status);
589         return NapiThrowError(env, TextErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
590     }
591     int lineNumber = 0;
592     if (!(argv[0] != nullptr && ConvertFromJsValue(env, argv[0], lineNumber))) {
593         TEXT_LOGE("Failed to convert line number");
594         return NapiGetUndefined(env);
595     }
596     double lineWidth = paragraph_->GetLineWidth(lineNumber);
597     return CreateJsNumber(env, lineWidth);
598 }
599 
DidExceedMaxLines(napi_env env,napi_callback_info info)600 napi_value JsParagraph::DidExceedMaxLines(napi_env env, napi_callback_info info)
601 {
602     JsParagraph* me = CheckParamsAndGetThis<JsParagraph>(env, info);
603     return (me != nullptr) ? me->OnDidExceedMaxLines(env, info) : nullptr;
604 }
605 
OnDidExceedMaxLines(napi_env env,napi_callback_info info)606 napi_value JsParagraph::OnDidExceedMaxLines(napi_env env, napi_callback_info info)
607 {
608     if (paragraph_ == nullptr) {
609         TEXT_LOGE("Null paragraph");
610         return NapiThrowError(env, TextErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
611     }
612     bool didExceedMaxLines = paragraph_->DidExceedMaxLines();
613     return CreateJsValue(env, didExceedMaxLines);
614 }
615 
GetActualTextRange(napi_env env,napi_callback_info info)616 napi_value JsParagraph::GetActualTextRange(napi_env env, napi_callback_info info)
617 {
618     JsParagraph* me = CheckParamsAndGetThis<JsParagraph>(env, info);
619     return (me != nullptr) ? me->OnGetActualTextRange(env, info) : nullptr;
620 }
621 
OnGetActualTextRange(napi_env env,napi_callback_info info)622 napi_value JsParagraph::OnGetActualTextRange(napi_env env, napi_callback_info info)
623 {
624     if (paragraph_ == nullptr) {
625         TEXT_LOGE("Null paragraph");
626         return NapiThrowError(env, TextErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
627     }
628 
629     size_t argc = ARGC_TWO;
630     napi_value argv[ARGC_TWO] = {nullptr};
631     napi_status status = napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
632     if (status != napi_ok || argc < ARGC_TWO) {
633         TEXT_LOGE("Failed to get parameter, argc %{public}zu, ret %{public}d", argc, status);
634         return NapiThrowError(env, TextErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
635     }
636     int lineNumber = 0;
637     if (!(ConvertFromJsValue(env, argv[0], lineNumber))) {
638         TEXT_LOGE("Failed to convert line number");
639         return NapiGetUndefined(env);
640     }
641     bool includeSpaces = false;
642     if (!(ConvertFromJsValue(env, argv[1], includeSpaces))) {
643         TEXT_LOGE("Failed to convert include spaces");
644         return NapiGetUndefined(env);
645     }
646     OHOS::Rosen::Boundary range = paragraph_->GetActualTextRange(lineNumber, includeSpaces);
647     return GetRangeAndConvertToJsValue(env, &range);
648 }
649 
GetLineMetrics(napi_env env,napi_callback_info info)650 napi_value JsParagraph::GetLineMetrics(napi_env env, napi_callback_info info)
651 {
652     size_t argc = ARGC_ONE;
653     napi_value argv[ARGC_ONE] = {nullptr};
654     napi_status status = napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
655     JsParagraph* me = CheckParamsAndGetThis<JsParagraph>(env, info);
656     if (status == napi_ok && argc < ARGC_ONE) {
657         return (me != nullptr) ? me->OnGetLineMetrics(env, info) : nullptr;
658     }
659     return (me != nullptr) ? me->OnGetLineMetricsAt(env, info) : nullptr;
660 }
661 
OnGetLineMetrics(napi_env env,napi_callback_info info)662 napi_value JsParagraph::OnGetLineMetrics(napi_env env, napi_callback_info info)
663 {
664     if (paragraph_ == nullptr) {
665         TEXT_LOGE("Null paragraph");
666         return NapiThrowError(env, TextErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
667     }
668     std::vector<LineMetrics> vectorLineMetrics = paragraph_->GetLineMetrics();
669     napi_value returnLineMetrics = nullptr;
670     NAPI_CALL(env, napi_create_array(env, &returnLineMetrics));
671     int num = static_cast<int>(vectorLineMetrics.size());
672     for (int index = 0; index < num; ++index) {
673         napi_value tempValue = CreateLineMetricsJsValue(env, vectorLineMetrics[index]);
674         napi_set_element(env, returnLineMetrics, index, tempValue);
675     }
676     return returnLineMetrics;
677 }
678 
OnGetLineMetricsAt(napi_env env,napi_callback_info info)679 napi_value JsParagraph::OnGetLineMetricsAt(napi_env env, napi_callback_info info)
680 {
681     if (paragraph_ == nullptr) {
682         TEXT_LOGE("Null paragraph");
683         return NapiThrowError(env, TextErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
684     }
685     size_t argc = ARGC_ONE;
686     napi_value argv[ARGC_ONE] = {nullptr};
687     napi_status status = napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
688     if (status != napi_ok || argc < ARGC_ONE) {
689         TEXT_LOGE("Failed to get parameter, argc %{public}zu, ret %{public}d", argc, status);
690         return NapiThrowError(env, TextErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
691     }
692     int lineNumber = 0;
693     if (!(ConvertFromJsValue(env, argv[0], lineNumber))) {
694         TEXT_LOGE("Failed to convert line number");
695         return NapiGetUndefined(env);
696     }
697     LineMetrics lineMetrics;
698     if (!paragraph_->GetLineMetricsAt(lineNumber, &lineMetrics)) {
699         TEXT_LOGE("Failed to get line metrics");
700         return nullptr;
701     }
702     return CreateLineMetricsJsValue(env, lineMetrics);
703 }
704 
GetFontMetricsByTextStyle(napi_env env,napi_callback_info info)705 napi_value JsParagraph::GetFontMetricsByTextStyle(napi_env env, napi_callback_info info)
706 {
707     JsParagraph* me = CheckParamsAndGetThis<JsParagraph>(env, info);
708     return (me != nullptr) ? me->OnGetFontMetricsByTextStyle(env, info) : nullptr;
709 }
710 
OnGetFontMetricsByTextStyle(napi_env env,napi_callback_info info)711 napi_value JsParagraph::OnGetFontMetricsByTextStyle(napi_env env, napi_callback_info info)
712 {
713     if (paragraph_ == nullptr) {
714         TEXT_LOGE("Null paragraph");
715         return NapiThrowError(env, TextErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
716     }
717     size_t argc = ARGC_ONE;
718     napi_value argv[ARGC_ONE] = {nullptr};
719     napi_status status = napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
720     if (status != napi_ok || argc < ARGC_ONE) {
721         TEXT_LOGE("Invalid argc %{public}zu", argc);
722         return NapiThrowError(env, TextErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
723     }
724     TextStyle textStyle;
725     if (!GetTextStyleFromJS(env, argv[0], textStyle)) {
726         TEXT_LOGE("Failed to convert text style");
727         return NapiThrowError(env, TextErrorCode::ERROR_INVALID_PARAM, "Invalid params");
728     }
729 
730     OHOS::Rosen::Drawing::FontMetrics fontmetrics = paragraph_->GetFontMetrics(textStyle);
731     return GetFontMetricsAndConvertToJsValue(env, &fontmetrics);
732 }
733 
GetLineFontMetrics(napi_env env,napi_callback_info info)734 napi_value JsParagraph::GetLineFontMetrics(napi_env env, napi_callback_info info)
735 {
736     JsParagraph* me = CheckParamsAndGetThis<JsParagraph>(env, info);
737     return (me != nullptr) ? me->OnGetLineFontMetrics(env, info) : nullptr;
738 }
739 
OnGetLineFontMetrics(napi_env env,napi_callback_info info)740 napi_value JsParagraph::OnGetLineFontMetrics(napi_env env, napi_callback_info info)
741 {
742     if (paragraph_ == nullptr) {
743         TEXT_LOGE("Null paragraph");
744         return NapiThrowError(env, TextErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
745     }
746     size_t argc = ARGC_ONE;
747     napi_value argv[ARGC_ONE] = {nullptr};
748     napi_status status = napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
749     if (status != napi_ok || argc < ARGC_ONE) {
750         TEXT_LOGE("Invalid argc %{public}zu", argc);
751         return NapiThrowError(env, TextErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
752     }
753     int lineNumber = 0;
754     if (!(ConvertFromJsValue(env, argv[0], lineNumber))) {
755         TEXT_LOGE("Invalid argv");
756         return NapiGetUndefined(env);
757     }
758 
759     napi_value returnFontMetrics = nullptr;
760     NAPI_CALL(env, napi_create_array(env, &returnFontMetrics));
761     size_t fontMetricsSize = 0;
762     std::vector<Drawing::FontMetrics> grabFontMetrics;
763     if (!paragraph_->GetLineFontMetrics(lineNumber, fontMetricsSize, grabFontMetrics)) {
764         TEXT_LOGE("Failed to get line font metrics");
765         return returnFontMetrics;
766     }
767 
768     int num = static_cast<int>(grabFontMetrics.size());
769     for (int index = 0; index < num; ++index) {
770         napi_value jsValue = GetFontMetricsAndConvertToJsValue(env, &grabFontMetrics[index]);
771         napi_set_element(env, returnFontMetrics, index, jsValue);
772     }
773     return returnFontMetrics;
774 }
775 
JsParagraph(std::shared_ptr<Typography> typography)776 JsParagraph::JsParagraph(std::shared_ptr<Typography> typography)
777     : paragraph_(typography)
778 {
779 }
780 
~JsParagraph()781 JsParagraph::~JsParagraph()
782 {
783 }
784 
GetParagraph()785 std::shared_ptr<Typography> JsParagraph::GetParagraph()
786 {
787     std::shared_ptr<Typography> typography = std::move(paragraph_);
788     return typography;
789 }
790 
CreateJsTypography(napi_env env,std::unique_ptr<Typography> typography)791 napi_value JsParagraph::CreateJsTypography(napi_env env, std::unique_ptr<Typography> typography)
792 {
793     if (!CreateConstructor(env)) {
794         TEXT_LOGE("Failed to create constructor");
795         return nullptr;
796     }
797     napi_value constructor = nullptr;
798     napi_value result = nullptr;
799     napi_status status = napi_get_reference_value(env, constructor_, &constructor);
800     if (status == napi_ok) {
801         napi_value argv = nullptr;
802         napi_create_external(
803             env, typography.release(), [](napi_env env, void* finalizeData, void* finalizeHint) {}, nullptr, &argv);
804         status = napi_new_instance(env, constructor, ARGC_ONE, &argv, &result);
805         if (status == napi_ok) {
806             return result;
807         } else {
808             TEXT_LOGE("Failed to new instance");
809         }
810     }
811     return result;
812 }
813 
GetTextLines(napi_env env,napi_callback_info info)814 napi_value JsParagraph::GetTextLines(napi_env env, napi_callback_info info)
815 {
816     JsParagraph* me = CheckParamsAndGetThis<JsParagraph>(env, info);
817     return (me != nullptr) ? me->OnGetTextLines(env, info) : nullptr;
818 }
819 
OnGetTextLines(napi_env env,napi_callback_info info)820 napi_value JsParagraph::OnGetTextLines(napi_env env, napi_callback_info info)
821 {
822     if (!paragraph_) {
823         TEXT_LOGE("Null paragraph");
824         return NapiThrowError(env, TextErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
825     }
826 
827     std::shared_ptr<Typography> paragraphCopy = paragraph_->CloneSelf();
828     if (!paragraphCopy) {
829         TEXT_LOGE("Failed to clone paragraph");
830         return NapiThrowError(env, TextErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
831     }
832 
833     std::vector<std::unique_ptr<TextLineBase>> textlineArr = paragraphCopy->GetTextLines();
834     napi_value array = nullptr;
835     NAPI_CALL(env, napi_create_array(env, &array));
836     uint32_t index = 0;
837     for (std::unique_ptr<TextLineBase>& item : textlineArr) {
838         napi_value itemObject = JsTextLine::CreateTextLine(env, info);
839         if (!itemObject) {
840             TEXT_LOGE("Failed to create text line");
841             continue;
842         }
843         JsTextLine* jsTextLine = nullptr;
844         napi_unwrap(env, itemObject, reinterpret_cast<void**>(&jsTextLine));
845         if (!jsTextLine) {
846             TEXT_LOGE("Failed to unwrap text line");
847             continue;
848         }
849         jsTextLine->SetTextLine(std::move(item));
850         jsTextLine->SetParagraph(paragraphCopy);
851 
852         napi_set_element(env, array, index++, itemObject);
853     }
854     return array;
855 }
856 
LayoutAsync(napi_env env,napi_callback_info info)857 napi_value JsParagraph::LayoutAsync(napi_env env, napi_callback_info info)
858 {
859     JsParagraph* me = CheckParamsAndGetThis<JsParagraph>(env, info);
860     return (me != nullptr) ? me->OnLayoutAsync(env, info) : nullptr;
861 }
862 
OnLayoutAsync(napi_env env,napi_callback_info info)863 napi_value JsParagraph::OnLayoutAsync(napi_env env, napi_callback_info info)
864 {
865     NAPI_CHECK_AND_THROW_ERROR(paragraph_ != nullptr, TextErrorCode::ERROR_INVALID_PARAM, "Paragraph is null");
866 
867     struct ConcreteContext : public ContextBase {
868         double width = 0.0;
869     };
870     sptr<ConcreteContext> context = sptr<ConcreteContext>::MakeSptr();
871     NAPI_CHECK_AND_THROW_ERROR(context != nullptr, TextErrorCode::ERROR_NO_MEMORY, "Failed to make context");
872     auto inputParser = [env, context](size_t argc, napi_value* argv) {
873         TEXT_ERROR_CHECK(argv, return, "Argv is null");
874         NAPI_CHECK_ARGS(context, context->status == napi_ok, napi_invalid_arg,
875             TextErrorCode::ERROR_INVALID_PARAM, return, "Status error, status=%d", static_cast<int>(context->status));
876         NAPI_CHECK_ARGS(context, argc >= ARGC_ONE, napi_invalid_arg, TextErrorCode::ERROR_INVALID_PARAM,
877             return, "Argc is invalid %zu", argc);
878         NAPI_CHECK_ARGS(context, NapiValueTypeIsValid(env, argv[0]) &&
879             ConvertFromJsValue(env, argv[0], context->width) && (!std::signbit(context->width)),
880             napi_invalid_arg, TextErrorCode::ERROR_INVALID_PARAM, return, "Argv is invalid %f", context->width);
881     };
882 
883     context->GetCbInfo(env, info, inputParser);
884 
885     auto executor = [context]() {
886         TEXT_ERROR_CHECK(context != nullptr, return, "Context is null");
887 
888         auto* jsParagraph = reinterpret_cast<JsParagraph*>(context->native);
889         NAPI_CHECK_ARGS(context, jsParagraph != nullptr, napi_generic_failure,
890             TextErrorCode::ERROR_INVALID_PARAM, return, "JsParagraph is nullptr");
891         NAPI_CHECK_ARGS(context, jsParagraph->paragraph_ != nullptr, napi_generic_failure,
892             TextErrorCode::ERROR_INVALID_PARAM, return, "Inner paragraph is null");
893         jsParagraph->paragraph_->Layout(context->width);
894     };
895 
896     auto complete = [env](napi_value& output) {
897         output = NapiGetUndefined(env);
898     };
899     return NapiAsyncWork::Enqueue(env, context, "onLayoutAsync", executor, complete);
900 }
901 
UpdateColor(napi_env env,napi_callback_info info)902 napi_value JsParagraph::UpdateColor(napi_env env, napi_callback_info info)
903 {
904     JsParagraph* me = CheckParamsAndGetThis<JsParagraph>(env, info);
905     return (me != nullptr) ? me->OnUpdateColor(env, info) : nullptr;
906 }
907 
OnUpdateColor(napi_env env,napi_callback_info info)908 napi_value JsParagraph::OnUpdateColor(napi_env env, napi_callback_info info)
909 {
910     NAPI_CHECK_AND_THROW_ERROR(paragraph_ != nullptr, TextErrorCode::ERROR_INVALID_PARAM, "Paragraph is null");
911 
912     size_t argc = ARGC_ONE;
913     napi_value argv[ARGC_ONE] = {nullptr};
914     napi_status status = napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
915     if (status != napi_ok || argc < ARGC_ONE) {
916         TEXT_LOGE("Failed to get parameter, argc %{public}zu, ret %{public}d", argc, status);
917         return NapiThrowError(env, TextErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
918     }
919     TextStyle textStyleTemplate;
920     if (!SetColorFromJS(env, argv[0], textStyleTemplate.color)) {
921         TEXT_LOGE("Invalid argv[0]");
922         return NapiThrowError(env, TextErrorCode::ERROR_INVALID_PARAM, "Invalid params");
923     }
924     textStyleTemplate.relayoutChangeBitmap.set(static_cast<size_t>(RelayoutTextStyleAttribute::FONT_COLOR));
925     paragraph_->UpdateAllTextStyles(textStyleTemplate);
926     return NapiGetUndefined(env);
927 }
928 
UpdateDecoration(napi_env env,napi_callback_info info)929 napi_value JsParagraph::UpdateDecoration(napi_env env, napi_callback_info info)
930 {
931     JsParagraph* me = CheckParamsAndGetThis<JsParagraph>(env, info);
932     return (me != nullptr) ? me->OnUpdateDecoration(env, info) : nullptr;
933 }
934 
OnUpdateDecoration(napi_env env,napi_callback_info info)935 napi_value JsParagraph::OnUpdateDecoration(napi_env env, napi_callback_info info)
936 {
937     NAPI_CHECK_AND_THROW_ERROR(paragraph_ != nullptr, TextErrorCode::ERROR_INVALID_PARAM, "Paragraph is null");
938 
939     size_t argc = ARGC_ONE;
940     napi_value argv[ARGC_ONE] = {nullptr};
941     napi_status status = napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
942     if (status != napi_ok || argc < ARGC_ONE) {
943         TEXT_LOGE("Failed to get parameter, argc %{public}zu, ret %{public}d", argc, status);
944         return NapiThrowError(env, TextErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
945     }
946 
947     TextStyle textStyleTemplate;
948     GetDecorationFromJSForUpdate(env, argv[0], textStyleTemplate);
949     paragraph_->UpdateAllTextStyles(textStyleTemplate);
950     return NapiGetUndefined(env);
951 }
952 
IsStrutStyleEqual(napi_env env,napi_callback_info info)953 napi_value JsParagraph::IsStrutStyleEqual(napi_env env, napi_callback_info info)
954 {
955     size_t argc = ARGC_TWO;
956     napi_value argv[ARGC_TWO] = {nullptr};
957     napi_status status = napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
958     if (status != napi_ok || argc < ARGC_TWO) {
959         TEXT_LOGE("Invalid argc %{public}zu", argc);
960         return NapiThrowError(env, TextErrorCode::ERROR_INVALID_PARAM, "Invalid params");
961     }
962 
963     TypographyStyle styleFrom;
964     if (!SetStrutStyleFromJS(env, argv[0], styleFrom)) {
965         TEXT_LOGE("Invalid argv[0]");
966         return NapiThrowError(env, TextErrorCode::ERROR_INVALID_PARAM, "Invalid params");
967     }
968 
969     TypographyStyle styleTo;
970     if (!SetStrutStyleFromJS(env, argv[1], styleTo)) {
971         TEXT_LOGE("Invalid argv[1]");
972         return NapiThrowError(env, TextErrorCode::ERROR_INVALID_PARAM, "Invalid params");
973     }
974 
975     bool equal = (styleFrom == styleTo);
976     return CreateJsValue(env, equal);
977 }
978 } // namespace OHOS::Rosen
979