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