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