• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 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 "frameworks/bridge/declarative_frontend/jsview/js_image.h"
17 
18 #if !defined(WINDOWS_PLATFORM) and !defined(MAC_PLATFORM)
19 #include <dlfcn.h>
20 #endif
21 
22 #include "base/image/pixel_map.h"
23 #include "base/log/ace_trace.h"
24 #include "frameworks/bridge/declarative_frontend/engine/js_ref_ptr.h"
25 #include "frameworks/bridge/declarative_frontend/view_stack_processor.h"
26 
27 namespace OHOS::Ace::Framework {
28 
LoadImageSuccEventToJSValue(const LoadImageSuccessEvent & eventInfo)29 JSRef<JSVal> LoadImageSuccEventToJSValue(const LoadImageSuccessEvent& eventInfo)
30 {
31     JSRef<JSObject> obj = JSRef<JSObject>::New();
32     obj->SetProperty("width", eventInfo.GetWidth());
33     obj->SetProperty("height", eventInfo.GetHeight());
34     obj->SetProperty("componentWidth", eventInfo.GetComponentWidth());
35     obj->SetProperty("componentHeight", eventInfo.GetComponentHeight());
36     obj->SetProperty("loadingStatus", eventInfo.GetLoadingStatus());
37     return JSRef<JSVal>::Cast(obj);
38 }
39 
LoadImageFailEventToJSValue(const LoadImageFailEvent & eventInfo)40 JSRef<JSVal> LoadImageFailEventToJSValue(const LoadImageFailEvent& eventInfo)
41 {
42     JSRef<JSObject> obj = JSRef<JSObject>::New();
43     obj->SetProperty("componentWidth", eventInfo.GetComponentWidth());
44     obj->SetProperty("componentHeight", eventInfo.GetComponentHeight());
45     return JSRef<JSVal>::Cast(obj);
46 }
47 
SetAlt(const JSCallbackInfo & args)48 void JSImage::SetAlt(const JSCallbackInfo& args)
49 {
50     if (args.Length() < 1) {
51         LOGE("The argv is wrong, it it supposed to have at least 1 argument");
52         return;
53     }
54 
55     std::string src;
56     if (!ParseJsMedia(args[0], src)) {
57         return;
58     }
59 
60     auto image = AceType::DynamicCast<ImageComponent>(ViewStackProcessor::GetInstance()->GetMainComponent());
61     if (image) {
62         image->SetAlt(src);
63     }
64 }
65 
SetObjectFit(int32_t value)66 void JSImage::SetObjectFit(int32_t value)
67 {
68     auto image = AceType::DynamicCast<ImageComponent>(ViewStackProcessor::GetInstance()->GetMainComponent());
69     if (image) {
70         image->SetImageFit(static_cast<ImageFit>(value));
71     }
72 }
73 
SetMatchTextDirection(bool value)74 void JSImage::SetMatchTextDirection(bool value)
75 {
76     auto image = AceType::DynamicCast<ImageComponent>(ViewStackProcessor::GetInstance()->GetMainComponent());
77     if (image) {
78         image->SetMatchTextDirection(value);
79     }
80 }
81 
SetFitOriginalSize(bool value)82 void JSImage::SetFitOriginalSize(bool value)
83 {
84     auto image = AceType::DynamicCast<ImageComponent>(ViewStackProcessor::GetInstance()->GetMainComponent());
85     if (image) {
86         image->SetFitMaxSize(!value);
87     }
88 }
89 
GetFrontDecoration()90 RefPtr<Decoration> JSImage::GetFrontDecoration()
91 {
92     auto box = ViewStackProcessor::GetInstance()->GetBoxComponent();
93     auto decoration = box->GetFrontDecoration();
94     if (!decoration) {
95         decoration = AceType::MakeRefPtr<Decoration>();
96         box->SetFrontDecoration(decoration);
97     }
98 
99     return decoration;
100 }
101 
GetBorder()102 const Border& JSImage::GetBorder()
103 {
104     return GetFrontDecoration()->GetBorder();
105 }
106 
GetLeftBorderEdge()107 BorderEdge JSImage::GetLeftBorderEdge()
108 {
109     return GetBorder().Left();
110 }
111 
GetTopBorderEdge()112 BorderEdge JSImage::GetTopBorderEdge()
113 {
114     return GetBorder().Top();
115 }
116 
GetRightBorderEdge()117 BorderEdge JSImage::GetRightBorderEdge()
118 {
119     return GetBorder().Right();
120 }
121 
GetBottomBorderEdge()122 BorderEdge JSImage::GetBottomBorderEdge()
123 {
124     return GetBorder().Bottom();
125 }
126 
SetBorderEdge(const BorderEdge & edge)127 void JSImage::SetBorderEdge(const BorderEdge& edge)
128 {
129     Border border = GetBorder();
130     border.SetBorderEdge(edge);
131     SetBorder(border);
132 }
133 
SetLeftBorderEdge(const BorderEdge & edge)134 void JSImage::SetLeftBorderEdge(const BorderEdge& edge)
135 {
136     Border border = GetBorder();
137     border.SetLeftEdge(edge);
138     SetBorder(border);
139 }
140 
SetTopBorderEdge(const BorderEdge & edge)141 void JSImage::SetTopBorderEdge(const BorderEdge& edge)
142 {
143     Border border = GetBorder();
144     border.SetTopEdge(edge);
145     SetBorder(border);
146 }
147 
SetRightBorderEdge(const BorderEdge & edge)148 void JSImage::SetRightBorderEdge(const BorderEdge& edge)
149 {
150     Border border = GetBorder();
151     border.SetRightEdge(edge);
152     SetBorder(border);
153 }
154 
SetBottomBorderEdge(const BorderEdge & edge)155 void JSImage::SetBottomBorderEdge(const BorderEdge& edge)
156 {
157     Border border = GetBorder();
158     border.SetBottomEdge(edge);
159     SetBorder(border);
160 }
161 
SetBorder(const Border & border)162 void JSImage::SetBorder(const Border& border)
163 {
164     GetFrontDecoration()->SetBorder(border);
165     auto image = AceType::DynamicCast<ImageComponent>(ViewStackProcessor::GetInstance()->GetMainComponent());
166     if (image) {
167         image->SetBorder(border);
168     }
169 }
170 
SetLeftBorderColor(const Color & color)171 void JSImage::SetLeftBorderColor(const Color& color)
172 {
173     BorderEdge edge = GetLeftBorderEdge();
174     edge.SetColor(color);
175     SetLeftBorderEdge(edge);
176 }
177 
SetTopBorderColor(const Color & color)178 void JSImage::SetTopBorderColor(const Color& color)
179 {
180     BorderEdge edge = GetTopBorderEdge();
181     edge.SetColor(color);
182     SetTopBorderEdge(edge);
183 }
184 
SetRightBorderColor(const Color & color)185 void JSImage::SetRightBorderColor(const Color& color)
186 {
187     BorderEdge edge = GetRightBorderEdge();
188     edge.SetColor(color);
189     SetRightBorderEdge(edge);
190 }
191 
SetBottomBorderColor(const Color & color)192 void JSImage::SetBottomBorderColor(const Color& color)
193 {
194     BorderEdge edge = GetBottomBorderEdge();
195     edge.SetColor(color);
196     SetBottomBorderEdge(edge);
197 }
198 
SetLeftBorderWidth(const Dimension & value)199 void JSImage::SetLeftBorderWidth(const Dimension& value)
200 {
201     BorderEdge edge = GetLeftBorderEdge();
202     edge.SetWidth(value);
203     SetLeftBorderEdge(edge);
204 }
205 
SetTopBorderWidth(const Dimension & value)206 void JSImage::SetTopBorderWidth(const Dimension& value)
207 {
208     BorderEdge edge = GetTopBorderEdge();
209     edge.SetWidth(value);
210     SetTopBorderEdge(edge);
211 }
212 
SetRightBorderWidth(const Dimension & value)213 void JSImage::SetRightBorderWidth(const Dimension& value)
214 {
215     BorderEdge edge = GetRightBorderEdge();
216     edge.SetWidth(value);
217     SetRightBorderEdge(edge);
218 }
219 
SetBottomBorderWidth(const Dimension & value)220 void JSImage::SetBottomBorderWidth(const Dimension& value)
221 {
222     BorderEdge edge = GetBottomBorderEdge();
223     edge.SetWidth(value);
224     SetBottomBorderEdge(edge);
225 }
226 
OnComplete(const JSCallbackInfo & args)227 void JSImage::OnComplete(const JSCallbackInfo& args)
228 {
229     LOGD("JSImage V8OnComplete");
230     if (args[0]->IsFunction()) {
231         auto jsLoadSuccFunc = AceType::MakeRefPtr<JsEventFunction<LoadImageSuccessEvent, 1>>(
232             JSRef<JSFunc>::Cast(args[0]), LoadImageSuccEventToJSValue);
233         auto image = AceType::DynamicCast<ImageComponent>(ViewStackProcessor::GetInstance()->GetMainComponent());
234         image->SetLoadSuccessEvent(EventMarker(
235             [execCtx = args.GetExecutionContext(), func = std::move(jsLoadSuccFunc)](const BaseEventInfo* info) {
236                 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
237                 auto eventInfo = TypeInfoHelper::DynamicCast<LoadImageSuccessEvent>(info);
238                 ACE_SCORING_EVENT("Image.onComplete");
239                 func->Execute(*eventInfo);
240             }));
241     } else {
242         LOGE("args not function");
243     }
244 }
245 
OnError(const JSCallbackInfo & args)246 void JSImage::OnError(const JSCallbackInfo& args)
247 {
248     LOGD("JSImage V8OnError");
249     if (args[0]->IsFunction()) {
250         auto jsLoadFailFunc = AceType::MakeRefPtr<JsEventFunction<LoadImageFailEvent, 1>>(
251             JSRef<JSFunc>::Cast(args[0]), LoadImageFailEventToJSValue);
252         auto image = AceType::DynamicCast<ImageComponent>(ViewStackProcessor::GetInstance()->GetMainComponent());
253         image->SetLoadFailEvent(EventMarker(
254             [execCtx = args.GetExecutionContext(), func = std::move(jsLoadFailFunc)](const BaseEventInfo* info) {
255                 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
256                 auto eventInfo = TypeInfoHelper::DynamicCast<LoadImageFailEvent>(info);
257                 ACE_SCORING_EVENT("Image.onError");
258                 func->Execute(*eventInfo);
259             }));
260     } else {
261         LOGE("args not function");
262     }
263 }
264 
OnFinish(const JSCallbackInfo & info)265 void JSImage::OnFinish(const JSCallbackInfo& info)
266 {
267     LOGD("JSImage V8OnFinish");
268     if (!info[0]->IsFunction()) {
269         LOGE("info[0] is not a function.");
270         return;
271     }
272     RefPtr<JsFunction> jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(info[0]));
273     auto eventMarker = EventMarker([execCtx = info.GetExecutionContext(), func = std::move(jsFunc)]() {
274         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
275         ACE_SCORING_EVENT("Image.onFinish");
276         func->Execute();
277     });
278     auto image = AceType::DynamicCast<ImageComponent>(ViewStackProcessor::GetInstance()->GetMainComponent());
279     image->SetSvgAnimatorFinishEvent(eventMarker);
280 }
281 
Create(const JSCallbackInfo & info)282 void JSImage::Create(const JSCallbackInfo& info)
283 {
284     if (info.Length() < 1) {
285         LOGE("The arg is wrong, it is supposed to have atleast 1 arguments");
286         return;
287     }
288     std::string src;
289     auto noPixMap = ParseJsMedia(info[0], src);
290     RefPtr<ImageComponent> imageComponent = AceType::MakeRefPtr<OHOS::Ace::ImageComponent>(src);
291     imageComponent->SetUseSkiaSvg(false);
292     ViewStackProcessor::GetInstance()->Push(imageComponent);
293     JSInteractableView::SetFocusable(true);
294     JSInteractableView::SetFocusNode(false);
295     if (noPixMap) {
296         return;
297     }
298 
299 #if !defined(WINDOWS_PLATFORM) and !defined(MAC_PLATFORM)
300     imageComponent->SetPixmap(CreatePixelMapFromNapiValue(info[0]));
301 #endif
302 }
303 
JsBorder(const JSCallbackInfo & info)304 void JSImage::JsBorder(const JSCallbackInfo& info)
305 {
306     JSViewAbstract::JsBorder(info);
307     SetBorder(GetBackDecoration()->GetBorder());
308 }
309 
JsBorderRadius(const JSCallbackInfo & info)310 void JSImage::JsBorderRadius(const JSCallbackInfo& info)
311 {
312     JSViewAbstract::JsBorderRadius(info);
313     SetBorder(GetBackDecoration()->GetBorder());
314 }
315 
SetSourceSize(const JSCallbackInfo & info)316 void JSImage::SetSourceSize(const JSCallbackInfo& info)
317 {
318     auto image = AceType::DynamicCast<ImageComponent>(ViewStackProcessor::GetInstance()->GetMainComponent());
319     image->SetImageSourceSize(JSViewAbstract::ParseSize(info));
320 }
321 
SetImageFill(const JSCallbackInfo & info)322 void JSImage::SetImageFill(const JSCallbackInfo& info)
323 {
324     if (info.Length() < 1) {
325         LOGE("The arg is wrong, it is supposed to have atleast 1 arguments");
326         return;
327     }
328 
329     Color color;
330     if (!ParseJsColor(info[0], color)) {
331         return;
332     }
333     auto image = AceType::DynamicCast<ImageComponent>(ViewStackProcessor::GetInstance()->GetMainComponent());
334     image->SetImageFill(color);
335 }
336 
SetImageRenderMode(int32_t imageRenderMode)337 void JSImage::SetImageRenderMode(int32_t imageRenderMode)
338 {
339     auto image = AceType::DynamicCast<ImageComponent>(ViewStackProcessor::GetInstance()->GetMainComponent());
340     image->SetImageRenderMode(static_cast<ImageRenderMode>(imageRenderMode));
341 }
342 
SetImageInterpolation(int32_t imageInterpolation)343 void JSImage::SetImageInterpolation(int32_t imageInterpolation)
344 {
345     auto image = AceType::DynamicCast<ImageComponent>(ViewStackProcessor::GetInstance()->GetMainComponent());
346     image->SetImageInterpolation(static_cast<ImageInterpolation>(imageInterpolation));
347 }
348 
SetImageRepeat(int32_t imageRepeat)349 void JSImage::SetImageRepeat(int32_t imageRepeat)
350 {
351     auto image = AceType::DynamicCast<ImageComponent>(ViewStackProcessor::GetInstance()->GetMainComponent());
352     image->SetImageRepeat(static_cast<ImageRepeat>(imageRepeat));
353 }
354 
JsTransition(const JSCallbackInfo & info)355 void JSImage::JsTransition(const JSCallbackInfo& info)
356 {
357     auto image = AceType::DynamicCast<ImageComponent>(ViewStackProcessor::GetInstance()->GetMainComponent());
358     if (image && image->IsSrcSvgImage()) {
359         JSViewAbstract::JsTransition(info);
360     } else {
361         JSViewAbstract::JsTransitionPassThrough(info);
362     }
363 }
364 
JsOpacity(const JSCallbackInfo & info)365 void JSImage::JsOpacity(const JSCallbackInfo& info)
366 {
367     auto image = AceType::DynamicCast<ImageComponent>(ViewStackProcessor::GetInstance()->GetMainComponent());
368     if (image && image->IsSrcSvgImage()) {
369         JSViewAbstract::JsOpacity(info);
370     } else {
371         JSViewAbstract::JsOpacityPassThrough(info);
372     }
373 }
374 
SetAutoResize(bool autoResize)375 void JSImage::SetAutoResize(bool autoResize)
376 {
377     auto image = AceType::DynamicCast<ImageComponent>(ViewStackProcessor::GetInstance()->GetMainComponent());
378     if (image) {
379         image->SetAutoResize(autoResize);
380     }
381 }
382 
SetSyncLoad(const JSCallbackInfo & info)383 void JSImage::SetSyncLoad(const JSCallbackInfo& info)
384 {
385     auto image = AceType::DynamicCast<ImageComponent>(ViewStackProcessor::GetInstance()->GetMainComponent());
386     if (image) {
387         image->SetSyncMode(info[0]->ToBoolean());
388     }
389 }
390 
JSBind(BindingTarget globalObj)391 void JSImage::JSBind(BindingTarget globalObj)
392 {
393     JSClass<JSImage>::Declare("Image");
394     MethodOptions opt = MethodOptions::NONE;
395     JSClass<JSImage>::StaticMethod("create", &JSImage::Create, opt);
396     JSClass<JSImage>::StaticMethod("alt", &JSImage::SetAlt, opt);
397     JSClass<JSImage>::StaticMethod("objectFit", &JSImage::SetObjectFit, opt);
398     JSClass<JSImage>::StaticMethod("matchTextDirection", &JSImage::SetMatchTextDirection, opt);
399     JSClass<JSImage>::StaticMethod("fitOriginalSize", &JSImage::SetFitOriginalSize, opt);
400     JSClass<JSImage>::StaticMethod("sourceSize", &JSImage::SetSourceSize, opt);
401     JSClass<JSImage>::StaticMethod("fillColor", &JSImage::SetImageFill, opt);
402     JSClass<JSImage>::StaticMethod("renderMode", &JSImage::SetImageRenderMode, opt);
403     JSClass<JSImage>::StaticMethod("objectRepeat", &JSImage::SetImageRepeat, opt);
404     JSClass<JSImage>::StaticMethod("interpolation", &JSImage::SetImageInterpolation, opt);
405     JSClass<JSImage>::StaticMethod("borderStyle", &JSViewAbstract::SetBorderStyle, opt);
406     JSClass<JSImage>::StaticMethod("borderColor", &JSViewAbstract::JsBorderColor);
407     JSClass<JSImage>::StaticMethod("border", &JSImage::JsBorder);
408     JSClass<JSImage>::StaticMethod("borderWidth", &JSViewAbstract::JsBorderWidth);
409     JSClass<JSImage>::StaticMethod("borderRadius", &JSImage::JsBorderRadius);
410     JSClass<JSImage>::StaticMethod("onAppear", &JSInteractableView::JsOnAppear);
411     JSClass<JSImage>::StaticMethod("onDisAppear", &JSInteractableView::JsOnDisAppear);
412     JSClass<JSImage>::StaticMethod("autoResize", &JSImage::SetAutoResize);
413 
414     JSClass<JSImage>::StaticMethod("onTouch", &JSInteractableView::JsOnTouch);
415     JSClass<JSImage>::StaticMethod("onHover", &JSInteractableView::JsOnHover);
416     JSClass<JSImage>::StaticMethod("onKeyEvent", &JSInteractableView::JsOnKey);
417     JSClass<JSImage>::StaticMethod("onDeleteEvent", &JSInteractableView::JsOnDelete);
418     JSClass<JSImage>::StaticMethod("onClick", &JSInteractableView::JsOnClick);
419     JSClass<JSImage>::StaticMethod("onComplete", &JSImage::OnComplete);
420     JSClass<JSImage>::StaticMethod("onError", &JSImage::OnError);
421     JSClass<JSImage>::StaticMethod("onFinish", &JSImage::OnFinish);
422     JSClass<JSImage>::StaticMethod("syncLoad", &JSImage::SetSyncLoad);
423     JSClass<JSImage>::StaticMethod("remoteMessage", &JSInteractableView::JsCommonRemoteMessage);
424     JSClass<JSImage>::Inherit<JSViewAbstract>();
425     // override method
426     JSClass<JSImage>::StaticMethod("opacity", &JSImage::JsOpacity);
427     JSClass<JSImage>::StaticMethod("transition", &JSImage::JsTransition);
428     JSClass<JSImage>::Bind<>(globalObj);
429 }
430 
431 } // namespace OHOS::Ace::Framework
432