• 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_fontdescriptor.h"
17 
18 #include "font_descriptor_mgr.h"
19 #include "napi_async_work.h"
20 #include "napi_common.h"
21 
22 namespace OHOS::Rosen {
23 namespace {
24 std::unordered_map<int, int> g_weightMap = {
25     {100, static_cast<int>(FontWeight::W100)},
26     {200, static_cast<int>(FontWeight::W200)},
27     {300, static_cast<int>(FontWeight::W300)},
28     {400, static_cast<int>(FontWeight::W400)},
29     {500, static_cast<int>(FontWeight::W500)},
30     {600, static_cast<int>(FontWeight::W600)},
31     {700, static_cast<int>(FontWeight::W700)},
32     {800, static_cast<int>(FontWeight::W800)},
33     {900, static_cast<int>(FontWeight::W900)}
34 };
35 }
36 
Init(napi_env env,napi_value exportObj)37 napi_value JsFontDescriptor::Init(napi_env env, napi_value exportObj)
38 {
39     napi_property_descriptor properties[] = {
40         DECLARE_NAPI_STATIC_FUNCTION("getSystemFontFullNamesByType", JsFontDescriptor::GetSystemFontFullNamesByType),
41         DECLARE_NAPI_STATIC_FUNCTION("getFontDescriptorByFullName", JsFontDescriptor::GetFontDescriptorByFullName),
42     };
43 
44     NAPI_CHECK_AND_THROW_ERROR(
45         napi_define_properties(env, exportObj, sizeof(properties) / sizeof(properties[0]), properties) == napi_ok,
46         TextErrorCode::ERROR_INVALID_PARAM, "Failed to define properties");
47     return exportObj;
48 }
49 
JsFontDescriptor()50 JsFontDescriptor::JsFontDescriptor() {}
51 
52 
SetProperty(napi_env env,napi_value object,const char * name,napi_value value)53 bool JsFontDescriptor::SetProperty(napi_env env, napi_value object, const char* name, napi_value value)
54 {
55     TEXT_ERROR_CHECK(napi_set_named_property(env, object, name, value) == napi_ok, return false,
56         "Failed to set %{public}s", name);
57     return true;
58 }
59 
ConvertFontDescWeight(napi_env env,napi_value obj,int weight)60 bool JsFontDescriptor::ConvertFontDescWeight(napi_env env, napi_value obj, int weight)
61 {
62     auto iter = g_weightMap.find(weight);
63     if (iter == g_weightMap.end()) {
64         return false;
65     }
66     TEXT_CHECK_RETURN_VALUE(SetProperty(env, obj, "weight", CreateJsValue(env, iter->second)), false);
67     return true;
68 }
69 
CreateAndSetProperties(napi_env env,napi_value fontDescriptor,FontDescSharedPtr item)70 bool JsFontDescriptor::CreateAndSetProperties(napi_env env, napi_value fontDescriptor, FontDescSharedPtr item)
71 {
72     std::vector<std::pair<const char*, std::variant<int, double, bool, std::string>>> properties = {
73         {"path", item->path},
74         {"postScriptName", item->postScriptName},
75         {"fullName", item->fullName},
76         {"fontFamily", item->fontFamily},
77         {"fontSubfamily", item->fontSubfamily},
78         {"width", item->width},
79         {"italic", item->italic},
80         {"monoSpace", item->monoSpace},
81         {"symbolic", item->symbolic},
82     };
83 
84     for (const auto& prop : properties) {
85         TEXT_CHECK(std::visit([&](auto& p) -> bool {
86             TEXT_CHECK(SetProperty(env, fontDescriptor, prop.first, CreateJsValue(env, p)), return false);
87             return true;
88         }, prop.second), return false);
89     }
90     return true;
91 }
92 
CreateFontDescriptor(napi_env env,FontDescSharedPtr & result)93 napi_value JsFontDescriptor::CreateFontDescriptor(napi_env env, FontDescSharedPtr& result)
94 {
95     TEXT_ERROR_CHECK(env != nullptr, return nullptr, "Env is nullptr");
96     TEXT_ERROR_CHECK(result != nullptr, return nullptr, "FontDescSharedPtr is nullptr");
97     napi_value fontDescriptor = nullptr;
98     TEXT_ERROR_CHECK(napi_create_object(env, &fontDescriptor) == napi_ok, return nullptr,
99         "Failed to create fontDescriptor");
100     TEXT_CHECK(CreateAndSetProperties(env, fontDescriptor, result), return nullptr);
101     TEXT_CHECK(ConvertFontDescWeight(env, fontDescriptor, result->weight), return nullptr);
102     return fontDescriptor;
103 }
104 
GetSystemFontFullNamesByType(napi_env env,napi_callback_info info)105 napi_value JsFontDescriptor::GetSystemFontFullNamesByType(napi_env env, napi_callback_info info)
106 {
107     struct SystemFontListContext : public ContextBase {
108         TextEngine::FontParser::SystemFontType systemFontType;
109         std::unordered_set<std::string> fontList;
110     };
111 
112     sptr<SystemFontListContext> context = sptr<SystemFontListContext>::MakeSptr();
113 
114     NAPI_CHECK_AND_THROW_ERROR(context != nullptr, TextErrorCode::ERROR_NO_MEMORY,
115         "Failed to get systemFont fullName list by type, no memory");
116 
117     auto inputParser = [env, context](size_t argc, napi_value *argv) {
118         TEXT_ERROR_CHECK(argv != nullptr, return, "Argv is nullptr");
119         NAPI_CHECK_ARGS(context, context->status == napi_ok, napi_invalid_arg,
120             TextErrorCode::ERROR_INVALID_PARAM, return, "Status error, status=%d", static_cast<int>(context->status));
121         NAPI_CHECK_ARGS(context, argc == ARGC_ONE, napi_invalid_arg, TextErrorCode::ERROR_INVALID_PARAM,
122             return, "Argc is invalid %zu", argc);
123         NAPI_CHECK_ARGS(context, ConvertFromJsValue(env, argv[0], context->systemFontType), napi_invalid_arg,
124             TextErrorCode::ERROR_INVALID_PARAM, return, "Parameter systemFontType is invalid");
125     };
126 
127     context->GetCbInfo(env, info, inputParser);
128 
129     auto executor = [context]() {
130         FontDescriptorMgrInstance.GetSystemFontFullNamesByType(context->systemFontType, context->fontList);
131     };
132 
133     auto complete = [env, context](napi_value& output) {
134         output = JsFontDescriptor::CreateFontList(env, context->fontList);
135     };
136 
137     return NapiAsyncWork::Enqueue(env, context, "GetSystemFontFullNamesByType", executor, complete);
138 }
139 
CreateFontList(napi_env env,std::unordered_set<std::string> & fontList)140 napi_value JsFontDescriptor::CreateFontList(napi_env env, std::unordered_set<std::string>& fontList)
141 {
142     TEXT_ERROR_CHECK(env != nullptr, return nullptr, "Env is nullptr");
143     napi_value fullNameArray = nullptr;
144     TEXT_ERROR_CHECK(napi_create_array(env, &fullNameArray) == napi_ok, return nullptr,
145         "Failed to create fontList");
146     uint32_t index = 0;
147     for (const auto& item : fontList) {
148         napi_value fullName = nullptr;
149         TEXT_ERROR_CHECK(napi_create_string_utf8(env, item.c_str(), NAPI_AUTO_LENGTH, &fullName) == napi_ok,
150             return nullptr, "Failed to create utf8 to string");
151         TEXT_ERROR_CHECK(napi_set_element(env, fullNameArray, index++, fullName) == napi_ok, return nullptr,
152             "Failed to set element");
153     }
154     return fullNameArray;
155 }
156 
GetFontDescriptorByFullName(napi_env env,napi_callback_info info)157 napi_value JsFontDescriptor::GetFontDescriptorByFullName(napi_env env, napi_callback_info info)
158 {
159     struct FontDescriptorContext : public ContextBase {
160         std::string fullName;
161         TextEngine::FontParser::SystemFontType systemFontType;
162         FontDescSharedPtr resultDesc = nullptr;
163     };
164 
165     sptr<FontDescriptorContext> context = sptr<FontDescriptorContext>::MakeSptr();
166 
167     NAPI_CHECK_AND_THROW_ERROR(context != nullptr, TextErrorCode::ERROR_NO_MEMORY,
168         "Failed to get fontDescriptor by name, no memory");
169 
170     auto inputParser = [env, context](size_t argc, napi_value *argv) {
171         TEXT_ERROR_CHECK(argv != nullptr, return, "Argv is nullptr");
172         NAPI_CHECK_ARGS(context, context->status == napi_ok, napi_invalid_arg,
173             TextErrorCode::ERROR_INVALID_PARAM, return, "Status error, status=%d", static_cast<int>(context->status));
174         NAPI_CHECK_ARGS(context, argc == ARGC_TWO, napi_invalid_arg, TextErrorCode::ERROR_INVALID_PARAM,
175             return, "Argc is invalid %zu", argc);
176         NAPI_CHECK_ARGS(context, ConvertFromJsValue(env, argv[0], context->fullName), napi_invalid_arg,
177             TextErrorCode::ERROR_INVALID_PARAM, return, "Parameter fullName is invalid");
178         NAPI_CHECK_ARGS(context, ConvertFromJsValue(env, argv[1], context->systemFontType), napi_invalid_arg,
179             TextErrorCode::ERROR_INVALID_PARAM, return, "Parameter systemFontType is invalid");
180     };
181 
182     context->GetCbInfo(env, info, inputParser);
183 
184     auto executor = [context]() {
185         FontDescriptorMgrInstance.GetFontDescSharedPtrByFullName(
186             context->fullName, context->systemFontType, context->resultDesc);
187     };
188 
189     auto complete = [env, context](napi_value& output) {
190         output = JsFontDescriptor::CreateFontDescriptor(env, context->resultDesc);
191     };
192 
193     return NapiAsyncWork::Enqueue(env, context, "GetFontDescriptorByFullName", executor, complete);
194 }
195 }