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_drawing_utils.h"
17 
18 #ifdef ROSEN_OHOS
19 #include <parameters.h>
20 #endif
21 
22 #include "draw/color.h"
23 
24 namespace OHOS::Rosen {
25 
26 #ifdef ROSEN_OHOS
27 bool JsDrawingTestUtils::closeDrawingTest_ =
28     std::atoi((OHOS::system::GetParameter("persist.sys.graphic.drawing.test", "0").c_str())) != 1;
29 #else
30 bool JsDrawingTestUtils::closeDrawingTest_ = true;
31 #endif
32 
33 namespace Drawing {
BindNativeFunction(napi_env env,napi_value object,const char * name,const char * moduleName,napi_callback func)34 void BindNativeFunction(napi_env env, napi_value object, const char* name, const char* moduleName, napi_callback func)
35 {
36     std::string fullName;
37     if (moduleName) {
38         fullName = moduleName;
39         fullName += '.';
40     }
41     fullName += name;
42     napi_value funcValue = nullptr;
43     napi_create_function(env, fullName.c_str(), fullName.size(), func, nullptr, &funcValue);
44     napi_set_named_property(env, object, fullName.c_str(), funcValue);
45 }
46 
CreateJsError(napi_env env,int32_t errCode,const std::string & message)47 napi_value CreateJsError(napi_env env, int32_t errCode, const std::string& message)
48 {
49     napi_value result = nullptr;
50     napi_create_error(env, CreateJsValue(env, errCode), CreateJsValue(env, message), &result);
51     return result;
52 }
53 
ConvertFromJsTextEncoding(napi_env env,TextEncoding & textEncoding,napi_value nativeType)54 bool ConvertFromJsTextEncoding(napi_env env, TextEncoding& textEncoding, napi_value nativeType)
55 {
56     napi_value type = nativeType;
57     if (type == nullptr) {
58         return false;
59     }
60     uint32_t resultValue = 0;
61     napi_get_value_uint32(env, type, &resultValue);
62 
63     switch (resultValue) {
64         case 0: // 0: TextEncoding::UTF8
65             textEncoding = TextEncoding::UTF8;
66             break;
67         case 1: // 1: TextEncoding::UTF16
68             textEncoding = TextEncoding::UTF16;
69             break;
70         case 2: // 2: TextEncoding::UTF32
71             textEncoding = TextEncoding::UTF32;
72             break;
73         case 3: // 3: TextEncoding::GLYPH_ID
74             textEncoding = TextEncoding::GLYPH_ID;
75             break;
76         default: // default: TextEncoding::UTF8
77             textEncoding = TextEncoding::UTF8;
78             break;
79     }
80     return true;
81 }
82 
NapiThrowError(napi_env env,DrawingErrorCode err,const std::string & message)83 napi_value NapiThrowError(napi_env env, DrawingErrorCode err, const std::string& message)
84 {
85     napi_throw(env, CreateJsError(env, static_cast<int32_t>(err), message));
86     return nullptr;
87 }
88 
89 static const char* g_argbString[4] = {"alpha", "red", "green", "blue"};
90 static const char* g_ltrbString[4] = {"left", "top", "right", "bottom"};
91 static const char* g_pointString[2] = {"x", "y"};
92 
ConvertFromJsColor(napi_env env,napi_value jsValue,int32_t * argb,size_t size)93 bool ConvertFromJsColor(napi_env env, napi_value jsValue, int32_t* argb, size_t size)
94 {
95     napi_value tempValue = nullptr;
96     for (size_t idx = 0; idx < size; idx++) {
97         int32_t* curChannel = argb + idx;
98         napi_get_named_property(env, jsValue, g_argbString[idx], &tempValue);
99         if (napi_get_value_int32(env, tempValue, curChannel) != napi_ok ||
100             *curChannel < 0 || *curChannel > Color::RGB_MAX) {
101             return false;
102         }
103     }
104     return true;
105 }
106 
ConvertFromJsRect(napi_env env,napi_value jsValue,double * ltrb,size_t size)107 bool ConvertFromJsRect(napi_env env, napi_value jsValue, double* ltrb, size_t size)
108 {
109     napi_value tempValue = nullptr;
110     for (size_t idx = 0; idx < size; idx++) {
111         double* curEdge = ltrb + idx;
112         napi_get_named_property(env, jsValue, g_ltrbString[idx], &tempValue);
113         if (napi_get_value_double(env, tempValue, curEdge) != napi_ok) {
114             return false;
115         }
116     }
117     return true;
118 }
119 
ConvertFromJsIRect(napi_env env,napi_value jsValue,int32_t * ltrb,size_t size)120 bool ConvertFromJsIRect(napi_env env, napi_value jsValue, int32_t* ltrb, size_t size)
121 {
122     napi_value tempValue = nullptr;
123     for (size_t idx = 0; idx < size; idx++) {
124         int32_t* curEdge = ltrb + idx;
125         napi_get_named_property(env, jsValue, g_ltrbString[idx], &tempValue);
126         if (napi_get_value_int32(env, tempValue, curEdge) != napi_ok) {
127             return false;
128         }
129     }
130     return true;
131 }
132 
ConvertFromJsShadowFlag(napi_env env,napi_value src,ShadowFlags & shadowFlag,ShadowFlags defaultFlag)133 bool ConvertFromJsShadowFlag(napi_env env, napi_value src, ShadowFlags& shadowFlag, ShadowFlags defaultFlag)
134 {
135     if (src == nullptr) {
136         return false;
137     }
138     uint32_t value = 0;
139     if (!ConvertFromJsValue(env, src, value)) {
140         return false;
141     }
142     shadowFlag = defaultFlag;
143     if (value >= static_cast<uint32_t>(ShadowFlags::NONE) && value <= static_cast<uint32_t>(ShadowFlags::ALL)) {
144         shadowFlag = static_cast<ShadowFlags>(value);
145     }
146     return true;
147 }
148 
ConvertFromJsPoint3d(napi_env env,napi_value src,Point3 & point3d)149 bool ConvertFromJsPoint3d(napi_env env, napi_value src, Point3& point3d)
150 {
151     if (src == nullptr) {
152         return false;
153     }
154     napi_value tempValue = nullptr;
155     double x = 0.0;
156     double y = 0.0;
157     double z = 0.0;
158     napi_get_named_property(env, src, "x", &tempValue);
159     bool isXOk = ConvertFromJsValue(env, tempValue, x);
160     napi_get_named_property(env, src, "y", &tempValue);
161     bool isYOk = ConvertFromJsValue(env, tempValue, y);
162     napi_get_named_property(env, src, "z", &tempValue);
163     bool isZOk = ConvertFromJsValue(env, tempValue, z);
164     if (!(isXOk && isYOk && isZOk)) {
165         return false;
166     }
167     point3d = Point3(x, y, z);
168     return true;
169 }
170 
ConvertFromJsPoint(napi_env env,napi_value jsValue,double * point,size_t size)171 bool ConvertFromJsPoint(napi_env env, napi_value jsValue, double* point, size_t size)
172 {
173     napi_value tempValue = nullptr;
174     for (size_t idx = 0; idx < size; idx++) {
175         double* curEdge = point + idx;
176         napi_get_named_property(env, jsValue, g_pointString[idx], &tempValue);
177         if (napi_get_value_double(env, tempValue, curEdge) != napi_ok) {
178             return false;
179         }
180     }
181     return true;
182 }
183 
ConvertFromJsPointsArray(napi_env env,napi_value array,Drawing::Point * points,uint32_t count)184 bool ConvertFromJsPointsArray(napi_env env, napi_value array, Drawing::Point* points, uint32_t count)
185 {
186     for (uint32_t i = 0; i < count; i++)  {
187         napi_value tempPoint = nullptr;
188         if (napi_get_element(env, array, i, &tempPoint) != napi_ok) {
189             return false;
190         }
191         if (!GetDrawingPointFromJsValue(env, tempPoint, points[i])) {
192             return false;
193         }
194     }
195     return true;
196 }
197 
GetFontMetricsAndConvertToJsValue(napi_env env,FontMetrics * metrics)198 napi_value GetFontMetricsAndConvertToJsValue(napi_env env, FontMetrics* metrics)
199 {
200     napi_value objValue = nullptr;
201     napi_create_object(env, &objValue);
202     if (metrics != nullptr && objValue != nullptr) {
203         napi_set_named_property(env, objValue, "top", CreateJsNumber(env, metrics->fTop));
204         napi_set_named_property(env, objValue, "ascent", CreateJsNumber(env, metrics->fAscent));
205         napi_set_named_property(env, objValue, "descent", CreateJsNumber(env, metrics->fDescent));
206         napi_set_named_property(env, objValue, "bottom", CreateJsNumber(env, metrics->fBottom));
207         napi_set_named_property(env, objValue, "leading", CreateJsNumber(env, metrics->fLeading));
208         napi_set_named_property(env, objValue, "flags", CreateJsNumber(env, metrics->fFlags));
209         napi_set_named_property(env, objValue, "avgCharWidth", CreateJsNumber(env, metrics->fAvgCharWidth));
210         napi_set_named_property(env, objValue, "maxCharWidth", CreateJsNumber(env, metrics->fMaxCharWidth));
211         napi_set_named_property(env, objValue, "xMin", CreateJsNumber(env, metrics->fXMin));
212         napi_set_named_property(env, objValue, "xMax", CreateJsNumber(env, metrics->fXMax));
213         napi_set_named_property(env, objValue, "xHeight", CreateJsNumber(env, metrics->fXHeight));
214         napi_set_named_property(env, objValue, "capHeight", CreateJsNumber(env, metrics->fCapHeight));
215         napi_set_named_property(env, objValue, "underlineThickness", CreateJsNumber(env,
216             metrics->fUnderlineThickness));
217         napi_set_named_property(env, objValue, "underlinePosition", CreateJsNumber(env,
218             metrics->fUnderlinePosition));
219         napi_set_named_property(env, objValue, "strikethroughThickness", CreateJsNumber(env,
220             metrics->fStrikeoutThickness));
221         napi_set_named_property(env, objValue, "strikethroughPosition", CreateJsNumber(env,
222             metrics->fStrikeoutPosition));
223     }
224     return objValue;
225 }
226 } // namespace Drawing
227 } // namespace OHOS::Rosen
228