• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2024 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "js_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(&currentStr, 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