• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 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_drawable_descriptor.h"
17 
18 #include "drawable_descriptor.h"
19 #include "interfaces/inner_api/drawable_descriptor/drawable_descriptor.h"
20 #include "js_native_api.h"
21 #include "js_native_api_types.h"
22 #include "napi/native_api.h"
23 #include "napi/native_common.h"
24 #include "napi/native_node_api.h"
25 #ifndef PREVIEW
26 #include "pixel_map_napi.h"
27 #endif
28 #include "base/utils/utils.h"
29 
30 namespace {
31 constexpr char DRAWABLE_BASE[] = "DrawableDescriptor";
32 constexpr char DRAWABLE_LAYERED[] = "LayeredDrawableDescriptor";
33 } // namespace
34 
35 namespace OHOS::Ace::Napi {
36 thread_local napi_ref JsDrawableDescriptor::baseConstructor_;
37 thread_local napi_ref JsDrawableDescriptor::layeredConstructor_;
38 
Constructor(napi_env env,napi_callback_info info)39 napi_value JsDrawableDescriptor::Constructor(napi_env env, napi_callback_info info)
40 {
41     napi_escapable_handle_scope scope = nullptr;
42     napi_open_escapable_handle_scope(env, &scope);
43     napi_value thisVar = nullptr;
44     NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr));
45     // create JsDrawable
46     auto* drawable = new DrawableDescriptor;
47     // wrap to napi_value
48     napi_wrap(env, thisVar, drawable, Destructor, nullptr, nullptr);
49     napi_escape_handle(env, scope, thisVar, &thisVar);
50     napi_close_escapable_handle_scope(env, scope);
51     return thisVar;
52 }
53 
Destructor(napi_env,void * data,void *)54 void JsDrawableDescriptor::Destructor(napi_env /* env */, void* data, void* /* hint */)
55 {
56     auto* field = reinterpret_cast<DrawableDescriptor*>(data);
57     delete field;
58 }
59 
InitDrawable(napi_env env)60 napi_value JsDrawableDescriptor::InitDrawable(napi_env env)
61 {
62     napi_value cons = nullptr;
63     napi_property_descriptor baseDes[] = {
64         DECLARE_NAPI_FUNCTION("getPixelMap", GetPixelMap),
65     };
66     NAPI_CALL(env, napi_define_class(env, DRAWABLE_BASE, NAPI_AUTO_LENGTH, Constructor, nullptr,
67                        sizeof(baseDes) / sizeof(napi_property_descriptor), baseDes, &cons));
68     NAPI_CALL(env, napi_create_reference(env, cons, 1, &baseConstructor_));
69     return cons;
70 }
71 
InitLayeredDrawable(napi_env env)72 napi_value JsDrawableDescriptor::InitLayeredDrawable(napi_env env)
73 {
74     napi_value cons = nullptr;
75     napi_property_descriptor layeredDes[] = {
76         DECLARE_NAPI_FUNCTION("getPixelMap", GetPixelMap),
77         DECLARE_NAPI_FUNCTION("getForeground", GetForeground),
78         DECLARE_NAPI_FUNCTION("getBackground", GetBackground),
79         DECLARE_NAPI_FUNCTION("getMask", GetMask),
80         DECLARE_NAPI_STATIC_FUNCTION("getMaskClipPath", GetMaskClipPath),
81     };
82     NAPI_CALL(env, napi_define_class(env, DRAWABLE_LAYERED, NAPI_AUTO_LENGTH, Constructor, nullptr,
83                        sizeof(layeredDes) / sizeof(napi_property_descriptor), layeredDes, &cons));
84     NAPI_CALL(env, napi_create_reference(env, cons, 1, &layeredConstructor_));
85     return cons;
86 }
87 
ToNapi(napi_env env,DrawableDescriptor * drawable,DrawableDescriptor::DrawableType type)88 napi_value JsDrawableDescriptor::ToNapi(
89     napi_env env, DrawableDescriptor* drawable, DrawableDescriptor::DrawableType type)
90 {
91     if (!drawable) {
92         return nullptr;
93     }
94     if (!baseConstructor_ || !layeredConstructor_) {
95         // init js class constructor by importing module manually
96         napi_value globalValue;
97         napi_get_global(env, &globalValue);
98         napi_value func;
99         napi_get_named_property(env, globalValue, "requireNapi", &func);
100 
101         napi_value module;
102         napi_create_string_utf8(env, MODULE_NAME, NAPI_AUTO_LENGTH, &module);
103         napi_value returnValue;
104         napi_call_function(env, globalValue, func, 1, &module, &returnValue);
105     }
106 
107     napi_value constructor = nullptr;
108     napi_value result = nullptr;
109     napi_status status;
110     switch (type) {
111         case DrawableDescriptor::DrawableType::LAYERED:
112             status = napi_get_reference_value(env, layeredConstructor_, &constructor);
113             break;
114         case DrawableDescriptor::DrawableType::BASE:
115             status = napi_get_reference_value(env, baseConstructor_, &constructor);
116             break;
117         default:
118             status = napi_status::napi_invalid_arg;
119             break;
120     }
121     if (status == napi_status::napi_ok) {
122         NAPI_CALL(env, napi_new_instance(env, constructor, 0, nullptr, &result));
123         NAPI_CALL(env, napi_wrap(env, result, drawable, Destructor, nullptr, nullptr));
124     } else {
125         HILOG_INFO("create reference failed, drawable constructor is null");
126     }
127 
128     return result;
129 }
130 
GetPixelMap(napi_env env,napi_callback_info info)131 napi_value JsDrawableDescriptor::GetPixelMap(napi_env env, napi_callback_info info)
132 {
133     napi_escapable_handle_scope scope = nullptr;
134     napi_open_escapable_handle_scope(env, &scope);
135     napi_value thisVar = nullptr;
136     NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr));
137     void* native = nullptr;
138     napi_unwrap(env, thisVar, &native);
139     auto* drawable = reinterpret_cast<DrawableDescriptor*>(native);
140     auto pixmap = drawable->GetPixelMap();
141 
142     napi_value result = Media::PixelMapNapi::CreatePixelMap(env, pixmap);
143     napi_escape_handle(env, scope, result, &result);
144     napi_close_escapable_handle_scope(env, scope);
145     return result;
146 }
147 
GetForeground(napi_env env,napi_callback_info info)148 napi_value JsDrawableDescriptor::GetForeground(napi_env env, napi_callback_info info)
149 {
150     napi_escapable_handle_scope scope = nullptr;
151     napi_open_escapable_handle_scope(env, &scope);
152     napi_value thisVar = nullptr;
153     NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr));
154     void* native = nullptr;
155     napi_unwrap(env, thisVar, &native);
156     auto* drawable = reinterpret_cast<LayeredDrawableDescriptor*>(native);
157     if (!drawable) {
158         return nullptr;
159     }
160 
161     auto foreground = drawable->GetForeground();
162     napi_value result = ToNapi(env, foreground.release(), DrawableDescriptor::DrawableType::BASE);
163     napi_escape_handle(env, scope, result, &result);
164     napi_close_escapable_handle_scope(env, scope);
165     return result;
166 }
167 
GetBackground(napi_env env,napi_callback_info info)168 napi_value JsDrawableDescriptor::GetBackground(napi_env env, napi_callback_info info)
169 {
170     napi_escapable_handle_scope scope = nullptr;
171     napi_open_escapable_handle_scope(env, &scope);
172     napi_value thisVar = nullptr;
173     NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr));
174     void* native = nullptr;
175     napi_unwrap(env, thisVar, &native);
176     auto* drawable = reinterpret_cast<LayeredDrawableDescriptor*>(native);
177     if (!drawable) {
178         return nullptr;
179     }
180 
181     auto background = drawable->GetBackground();
182     napi_value result = ToNapi(env, background.release(), DrawableDescriptor::DrawableType::BASE);
183     napi_escape_handle(env, scope, result, &result);
184     napi_close_escapable_handle_scope(env, scope);
185     return result;
186 }
187 
GetMask(napi_env env,napi_callback_info info)188 napi_value JsDrawableDescriptor::GetMask(napi_env env, napi_callback_info info)
189 {
190     napi_escapable_handle_scope scope = nullptr;
191     napi_open_escapable_handle_scope(env, &scope);
192     napi_value thisVar = nullptr;
193     NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr));
194     void* native = nullptr;
195     napi_unwrap(env, thisVar, &native);
196     auto* drawable = reinterpret_cast<LayeredDrawableDescriptor*>(native);
197     if (!drawable) {
198         return nullptr;
199     }
200 
201     auto mask = drawable->GetMask();
202     napi_value result = ToNapi(env, mask.release(), DrawableDescriptor::DrawableType::BASE);
203     napi_escape_handle(env, scope, result, &result);
204     napi_close_escapable_handle_scope(env, scope);
205     return result;
206 }
207 
GetMaskClipPath(napi_env env,napi_callback_info info)208 napi_value JsDrawableDescriptor::GetMaskClipPath(napi_env env, napi_callback_info info)
209 {
210     auto path = OHOS::Ace::Napi::LayeredDrawableDescriptor::GetStaticMaskClipPath();
211     napi_value result = nullptr;
212     if (napi_ok != napi_create_string_utf8(env, path.c_str(), NAPI_AUTO_LENGTH, &result)) {
213         HILOG_INFO("JsDrawableDescriptor Failed");
214     }
215     return result;
216 }
217 
Export(napi_env env,napi_value exports)218 napi_value JsDrawableDescriptor::Export(napi_env env, napi_value exports)
219 {
220     // export base class
221     napi_value cons = InitDrawable(env);
222     NAPI_CALL(env, napi_set_named_property(env, exports, DRAWABLE_BASE, cons));
223 
224     // export child class
225     cons = InitLayeredDrawable(env);
226     NAPI_CALL(env, napi_set_named_property(env, exports, DRAWABLE_LAYERED, cons));
227     return exports;
228 }
229 } // namespace OHOS::Ace::Napi
230