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