• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 Shenzhen Kaihong Digital Industry Development 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 
17 #include "interfaces/napi/kits/utils/napi_utils.h"
18 
19 #include "bridge/common/utils/engine_helper.h"
20 #include "core/common/font_manager.h"
21 
22 namespace OHOS::Ace::Napi {
23 namespace {
24 constexpr size_t STR_BUFFER_SIZE = 1024;
25 constexpr int32_t FONT_INFO_INDEX_PATH = 0;
26 constexpr int32_t FONT_INFO_INDEX_POST_SCRIPT_NAME = 1;
27 constexpr int32_t FONT_INFO_INDEX_FULL_NAME = 2;
28 constexpr int32_t FONT_INFO_INDEX_FAMILY = 3;
29 constexpr int32_t FONT_INFO_INDEX_SUB_FAMILY = 4;
30 constexpr int32_t FONT_INFO_INDEX_WEIGHT = 5;
31 constexpr int32_t FONT_INFO_INDEX_WIDTH = 6;
32 constexpr int32_t FONT_INFO_INDEX_ITALIC = 7;
33 constexpr int32_t FONT_INFO_INDEX_MONOSPACE = 8;
34 constexpr int32_t FONT_INFO_INDEX_SYMBOLIC = 9;
35 constexpr int32_t FONT_INFO_INDEX_MAX = 10;
36 }
37 
ParseFamilyNameOrSrc(napi_env env,napi_value familyNameOrSrcNApi,std::string & familyNameOrSrc,napi_valuetype valueType,ResourceInfo & info)38 static bool ParseFamilyNameOrSrc(napi_env env, napi_value familyNameOrSrcNApi, std::string& familyNameOrSrc,
39     napi_valuetype valueType, ResourceInfo& info)
40 {
41     napi_typeof(env, familyNameOrSrcNApi, &valueType);
42     if (valueType == napi_string) {
43         size_t nameLen = 0;
44         napi_get_value_string_utf8(env, familyNameOrSrcNApi, nullptr, 0, &nameLen);
45         std::unique_ptr<char[]> name = std::make_unique<char[]>(nameLen + 1);
46         napi_get_value_string_utf8(env, familyNameOrSrcNApi, name.get(), nameLen + 1, &nameLen);
47         familyNameOrSrc = name.get();
48     } else if (valueType == napi_object) {
49         if (!ParseResourceParam(env, familyNameOrSrcNApi, info)) {
50             return false;
51         }
52         if (!ParseString(info, familyNameOrSrc)) {
53             return false;
54         }
55     } else {
56         return false;
57     }
58     return true;
59 }
60 
JSRegisterFont(napi_env env,napi_callback_info info)61 static napi_value JSRegisterFont(napi_env env, napi_callback_info info)
62 {
63     size_t argc = 1;
64     napi_value argv = nullptr;
65     napi_value thisVar = nullptr;
66     void* data = nullptr;
67     napi_get_cb_info(env, info, &argc, &argv, &thisVar, &data);
68 
69     napi_value familyNameNApi = nullptr;
70     napi_value familySrcNApi = nullptr;
71     std::string familyName;
72     std::string familySrc;
73 
74     napi_valuetype valueType = napi_undefined;
75     napi_typeof(env, argv, &valueType);
76     if (valueType == napi_object) {
77         napi_get_named_property(env, argv, "familyName", &familyNameNApi);
78         napi_get_named_property(env, argv, "familySrc", &familySrcNApi);
79     } else {
80         return nullptr;
81     }
82 
83     ResourceInfo resourceInfo;
84     if (!ParseFamilyNameOrSrc(env, familyNameNApi, familyName, valueType, resourceInfo)) {
85         return nullptr;
86     }
87     if (!ParseFamilyNameOrSrc(env, familySrcNApi, familySrc, valueType, resourceInfo)) {
88         return nullptr;
89     }
90 
91     std::string bundleName = resourceInfo.bundleName.has_value() ? resourceInfo.bundleName.value() : "";
92     std::string moduleName = resourceInfo.moduleName.has_value() ? resourceInfo.moduleName.value() : "";
93     auto container = Container::CurrentSafely();
94     if (bundleName.empty() && container) {
95         bundleName = container->GetBundleName();
96     }
97     if (moduleName.empty() && container) {
98         moduleName = container->GetModuleName();
99     }
100     auto delegate = EngineHelper::GetCurrentDelegateSafely();
101     if (!delegate) {
102         return nullptr;
103     }
104     TAG_LOGI(AceLogTag::ACE_FONT, "begin to register font.");
105     delegate->RegisterFont(familyName, familySrc, bundleName, moduleName);
106     return nullptr;
107 }
108 
JSgetSystemFontList(napi_env env,napi_callback_info info)109 static napi_value JSgetSystemFontList(napi_env env, napi_callback_info info)
110 {
111     napi_value arrayResult = nullptr;
112     napi_create_array(env, &arrayResult);
113     bool isArray = false;
114     if (napi_is_array(env, arrayResult, &isArray) != napi_ok || !isArray) {
115         return arrayResult;
116     }
117     std::vector<std::string> fontList;
118     auto delegate = EngineHelper::GetCurrentDelegateSafely();
119     if (!delegate) {
120         return nullptr;
121     }
122     delegate->GetSystemFontList(fontList);
123 
124     int32_t index = 0;
125     for (const std::string& font : fontList) {
126         napi_value result = nullptr;
127         napi_create_string_utf8(env, font.c_str(), font.length(), &result);
128         napi_set_element(env, arrayResult, index++, result);
129     }
130     return arrayResult;
131 }
132 
JSgetFontByName(napi_env env,napi_callback_info info)133 static napi_value JSgetFontByName(napi_env env, napi_callback_info info)
134 {
135     size_t argc = 1;
136     napi_value argv = nullptr;
137     napi_value thisVar = nullptr;
138     void* data = nullptr;
139     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, &argv, &thisVar, &data));
140     NAPI_ASSERT(env, argc == 1, "requires 1 parameter");
141 
142     napi_valuetype type;
143     NAPI_CALL(env, napi_typeof(env, argv, &type));
144     NAPI_ASSERT(env, type == napi_string, "type mismatch");
145     char fontName[STR_BUFFER_SIZE] = { 0 };
146     size_t len = 0;
147     napi_get_value_string_utf8(env, argv, fontName, STR_BUFFER_SIZE, &len);
148     NAPI_ASSERT(env, len < STR_BUFFER_SIZE, "condition string too long");
149     std::string fontNameStr(fontName, len);
150 
151     FontInfo fontInfo;
152     auto delegate = EngineHelper::GetCurrentDelegateSafely();
153     if (!delegate) {
154         return nullptr;
155     }
156     if (!delegate->GetSystemFont(fontNameStr, fontInfo)) {
157         return nullptr;
158     }
159 
160     napi_value resultArray[FONT_INFO_INDEX_MAX] = { 0 };
161     napi_create_string_utf8(env, fontInfo.path.c_str(), NAPI_AUTO_LENGTH, &resultArray[FONT_INFO_INDEX_PATH]);
162     napi_create_string_utf8(env, fontInfo.postScriptName.c_str(), NAPI_AUTO_LENGTH,
163         &resultArray[FONT_INFO_INDEX_POST_SCRIPT_NAME]);
164     napi_create_string_utf8(env, fontInfo.fullName.c_str(), NAPI_AUTO_LENGTH, &resultArray[FONT_INFO_INDEX_FULL_NAME]);
165     napi_create_string_utf8(env, fontInfo.family.c_str(), NAPI_AUTO_LENGTH, &resultArray[FONT_INFO_INDEX_FAMILY]);
166     napi_create_string_utf8(env, fontInfo.subfamily.c_str(), NAPI_AUTO_LENGTH,
167         &resultArray[FONT_INFO_INDEX_SUB_FAMILY]);
168     napi_create_int32(env, fontInfo.weight, &resultArray[FONT_INFO_INDEX_WEIGHT]);
169     napi_create_int32(env, fontInfo.width, &resultArray[FONT_INFO_INDEX_WIDTH]);
170     napi_get_boolean(env, fontInfo.italic, &resultArray[FONT_INFO_INDEX_ITALIC]);
171     napi_get_boolean(env, fontInfo.monoSpace, &resultArray[FONT_INFO_INDEX_MONOSPACE]);
172     napi_get_boolean(env, fontInfo.symbolic, &resultArray[FONT_INFO_INDEX_SYMBOLIC]);
173 
174     napi_value result = nullptr;
175     napi_create_object(env, &result);
176     napi_set_named_property(env, result, "path", resultArray[FONT_INFO_INDEX_PATH]);
177     napi_set_named_property(env, result, "postScriptName", resultArray[FONT_INFO_INDEX_POST_SCRIPT_NAME]);
178     napi_set_named_property(env, result, "fullName", resultArray[FONT_INFO_INDEX_FULL_NAME]);
179     napi_set_named_property(env, result, "family", resultArray[FONT_INFO_INDEX_FAMILY]);
180     napi_set_named_property(env, result, "subfamily", resultArray[FONT_INFO_INDEX_SUB_FAMILY]);
181     napi_set_named_property(env, result, "weight", resultArray[FONT_INFO_INDEX_WEIGHT]);
182     napi_set_named_property(env, result, "width", resultArray[FONT_INFO_INDEX_WIDTH]);
183     napi_set_named_property(env, result, "italic", resultArray[FONT_INFO_INDEX_ITALIC]);
184     napi_set_named_property(env, result, "monoSpace", resultArray[FONT_INFO_INDEX_MONOSPACE]);
185     napi_set_named_property(env, result, "symbolic", resultArray[FONT_INFO_INDEX_SYMBOLIC]);
186 
187     return result;
188 }
189 
GetUIFontGenericInfo(napi_env env,const FontConfigJsonInfo & fontConfigJsonInfo)190 static napi_value GetUIFontGenericInfo(napi_env env, const FontConfigJsonInfo& fontConfigJsonInfo)
191 {
192     napi_value genericSetResult = nullptr;
193     napi_create_array(env, &genericSetResult);
194     int32_t index = 0;
195     for (const FontGenericInfo& generic: fontConfigJsonInfo.genericSet) {
196         napi_value genericResult = nullptr;
197         napi_create_object(env, &genericResult);
198         napi_value familyResult = nullptr;
199         napi_create_string_utf8(env, generic.familyName.c_str(), generic.familyName.length(), &familyResult);
200         napi_value aliasSetResult = nullptr;
201         napi_create_array(env, &aliasSetResult);
202         int32_t index2 = 0;
203         for (const AliasInfo& alias: generic.aliasSet) {
204             napi_value aliasResult = nullptr;
205             napi_create_object(env, &aliasResult);
206             napi_value familyNameResult = nullptr;
207             napi_create_string_utf8(env, alias.familyName.c_str(), alias.familyName.length(), &familyNameResult);
208             napi_value weightResult = nullptr;
209             napi_create_int32(env, alias.weight, &weightResult);
210             napi_set_named_property(env, aliasResult, "name", familyNameResult);
211             napi_set_named_property(env, aliasResult, "weight", weightResult);
212             napi_set_element(env, aliasSetResult, index2++, aliasResult);
213         }
214         index2 = 0;
215         napi_value adjustSetResult = nullptr;
216         napi_create_array(env, &adjustSetResult);
217         for (const AdjustInfo& adjust: generic.adjustSet) {
218             napi_value adjustResult = nullptr;
219             napi_create_object(env, &adjustResult);
220             napi_value weightResult = nullptr;
221             napi_create_int32(env, adjust.origValue, &weightResult);
222             napi_value toResult = nullptr;
223             napi_create_int32(env, adjust.newValue, &toResult);
224             napi_set_named_property(env, adjustResult, "weight", weightResult);
225             napi_set_named_property(env, adjustResult, "to", toResult);
226             napi_set_element(env, adjustSetResult, index2++, adjustResult);
227         }
228         napi_set_named_property(env, genericResult, "family", familyResult);
229         napi_set_named_property(env, genericResult, "alias", aliasSetResult);
230         napi_set_named_property(env, genericResult, "adjust", adjustSetResult);
231         napi_set_element(env, genericSetResult, index++, genericResult);
232     }
233     return genericSetResult;
234 }
235 
GetUIFontFallbackInfo(napi_env env,const FontConfigJsonInfo & fontConfigJsonInfo)236 static napi_value GetUIFontFallbackInfo(napi_env env, const FontConfigJsonInfo& fontConfigJsonInfo)
237 {
238     napi_value fallbackGroupSetResult = nullptr;
239     napi_create_array(env, &fallbackGroupSetResult);
240     int32_t index = 0;
241     for (const FallbackGroup& fallbackGroup: fontConfigJsonInfo.fallbackGroupSet) {
242         napi_value fallbackGroupResult = nullptr;
243         napi_create_object(env, &fallbackGroupResult);
244         napi_value fontSetNameResult = nullptr;
245         napi_create_string_utf8(env, fallbackGroup.groupName.c_str(),
246             fallbackGroup.groupName.length(), &fontSetNameResult);
247         napi_value fallbackListResult = nullptr;
248         napi_create_array(env, &fallbackListResult);
249         int32_t index2 = 0;
250         for (const FallbackInfo& fallback: fallbackGroup.fallbackInfoSet) {
251             napi_value fallbackResult = nullptr;
252             napi_create_object(env, &fallbackResult);
253             napi_value familyResult = nullptr;
254             napi_create_string_utf8(env, fallback.familyName.c_str(), fallback.familyName.length(), &familyResult);
255             napi_value languageResult = nullptr;
256             napi_create_string_utf8(env, fallback.font.c_str(), fallback.font.length(), &languageResult);
257 
258             napi_set_named_property(env, fallbackResult, "language", languageResult);
259             napi_set_named_property(env, fallbackResult, "family", familyResult);
260             napi_set_element(env, fallbackListResult, index2++, fallbackResult);
261         }
262         napi_set_named_property(env, fallbackGroupResult, "fontSetName", fontSetNameResult);
263         napi_set_named_property(env, fallbackGroupResult, "fallback", fallbackListResult);
264         napi_set_element(env, fallbackGroupSetResult, index++, fallbackGroupResult);
265     }
266     return fallbackGroupSetResult;
267 }
268 
JsGetUIFontConfig(napi_env env,napi_callback_info info)269 static napi_value JsGetUIFontConfig(napi_env env, napi_callback_info info)
270 {
271     FontConfigJsonInfo fontConfigJsonInfo;
272     auto delegate = EngineHelper::GetCurrentDelegateSafely();
273     if (!delegate) {
274         return nullptr;
275     }
276     delegate->GetUIFontConfig(fontConfigJsonInfo);
277     napi_value result = nullptr;
278     napi_create_object(env, &result);
279     napi_value fontDirSetResult = nullptr;
280     napi_create_array(env, &fontDirSetResult);
281     int32_t index = 0;
282     for (const std::string& fontDir : fontConfigJsonInfo.fontDirSet) {
283         napi_value fontDirResult = nullptr;
284         napi_create_string_utf8(env, fontDir.c_str(), fontDir.length(), &fontDirResult);
285         napi_set_element(env, fontDirSetResult, index++, fontDirResult);
286     }
287     napi_value genericSetResult = GetUIFontGenericInfo(env, fontConfigJsonInfo);
288     napi_value fallbackGroupSetResult = GetUIFontFallbackInfo(env, fontConfigJsonInfo);
289 
290     napi_set_named_property(env, result, "fontDir", fontDirSetResult);
291     napi_set_named_property(env, result, "generic", genericSetResult);
292     napi_set_named_property(env, result, "fallbackGroups", fallbackGroupSetResult);
293     return result;
294 }
295 
FontExport(napi_env env,napi_value exports)296 static napi_value FontExport(napi_env env, napi_value exports)
297 {
298     napi_property_descriptor fontDesc[] = {
299         DECLARE_NAPI_FUNCTION("registerFont", JSRegisterFont),
300         DECLARE_NAPI_FUNCTION("getSystemFontList", JSgetSystemFontList),
301         DECLARE_NAPI_FUNCTION("getFontByName", JSgetFontByName),
302         DECLARE_NAPI_FUNCTION("getUIFontConfig", JsGetUIFontConfig)
303     };
304     NAPI_CALL(env, napi_define_properties(env, exports, sizeof(fontDesc) / sizeof(fontDesc[0]), fontDesc));
305     return exports;
306 }
307 
308 static napi_module fontModule = {
309     .nm_version = 1,
310     .nm_flags = 0,
311     .nm_filename = nullptr,
312     .nm_register_func = FontExport,
313     .nm_modname = "font",
314     .nm_priv = ((void*)0),
315     .reserved = { 0 },
316 };
317 
FontRegister()318 extern "C" __attribute__((constructor)) void FontRegister()
319 {
320     napi_module_register(&fontModule);
321 }
322 } // namespace OHOS::Ace::Napi
323