• 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 "font_napi/js_typeface.h"
17 #include "js_drawing_utils.h"
18 
19 #ifdef ROSEN_OHOS
20 #include <parameters.h>
21 #endif
22 
23 #include "draw/color.h"
24 #include "rosen_text/font_collection.h"
25 
26 namespace OHOS::Rosen {
27 
28 #ifdef ROSEN_OHOS
29 bool JsDrawingTestUtils::closeDrawingTest_ =
30     std::atoi((OHOS::system::GetParameter("persist.sys.graphic.drawing.test", "0").c_str())) != 1;
31 #else
32 bool JsDrawingTestUtils::closeDrawingTest_ = true;
33 #endif
34 
35 namespace Drawing {
36 const char* const JSCOLOR[4] = {"alpha", "red", "green", "blue"};
37 
BindNativeFunction(napi_env env,napi_value object,const char * name,const char * moduleName,napi_callback func)38 void BindNativeFunction(napi_env env, napi_value object, const char* name, const char* moduleName, napi_callback func)
39 {
40     std::string fullName;
41     if (moduleName) {
42         fullName = moduleName;
43         fullName += '.';
44     }
45     fullName += name;
46     napi_value funcValue = nullptr;
47     napi_create_function(env, fullName.c_str(), fullName.size(), func, nullptr, &funcValue);
48     napi_set_named_property(env, object, fullName.c_str(), funcValue);
49 }
50 
CreateJsError(napi_env env,int32_t errCode,const std::string & message)51 napi_value CreateJsError(napi_env env, int32_t errCode, const std::string& message)
52 {
53     napi_value result = nullptr;
54     napi_create_error(env, CreateJsValue(env, errCode), CreateJsValue(env, message), &result);
55     return result;
56 }
57 
ConvertFromJsTextEncoding(napi_env env,TextEncoding & textEncoding,napi_value nativeType)58 bool ConvertFromJsTextEncoding(napi_env env, TextEncoding& textEncoding, napi_value nativeType)
59 {
60     napi_value type = nativeType;
61     if (type == nullptr) {
62         return false;
63     }
64     uint32_t resultValue = 0;
65     napi_get_value_uint32(env, type, &resultValue);
66 
67     switch (resultValue) {
68         case 0: // 0: TextEncoding::UTF8
69             textEncoding = TextEncoding::UTF8;
70             break;
71         case 1: // 1: TextEncoding::UTF16
72             textEncoding = TextEncoding::UTF16;
73             break;
74         case 2: // 2: TextEncoding::UTF32
75             textEncoding = TextEncoding::UTF32;
76             break;
77         case 3: // 3: TextEncoding::GLYPH_ID
78             textEncoding = TextEncoding::GLYPH_ID;
79             break;
80         default: // default: TextEncoding::UTF8
81             textEncoding = TextEncoding::UTF8;
82             break;
83     }
84     return true;
85 }
86 
NapiThrowError(napi_env env,DrawingErrorCode err,const std::string & message)87 napi_value NapiThrowError(napi_env env, DrawingErrorCode err, const std::string& message)
88 {
89     napi_throw(env, CreateJsError(env, static_cast<int32_t>(err), message));
90     return nullptr;
91 }
92 
93 static const char* g_argbString[4] = {"alpha", "red", "green", "blue"};
94 static const char* g_ltrbString[4] = {"left", "top", "right", "bottom"};
95 static const char* g_pointString[2] = {"x", "y"};
96 
ConvertFromJsColor(napi_env env,napi_value jsValue,int32_t * argb,size_t size)97 bool ConvertFromJsColor(napi_env env, napi_value jsValue, int32_t* argb, size_t size)
98 {
99     napi_value tempValue = nullptr;
100     for (size_t idx = 0; idx < size; idx++) {
101         int32_t* curChannel = argb + idx;
102         napi_get_named_property(env, jsValue, g_argbString[idx], &tempValue);
103         if (napi_get_value_int32(env, tempValue, curChannel) != napi_ok ||
104             *curChannel < 0 || *curChannel > Color::RGB_MAX) {
105             return false;
106         }
107     }
108     return true;
109 }
110 
ConvertFromAdaptHexJsColor(napi_env env,napi_value jsValue,Drawing::ColorQuad & jsColor)111 bool ConvertFromAdaptHexJsColor(napi_env env, napi_value jsValue, Drawing::ColorQuad& jsColor)
112 {
113     bool isJsColor = false;
114     napi_has_named_property(env, jsValue, JSCOLOR[0], &isJsColor);
115     if (isJsColor) {
116         int32_t argb[ARGC_FOUR] = {0};
117         if (!ConvertFromJsColor(env, jsValue, argb, ARGC_FOUR)) {
118             return false;
119         }
120         jsColor = Color::ColorQuadSetARGB(argb[ARGC_ZERO], argb[ARGC_ONE], argb[ARGC_TWO], argb[ARGC_THREE]);
121     } else {
122         if (napi_get_value_uint32(env, jsValue, &jsColor) != napi_ok) {
123             return false;
124         }
125     }
126     return true;
127 }
128 
ConvertFromJsRect(napi_env env,napi_value jsValue,double * ltrb,size_t size)129 bool ConvertFromJsRect(napi_env env, napi_value jsValue, double* ltrb, size_t size)
130 {
131     napi_value tempValue = nullptr;
132     for (size_t idx = 0; idx < size; idx++) {
133         double* curEdge = ltrb + idx;
134         napi_get_named_property(env, jsValue, g_ltrbString[idx], &tempValue);
135         if (napi_get_value_double(env, tempValue, curEdge) != napi_ok) {
136             return false;
137         }
138     }
139     return true;
140 }
141 
ConvertFromJsIRect(napi_env env,napi_value jsValue,int32_t * ltrb,size_t size)142 bool ConvertFromJsIRect(napi_env env, napi_value jsValue, int32_t* ltrb, size_t size)
143 {
144     napi_value tempValue = nullptr;
145     for (size_t idx = 0; idx < size; idx++) {
146         int32_t* curEdge = ltrb + idx;
147         napi_get_named_property(env, jsValue, g_ltrbString[idx], &tempValue);
148         if (napi_get_value_int32(env, tempValue, curEdge) != napi_ok) {
149             return false;
150         }
151     }
152     return true;
153 }
154 
ConvertFromJsShadowFlag(napi_env env,napi_value src,ShadowFlags & shadowFlag,ShadowFlags defaultFlag)155 bool ConvertFromJsShadowFlag(napi_env env, napi_value src, ShadowFlags& shadowFlag, ShadowFlags defaultFlag)
156 {
157     if (src == nullptr) {
158         return false;
159     }
160     uint32_t value = 0;
161     if (!ConvertFromJsValue(env, src, value)) {
162         return false;
163     }
164     shadowFlag = defaultFlag;
165     if (value >= static_cast<uint32_t>(ShadowFlags::NONE) && value <= static_cast<uint32_t>(ShadowFlags::ALL)) {
166         shadowFlag = static_cast<ShadowFlags>(value);
167     }
168     return true;
169 }
170 
ConvertFromJsPoint3d(napi_env env,napi_value src,Point3 & point3d)171 bool ConvertFromJsPoint3d(napi_env env, napi_value src, Point3& point3d)
172 {
173     if (src == nullptr) {
174         return false;
175     }
176     napi_value tempValue = nullptr;
177     double x = 0.0;
178     double y = 0.0;
179     double z = 0.0;
180     napi_get_named_property(env, src, "x", &tempValue);
181     bool isXOk = ConvertFromJsValue(env, tempValue, x);
182     napi_get_named_property(env, src, "y", &tempValue);
183     bool isYOk = ConvertFromJsValue(env, tempValue, y);
184     napi_get_named_property(env, src, "z", &tempValue);
185     bool isZOk = ConvertFromJsValue(env, tempValue, z);
186     if (!(isXOk && isYOk && isZOk)) {
187         return false;
188     }
189     point3d = Point3(x, y, z);
190     return true;
191 }
192 
ConvertFromJsPoint(napi_env env,napi_value jsValue,double * point,size_t size)193 bool ConvertFromJsPoint(napi_env env, napi_value jsValue, double* point, size_t size)
194 {
195     if (point == nullptr) {
196         return false;
197     }
198     napi_value tempValue = nullptr;
199     for (size_t idx = 0; idx < size; idx++) {
200         double* curEdge = point + idx;
201         napi_get_named_property(env, jsValue, g_pointString[idx], &tempValue);
202         if (napi_get_value_double(env, tempValue, curEdge) != napi_ok) {
203             return false;
204         }
205     }
206     return true;
207 }
208 
ConvertFromJsPointsArray(napi_env env,napi_value array,Drawing::Point * points,uint32_t count)209 bool ConvertFromJsPointsArray(napi_env env, napi_value array, Drawing::Point* points, uint32_t count)
210 {
211     if (points == nullptr) {
212         return false;
213     }
214     for (uint32_t i = 0; i < count; i++)  {
215         napi_value tempPoint = nullptr;
216         if (napi_get_element(env, array, i, &tempPoint) != napi_ok) {
217             return false;
218         }
219         if (!GetDrawingPointFromJsValue(env, tempPoint, points[i])) {
220             return false;
221         }
222     }
223     return true;
224 }
225 
ConvertFromJsPointsArrayOffset(napi_env env,napi_value array,Drawing::Point * points,uint32_t count,uint32_t offset)226 bool ConvertFromJsPointsArrayOffset(napi_env env, napi_value array, Drawing::Point* points,
227     uint32_t count, uint32_t offset)
228 {
229     if (points == nullptr) {
230         return false;
231     }
232     for (uint32_t i = offset; i < offset + count; i++)  {
233         napi_value tempPoint = nullptr;
234         if (napi_get_element(env, array, i, &tempPoint) != napi_ok) {
235             return false;
236         }
237         if (!GetDrawingPointFromJsValue(env, tempPoint, points[i - offset])) {
238             return false;
239         }
240     }
241     return true;
242 }
243 
GetFontMetricsAndConvertToJsValue(napi_env env,FontMetrics * metrics)244 napi_value GetFontMetricsAndConvertToJsValue(napi_env env, FontMetrics* metrics)
245 {
246     napi_value objValue = nullptr;
247     napi_create_object(env, &objValue);
248     if (metrics != nullptr && objValue != nullptr) {
249         napi_set_named_property(env, objValue, "top", CreateJsNumber(env, metrics->fTop));
250         napi_set_named_property(env, objValue, "ascent", CreateJsNumber(env, metrics->fAscent));
251         napi_set_named_property(env, objValue, "descent", CreateJsNumber(env, metrics->fDescent));
252         napi_set_named_property(env, objValue, "bottom", CreateJsNumber(env, metrics->fBottom));
253         napi_set_named_property(env, objValue, "leading", CreateJsNumber(env, metrics->fLeading));
254         napi_set_named_property(env, objValue, "flags", CreateJsNumber(env, metrics->fFlags));
255         napi_set_named_property(env, objValue, "avgCharWidth", CreateJsNumber(env, metrics->fAvgCharWidth));
256         napi_set_named_property(env, objValue, "maxCharWidth", CreateJsNumber(env, metrics->fMaxCharWidth));
257         napi_set_named_property(env, objValue, "xMin", CreateJsNumber(env, metrics->fXMin));
258         napi_set_named_property(env, objValue, "xMax", CreateJsNumber(env, metrics->fXMax));
259         napi_set_named_property(env, objValue, "xHeight", CreateJsNumber(env, metrics->fXHeight));
260         napi_set_named_property(env, objValue, "capHeight", CreateJsNumber(env, metrics->fCapHeight));
261         napi_set_named_property(env, objValue, "underlineThickness", CreateJsNumber(env,
262             metrics->fUnderlineThickness));
263         napi_set_named_property(env, objValue, "underlinePosition", CreateJsNumber(env,
264             metrics->fUnderlinePosition));
265         napi_set_named_property(env, objValue, "strikethroughThickness", CreateJsNumber(env,
266             metrics->fStrikeoutThickness));
267         napi_set_named_property(env, objValue, "strikethroughPosition", CreateJsNumber(env,
268             metrics->fStrikeoutPosition));
269     }
270     return objValue;
271 }
272 
GetThemeFont(std::shared_ptr<Font> font)273 std::shared_ptr<Font> GetThemeFont(std::shared_ptr<Font> font)
274 {
275     if (!font->IsThemeFontFollowed() || font->GetTypeface() != JsTypeface::GetZhCnTypeface()) {
276         return nullptr;
277     }
278     std::shared_ptr<FontCollection> fontCollection = FontCollection::Create();
279     if (fontCollection == nullptr) {
280         return nullptr;
281     }
282     std::shared_ptr<FontMgr> fontMgr = fontCollection->GetFontMgr();
283     if (fontMgr == nullptr) {
284         return nullptr;
285     }
286     std::shared_ptr<Typeface> themeTypeface =
287         std::shared_ptr<Typeface>(fontMgr->MatchFamilyStyle(THEME_FONT, FontStyle()));
288     if (themeTypeface == nullptr) {
289         return nullptr;
290     }
291     std::shared_ptr<Font> themeFont = std::make_shared<Font>(*font);
292     themeFont->SetTypeface(themeTypeface);
293     return themeFont;
294 }
295 } // namespace Drawing
296 } // namespace OHOS::Rosen
297