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