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 #include "bridge/declarative_frontend/engine/jsi/nativeModule/arkts_native_image_span_bridge.h"
16 
17 #include "bridge/declarative_frontend/engine/jsi/nativeModule/arkts_utils.h"
18 
19 #include "base/image/pixel_map.h"
20 #include "bridge/declarative_frontend/jsview/js_image.h"
21 #include "bridge/declarative_frontend/jsview/js_utils.h"
22 #include "core/components_ng/pattern/image/image_model_ng.h"
23 #include "core/components_ng/pattern/text/image_span_view.h"
24 
25 namespace OHOS::Ace::NG {
26 namespace {
27 constexpr int NUM_0 = 0;
28 constexpr int NUM_1 = 1;
29 constexpr int NUM_2 = 2;
30 constexpr int NUM_3 = 3;
31 constexpr int NUM_4 = 4;
32 constexpr int SIZE_OF_FOUR = 4;
33 const std::vector<float> DEFAULT_COLOR_FILTER_MATRIX = {
34     1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f,
35     0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f
36 };
37 
ParseOuterBorderRadius(ArkUIRuntimeCallInfo * runtimeCallInfo,EcmaVM * vm,std::vector<ArkUI_Float32> & values,std::vector<ArkUI_Int32> & units,int32_t argsIndex)38 void ParseOuterBorderRadius(ArkUIRuntimeCallInfo* runtimeCallInfo, EcmaVM* vm, std::vector<ArkUI_Float32>& values,
39     std::vector<ArkUI_Int32>& units, int32_t argsIndex)
40 {
41     Local<JSValueRef> topLeftArgs = runtimeCallInfo->GetCallArgRef(argsIndex);
42     Local<JSValueRef> topRightArgs = runtimeCallInfo->GetCallArgRef(argsIndex + NUM_1);
43     Local<JSValueRef> bottomLeftArgs = runtimeCallInfo->GetCallArgRef(argsIndex + NUM_2);
44     Local<JSValueRef> bottomRightArgs = runtimeCallInfo->GetCallArgRef(argsIndex + NUM_3);
45 
46     std::optional<CalcDimension> topLeftOptional;
47     std::optional<CalcDimension> topRightOptional;
48     std::optional<CalcDimension> bottomLeftOptional;
49     std::optional<CalcDimension> bottomRightOptional;
50 
51     ArkTSUtils::ParseOuterBorder(vm, topLeftArgs, topLeftOptional);
52     ArkTSUtils::ParseOuterBorder(vm, topRightArgs, topRightOptional);
53     ArkTSUtils::ParseOuterBorder(vm, bottomLeftArgs, bottomLeftOptional);
54     ArkTSUtils::ParseOuterBorder(vm, bottomRightArgs, bottomRightOptional);
55 
56     ArkTSUtils::PushOuterBorderDimensionVector(topLeftOptional, values, units);
57     ArkTSUtils::PushOuterBorderDimensionVector(topRightOptional, values, units);
58     ArkTSUtils::PushOuterBorderDimensionVector(bottomLeftOptional, values, units);
59     ArkTSUtils::PushOuterBorderDimensionVector(bottomRightOptional, values, units);
60 }
61 } // namespace
62 
SetVerticalAlign(ArkUIRuntimeCallInfo * runtimeCallInfo)63 ArkUINativeModuleValue ImageSpanBridge::SetVerticalAlign(ArkUIRuntimeCallInfo* runtimeCallInfo)
64 {
65     EcmaVM* vm = runtimeCallInfo->GetVM();
66     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
67     Local<JSValueRef> node = runtimeCallInfo->GetCallArgRef(0);
68     Local<JSValueRef> verticalAlign = runtimeCallInfo->GetCallArgRef(1);
69     auto nativeNode = nodePtr(node->ToNativePointer(vm)->Value());
70     int32_t value = static_cast<int32_t>(VerticalAlign::BOTTOM);
71     if (verticalAlign->IsNumber()) {
72         value = verticalAlign->Int32Value(vm);
73         auto align = static_cast<VerticalAlign>(value);
74         if (align < VerticalAlign::TOP || align > VerticalAlign::NONE) {
75             align = VerticalAlign::BOTTOM;
76         }
77         value = static_cast<int32_t>(align);
78     }
79     GetArkUINodeModifiers()->getImageSpanModifier()->setImageSpanVerticalAlign(nativeNode, value);
80     return panda::JSValueRef::Undefined(vm);
81 }
82 
ResetVerticalAlign(ArkUIRuntimeCallInfo * runtimeCallInfo)83 ArkUINativeModuleValue ImageSpanBridge::ResetVerticalAlign(ArkUIRuntimeCallInfo* runtimeCallInfo)
84 {
85     EcmaVM* vm = runtimeCallInfo->GetVM();
86     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
87     Local<JSValueRef> node = runtimeCallInfo->GetCallArgRef(0);
88     auto nativeNode = nodePtr(node->ToNativePointer(vm)->Value());
89     GetArkUINodeModifiers()->getImageSpanModifier()->resetImageSpanVerticalAlign(nativeNode);
90     return panda::JSValueRef::Undefined(vm);
91 }
92 
SetObjectFit(ArkUIRuntimeCallInfo * runtimeCallInfo)93 ArkUINativeModuleValue ImageSpanBridge::SetObjectFit(ArkUIRuntimeCallInfo* runtimeCallInfo)
94 {
95     EcmaVM* vm = runtimeCallInfo->GetVM();
96     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
97     Local<JSValueRef> node = runtimeCallInfo->GetCallArgRef(0);
98     Local<JSValueRef> objectFit = runtimeCallInfo->GetCallArgRef(1);
99     auto nativeNode = nodePtr(node->ToNativePointer(vm)->Value());
100     int32_t value = static_cast<int32_t>(ImageFit::COVER);
101     if (objectFit->IsNumber()) {
102         value = objectFit->Int32Value(vm);
103         auto fit = static_cast<ImageFit>(value);
104         if (fit < ImageFit::FILL || fit > ImageFit::SCALE_DOWN) {
105             fit = ImageFit::COVER;
106         }
107         value = static_cast<int32_t>(fit);
108     }
109     GetArkUINodeModifiers()->getImageSpanModifier()->setImageSpanObjectFit(nativeNode, value);
110     return panda::JSValueRef::Undefined(vm);
111 }
112 
ResetObjectFit(ArkUIRuntimeCallInfo * runtimeCallInfo)113 ArkUINativeModuleValue ImageSpanBridge::ResetObjectFit(ArkUIRuntimeCallInfo* runtimeCallInfo)
114 {
115     EcmaVM* vm = runtimeCallInfo->GetVM();
116     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
117     Local<JSValueRef> node = runtimeCallInfo->GetCallArgRef(0);
118     auto nativeNode = nodePtr(node->ToNativePointer(vm)->Value());
119     GetArkUINodeModifiers()->getImageSpanModifier()->resetImageSpanObjectFit(nativeNode);
120     return panda::JSValueRef::Undefined(vm);
121 }
122 
SetTextBackgroundStyle(ArkUIRuntimeCallInfo * runtimeCallInfo)123 ArkUINativeModuleValue ImageSpanBridge::SetTextBackgroundStyle(ArkUIRuntimeCallInfo* runtimeCallInfo)
124 {
125     EcmaVM* vm = runtimeCallInfo->GetVM();
126     Color color;
127     std::vector<ArkUI_Float32> radiusArray;
128     std::vector<ArkUI_Int32> valueUnits;
129     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(NUM_0);
130     Local<JSValueRef> secondArg = runtimeCallInfo->GetCallArgRef(NUM_1);
131     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
132     if (!ArkTSUtils::ParseJsColorAlpha(vm, secondArg, color)) {
133         color = Color::TRANSPARENT;
134     }
135     ParseOuterBorderRadius(runtimeCallInfo, vm, radiusArray, valueUnits, NUM_2); // Border Radius args start index
136     GetArkUINodeModifiers()->getImageSpanModifier()->setImageSpanTextBackgroundStyle(
137         nativeNode, color.GetValue(), radiusArray.data(), valueUnits.data(), static_cast<int32_t>(radiusArray.size()));
138     return panda::JSValueRef::Undefined(vm);
139 }
140 
ResetTextBackgroundStyle(ArkUIRuntimeCallInfo * runtimeCallInfo)141 ArkUINativeModuleValue ImageSpanBridge::ResetTextBackgroundStyle(ArkUIRuntimeCallInfo* runtimeCallInfo)
142 {
143     EcmaVM* vm = runtimeCallInfo->GetVM();
144     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(NUM_0);
145     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
146     GetArkUINodeModifiers()->getImageSpanModifier()->resetImageSpanTextBackgroundStyle(nativeNode);
147     return panda::JSValueRef::Undefined(vm);
148 }
149 
SetBaselineOffset(ArkUIRuntimeCallInfo * runtimeCallInfo)150 ArkUINativeModuleValue ImageSpanBridge::SetBaselineOffset(ArkUIRuntimeCallInfo *runtimeCallInfo)
151 {
152     EcmaVM *vm = runtimeCallInfo->GetVM();
153     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
154     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(NUM_0);
155     Local<JSValueRef> secondArg = runtimeCallInfo->GetCallArgRef(NUM_1);
156     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
157     CalcDimension result;
158     if (secondArg->IsObject(vm) && ArkTSUtils::ParseJsLengthMetrics(vm, secondArg, result) &&
159         result.Unit() != DimensionUnit::PERCENT && !std::isnan(result.Value())) {
160         GetArkUINodeModifiers()->getImageSpanModifier()->setImageSpanBaselineOffset(
161             nativeNode, result.Value(), static_cast<int8_t>(result.Unit()));
162     } else {
163         GetArkUINodeModifiers()->getImageSpanModifier()->resetImageSpanBaselineOffset(nativeNode);
164     }
165     return panda::JSValueRef::Undefined(vm);
166 }
167 
ResetBaselineOffset(ArkUIRuntimeCallInfo * runtimeCallInfo)168 ArkUINativeModuleValue ImageSpanBridge::ResetBaselineOffset(ArkUIRuntimeCallInfo* runtimeCallInfo)
169 {
170     EcmaVM* vm = runtimeCallInfo->GetVM();
171     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
172     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(NUM_0);
173     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
174     GetArkUINodeModifiers()->getImageSpanModifier()->resetImageSpanBaselineOffset(nativeNode);
175     return panda::JSValueRef::Undefined(vm);
176 }
177 
SetAlt(ArkUIRuntimeCallInfo * runtimeCallInfo)178 ArkUINativeModuleValue ImageSpanBridge::SetAlt(ArkUIRuntimeCallInfo *runtimeCallInfo)
179 {
180     EcmaVM* vm = runtimeCallInfo->GetVM();
181     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
182     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
183     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
184     Framework::JsiCallbackInfo info = Framework::JsiCallbackInfo(runtimeCallInfo);
185     RefPtr<PixelMap> pixmap = nullptr;
186 #if defined (PIXEL_MAP_SUPPORTED)
187     pixmap = Framework::CreatePixelMapFromNapiValue(info[1]);
188 #endif
189     if (pixmap) {
190         ImageSpanView::SetAlt(reinterpret_cast<FrameNode*>(nativeNode), pixmap);
191     }
192     return panda::JSValueRef::Undefined(vm);
193 }
194 
ResetAlt(ArkUIRuntimeCallInfo * runtimeCallInfo)195 ArkUINativeModuleValue ImageSpanBridge::ResetAlt(ArkUIRuntimeCallInfo* runtimeCallInfo)
196 {
197     EcmaVM* vm = runtimeCallInfo->GetVM();
198     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
199     return panda::JSValueRef::Undefined(vm);
200 }
201 
SetOnComplete(ArkUIRuntimeCallInfo * runtimeCallInfo)202 ArkUINativeModuleValue ImageSpanBridge::SetOnComplete(ArkUIRuntimeCallInfo *runtimeCallInfo)
203 {
204     EcmaVM *vm = runtimeCallInfo->GetVM();
205     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
206     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
207     Local<JSValueRef> callbackArg = runtimeCallInfo->GetCallArgRef(1);
208     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
209     auto frameNode = reinterpret_cast<FrameNode*>(nativeNode);
210     CHECK_NULL_RETURN(frameNode, panda::NativePointerRef::New(vm, nullptr));
211     if (callbackArg->IsUndefined() || callbackArg->IsNull() || !callbackArg->IsFunction(vm)) {
212         GetArkUINodeModifiers()->getImageSpanModifier()->resetImageSpanOnComplete(nativeNode);
213         return panda::JSValueRef::Undefined(vm);
214     }
215     panda::Local<panda::FunctionRef> func = callbackArg->ToObject(vm);
216     std::function<void(LoadImageSuccessEvent&)> callback = [vm, frameNode,
217         func = panda::CopyableGlobal(vm, func)](LoadImageSuccessEvent& event) {
218         panda::LocalScope pandaScope(vm);
219         panda::TryCatch trycatch(vm);
220         PipelineContext::SetCallBackNode(AceType::WeakClaim(frameNode));
221         const char* keys[] = { "width", "height", "componentWidth", "componentHeight", "loadingStatus", "contentWidth",
222             "contentHeight", "contentOffsetX", "contentOffsetY" };
223         Local<JSValueRef> values[] = { panda::NumberRef::New(vm, event.GetWidth()),
224             panda::NumberRef::New(vm, event.GetHeight()), panda::NumberRef::New(vm, event.GetComponentWidth()),
225             panda::NumberRef::New(vm, event.GetComponentHeight()), panda::NumberRef::New(vm, event.GetLoadingStatus()),
226             panda::NumberRef::New(vm, event.GetContentWidth()), panda::NumberRef::New(vm, event.GetContentHeight()),
227             panda::NumberRef::New(vm, event.GetContentOffsetX()),
228             panda::NumberRef::New(vm, event.GetContentOffsetY()) };
229         auto eventObject = panda::ObjectRef::NewWithNamedProperties(vm, ArraySize(keys), keys, values);
230         eventObject->SetNativePointerFieldCount(vm, 1);
231         eventObject->SetNativePointerField(vm, 0, static_cast<void*>(&event));
232         panda::Local<panda::JSValueRef> params[1] = { eventObject };
233         func->Call(vm, func.ToLocal(), params, 1);
234     };
235     GetArkUINodeModifiers()->getImageSpanModifier()->setImageSpanOnComplete(
236         nativeNode, reinterpret_cast<void*>(&callback));
237     return panda::JSValueRef::Undefined(vm);
238 }
239 
ResetOnComplete(ArkUIRuntimeCallInfo * runtimeCallInfo)240 ArkUINativeModuleValue ImageSpanBridge::ResetOnComplete(ArkUIRuntimeCallInfo* runtimeCallInfo)
241 {
242     EcmaVM* vm = runtimeCallInfo->GetVM();
243     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
244     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
245     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
246     GetArkUINodeModifiers()->getImageSpanModifier()->resetImageSpanOnComplete(nativeNode);
247     return panda::JSValueRef::Undefined(vm);
248 }
249 
SetOnError(ArkUIRuntimeCallInfo * runtimeCallInfo)250 ArkUINativeModuleValue ImageSpanBridge::SetOnError(ArkUIRuntimeCallInfo *runtimeCallInfo)
251 {
252     EcmaVM *vm = runtimeCallInfo->GetVM();
253     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
254     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
255     Local<JSValueRef> callbackArg = runtimeCallInfo->GetCallArgRef(1);
256     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
257     auto frameNode = reinterpret_cast<FrameNode*>(nativeNode);
258     CHECK_NULL_RETURN(frameNode, panda::NativePointerRef::New(vm, nullptr));
259     if (callbackArg->IsUndefined() || callbackArg->IsNull() || !callbackArg->IsFunction(vm)) {
260         GetArkUINodeModifiers()->getImageSpanModifier()->resetImageSpanOnError(nativeNode);
261         return panda::JSValueRef::Undefined(vm);
262     }
263     panda::Local<panda::FunctionRef> func = callbackArg->ToObject(vm);
264     std::function<void(LoadImageFailEvent&)> callback = [vm, frameNode,
265         func = panda::CopyableGlobal(vm, func)](LoadImageFailEvent& event) {
266         panda::LocalScope pandaScope(vm);
267         panda::TryCatch trycatch(vm);
268         PipelineContext::SetCallBackNode(AceType::WeakClaim(frameNode));
269         const char* keys[] = { "componentWidth", "componentHeight", "message" };
270         Local<JSValueRef> values[] = { panda::NumberRef::New(vm, event.GetComponentWidth()),
271             panda::NumberRef::New(vm, event.GetComponentHeight()),
272             panda::StringRef::NewFromUtf8(vm, event.GetErrorMessage().c_str()) };
273         auto eventObject = panda::ObjectRef::NewWithNamedProperties(vm, ArraySize(keys), keys, values);
274         eventObject->SetNativePointerFieldCount(vm, 1);
275         eventObject->SetNativePointerField(vm, 0, static_cast<void*>(&event));
276         panda::Local<panda::JSValueRef> params[1] = { eventObject };
277         func->Call(vm, func.ToLocal(), params, 1);
278     };
279     GetArkUINodeModifiers()->getImageSpanModifier()->setImageSpanOnError(
280         nativeNode, reinterpret_cast<void*>(&callback));
281     return panda::JSValueRef::Undefined(vm);
282 }
283 
ResetOnError(ArkUIRuntimeCallInfo * runtimeCallInfo)284 ArkUINativeModuleValue ImageSpanBridge::ResetOnError(ArkUIRuntimeCallInfo* runtimeCallInfo)
285 {
286     EcmaVM* vm = runtimeCallInfo->GetVM();
287     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
288     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
289     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
290     GetArkUINodeModifiers()->getImageSpanModifier()->resetImageSpanOnError(nativeNode);
291     return panda::JSValueRef::Undefined(vm);
292 }
293 
SetSpanColorFilterObject(const EcmaVM * vm,const Local<JSValueRef> & jsObjArg,ArkUINodeHandle nativeNode)294 void SetSpanColorFilterObject(const EcmaVM* vm, const Local<JSValueRef>& jsObjArg, ArkUINodeHandle nativeNode)
295 {
296     Framework::JSColorFilter* colorFilter;
297     if (!jsObjArg->IsUndefined() && !jsObjArg->IsNull()) {
298         colorFilter = static_cast<Framework::JSColorFilter*>(jsObjArg->ToObject(vm)->GetNativePointerField(vm, 0));
299     } else {
300         GetArkUINodeModifiers()->getImageSpanModifier()->setImageSpanColorFilter(
301             nativeNode, &(*DEFAULT_COLOR_FILTER_MATRIX.begin()), COLOR_FILTER_MATRIX_SIZE);
302         return;
303     }
304     if (colorFilter && colorFilter->GetColorFilterMatrix().size() == COLOR_FILTER_MATRIX_SIZE) {
305         GetArkUINodeModifiers()->getImageSpanModifier()->setImageSpanColorFilter(
306             nativeNode, &(*colorFilter->GetColorFilterMatrix().begin()), COLOR_FILTER_MATRIX_SIZE);
307         return;
308     }
309     GetArkUINodeModifiers()->getImageSpanModifier()->setImageSpanColorFilter(
310         nativeNode, &(*DEFAULT_COLOR_FILTER_MATRIX.begin()), COLOR_FILTER_MATRIX_SIZE);
311 }
312 
SetColorFilter(ArkUIRuntimeCallInfo * runtimeCallInfo)313 ArkUINativeModuleValue ImageSpanBridge::SetColorFilter(ArkUIRuntimeCallInfo* runtimeCallInfo)
314 {
315     EcmaVM* vm = runtimeCallInfo->GetVM();
316     CHECK_NULL_RETURN(vm, panda::JSValueRef::Undefined(vm));
317     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
318     Local<JSValueRef> jsObjArg = runtimeCallInfo->GetCallArgRef(1);
319     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
320     Framework::JsiCallbackInfo info = Framework::JsiCallbackInfo(runtimeCallInfo);
321     if (!jsObjArg->IsArray(vm) && !jsObjArg->IsObject(vm)) {
322         GetArkUINodeModifiers()->getImageSpanModifier()->setImageSpanColorFilter(
323             nativeNode, &(*DEFAULT_COLOR_FILTER_MATRIX.begin()), COLOR_FILTER_MATRIX_SIZE);
324         return panda::JSValueRef::Undefined(vm);
325     }
326     if (jsObjArg->IsObject(vm) && !jsObjArg->IsArray(vm)) {
327         auto drawingColorFilter = Ace::Framework::CreateDrawingColorFilter(info[1]);
328         if (drawingColorFilter) {
329             ImageModelNG::SetDrawingColorFilter(reinterpret_cast<FrameNode*>(nativeNode), drawingColorFilter);
330             return panda::JSValueRef::Undefined(vm);
331         }
332         SetSpanColorFilterObject(vm, jsObjArg, nativeNode);
333         return panda::JSValueRef::Undefined(vm);
334     }
335     auto array = panda::CopyableGlobal<panda::ArrayRef>(vm, jsObjArg);
336     if (array->Length(vm) != COLOR_FILTER_MATRIX_SIZE) {
337         GetArkUINodeModifiers()->getImageSpanModifier()->setImageSpanColorFilter(
338             nativeNode, &(*DEFAULT_COLOR_FILTER_MATRIX.begin()), COLOR_FILTER_MATRIX_SIZE);
339         return panda::JSValueRef::Undefined(vm);
340     }
341     std::vector<float> colorFilter;
342     for (size_t i = 0; i < array->Length(vm); i++) {
343         auto value = array->GetValueAt(vm, jsObjArg, i);
344         if (value->IsNumber()) {
345             colorFilter.emplace_back(value->ToNumber(vm)->Value());
346         } else {
347             GetArkUINodeModifiers()->getImageSpanModifier()->setImageSpanColorFilter(
348                 nativeNode, &(*DEFAULT_COLOR_FILTER_MATRIX.begin()), COLOR_FILTER_MATRIX_SIZE);
349             return panda::JSValueRef::Undefined(vm);
350         }
351     }
352     GetArkUINodeModifiers()->getImageSpanModifier()->setImageSpanColorFilter(
353         nativeNode, &(*colorFilter.begin()), COLOR_FILTER_MATRIX_SIZE);
354     return panda::JSValueRef::Undefined(vm);
355 }
356 
ResetColorFilter(ArkUIRuntimeCallInfo * runtimeCallInfo)357 ArkUINativeModuleValue ImageSpanBridge::ResetColorFilter(ArkUIRuntimeCallInfo* runtimeCallInfo)
358 {
359     EcmaVM* vm = runtimeCallInfo->GetVM();
360     CHECK_NULL_RETURN(vm, panda::JSValueRef::Undefined(vm));
361     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
362     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
363     GetArkUINodeModifiers()->getImageSpanModifier()->resetImageSpanColorFilter(nativeNode);
364     return panda::JSValueRef::Undefined(vm);
365 }
366 
SetBorderRadius(ArkUIRuntimeCallInfo * runtimeCallInfo)367 ArkUINativeModuleValue ImageSpanBridge::SetBorderRadius(ArkUIRuntimeCallInfo *runtimeCallInfo)
368 {
369     EcmaVM *vm = runtimeCallInfo->GetVM();
370     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
371     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
372     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
373     Local<JSValueRef> topLeftArgs = runtimeCallInfo->GetCallArgRef(NUM_1);
374     Local<JSValueRef> topRightArgs = runtimeCallInfo->GetCallArgRef(NUM_2);
375     Local<JSValueRef> bottomLeftArgs = runtimeCallInfo->GetCallArgRef(NUM_3);
376     Local<JSValueRef> bottomRightArgs = runtimeCallInfo->GetCallArgRef(NUM_4);
377     if (topLeftArgs->IsUndefined() && topRightArgs->IsUndefined() && bottomLeftArgs->IsUndefined() &&
378         bottomRightArgs->IsUndefined()) {
379         GetArkUINodeModifiers()->getImageSpanModifier()->resetImageSpanBorderRadius(nativeNode);
380         return panda::JSValueRef::Undefined(vm);
381     }
382 
383     CalcDimension topLeft;
384     CalcDimension topRight;
385     CalcDimension bottomLeft;
386     CalcDimension bottomRight;
387 
388     ArkTSUtils::ParseAllBorder(vm, topLeftArgs, topLeft);
389     ArkTSUtils::ParseAllBorder(vm, topRightArgs, topRight);
390     ArkTSUtils::ParseAllBorder(vm, bottomLeftArgs, bottomLeft);
391     ArkTSUtils::ParseAllBorder(vm, bottomRightArgs, bottomRight);
392 
393     uint32_t size = SIZE_OF_FOUR;
394     ArkUI_Float32 values[size];
395     int units[size];
396 
397     values[NUM_0] = topLeft.Value();
398     units[NUM_0] = static_cast<int>(topLeft.Unit());
399     values[NUM_1] = topRight.Value();
400     units[NUM_1] = static_cast<int>(topRight.Unit());
401     values[NUM_2] = bottomLeft.Value();
402     units[NUM_2] = static_cast<int>(bottomLeft.Unit());
403     values[NUM_3] = bottomRight.Value();
404     units[NUM_3] = static_cast<int>(bottomRight.Unit());
405 
406     GetArkUINodeModifiers()->getImageSpanModifier()->setImageSpanBorderRadius(nativeNode, values, units, SIZE_OF_FOUR);
407 
408     return panda::JSValueRef::Undefined(vm);
409 }
410 
ResetBorderRadius(ArkUIRuntimeCallInfo * runtimeCallInfo)411 ArkUINativeModuleValue ImageSpanBridge::ResetBorderRadius(ArkUIRuntimeCallInfo *runtimeCallInfo)
412 {
413     EcmaVM *vm = runtimeCallInfo->GetVM();
414     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
415     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
416     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
417     GetArkUINodeModifiers()->getImageSpanModifier()->resetImageSpanBorderRadius(nativeNode);
418     return panda::JSValueRef::Undefined(vm);
419 }
420 } // namespace OHOS::Ace::NG
421