• 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 #include "ImageJS.h"
16 
17 #include <scene/interface/intf_scene.h>
18 
19 #include "SceneJS.h"
20 
21 using namespace SCENE_NS;
22 
Init(napi_env env,napi_value exports)23 void ImageJS::Init(napi_env env, napi_value exports)
24 {
25     using namespace NapiApi;
26     // clang-format off
27     BASE_NS::vector<napi_property_descriptor> props;
28     SceneResourceImpl::GetPropertyDescs(props);
29     props.emplace_back(GetProperty<uint32_t, ImageJS, &ImageJS::GetWidth>("width"));
30     props.emplace_back(GetProperty<uint32_t, ImageJS, &ImageJS::GetHeight>("height"));
31 
32     // clang-format on
33 
34     napi_value func;
35     auto status = napi_define_class(
36         env, "Image", NAPI_AUTO_LENGTH, BaseObject::ctor<ImageJS>(), nullptr, props.size(), props.data(), &func);
37 
38     NapiApi::MyInstanceState* mis;
39     GetInstanceData(env, (void**)&mis);
40     mis->StoreCtor("Image", func);
41 }
42 
DisposeNative(void * sc)43 void ImageJS::DisposeNative(void* sc)
44 {
45     if (!disposed_) {
46         disposed_ = true;
47         LOG_V("ImageJS::DisposeNative");
48         NapiApi::Object obj = scene_.GetObject();
49         SceneJS* sceneJS = nullptr;
50         if (sc) {
51             sceneJS = static_cast<SceneJS*>(sc);
52         } else {
53             auto* tro = obj.Native<TrueRootObject>();
54             if (tro) {
55                 sceneJS = static_cast<SceneJS*>(tro->GetInstanceImpl(SceneJS::ID));
56             }
57         }
58         if (sc) {
59             sceneJS->ReleaseDispose(reinterpret_cast<uintptr_t>(&scene_));
60         }
61         // reset the native object refs
62         if (auto bitmap = interface_pointer_cast<IBitmap>(GetNativeObject())) {
63             SetNativeObject(nullptr, false);
64             SetNativeObject(nullptr, true);
65             if (obj) {
66                 BASE_NS::string uri =
67                     FetchResourceOrUri(uri_.GetEnv(), uri_.GetObject().ToNapiValue());
68                 ExecSyncTask([uri, sceneJS]() -> META_NS::IAny::Ptr {
69                     if (sceneJS) {
70                         sceneJS->StoreBitmap(uri, nullptr);
71                     }
72                     return {};
73                 });
74             }
75         } else {
76             SetNativeObject(nullptr, false);
77         }
78         scene_.Reset();
79     }
80 }
GetInstanceImpl(uint32_t id)81 void* ImageJS::GetInstanceImpl(uint32_t id)
82 {
83     if (id == ImageJS::ID)
84         return this;
85     return SceneResourceImpl::GetInstanceImpl(id);
86 }
Finalize(napi_env env)87 void ImageJS::Finalize(napi_env env)
88 {
89     DisposeNative(nullptr);
90     BaseObject<ImageJS>::Finalize(env);
91 }
92 
ImageJS(napi_env e,napi_callback_info i)93 ImageJS::ImageJS(napi_env e, napi_callback_info i)
94     : BaseObject<ImageJS>(e, i), SceneResourceImpl(SceneResourceType::IMAGE)
95 {
96     NapiApi::FunctionContext<NapiApi::Object, NapiApi::Object> fromJs(e, i);
97     NapiApi::Object meJs(fromJs.This());
98     NapiApi::Object scene = fromJs.Arg<0>(); // access to owning scene...
99     scene_ = { scene };
100     if (!GetNativeMeta<SCENE_NS::IScene>(scene_.GetObject())) {
101         LOG_F("INVALID SCENE!");
102     }
103 
104     SceneJS* sceneJS = nullptr;
105     auto* tro = scene.Native<TrueRootObject>();
106     if (tro) {
107         sceneJS = static_cast<SceneJS*>(tro->GetInstanceImpl(SceneJS::ID));
108     }
109     NapiApi::Object args = fromJs.Arg<1>();
110 
111     SCENE_NS::IBitmap::Ptr bitmap;
112 
113     // check if we got the NativeObject as parameter.
114     bitmap = GetNativeObjectParam<SCENE_NS::IBitmap>(args);
115 
116     if (auto prm = args.Get("uri")) {
117         NapiApi::Object resType = args.Get<NapiApi::Object>("uri");
118         BASE_NS::string uriType = args.Get<BASE_NS::string>("uri");
119 
120         BASE_NS::string uri = FetchResourceOrUri(args.GetEnv(), prm);
121         if (!uri.empty()) {
122             if (!resType) {
123                 // raw string then.. make it  "resource" / "rawfile" if possible.
124                 if (uri.find("OhosRawFile://") == 0) {
125                     // we can only convert "OhosRawFile://" type uris back to "resource" objects.
126                     NapiApi::Env env(e);
127                     napi_value global;
128                     napi_get_global(env, &global);
129                     NapiApi::Object g(env, global);
130                     napi_value func = g.Get("$rawfile");
131                     NapiApi::Function f(env, func);
132                     if (f) {
133                         BASE_NS::string noschema(uri.substr(14)); // 14: length
134                         napi_value arg = env.GetString(noschema);
135                         napi_value res = f.Invoke(g, 1, &arg);
136                         SetUri(NapiApi::StrongRef(env, res));
137                     }
138                 }
139             } else {
140                 SetUri(NapiApi::StrongRef(resType));
141             }
142         }
143         if (!bitmap) {
144             // if we did not receive it already...
145             if (sceneJS) {
146                 bitmap = sceneJS->FetchBitmap(uri);
147             }
148         }
149     }
150     if (sceneJS) {
151         sceneJS->DisposeHook(reinterpret_cast<uintptr_t>(&scene_), meJs);
152     }
153     auto obj = interface_pointer_cast<META_NS::IObject>(bitmap);
154     SetNativeObject(obj, false);
155     StoreJsObj(obj, meJs);
156 
157     BASE_NS::string name;
158     if (auto prm = args.Get<BASE_NS::string>("name"); prm.IsDefined()) {
159         name = prm;
160     } else {
161         if (auto named = interface_cast<META_NS::IObject>(obj)) {
162             name = named->GetName();
163         }
164     }
165     meJs.Set("name", name);
166 }
167 
~ImageJS()168 ImageJS::~ImageJS()
169 {
170     DisposeNative(nullptr);
171 }
172 
GetWidth(NapiApi::FunctionContext<> & ctx)173 napi_value ImageJS::GetWidth(NapiApi::FunctionContext<>& ctx)
174 {
175     if (!validateSceneRef()) {
176         return ctx.GetUndefined();
177     }
178     uint32_t width = 0;
179     if (auto env = interface_cast<IBitmap>(GetNativeObject())) {
180         width = env->Size()->GetValue().x;
181     }
182     return ctx.GetNumber(width);
183 }
184 
GetHeight(NapiApi::FunctionContext<> & ctx)185 napi_value ImageJS::GetHeight(NapiApi::FunctionContext<>& ctx)
186 {
187     if (!validateSceneRef()) {
188         return ctx.GetUndefined();
189     }
190     uint32_t height = 0;
191     if (auto env = interface_cast<IBitmap>(GetNativeObject())) {
192         height = env->Size()->GetValue().y;
193     }
194     return ctx.GetNumber(height);
195 }
196