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