• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 } // namespace
38 
SetVerticalAlign(ArkUIRuntimeCallInfo * runtimeCallInfo)39 ArkUINativeModuleValue ImageSpanBridge::SetVerticalAlign(ArkUIRuntimeCallInfo* runtimeCallInfo)
40 {
41     EcmaVM* vm = runtimeCallInfo->GetVM();
42     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
43     Local<JSValueRef> node = runtimeCallInfo->GetCallArgRef(0);
44     Local<JSValueRef> verticalAlign = runtimeCallInfo->GetCallArgRef(1);
45     CHECK_NULL_RETURN(node->IsNativePointer(vm), panda::JSValueRef::Undefined(vm));
46     auto nativeNode = nodePtr(node->ToNativePointer(vm)->Value());
47     int32_t value = static_cast<int32_t>(VerticalAlign::BOTTOM);
48     if (verticalAlign->IsNumber()) {
49         value = verticalAlign->Int32Value(vm);
50         auto align = static_cast<VerticalAlign>(value);
51         if (align < VerticalAlign::TOP || align > VerticalAlign::NONE) {
52             align = VerticalAlign::BOTTOM;
53         }
54         value = static_cast<int32_t>(align);
55     }
56     GetArkUINodeModifiers()->getImageSpanModifier()->setImageSpanVerticalAlign(nativeNode, value);
57     return panda::JSValueRef::Undefined(vm);
58 }
59 
ResetVerticalAlign(ArkUIRuntimeCallInfo * runtimeCallInfo)60 ArkUINativeModuleValue ImageSpanBridge::ResetVerticalAlign(ArkUIRuntimeCallInfo* runtimeCallInfo)
61 {
62     EcmaVM* vm = runtimeCallInfo->GetVM();
63     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
64     Local<JSValueRef> node = runtimeCallInfo->GetCallArgRef(0);
65     CHECK_NULL_RETURN(node->IsNativePointer(vm), panda::JSValueRef::Undefined(vm));
66     auto nativeNode = nodePtr(node->ToNativePointer(vm)->Value());
67     GetArkUINodeModifiers()->getImageSpanModifier()->resetImageSpanVerticalAlign(nativeNode);
68     return panda::JSValueRef::Undefined(vm);
69 }
70 
SetObjectFit(ArkUIRuntimeCallInfo * runtimeCallInfo)71 ArkUINativeModuleValue ImageSpanBridge::SetObjectFit(ArkUIRuntimeCallInfo* runtimeCallInfo)
72 {
73     EcmaVM* vm = runtimeCallInfo->GetVM();
74     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
75     Local<JSValueRef> node = runtimeCallInfo->GetCallArgRef(0);
76     Local<JSValueRef> objectFit = runtimeCallInfo->GetCallArgRef(1);
77     CHECK_NULL_RETURN(node->IsNativePointer(vm), panda::JSValueRef::Undefined(vm));
78     auto nativeNode = nodePtr(node->ToNativePointer(vm)->Value());
79     int32_t value = static_cast<int32_t>(ImageFit::COVER);
80     if (objectFit->IsNumber()) {
81         value = objectFit->Int32Value(vm);
82         auto fit = static_cast<ImageFit>(value);
83         if (fit < ImageFit::FILL || fit > ImageFit::SCALE_DOWN) {
84             fit = ImageFit::COVER;
85         }
86         value = static_cast<int32_t>(fit);
87     }
88     GetArkUINodeModifiers()->getImageSpanModifier()->setImageSpanObjectFit(nativeNode, value);
89     return panda::JSValueRef::Undefined(vm);
90 }
91 
ResetObjectFit(ArkUIRuntimeCallInfo * runtimeCallInfo)92 ArkUINativeModuleValue ImageSpanBridge::ResetObjectFit(ArkUIRuntimeCallInfo* runtimeCallInfo)
93 {
94     EcmaVM* vm = runtimeCallInfo->GetVM();
95     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
96     Local<JSValueRef> node = runtimeCallInfo->GetCallArgRef(0);
97     CHECK_NULL_RETURN(node->IsNativePointer(vm), panda::JSValueRef::Undefined(vm));
98     auto nativeNode = nodePtr(node->ToNativePointer(vm)->Value());
99     GetArkUINodeModifiers()->getImageSpanModifier()->resetImageSpanObjectFit(nativeNode);
100     return panda::JSValueRef::Undefined(vm);
101 }
102 
SetTextBackgroundStyle(ArkUIRuntimeCallInfo * runtimeCallInfo)103 ArkUINativeModuleValue ImageSpanBridge::SetTextBackgroundStyle(ArkUIRuntimeCallInfo* runtimeCallInfo)
104 {
105     EcmaVM* vm = runtimeCallInfo->GetVM();
106     Color color;
107     std::vector<ArkUI_Float32> radiusArray;
108     std::vector<ArkUI_Int32> valueUnits;
109     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(NUM_0);
110     Local<JSValueRef> secondArg = runtimeCallInfo->GetCallArgRef(NUM_1);
111     CHECK_NULL_RETURN(firstArg->IsNativePointer(vm), panda::JSValueRef::Undefined(vm));
112     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
113     std::shared_ptr<TextBackgroundStyle> style = std::make_shared<TextBackgroundStyle>();
114     RefPtr<ResourceObject> colorResObj;
115     auto nodeInfo = ArkTSUtils::MakeNativeNodeInfo(nativeNode);
116     if (!ArkTSUtils::ParseJsColorAlpha(vm, secondArg, color, colorResObj, nodeInfo)) {
117         color = Color::TRANSPARENT;
118     }
119     ArkTSUtils::ParseOuterBorderRadius(runtimeCallInfo, vm, radiusArray, valueUnits, NUM_2, style);
120     ArkTSUtils::SetTextBackgroundStyle(style, color, colorResObj, radiusArray.data(), valueUnits.data());
121     GetArkUINodeModifiers()->getImageSpanModifier()->setImageSpanTextBackgroundStyle(
122         nativeNode, color.GetValue(), radiusArray.data(), valueUnits.data(), static_cast<int32_t>(radiusArray.size()),
123         style.get());
124     return panda::JSValueRef::Undefined(vm);
125 }
126 
ResetTextBackgroundStyle(ArkUIRuntimeCallInfo * runtimeCallInfo)127 ArkUINativeModuleValue ImageSpanBridge::ResetTextBackgroundStyle(ArkUIRuntimeCallInfo* runtimeCallInfo)
128 {
129     EcmaVM* vm = runtimeCallInfo->GetVM();
130     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(NUM_0);
131     CHECK_NULL_RETURN(firstArg->IsNativePointer(vm), panda::JSValueRef::Undefined(vm));
132     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
133     GetArkUINodeModifiers()->getImageSpanModifier()->resetImageSpanTextBackgroundStyle(nativeNode);
134     return panda::JSValueRef::Undefined(vm);
135 }
136 
SetBaselineOffset(ArkUIRuntimeCallInfo * runtimeCallInfo)137 ArkUINativeModuleValue ImageSpanBridge::SetBaselineOffset(ArkUIRuntimeCallInfo *runtimeCallInfo)
138 {
139     EcmaVM *vm = runtimeCallInfo->GetVM();
140     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
141     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(NUM_0);
142     Local<JSValueRef> secondArg = runtimeCallInfo->GetCallArgRef(NUM_1);
143     CHECK_NULL_RETURN(firstArg->IsNativePointer(vm), panda::JSValueRef::Undefined(vm));
144     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
145     CalcDimension result;
146     if (secondArg->IsObject(vm) && ArkTSUtils::ParseJsLengthMetrics(vm, secondArg, result) &&
147         result.Unit() != DimensionUnit::PERCENT && !std::isnan(result.Value())) {
148         GetArkUINodeModifiers()->getImageSpanModifier()->setImageSpanBaselineOffset(
149             nativeNode, result.Value(), static_cast<int8_t>(result.Unit()));
150     } else {
151         GetArkUINodeModifiers()->getImageSpanModifier()->resetImageSpanBaselineOffset(nativeNode);
152     }
153     return panda::JSValueRef::Undefined(vm);
154 }
155 
ResetBaselineOffset(ArkUIRuntimeCallInfo * runtimeCallInfo)156 ArkUINativeModuleValue ImageSpanBridge::ResetBaselineOffset(ArkUIRuntimeCallInfo* runtimeCallInfo)
157 {
158     EcmaVM* vm = runtimeCallInfo->GetVM();
159     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
160     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(NUM_0);
161     CHECK_NULL_RETURN(firstArg->IsNativePointer(vm), panda::JSValueRef::Undefined(vm));
162     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
163     GetArkUINodeModifiers()->getImageSpanModifier()->resetImageSpanBaselineOffset(nativeNode);
164     return panda::JSValueRef::Undefined(vm);
165 }
166 
SetAlt(ArkUIRuntimeCallInfo * runtimeCallInfo)167 ArkUINativeModuleValue ImageSpanBridge::SetAlt(ArkUIRuntimeCallInfo *runtimeCallInfo)
168 {
169     EcmaVM* vm = runtimeCallInfo->GetVM();
170     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
171     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
172     CHECK_NULL_RETURN(firstArg->IsNativePointer(vm), panda::JSValueRef::Undefined(vm));
173     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
174     Framework::JsiCallbackInfo info = Framework::JsiCallbackInfo(runtimeCallInfo);
175     RefPtr<PixelMap> pixmap = nullptr;
176 #if defined (PIXEL_MAP_SUPPORTED)
177     pixmap = Framework::CreatePixelMapFromNapiValue(info[1]);
178 #endif
179     if (pixmap) {
180         ImageSpanView::SetAlt(reinterpret_cast<FrameNode*>(nativeNode), pixmap);
181     }
182     return panda::JSValueRef::Undefined(vm);
183 }
184 
ResetAlt(ArkUIRuntimeCallInfo * runtimeCallInfo)185 ArkUINativeModuleValue ImageSpanBridge::ResetAlt(ArkUIRuntimeCallInfo* runtimeCallInfo)
186 {
187     EcmaVM* vm = runtimeCallInfo->GetVM();
188     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
189     return panda::JSValueRef::Undefined(vm);
190 }
191 
SetOnComplete(ArkUIRuntimeCallInfo * runtimeCallInfo)192 ArkUINativeModuleValue ImageSpanBridge::SetOnComplete(ArkUIRuntimeCallInfo *runtimeCallInfo)
193 {
194     EcmaVM *vm = runtimeCallInfo->GetVM();
195     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
196     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
197     Local<JSValueRef> callbackArg = runtimeCallInfo->GetCallArgRef(1);
198     CHECK_NULL_RETURN(firstArg->IsNativePointer(vm), panda::JSValueRef::Undefined(vm));
199     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
200     auto frameNode = reinterpret_cast<FrameNode*>(nativeNode);
201     CHECK_NULL_RETURN(frameNode, panda::NativePointerRef::New(vm, nullptr));
202     if (callbackArg->IsUndefined() || callbackArg->IsNull() || !callbackArg->IsFunction(vm)) {
203         GetArkUINodeModifiers()->getImageSpanModifier()->resetImageSpanOnComplete(nativeNode);
204         return panda::JSValueRef::Undefined(vm);
205     }
206     panda::Local<panda::FunctionRef> func = callbackArg->ToObject(vm);
207     std::function<void(LoadImageSuccessEvent&)> callback = [vm, frameNode,
208         func = panda::CopyableGlobal(vm, func)](LoadImageSuccessEvent& event) {
209         panda::LocalScope pandaScope(vm);
210         panda::TryCatch trycatch(vm);
211         PipelineContext::SetCallBackNode(AceType::WeakClaim(frameNode));
212         const char* keys[] = { "width", "height", "componentWidth", "componentHeight", "loadingStatus", "contentWidth",
213             "contentHeight", "contentOffsetX", "contentOffsetY" };
214         Local<JSValueRef> values[] = { panda::NumberRef::New(vm, event.GetWidth()),
215             panda::NumberRef::New(vm, event.GetHeight()), panda::NumberRef::New(vm, event.GetComponentWidth()),
216             panda::NumberRef::New(vm, event.GetComponentHeight()), panda::NumberRef::New(vm, event.GetLoadingStatus()),
217             panda::NumberRef::New(vm, event.GetContentWidth()), panda::NumberRef::New(vm, event.GetContentHeight()),
218             panda::NumberRef::New(vm, event.GetContentOffsetX()),
219             panda::NumberRef::New(vm, event.GetContentOffsetY()) };
220         auto eventObject = panda::ObjectRef::NewWithNamedProperties(vm, ArraySize(keys), keys, values);
221         eventObject->SetNativePointerFieldCount(vm, 1);
222         eventObject->SetNativePointerField(vm, 0, static_cast<void*>(&event));
223         panda::Local<panda::JSValueRef> params[1] = { eventObject };
224         func->Call(vm, func.ToLocal(), params, 1);
225     };
226     GetArkUINodeModifiers()->getImageSpanModifier()->setImageSpanOnComplete(
227         nativeNode, reinterpret_cast<void*>(&callback));
228     return panda::JSValueRef::Undefined(vm);
229 }
230 
ResetOnComplete(ArkUIRuntimeCallInfo * runtimeCallInfo)231 ArkUINativeModuleValue ImageSpanBridge::ResetOnComplete(ArkUIRuntimeCallInfo* runtimeCallInfo)
232 {
233     EcmaVM* vm = runtimeCallInfo->GetVM();
234     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
235     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
236     CHECK_NULL_RETURN(firstArg->IsNativePointer(vm), panda::JSValueRef::Undefined(vm));
237     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
238     GetArkUINodeModifiers()->getImageSpanModifier()->resetImageSpanOnComplete(nativeNode);
239     return panda::JSValueRef::Undefined(vm);
240 }
241 
SetOnError(ArkUIRuntimeCallInfo * runtimeCallInfo)242 ArkUINativeModuleValue ImageSpanBridge::SetOnError(ArkUIRuntimeCallInfo *runtimeCallInfo)
243 {
244     EcmaVM *vm = runtimeCallInfo->GetVM();
245     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
246     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
247     Local<JSValueRef> callbackArg = runtimeCallInfo->GetCallArgRef(1);
248     CHECK_NULL_RETURN(firstArg->IsNativePointer(vm), panda::JSValueRef::Undefined(vm));
249     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
250     auto frameNode = reinterpret_cast<FrameNode*>(nativeNode);
251     CHECK_NULL_RETURN(frameNode, panda::NativePointerRef::New(vm, nullptr));
252     if (callbackArg->IsUndefined() || callbackArg->IsNull() || !callbackArg->IsFunction(vm)) {
253         GetArkUINodeModifiers()->getImageSpanModifier()->resetImageSpanOnError(nativeNode);
254         return panda::JSValueRef::Undefined(vm);
255     }
256     panda::Local<panda::FunctionRef> func = callbackArg->ToObject(vm);
257     std::function<void(LoadImageFailEvent&)> callback = [vm, frameNode,
258         func = panda::CopyableGlobal(vm, func)](LoadImageFailEvent& event) {
259         panda::LocalScope pandaScope(vm);
260         panda::TryCatch trycatch(vm);
261         PipelineContext::SetCallBackNode(AceType::WeakClaim(frameNode));
262         const char* keys[] = { "componentWidth", "componentHeight", "message" };
263         Local<JSValueRef> values[] = { panda::NumberRef::New(vm, event.GetComponentWidth()),
264             panda::NumberRef::New(vm, event.GetComponentHeight()),
265             panda::StringRef::NewFromUtf8(vm, event.GetErrorMessage().c_str()) };
266         auto eventObject = panda::ObjectRef::NewWithNamedProperties(vm, ArraySize(keys), keys, values);
267         eventObject->SetNativePointerFieldCount(vm, 1);
268         eventObject->SetNativePointerField(vm, 0, static_cast<void*>(&event));
269         panda::Local<panda::JSValueRef> params[1] = { eventObject };
270         func->Call(vm, func.ToLocal(), params, 1);
271     };
272     GetArkUINodeModifiers()->getImageSpanModifier()->setImageSpanOnError(
273         nativeNode, reinterpret_cast<void*>(&callback));
274     return panda::JSValueRef::Undefined(vm);
275 }
276 
ResetOnError(ArkUIRuntimeCallInfo * runtimeCallInfo)277 ArkUINativeModuleValue ImageSpanBridge::ResetOnError(ArkUIRuntimeCallInfo* runtimeCallInfo)
278 {
279     EcmaVM* vm = runtimeCallInfo->GetVM();
280     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
281     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
282     CHECK_NULL_RETURN(firstArg->IsNativePointer(vm), panda::JSValueRef::Undefined(vm));
283     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
284     GetArkUINodeModifiers()->getImageSpanModifier()->resetImageSpanOnError(nativeNode);
285     return panda::JSValueRef::Undefined(vm);
286 }
287 
SetBorderRadius(ArkUIRuntimeCallInfo * runtimeCallInfo)288 ArkUINativeModuleValue ImageSpanBridge::SetBorderRadius(ArkUIRuntimeCallInfo *runtimeCallInfo)
289 {
290     EcmaVM *vm = runtimeCallInfo->GetVM();
291     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
292     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
293     CHECK_NULL_RETURN(firstArg->IsNativePointer(vm), panda::JSValueRef::Undefined(vm));
294     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
295     Local<JSValueRef> topLeftArgs = runtimeCallInfo->GetCallArgRef(NUM_1);
296     Local<JSValueRef> topRightArgs = runtimeCallInfo->GetCallArgRef(NUM_2);
297     Local<JSValueRef> bottomLeftArgs = runtimeCallInfo->GetCallArgRef(NUM_3);
298     Local<JSValueRef> bottomRightArgs = runtimeCallInfo->GetCallArgRef(NUM_4);
299     if (topLeftArgs->IsUndefined() && topRightArgs->IsUndefined() && bottomLeftArgs->IsUndefined() &&
300         bottomRightArgs->IsUndefined()) {
301         GetArkUINodeModifiers()->getImageSpanModifier()->resetImageSpanBorderRadius(nativeNode);
302         return panda::JSValueRef::Undefined(vm);
303     }
304 
305     CalcDimension topLeft;
306     CalcDimension topRight;
307     CalcDimension bottomLeft;
308     CalcDimension bottomRight;
309 
310     bool isLengthMetrics = false;
311     isLengthMetrics |= ArkTSUtils::ParseJsLengthMetrics(vm, topLeftArgs, topLeft);
312     isLengthMetrics |= ArkTSUtils::ParseJsLengthMetrics(vm, topRightArgs, topRight);
313     isLengthMetrics |= ArkTSUtils::ParseJsLengthMetrics(vm, bottomLeftArgs, bottomLeft);
314     isLengthMetrics |= ArkTSUtils::ParseJsLengthMetrics(vm, bottomRightArgs, bottomRight);
315     if (!isLengthMetrics) {
316         ArkTSUtils::ParseAllBorder(vm, topLeftArgs, topLeft);
317         ArkTSUtils::ParseAllBorder(vm, topRightArgs, topRight);
318         ArkTSUtils::ParseAllBorder(vm, bottomLeftArgs, bottomLeft);
319         ArkTSUtils::ParseAllBorder(vm, bottomRightArgs, bottomRight);
320     }
321     auto directionChanged = false;
322     auto isRightToLeft = AceApplicationInfo::GetInstance().IsRightToLeft();
323     directionChanged = isRightToLeft && isLengthMetrics;
324     uint32_t size = SIZE_OF_FOUR;
325     ArkUI_Float32 values[size];
326     int units[size];
327     values[NUM_0] = directionChanged ? topRight.Value() : topLeft.Value();
328     units[NUM_0] = directionChanged ? static_cast<int>(topRight.Unit()) : static_cast<int>(topLeft.Unit());
329     values[NUM_1] = directionChanged ? topLeft.Value() : topRight.Value();
330     units[NUM_1] = directionChanged ? static_cast<int>(topLeft.Unit()) : static_cast<int>(topRight.Unit());
331     values[NUM_2] = directionChanged ? bottomRight.Value() : bottomLeft.Value();
332     units[NUM_2] = directionChanged ? static_cast<int>(bottomRight.Unit()) : static_cast<int>(bottomLeft.Unit());
333     values[NUM_3] = directionChanged ? bottomLeft.Value() : bottomRight.Value();
334     units[NUM_3] = directionChanged ? static_cast<int>(bottomLeft.Unit()) : static_cast<int>(bottomRight.Unit());
335 
336     GetArkUINodeModifiers()->getImageSpanModifier()->setImageSpanBorderRadius(nativeNode, values, units, SIZE_OF_FOUR);
337 
338     return panda::JSValueRef::Undefined(vm);
339 }
340 
ResetBorderRadius(ArkUIRuntimeCallInfo * runtimeCallInfo)341 ArkUINativeModuleValue ImageSpanBridge::ResetBorderRadius(ArkUIRuntimeCallInfo *runtimeCallInfo)
342 {
343     EcmaVM *vm = runtimeCallInfo->GetVM();
344     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
345     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
346     CHECK_NULL_RETURN(firstArg->IsNativePointer(vm), panda::JSValueRef::Undefined(vm));
347     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
348     GetArkUINodeModifiers()->getImageSpanModifier()->resetImageSpanBorderRadius(nativeNode);
349     return panda::JSValueRef::Undefined(vm);
350 }
351 
SetSpanColorFilterObject(const EcmaVM * vm,const Local<JSValueRef> & jsObjArg,ArkUINodeHandle nativeNode)352 void SetSpanColorFilterObject(const EcmaVM* vm, const Local<JSValueRef>& jsObjArg, ArkUINodeHandle nativeNode)
353 {
354     Framework::JSColorFilter* colorFilter = nullptr;
355     if (!jsObjArg->IsUndefined() && !jsObjArg->IsNull()) {
356         colorFilter = static_cast<Framework::JSColorFilter*>(jsObjArg->ToObject(vm)->GetNativePointerField(vm, 0));
357     } else {
358         GetArkUINodeModifiers()->getImageSpanModifier()->setImageSpanColorFilter(
359             nativeNode, &(*DEFAULT_COLOR_FILTER_MATRIX.begin()), COLOR_FILTER_MATRIX_SIZE);
360         return;
361     }
362     if (colorFilter && colorFilter->GetColorFilterMatrix().size() == COLOR_FILTER_MATRIX_SIZE) {
363         GetArkUINodeModifiers()->getImageSpanModifier()->setImageSpanColorFilter(
364             nativeNode, &(*colorFilter->GetColorFilterMatrix().begin()), COLOR_FILTER_MATRIX_SIZE);
365         return;
366     }
367     GetArkUINodeModifiers()->getImageSpanModifier()->setImageSpanColorFilter(
368         nativeNode, &(*DEFAULT_COLOR_FILTER_MATRIX.begin()), COLOR_FILTER_MATRIX_SIZE);
369 }
370 
SetColorFilter(ArkUIRuntimeCallInfo * runtimeCallInfo)371 ArkUINativeModuleValue ImageSpanBridge::SetColorFilter(ArkUIRuntimeCallInfo* runtimeCallInfo)
372 {
373     EcmaVM* vm = runtimeCallInfo->GetVM();
374     CHECK_NULL_RETURN(vm, panda::JSValueRef::Undefined(vm));
375     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
376     Local<JSValueRef> jsObjArg = runtimeCallInfo->GetCallArgRef(1);
377     CHECK_NULL_RETURN(firstArg->IsNativePointer(vm), panda::JSValueRef::Undefined(vm));
378     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
379     Framework::JsiCallbackInfo info = Framework::JsiCallbackInfo(runtimeCallInfo);
380     if (!jsObjArg->IsArray(vm) && !jsObjArg->IsObject(vm)) {
381         GetArkUINodeModifiers()->getImageSpanModifier()->setImageSpanColorFilter(
382             nativeNode, &(*DEFAULT_COLOR_FILTER_MATRIX.begin()), COLOR_FILTER_MATRIX_SIZE);
383         return panda::JSValueRef::Undefined(vm);
384     }
385     if (jsObjArg->IsObject(vm) && !jsObjArg->IsArray(vm)) {
386         auto drawingColorFilter = Ace::Framework::CreateDrawingColorFilter(info[1]);
387         if (drawingColorFilter) {
388             ImageModelNG::SetDrawingColorFilter(reinterpret_cast<FrameNode*>(nativeNode), drawingColorFilter);
389             return panda::JSValueRef::Undefined(vm);
390         }
391         SetSpanColorFilterObject(vm, jsObjArg, nativeNode);
392         return panda::JSValueRef::Undefined(vm);
393     }
394     auto array = panda::CopyableGlobal<panda::ArrayRef>(vm, jsObjArg);
395     if (array.IsEmpty() || array->IsUndefined() || array->IsNull() || array->Length(vm) != COLOR_FILTER_MATRIX_SIZE) {
396         GetArkUINodeModifiers()->getImageSpanModifier()->setImageSpanColorFilter(
397             nativeNode, &(*DEFAULT_COLOR_FILTER_MATRIX.begin()), COLOR_FILTER_MATRIX_SIZE);
398         return panda::JSValueRef::Undefined(vm);
399     }
400     std::vector<float> colorFilter;
401     for (size_t i = 0; i < array->Length(vm); i++) {
402         auto value = array->GetValueAt(vm, jsObjArg, i);
403         if (value->IsNumber()) {
404             colorFilter.emplace_back(value->ToNumber(vm)->Value());
405         } else {
406             GetArkUINodeModifiers()->getImageSpanModifier()->setImageSpanColorFilter(
407                 nativeNode, &(*DEFAULT_COLOR_FILTER_MATRIX.begin()), COLOR_FILTER_MATRIX_SIZE);
408             return panda::JSValueRef::Undefined(vm);
409         }
410     }
411     GetArkUINodeModifiers()->getImageSpanModifier()->setImageSpanColorFilter(
412         nativeNode, &(*colorFilter.begin()), COLOR_FILTER_MATRIX_SIZE);
413     return panda::JSValueRef::Undefined(vm);
414 }
415 
ResetColorFilter(ArkUIRuntimeCallInfo * runtimeCallInfo)416 ArkUINativeModuleValue ImageSpanBridge::ResetColorFilter(ArkUIRuntimeCallInfo* runtimeCallInfo)
417 {
418     EcmaVM* vm = runtimeCallInfo->GetVM();
419     CHECK_NULL_RETURN(vm, panda::JSValueRef::Undefined(vm));
420     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
421     CHECK_NULL_RETURN(firstArg->IsNativePointer(vm), panda::JSValueRef::Undefined(vm));
422     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
423     GetArkUINodeModifiers()->getImageSpanModifier()->resetImageSpanColorFilter(nativeNode);
424     return panda::JSValueRef::Undefined(vm);
425 }
426 
CheckIsCard()427 bool CheckIsCard()
428 {
429     auto container = Container::Current();
430     CHECK_NULL_RETURN(container, false);
431     auto context = PipelineBase::GetCurrentContextSafelyWithCheck();
432     CHECK_NULL_RETURN(context, false);
433     return context->IsFormRender() && !container->IsDynamicRender();
434 }
435 
SetImageSpanSrc(ArkUIRuntimeCallInfo * runtimeCallInfo)436 ArkUINativeModuleValue ImageSpanBridge::SetImageSpanSrc(ArkUIRuntimeCallInfo* runtimeCallInfo)
437 {
438     EcmaVM* vm = runtimeCallInfo->GetVM();
439     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
440     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
441     Local<JSValueRef> secondArg = runtimeCallInfo->GetCallArgRef(1);
442     CHECK_NULL_RETURN(firstArg->IsNativePointer(vm), panda::JSValueRef::Undefined(vm));
443     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
444     Framework::JsiCallbackInfo info = Framework::JsiCallbackInfo(runtimeCallInfo);
445 
446     auto nodeModifiers = GetArkUINodeModifiers();
447     CHECK_NULL_RETURN(nodeModifiers, panda::JSValueRef::Undefined(vm));
448     int32_t resId = 0;
449     if (info.Length() > 1 && info[1]->IsObject()) {
450         Framework::JSRef<Framework::JSObject> jsObj = Framework::JSRef<Framework::JSObject>::Cast(info[1]);
451         Framework::JSRef<Framework::JSVal> tmp = jsObj->GetProperty("id");
452         if (!tmp->IsNull() && tmp->IsNumber()) {
453             resId = tmp->ToNumber<int32_t>();
454         }
455     }
456     bool isCard = CheckIsCard();
457     std::string src;
458     bool srcValid = ArkTSUtils::ParseJsMedia(vm, secondArg, src);
459     if (isCard && secondArg->IsString(vm)) {
460         SrcType srcType = ImageSourceInfo::ResolveURIType(src);
461         bool notSupport = (srcType == SrcType::NETWORK || srcType == SrcType::FILE || srcType == SrcType::DATA_ABILITY);
462         if (notSupport) {
463             src.clear();
464         }
465     }
466     std::string bundleName;
467     std::string moduleName;
468     ArkTSUtils::GetJsMediaBundleInfo(vm, secondArg, bundleName, moduleName);
469     RefPtr<PixelMap> pixmap = nullptr;
470     if (!srcValid) {
471 #if defined(PIXEL_MAP_SUPPORTED)
472         pixmap = Framework::CreatePixelMapFromNapiValue(info[1]);
473 #endif
474     }
475     if (pixmap) {
476         ImageSpanView::SetPixelMap(reinterpret_cast<FrameNode*>(nativeNode), pixmap);
477     } else {
478         nodeModifiers->getImageSpanModifier()->setImageSpanSrc(
479             nativeNode, src.c_str(), bundleName.c_str(), moduleName.c_str(), (resId == -1));
480     }
481     return panda::JSValueRef::Undefined(vm);
482 }
483 } // namespace OHOS::Ace::NG
484