• 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 "ParamParsing.h"
20 #include "RenderContextJS.h"
21 #include "SceneJS.h"
22 
23 using namespace SCENE_NS;
24 
Init(napi_env env,napi_value exports)25 void ImageJS::Init(napi_env env, napi_value exports)
26 {
27     using namespace NapiApi;
28     // clang-format off
29     BASE_NS::vector<napi_property_descriptor> props;
30     SceneResourceImpl::GetPropertyDescs(props);
31     props.emplace_back(GetProperty<uint32_t, ImageJS, &ImageJS::GetWidth>("width"));
32     props.emplace_back(GetProperty<uint32_t, ImageJS, &ImageJS::GetHeight>("height"));
33 
34     // clang-format on
35 
36     napi_value func;
37     auto status = napi_define_class(
38         env, "Image", NAPI_AUTO_LENGTH, BaseObject::ctor<ImageJS>(), nullptr, props.size(), props.data(), &func);
39 
40     NapiApi::MyInstanceState *mis;
41     NapiApi::MyInstanceState::GetInstance(env, (void **)&mis);
42     if (mis) {
43         mis->StoreCtor("Image", func);
44     }
45 }
46 
DisposeNative(void * sc)47 void ImageJS::DisposeNative(void *sc)
48 {
49     if (!disposed_) {
50         disposed_ = true;
51         LOG_V("ImageJS::DisposeNative");
52 
53         if (sc && resources_) {
54             resources_->ReleaseDispose(reinterpret_cast<uintptr_t>(&scene_));
55 
56             if (BASE_NS::string uri = ExtractUri(uri_.GetObject()); !uri.empty()) {
57                 ExecSyncTask([uri, resources = resources_]() -> META_NS::IAny::Ptr {
58                     if (resources) {
59                         resources->StoreBitmap(uri, nullptr);
60                     }
61                     return {};
62                 });
63             }
64         }
65 
66         UnsetNativeObject();
67         scene_.Reset();
68         resources_.reset();
69     }
70 }
GetInstanceImpl(uint32_t id)71 void *ImageJS::GetInstanceImpl(uint32_t id)
72 {
73     if (id == ImageJS::ID)
74         return this;
75     return SceneResourceImpl::GetInstanceImpl(id);
76 }
Finalize(napi_env env)77 void ImageJS::Finalize(napi_env env)
78 {
79     DisposeNative(scene_.GetObject().GetJsWrapper<SceneJS>());
80     BaseObject::Finalize(env);
81 }
82 
ImageJS(napi_env e,napi_callback_info i)83 ImageJS::ImageJS(napi_env e, napi_callback_info i) : BaseObject(e, i), SceneResourceImpl(SceneResourceType::IMAGE)
84 {
85     NapiApi::FunctionContext<NapiApi::Object, NapiApi::Object> fromJs(e, i);
86     NapiApi::Object meJs(fromJs.This());
87     NapiApi::Object renderContext = fromJs.Arg<0>(); // access to owning context...
88     scene_ = { renderContext };
89     if (!scene_.GetObject().GetJsWrapper<RenderContextJS>()) {
90         LOG_F("Invalid render context for ImageJS");
91     }
92 
93     if (const auto renderContextJs = renderContext.GetJsWrapper<RenderContextJS>()) {
94         resources_ = renderContextJs->GetResources();
95         if (resources_) {
96             resources_->DisposeHook(reinterpret_cast<uintptr_t>(&scene_), meJs);
97         }
98     }
99 
100     if (!GetNativeObject<SCENE_NS::IBitmap>()) {
101         LOG_E("Cannot finish creating an image: Native image object missing");
102         assert(false);
103         return;
104     }
105 
106     NapiApi::Object args = fromJs.Arg<1>();
107     if (auto prm = args.Get("uri")) {
108         NapiApi::Object resType = args.Get<NapiApi::Object>("uri");
109         BASE_NS::string uriType = args.Get<BASE_NS::string>("uri");
110         BASE_NS::string uri = ExtractUri(uriType);
111         if (uri.empty()) {
112             uri = ExtractUri(resType);
113         }
114         if (!uri.empty()) {
115             if (!resType) {
116                 // raw string then.. make it  "resource" / "rawfile" if possible.
117                 if (uri.find("OhosRawFile://") == 0) {
118                     // we can only convert "OhosRawFile://" type uris back to "resource" objects.
119                     NapiApi::Env env(e);
120                     napi_value global;
121                     napi_get_global(env, &global);
122                     NapiApi::Object g(env, global);
123                     napi_value func = g.Get("$rawfile");
124                     NapiApi::Function f(env, func);
125                     if (f) {
126                         BASE_NS::string noschema(uri.substr(14)); // 14: length
127                         napi_value arg = env.GetString(noschema);
128                         napi_value res = f.Invoke(g, 1, &arg);
129                         SetUri(NapiApi::StrongRef(env, res));
130                     }
131                 }
132             } else {
133                 SetUri(NapiApi::StrongRef(resType));
134             }
135         }
136     }
137 
138     if (const auto name = ExtractName(args); !name.empty()) {
139         meJs.Set("name", name);
140     }
141 }
142 
~ImageJS()143 ImageJS::~ImageJS()
144 {
145     DisposeNative(nullptr);
146 }
147 
GetWidth(NapiApi::FunctionContext<> & ctx)148 napi_value ImageJS::GetWidth(NapiApi::FunctionContext<> &ctx)
149 {
150     if (!validateSceneRef()) {
151         return ctx.GetUndefined();
152     }
153     uint32_t width = 0;
154     if (auto env = interface_cast<IBitmap>(GetNativeObject())) {
155         width = env->Size()->GetValue().x;
156     }
157     return ctx.GetNumber(width);
158 }
159 
GetHeight(NapiApi::FunctionContext<> & ctx)160 napi_value ImageJS::GetHeight(NapiApi::FunctionContext<> &ctx)
161 {
162     if (!validateSceneRef()) {
163         return ctx.GetUndefined();
164     }
165     uint32_t height = 0;
166     if (auto env = interface_cast<IBitmap>(GetNativeObject())) {
167         height = env->Size()->GetValue().y;
168     }
169     return ctx.GetNumber(height);
170 }
171