1 /*
2 * Copyright (c) 2025 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_typefacearguments.h"
17
18 #include "native_value.h"
19
20 #include "js_drawing_utils.h"
21
22
23 namespace OHOS::Rosen {
24 namespace Drawing {
25 thread_local napi_ref JsTypeFaceArguments::constructor_ = nullptr;
26 const std::string CLASS_NAME = "TypefaceArguments";
27 constexpr uint32_t VARIATION_AXIS_LENGTH = 4;
28 constexpr uint32_t AXIS_OFFSET_ZERO = 24;
29 constexpr uint32_t AXIS_OFFSET_ONE = 16;
30 constexpr uint32_t AXIS_OFFSET_TWO = 8;
Init(napi_env env,napi_value exportObj)31 napi_value JsTypeFaceArguments::Init(napi_env env, napi_value exportObj)
32 {
33 napi_property_descriptor properties[] = {
34 DECLARE_NAPI_FUNCTION("addVariation", JsTypeFaceArguments::AddVariation),
35 };
36
37 napi_value constructor = nullptr;
38 napi_status status = napi_define_class(env, CLASS_NAME.c_str(), NAPI_AUTO_LENGTH, Constructor, nullptr,
39 sizeof(properties) /sizeof(properties[0]), properties, &constructor);
40 if (status != napi_ok) {
41 ROSEN_LOGE("JsTypeFaceArguments::Init failed to define Tool class");
42 return nullptr;
43 }
44
45 status = napi_create_reference(env, constructor, 1, &constructor_);
46 if (status != napi_ok) {
47 ROSEN_LOGE("JsTypeFaceArguments::Init failed to create a refenence of constructor");
48 return nullptr;
49 }
50
51 status = napi_set_named_property(env, exportObj, CLASS_NAME.c_str(), constructor);
52 if (status != napi_ok) {
53 ROSEN_LOGE("JsTypeFaceArguments::Init failed to set constructor");
54 return nullptr;
55 }
56 return exportObj;
57 }
58
Constructor(napi_env env,napi_callback_info info)59 napi_value JsTypeFaceArguments::Constructor(napi_env env, napi_callback_info info)
60 {
61 size_t argc = ARGC_ZERO;
62 napi_value jsThis = nullptr;
63 napi_status status = napi_get_cb_info(env, info, &argc, nullptr, &jsThis, nullptr);
64 if (status != napi_ok) {
65 ROSEN_LOGE("failed to napi_get_cb_info");
66 return nullptr;
67 }
68
69 if (argc != ARGC_ZERO) {
70 return NapiThrowError(env, DrawingErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
71 }
72 auto typeFaceArguments = std::make_shared<TypeFaceArgumentsHelper>();
73 JsTypeFaceArguments* jsTypeFaceArguments = new JsTypeFaceArguments(typeFaceArguments);
74
75 status = napi_wrap(env, jsThis, jsTypeFaceArguments, JsTypeFaceArguments::Destructor, nullptr, nullptr);
76 if (status != napi_ok) {
77 delete jsTypeFaceArguments;
78 ROSEN_LOGE("faile to wrap native instance");
79 return nullptr;
80 }
81 return jsThis;
82 }
83
Destructor(napi_env env,void * nativeObject,void * finalize)84 void JsTypeFaceArguments::Destructor(napi_env env, void* nativeObject, void* finalize)
85 {
86 (void) finalize;
87 if (nativeObject != nullptr) {
88 JsTypeFaceArguments *napi = reinterpret_cast<JsTypeFaceArguments*>(nativeObject);
89 delete napi;
90 }
91 }
92
~JsTypeFaceArguments()93 JsTypeFaceArguments::~JsTypeFaceArguments()
94 {
95 m_typeFaceArguments = nullptr;
96 }
97
GetTypeFaceArgumentsHelper()98 std::shared_ptr<TypeFaceArgumentsHelper> JsTypeFaceArguments::GetTypeFaceArgumentsHelper()
99 {
100 return m_typeFaceArguments;
101 }
102
ConvertToFontArguments(std::shared_ptr<TypeFaceArgumentsHelper> typeFaceArgumentsHelper,FontArguments & fontArguments)103 void JsTypeFaceArguments::ConvertToFontArguments(std::shared_ptr<TypeFaceArgumentsHelper> typeFaceArgumentsHelper,
104 FontArguments& fontArguments)
105 {
106 fontArguments.SetCollectionIndex(typeFaceArgumentsHelper->fontCollectionIndex);
107 fontArguments.SetVariationDesignPosition({reinterpret_cast<const FontArguments::VariationPosition::Coordinate*>(
108 typeFaceArgumentsHelper->coordinate.data()), typeFaceArgumentsHelper->coordinate.size()});
109 }
110
ConvertAxisToNumber(const std::string & axis)111 uint32_t JsTypeFaceArguments::ConvertAxisToNumber(const std::string& axis)
112 {
113 return (((uint32_t)axis[ARGC_ZERO] << AXIS_OFFSET_ZERO) | ((uint32_t)axis[ARGC_ONE] << AXIS_OFFSET_ONE) |
114 ((uint32_t)axis[ARGC_TWO] << AXIS_OFFSET_TWO) | ((uint32_t)axis[ARGC_THREE]));
115 }
116
AddVariation(napi_env env,napi_callback_info info)117 napi_value JsTypeFaceArguments::AddVariation(napi_env env, napi_callback_info info)
118 {
119 napi_value argv[ARGC_TWO] = {nullptr};
120 CHECK_PARAM_NUMBER_WITHOUT_OPTIONAL_PARAMS(argv, ARGC_TWO);
121
122 std::string axis = "";
123 GET_JSVALUE_PARAM(ARGC_ZERO, axis);
124 if (axis.length() != VARIATION_AXIS_LENGTH) {
125 return NapiThrowError(env, DrawingErrorCode::ERROR_PARAM_VERIFICATION_FAILED,
126 std::string("Incorrect parameter0 length, the length must be four"));
127 }
128
129 double value = 0.0;
130 GET_DOUBLE_PARAM(ARGC_ONE, value);
131
132 JsTypeFaceArguments* jsTypeFaceArguments = CheckParamsAndGetThis<JsTypeFaceArguments>(env, info);
133 if (jsTypeFaceArguments == nullptr) {
134 ROSEN_LOGE("JsTypeFaceArguments::AddVariation this is nullptr");
135 return nullptr;
136 }
137 auto typeFaceArgumentsHelper = jsTypeFaceArguments->GetTypeFaceArgumentsHelper();
138 if (typeFaceArgumentsHelper == nullptr) {
139 ROSEN_LOGE("JsTypeFaceArguments::AddVariation failed to GetTypeFaceArgumentsHelper");
140 return nullptr;
141 }
142 typeFaceArgumentsHelper->coordinate.push_back({ConvertAxisToNumber(axis), (float)value});
143 return nullptr;
144 }
145
146 } // namespace Drawing
147 } // namespace OHOS::Rosen