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 "canvas_napi/js_canvas.h"
18 #include "draw/canvas.h"
19 #include "napi_common.h"
20 #include "paragraph_builder_napi/js_paragraph_builder.h"
21 #include "path_napi/js_path.h"
22 #include "text_line_napi/js_text_line.h"
23 #include "utils/text_log.h"
24
25 namespace OHOS::Rosen {
26 namespace {
27 const std::string CLASS_NAME = "Paragraph";
28 }
29
30 std::unique_ptr<Typography> JsParagraph::g_Typography = nullptr;
31 thread_local napi_ref JsParagraph::constructor_ = nullptr;
32
Constructor(napi_env env,napi_callback_info info)33 napi_value JsParagraph::Constructor(napi_env env, napi_callback_info info)
34 {
35 size_t argCount = 0;
36 napi_value jsThis = nullptr;
37 napi_status status = napi_get_cb_info(env, info, &argCount, nullptr, &jsThis, nullptr);
38 if (status != napi_ok) {
39 TEXT_LOGE("JsParagraph::Constructor failed to napi_get_cb_info");
40 return nullptr;
41 }
42
43 if (!g_Typography) {
44 TEXT_LOGE("Typography is null");
45 return nullptr;
46 }
47
48 JsParagraph *jsParagraph = new(std::nothrow) JsParagraph(std::move(g_Typography));
49 if (jsParagraph == nullptr) {
50 return nullptr;
51 }
52
53 status = napi_wrap(env, jsThis, jsParagraph,
54 JsParagraph::Destructor, nullptr, nullptr);
55 if (status != napi_ok) {
56 delete jsParagraph;
57 TEXT_LOGE("JsParagraph::Constructor failed to wrap native instance");
58 return nullptr;
59 }
60 return jsThis;
61 }
62
Init(napi_env env,napi_value exportObj)63 napi_value JsParagraph::Init(napi_env env, napi_value exportObj)
64 {
65 napi_property_descriptor properties[] = {
66 DECLARE_NAPI_FUNCTION("layoutSync", JsParagraph::Layout),
67 DECLARE_NAPI_FUNCTION("paint", JsParagraph::Paint),
68 DECLARE_NAPI_FUNCTION("paintOnPath", JsParagraph::PaintOnPath),
69 DECLARE_NAPI_FUNCTION("getMaxWidth", JsParagraph::GetMaxWidth),
70 DECLARE_NAPI_FUNCTION("getHeight", JsParagraph::GetHeight),
71 DECLARE_NAPI_FUNCTION("getLongestLine", JsParagraph::GetLongestLine),
72 DECLARE_NAPI_FUNCTION("getLongestLineWithIndent", JsParagraph::GetLongestLineWithIndent),
73 DECLARE_NAPI_FUNCTION("getMinIntrinsicWidth", JsParagraph::GetMinIntrinsicWidth),
74 DECLARE_NAPI_FUNCTION("getMaxIntrinsicWidth", JsParagraph::GetMaxIntrinsicWidth),
75 DECLARE_NAPI_FUNCTION("getAlphabeticBaseline", JsParagraph::GetAlphabeticBaseline),
76 DECLARE_NAPI_FUNCTION("getIdeographicBaseline", JsParagraph::GetIdeographicBaseline),
77 DECLARE_NAPI_FUNCTION("getRectsForRange", JsParagraph::GetRectsForRange),
78 DECLARE_NAPI_FUNCTION("getRectsForPlaceholders", JsParagraph::GetRectsForPlaceholders),
79 DECLARE_NAPI_FUNCTION("getGlyphPositionAtCoordinate", JsParagraph::GetGlyphPositionAtCoordinate),
80 DECLARE_NAPI_FUNCTION("getWordBoundary", JsParagraph::GetWordBoundary),
81 DECLARE_NAPI_FUNCTION("getLineCount", JsParagraph::GetLineCount),
82 DECLARE_NAPI_FUNCTION("getLineHeight", JsParagraph::GetLineHeight),
83 DECLARE_NAPI_FUNCTION("getLineWidth", JsParagraph::GetLineWidth),
84 DECLARE_NAPI_FUNCTION("didExceedMaxLines", JsParagraph::DidExceedMaxLines),
85 DECLARE_NAPI_FUNCTION("getTextLines", JsParagraph::GetTextLines),
86 DECLARE_NAPI_FUNCTION("getActualTextRange", JsParagraph::GetActualTextRange),
87 DECLARE_NAPI_FUNCTION("getLineMetrics", JsParagraph::GetLineMetrics),
88 };
89 napi_value constructor = nullptr;
90 napi_status status = napi_define_class(env, CLASS_NAME.c_str(), NAPI_AUTO_LENGTH, Constructor, nullptr,
91 sizeof(properties) / sizeof(properties[0]), properties, &constructor);
92 if (status != napi_ok) {
93 TEXT_LOGE("Failed to define Paragraph class");
94 return nullptr;
95 }
96
97 status = napi_create_reference(env, constructor, 1, &constructor_);
98 if (status != napi_ok) {
99 TEXT_LOGE("Failed to create reference of result");
100 return nullptr;
101 }
102
103 status = napi_set_named_property(env, exportObj, CLASS_NAME.c_str(), constructor);
104 if (status != napi_ok) {
105 TEXT_LOGE("Failed to set result");
106 return nullptr;
107 }
108 return exportObj;
109 }
110
111
Destructor(napi_env env,void * nativeObject,void * finalize)112 void JsParagraph::Destructor(napi_env env, void *nativeObject, void *finalize)
113 {
114 (void)finalize;
115 if (nativeObject != nullptr) {
116 JsParagraph *napi = reinterpret_cast<JsParagraph *>(nativeObject);
117 delete napi;
118 }
119 }
120
Layout(napi_env env,napi_callback_info info)121 napi_value JsParagraph::Layout(napi_env env, napi_callback_info info)
122 {
123 JsParagraph* me = CheckParamsAndGetThis<JsParagraph>(env, info);
124 return (me != nullptr) ? me->OnLayout(env, info) : nullptr;
125 }
126
OnLayout(napi_env env,napi_callback_info info)127 napi_value JsParagraph::OnLayout(napi_env env, napi_callback_info info)
128 {
129 if (paragraph_ == nullptr) {
130 TEXT_LOGE("JsParagraph::OnLayout paragraph_ is nullptr");
131 return NapiThrowError(env, TextErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
132 }
133 size_t argc = ARGC_ONE;
134 napi_value argv[ARGC_ONE] = {nullptr};
135 napi_status status = napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
136 if (status != napi_ok || argc < ARGC_ONE) {
137 TEXT_LOGE("JsParagraph::OnLayout Argc is invalid: %{public}zu", argc);
138 return NapiThrowError(env, TextErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
139 }
140 double width = 0.0;
141 if (!(argv[0] != nullptr && ConvertFromJsValue(env, argv[0], width))) {
142 TEXT_LOGE("JsParagraph::OnLayout Argv is invalid");
143 return NapiGetUndefined(env);
144 }
145
146 paragraph_->Layout(width);
147 return NapiGetUndefined(env);
148 }
149
Paint(napi_env env,napi_callback_info info)150 napi_value JsParagraph::Paint(napi_env env, napi_callback_info info)
151 {
152 JsParagraph* me = CheckParamsAndGetThis<JsParagraph>(env, info);
153 return (me != nullptr) ? me->OnPaint(env, info) : nullptr;
154 }
155
OnPaint(napi_env env,napi_callback_info info)156 napi_value JsParagraph::OnPaint(napi_env env, napi_callback_info info)
157 {
158 if (paragraph_ == nullptr) {
159 TEXT_LOGE("JsParagraph::OnPaint paragraph_ is nullptr");
160 return NapiThrowError(env, TextErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
161 }
162 size_t argc = ARGC_THREE;
163 napi_value argv[ARGC_THREE] = {nullptr};
164 napi_status status = napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
165 if (status != napi_ok || argc < ARGC_THREE) {
166 TEXT_LOGE("JsParagraph::OnPaint Argc is invalid: %{public}zu", argc);
167 return NapiThrowError(env, TextErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
168 }
169 if (argv[0] == nullptr) {
170 TEXT_LOGE("Argv is invalid");
171 return NapiGetUndefined(env);
172 }
173 Drawing::JsCanvas* jsCanvas = nullptr;
174 double x = 0.0;
175 double y = 0.0;
176 napi_unwrap(env, argv[0], reinterpret_cast<void **>(&jsCanvas));
177 if (!jsCanvas || !jsCanvas->GetCanvas() ||
178 !(argv[ARGC_ONE] != nullptr && ConvertFromJsValue(env, argv[ARGC_ONE], x) &&
179 argv[ARGC_TWO] != nullptr && ConvertFromJsValue(env, argv[ARGC_TWO], y))) {
180 TEXT_LOGE("JsParagraph::OnPaint Argv is invalid");
181 return NapiGetUndefined(env);
182 }
183 paragraph_->Paint(jsCanvas->GetCanvas(), x, y);
184
185 return NapiGetUndefined(env);
186 }
187
PaintOnPath(napi_env env,napi_callback_info info)188 napi_value JsParagraph::PaintOnPath(napi_env env, napi_callback_info info)
189 {
190 JsParagraph* me = CheckParamsAndGetThis<JsParagraph>(env, info);
191 return (me != nullptr) ? me->OnPaintOnPath(env, info) : nullptr;
192 }
193
OnPaintOnPath(napi_env env,napi_callback_info info)194 napi_value JsParagraph::OnPaintOnPath(napi_env env, napi_callback_info info)
195 {
196 if (paragraph_ == nullptr) {
197 TEXT_LOGE("JsParagraph::OnPaintOnPath paragraph_ is nullptr");
198 return NapiThrowError(env, TextErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
199 }
200 size_t argc = ARGC_FOUR;
201 napi_value argv[ARGC_FOUR] = { nullptr };
202 napi_status status = napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
203 if (status != napi_ok || argc < ARGC_FOUR) {
204 TEXT_LOGE("JsParagraph::OnPaintOnPath Argc is invalid: %{public}zu", argc);
205 return NapiThrowError(env, TextErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
206 }
207 Drawing::JsCanvas* jsCanvas = nullptr;
208 Drawing::JsPath* jsPath = nullptr;
209 double hOffset = 0.0;
210 double vOffset = 0.0;
211 napi_unwrap(env, argv[0], reinterpret_cast<void**>(&jsCanvas));
212 GET_UNWRAP_PARAM(ARGC_ONE, jsPath);
213 if (!jsCanvas || !jsCanvas->GetCanvas() || !jsPath || !jsPath->GetPath() ||
214 !(ConvertFromJsValue(env, argv[ARGC_TWO], hOffset) && ConvertFromJsValue(env, argv[ARGC_THREE], vOffset))) {
215 TEXT_LOGE("JsParagraph::OnPaintOnPath Argv is invalid");
216 return NapiGetUndefined(env);
217 }
218 paragraph_->Paint(jsCanvas->GetCanvas(), jsPath->GetPath(), hOffset, vOffset);
219
220 return NapiGetUndefined(env);
221 }
222
GetMaxWidth(napi_env env,napi_callback_info info)223 napi_value JsParagraph::GetMaxWidth(napi_env env, napi_callback_info info)
224 {
225 JsParagraph* me = CheckParamsAndGetThis<JsParagraph>(env, info);
226 return (me != nullptr) ? me->OnGetMaxWidth(env, info) : nullptr;
227 }
228
OnGetMaxWidth(napi_env env,napi_callback_info info)229 napi_value JsParagraph::OnGetMaxWidth(napi_env env, napi_callback_info info)
230 {
231 if (paragraph_ == nullptr) {
232 TEXT_LOGE("JsParagraph::OnGetMaxWidth paragraph_ is nullptr");
233 return NapiThrowError(env, TextErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
234 }
235 double maxWidth = paragraph_->GetMaxWidth();
236 return CreateJsNumber(env, maxWidth);
237 }
238
GetHeight(napi_env env,napi_callback_info info)239 napi_value JsParagraph::GetHeight(napi_env env, napi_callback_info info)
240 {
241 JsParagraph* me = CheckParamsAndGetThis<JsParagraph>(env, info);
242 return (me != nullptr) ? me->OnGetHeight(env, info) : nullptr;
243 }
244
OnGetHeight(napi_env env,napi_callback_info info)245 napi_value JsParagraph::OnGetHeight(napi_env env, napi_callback_info info)
246 {
247 if (paragraph_ == nullptr) {
248 TEXT_LOGE("JsParagraph::OnGetHeight paragraph_ is nullptr");
249 return NapiThrowError(env, TextErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
250 }
251 double height = paragraph_->GetHeight();
252 return CreateJsNumber(env, height);
253 }
254
GetLongestLine(napi_env env,napi_callback_info info)255 napi_value JsParagraph::GetLongestLine(napi_env env, napi_callback_info info)
256 {
257 JsParagraph* me = CheckParamsAndGetThis<JsParagraph>(env, info);
258 return (me != nullptr) ? me->OnGetLongestLine(env, info) : nullptr;
259 }
260
OnGetLongestLine(napi_env env,napi_callback_info info)261 napi_value JsParagraph::OnGetLongestLine(napi_env env, napi_callback_info info)
262 {
263 if (paragraph_ == nullptr) {
264 TEXT_LOGE("JsParagraph::OnGetLongestLine paragraph_ is nullptr");
265 return NapiThrowError(env, TextErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
266 }
267 double longestLine = paragraph_->GetActualWidth();
268 return CreateJsNumber(env, longestLine);
269 }
270
GetLongestLineWithIndent(napi_env env,napi_callback_info info)271 napi_value JsParagraph::GetLongestLineWithIndent(napi_env env, napi_callback_info info)
272 {
273 JsParagraph* me = CheckParamsAndGetThis<JsParagraph>(env, info);
274 return (me != nullptr) ? me->OnGetLongestLineWithIndent(env, info) : nullptr;
275 }
276
OnGetLongestLineWithIndent(napi_env env,napi_callback_info info)277 napi_value JsParagraph::OnGetLongestLineWithIndent(napi_env env, napi_callback_info info)
278 {
279 if (paragraph_ == nullptr) {
280 TEXT_LOGE("Paragraph is nullptr");
281 return NapiThrowError(env, TextErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
282 }
283 double longestLine = paragraph_->GetLongestLineWithIndent();
284 return CreateJsNumber(env, longestLine);
285 }
286
GetMinIntrinsicWidth(napi_env env,napi_callback_info info)287 napi_value JsParagraph::GetMinIntrinsicWidth(napi_env env, napi_callback_info info)
288 {
289 JsParagraph* me = CheckParamsAndGetThis<JsParagraph>(env, info);
290 return (me != nullptr) ? me->OnGetMinIntrinsicWidth(env, info) : nullptr;
291 }
292
OnGetMinIntrinsicWidth(napi_env env,napi_callback_info info)293 napi_value JsParagraph::OnGetMinIntrinsicWidth(napi_env env, napi_callback_info info)
294 {
295 if (paragraph_ == nullptr) {
296 TEXT_LOGE("JsParagraph::OnGetMinIntrinsicWidth paragraph_ is nullptr");
297 return NapiThrowError(env, TextErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
298 }
299 double minIntrinsicWidth = paragraph_->GetMinIntrinsicWidth();
300 return CreateJsNumber(env, minIntrinsicWidth);
301 }
302
GetMaxIntrinsicWidth(napi_env env,napi_callback_info info)303 napi_value JsParagraph::GetMaxIntrinsicWidth(napi_env env, napi_callback_info info)
304 {
305 JsParagraph* me = CheckParamsAndGetThis<JsParagraph>(env, info);
306 return (me != nullptr) ? me->OnGetMaxIntrinsicWidth(env, info) : nullptr;
307 }
308
OnGetMaxIntrinsicWidth(napi_env env,napi_callback_info info)309 napi_value JsParagraph::OnGetMaxIntrinsicWidth(napi_env env, napi_callback_info info)
310 {
311 if (paragraph_ == nullptr) {
312 TEXT_LOGE("JsParagraph::OnGetMaxIntrinsicWidth paragraph_ is nullptr");
313 return NapiThrowError(env, TextErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
314 }
315 double maxIntrinsicWidth = paragraph_->GetMaxIntrinsicWidth();
316 return CreateJsNumber(env, maxIntrinsicWidth);
317 }
318
GetAlphabeticBaseline(napi_env env,napi_callback_info info)319 napi_value JsParagraph::GetAlphabeticBaseline(napi_env env, napi_callback_info info)
320 {
321 JsParagraph* me = CheckParamsAndGetThis<JsParagraph>(env, info);
322 return (me != nullptr) ? me->OnGetAlphabeticBaseline(env, info) : nullptr;
323 }
324
OnGetAlphabeticBaseline(napi_env env,napi_callback_info info)325 napi_value JsParagraph::OnGetAlphabeticBaseline(napi_env env, napi_callback_info info)
326 {
327 if (paragraph_ == nullptr) {
328 TEXT_LOGE("JsParagraph::OnGetAlphabeticBaseline paragraph_ is nullptr");
329 return NapiThrowError(env, TextErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
330 }
331 double alphabeticBaseline = paragraph_->GetAlphabeticBaseline();
332 return CreateJsNumber(env, alphabeticBaseline);
333 }
334
GetIdeographicBaseline(napi_env env,napi_callback_info info)335 napi_value JsParagraph::GetIdeographicBaseline(napi_env env, napi_callback_info info)
336 {
337 JsParagraph* me = CheckParamsAndGetThis<JsParagraph>(env, info);
338 return (me != nullptr) ? me->OnGetIdeographicBaseline(env, info) : nullptr;
339 }
340
OnGetIdeographicBaseline(napi_env env,napi_callback_info info)341 napi_value JsParagraph::OnGetIdeographicBaseline(napi_env env, napi_callback_info info)
342 {
343 if (paragraph_ == nullptr) {
344 TEXT_LOGE("JsParagraph::OnGetIdeographicBaseline paragraph_ is nullptr");
345 return NapiThrowError(env, TextErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
346 }
347 double ideographicBaseline = paragraph_->GetIdeographicBaseline();
348 return CreateJsNumber(env, ideographicBaseline);
349 }
350
GetRectsForRange(napi_env env,napi_callback_info info)351 napi_value JsParagraph::GetRectsForRange(napi_env env, napi_callback_info info)
352 {
353 JsParagraph* me = CheckParamsAndGetThis<JsParagraph>(env, info);
354 return (me != nullptr) ? me->OnGetRectsForRange(env, info) : nullptr;
355 }
356
OnGetRectsForRange(napi_env env,napi_callback_info info)357 napi_value JsParagraph::OnGetRectsForRange(napi_env env, napi_callback_info info)
358 {
359 if (paragraph_ == nullptr) {
360 TEXT_LOGE("JsParagraph::OnGetRectsForRange paragraph_ is nullptr");
361 return NapiThrowError(env, TextErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
362 }
363 size_t argc = ARGC_THREE;
364 napi_value argv[ARGC_THREE] = {nullptr};
365 napi_status status = napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
366 if (status != napi_ok || argc < ARGC_THREE) {
367 TEXT_LOGE("JsParagraph::OnGetRectsForRange Argc is invalid: %{public}zu", argc);
368 return NapiThrowError(env, TextErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
369 }
370 napi_valuetype valueType = napi_undefined;
371 if (argv[0] == nullptr || napi_typeof(env, argv[0], &valueType) != napi_ok || valueType != napi_object) {
372 TEXT_LOGE("JsParagraph::OnGetRectsForRange Argv[0] is invalid");
373 return NapiGetUndefined(env);
374 }
375 napi_value tempValue = nullptr;
376 size_t start = 0;
377 size_t end = 0;
378 TextRectWidthStyle wstyle;
379 TextRectHeightStyle hstyle;
380 napi_get_named_property(env, argv[0], "start", &tempValue);
381 if (tempValue == nullptr) {
382 TEXT_LOGE("Get start property failed");
383 return NapiGetUndefined(env);
384 }
385 bool isStartOk = ConvertFromJsValue(env, tempValue, start);
386 tempValue = nullptr;
387 napi_get_named_property(env, argv[0], "end", &tempValue);
388 if (tempValue == nullptr) {
389 TEXT_LOGE("Get end property failed");
390 return NapiGetUndefined(env);
391 }
392 bool isEndOk = ConvertFromJsValue(env, tempValue, end);
393 if (!(isStartOk && isEndOk && argv[ARGC_ONE] != nullptr && ConvertFromJsValue(env, argv[ARGC_ONE], wstyle) &&
394 argv[ARGC_TWO] != nullptr && ConvertFromJsValue(env, argv[ARGC_TWO], hstyle))) {
395 TEXT_LOGE("JsParagraph::OnGetRectsForRange Argv is invalid");
396 return NapiGetUndefined(env);
397 }
398 std::vector<TextRect> rectsForRange = paragraph_->GetTextRectsByBoundary(start, end, hstyle, wstyle);
399 napi_value returnrectsForRange = nullptr;
400 NAPI_CALL(env, napi_create_array(env, &returnrectsForRange));
401 int num = static_cast<int>(rectsForRange.size());
402 for (int index = 0; index < num; ++index) {
403 napi_value tempValue2 = CreateTextRectJsValue(env, rectsForRange[index]);
404 NAPI_CALL(env, napi_set_element(env, returnrectsForRange, index, tempValue2));
405 }
406 return returnrectsForRange;
407 }
408
GetRectsForPlaceholders(napi_env env,napi_callback_info info)409 napi_value JsParagraph::GetRectsForPlaceholders(napi_env env, napi_callback_info info)
410 {
411 JsParagraph* me = CheckParamsAndGetThis<JsParagraph>(env, info);
412 return (me != nullptr) ? me->OnGetRectsForPlaceholders(env, info) : nullptr;
413 }
414
OnGetRectsForPlaceholders(napi_env env,napi_callback_info info)415 napi_value JsParagraph::OnGetRectsForPlaceholders(napi_env env, napi_callback_info info)
416 {
417 if (paragraph_ == nullptr) {
418 TEXT_LOGE("JsParagraph::OnGetRectsForPlaceholders paragraph_ is nullptr");
419 return NapiThrowError(env, TextErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
420 }
421 std::vector<TextRect> rectsForPlaceholders = paragraph_->GetTextRectsOfPlaceholders();
422 napi_value returnPlaceholders = nullptr;
423 NAPI_CALL(env, napi_create_array(env, &returnPlaceholders));
424 int num = static_cast<int>(rectsForPlaceholders.size());
425 for (int index = 0; index < num; ++index) {
426 napi_value tempValue = CreateTextRectJsValue(env, rectsForPlaceholders[index]);
427 if (tempValue != nullptr) {
428 NAPI_CALL(env, napi_set_element(env, returnPlaceholders, index, tempValue));
429 }
430 }
431 return returnPlaceholders;
432 }
433
GetGlyphPositionAtCoordinate(napi_env env,napi_callback_info info)434 napi_value JsParagraph::GetGlyphPositionAtCoordinate(napi_env env, napi_callback_info info)
435 {
436 JsParagraph* me = CheckParamsAndGetThis<JsParagraph>(env, info);
437 return (me != nullptr) ? me->OnGetGlyphPositionAtCoordinate(env, info) : nullptr;
438 }
439
OnGetGlyphPositionAtCoordinate(napi_env env,napi_callback_info info)440 napi_value JsParagraph::OnGetGlyphPositionAtCoordinate(napi_env env, napi_callback_info info)
441 {
442 if (paragraph_ == nullptr) {
443 TEXT_LOGE("JsParagraph::OnGetGlyphPositionAtCoordinate paragraph_ is nullptr");
444 return NapiThrowError(env, TextErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
445 }
446 size_t argc = ARGC_TWO;
447 napi_value argv[ARGC_TWO] = {nullptr};
448 napi_status status = napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
449 if (status != napi_ok || argc < ARGC_TWO) {
450 TEXT_LOGE("JsParagraph::OnGetGlyphPositionAtCoordinate Argc is invalid: %{public}zu", argc);
451 return NapiThrowError(env, TextErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
452 }
453 double dx = 0.0;
454 double dy = 0.0;
455 if (!(argv[0] != nullptr && ConvertFromJsValue(env, argv[0], dx) && argv[1] != nullptr &&
456 ConvertFromJsValue(env, argv[1], dy))) {
457 TEXT_LOGE("JsParagraph::OnGetGlyphPositionAtCoordinate Argv is invalid");
458 return NapiGetUndefined(env);
459 }
460 IndexAndAffinity positionWithAffinity = paragraph_->GetGlyphIndexByCoordinate(dx, dy);
461 return GetPositionWithAffinityAndConvertToJsValue(env, &positionWithAffinity);
462 }
463
GetWordBoundary(napi_env env,napi_callback_info info)464 napi_value JsParagraph::GetWordBoundary(napi_env env, napi_callback_info info)
465 {
466 JsParagraph* me = CheckParamsAndGetThis<JsParagraph>(env, info);
467 return (me != nullptr) ? me->OnGetWordBoundary(env, info) : nullptr;
468 }
469
OnGetWordBoundary(napi_env env,napi_callback_info info)470 napi_value JsParagraph::OnGetWordBoundary(napi_env env, napi_callback_info info)
471 {
472 if (paragraph_ == nullptr) {
473 TEXT_LOGE("JsParagraph::OnGetWordBoundary paragraph_ is nullptr");
474 return NapiThrowError(env, TextErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
475 }
476 size_t argc = ARGC_ONE;
477 napi_value argv[ARGC_ONE] = {nullptr};
478 napi_status status = napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
479 if (status != napi_ok || argc < ARGC_ONE) {
480 TEXT_LOGE("JsParagraph::OnGetWordBoundary Argc is invalid: %{public}zu", argc);
481 return NapiThrowError(env, TextErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
482 }
483 size_t offset = 0;
484 if (!(argv[0] != nullptr && ConvertFromJsValue(env, argv[0], offset))) {
485 TEXT_LOGE("JsParagraph::OnGetWordBoundary Argv is invalid");
486 return NapiGetUndefined(env);
487 }
488 Boundary range = paragraph_->GetWordBoundaryByIndex(offset);
489 return GetRangeAndConvertToJsValue(env, &range);
490 }
491
GetLineCount(napi_env env,napi_callback_info info)492 napi_value JsParagraph::GetLineCount(napi_env env, napi_callback_info info)
493 {
494 JsParagraph* me = CheckParamsAndGetThis<JsParagraph>(env, info);
495 return (me != nullptr) ? me->OnGetLineCount(env, info) : nullptr;
496 }
497
OnGetLineCount(napi_env env,napi_callback_info info)498 napi_value JsParagraph::OnGetLineCount(napi_env env, napi_callback_info info)
499 {
500 if (paragraph_ == nullptr) {
501 TEXT_LOGE("JsParagraph::OnGetLineCount paragraph_ is nullptr");
502 return NapiThrowError(env, TextErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
503 }
504 size_t lineCount = static_cast<size_t>(paragraph_->GetLineCount());
505 return CreateJsNumber(env, lineCount);
506 }
507
GetLineHeight(napi_env env,napi_callback_info info)508 napi_value JsParagraph::GetLineHeight(napi_env env, napi_callback_info info)
509 {
510 JsParagraph* me = CheckParamsAndGetThis<JsParagraph>(env, info);
511 return (me != nullptr) ? me->OnGetLineHeight(env, info) : nullptr;
512 }
513
OnGetLineHeight(napi_env env,napi_callback_info info)514 napi_value JsParagraph::OnGetLineHeight(napi_env env, napi_callback_info info)
515 {
516 if (paragraph_ == nullptr) {
517 TEXT_LOGE("JsParagraph::OnGetLineHeight paragraph_ is nullptr");
518 return NapiThrowError(env, TextErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
519 }
520 size_t argc = ARGC_ONE;
521 napi_value argv[ARGC_ONE] = {nullptr};
522 napi_status status = napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
523 if (status != napi_ok || argc < ARGC_ONE) {
524 TEXT_LOGE("JsParagraph::OnGetLineHeight Argc is invalid: %{public}zu", argc);
525 return NapiThrowError(env, TextErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
526 }
527 int lineNumber = 0;
528 if (!(argv[0] != nullptr && ConvertFromJsValue(env, argv[0], lineNumber))) {
529 TEXT_LOGE("JsParagraph::OnGetLineHeight Argv is invalid");
530 return NapiGetUndefined(env);
531 }
532 double lineHeight = paragraph_->GetLineHeight(lineNumber);
533 return CreateJsNumber(env, lineHeight);
534 }
535
GetLineWidth(napi_env env,napi_callback_info info)536 napi_value JsParagraph::GetLineWidth(napi_env env, napi_callback_info info)
537 {
538 JsParagraph* me = CheckParamsAndGetThis<JsParagraph>(env, info);
539 return (me != nullptr) ? me->OnGetLineWidth(env, info) : nullptr;
540 }
541
OnGetLineWidth(napi_env env,napi_callback_info info)542 napi_value JsParagraph::OnGetLineWidth(napi_env env, napi_callback_info info)
543 {
544 if (paragraph_ == nullptr) {
545 TEXT_LOGE("JsParagraph::OnGetLineWidth paragraph_ is nullptr");
546 return NapiThrowError(env, TextErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
547 }
548 size_t argc = ARGC_ONE;
549 napi_value argv[ARGC_ONE] = {nullptr};
550 napi_status status = napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
551 if (status != napi_ok || argc < ARGC_ONE) {
552 TEXT_LOGE("JsParagraph::OnGetLineWidth Argc is invalid: %{public}zu", argc);
553 return NapiThrowError(env, TextErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
554 }
555 int lineNumber = 0;
556 if (!(argv[0] != nullptr && ConvertFromJsValue(env, argv[0], lineNumber))) {
557 TEXT_LOGE("JsParagraph::OnGetLineWidth Argv is invalid");
558 return NapiGetUndefined(env);
559 }
560 double lineWidth = paragraph_->GetLineWidth(lineNumber);
561 return CreateJsNumber(env, lineWidth);
562 }
563
DidExceedMaxLines(napi_env env,napi_callback_info info)564 napi_value JsParagraph::DidExceedMaxLines(napi_env env, napi_callback_info info)
565 {
566 JsParagraph* me = CheckParamsAndGetThis<JsParagraph>(env, info);
567 return (me != nullptr) ? me->OnDidExceedMaxLines(env, info) : nullptr;
568 }
569
OnDidExceedMaxLines(napi_env env,napi_callback_info info)570 napi_value JsParagraph::OnDidExceedMaxLines(napi_env env, napi_callback_info info)
571 {
572 if (paragraph_ == nullptr) {
573 TEXT_LOGE("JsParagraph::OnDidExceedMaxLines paragraph_ is nullptr");
574 return NapiThrowError(env, TextErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
575 }
576 bool didExceedMaxLines = paragraph_->DidExceedMaxLines();
577 return CreateJsValue(env, didExceedMaxLines);
578 }
579
GetActualTextRange(napi_env env,napi_callback_info info)580 napi_value JsParagraph::GetActualTextRange(napi_env env, napi_callback_info info)
581 {
582 JsParagraph* me = CheckParamsAndGetThis<JsParagraph>(env, info);
583 return (me != nullptr) ? me->OnGetActualTextRange(env, info) : nullptr;
584 }
585
OnGetActualTextRange(napi_env env,napi_callback_info info)586 napi_value JsParagraph::OnGetActualTextRange(napi_env env, napi_callback_info info)
587 {
588 if (paragraph_ == nullptr) {
589 TEXT_LOGE("JsParagraph::OnGetActualTextRange paragraph_ is nullptr");
590 return NapiThrowError(env, TextErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
591 }
592
593 size_t argc = ARGC_TWO;
594 napi_value argv[ARGC_TWO] = {nullptr};
595 napi_status status = napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
596 if (status != napi_ok || argc < ARGC_TWO) {
597 TEXT_LOGE("JsParagraph::OnGetActualTextRange Argc is invalid: %{public}zu", argc);
598 return NapiThrowError(env, TextErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
599 }
600 int lineNumber = 0;
601 if (!(ConvertFromJsValue(env, argv[0], lineNumber))) {
602 TEXT_LOGE("JsParagraph::OnGetActualTextRange Argv is invalid");
603 return NapiGetUndefined(env);
604 }
605 bool includeSpaces = false;
606 if (!(ConvertFromJsValue(env, argv[1], includeSpaces))) {
607 TEXT_LOGE("JsParagraph::OnGetActualTextRange Argv is invalid");
608 return NapiGetUndefined(env);
609 }
610 OHOS::Rosen::Boundary range = paragraph_->GetActualTextRange(lineNumber, includeSpaces);
611 return GetRangeAndConvertToJsValue(env, &range);
612 }
613
GetLineMetrics(napi_env env,napi_callback_info info)614 napi_value JsParagraph::GetLineMetrics(napi_env env, napi_callback_info info)
615 {
616 size_t argc = ARGC_ONE;
617 napi_value argv[ARGC_ONE] = {nullptr};
618 napi_status status = napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
619 JsParagraph* me = CheckParamsAndGetThis<JsParagraph>(env, info);
620 if (status == napi_ok && argc < ARGC_ONE) {
621 return (me != nullptr) ? me->OnGetLineMetrics(env, info) : nullptr;
622 }
623 return (me != nullptr) ? me->OnGetLineMetricsAt(env, info) : nullptr;
624 }
625
OnGetLineMetrics(napi_env env,napi_callback_info info)626 napi_value JsParagraph::OnGetLineMetrics(napi_env env, napi_callback_info info)
627 {
628 if (paragraph_ == nullptr) {
629 TEXT_LOGE("JsParagraph::OnGetLineMetrics paragraph_ is nullptr");
630 return NapiThrowError(env, TextErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
631 }
632 std::vector<LineMetrics> vectorLineMetrics = paragraph_->GetLineMetrics();
633 napi_value returnLineMetrics = nullptr;
634 NAPI_CALL(env, napi_create_array(env, &returnLineMetrics));
635 int num = static_cast<int>(vectorLineMetrics.size());
636 for (int index = 0; index < num; ++index) {
637 napi_value tempValue = CreateLineMetricsJsValue(env, vectorLineMetrics[index]);
638 napi_set_element(env, returnLineMetrics, index, tempValue);
639 }
640 return returnLineMetrics;
641 }
642
OnGetLineMetricsAt(napi_env env,napi_callback_info info)643 napi_value JsParagraph::OnGetLineMetricsAt(napi_env env, napi_callback_info info)
644 {
645 if (paragraph_ == nullptr) {
646 TEXT_LOGE("JsParagraph::OnGetLineMetricsAt paragraph_ is nullptr");
647 return NapiThrowError(env, TextErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
648 }
649 size_t argc = ARGC_ONE;
650 napi_value argv[ARGC_ONE] = {nullptr};
651 napi_status status = napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
652 if (status != napi_ok || argc < ARGC_ONE) {
653 TEXT_LOGE("JsParagraph::OnLayout Argc is invalid: %{public}zu", argc);
654 return NapiThrowError(env, TextErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
655 }
656 int lineNumber = 0;
657 if (!(ConvertFromJsValue(env, argv[0], lineNumber))) {
658 TEXT_LOGE("JsParagraph::OnGetLineMetricsAt Argv is invalid");
659 return NapiGetUndefined(env);
660 }
661 LineMetrics lineMetrics;
662 if (!paragraph_->GetLineMetricsAt(lineNumber, &lineMetrics)) {
663 return nullptr;
664 }
665 return CreateLineMetricsJsValue(env, lineMetrics);
666 }
667
JsParagraph(std::shared_ptr<Typography> typography)668 JsParagraph::JsParagraph(std::shared_ptr<Typography> typography)
669 : paragraph_(typography)
670 {
671 }
672
~JsParagraph()673 JsParagraph::~JsParagraph()
674 {
675 }
676
GetParagraph()677 std::shared_ptr<Typography> JsParagraph::GetParagraph()
678 {
679 std::shared_ptr<Typography> typography = std::move(paragraph_);
680 return typography;
681 }
682
CreateJsTypography(napi_env env,std::unique_ptr<Typography> typography)683 napi_value JsParagraph::CreateJsTypography(napi_env env, std::unique_ptr<Typography> typography)
684 {
685 napi_value constructor = nullptr;
686 napi_value result = nullptr;
687 napi_status status = napi_get_reference_value(env, constructor_, &constructor);
688 if (status == napi_ok) {
689 g_Typography = std::move(typography);
690 status = napi_new_instance(env, constructor, 0, nullptr, &result);
691 if (status == napi_ok) {
692 return result;
693 } else {
694 TEXT_LOGE("CreateJsTypography: New instance could not be obtained");
695 }
696 }
697 return result;
698 }
699
GetTextLines(napi_env env,napi_callback_info info)700 napi_value JsParagraph::GetTextLines(napi_env env, napi_callback_info info)
701 {
702 JsParagraph* me = CheckParamsAndGetThis<JsParagraph>(env, info);
703 return (me != nullptr) ? me->OnGetTextLines(env, info) : nullptr;
704 }
705
OnGetTextLines(napi_env env,napi_callback_info info)706 napi_value JsParagraph::OnGetTextLines(napi_env env, napi_callback_info info)
707 {
708 if (!paragraph_) {
709 TEXT_LOGE("JsParagraph::OnGetTextLines paragraph_ is nullptr");
710 return NapiThrowError(env, TextErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
711 }
712
713 std::shared_ptr<Typography> paragraphCopy = paragraph_->CloneSelf();
714 if (!paragraphCopy) {
715 TEXT_LOGE("JsParagraph::OnGetTextLines paragraphCopy is nullptr");
716 return NapiThrowError(env, TextErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
717 }
718
719 std::vector<std::unique_ptr<TextLineBase>> textlineArr = paragraphCopy->GetTextLines();
720 napi_value array = nullptr;
721 NAPI_CALL(env, napi_create_array(env, &array));
722 uint32_t index = 0;
723 for (std::unique_ptr<TextLineBase>& item : textlineArr) {
724 napi_value itemObject = JsTextLine::CreateTextLine(env, info);
725 if (!itemObject) {
726 TEXT_LOGE("JsParagraph::OnGetTextLines itemObject is null");
727 continue;
728 }
729 JsTextLine* jsTextLine = nullptr;
730 napi_unwrap(env, itemObject, reinterpret_cast<void**>(&jsTextLine));
731 if (!jsTextLine) {
732 TEXT_LOGE("JsParagraph::OnGetTextLines napi_unwrap jsTextLine is null");
733 continue;
734 }
735 jsTextLine->SetTextLine(std::move(item));
736 jsTextLine->SetParagraph(paragraphCopy);
737
738 napi_set_element(env, array, index++, itemObject);
739 }
740 return array;
741 }
742 } // namespace OHOS::Rosen
743