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 #ifndef OHOS_JS_DRAWING_UTILS_H
17 #define OHOS_JS_DRAWING_UTILS_H
18
19 #include <map>
20 #ifdef ROSEN_OHOS
21 #include "hilog/log.h"
22 #endif
23
24 #include "native_engine/native_engine.h"
25 #include "native_engine/native_value.h"
26 #include "text/font_metrics.h"
27 #include "text/font_types.h"
28 #include "utils/rect.h"
29
30 namespace OHOS::Rosen {
31 namespace Drawing {
32 constexpr size_t ARGC_ONE = 1;
33 constexpr size_t ARGC_TWO = 2;
34 constexpr size_t ARGC_THREE = 3;
35 constexpr size_t ARGC_FOUR = 4;
36 constexpr size_t ARGC_FIVE = 5;
37 constexpr size_t ARGC_SIX = 6;
38
39 enum class DrawingErrorCode : int32_t {
40 OK = 0,
41 ERROR_NO_PERMISSION = 201, // the value do not change. It is defined on all system
42 ERROR_INVALID_PARAM = 401, // the value do not change. It is defined on all system
43 ERROR_DEVICE_NOT_SUPPORT = 801, // the value do not change. It is defined on all system
44 ERROR_ABNORMAL_PARAM_VALUE = 18600001, // the value do not change. It is defined on color manager system
45 };
46
47 template<class T>
48 T* CheckParamsAndGetThis(const napi_env env, napi_callback_info info, const char* name = nullptr)
49 {
50 if (env == nullptr || info == nullptr) {
51 return nullptr;
52 }
53 napi_value object = nullptr;
54 napi_value propertyNameValue = nullptr;
55 napi_value pointerValue = nullptr;
56 napi_get_cb_info(env, info, nullptr, nullptr, &object, nullptr);
57 if (object != nullptr && name != nullptr) {
58 napi_create_string_utf8(env, name, NAPI_AUTO_LENGTH, &propertyNameValue);
59 }
60 napi_value& resObject = propertyNameValue ? propertyNameValue : object;
61 if (resObject) {
62 return napi_unwrap(env, resObject, (void **)(&pointerValue)) == napi_ok ?
63 reinterpret_cast<T*>(pointerValue) : nullptr;
64 }
65 return nullptr;
66 }
67
68 template<typename T, size_t N>
ArraySize(T (&)[N])69 inline constexpr size_t ArraySize(T (&)[N]) noexcept
70 {
71 return N;
72 }
73
CreateJsUndefined(napi_env env)74 inline napi_value CreateJsUndefined(napi_env env)
75 {
76 napi_value result = nullptr;
77 napi_get_undefined(env, &result);
78 return result;
79 }
80
CreateJsNull(napi_env env)81 inline napi_value CreateJsNull(napi_env env)
82 {
83 napi_value result = nullptr;
84 napi_get_null(env, &result);
85 return result;
86 }
87
CreateJsNumber(napi_env env,int32_t value)88 inline napi_value CreateJsNumber(napi_env env, int32_t value)
89 {
90 napi_value result = nullptr;
91 napi_create_int32(env, value, &result);
92 return result;
93 }
94
CreateJsNumber(napi_env env,uint32_t value)95 inline napi_value CreateJsNumber(napi_env env, uint32_t value)
96 {
97 napi_value result = nullptr;
98 napi_create_uint32(env, value, &result);
99 return result;
100 }
101
CreateJsNumber(napi_env env,int64_t value)102 inline napi_value CreateJsNumber(napi_env env, int64_t value)
103 {
104 napi_value result = nullptr;
105 napi_create_int64(env, value, &result);
106 return result;
107 }
108
CreateJsNumber(napi_env env,double value)109 inline napi_value CreateJsNumber(napi_env env, double value)
110 {
111 napi_value result = nullptr;
112 napi_create_double(env, value, &result);
113 return result;
114 }
115
116 template<class T>
CreateJsValue(napi_env env,const T & value)117 napi_value CreateJsValue(napi_env env, const T& value)
118 {
119 using ValueType = std::remove_cv_t<std::remove_reference_t<T>>;
120 napi_value result = nullptr;
121 if constexpr (std::is_same_v<ValueType, bool>) {
122 napi_get_boolean(env, value, &result);
123 return result;
124 } else if constexpr (std::is_arithmetic_v<ValueType>) {
125 return CreateJsNumber(env, value);
126 } else if constexpr (std::is_same_v<ValueType, std::string>) {
127 napi_create_string_utf8(env, value.c_str(), value.length(), &result);
128 return result;
129 } else if constexpr (std::is_enum_v<ValueType>) {
130 return CreateJsNumber(env, static_cast<std::make_signed_t<ValueType>>(value));
131 } else if constexpr (std::is_same_v<ValueType, const char*>) {
132 (value != nullptr) ? napi_create_string_utf8(env, value, strlen(value), &result) :
133 napi_get_undefined(env, &result);
134 return result;
135 }
136 }
137
ConvertFromJsNumber(napi_env env,napi_value jsValue,int32_t & value)138 inline bool ConvertFromJsNumber(napi_env env, napi_value jsValue, int32_t& value)
139 {
140 return napi_get_value_int32(env, jsValue, &value) == napi_ok;
141 }
142
ConvertFromJsNumber(napi_env env,napi_value jsValue,uint32_t & value)143 inline bool ConvertFromJsNumber(napi_env env, napi_value jsValue, uint32_t& value)
144 {
145 return napi_get_value_uint32(env, jsValue, &value) == napi_ok;
146 }
147
ConvertFromJsNumber(napi_env env,napi_value jsValue,int64_t & value)148 inline bool ConvertFromJsNumber(napi_env env, napi_value jsValue, int64_t& value)
149 {
150 return napi_get_value_int64(env, jsValue, &value) == napi_ok;
151 }
152
ConvertFromJsNumber(napi_env env,napi_value jsValue,double & value)153 inline bool ConvertFromJsNumber(napi_env env, napi_value jsValue, double& value)
154 {
155 return napi_get_value_double(env, jsValue, &value) == napi_ok;
156 }
157
ConvertFromJsNumber(napi_env env,napi_value jsValue,bool & value)158 inline bool ConvertFromJsNumber(napi_env env, napi_value jsValue, bool& value)
159 {
160 return napi_get_value_bool(env, jsValue, &value) == napi_ok;
161 }
162
163 template<class T>
ConvertFromJsValue(napi_env env,napi_value jsValue,T & value)164 bool ConvertFromJsValue(napi_env env, napi_value jsValue, T& value)
165 {
166 if (jsValue == nullptr) {
167 return false;
168 }
169
170 using ValueType = std::remove_cv_t<std::remove_reference_t<T>>;
171 if constexpr (std::is_same_v<ValueType, bool>) {
172 return napi_get_value_bool(env, jsValue, &value) == napi_ok;
173 } else if constexpr (std::is_arithmetic_v<ValueType>) {
174 return ConvertFromJsNumber(env, jsValue, value);
175 } else if constexpr (std::is_same_v<ValueType, std::string>) {
176 size_t len = 0;
177 if (napi_get_value_string_utf8(env, jsValue, nullptr, 0, &len) != napi_ok) {
178 return false;
179 }
180 auto buffer = std::make_unique<char[]>(len + 1);
181 size_t strLength = 0;
182 if (napi_get_value_string_utf8(env, jsValue, buffer.get(), len + 1, &strLength) == napi_ok) {
183 value = buffer.get();
184 return true;
185 }
186 return false;
187 } else if constexpr (std::is_enum_v<ValueType>) {
188 std::make_signed_t<ValueType> numberValue = 0;
189 if (!ConvertFromJsNumber(env, jsValue, numberValue)) {
190 return false;
191 }
192 value = static_cast<ValueType>(numberValue);
193 return true;
194 }
195 return false;
196 }
197
ConvertClampFromJsValue(napi_env env,napi_value jsValue,int32_t & value,int32_t lo,int32_t hi)198 inline bool ConvertClampFromJsValue(napi_env env, napi_value jsValue, int32_t& value, int32_t lo, int32_t hi)
199 {
200 if (jsValue == nullptr) {
201 return false;
202 }
203 bool ret = napi_get_value_int32(env, jsValue, &value) == napi_ok;
204 value = std::clamp(value, lo, hi);
205 return ret;
206 }
207
GetDoubleAndConvertToJsValue(napi_env env,double d)208 inline napi_value GetDoubleAndConvertToJsValue(napi_env env, double d)
209 {
210 napi_value value = nullptr;
211 (void)napi_create_double(env, d, &value);
212 return value;
213 }
214
GetStringAndConvertToJsValue(napi_env env,std::string str)215 inline napi_value GetStringAndConvertToJsValue(napi_env env, std::string str)
216 {
217 napi_value objValue = nullptr;
218 napi_create_string_utf8(env, str.c_str(), str.length(), &objValue);
219 return objValue;
220 }
221
GetFontMetricsAndConvertToJsValue(napi_env env,FontMetrics * metrics)222 inline napi_value GetFontMetricsAndConvertToJsValue(napi_env env, FontMetrics* metrics)
223 {
224 napi_value objValue = nullptr;
225 napi_create_object(env, &objValue);
226 if (metrics != nullptr && objValue != nullptr) {
227 napi_set_named_property(env, objValue, "top", CreateJsNumber(env, metrics->fTop));
228 napi_set_named_property(env, objValue, "ascent", CreateJsNumber(env, metrics->fAscent));
229 napi_set_named_property(env, objValue, "descent", CreateJsNumber(env, metrics->fDescent));
230 napi_set_named_property(env, objValue, "bottom", CreateJsNumber(env, metrics->fBottom));
231 napi_set_named_property(env, objValue, "leading", CreateJsNumber(env, metrics->fLeading));
232 }
233 return objValue;
234 }
235
GetRectAndConvertToJsValue(napi_env env,std::shared_ptr<Rect> rect)236 inline napi_value GetRectAndConvertToJsValue(napi_env env, std::shared_ptr<Rect> rect)
237 {
238 napi_value objValue = nullptr;
239 napi_create_object(env, &objValue);
240 if (rect != nullptr && objValue != nullptr) {
241 napi_set_named_property(env, objValue, "left", CreateJsNumber(env, rect->GetLeft()));
242 napi_set_named_property(env, objValue, "top", CreateJsNumber(env, rect->GetTop()));
243 napi_set_named_property(env, objValue, "right", CreateJsNumber(env, rect->GetRight()));
244 napi_set_named_property(env, objValue, "bottom", CreateJsNumber(env, rect->GetBottom()));
245 }
246 return objValue;
247 }
248
NapiGetUndefined(napi_env env)249 inline napi_value NapiGetUndefined(napi_env env)
250 {
251 napi_value result = nullptr;
252 napi_get_undefined(env, &result);
253 return result;
254 }
255
256 void BindNativeFunction(napi_env env, napi_value object, const char* name, const char* moduleName, napi_callback func);
257 napi_value CreateJsError(napi_env env, int32_t errCode, const std::string& message);
258
259 bool ConvertFromJsTextEncoding(napi_env env, TextEncoding& textEncoding, napi_value nativeType);
260
261 napi_value NapiThrowError(napi_env env, DrawingErrorCode err, const std::string& message);
262 } // namespace Drawing
263 } // namespace OHOS::Rosen
264
265 #ifdef ROSEN_OHOS
266 constexpr OHOS::HiviewDFX::HiLogLabel LABEL_ROSEN = {LOG_CORE, 0xD001400, "JsDrawing"};
267 #define ROSEN_LOGI(format, ...) \
268 OHOS::HiviewDFX::HiLog::Info(LABEL_ROSEN, format, ##__VA_ARGS__)
269 #define ROSEN_LOGD(format, ...) \
270 OHOS::HiviewDFX::HiLog::Debug(LABEL_ROSEN, format, ##__VA_ARGS__)
271 #define ROSEN_LOGE(format, ...) \
272 OHOS::HiviewDFX::HiLog::Error(LABEL_ROSEN, format, ##__VA_ARGS__)
273 #else
274 #define ROSEN_LOGI(format, ...)
275 #define ROSEN_LOGD(format, ...)
276 #define ROSEN_LOGE(format, ...)
277 #endif
278
279 #endif // OHOS_JS_DRAWING_UTILS_H
280