• 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_run.h"
17 #include "napi_common.h"
18 #include "utils/text_log.h"
19 #include "canvas_napi/js_canvas.h"
20 #include "font_napi/js_font.h"
21 #include "recording/recording_canvas.h"
22 
23 namespace OHOS::Rosen {
24 thread_local napi_ref JsRun::constructor_ = nullptr;
25 const std::string CLASS_NAME = "Run";
Constructor(napi_env env,napi_callback_info info)26 napi_value JsRun::Constructor(napi_env env, napi_callback_info info)
27 {
28     size_t argCount = 0;
29     napi_value jsThis = nullptr;
30     napi_status status = napi_get_cb_info(env, info, &argCount, nullptr, &jsThis, nullptr);
31     if (status != napi_ok) {
32         TEXT_LOGE("JsRun::Constructor failed to napi_get_cb_info");
33         return nullptr;
34     }
35 
36     JsRun* jsRun = new(std::nothrow) JsRun();
37     if (!jsRun) {
38         TEXT_LOGE("JsRun::Constructor failed to create JsRun");
39         return nullptr;
40     }
41 
42     status = napi_wrap(env, jsThis, jsRun,
43         JsRun::Destructor, nullptr, nullptr);
44     if (status != napi_ok) {
45         delete jsRun;
46         TEXT_LOGE("JsRun::Constructor Failed to wrap native instance");
47         return nullptr;
48     }
49 
50     return jsThis;
51 }
52 
Init(napi_env env,napi_value exportObj)53 napi_value JsRun::Init(napi_env env, napi_value exportObj)
54 {
55     napi_property_descriptor properties[] = {
56         DECLARE_NAPI_FUNCTION("getGlyphCount", JsRun::GetGlyphCount),
57         DECLARE_NAPI_FUNCTION("getGlyphs", JsRun::GetGlyphs),
58         DECLARE_NAPI_FUNCTION("getPositions", JsRun::GetPositions),
59         DECLARE_NAPI_FUNCTION("getOffsets", JsRun::GetOffsets),
60         DECLARE_NAPI_FUNCTION("getFont", JsRun::GetFont),
61         DECLARE_NAPI_FUNCTION("paint", JsRun::Paint),
62     };
63 
64     napi_value constructor = nullptr;
65     napi_status status = napi_define_class(env, CLASS_NAME.c_str(), NAPI_AUTO_LENGTH, Constructor, nullptr,
66         sizeof(properties) / sizeof(properties[0]), properties, &constructor);
67     if (status != napi_ok) {
68         TEXT_LOGE("JsRun::Init Failed to define JsRun class");
69         return nullptr;
70     }
71 
72     status = napi_create_reference(env, constructor, 1, &constructor_);
73     if (status != napi_ok) {
74         TEXT_LOGE("JsRun::Init Failed to create reference of constructor");
75         return nullptr;
76     }
77 
78     status = napi_set_named_property(env, exportObj, CLASS_NAME.c_str(), constructor);
79     if (status != napi_ok) {
80         TEXT_LOGE("JsRun::Init Failed to set constructor");
81         return nullptr;
82     }
83 
84     return exportObj;
85 }
86 
Destructor(napi_env env,void * nativeObject,void * finalize)87 void JsRun::Destructor(napi_env env, void* nativeObject, void* finalize)
88 {
89     (void)finalize;
90     if (nativeObject != nullptr) {
91         JsRun* jsRun = reinterpret_cast<JsRun*>(nativeObject);
92         delete jsRun;
93     }
94 }
95 
CreateRun(napi_env env,napi_callback_info info)96 napi_value JsRun::CreateRun(napi_env env, napi_callback_info info)
97 {
98     napi_value result = nullptr;
99     napi_value constructor = nullptr;
100     napi_status status = napi_get_reference_value(env, constructor_, &constructor);
101     if (status != napi_ok) {
102         TEXT_LOGE("Failed to get the representation of constructor object");
103         return nullptr;
104     }
105 
106     status = napi_new_instance(env, constructor, 0, nullptr, &result);
107     if (status != napi_ok) {
108         TEXT_LOGE("Failed to instantiate JavaScript font instance");
109         return nullptr;
110     }
111     return result;
112 }
113 
JsRun()114 JsRun::JsRun()
115 {
116 }
117 
SetRun(std::unique_ptr<Run> run)118 void JsRun::SetRun(std::unique_ptr<Run> run)
119 {
120     run_ = std::move(run);
121 }
122 
GetGlyphCount(napi_env env,napi_callback_info info)123 napi_value JsRun::GetGlyphCount(napi_env env, napi_callback_info info)
124 {
125     JsRun* me = CheckParamsAndGetThis<JsRun>(env, info);
126     return (me != nullptr) ? me->OnGetGlyphCount(env, info) : nullptr;
127 }
128 
OnGetGlyphCount(napi_env env,napi_callback_info info)129 napi_value JsRun::OnGetGlyphCount(napi_env env, napi_callback_info info)
130 {
131     if (!run_) {
132         TEXT_LOGE("JsRun::OnGetGlyphCount run is nullptr");
133         return NapiThrowError(env, TextErrorCode::ERROR_INVALID_PARAM, "JsRun::OnGetGlyphCount run is nullptr.");
134     }
135     int64_t count = static_cast<int64_t>(run_->GetGlyphCount());
136     return CreateJsNumber(env, count);
137 }
138 
GetGlyphs(napi_env env,napi_callback_info info)139 napi_value JsRun::GetGlyphs(napi_env env, napi_callback_info info)
140 {
141     JsRun* me = CheckParamsAndGetThis<JsRun>(env, info);
142     return (me != nullptr) ? me->OnGetGlyphs(env, info) : nullptr;
143 }
144 
OnGetGlyphs(napi_env env,napi_callback_info info)145 napi_value JsRun::OnGetGlyphs(napi_env env, napi_callback_info info)
146 {
147     if (!run_) {
148         TEXT_LOGE("Failed run is nullptr");
149         return NapiThrowError(env, TextErrorCode::ERROR_INVALID_PARAM, "Failed run is nullptr");
150     }
151 
152     std::vector<uint16_t> glyphs = run_->GetGlyphs();
153     napi_value napiGlyphs = nullptr;
154     NAPI_CALL(env, napi_create_array(env, &napiGlyphs));
155     size_t glyphSize = glyphs.size();
156     for (size_t index = 0; index < glyphSize; ++index) {
157         NAPI_CALL(env, napi_set_element(env, napiGlyphs, index,
158             CreateJsNumber(env, static_cast<uint32_t>(glyphs.at(index)))));
159     }
160     return napiGlyphs;
161 }
162 
GetPositions(napi_env env,napi_callback_info info)163 napi_value JsRun::GetPositions(napi_env env, napi_callback_info info)
164 {
165     JsRun* me = CheckParamsAndGetThis<JsRun>(env, info);
166     return (me != nullptr) ? me->OnGetPositions(env, info) : nullptr;
167 }
168 
OnGetPositions(napi_env env,napi_callback_info info)169 napi_value JsRun::OnGetPositions(napi_env env, napi_callback_info info)
170 {
171     if (!run_) {
172         TEXT_LOGE("Failed run is nullptr");
173         return NapiThrowError(env, TextErrorCode::ERROR_INVALID_PARAM, "Failed run is nullptr.");
174     }
175 
176     std::vector<Drawing::Point> positions = run_->GetPositions();
177     napi_value napiPositions = nullptr;
178     NAPI_CALL(env, napi_create_array(env, &napiPositions));
179     size_t positionSize = positions.size();
180     for (size_t index = 0; index < positionSize; ++index) {
181         NAPI_CALL(env, napi_set_element(env, napiPositions, index,
182             GetPointAndConvertToJsValue(env, positions.at(index))));
183     }
184     return napiPositions;
185 }
186 
GetOffsets(napi_env env,napi_callback_info info)187 napi_value JsRun::GetOffsets(napi_env env, napi_callback_info info)
188 {
189     JsRun* me = CheckParamsAndGetThis<JsRun>(env, info);
190     return (me != nullptr) ? me->OnGetOffsets(env, info) : nullptr;
191 }
192 
OnGetOffsets(napi_env env,napi_callback_info info)193 napi_value JsRun::OnGetOffsets(napi_env env, napi_callback_info info)
194 {
195     if (!run_) {
196         TEXT_LOGE("JsRun::OnGetOffsets run is nullptr");
197         return NapiThrowError(env, TextErrorCode::ERROR_INVALID_PARAM, "JsRun::OnGetOffsets run is nullptr.");
198     }
199 
200     std::vector<Drawing::Point> offsets = run_->GetOffsets();
201     napi_value napiOffsets = nullptr;
202     NAPI_CALL(env, napi_create_array(env, &napiOffsets));
203     size_t offsetSize = offsets.size();
204     for (size_t index = 0; index < offsetSize; ++index) {
205         NAPI_CALL(env, napi_set_element(env, napiOffsets, index,
206             GetPointAndConvertToJsValue(env, offsets.at(index))));
207     }
208     return napiOffsets;
209 }
210 
GetFont(napi_env env,napi_callback_info info)211 napi_value JsRun::GetFont(napi_env env, napi_callback_info info)
212 {
213     JsRun* me = CheckParamsAndGetThis<JsRun>(env, info);
214     return (me != nullptr) ? me->OnGetFont(env, info) : nullptr;
215 }
216 
OnGetFont(napi_env env,napi_callback_info info)217 napi_value JsRun::OnGetFont(napi_env env, napi_callback_info info)
218 {
219     if (!run_) {
220         TEXT_LOGE("JsRun::OnGetFont run is nullptr");
221         return NapiThrowError(env, TextErrorCode::ERROR_INVALID_PARAM, "JsRun::OnGetFont run is nullptr.");
222     }
223 
224     std::shared_ptr<Drawing::Font> fontPtr = std::make_shared<Drawing::Font>(run_->GetFont());
225     if (!fontPtr) {
226         TEXT_LOGE("JsRun::OnGetFont fontPtr is nullptr");
227         return NapiThrowError(env, TextErrorCode::ERROR_INVALID_PARAM, "JsRun::OnGetFont fontPtr is nullptr.");
228     }
229 
230     napi_value resultValue  = Drawing::JsFont::CreateFont(env, info);
231     if (!resultValue) {
232         TEXT_LOGE("JsRun::OnGetFont JsFont::CreateFont resultValue is null");
233         return nullptr;
234     }
235     Drawing::JsFont* jsFont = nullptr;
236     napi_unwrap(env, resultValue, reinterpret_cast<void**>(&jsFont));
237     if (!jsFont) {
238         TEXT_LOGE("JsRun::OnGetFont napi_unwrap jsFont is null");
239         return nullptr;
240     }
241     jsFont->SetFont(fontPtr);
242     return resultValue;
243 }
244 
Paint(napi_env env,napi_callback_info info)245 napi_value JsRun::Paint(napi_env env, napi_callback_info info)
246 {
247     JsRun* me = CheckParamsAndGetThis<JsRun>(env, info);
248     return (me != nullptr) ? me->OnPaint(env, info) : nullptr;
249 }
250 
OnPaint(napi_env env,napi_callback_info info)251 napi_value JsRun::OnPaint(napi_env env, napi_callback_info info)
252 {
253     if (run_ == nullptr) {
254         TEXT_LOGE("JsRun::OnPaint run is nullptr");
255         return NapiThrowError(env, TextErrorCode::ERROR_INVALID_PARAM, "JsRun::OnPaint run is nullptr.");
256     }
257     size_t argc = ARGC_THREE;
258     napi_value argv[ARGC_THREE] = {nullptr};
259     napi_status status = napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
260     if (status != napi_ok || argc < ARGC_THREE) {
261         TEXT_LOGE("JsRun::OnPaint Argc is invalid: %{public}zu", argc);
262         return NapiThrowError(env, TextErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
263     }
264     if (argv[0] == nullptr) {
265         TEXT_LOGE("JsRun::OnPaint argv[0] is invalid");
266         return NapiGetUndefined(env);
267     }
268     Drawing::JsCanvas* jsCanvas = nullptr;
269     double x = 0.0;
270     double y = 0.0;
271     napi_unwrap(env, argv[0], reinterpret_cast<void **>(&jsCanvas));
272     if (!jsCanvas || !jsCanvas->GetCanvas() ||
273         !(argv[ARGC_ONE] != nullptr && ConvertFromJsValue(env, argv[ARGC_ONE], x) &&
274         argv[ARGC_TWO] != nullptr && ConvertFromJsValue(env, argv[ARGC_TWO], y))) {
275         TEXT_LOGE("JsRun::OnPaint Argv is invalid");
276         return NapiGetUndefined(env);
277     }
278     run_->Paint(jsCanvas->GetCanvas(), x, y);
279 
280     return NapiGetUndefined(env);
281 }
282 
SetParagraph(std::shared_ptr<Typography> paragraph)283 void JsRun::SetParagraph(std::shared_ptr<Typography> paragraph)
284 {
285     paragraph_ = paragraph;
286 }
287 } // namespace OHOS::Rosen
288