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_animator_bridge.h"
16
17 #include "base/geometry/dimension.h"
18 #include "base/geometry/ng/offset_t.h"
19 #include "base/memory/referenced.h"
20 #include "core/interfaces/native/node/api.h"
21 #include "bridge/declarative_frontend/engine/jsi/nativeModule/arkts_utils.h"
22 #include "bridge/declarative_frontend/jsview/js_image_animator.h"
23 #include "core/components/declaration/image/image_animator_declaration.h"
24
25 namespace OHOS::Ace::NG {
26 constexpr int32_t DEFAULT_DURATION = 1000; // ms
27
28 constexpr int NUM_0 = 0;
29 constexpr int NUM_1 = 1;
30 constexpr int NUM_2 = 2;
31 constexpr int NUM_3 = 3;
32 constexpr int NUM_4 = 4;
33 constexpr int NUM_5 = 5;
34 constexpr int NUM_6 = 6;
35 constexpr int NUM_7 = 7;
36 constexpr int32_t IMAGESIZE = 4;
37 constexpr FillMode DEFAULT_FILL_MODE = FillMode::FORWARDS;
SetState(ArkUIRuntimeCallInfo * runtimeCallInfo)38 ArkUINativeModuleValue ImageAnimatorBridge::SetState(ArkUIRuntimeCallInfo* runtimeCallInfo)
39 {
40 EcmaVM* vm = runtimeCallInfo->GetVM();
41 CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
42 Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
43 Local<JSValueRef> secondArg = runtimeCallInfo->GetCallArgRef(1);
44 void* nativeNode = firstArg->ToNativePointer(vm)->Value();
45 int32_t state = static_cast<int32_t>(Animator::Status::IDLE);
46 if (secondArg->IsNumber()) {
47 state = secondArg->Int32Value(vm);
48 if (state < static_cast<int32_t>(Animator::Status::IDLE) ||
49 state > static_cast<int32_t>(Animator::Status::STOPPED)) {
50 state = static_cast<int32_t>(Animator::Status::IDLE);
51 }
52 GetArkUIInternalNodeAPI()->GetImageAnimatorModifier().SetState(nativeNode, state);
53 } else {
54 GetArkUIInternalNodeAPI()->GetImageAnimatorModifier().ResetState(nativeNode);
55 }
56
57 return panda::JSValueRef::Undefined(vm);
58 }
59
ResetState(ArkUIRuntimeCallInfo * runtimeCallInfo)60 ArkUINativeModuleValue ImageAnimatorBridge::ResetState(ArkUIRuntimeCallInfo* runtimeCallInfo)
61 {
62 EcmaVM* vm = runtimeCallInfo->GetVM();
63 CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
64 Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
65 void* nativeNode = firstArg->ToNativePointer(vm)->Value();
66 GetArkUIInternalNodeAPI()->GetImageAnimatorModifier().ResetState(nativeNode);
67 return panda::JSValueRef::Undefined(vm);
68 }
69
SetDuration(ArkUIRuntimeCallInfo * runtimeCallInfo)70 ArkUINativeModuleValue ImageAnimatorBridge::SetDuration(ArkUIRuntimeCallInfo* runtimeCallInfo)
71 {
72 EcmaVM* vm = runtimeCallInfo->GetVM();
73 CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
74 Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
75 Local<JSValueRef> secondArg = runtimeCallInfo->GetCallArgRef(1);
76 void* nativeNode = firstArg->ToNativePointer(vm)->Value();
77 int32_t duration = DEFAULT_DURATION;
78 if (secondArg->IsNumber()) {
79 duration = secondArg->Int32Value(vm);
80 if (duration < 0) {
81 duration = DEFAULT_DURATION;
82 }
83 }
84 GetArkUIInternalNodeAPI()->GetImageAnimatorModifier().SetDuration(nativeNode, duration);
85 return panda::JSValueRef::Undefined(vm);
86 }
87
ResetDuration(ArkUIRuntimeCallInfo * runtimeCallInfo)88 ArkUINativeModuleValue ImageAnimatorBridge::ResetDuration(ArkUIRuntimeCallInfo* runtimeCallInfo)
89 {
90 EcmaVM* vm = runtimeCallInfo->GetVM();
91 CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
92 Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
93 void* nativeNode = firstArg->ToNativePointer(vm)->Value();
94 int32_t duration = DEFAULT_DURATION;
95 GetArkUIInternalNodeAPI()->GetImageAnimatorModifier().SetDuration(nativeNode, duration);
96 return panda::JSValueRef::Undefined(vm);
97 }
98
SetFixedSize(ArkUIRuntimeCallInfo * runtimeCallInfo)99 ArkUINativeModuleValue ImageAnimatorBridge::SetFixedSize(ArkUIRuntimeCallInfo* runtimeCallInfo)
100 {
101 EcmaVM* vm = runtimeCallInfo->GetVM();
102 CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
103 Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
104 Local<JSValueRef> secondArg = runtimeCallInfo->GetCallArgRef(1);
105 void* nativeNode = firstArg->ToNativePointer(vm)->Value();
106
107 uint32_t fixedSize = 1;
108 if (secondArg->IsBoolean()) {
109 fixedSize = static_cast<uint32_t>(secondArg->ToBoolean(vm)->Value());
110 GetArkUIInternalNodeAPI()->GetImageAnimatorModifier().SetFixedSize(nativeNode, fixedSize);
111 } else {
112 GetArkUIInternalNodeAPI()->GetImageAnimatorModifier().ResetFixedSize(nativeNode);
113 }
114
115 return panda::JSValueRef::Undefined(vm);
116 }
117
ResetFixedSize(ArkUIRuntimeCallInfo * runtimeCallInfo)118 ArkUINativeModuleValue ImageAnimatorBridge::ResetFixedSize(ArkUIRuntimeCallInfo* runtimeCallInfo)
119 {
120 EcmaVM* vm = runtimeCallInfo->GetVM();
121 CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
122 Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
123 void* nativeNode = firstArg->ToNativePointer(vm)->Value();
124 GetArkUIInternalNodeAPI()->GetImageAnimatorModifier().ResetFixedSize(nativeNode);
125 return panda::JSValueRef::Undefined(vm);
126 }
127
SetFillMode(ArkUIRuntimeCallInfo * runtimeCallInfo)128 ArkUINativeModuleValue ImageAnimatorBridge::SetFillMode(ArkUIRuntimeCallInfo* runtimeCallInfo)
129 {
130 EcmaVM* vm = runtimeCallInfo->GetVM();
131 CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
132 Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
133 Local<JSValueRef> secondArg = runtimeCallInfo->GetCallArgRef(1);
134 void* nativeNode = firstArg->ToNativePointer(vm)->Value();
135
136 if (secondArg->IsNumber()) {
137 int32_t fillMode = secondArg->Int32Value(vm);
138 if (fillMode < static_cast<int32_t>(FillMode::NONE) || fillMode > static_cast<int32_t>(FillMode::BOTH)) {
139 fillMode = static_cast<int32_t>(DEFAULT_FILL_MODE);
140 }
141 GetArkUIInternalNodeAPI()->GetImageAnimatorModifier().SetFillMode(nativeNode, fillMode);
142 } else {
143 GetArkUIInternalNodeAPI()->GetImageAnimatorModifier().ResetFillMode(nativeNode);
144 }
145 return panda::JSValueRef::Undefined(vm);
146 }
147
ResetFillMode(ArkUIRuntimeCallInfo * runtimeCallInfo)148 ArkUINativeModuleValue ImageAnimatorBridge::ResetFillMode(ArkUIRuntimeCallInfo* runtimeCallInfo)
149 {
150 EcmaVM* vm = runtimeCallInfo->GetVM();
151 CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
152 Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
153 void* nativeNode = firstArg->ToNativePointer(vm)->Value();
154 GetArkUIInternalNodeAPI()->GetImageAnimatorModifier().ResetFillMode(nativeNode);
155 return panda::JSValueRef::Undefined(vm);
156 }
157
SetReverse(ArkUIRuntimeCallInfo * runtimeCallInfo)158 ArkUINativeModuleValue ImageAnimatorBridge::SetReverse(ArkUIRuntimeCallInfo* runtimeCallInfo)
159 {
160 EcmaVM* vm = runtimeCallInfo->GetVM();
161 CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
162 Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(NUM_0);
163 Local<JSValueRef> secondArg = runtimeCallInfo->GetCallArgRef(NUM_1);
164 void* nativeNode = firstArg->ToNativePointer(vm)->Value();
165
166 if (secondArg->IsBoolean()) {
167 uint32_t value = static_cast<uint32_t>(secondArg->ToBoolean(vm)->Value());
168 GetArkUIInternalNodeAPI()->GetImageAnimatorModifier().SetReverse(nativeNode, value);
169 } else {
170 GetArkUIInternalNodeAPI()->GetImageAnimatorModifier().ResetReverse(nativeNode);
171 }
172
173 return panda::JSValueRef::Undefined(vm);
174 }
175
ResetReverse(ArkUIRuntimeCallInfo * runtimeCallInfo)176 ArkUINativeModuleValue ImageAnimatorBridge::ResetReverse(ArkUIRuntimeCallInfo* runtimeCallInfo)
177 {
178 EcmaVM* vm = runtimeCallInfo->GetVM();
179 CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
180 Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(NUM_0);
181 void* nativeNode = firstArg->ToNativePointer(vm)->Value();
182 GetArkUIInternalNodeAPI()->GetImageAnimatorModifier().ResetReverse(nativeNode);
183 return panda::JSValueRef::Undefined(vm);
184 }
185
SetImages(ArkUIRuntimeCallInfo * runtimeCallInfo)186 ArkUINativeModuleValue ImageAnimatorBridge::SetImages(ArkUIRuntimeCallInfo* runtimeCallInfo)
187 {
188 EcmaVM* vm = runtimeCallInfo->GetVM();
189 CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
190 Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(NUM_0);
191 Local<JSValueRef> secondArg = runtimeCallInfo->GetCallArgRef(NUM_1);
192 Local<JSValueRef> thirdArg = runtimeCallInfo->GetCallArgRef(NUM_2);
193 Local<JSValueRef> fourthArg = runtimeCallInfo->GetCallArgRef(NUM_3);
194 Local<JSValueRef> fifthArg = runtimeCallInfo->GetCallArgRef(NUM_4);
195 Local<JSValueRef> sixthArg = runtimeCallInfo->GetCallArgRef(NUM_5);
196 Local<JSValueRef> seventhArg = runtimeCallInfo->GetCallArgRef(NUM_6);
197 Local<JSValueRef> eighthArg = runtimeCallInfo->GetCallArgRef(NUM_7);
198 void* nativeNode = firstArg->ToNativePointer(vm)->Value();
199
200 if (!eighthArg->IsNumber() || eighthArg->Int32Value(vm) <= 0) {
201 return panda::JSValueRef::Undefined(vm);
202 }
203 int32_t arrayLength = eighthArg->Int32Value(vm);
204
205 if (secondArg->IsNull() || !secondArg->IsArray(vm) || thirdArg->IsNull() || !thirdArg->IsArray(vm) ||
206 fourthArg->IsNull() || !fourthArg->IsArray(vm) || fifthArg->IsNull() || !fifthArg->IsArray(vm) ||
207 sixthArg->IsNull() || !sixthArg->IsArray(vm) || seventhArg->IsNull() || !seventhArg->IsArray(vm)) {
208 return panda::JSValueRef::Undefined(vm);
209 }
210 auto parseDimensionStruct = [](const EcmaVM* vm, const Local<JSValueRef>& arg) {
211 CalcDimension val(0.0, DimensionUnit::VP);
212 ArkTSUtils::ParseJsDimensionVp(vm, arg, val);
213 return val;
214 };
215 auto parseInt32 = [](const EcmaVM* vm, const Local<JSValueRef>& arg) {
216 if (arg->IsNumber()) {
217 return arg->Int32Value(vm);
218 }
219 return 0;
220 };
221 auto srcArray = std::make_unique<std::string[]>(arrayLength);
222 auto calcDimension = std::make_unique<CalcDimension[]>(arrayLength * 4);
223 auto durationArray = std::make_unique<int32_t[]>(arrayLength);
224 if (!ArkTSUtils::ParseStringArray(vm, secondArg, srcArray.get(), arrayLength) ||
225 !ArkTSUtils::ParseArray<CalcDimension>(
226 vm, thirdArg, calcDimension.get() + arrayLength * NUM_0, arrayLength, parseDimensionStruct) ||
227 !ArkTSUtils::ParseArray<CalcDimension>(
228 vm, fourthArg, calcDimension.get() + arrayLength * NUM_1, arrayLength, parseDimensionStruct) ||
229 !ArkTSUtils::ParseArray<CalcDimension>(
230 vm, fifthArg, calcDimension.get() + arrayLength * NUM_2, arrayLength, parseDimensionStruct) ||
231 !ArkTSUtils::ParseArray<CalcDimension>(
232 vm, sixthArg, calcDimension.get() + arrayLength * NUM_3, arrayLength, parseDimensionStruct) ||
233 !ArkTSUtils::ParseArray<int32_t>(vm, seventhArg, durationArray.get(), arrayLength, parseInt32)) {
234 return panda::JSValueRef::Undefined(vm);
235 }
236 auto images = std::make_unique<ArkUIImagePropertiesStruct[]>(arrayLength);
237 for (int32_t i = 0; i < arrayLength; i++) {
238 images[i].src = srcArray[i].c_str();
239 for (int32_t j = 0; j < IMAGESIZE; j++) {
240 images[i].number[j] = calcDimension[arrayLength * i + j].Value();
241 images[i].unit[j] = static_cast<int8_t>(calcDimension[arrayLength * i + j].Unit());
242 images[i].calc[j] = const_cast<char*>(calcDimension[arrayLength * i + j].CalcValue().c_str());
243 }
244 images[i].duration = *(durationArray.get() + i);
245 }
246 GetArkUIInternalNodeAPI()->GetImageAnimatorModifier().SetImages(nativeNode, images.get(), arrayLength);
247 return panda::JSValueRef::Undefined(vm);
248 }
249
ResetImages(ArkUIRuntimeCallInfo * runtimeCallInfo)250 ArkUINativeModuleValue ImageAnimatorBridge::ResetImages(ArkUIRuntimeCallInfo* runtimeCallInfo)
251 {
252 EcmaVM* vm = runtimeCallInfo->GetVM();
253 CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
254 Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(NUM_0);
255 void* nativeNode = firstArg->ToNativePointer(vm)->Value();
256 GetArkUIInternalNodeAPI()->GetImageAnimatorModifier().ResetImages(nativeNode);
257 return panda::JSValueRef::Undefined(vm);
258 }
259
SetIteration(ArkUIRuntimeCallInfo * runtimeCallInfo)260 ArkUINativeModuleValue ImageAnimatorBridge::SetIteration(ArkUIRuntimeCallInfo* runtimeCallInfo)
261 {
262 EcmaVM* vm = runtimeCallInfo->GetVM();
263 CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
264 Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
265 Local<JSValueRef> secondArg = runtimeCallInfo->GetCallArgRef(1);
266 void* nativeNode = firstArg->ToNativePointer(vm)->Value();
267 int32_t value ;
268 if (secondArg->IsNumber()) {
269 value = secondArg->Int32Value(vm);
270 } else {
271 return panda::JSValueRef::Undefined(vm);
272 }
273
274 GetArkUIInternalNodeAPI()->GetImageAnimatorModifier().SetImageAnimatorIteration(nativeNode, value);
275 return panda::JSValueRef::Undefined(vm);
276 }
277
ResetIteration(ArkUIRuntimeCallInfo * runtimeCallInfo)278 ArkUINativeModuleValue ImageAnimatorBridge::ResetIteration(ArkUIRuntimeCallInfo* runtimeCallInfo)
279 {
280 EcmaVM* vm = runtimeCallInfo->GetVM();
281 CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
282 Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
283 void* nativeNode = firstArg->ToNativePointer(vm)->Value();
284 GetArkUIInternalNodeAPI()->GetImageAnimatorModifier().ResetImageAnimatorIteration(nativeNode);
285 return panda::JSValueRef::Undefined(vm);
286 }
287 } // namespace OHOS::Ace::NG
288