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_font.h"
17
18 #include "js_drawing_utils.h"
19 #include "js_typeface.h"
20 #include "native_value.h"
21 #include "path_napi/js_path.h"
22 #ifdef USE_M133_SKIA
23 #include "src/base/SkUTF.h"
24 #else
25 #include "src/utils/SkUTF.h"
26 #endif
27
28 namespace OHOS::Rosen {
29 namespace Drawing {
30 thread_local napi_ref JsFont::constructor_ = nullptr;
31 static std::mutex g_constructorInitMutex;
32 const std::string CLASS_NAME = "Font";
33
34 static napi_property_descriptor properties[] = {
35 DECLARE_NAPI_FUNCTION("enableSubpixel", JsFont::EnableSubpixel),
36 DECLARE_NAPI_FUNCTION("enableEmbolden", JsFont::EnableEmbolden),
37 DECLARE_NAPI_FUNCTION("enableLinearMetrics", JsFont::EnableLinearMetrics),
38 DECLARE_NAPI_FUNCTION("setBaselineSnap", JsFont::SetBaselineSnap),
39 DECLARE_NAPI_FUNCTION("setEmbeddedBitmaps", JsFont::SetEmbeddedBitmaps),
40 DECLARE_NAPI_FUNCTION("setForceAutoHinting", JsFont::SetForceAutoHinting),
41 DECLARE_NAPI_FUNCTION("setSize", JsFont::SetSize),
42 DECLARE_NAPI_FUNCTION("setTypeface", JsFont::SetTypeface),
43 DECLARE_NAPI_FUNCTION("getTypeface", JsFont::GetTypeface),
44 DECLARE_NAPI_FUNCTION("getSize", JsFont::GetSize),
45 DECLARE_NAPI_FUNCTION("getMetrics", JsFont::GetMetrics),
46 DECLARE_NAPI_FUNCTION("getWidths", JsFont::GetWidths),
47 DECLARE_NAPI_FUNCTION("measureSingleCharacter", JsFont::MeasureSingleCharacter),
48 DECLARE_NAPI_FUNCTION("measureSingleCharacterWithFeatures", JsFont::MeasureSingleCharacterWithFeatures),
49 DECLARE_NAPI_FUNCTION("measureText", JsFont::MeasureText),
50 DECLARE_NAPI_FUNCTION("setScaleX", JsFont::SetScaleX),
51 DECLARE_NAPI_FUNCTION("setSkewX", JsFont::SetSkewX),
52 DECLARE_NAPI_FUNCTION("setEdging", JsFont::SetEdging),
53 DECLARE_NAPI_FUNCTION("setHinting", JsFont::SetHinting),
54 DECLARE_NAPI_FUNCTION("countText", JsFont::CountText),
55 DECLARE_NAPI_FUNCTION("isBaselineSnap", JsFont::IsBaselineSnap),
56 DECLARE_NAPI_FUNCTION("isEmbeddedBitmaps", JsFont::IsEmbeddedBitmaps),
57 DECLARE_NAPI_FUNCTION("isForceAutoHinting", JsFont::IsForceAutoHinting),
58 DECLARE_NAPI_FUNCTION("isSubpixel", JsFont::IsSubpixel),
59 DECLARE_NAPI_FUNCTION("isLinearMetrics", JsFont::IsLinearMetrics),
60 DECLARE_NAPI_FUNCTION("getSkewX", JsFont::GetSkewX),
61 DECLARE_NAPI_FUNCTION("isEmbolden", JsFont::IsEmbolden),
62 DECLARE_NAPI_FUNCTION("getScaleX", JsFont::GetScaleX),
63 DECLARE_NAPI_FUNCTION("getHinting", JsFont::GetHinting),
64 DECLARE_NAPI_FUNCTION("getEdging", JsFont::GetEdging),
65 DECLARE_NAPI_FUNCTION("textToGlyphs", JsFont::TextToGlyphs),
66 DECLARE_NAPI_FUNCTION("createPathForGlyph", JsFont::CreatePathForGlyph),
67 DECLARE_NAPI_FUNCTION("getBounds", JsFont::GetBounds),
68 DECLARE_NAPI_FUNCTION("getTextPath", JsFont::CreatePathForText),
69 DECLARE_NAPI_FUNCTION("setThemeFontFollowed", JsFont::SetThemeFontFollowed),
70 DECLARE_NAPI_FUNCTION("isThemeFontFollowed", JsFont::IsThemeFontFollowed),
71 };
72
CreateConstructor(napi_env env)73 bool JsFont::CreateConstructor(napi_env env)
74 {
75 napi_value constructor = nullptr;
76 napi_status status = napi_define_class(env, CLASS_NAME.c_str(), NAPI_AUTO_LENGTH, Constructor, nullptr,
77 sizeof(properties) / sizeof(properties[0]), properties, &constructor);
78 if (status != napi_ok) {
79 ROSEN_LOGE("Failed to define Font class");
80 return false;
81 }
82
83 status = napi_create_reference(env, constructor, 1, &constructor_);
84 if (status != napi_ok) {
85 ROSEN_LOGE("Failed to create reference of constructor");
86 return false;
87 }
88 return true;
89 }
90
Init(napi_env env,napi_value exportObj)91 napi_value JsFont::Init(napi_env env, napi_value exportObj)
92 {
93 {
94 std::lock_guard<std::mutex> lock(g_constructorInitMutex);
95 if (!constructor_) {
96 if (!CreateConstructor(env)) {
97 ROSEN_LOGE("Failed to CreateConstructor");
98 return nullptr;
99 }
100 }
101 }
102
103 napi_value constructor = nullptr;
104 napi_status status = napi_get_reference_value(env, constructor_, &constructor);
105 if (status != napi_ok) {
106 ROSEN_LOGE("Failed to get the representation of constructor object");
107 return nullptr;
108 }
109
110 status = napi_set_named_property(env, exportObj, CLASS_NAME.c_str(), constructor);
111 if (status != napi_ok) {
112 ROSEN_LOGE("Failed to set constructor");
113 return nullptr;
114 }
115
116 napi_property_descriptor staticProperty[] = {
117 DECLARE_NAPI_STATIC_FUNCTION("createFont", JsFont::CreateFont),
118 };
119 status = napi_define_properties(env, exportObj, 1, staticProperty);
120 if (status != napi_ok) {
121 ROSEN_LOGE("Failed to define static function");
122 return nullptr;
123 }
124 return exportObj;
125 }
126
Constructor(napi_env env,napi_callback_info info)127 napi_value JsFont::Constructor(napi_env env, napi_callback_info info)
128 {
129 size_t argCount = 0;
130 napi_value jsThis = nullptr;
131 napi_status status = napi_get_cb_info(env, info, &argCount, nullptr, &jsThis, nullptr);
132 if (status != napi_ok) {
133 ROSEN_LOGE("failed to napi_get_cb_info");
134 return nullptr;
135 }
136
137 std::shared_ptr<Font> font = std::make_shared<Font>();
138 font->SetTypeface(JsTypeface::GetZhCnTypeface());
139 JsFont *jsFont = new JsFont(font);
140
141 status = napi_wrap_async_finalizer(env, jsThis, jsFont, JsFont::Destructor, nullptr, nullptr, 0);
142 if (status != napi_ok) {
143 delete jsFont;
144 ROSEN_LOGE("Failed to wrap native instance");
145 return nullptr;
146 }
147 return jsThis;
148 }
149
Destructor(napi_env env,void * nativeObject,void * finalize)150 void JsFont::Destructor(napi_env env, void *nativeObject, void *finalize)
151 {
152 (void)finalize;
153 if (nativeObject != nullptr) {
154 JsFont *napi = reinterpret_cast<JsFont *>(nativeObject);
155 delete napi;
156 }
157 }
158
CreatePathForText(napi_env env,napi_callback_info info)159 napi_value JsFont::CreatePathForText(napi_env env, napi_callback_info info)
160 {
161 JsFont* me = CheckParamsAndGetThis<JsFont>(env, info);
162 return (me != nullptr) ? me->OnCreatePathForText(env, info) : nullptr;
163 }
164
CreateFont(napi_env env,napi_callback_info info)165 napi_value JsFont::CreateFont(napi_env env, napi_callback_info info)
166 {
167 {
168 std::lock_guard<std::mutex> lock(g_constructorInitMutex);
169 if (!constructor_) {
170 if (!CreateConstructor(env)) {
171 ROSEN_LOGE("Failed to CreateConstructor");
172 return nullptr;
173 }
174 }
175 }
176
177 napi_value result = nullptr;
178 napi_value constructor = nullptr;
179 napi_status status = napi_get_reference_value(env, constructor_, &constructor);
180 if (status != napi_ok) {
181 ROSEN_LOGE("Failed to get the representation of constructor object");
182 return nullptr;
183 }
184
185 status = napi_new_instance(env, constructor, 0, nullptr, &result);
186 if (status != napi_ok) {
187 ROSEN_LOGE("Failed to instantiate JavaScript font instance");
188 return nullptr;
189 }
190 return result;
191 }
192
~JsFont()193 JsFont::~JsFont()
194 {
195 m_font = nullptr;
196 }
197
EnableSubpixel(napi_env env,napi_callback_info info)198 napi_value JsFont::EnableSubpixel(napi_env env, napi_callback_info info)
199 {
200 JsFont* me = CheckParamsAndGetThis<JsFont>(env, info);
201 return (me != nullptr) ? me->OnEnableSubpixel(env, info) : nullptr;
202 }
203
EnableEmbolden(napi_env env,napi_callback_info info)204 napi_value JsFont::EnableEmbolden(napi_env env, napi_callback_info info)
205 {
206 JsFont* me = CheckParamsAndGetThis<JsFont>(env, info);
207 return (me != nullptr) ? me->OnEnableEmbolden(env, info) : nullptr;
208 }
209
EnableLinearMetrics(napi_env env,napi_callback_info info)210 napi_value JsFont::EnableLinearMetrics(napi_env env, napi_callback_info info)
211 {
212 JsFont* me = CheckParamsAndGetThis<JsFont>(env, info);
213 return (me != nullptr) ? me->OnEnableLinearMetrics(env, info) : nullptr;
214 }
215
SetBaselineSnap(napi_env env,napi_callback_info info)216 napi_value JsFont::SetBaselineSnap(napi_env env, napi_callback_info info)
217 {
218 JsFont* me = CheckParamsAndGetThis<JsFont>(env, info);
219 return (me != nullptr) ? me->OnSetBaselineSnap(env, info) : nullptr;
220 }
221
SetEmbeddedBitmaps(napi_env env,napi_callback_info info)222 napi_value JsFont::SetEmbeddedBitmaps(napi_env env, napi_callback_info info)
223 {
224 JsFont* me = CheckParamsAndGetThis<JsFont>(env, info);
225 return (me != nullptr) ? me->OnSetEmbeddedBitmaps(env, info) : nullptr;
226 }
227
SetForceAutoHinting(napi_env env,napi_callback_info info)228 napi_value JsFont::SetForceAutoHinting(napi_env env, napi_callback_info info)
229 {
230 JsFont* me = CheckParamsAndGetThis<JsFont>(env, info);
231 return (me != nullptr) ? me->OnSetForceAutoHinting(env, info) : nullptr;
232 }
233
SetSize(napi_env env,napi_callback_info info)234 napi_value JsFont::SetSize(napi_env env, napi_callback_info info)
235 {
236 JsFont* me = CheckParamsAndGetThis<JsFont>(env, info);
237 return (me != nullptr) ? me->OnSetSize(env, info) : nullptr;
238 }
239
SetTypeface(napi_env env,napi_callback_info info)240 napi_value JsFont::SetTypeface(napi_env env, napi_callback_info info)
241 {
242 JsFont* me = CheckParamsAndGetThis<JsFont>(env, info);
243 return (me != nullptr) ? me->OnSetTypeface(env, info) : nullptr;
244 }
245
GetTypeface(napi_env env,napi_callback_info info)246 napi_value JsFont::GetTypeface(napi_env env, napi_callback_info info)
247 {
248 JsFont* me = CheckParamsAndGetThis<JsFont>(env, info);
249 return (me != nullptr) ? me->OnGetTypeface(env, info) : nullptr;
250 }
251
GetSize(napi_env env,napi_callback_info info)252 napi_value JsFont::GetSize(napi_env env, napi_callback_info info)
253 {
254 JsFont* me = CheckParamsAndGetThis<JsFont>(env, info);
255 return (me != nullptr) ? me->OnGetSize(env, info) : nullptr;
256 }
257
GetMetrics(napi_env env,napi_callback_info info)258 napi_value JsFont::GetMetrics(napi_env env, napi_callback_info info)
259 {
260 JsFont* me = CheckParamsAndGetThis<JsFont>(env, info);
261 return (me != nullptr) ? me->OnGetMetrics(env, info) : nullptr;
262 }
263
GetWidths(napi_env env,napi_callback_info info)264 napi_value JsFont::GetWidths(napi_env env, napi_callback_info info)
265 {
266 JsFont* me = CheckParamsAndGetThis<JsFont>(env, info);
267 return (me != nullptr) ? me->OnGetWidths(env, info) : nullptr;
268 }
269
GetBounds(napi_env env,napi_callback_info info)270 napi_value JsFont::GetBounds(napi_env env, napi_callback_info info)
271 {
272 JsFont* me = CheckParamsAndGetThis<JsFont>(env, info);
273 return (me != nullptr) ? me->OnGetBounds(env, info) : nullptr;
274 }
275
IsBaselineSnap(napi_env env,napi_callback_info info)276 napi_value JsFont::IsBaselineSnap(napi_env env, napi_callback_info info)
277 {
278 JsFont* me = CheckParamsAndGetThis<JsFont>(env, info);
279 return (me != nullptr) ? me->OnIsBaselineSnap(env, info) : nullptr;
280 }
281
IsEmbeddedBitmaps(napi_env env,napi_callback_info info)282 napi_value JsFont::IsEmbeddedBitmaps(napi_env env, napi_callback_info info)
283 {
284 JsFont* me = CheckParamsAndGetThis<JsFont>(env, info);
285 return (me != nullptr) ? me->OnIsEmbeddedBitmaps(env, info) : nullptr;
286 }
287
IsForceAutoHinting(napi_env env,napi_callback_info info)288 napi_value JsFont::IsForceAutoHinting(napi_env env, napi_callback_info info)
289 {
290 JsFont* me = CheckParamsAndGetThis<JsFont>(env, info);
291 return (me != nullptr) ? me->OnIsForceAutoHinting(env, info) : nullptr;
292 }
293
MeasureSingleCharacter(napi_env env,napi_callback_info info)294 napi_value JsFont::MeasureSingleCharacter(napi_env env, napi_callback_info info)
295 {
296 JsFont* me = CheckParamsAndGetThis<JsFont>(env, info);
297 return (me != nullptr) ? me->OnMeasureSingleCharacter(env, info) : nullptr;
298 }
299
MeasureSingleCharacterWithFeatures(napi_env env,napi_callback_info info)300 napi_value JsFont::MeasureSingleCharacterWithFeatures(napi_env env, napi_callback_info info)
301 {
302 JsFont* me = CheckParamsAndGetThis<JsFont>(env, info);
303 return (me != nullptr) ? me->OnMeasureSingleCharacterWithFeatures(env, info) : nullptr;
304 }
305
MeasureText(napi_env env,napi_callback_info info)306 napi_value JsFont::MeasureText(napi_env env, napi_callback_info info)
307 {
308 JsFont* me = CheckParamsAndGetThis<JsFont>(env, info);
309 return (me != nullptr) ? me->OnMeasureText(env, info) : nullptr;
310 }
311
SetScaleX(napi_env env,napi_callback_info info)312 napi_value JsFont::SetScaleX(napi_env env, napi_callback_info info)
313 {
314 JsFont* me = CheckParamsAndGetThis<JsFont>(env, info);
315 return (me != nullptr) ? me->OnSetScaleX(env, info) : nullptr;
316 }
317
SetSkewX(napi_env env,napi_callback_info info)318 napi_value JsFont::SetSkewX(napi_env env, napi_callback_info info)
319 {
320 JsFont* me = CheckParamsAndGetThis<JsFont>(env, info);
321 return (me != nullptr) ? me->OnSetSkewX(env, info) : nullptr;
322 }
323
SetEdging(napi_env env,napi_callback_info info)324 napi_value JsFont::SetEdging(napi_env env, napi_callback_info info)
325 {
326 JsFont* me = CheckParamsAndGetThis<JsFont>(env, info);
327 return (me != nullptr) ? me->OnSetEdging(env, info) : nullptr;
328 }
329
SetHinting(napi_env env,napi_callback_info info)330 napi_value JsFont::SetHinting(napi_env env, napi_callback_info info)
331 {
332 JsFont* me = CheckParamsAndGetThis<JsFont>(env, info);
333 return (me != nullptr) ? me->OnSetHinting(env, info) : nullptr;
334 }
335
CountText(napi_env env,napi_callback_info info)336 napi_value JsFont::CountText(napi_env env, napi_callback_info info)
337 {
338 JsFont* me = CheckParamsAndGetThis<JsFont>(env, info);
339 return (me != nullptr) ? me->OnCountText(env, info) : nullptr;
340 }
341
IsSubpixel(napi_env env,napi_callback_info info)342 napi_value JsFont::IsSubpixel(napi_env env, napi_callback_info info)
343 {
344 JsFont* me = CheckParamsAndGetThis<JsFont>(env, info);
345 return (me != nullptr) ? me->OnIsSubpixel(env, info) : nullptr;
346 }
347
IsLinearMetrics(napi_env env,napi_callback_info info)348 napi_value JsFont::IsLinearMetrics(napi_env env, napi_callback_info info)
349 {
350 JsFont* me = CheckParamsAndGetThis<JsFont>(env, info);
351 return (me != nullptr) ? me->OnIsLinearMetrics(env, info) : nullptr;
352 }
353
GetSkewX(napi_env env,napi_callback_info info)354 napi_value JsFont::GetSkewX(napi_env env, napi_callback_info info)
355 {
356 JsFont* me = CheckParamsAndGetThis<JsFont>(env, info);
357 return (me != nullptr) ? me->OnGetSkewX(env, info) : nullptr;
358 }
359
IsEmbolden(napi_env env,napi_callback_info info)360 napi_value JsFont::IsEmbolden(napi_env env, napi_callback_info info)
361 {
362 JsFont* me = CheckParamsAndGetThis<JsFont>(env, info);
363 return (me != nullptr) ? me->OnIsEmbolden(env, info) : nullptr;
364 }
365
GetScaleX(napi_env env,napi_callback_info info)366 napi_value JsFont::GetScaleX(napi_env env, napi_callback_info info)
367 {
368 JsFont* me = CheckParamsAndGetThis<JsFont>(env, info);
369 return (me != nullptr) ? me->OnGetScaleX(env, info) : nullptr;
370 }
371
GetHinting(napi_env env,napi_callback_info info)372 napi_value JsFont::GetHinting(napi_env env, napi_callback_info info)
373 {
374 JsFont* me = CheckParamsAndGetThis<JsFont>(env, info);
375 return (me != nullptr) ? me->OnGetHinting(env, info) : nullptr;
376 }
377
GetEdging(napi_env env,napi_callback_info info)378 napi_value JsFont::GetEdging(napi_env env, napi_callback_info info)
379 {
380 JsFont* me = CheckParamsAndGetThis<JsFont>(env, info);
381 return (me != nullptr) ? me->OnGetEdging(env, info) : nullptr;
382 }
383
TextToGlyphs(napi_env env,napi_callback_info info)384 napi_value JsFont::TextToGlyphs(napi_env env, napi_callback_info info)
385 {
386 JsFont* me = CheckParamsAndGetThis<JsFont>(env, info);
387 return (me != nullptr) ? me->OnTextToGlyphs(env, info) : nullptr;
388 }
389
CreatePathForGlyph(napi_env env,napi_callback_info info)390 napi_value JsFont::CreatePathForGlyph(napi_env env, napi_callback_info info)
391 {
392 JsFont* me = CheckParamsAndGetThis<JsFont>(env, info);
393 return (me != nullptr) ? me->OnCreatePathForGlyph(env, info) : nullptr;
394 }
395
SetThemeFontFollowed(napi_env env,napi_callback_info info)396 napi_value JsFont::SetThemeFontFollowed(napi_env env, napi_callback_info info)
397 {
398 JsFont* me = CheckParamsAndGetThis<JsFont>(env, info);
399 return (me != nullptr) ? me->OnSetThemeFontFollowed(env, info) : nullptr;
400 }
401
IsThemeFontFollowed(napi_env env,napi_callback_info info)402 napi_value JsFont::IsThemeFontFollowed(napi_env env, napi_callback_info info)
403 {
404 JsFont* me = CheckParamsAndGetThis<JsFont>(env, info);
405 return (me != nullptr) ? me->OnIsThemeFontFollowed(env, info) : nullptr;
406 }
407
OnEnableSubpixel(napi_env env,napi_callback_info info)408 napi_value JsFont::OnEnableSubpixel(napi_env env, napi_callback_info info)
409 {
410 if (m_font == nullptr) {
411 ROSEN_LOGE("JsFont::OnEnableSubpixel font is nullptr");
412 return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
413 }
414
415 napi_value argv[ARGC_ONE] = {nullptr};
416 CHECK_PARAM_NUMBER_WITHOUT_OPTIONAL_PARAMS(argv, ARGC_ONE);
417
418 bool isSubpixel = false;
419 GET_BOOLEAN_PARAM(ARGC_ZERO, isSubpixel);
420
421 m_font->SetSubpixel(isSubpixel);
422 return nullptr;
423 }
424
OnEnableEmbolden(napi_env env,napi_callback_info info)425 napi_value JsFont::OnEnableEmbolden(napi_env env, napi_callback_info info)
426 {
427 if (m_font == nullptr) {
428 ROSEN_LOGE("JsFont::OnEnableEmbolden font is nullptr");
429 return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
430 }
431
432 napi_value argv[ARGC_ONE] = {nullptr};
433 CHECK_PARAM_NUMBER_WITHOUT_OPTIONAL_PARAMS(argv, ARGC_ONE);
434
435 bool isEmbolden = false;
436 GET_BOOLEAN_PARAM(ARGC_ZERO, isEmbolden);
437
438 m_font->SetEmbolden(isEmbolden);
439 return nullptr;
440 }
441
OnEnableLinearMetrics(napi_env env,napi_callback_info info)442 napi_value JsFont::OnEnableLinearMetrics(napi_env env, napi_callback_info info)
443 {
444 if (m_font == nullptr) {
445 ROSEN_LOGE("JsFont::OnEnableLinearMetrics font is nullptr");
446 return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
447 }
448
449 napi_value argv[ARGC_ONE] = {nullptr};
450 CHECK_PARAM_NUMBER_WITHOUT_OPTIONAL_PARAMS(argv, ARGC_ONE);
451
452 bool isLinearMetrics = false;
453 GET_BOOLEAN_PARAM(ARGC_ZERO, isLinearMetrics);
454
455 m_font->SetLinearMetrics(isLinearMetrics);
456 return nullptr;
457 }
458
OnSetBaselineSnap(napi_env env,napi_callback_info info)459 napi_value JsFont::OnSetBaselineSnap(napi_env env, napi_callback_info info)
460 {
461 if (m_font == nullptr) {
462 ROSEN_LOGE("JsFont::OnSetBaselineSnap font is nullptr");
463 return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
464 }
465
466 napi_value argv[ARGC_ONE] = {nullptr};
467 CHECK_PARAM_NUMBER_WITHOUT_OPTIONAL_PARAMS(argv, ARGC_ONE);
468
469 bool baselineSnap = false;
470 GET_BOOLEAN_PARAM(ARGC_ZERO, baselineSnap);
471
472 m_font->SetBaselineSnap(baselineSnap);
473 return nullptr;
474 }
475
OnIsBaselineSnap(napi_env env,napi_callback_info info)476 napi_value JsFont::OnIsBaselineSnap(napi_env env, napi_callback_info info)
477 {
478 if (m_font == nullptr) {
479 ROSEN_LOGE("JsFont::OnIsBaselineSnap font is nullptr");
480 return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
481 }
482
483 bool baselineSnap = m_font->IsBaselineSnap();
484 return CreateJsValue(env, baselineSnap);
485 }
486
OnSetEmbeddedBitmaps(napi_env env,napi_callback_info info)487 napi_value JsFont::OnSetEmbeddedBitmaps(napi_env env, napi_callback_info info)
488 {
489 if (m_font == nullptr) {
490 ROSEN_LOGE("JsFont::OnSetEmbeddedBitmaps font is nullptr");
491 return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
492 }
493
494 napi_value argv[ARGC_ONE] = {nullptr};
495 CHECK_PARAM_NUMBER_WITHOUT_OPTIONAL_PARAMS(argv, ARGC_ONE);
496
497 bool embeddedBitmaps = false;
498 GET_BOOLEAN_PARAM(ARGC_ZERO, embeddedBitmaps);
499
500 m_font->SetEmbeddedBitmaps(embeddedBitmaps);
501 return nullptr;
502 }
503
OnIsEmbeddedBitmaps(napi_env env,napi_callback_info info)504 napi_value JsFont::OnIsEmbeddedBitmaps(napi_env env, napi_callback_info info)
505 {
506 if (m_font == nullptr) {
507 ROSEN_LOGE("JsFont::OnIsEmbeddedBitmaps font is nullptr");
508 return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
509 }
510
511 bool embeddedBitmaps = m_font->IsEmbeddedBitmaps();
512 return CreateJsValue(env, embeddedBitmaps);
513 }
514
OnSetForceAutoHinting(napi_env env,napi_callback_info info)515 napi_value JsFont::OnSetForceAutoHinting(napi_env env, napi_callback_info info)
516 {
517 if (m_font == nullptr) {
518 ROSEN_LOGE("JsFont::OnSetForceAutoHinting font is nullptr");
519 return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
520 }
521
522 napi_value argv[ARGC_ONE] = {nullptr};
523 CHECK_PARAM_NUMBER_WITHOUT_OPTIONAL_PARAMS(argv, ARGC_ONE);
524
525 bool isForceAutoHinting = false;
526 GET_BOOLEAN_PARAM(ARGC_ZERO, isForceAutoHinting);
527
528 m_font->SetForceAutoHinting(isForceAutoHinting);
529 return nullptr;
530 }
531
OnIsForceAutoHinting(napi_env env,napi_callback_info info)532 napi_value JsFont::OnIsForceAutoHinting(napi_env env, napi_callback_info info)
533 {
534 if (m_font == nullptr) {
535 ROSEN_LOGE("JsFont::OnIsForceAutoHinting font is nullptr");
536 return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
537 }
538
539 bool isForceAutoHinting = m_font->IsForceAutoHinting();
540 return CreateJsValue(env, isForceAutoHinting);
541 }
542
OnGetWidths(napi_env env,napi_callback_info info)543 napi_value JsFont::OnGetWidths(napi_env env, napi_callback_info info)
544 {
545 if (m_font == nullptr) {
546 ROSEN_LOGE("JsFont::OnGetWidths font is nullptr");
547 return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
548 }
549
550 napi_value argv[ARGC_ONE] = { nullptr };
551 CHECK_PARAM_NUMBER_WITHOUT_OPTIONAL_PARAMS(argv, ARGC_ONE);
552
553 uint32_t fontSize = 0;
554 napi_get_array_length(env, argv[ARGC_ZERO], &fontSize);
555 if (fontSize == 0) {
556 return nullptr;
557 }
558
559 std::unique_ptr<uint16_t[]> glyphPtr = std::make_unique<uint16_t[]>(fontSize);
560 for (uint32_t i = 0; i < fontSize; i++) {
561 napi_value tempglyph = nullptr;
562 napi_get_element(env, argv[ARGC_ZERO], i, &tempglyph);
563 uint32_t glyph_t = 0;
564 bool isColorOk = ConvertFromJsValue(env, tempglyph, glyph_t);
565 if (!isColorOk) {
566 ROSEN_LOGE("JsFont::OnGetWidths Argv[ARGC_ZERO] is invalid");
567 return nullptr;
568 }
569 glyphPtr[i] = glyph_t;
570 }
571
572 std::unique_ptr<float[]> widthPtr = std::make_unique<float[]>(fontSize);
573 std::shared_ptr<Font> themeFont = GetThemeFont(m_font);
574 std::shared_ptr<Font> realFont = themeFont == nullptr ? m_font : themeFont;
575 realFont->GetWidths(glyphPtr.get(), fontSize, widthPtr.get());
576 napi_value widthJsArray;
577 napi_status status = napi_create_array(env, &widthJsArray);
578 if (status != napi_ok) {
579 ROSEN_LOGE("failed to napi_create_array");
580 return nullptr;
581 }
582 for (size_t i = 0; i < fontSize; i++) {
583 napi_value element = CreateJsValue(env, widthPtr[i]);
584 napi_set_element(env, widthJsArray, i, element);
585 }
586 return widthJsArray;
587 }
588
OnSetSize(napi_env env,napi_callback_info info)589 napi_value JsFont::OnSetSize(napi_env env, napi_callback_info info)
590 {
591 if (m_font == nullptr) {
592 ROSEN_LOGE("JsFont::OnSetSize font is nullptr");
593 return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
594 }
595
596 napi_value argv[ARGC_ONE] = {nullptr};
597 CHECK_PARAM_NUMBER_WITHOUT_OPTIONAL_PARAMS(argv, ARGC_ONE);
598
599 double textSize = 0.0;
600 GET_DOUBLE_PARAM(ARGC_ZERO, textSize);
601
602 m_font->SetSize((float)textSize);
603 return nullptr;
604 }
605
OnGetSize(napi_env env,napi_callback_info info)606 napi_value JsFont::OnGetSize(napi_env env, napi_callback_info info)
607 {
608 if (m_font == nullptr) {
609 ROSEN_LOGE("JsFont::OnGetSize font is nullptr");
610 return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
611 }
612
613 double textSize = m_font->GetSize();
614 return GetDoubleAndConvertToJsValue(env, textSize);
615 }
616
OnGetMetrics(napi_env env,napi_callback_info info)617 napi_value JsFont::OnGetMetrics(napi_env env, napi_callback_info info)
618 {
619 if (m_font == nullptr) {
620 ROSEN_LOGE("JsFont::OnGetMetrics font is nullptr");
621 return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
622 }
623 FontMetrics metrics;
624 std::shared_ptr<Font> themeFont = GetThemeFont(m_font);
625 std::shared_ptr<Font> realFont = themeFont == nullptr ? m_font : themeFont;
626 realFont->GetMetrics(&metrics);
627 return GetFontMetricsAndConvertToJsValue(env, &metrics);
628 }
629
OnSetTypeface(napi_env env,napi_callback_info info)630 napi_value JsFont::OnSetTypeface(napi_env env, napi_callback_info info)
631 {
632 if (m_font == nullptr) {
633 ROSEN_LOGE("JsFont::OnSetTypeface font is nullptr");
634 return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
635 }
636
637 napi_value argv[ARGC_ONE] = {nullptr};
638 CHECK_PARAM_NUMBER_WITHOUT_OPTIONAL_PARAMS(argv, ARGC_ONE);
639
640 JsTypeface *jsTypeface = nullptr;
641 GET_UNWRAP_PARAM(ARGC_ZERO, jsTypeface);
642
643 m_font->SetTypeface(jsTypeface->GetTypeface());
644 return nullptr;
645 }
646
OnGetTypeface(napi_env env,napi_callback_info info)647 napi_value JsFont::OnGetTypeface(napi_env env, napi_callback_info info)
648 {
649 if (m_font == nullptr) {
650 ROSEN_LOGE("JsFont::OnGetTypeface font is nullptr");
651 return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
652 }
653
654 std::shared_ptr<Typeface> typeface = m_font->GetTypeface();
655 return JsTypeface::CreateJsTypeface(env, typeface);
656 }
657
OnGetBounds(napi_env env,napi_callback_info info)658 napi_value JsFont::OnGetBounds(napi_env env, napi_callback_info info)
659 {
660 if (m_font == nullptr) {
661 ROSEN_LOGE("JsFont::OnGetBounds font is nullptr");
662 return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
663 }
664 napi_value argv[ARGC_ONE] = { nullptr };
665 CHECK_PARAM_NUMBER_WITHOUT_OPTIONAL_PARAMS(argv, ARGC_ONE);
666 uint32_t glyphscnt = UINT32_MAX;
667 napi_status status = napi_get_array_length(env, argv[ARGC_ZERO], &glyphscnt);
668 if (status != napi_ok || glyphscnt == 0) {
669 ROSEN_LOGE("Failed to get size of glyph array %u", glyphscnt);
670 return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
671 }
672 std::unique_ptr<uint16_t[]> glyphPtr = std::make_unique<uint16_t[]>(glyphscnt);
673 for (uint32_t i = 0; i < glyphscnt; i++) {
674 napi_value tempglyph = nullptr;
675 status = napi_get_element(env, argv[ARGC_ZERO], i, &tempglyph);
676 if (status != napi_ok) {
677 ROSEN_LOGE("Failed to get element of glyph array");
678 return nullptr;
679 }
680 uint32_t glyph_t = 0;
681 bool ret = ConvertFromJsValue(env, tempglyph, glyph_t);
682 if (!ret) {
683 ROSEN_LOGE("JsFont::OnGetBounds Argv[ARGC_ZERO] is invalid");
684 return nullptr;
685 }
686 glyphPtr[i] = glyph_t;
687 }
688 std::unique_ptr<Rect[]> rectPtr = std::make_unique<Rect[]>(glyphscnt);
689 std::shared_ptr<Font> themeFont = GetThemeFont(m_font);
690 std::shared_ptr<Font> realFont = themeFont == nullptr ? m_font : themeFont;
691 realFont->GetWidths(glyphPtr.get(), glyphscnt, nullptr, rectPtr.get());
692 napi_value rectJsArray;
693 status = napi_create_array(env, &rectJsArray);
694 if (status != napi_ok) {
695 ROSEN_LOGE("failed to napi_create_array");
696 return nullptr;
697 }
698 for (uint32_t i = 0; i < glyphscnt; i++) {
699 napi_value element = GetRectAndConvertToJsValue(env, rectPtr[i]);
700 status = napi_set_element(env, rectJsArray, i, element);
701 if (status != napi_ok) {
702 ROSEN_LOGE("failed to set array element");
703 return nullptr;
704 }
705 }
706 return rectJsArray;
707 }
708
OnMeasureSingleCharacter(napi_env env,napi_callback_info info)709 napi_value JsFont::OnMeasureSingleCharacter(napi_env env, napi_callback_info info)
710 {
711 if (m_font == nullptr) {
712 ROSEN_LOGE("JsFont::OnMeasureSingleCharacter font is nullptr");
713 return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
714 }
715
716 napi_value argv[ARGC_ONE] = {nullptr};
717 CHECK_PARAM_NUMBER_WITHOUT_OPTIONAL_PARAMS(argv, ARGC_ONE);
718
719 size_t len = 0;
720 if (napi_get_value_string_utf8(env, argv[ARGC_ZERO], nullptr, 0, &len) != napi_ok) {
721 return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Incorrect parameter0 type.");
722 }
723 if (len == 0 || len > 4) { // 4 is the maximum length of a character encoded in UTF8.
724 return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM,
725 "Parameter verification failed. Input parameter0 should be single character.");
726 }
727 char str[len + 1];
728 if (napi_get_value_string_utf8(env, argv[ARGC_ZERO], str, len + 1, &len) != napi_ok) {
729 return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Incorrect parameter0 type.");
730 }
731
732 const char* currentStr = str;
733 int32_t unicode = SkUTF::NextUTF8(¤tStr, currentStr + len);
734 size_t byteLen = currentStr - str;
735 if (byteLen != len) {
736 return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM,
737 "Parameter verification failed. Input parameter0 should be single character.");
738 }
739 std::shared_ptr<Font> themeFont = MatchThemeFont(m_font, unicode);
740 std::shared_ptr<Font> realFont = themeFont == nullptr ? m_font : themeFont;
741 return GetDoubleAndConvertToJsValue(env, realFont->MeasureSingleCharacter(unicode));
742 }
743
OnMeasureSingleCharacterWithFeatures(napi_env env,napi_callback_info info)744 napi_value JsFont::OnMeasureSingleCharacterWithFeatures(napi_env env, napi_callback_info info)
745 {
746 if (m_font == nullptr) {
747 ROSEN_LOGE("JsFont::OnMeasureSingleCharacterWithFeatures font is nullptr");
748 return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
749 }
750
751 napi_value argv[ARGC_TWO] = {nullptr};
752 CHECK_PARAM_NUMBER_WITHOUT_OPTIONAL_PARAMS(argv, ARGC_TWO);
753
754 size_t len = 0;
755 if (napi_get_value_string_utf8(env, argv[ARGC_ZERO], nullptr, 0, &len) != napi_ok) {
756 return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Incorrect parameter0 type.");
757 }
758 if (len == 0 || len > 4) { // 4 is the maximum length of a character encoded in UTF8.
759 return NapiThrowError(env, DrawingErrorCode::ERROR_PARAM_VERIFICATION_FAILED,
760 "Parameter verification failed. Input parameter0 should be single character.");
761 }
762 std::vector<char> strBuffer(len + 1);
763 if (napi_get_value_string_utf8(env, argv[ARGC_ZERO], strBuffer.data(), len + 1, &len) != napi_ok) {
764 return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Incorrect parameter0 type.");
765 }
766
767 strBuffer[len] = 0;
768 const char* currentPtr = strBuffer.data();
769 const char* endPtr = strBuffer.data() + len;
770 int32_t unicode = SkUTF::NextUTF8(¤tPtr, endPtr);
771 size_t byteLen = currentPtr - strBuffer.data();
772 if (byteLen != len) {
773 return NapiThrowError(env, DrawingErrorCode::ERROR_PARAM_VERIFICATION_FAILED,
774 "Parameter verification failed. Input parameter0 should be single character.");
775 }
776
777 std::shared_ptr<Font> themeFont = MatchThemeFont(m_font, unicode);
778 std::shared_ptr<Font> realFont = themeFont == nullptr ? m_font : themeFont;
779
780 napi_value array = argv[ARGC_ONE];
781 uint32_t size = 0;
782 if (napi_get_array_length(env, array, &size) != napi_ok) {
783 return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Invalid src array");
784 }
785 std::shared_ptr<DrawingFontFeatures> featuresPtr = std::make_shared<DrawingFontFeatures>();
786 MakeFontFeaturesFromJsArray(env, featuresPtr, size, array);
787 return GetDoubleAndConvertToJsValue(env, realFont->MeasureSingleCharacterWithFeatures(strBuffer.data(),
788 unicode, featuresPtr));
789 }
790
OnMeasureText(napi_env env,napi_callback_info info)791 napi_value JsFont::OnMeasureText(napi_env env, napi_callback_info info)
792 {
793 if (m_font == nullptr) {
794 ROSEN_LOGE("JsFont::OnMeasureText font is nullptr");
795 return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
796 }
797
798 napi_value argv[ARGC_TWO] = {nullptr};
799 CHECK_PARAM_NUMBER_WITHOUT_OPTIONAL_PARAMS(argv, ARGC_TWO);
800
801 std::string text = "";
802 if (!ConvertFromJsValue(env, argv[ARGC_ZERO], text)) {
803 ROSEN_LOGE("JsFont::OnMeasureText Argv[0] is invalid");
804 return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM,
805 "Parameter verification failed. The text input must be string.");
806 }
807
808 TextEncoding TextEncoding = TextEncoding::UTF8;
809 if (!ConvertFromJsTextEncoding(env, TextEncoding, argv[1])) {
810 ROSEN_LOGE("JsFont::OnMeasureText ConvertFromJsTextEncoding failed");
811 return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM,
812 "Parameter verification failed. The TextEncoding input must be valid.");
813 }
814
815 std::shared_ptr<Font> themeFont = GetThemeFont(m_font);
816 std::shared_ptr<Font> realFont = themeFont == nullptr ? m_font : themeFont;
817 double textSize = realFont->MeasureText(text.c_str(), text.length(), TextEncoding);
818 return GetDoubleAndConvertToJsValue(env, textSize);
819 }
820
OnSetScaleX(napi_env env,napi_callback_info info)821 napi_value JsFont::OnSetScaleX(napi_env env, napi_callback_info info)
822 {
823 if (m_font == nullptr) {
824 ROSEN_LOGE("JsFont::OnSetScaleX font is nullptr");
825 return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
826 }
827
828 napi_value argv[ARGC_ONE] = {nullptr};
829 CHECK_PARAM_NUMBER_WITHOUT_OPTIONAL_PARAMS(argv, ARGC_ONE);
830
831 double scaleX = 0.0;
832 GET_DOUBLE_PARAM(ARGC_ZERO, scaleX);
833
834 JS_CALL_DRAWING_FUNC(m_font->SetScaleX(scaleX));
835 return nullptr;
836 }
837
OnSetSkewX(napi_env env,napi_callback_info info)838 napi_value JsFont::OnSetSkewX(napi_env env, napi_callback_info info)
839 {
840 if (m_font == nullptr) {
841 ROSEN_LOGE("JsFont::OnSetSkewX font is nullptr");
842 return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
843 }
844
845 napi_value argv[ARGC_ONE] = {nullptr};
846 CHECK_PARAM_NUMBER_WITHOUT_OPTIONAL_PARAMS(argv, ARGC_ONE);
847
848 double skewX = 0.0;
849 GET_DOUBLE_PARAM(ARGC_ZERO, skewX);
850
851 JS_CALL_DRAWING_FUNC(m_font->SetSkewX(skewX));
852 return nullptr;
853 }
854
OnSetEdging(napi_env env,napi_callback_info info)855 napi_value JsFont::OnSetEdging(napi_env env, napi_callback_info info)
856 {
857 if (m_font == nullptr) {
858 ROSEN_LOGE("JsFont::OnSetEdging font is nullptr");
859 return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
860 }
861
862 napi_value argv[ARGC_ONE] = {nullptr};
863 CHECK_PARAM_NUMBER_WITHOUT_OPTIONAL_PARAMS(argv, ARGC_ONE);
864
865 int32_t fontEdging = 0;
866 GET_ENUM_PARAM(ARGC_ZERO, fontEdging, 0, static_cast<int32_t>(FontEdging::SUBPIXEL_ANTI_ALIAS));
867
868 JS_CALL_DRAWING_FUNC(m_font->SetEdging(static_cast<FontEdging>(fontEdging)));
869 return nullptr;
870 }
871
OnSetHinting(napi_env env,napi_callback_info info)872 napi_value JsFont::OnSetHinting(napi_env env, napi_callback_info info)
873 {
874 if (m_font == nullptr) {
875 ROSEN_LOGE("JsFont::OnSetHinting font is nullptr");
876 return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
877 }
878
879 napi_value argv[ARGC_ONE] = {nullptr};
880 CHECK_PARAM_NUMBER_WITHOUT_OPTIONAL_PARAMS(argv, ARGC_ONE);
881
882 int32_t fontHinting = 0;
883 GET_ENUM_PARAM(ARGC_ZERO, fontHinting, 0, static_cast<int32_t>(FontHinting::FULL));
884
885 JS_CALL_DRAWING_FUNC(m_font->SetHinting(static_cast<FontHinting>(fontHinting)));
886 return nullptr;
887 }
888
OnCountText(napi_env env,napi_callback_info info)889 napi_value JsFont::OnCountText(napi_env env, napi_callback_info info)
890 {
891 if (m_font == nullptr) {
892 ROSEN_LOGE("JsFont::OnCountText font is nullptr");
893 return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
894 }
895
896 napi_value argv[ARGC_ONE] = {nullptr};
897 CHECK_PARAM_NUMBER_WITHOUT_OPTIONAL_PARAMS(argv, ARGC_ONE);
898
899 std::string text = "";
900 if (!ConvertFromJsValue(env, argv[ARGC_ZERO], text)) {
901 ROSEN_LOGE("JsFont::OnCountText Argv[ARGC_ZERO] is invalid");
902 return nullptr;
903 }
904
905 std::shared_ptr<Font> themeFont = GetThemeFont(m_font);
906 std::shared_ptr<Font> realFont = themeFont == nullptr ? m_font : themeFont;
907 int32_t textSize = realFont->CountText(text.c_str(), text.length(), TextEncoding::UTF8);
908 return CreateJsNumber(env, textSize);
909 }
910
OnIsSubpixel(napi_env env,napi_callback_info info)911 napi_value JsFont::OnIsSubpixel(napi_env env, napi_callback_info info)
912 {
913 if (m_font == nullptr) {
914 ROSEN_LOGE("JsFont::OnIsSubpixel font is nullptr");
915 return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
916 }
917
918 bool subpixel = m_font->IsSubpixel();
919 return CreateJsValue(env, subpixel);
920 }
921
OnIsLinearMetrics(napi_env env,napi_callback_info info)922 napi_value JsFont::OnIsLinearMetrics(napi_env env, napi_callback_info info)
923 {
924 if (m_font == nullptr) {
925 ROSEN_LOGE("JsFont::OnIsLinearMetrics font is nullptr");
926 return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
927 }
928
929 bool linear = m_font->IsLinearMetrics();
930 return CreateJsValue(env, linear);
931 }
932
OnGetSkewX(napi_env env,napi_callback_info info)933 napi_value JsFont::OnGetSkewX(napi_env env, napi_callback_info info)
934 {
935 if (m_font == nullptr) {
936 ROSEN_LOGE("JsFont::OnGetSkewX font is nullptr");
937 return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
938 }
939
940 double skewX = m_font->GetSkewX();
941 return GetDoubleAndConvertToJsValue(env, skewX);
942 }
943
OnIsEmbolden(napi_env env,napi_callback_info info)944 napi_value JsFont::OnIsEmbolden(napi_env env, napi_callback_info info)
945 {
946 if (m_font == nullptr) {
947 ROSEN_LOGE("JsFont::OnIsEmbolden font is nullptr");
948 return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
949 }
950
951 bool fakeBoldText = m_font->IsEmbolden();
952 return CreateJsValue(env, fakeBoldText);
953 }
954
OnGetScaleX(napi_env env,napi_callback_info info)955 napi_value JsFont::OnGetScaleX(napi_env env, napi_callback_info info)
956 {
957 if (m_font == nullptr) {
958 ROSEN_LOGE("JsFont::OnGetScaleX font is nullptr");
959 return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
960 }
961
962 double scaleX = m_font->GetScaleX();
963 return GetDoubleAndConvertToJsValue(env, scaleX);
964 }
965
OnGetHinting(napi_env env,napi_callback_info info)966 napi_value JsFont::OnGetHinting(napi_env env, napi_callback_info info)
967 {
968 if (m_font == nullptr) {
969 ROSEN_LOGE("JsFont::OnGetHinting font is nullptr");
970 return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
971 }
972
973 FontHinting hinting = m_font->GetHinting();
974 return CreateJsNumber(env, static_cast<uint32_t>(hinting));
975 }
976
OnGetEdging(napi_env env,napi_callback_info info)977 napi_value JsFont::OnGetEdging(napi_env env, napi_callback_info info)
978 {
979 if (m_font == nullptr) {
980 ROSEN_LOGE("JsFont::OnGetEdging font is nullptr");
981 return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
982 }
983
984 FontEdging edging = m_font->GetEdging();
985 return CreateJsNumber(env, static_cast<uint32_t>(edging));
986 }
987
OnTextToGlyphs(napi_env env,napi_callback_info info)988 napi_value JsFont::OnTextToGlyphs(napi_env env, napi_callback_info info)
989 {
990 if (m_font == nullptr) {
991 ROSEN_LOGE("JsFont::OnTextToGlyphs font is nullptr");
992 return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
993 }
994
995 size_t argc = ARGC_TWO;
996 napi_value argv[ARGC_TWO] = { nullptr };
997 CHECK_PARAM_NUMBER_WITH_OPTIONAL_PARAMS(argv, argc, ARGC_ONE, ARGC_TWO);
998
999 std::string text = "";
1000 if (!ConvertFromJsValue(env, argv[ARGC_ZERO], text)) {
1001 ROSEN_LOGE("JsFont::OnTextToGlyphs Argv[ARGC_ZERO] is invalid");
1002 return nullptr;
1003 }
1004
1005 std::shared_ptr<Font> themeFont = GetThemeFont(m_font);
1006 std::shared_ptr<Font> realFont = themeFont == nullptr ? m_font : themeFont;
1007 uint32_t glyphCount = static_cast<uint32_t>(realFont->CountText(text.c_str(), text.length(), TextEncoding::UTF8));
1008 if (argc == ARGC_TWO) {
1009 uint32_t inputCount = 0;
1010 GET_UINT32_PARAM(ARGC_ONE, inputCount);
1011 if (glyphCount != inputCount) {
1012 return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
1013 }
1014 }
1015
1016 std::unique_ptr<uint16_t[]> glyphPtr = std::make_unique<uint16_t[]>(glyphCount);
1017 realFont->TextToGlyphs(text.c_str(), text.length(), TextEncoding::UTF8, glyphPtr.get(), glyphCount);
1018
1019 napi_value glyphJsArray;
1020 napi_status status = napi_create_array(env, &glyphJsArray);
1021 if (status != napi_ok) {
1022 ROSEN_LOGE("failed to napi_create_array");
1023 return nullptr;
1024 }
1025 for (size_t i = 0; i < glyphCount; i++) {
1026 napi_value element = CreateJsValue(env, glyphPtr[i]);
1027 napi_set_element(env, glyphJsArray, i, element);
1028 }
1029 return glyphJsArray;
1030 }
1031
OnCreatePathForGlyph(napi_env env,napi_callback_info info)1032 napi_value JsFont::OnCreatePathForGlyph(napi_env env, napi_callback_info info)
1033 {
1034 if (m_font == nullptr) {
1035 ROSEN_LOGE("JsFont::OnCreatePathForGlyph font is nullptr");
1036 return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
1037 }
1038
1039 napi_value argv[ARGC_ONE] = {nullptr};
1040 CHECK_PARAM_NUMBER_WITHOUT_OPTIONAL_PARAMS(argv, ARGC_ONE);
1041 uint32_t id = 0;
1042 GET_UINT32_PARAM(ARGC_ZERO, id);
1043
1044 Path* path = new Path();
1045 if (path == nullptr) {
1046 ROSEN_LOGE("JsFont::OnCreatePathForGlyph Failed to create Path");
1047 return nullptr;
1048 }
1049 std::shared_ptr<Font> themeFont = GetThemeFont(m_font);
1050 std::shared_ptr<Font> realFont = themeFont == nullptr ? m_font : themeFont;
1051 if (!realFont->GetPathForGlyph(static_cast<uint16_t>(id), path)) {
1052 delete path;
1053 return nullptr;
1054 }
1055 return JsPath::CreateJsPath(env, path);
1056 }
1057
GetFont()1058 std::shared_ptr<Font> JsFont::GetFont()
1059 {
1060 return m_font;
1061 }
1062
SetFont(std::shared_ptr<Font> font)1063 void JsFont::SetFont(std::shared_ptr<Font> font)
1064 {
1065 m_font = font;
1066 }
1067
OnCreatePathForText(napi_env env,napi_callback_info info)1068 napi_value JsFont::OnCreatePathForText(napi_env env, napi_callback_info info)
1069 {
1070 if (m_font == nullptr) {
1071 return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Invalid params");
1072 }
1073
1074 napi_value argv[ARGC_FOUR] = {nullptr};
1075 CHECK_PARAM_NUMBER_WITHOUT_OPTIONAL_PARAMS(argv, ARGC_FOUR);
1076
1077 std::string text = "";
1078 if (!ConvertFromJsValue(env, argv[ARGC_ZERO], text)) {
1079 return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Failed to convert the first parameter");
1080 }
1081
1082 uint32_t byteLength = 0;
1083 if (!ConvertFromJsNumber(env, argv[ARGC_ONE], byteLength)) {
1084 return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Failed to convert the second parameter");
1085 }
1086
1087 double x = 0.0;
1088 if (!ConvertFromJsNumber(env, argv[ARGC_TWO], x)) {
1089 return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Failed to convert the third parameter");
1090 }
1091
1092 double y = 0.0;
1093 if (!ConvertFromJsNumber(env, argv[ARGC_THREE], y)) {
1094 return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Failed to convert the fourth parameter");
1095 }
1096
1097 Path* path = new Path();
1098 std::shared_ptr<Font> themeFont = GetThemeFont(m_font);
1099 std::shared_ptr<Font> realFont = themeFont == nullptr ? m_font : themeFont;
1100 realFont->GetTextPath(text.c_str(), byteLength, TextEncoding::UTF8, x, y, path);
1101 return JsPath::CreateJsPath(env, path);
1102 }
1103
OnSetThemeFontFollowed(napi_env env,napi_callback_info info)1104 napi_value JsFont::OnSetThemeFontFollowed(napi_env env, napi_callback_info info)
1105 {
1106 if (m_font == nullptr) {
1107 ROSEN_LOGE("JsFont::OnSetThemeFontFollowed font is nullptr");
1108 return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
1109 }
1110
1111 napi_value argv[ARGC_ONE] = {nullptr};
1112 CHECK_PARAM_NUMBER_WITHOUT_OPTIONAL_PARAMS(argv, ARGC_ONE);
1113
1114 bool followed = false;
1115 GET_BOOLEAN_PARAM(ARGC_ZERO, followed);
1116
1117 m_font->SetThemeFontFollowed(followed);
1118 return nullptr;
1119 }
1120
OnIsThemeFontFollowed(napi_env env,napi_callback_info info)1121 napi_value JsFont::OnIsThemeFontFollowed(napi_env env, napi_callback_info info)
1122 {
1123 if (m_font == nullptr) {
1124 ROSEN_LOGE("JsFont::OnIsThemeFontFollowed font is nullptr");
1125 return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
1126 }
1127
1128 bool followed = m_font->IsThemeFontFollowed();
1129 return CreateJsValue(env, followed);
1130 }
1131 } // namespace Drawing
1132 } // namespace OHOS::Rosen