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