• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2025 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 "bridge/declarative_frontend/jsview/js_image.h"
17 
18 #include <cstdint>
19 #include <memory>
20 #include <vector>
21 #ifndef PREVIEW
22 #include <dlfcn.h>
23 #endif
24 
25 #include "interfaces/inner_api/ace/ai/image_analyzer.h"
26 #include "interfaces/inner_api/ui_session/ui_session_manager.h"
27 
28 #include "base/geometry/ng/vector.h"
29 #include "base/image/drawable_descriptor.h"
30 #include "base/image/drawing_color_filter.h"
31 #include "base/image/drawing_lattice.h"
32 #include "base/image/pixel_map.h"
33 #include "base/log/ace_scoring_log.h"
34 #include "base/log/ace_trace.h"
35 #include "bridge/common/utils/engine_helper.h"
36 #include "bridge/declarative_frontend/engine/functions/js_drag_function.h"
37 #include "bridge/declarative_frontend/engine/js_ref_ptr.h"
38 #include "bridge/declarative_frontend/engine/js_types.h"
39 #include "bridge/declarative_frontend/engine/jsi/js_ui_index.h"
40 #include "bridge/declarative_frontend/jsview/models/image_model_impl.h"
41 #include "core/common/container.h"
42 #include "core/components/common/layout/constants.h"
43 #include "core/components/image/image_event.h"
44 #include "core/components/image/image_theme.h"
45 #include "core/components_ng/base/view_abstract_model.h"
46 #include "core/components_ng/base/view_stack_processor.h"
47 #include "core/components_ng/event/gesture_event_hub.h"
48 #include "core/components_ng/pattern/image/image_model.h"
49 #include "core/components_ng/pattern/image/image_model_ng.h"
50 #include "core/image/image_source_info.h"
51 
52 namespace {
53 const std::vector<float> DEFAULT_COLORFILTER_MATRIX = { 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0 };
54 constexpr float CEIL_SMOOTHEDGE_VALUE = 1.333f;
55 constexpr float FLOOR_SMOOTHEDGE_VALUE = 0.334f;
56 constexpr float DEFAULT_SMOOTHEDGE_VALUE = 0.0f;
57 constexpr uint32_t FIT_MATRIX = 16;
58 constexpr char DRAWABLE_DESCRIPTOR_NAME[] = "DrawableDescriptor";
59 constexpr char LAYERED_DRAWABLE_DESCRIPTOR_NAME[] = "LayeredDrawableDescriptor";
60 constexpr char ANIMATED_DRAWABLE_DESCRIPTOR_NAME[] = "AnimatedDrawableDescriptor";
61 constexpr char PIXELMAP_DRAWABLE_DESCRIPTOR_NAME[] = "PixelMapDrawableDescriptor";
62 } // namespace
63 
64 namespace OHOS::Ace {
65 
66 namespace {
CreateSourceInfo(const std::shared_ptr<std::string> & srcRef,RefPtr<PixelMap> & pixmap,const std::string & bundleName,const std::string & moduleName)67 ImageSourceInfo CreateSourceInfo(const std::shared_ptr<std::string>& srcRef, RefPtr<PixelMap>& pixmap,
68     const std::string& bundleName, const std::string& moduleName)
69 {
70 #if defined(PIXEL_MAP_SUPPORTED)
71     if (pixmap) {
72         return ImageSourceInfo(pixmap);
73     }
74 #endif
75     return { srcRef, bundleName, moduleName };
76 }
77 } // namespace
78 
79 std::unique_ptr<ImageModel> ImageModel::instance_ = nullptr;
80 std::mutex ImageModel::mutex_;
81 
GetInstance()82 ImageModel* __attribute__((optnone)) ImageModel::GetInstance()
83 {
84     if (!instance_) {
85         std::lock_guard<std::mutex> lock(mutex_);
86         if (!instance_) {
87 #ifdef NG_BUILD
88             instance_.reset(new NG::ImageModelNG());
89 #else
90             if (Container::IsCurrentUseNewPipeline()) {
91                 instance_.reset(new NG::ImageModelNG());
92             } else {
93                 instance_.reset(new Framework::ImageModelImpl());
94             }
95 #endif
96         }
97     }
98     return instance_.get();
99 }
100 
101 } // namespace OHOS::Ace
102 
103 namespace OHOS::Ace::Framework {
104 
LoadImageSuccEventToJSValue(const LoadImageSuccessEvent & eventInfo)105 JSRef<JSVal> LoadImageSuccEventToJSValue(const LoadImageSuccessEvent& eventInfo)
106 {
107     JSRef<JSObject> obj = JSRef<JSObject>::New();
108     obj->SetProperty("width", eventInfo.GetWidth());
109     obj->SetProperty("height", eventInfo.GetHeight());
110     obj->SetProperty("componentWidth", eventInfo.GetComponentWidth());
111     obj->SetProperty("componentHeight", eventInfo.GetComponentHeight());
112     obj->SetProperty("loadingStatus", eventInfo.GetLoadingStatus());
113     obj->SetProperty("contentWidth", eventInfo.GetContentWidth());
114     obj->SetProperty("contentHeight", eventInfo.GetContentHeight());
115     obj->SetProperty("contentOffsetX", eventInfo.GetContentOffsetX());
116     obj->SetProperty("contentOffsetY", eventInfo.GetContentOffsetY());
117     return JSRef<JSVal>::Cast(obj);
118 }
119 
LoadImageFailEventToJSValue(const LoadImageFailEvent & eventInfo)120 JSRef<JSVal> LoadImageFailEventToJSValue(const LoadImageFailEvent& eventInfo)
121 {
122     JSRef<JSObject> obj = JSRef<JSObject>::New();
123     obj->SetProperty("componentWidth", eventInfo.GetComponentWidth());
124     obj->SetProperty("componentHeight", eventInfo.GetComponentHeight());
125     obj->SetProperty("message", eventInfo.GetErrorMessage());
126     return JSRef<JSVal>::Cast(obj);
127 }
128 
SetAlt(const JSCallbackInfo & args)129 void JSImage::SetAlt(const JSCallbackInfo& args)
130 {
131     if (ImageModel::GetInstance()->GetIsAnimation()) {
132         return;
133     }
134     if (args.Length() < 1) {
135         return;
136     }
137 
138     auto context = PipelineBase::GetCurrentContext();
139     CHECK_NULL_VOID(context);
140     bool isCard = context->IsFormRender();
141 
142     std::string src;
143     bool srcValid = false;
144     if (args[0]->IsString()) {
145         src = args[0]->ToString();
146     } else {
147         srcValid = ParseJsMedia(args[0], src);
148     }
149     if (ImageSourceInfo::ResolveURIType(src) == SrcType::NETWORK) {
150         return;
151     }
152     int32_t resId = 0;
153     if (args[0]->IsObject()) {
154         JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(args[0]);
155         JSRef<JSVal> tmp = jsObj->GetProperty("id");
156         if (!tmp->IsNull() && tmp->IsNumber()) {
157             resId = tmp->ToNumber<int32_t>();
158         }
159     }
160     std::string bundleName;
161     std::string moduleName;
162     GetJsMediaBundleInfo(args[0], bundleName, moduleName);
163     RefPtr<PixelMap> pixmap = nullptr;
164 
165     // input is Drawable
166     if (!srcValid && !isCard) {
167 #if defined(PIXEL_MAP_SUPPORTED)
168         pixmap = CreatePixelMapFromNapiValue(args[0]);
169 #endif
170     }
171     auto srcRef = std::make_shared<std::string>(src);
172     auto srcInfo = CreateSourceInfo(srcRef, pixmap, bundleName, moduleName);
173     srcInfo.SetIsUriPureNumber((resId == -1));
174     ImageModel::GetInstance()->SetAlt(srcInfo);
175 }
176 
SetObjectFit(const JSCallbackInfo & args)177 void JSImage::SetObjectFit(const JSCallbackInfo& args)
178 {
179     if (args.Length() < 1) {
180         ImageModel::GetInstance()->SetImageFit(ImageFit::COVER);
181         return;
182     }
183     int32_t parseRes = 2;
184     ParseJsInteger(args[0], parseRes);
185     if (parseRes < static_cast<int32_t>(ImageFit::FILL) || parseRes > static_cast<int32_t>(ImageFit::MATRIX)) {
186         parseRes = 2;
187     }
188     auto fit = static_cast<ImageFit>(parseRes);
189     if (parseRes == FIT_MATRIX) {
190         fit = ImageFit::MATRIX;
191     }
192     ImageModel::GetInstance()->SetImageFit(fit);
193 }
194 
SetImageMatrix(const JSCallbackInfo & args)195 void JSImage::SetImageMatrix(const JSCallbackInfo& args)
196 {
197     if (args.Length() > 0) {
198         auto jsVal = args[0];
199         if (!jsVal->IsObject()) {
200             SetDefaultImageMatrix();
201             return;
202         }
203         JSRef<JSVal> array = JSRef<JSObject>::Cast(jsVal)->GetProperty(static_cast<int32_t>(ArkUIIndex::MATRIX4X4));
204         const auto matrix4Len = Matrix4::DIMENSION * Matrix4::DIMENSION;
205         if (!array->IsArray()) {
206             return;
207         }
208         JSRef<JSArray> jsArray = JSRef<JSArray>::Cast(array);
209         if (jsArray->Length() != matrix4Len) {
210             return;
211         }
212         std::vector<float> matrix(matrix4Len);
213         for (int32_t i = 0; i < matrix4Len; i++) {
214             double value = 0.0;
215             ParseJsDouble(jsArray->GetValueAt(i), value);
216             matrix[i] = static_cast<float>(value);
217         }
218         Matrix4 setValue = Matrix4(matrix[0], matrix[4], matrix[8], matrix[12], matrix[1], matrix[5], matrix[9],
219             matrix[13], matrix[2], matrix[6], matrix[10], matrix[14], matrix[3], matrix[7], matrix[11], matrix[15]);
220         ImageModel::GetInstance()->SetImageMatrix(setValue);
221     } else {
222         SetDefaultImageMatrix();
223         return;
224     }
225 }
226 
SetDefaultImageMatrix()227 void JSImage::SetDefaultImageMatrix()
228 {
229     const auto matrix4Len = Matrix4::DIMENSION * Matrix4::DIMENSION;
230     std::vector<float> matrix(matrix4Len);
231     const int32_t initPosition = 5;
232     for (int32_t i = 0; i < matrix4Len; i = i + initPosition) {
233         matrix[i] = 1.0f;
234     }
235     Matrix4 setValue = Matrix4(matrix[0], matrix[4], matrix[8], matrix[12], matrix[1], matrix[5], matrix[9], matrix[13],
236         matrix[2], matrix[6], matrix[10], matrix[14], matrix[3], matrix[7], matrix[11], matrix[15]);
237     ImageModel::GetInstance()->SetImageMatrix(setValue);
238 }
239 
SetMatchTextDirection(bool value)240 void JSImage::SetMatchTextDirection(bool value)
241 {
242     if (ImageModel::GetInstance()->GetIsAnimation()) {
243         return;
244     }
245     ImageModel::GetInstance()->SetMatchTextDirection(value);
246 }
247 
SetFitOriginalSize(bool value)248 void JSImage::SetFitOriginalSize(bool value)
249 {
250     if (ImageModel::GetInstance()->GetIsAnimation()) {
251         return;
252     }
253     ImageModel::GetInstance()->SetFitOriginSize(value);
254 }
255 
SetBorder(const Border & border)256 void JSImage::SetBorder(const Border& border)
257 {
258     ImageModel::GetInstance()->SetBorder(border);
259 }
260 
OnComplete(const JSCallbackInfo & args)261 void JSImage::OnComplete(const JSCallbackInfo& args)
262 {
263     if (args[0]->IsFunction()) {
264         auto jsLoadSuccFunc = AceType::MakeRefPtr<JsEventFunction<LoadImageSuccessEvent, 1>>(
265             JSRef<JSFunc>::Cast(args[0]), LoadImageSuccEventToJSValue);
266 
267         auto onComplete = [execCtx = args.GetExecutionContext(), func = std::move(jsLoadSuccFunc)](
268                               const LoadImageSuccessEvent& info) {
269             JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
270             ACE_SCORING_EVENT("Image.onComplete");
271             func->Execute(info);
272             UiSessionManager::GetInstance()->ReportComponentChangeEvent("event", "Image.onComplete");
273         };
274         ImageModel::GetInstance()->SetOnComplete(std::move(onComplete));
275     }
276 }
277 
OnError(const JSCallbackInfo & args)278 void JSImage::OnError(const JSCallbackInfo& args)
279 {
280     if (args[0]->IsFunction()) {
281         auto jsLoadFailFunc = AceType::MakeRefPtr<JsEventFunction<LoadImageFailEvent, 1>>(
282             JSRef<JSFunc>::Cast(args[0]), LoadImageFailEventToJSValue);
283         auto onError = [execCtx = args.GetExecutionContext(), func = std::move(jsLoadFailFunc)](
284                            const LoadImageFailEvent& info) {
285             JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
286             ACE_SCORING_EVENT("Image.onError");
287             func->Execute(info);
288             UiSessionManager::GetInstance()->ReportComponentChangeEvent("event", "Image.onError");
289         };
290 
291         ImageModel::GetInstance()->SetOnError(onError);
292     }
293 }
294 
OnFinish(const JSCallbackInfo & info)295 void JSImage::OnFinish(const JSCallbackInfo& info)
296 {
297     auto tmpInfo = info[0];
298     if (!tmpInfo->IsFunction()) {
299         return;
300     }
301     RefPtr<JsFunction> jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(tmpInfo));
302     WeakPtr<NG::FrameNode> targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
303     auto onFinish = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), node = targetNode]() {
304         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
305         ACE_SCORING_EVENT("Image.onFinish");
306         PipelineContext::SetCallBackNode(node);
307         func->Execute();
308     };
309     ImageModel::GetInstance()->SetSvgAnimatorFinishEvent(onFinish);
310 }
311 
Create(const JSCallbackInfo & info)312 void JSImage::Create(const JSCallbackInfo& info)
313 {
314     if (info.Length() < 1) {
315         return;
316     }
317     CreateImage(info);
318 }
319 
CheckIsCard(std::string & src,const JSRef<JSVal> & imageInfo)320 void JSImage::CheckIsCard(std::string& src, const JSRef<JSVal>& imageInfo)
321 {
322     bool isCard = false;
323     auto container = Container::Current();
324     if (container) {
325         isCard = container->IsFormRender() && !container->IsDynamicRender();
326     } else {
327         TAG_LOGW(AceLogTag::ACE_IMAGE, "check is card, container is null");
328     }
329     if (isCard && imageInfo->IsString()) {
330         SrcType srcType = ImageSourceInfo::ResolveURIType(src);
331         bool notSupport = (srcType == SrcType::NETWORK || srcType == SrcType::FILE || srcType == SrcType::DATA_ABILITY);
332         if (notSupport) {
333             src.clear();
334         }
335     }
336 }
337 
338 // The image reset only when the param is ImageContent.Empty
CheckResetImage(const bool & srcValid,const JSCallbackInfo & info)339 bool JSImage::CheckResetImage(const bool& srcValid, const JSCallbackInfo& info)
340 {
341     if (!srcValid) {
342         int32_t parseRes = -1;
343         if (info.Length() < 1 || !ParseJsInteger(info[0], parseRes)) {
344             return false;
345         }
346         ImageModel::GetInstance()->ResetImage();
347         return true;
348     }
349     return false;
350 }
351 
ParseImageType(const JSRef<JSVal> & imageInfo)352 ImageType JSImage::ParseImageType(const JSRef<JSVal>& imageInfo)
353 {
354     if (!imageInfo->IsObject()) {
355         return ImageType::BASE;
356     }
357 
358     JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(imageInfo);
359     if (jsObj->IsUndefined()) {
360         return ImageType::BASE;
361     }
362     JSRef<JSVal> jsTypeName = jsObj->GetProperty("typeName");
363     if (!jsTypeName->IsString()) {
364         return ImageType::BASE;
365     }
366     auto typeName = jsTypeName->ToString();
367     if (typeName == DRAWABLE_DESCRIPTOR_NAME) {
368         return ImageType::DRAWABLE;
369     } else if (typeName == LAYERED_DRAWABLE_DESCRIPTOR_NAME) {
370         return ImageType::LAYERED_DRAWABLE;
371     } else if (typeName == ANIMATED_DRAWABLE_DESCRIPTOR_NAME) {
372         return ImageType::ANIMATED_DRAWABLE;
373     } else if (typeName == PIXELMAP_DRAWABLE_DESCRIPTOR_NAME) {
374         return ImageType::PIXELMAP_DRAWABLE;
375     } else {
376         return ImageType::BASE;
377     }
378 }
379 
CreateImage(const JSCallbackInfo & info,bool isImageSpan)380 void JSImage::CreateImage(const JSCallbackInfo& info, bool isImageSpan)
381 {
382     std::string bundleName;
383     std::string moduleName;
384     std::string src;
385     auto imageInfo = info[0];
386     int32_t resId = 0;
387     bool srcValid = ParseJsMediaWithBundleName(imageInfo, src, bundleName, moduleName, resId);
388     CHECK_EQUAL_VOID(CheckResetImage(srcValid, info), true);
389     CheckIsCard(src, imageInfo);
390     RefPtr<PixelMap> pixmap = nullptr;
391 
392     if (!srcValid) {
393 #ifdef PIXEL_MAP_SUPPORTED
394         auto type = ParseImageType(imageInfo);
395         if (type == ImageType::ANIMATED_DRAWABLE) {
396             std::vector<RefPtr<PixelMap>> pixelMaps;
397             int32_t duration = -1;
398             int32_t iterations = 1;
399             if (GetPixelMapListFromAnimatedDrawable(imageInfo, pixelMaps, duration, iterations)) {
400                 CreateImageAnimation(pixelMaps, duration, iterations);
401                 return;
402             }
403         } else if (type == ImageType::PIXELMAP_DRAWABLE) {
404             auto* address = UnwrapNapiValue(imageInfo);
405             auto drawable = DrawableDescriptor::CreateDrawable(address);
406             if (!drawable) {
407                 return;
408             }
409             if (drawable->GetDrawableSrcType() == 1) {
410                 pixmap = GetDrawablePixmap(imageInfo);
411             } else {
412                 ImageModel::GetInstance()->Create(drawable);
413                 ParseImageAIOptions(info);
414                 return;
415             }
416         } else if (type == ImageType::LAYERED_DRAWABLE || type == ImageType::DRAWABLE) {
417             pixmap = GetDrawablePixmap(imageInfo);
418         } else {
419             pixmap = CreatePixelMapFromNapiValue(imageInfo);
420         }
421 #endif
422     }
423     ImageInfoConfig config;
424     config.src = std::make_shared<std::string>(src);
425     config.bundleName = bundleName;
426     config.moduleName = moduleName;
427     config.isUriPureNumber = (resId == -1);
428     config.isImageSpan = isImageSpan;
429     ImageModel::GetInstance()->Create(config, pixmap);
430     ParseImageAIOptions(info);
431 }
432 
ParseImageAIOptions(const JSCallbackInfo & info)433 void JSImage::ParseImageAIOptions(const JSCallbackInfo& info)
434 {
435     if (info.Length() <= 1) {
436         return;
437     }
438     auto options = info[1];
439     if (!options->IsObject()) {
440         return;
441     }
442     auto engine = EngineHelper::GetCurrentEngine();
443     CHECK_NULL_VOID(engine);
444     NativeEngine* nativeEngine = engine->GetNativeEngine();
445     panda::Local<JsiValue> value = options.Get().GetLocalHandle();
446     JSValueWrapper valueWrapper = value;
447     ScopeRAII scope(reinterpret_cast<napi_env>(nativeEngine));
448     napi_value optionsValue = nativeEngine->ValueToNapiValue(valueWrapper);
449     ImageModel::GetInstance()->SetImageAIOptions(optionsValue);
450 }
451 
IsDrawable(const JSRef<JSVal> & jsValue)452 bool JSImage::IsDrawable(const JSRef<JSVal>& jsValue)
453 {
454     if (!jsValue->IsObject()) {
455         return false;
456     }
457     JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
458     if (jsObj->IsUndefined()) {
459         return false;
460     }
461 
462     // if jsObject has function getPixelMap, it's a DrawableDescriptor object
463     JSRef<JSVal> func = jsObj->GetProperty("getPixelMap");
464     return (!func->IsNull() && func->IsFunction());
465 }
466 
JsBorder(const JSCallbackInfo & info)467 void JSImage::JsBorder(const JSCallbackInfo& info)
468 {
469     if (Container::LessThanAPITargetVersion(PlatformVersion::VERSION_FOURTEEN)) {
470         JSViewAbstract::JsBorder(info);
471         ImageModel::GetInstance()->SetBackBorder();
472         return;
473     }
474     // handles generic property logic.
475     JSViewAbstract::JsBorder(info);
476     // handles the image component separately, aiming to extract and set the borderRadius property
477     if (!info[0]->IsObject()) {
478         CalcDimension borderRadius;
479         ImageModel::GetInstance()->SetBorderRadius(borderRadius);
480         return;
481     }
482     JSRef<JSObject> object = JSRef<JSObject>::Cast(info[0]);
483 
484     auto valueRadius = object->GetProperty(static_cast<int32_t>(ArkUIIndex::RADIUS));
485     if (!valueRadius->IsUndefined()) {
486         ParseBorderRadius(valueRadius);
487     }
488 }
489 
ParseBorderRadius(const JSRef<JSVal> & args)490 void JSImage::ParseBorderRadius(const JSRef<JSVal>& args)
491 {
492     CalcDimension borderRadius;
493     if (ParseJsDimensionVp(args, borderRadius)) {
494         ViewAbstractModel::GetInstance()->SetBorderRadius(borderRadius);
495         ImageModel::GetInstance()->SetBorderRadius(borderRadius);
496     } else if (args->IsObject()) {
497         JSRef<JSObject> object = JSRef<JSObject>::Cast(args);
498         CalcDimension topLeft;
499         CalcDimension topRight;
500         CalcDimension bottomLeft;
501         CalcDimension bottomRight;
502         if (ParseAllBorderRadiuses(object, topLeft, topRight, bottomLeft, bottomRight)) {
503             ImageModel::GetInstance()->SetBorderRadius(
504                 GetLocalizedBorderRadius(topLeft, topRight, bottomLeft, bottomRight));
505             ViewAbstractModel::GetInstance()->SetBorderRadius(
506                 GetLocalizedBorderRadius(topLeft, topRight, bottomLeft, bottomRight));
507             return;
508         }
509         ImageModel::GetInstance()->SetBorderRadius(topLeft, topRight, bottomLeft, bottomRight);
510         ViewAbstractModel::GetInstance()->SetBorderRadius(topLeft, topRight, bottomLeft, bottomRight);
511     }
512 }
513 
ParseResizableSlice(const JSRef<JSObject> & resizableObject)514 void JSImage::ParseResizableSlice(const JSRef<JSObject>& resizableObject)
515 {
516     ImageResizableSlice sliceResult;
517     if (resizableObject->IsEmpty()) {
518         ImageModel::GetInstance()->SetResizableSlice(sliceResult);
519         return;
520     }
521     auto sliceValue = resizableObject->GetProperty("slice");
522     if (!sliceValue->IsObject()) {
523         ImageModel::GetInstance()->SetResizableSlice(sliceResult);
524         return;
525     }
526     JSRef<JSObject> sliceObj = JSRef<JSObject>::Cast(sliceValue);
527     if (sliceObj->IsEmpty()) {
528         ImageModel::GetInstance()->SetResizableSlice(sliceResult);
529         return;
530     }
531     UpdateSliceResult(sliceObj, sliceResult);
532 
533     ImageModel::GetInstance()->SetResizableSlice(sliceResult);
534 }
535 
ParseResizableLattice(const JSRef<JSObject> & resizableObject)536 void JSImage::ParseResizableLattice(const JSRef<JSObject>& resizableObject)
537 {
538     auto latticeValue = resizableObject->GetProperty("lattice");
539     if (latticeValue->IsUndefined() || latticeValue->IsNull()) {
540         ImageModel::GetInstance()->ResetResizableLattice();
541     }
542     CHECK_NULL_VOID(latticeValue->IsObject());
543     auto drawingLattice = CreateDrawingLattice(latticeValue);
544     if (drawingLattice) {
545         ImageModel::GetInstance()->SetResizableLattice(drawingLattice);
546     } else {
547         ImageModel::GetInstance()->ResetResizableLattice();
548     }
549 }
550 
JsImageResizable(const JSCallbackInfo & info)551 void JSImage::JsImageResizable(const JSCallbackInfo& info)
552 {
553     if (ImageModel::GetInstance()->GetIsAnimation()) {
554         return;
555     }
556     auto infoObj = info[0];
557     if (!infoObj->IsObject()) {
558         ImageModel::GetInstance()->SetResizableSlice(ImageResizableSlice());
559         return;
560     }
561     JSRef<JSObject> resizableObject = JSRef<JSObject>::Cast(infoObj);
562     ParseResizableSlice(resizableObject);
563     ParseResizableLattice(resizableObject);
564 }
565 
UpdateSliceResult(const JSRef<JSObject> & sliceObj,ImageResizableSlice & sliceResult)566 void JSImage::UpdateSliceResult(const JSRef<JSObject>& sliceObj, ImageResizableSlice& sliceResult)
567 {
568     // creatge a array has 4 elements for paresing sliceSize
569     static std::array<int32_t, 4> keys = { static_cast<int32_t>(ArkUIIndex::LEFT),
570         static_cast<int32_t>(ArkUIIndex::RIGHT), static_cast<int32_t>(ArkUIIndex::TOP),
571         static_cast<int32_t>(ArkUIIndex::BOTTOM) };
572     for (uint32_t i = 0; i < keys.size(); i++) {
573         auto sliceSize = sliceObj->GetProperty(keys.at(i));
574         CalcDimension sliceDimension;
575         if (!ParseJsDimensionVp(sliceSize, sliceDimension)) {
576             continue;
577         }
578         if (!sliceDimension.IsValid()) {
579             continue;
580         }
581         switch (static_cast<BorderImageDirection>(i)) {
582             case BorderImageDirection::LEFT:
583                 sliceResult.left = sliceDimension;
584                 break;
585             case BorderImageDirection::RIGHT:
586                 sliceResult.right = sliceDimension;
587                 break;
588             case BorderImageDirection::TOP:
589                 sliceResult.top = sliceDimension;
590                 break;
591             case BorderImageDirection::BOTTOM:
592                 sliceResult.bottom = sliceDimension;
593                 break;
594             default:
595                 break;
596         }
597     }
598     ImageModel::GetInstance()->SetResizableSlice(sliceResult);
599 }
600 
JsBorderRadius(const JSCallbackInfo & info)601 void JSImage::JsBorderRadius(const JSCallbackInfo& info)
602 {
603     if (Container::LessThanAPITargetVersion(PlatformVersion::VERSION_FOURTEEN)) {
604         JSViewAbstract::JsBorderRadius(info);
605         ImageModel::GetInstance()->SetBackBorder();
606         return;
607     }
608     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::STRING, JSCallbackInfoType::NUMBER,
609         JSCallbackInfoType::OBJECT };
610     auto jsVal = info[0];
611     if (!CheckJSCallbackInfo("JsBorderRadius", jsVal, checkList)) {
612         ViewAbstractModel::GetInstance()->SetBorderRadius(Dimension {});
613         ImageModel::GetInstance()->SetBorderRadius(Dimension {});
614         return;
615     }
616     ParseBorderRadius(jsVal);
617 }
618 
SetSourceSize(const JSCallbackInfo & info)619 void JSImage::SetSourceSize(const JSCallbackInfo& info)
620 {
621     if (ImageModel::GetInstance()->GetIsAnimation()) {
622         return;
623     }
624     ImageModel::GetInstance()->SetImageSourceSize(JSViewAbstract::ParseSize(info));
625 }
626 
ParseColorContent(const JSRef<JSVal> & jsValue)627 bool JSImage::ParseColorContent(const JSRef<JSVal>& jsValue)
628 {
629     if (jsValue.IsEmpty() || jsValue->IsNull() || !jsValue->IsObject()) {
630         return false;
631     }
632     auto paramObject = JSRef<JSObject>::Cast(jsValue);
633     JSRef<JSVal> typeVal = paramObject->GetProperty("colorContent_");
634     return !typeVal.IsEmpty() && typeVal->IsString() && typeVal->ToString() == "ORIGIN";
635 }
636 
SetImageFill(const JSCallbackInfo & info)637 void JSImage::SetImageFill(const JSCallbackInfo& info)
638 {
639     if (ImageModel::GetInstance()->GetIsAnimation()) {
640         return;
641     }
642     if (info.Length() < 1) {
643         return;
644     }
645 
646     Color color;
647     if (!ParseJsColor(info[0], color)) {
648         if (ParseColorContent(info[0])) {
649             ImageModel::GetInstance()->ResetImageFill();
650             return;
651         }
652         if (Container::LessThanAPITargetVersion(PlatformVersion::VERSION_ELEVEN)) {
653             return;
654         }
655         auto pipelineContext = PipelineBase::GetCurrentContext();
656         CHECK_NULL_VOID(pipelineContext);
657         auto theme = pipelineContext->GetTheme<ImageTheme>();
658         CHECK_NULL_VOID(theme);
659         color = theme->GetFillColor();
660     }
661     ImageModel::GetInstance()->SetImageFill(color);
662 }
663 
SetImageRenderMode(const JSCallbackInfo & info)664 void JSImage::SetImageRenderMode(const JSCallbackInfo& info)
665 {
666     if (ImageModel::GetInstance()->GetIsAnimation()) {
667         return;
668     }
669     if (info.Length() < 1) {
670         ImageModel::GetInstance()->SetImageRenderMode(ImageRenderMode::ORIGINAL);
671         return;
672     }
673     auto jsImageRenderMode = info[0];
674     if (jsImageRenderMode->IsNumber()) {
675         auto renderMode = static_cast<ImageRenderMode>(jsImageRenderMode->ToNumber<int32_t>());
676         if (renderMode < ImageRenderMode::ORIGINAL || renderMode > ImageRenderMode::TEMPLATE) {
677             renderMode = ImageRenderMode::ORIGINAL;
678         }
679         ImageModel::GetInstance()->SetImageRenderMode(renderMode);
680     } else {
681         ImageModel::GetInstance()->SetImageRenderMode(ImageRenderMode::ORIGINAL);
682     }
683 }
684 
SetImageInterpolation(int32_t imageInterpolation)685 void JSImage::SetImageInterpolation(int32_t imageInterpolation)
686 {
687     if (ImageModel::GetInstance()->GetIsAnimation()) {
688         return;
689     }
690     auto interpolation = static_cast<ImageInterpolation>(imageInterpolation);
691     if (interpolation < ImageInterpolation::NONE || interpolation > ImageInterpolation::HIGH) {
692         interpolation = ImageInterpolation::NONE;
693     }
694     ImageModel::GetInstance()->SetImageInterpolation(interpolation);
695 }
696 
SetImageRepeat(int32_t imageRepeat)697 void JSImage::SetImageRepeat(int32_t imageRepeat)
698 {
699     auto repeat = static_cast<ImageRepeat>(imageRepeat);
700     if (repeat < ImageRepeat::NO_REPEAT || repeat > ImageRepeat::REPEAT) {
701         repeat = ImageRepeat::NO_REPEAT;
702     }
703     ImageModel::GetInstance()->SetImageRepeat(repeat);
704 }
705 
JsTransition(const JSCallbackInfo & info)706 void JSImage::JsTransition(const JSCallbackInfo& info)
707 {
708     if (ImageModel::GetInstance()->IsSrcSvgImage()) {
709         JSViewAbstract::JsTransition(info);
710     } else {
711         JSViewAbstract::JsTransitionPassThrough(info);
712     }
713 }
714 
JsOpacity(const JSCallbackInfo & info)715 void JSImage::JsOpacity(const JSCallbackInfo& info)
716 {
717     if (ImageModel::GetInstance()->IsSrcSvgImage()) {
718         JSViewAbstract::JsOpacity(info);
719     } else {
720         JSViewAbstract::JsOpacityPassThrough(info);
721     }
722 }
723 
JsBlur(const JSCallbackInfo & info)724 void JSImage::JsBlur(const JSCallbackInfo& info)
725 {
726 // only flutter runs special image blur
727 #ifdef ENABLE_ROSEN_BACKEND
728     JSViewAbstract::JsBlur(info);
729 #else
730     if (info.Length() < 1) {
731         return;
732     }
733     double blur = 0.0;
734     if (ParseJsDouble(info[0], blur)) {
735         ImageModel::GetInstance()->SetBlur(blur);
736     }
737 #endif
738 }
739 
SetAutoResize(bool autoResize)740 void JSImage::SetAutoResize(bool autoResize)
741 {
742     if (ImageModel::GetInstance()->GetIsAnimation()) {
743         return;
744     }
745     ImageModel::GetInstance()->SetAutoResize(autoResize);
746 }
747 
SetSyncLoad(const JSCallbackInfo & info)748 void JSImage::SetSyncLoad(const JSCallbackInfo& info)
749 {
750     if (ImageModel::GetInstance()->GetIsAnimation()) {
751         return;
752     }
753     if (info.Length() < 1) {
754         return;
755     }
756     auto tmpInfo = info[0];
757     if (!tmpInfo->IsBoolean()) {
758         return;
759     }
760     ImageModel::GetInstance()->SetSyncMode(tmpInfo->ToBoolean());
761 }
762 
ConstructorCallback(const JSCallbackInfo & args)763 void JSColorFilter::ConstructorCallback(const JSCallbackInfo& args)
764 {
765     if (args.Length() < 1) {
766         return;
767     }
768     auto tmpInfo = args[0];
769     if (!tmpInfo->IsArray()) {
770         return;
771     }
772     JSRef<JSArray> array = JSRef<JSArray>::Cast(tmpInfo);
773     if (array->Length() != COLOR_FILTER_MATRIX_SIZE) {
774         return;
775     }
776     auto jscolorfilter = Referenced::MakeRefPtr<JSColorFilter>();
777     if (jscolorfilter == nullptr) {
778         return;
779     }
780     std::vector<float> colorfilter;
781     for (size_t i = 0; i < array->Length(); i++) {
782         JSRef<JSVal> value = array->GetValueAt(i);
783         if (value->IsNumber()) {
784             colorfilter.emplace_back(value->ToNumber<float>());
785         }
786     }
787     if (colorfilter.size() != COLOR_FILTER_MATRIX_SIZE) {
788         return;
789     }
790     jscolorfilter->SetColorFilterMatrix(std::move(colorfilter));
791     jscolorfilter->IncRefCount();
792     args.SetReturnValue(Referenced::RawPtr(jscolorfilter));
793 }
794 
DestructorCallback(JSColorFilter * obj)795 void JSColorFilter::DestructorCallback(JSColorFilter* obj)
796 {
797     if (obj != nullptr) {
798         obj->DecRefCount();
799     }
800 }
801 
SetColorFilter(const JSCallbackInfo & info)802 void JSImage::SetColorFilter(const JSCallbackInfo& info)
803 {
804     if (info.Length() != 1) {
805         ImageModel::GetInstance()->SetColorFilterMatrix(DEFAULT_COLORFILTER_MATRIX);
806         return;
807     }
808     auto tmpInfo = info[0];
809     if (!tmpInfo->IsArray() && !tmpInfo->IsObject()) {
810         ImageModel::GetInstance()->SetColorFilterMatrix(DEFAULT_COLORFILTER_MATRIX);
811         return;
812     }
813     if (tmpInfo->IsObject() && !tmpInfo->IsArray()) {
814         auto drawingColorFilter = CreateDrawingColorFilter(tmpInfo);
815         if (drawingColorFilter) {
816             ImageModel::GetInstance()->SetDrawingColorFilter(drawingColorFilter);
817             return;
818         }
819         JSColorFilter* colorFilter;
820         if (!tmpInfo->IsUndefined() && !tmpInfo->IsNull()) {
821             colorFilter = JSRef<JSObject>::Cast(tmpInfo)->Unwrap<JSColorFilter>();
822         } else {
823             ImageModel::GetInstance()->SetColorFilterMatrix(DEFAULT_COLORFILTER_MATRIX);
824             return;
825         }
826         if (colorFilter && colorFilter->GetColorFilterMatrix().size() == COLOR_FILTER_MATRIX_SIZE) {
827             ImageModel::GetInstance()->SetColorFilterMatrix(colorFilter->GetColorFilterMatrix());
828             return;
829         }
830         ImageModel::GetInstance()->SetColorFilterMatrix(DEFAULT_COLORFILTER_MATRIX);
831         return;
832     }
833     JSRef<JSArray> array = JSRef<JSArray>::Cast(tmpInfo);
834     if (array->Length() != COLOR_FILTER_MATRIX_SIZE) {
835         ImageModel::GetInstance()->SetColorFilterMatrix(DEFAULT_COLORFILTER_MATRIX);
836         return;
837     }
838     std::vector<float> colorfilter;
839     for (size_t i = 0; i < array->Length(); i++) {
840         JSRef<JSVal> value = array->GetValueAt(i);
841         if (value->IsNumber()) {
842             colorfilter.emplace_back(value->ToNumber<float>());
843         } else {
844             ImageModel::GetInstance()->SetColorFilterMatrix(DEFAULT_COLORFILTER_MATRIX);
845             return;
846         }
847     }
848     ImageModel::GetInstance()->SetColorFilterMatrix(colorfilter);
849 }
850 
SetSmoothEdge(const JSCallbackInfo & info)851 void JSImage::SetSmoothEdge(const JSCallbackInfo& info)
852 {
853     if (info.Length() != 1) {
854         ImageModel::GetInstance()->SetSmoothEdge(DEFAULT_SMOOTHEDGE_VALUE);
855         return;
856     }
857     double parseRes = DEFAULT_SMOOTHEDGE_VALUE;
858     ParseJsDouble(info[0], parseRes);
859     // Effective range : (FLOOR_SMOOTHEDGE_VALUE, CEIL_SMOOTHEDGE_VALUE]
860     // otherwise: DEFAULT_SMOOTHEDGE_VALUE
861     if (GreatNotEqual(parseRes, CEIL_SMOOTHEDGE_VALUE) || LessNotEqual(parseRes, FLOOR_SMOOTHEDGE_VALUE)) {
862         parseRes = DEFAULT_SMOOTHEDGE_VALUE;
863     }
864     ImageModel::GetInstance()->SetSmoothEdge(static_cast<float>(parseRes));
865 }
866 
SetDynamicRangeMode(const JSCallbackInfo & info)867 void JSImage::SetDynamicRangeMode(const JSCallbackInfo& info)
868 {
869     if (info.Length() < 1) {
870         ImageModel::GetInstance()->SetDynamicRangeMode(DynamicRangeMode::STANDARD);
871         return;
872     }
873     int32_t parseRes = static_cast<int32_t>(DynamicRangeMode::STANDARD);
874     ParseJsInteger(info[0], parseRes);
875     if (parseRes < static_cast<int32_t>(DynamicRangeMode::HIGH) ||
876         parseRes > static_cast<int32_t>(DynamicRangeMode::STANDARD)) {
877         parseRes = static_cast<int32_t>(DynamicRangeMode::STANDARD);
878     }
879     DynamicRangeMode dynamicRangeMode = static_cast<DynamicRangeMode>(parseRes);
880     ImageModel::GetInstance()->SetDynamicRangeMode(dynamicRangeMode);
881 }
882 
SetEnhancedImageQuality(const JSCallbackInfo & info)883 void JSImage::SetEnhancedImageQuality(const JSCallbackInfo& info)
884 {
885     if (info.Length() < 1) {
886         ImageModel::GetInstance()->SetEnhancedImageQuality(AIImageQuality::LOW);
887         return;
888     }
889     int32_t parseRes = static_cast<int32_t>(AIImageQuality::LOW);
890     ParseJsInteger(info[0], parseRes);
891     if (parseRes < static_cast<int32_t>(AIImageQuality::LOW) || parseRes > static_cast<int32_t>(AIImageQuality::HIGH)) {
892         parseRes = static_cast<int32_t>(AIImageQuality::LOW);
893     }
894     AIImageQuality resolutionQuality = static_cast<AIImageQuality>(parseRes);
895     ImageModel::GetInstance()->SetEnhancedImageQuality(resolutionQuality);
896 }
897 
SetOrientation(const JSCallbackInfo & info)898 void JSImage::SetOrientation(const JSCallbackInfo& info)
899 {
900     if (info.Length() < 1) {
901         ImageModel::GetInstance()->SetOrientation(ImageRotateOrientation::UP);
902         return;
903     }
904     int32_t parseRes = 0;
905     ParseJsInteger(info[0], parseRes);
906     if (parseRes < static_cast<int>(ImageRotateOrientation::AUTO) ||
907         parseRes > static_cast<int>(ImageRotateOrientation::LEFT)) {
908         parseRes = static_cast<int>(ImageRotateOrientation::UP);
909     }
910     auto res = static_cast<ImageRotateOrientation>(parseRes);
911     ImageModel::GetInstance()->SetOrientation(res);
912 }
913 
CreateImageAnimation(std::vector<RefPtr<PixelMap>> & pixelMaps,int32_t duration,int32_t iterations)914 void JSImage::CreateImageAnimation(std::vector<RefPtr<PixelMap>>& pixelMaps, int32_t duration, int32_t iterations)
915 {
916     std::vector<ImageProperties> imageList;
917     for (int i = 0; i < static_cast<int32_t>(pixelMaps.size()); i++) {
918         ImageProperties image;
919         image.pixelMap = pixelMaps[i];
920         imageList.push_back(image);
921     }
922     ImageModel::GetInstance()->CreateAnimation(imageList, duration, iterations);
923 }
924 
JSBind(BindingTarget globalObj)925 void JSImage::JSBind(BindingTarget globalObj)
926 {
927     JSClass<JSImage>::Declare("Image");
928     MethodOptions opt = MethodOptions::NONE;
929     JSClass<JSImage>::StaticMethod("create", &JSImage::Create, opt);
930     JSClass<JSImage>::StaticMethod("alt", &JSImage::SetAlt, opt);
931     JSClass<JSImage>::StaticMethod("objectFit", &JSImage::SetObjectFit, opt);
932     JSClass<JSImage>::StaticMethod("imageMatrix", &JSImage::SetImageMatrix, opt);
933     JSClass<JSImage>::StaticMethod("matchTextDirection", &JSImage::SetMatchTextDirection, opt);
934     JSClass<JSImage>::StaticMethod("fitOriginalSize", &JSImage::SetFitOriginalSize, opt);
935     JSClass<JSImage>::StaticMethod("sourceSize", &JSImage::SetSourceSize, opt);
936     JSClass<JSImage>::StaticMethod("fillColor", &JSImage::SetImageFill, opt);
937     JSClass<JSImage>::StaticMethod("renderMode", &JSImage::SetImageRenderMode, opt);
938     JSClass<JSImage>::StaticMethod("objectRepeat", &JSImage::SetImageRepeat, opt);
939     JSClass<JSImage>::StaticMethod("interpolation", &JSImage::SetImageInterpolation, opt);
940     JSClass<JSImage>::StaticMethod("colorFilter", &JSImage::SetColorFilter, opt);
941     JSClass<JSImage>::StaticMethod("edgeAntialiasing", &JSImage::SetSmoothEdge, opt);
942     JSClass<JSImage>::StaticMethod("dynamicRangeMode", &JSImage::SetDynamicRangeMode, opt);
943     JSClass<JSImage>::StaticMethod("enhancedImageQuality", &JSImage::SetEnhancedImageQuality, opt);
944     JSClass<JSImage>::StaticMethod("orientation", &JSImage::SetOrientation, opt);
945 
946     JSClass<JSImage>::StaticMethod("border", &JSImage::JsBorder);
947     JSClass<JSImage>::StaticMethod("borderRadius", &JSImage::JsBorderRadius);
948     JSClass<JSImage>::StaticMethod("onAttach", &JSInteractableView::JsOnAttach);
949     JSClass<JSImage>::StaticMethod("onAppear", &JSInteractableView::JsOnAppear);
950     JSClass<JSImage>::StaticMethod("onDetach", &JSInteractableView::JsOnDetach);
951     JSClass<JSImage>::StaticMethod("onDisAppear", &JSInteractableView::JsOnDisAppear);
952     JSClass<JSImage>::StaticMethod("autoResize", &JSImage::SetAutoResize);
953     JSClass<JSImage>::StaticMethod("resizable", &JSImage::JsImageResizable);
954 
955     JSClass<JSImage>::StaticMethod("onTouch", &JSInteractableView::JsOnTouch);
956     JSClass<JSImage>::StaticMethod("onHover", &JSInteractableView::JsOnHover);
957     JSClass<JSImage>::StaticMethod("onKeyEvent", &JSInteractableView::JsOnKey);
958     JSClass<JSImage>::StaticMethod("onDeleteEvent", &JSInteractableView::JsOnDelete);
959     JSClass<JSImage>::StaticMethod("onClick", &JSInteractableView::JsOnClick);
960     JSClass<JSImage>::StaticMethod("onComplete", &JSImage::OnComplete);
961     JSClass<JSImage>::StaticMethod("onError", &JSImage::OnError);
962     JSClass<JSImage>::StaticMethod("onFinish", &JSImage::OnFinish);
963     JSClass<JSImage>::StaticMethod("syncLoad", &JSImage::SetSyncLoad);
964     JSClass<JSImage>::StaticMethod("remoteMessage", &JSInteractableView::JsCommonRemoteMessage);
965     JSClass<JSImage>::StaticMethod("draggable", &JSImage::JsSetDraggable);
966     JSClass<JSImage>::StaticMethod("onDragStart", &JSImage::JsOnDragStart);
967     JSClass<JSImage>::StaticMethod("copyOption", &JSImage::SetCopyOption);
968     JSClass<JSImage>::StaticMethod("enableAnalyzer", &JSImage::EnableAnalyzer);
969     JSClass<JSImage>::StaticMethod("analyzerConfig", &JSImage::AnalyzerConfig);
970 
971     // override method
972     JSClass<JSImage>::StaticMethod("opacity", &JSImage::JsOpacity);
973     JSClass<JSImage>::StaticMethod("blur", &JSImage::JsBlur);
974     JSClass<JSImage>::StaticMethod("transition", &JSImage::JsTransition);
975     JSClass<JSImage>::StaticMethod("pointLight", &JSViewAbstract::JsPointLight, opt);
976     JSClass<JSImage>::InheritAndBind<JSViewAbstract>(globalObj);
977 
978     JSClass<JSColorFilter>::Declare("ColorFilter");
979     JSClass<JSColorFilter>::Bind(globalObj, JSColorFilter::ConstructorCallback, JSColorFilter::DestructorCallback);
980 }
981 
JsSetDraggable(const JSCallbackInfo & info)982 void JSImage::JsSetDraggable(const JSCallbackInfo& info)
983 {
984     bool draggable = Container::GreatOrEqualAPITargetVersion(PlatformVersion::VERSION_TWENTY);
985     if (info.Length() > 0 && info[0]->IsBoolean()) {
986         draggable = info[0]->ToBoolean();
987     }
988     ImageModel::GetInstance()->SetDraggable(draggable);
989 }
990 
JsOnDragStart(const JSCallbackInfo & info)991 void JSImage::JsOnDragStart(const JSCallbackInfo& info)
992 {
993     if (!Container::LessThanAPITargetVersion(PlatformVersion::VERSION_FIFTEEN)) {
994         JSViewAbstract::JsOnDragStart(info);
995         return;
996     }
997     if (info.Length() != 1 || !info[0]->IsFunction()) {
998         return;
999     }
1000     RefPtr<JsDragFunction> jsOnDragStartFunc = AceType::MakeRefPtr<JsDragFunction>(JSRef<JSFunc>::Cast(info[0]));
1001     WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
1002     auto onDragStartId = [execCtx = info.GetExecutionContext(), func = std::move(jsOnDragStartFunc), node = frameNode](
1003                              const RefPtr<DragEvent>& info, const std::string& extraParams) -> NG::DragDropBaseInfo {
1004         NG::DragDropBaseInfo itemInfo;
1005         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx, itemInfo);
1006         PipelineContext::SetCallBackNode(node);
1007         auto ret = func->Execute(info, extraParams);
1008         if (!ret->IsObject()) {
1009             return itemInfo;
1010         }
1011         if (ParseAndUpdateDragItemInfo(ret, itemInfo)) {
1012             return itemInfo;
1013         }
1014 
1015         auto builderObj = JSRef<JSObject>::Cast(ret);
1016 #if defined(PIXEL_MAP_SUPPORTED)
1017         auto pixmap = builderObj->GetProperty("pixelMap");
1018         itemInfo.pixelMap = CreatePixelMapFromNapiValue(pixmap);
1019 #endif
1020         auto extraInfo = builderObj->GetProperty("extraInfo");
1021         ParseJsString(extraInfo, itemInfo.extraInfo);
1022         ParseAndUpdateDragItemInfo(builderObj->GetProperty("builder"), itemInfo);
1023         return itemInfo;
1024     };
1025     ImageModel::GetInstance()->SetOnDragStart(std::move(onDragStartId));
1026 }
1027 
SetCopyOption(const JSCallbackInfo & info)1028 void JSImage::SetCopyOption(const JSCallbackInfo& info)
1029 {
1030     if (ImageModel::GetInstance()->GetIsAnimation()) {
1031         return;
1032     }
1033     auto copyOptions = CopyOptions::None;
1034     if (info[0]->IsNumber()) {
1035         auto enumNumber = info[0]->ToNumber<int>();
1036         copyOptions = static_cast<CopyOptions>(enumNumber);
1037         if (copyOptions < CopyOptions::None || copyOptions > CopyOptions::Distributed) {
1038             copyOptions = CopyOptions::None;
1039         }
1040     }
1041     ImageModel::GetInstance()->SetCopyOption(copyOptions);
1042 }
1043 
EnableAnalyzer(bool isEnableAnalyzer)1044 void JSImage::EnableAnalyzer(bool isEnableAnalyzer)
1045 {
1046     if (ImageModel::GetInstance()->GetIsAnimation()) {
1047         return;
1048     }
1049     ImageModel::GetInstance()->EnableAnalyzer(isEnableAnalyzer);
1050 }
1051 
AnalyzerConfig(const JSCallbackInfo & info)1052 void JSImage::AnalyzerConfig(const JSCallbackInfo& info)
1053 {
1054     auto configParams = info[0];
1055     if (configParams->IsNull() || !configParams->IsObject()) {
1056         return;
1057     }
1058     auto engine = EngineHelper::GetCurrentEngine();
1059     CHECK_NULL_VOID(engine);
1060     NativeEngine* nativeEngine = engine->GetNativeEngine();
1061     CHECK_NULL_VOID(nativeEngine);
1062     panda::Local<JsiValue> value = configParams.Get().GetLocalHandle();
1063     JSValueWrapper valueWrapper = value;
1064     ScopeRAII scope(reinterpret_cast<napi_env>(nativeEngine));
1065     napi_value nativeValue = nativeEngine->ValueToNapiValue(valueWrapper);
1066     ImageModel::GetInstance()->SetImageAnalyzerConfig(nativeValue);
1067 
1068     // As an example, the function is not in effect.
1069     auto paramObject = JSRef<JSObject>::Cast(configParams);
1070     JSRef<JSVal> typeVal = paramObject->GetProperty("types");
1071     ImageAnalyzerConfig analyzerConfig;
1072     if (typeVal->IsArray()) {
1073         auto array = JSRef<JSArray>::Cast(typeVal);
1074         std::set<ImageAnalyzerType> types;
1075         for (size_t i = 0; i < array->Length(); ++i) {
1076             if (!array->GetValueAt(i)->IsNumber()) {
1077                 continue;
1078             }
1079             int value = array->GetValueAt(i)->ToNumber<int>();
1080             ImageAnalyzerType type = static_cast<ImageAnalyzerType>(value);
1081             if (type != ImageAnalyzerType::SUBJECT && type != ImageAnalyzerType::TEXT) {
1082                 continue;
1083             }
1084             types.insert(type);
1085         }
1086         analyzerConfig.types = std::move(types);
1087     }
1088     ImageModel::GetInstance()->SetImageAnalyzerConfig(analyzerConfig);
1089 }
1090 
1091 } // namespace OHOS::Ace::Framework
1092