1 /*
2  * Copyright (c) 2021 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 
16 #include "frameworks/bridge/common/utils/transform_convertor.h"
17 
18 #include "frameworks/bridge/common/dom/dom_type.h"
19 
20 namespace OHOS::Ace {
21 namespace {
22 
23 constexpr int32_t PARAM_SINGLE = 1;
24 constexpr int32_t PARAM_DOUBLE = 2;
25 constexpr int32_t PARAM_THREE = 3;
26 constexpr int32_t PARAM_FOUR = 4;
27 constexpr int32_t PARAM_SIX = 6;
28 constexpr int32_t PARAM_SIXTEEN = 16;
29 
30 } // namespace
31 
32 const std::vector<std::string> TransformConvertor::TransformKey = {
33     DOM_TRANSLATE,
34     DOM_TRANSLATE_3D,
35     DOM_TRANSLATE_X,
36     DOM_TRANSLATE_Y,
37     DOM_TRANSLATE_Z,
38     DOM_ROTATE,
39     DOM_ROTATE_3D,
40     DOM_ROTATE_X,
41     DOM_ROTATE_Y,
42     DOM_ROTATE_Z,
43     DOM_SCALE,
44     DOM_SCALE_3D,
45     DOM_SCALE_X,
46     DOM_SCALE_Y,
47     DOM_SCALE_Z,
48     DOM_SKEW,
49     DOM_SKEW_X,
50     DOM_SKEW_Y,
51     DOM_MATRIX,
52     DOM_MATRIX_3D,
53     DOM_PERSPECTIVE,
54 };
55 
Convert(const std::string & key,const std::string & value,double time)56 void TransformConvertor::Convert(const std::string& key, const std::string& value, double time)
57 {
58     auto iter = TransformConvertorMap.find(key);
59     if (iter != TransformConvertorMap.end()) {
60         iter->second(value, time, *this);
61     }
62 }
63 
InsertIdentityKeyframe(double time)64 void TransformConvertor::InsertIdentityKeyframe(double time)
65 {
66     noneKeyframeTimes_.push_back(static_cast<float>(time));
67 }
68 
AddAnimationToTweenOption(TweenOption & option) const69 void TransformConvertor::AddAnimationToTweenOption(TweenOption& option) const
70 {
71     auto noneKeyframes = std::list<RefPtr<Keyframe<TransformOperation>>>();
72     TransformOperation operation;
73     operation.type_ = TransformOperationType::UNDEFINED;
74     for (float time : noneKeyframeTimes_) {
75         noneKeyframes.push_back(AceType::MakeRefPtr<Keyframe<TransformOperation>>(time, operation));
76     }
77     for (const auto& animation : operationList_) {
78         if (!noneKeyframes.empty()) {
79             // insert transform: none keyframe into animation
80             animation->AddKeyframe(noneKeyframes);
81         }
82         option.AddTransformAnimation(animation);
83     }
84 }
85 
ApplyCurve(const RefPtr<Curve> & curve)86 void TransformConvertor::ApplyCurve(const RefPtr<Curve>& curve)
87 {
88     for (const auto& animation : operationList_) {
89         if (animation) {
90             animation->SetCurve(curve);
91         }
92     }
93 }
94 
ClearAnimations()95 void TransformConvertor::ClearAnimations()
96 {
97     operationList_.clear();
98     operationMap_.clear();
99     noneKeyframeTimes_.clear();
100 }
101 
AddKeyframe(AnimationType type,const RefPtr<Keyframe<TransformOperation>> & keyframe)102 void TransformConvertor::AddKeyframe(AnimationType type, const RefPtr<Keyframe<TransformOperation>>& keyframe)
103 {
104     auto& animation = operationMap_[type];
105     if (!animation) {
106         animation = AceType::MakeRefPtr<KeyframeAnimation<TransformOperation>>();
107         operationList_.push_back(animation);
108     }
109     animation->AddKeyframe(keyframe);
110 }
111 
AddKeyframe(AnimationType type,double time,const TranslateOperation & translate)112 void TransformConvertor::AddKeyframe(AnimationType type, double time, const TranslateOperation& translate)
113 {
114     TransformOperation operation;
115     operation.type_ = TransformOperationType::TRANSLATE;
116     operation.translateOperation_ = translate;
117     auto keyframe = AceType::MakeRefPtr<Keyframe<TransformOperation>>(time, operation);
118     AddKeyframe(type, keyframe);
119 }
120 
AddKeyframe(AnimationType type,double time,const SkewOperation & skew)121 void TransformConvertor::AddKeyframe(AnimationType type, double time, const SkewOperation& skew)
122 {
123     TransformOperation operation;
124     operation.type_ = TransformOperationType::SKEW;
125     operation.skewOperation_ = skew;
126     auto keyframe = AceType::MakeRefPtr<Keyframe<TransformOperation>>(time, operation);
127     AddKeyframe(type, keyframe);
128 }
129 
AddKeyframe(AnimationType type,double time,const ScaleOperation & scale)130 void TransformConvertor::AddKeyframe(AnimationType type, double time, const ScaleOperation& scale)
131 {
132     TransformOperation operation;
133     operation.type_ = TransformOperationType::SCALE;
134     operation.scaleOperation_ = scale;
135     auto keyframe = AceType::MakeRefPtr<Keyframe<TransformOperation>>(time, operation);
136     AddKeyframe(type, keyframe);
137 }
138 
AddKeyframe(AnimationType type,double time,const RotateOperation & rotate)139 void TransformConvertor::AddKeyframe(AnimationType type, double time, const RotateOperation& rotate)
140 {
141     TransformOperation operation;
142     operation.type_ = TransformOperationType::ROTATE;
143     operation.rotateOperation_ = rotate;
144     auto keyframe = AceType::MakeRefPtr<Keyframe<TransformOperation>>(time, operation);
145     AddKeyframe(type, keyframe);
146 }
147 
AddKeyframe(AnimationType type,double time,const Matrix4 & matrix)148 void TransformConvertor::AddKeyframe(AnimationType type, double time, const Matrix4& matrix)
149 {
150     TransformOperation operation;
151     operation.type_ = TransformOperationType::MATRIX;
152     operation.matrix4_ = matrix;
153     auto keyframe = AceType::MakeRefPtr<Keyframe<TransformOperation>>(time, operation);
154     AddKeyframe(type, keyframe);
155 }
156 
AddKeyframe(AnimationType type,double time,const PerspectiveOperation & distance)157 void TransformConvertor::AddKeyframe(AnimationType type, double time, const PerspectiveOperation& distance)
158 {
159     TransformOperation operation;
160     operation.type_ = TransformOperationType::PERSPECTIVE;
161     operation.perspectiveOperation_ = distance;
162     auto keyframe = AceType::MakeRefPtr<Keyframe<TransformOperation>>(time, operation);
163     AddKeyframe(type, keyframe);
164 }
165 
166 const std::unordered_map<std::string, void (*)(const std::string&, const double&, TransformConvertor&)>
167     TransformConvertor::TransformConvertorMap = {
168         { DOM_TRANSLATE,
__anonc5ef80110202() 169             [](const std::string& typeValue, const double& time, TransformConvertor& convertor) {
170                 std::vector<std::string> offsets;
171                 StringUtils::StringSplitter(typeValue, ' ', offsets);
172                 if (offsets.size() == PARAM_DOUBLE) {
173                     auto dx = StringUtils::StringToDimension(offsets[0]);
174                     auto dy = StringUtils::StringToDimension(offsets[1]);
175                     convertor.AddKeyframe(AnimationType::TRANSLATE, time, TranslateOperation(dx, dy, Dimension {}));
176                 } else if (offsets.size() == PARAM_SINGLE) {
177                     auto dx = StringUtils::StringToDimension(offsets[0]);
178                     convertor.AddKeyframe(AnimationType::TRANSLATE, time, TranslateOperation(dx, Dimension {}));
179                 }
180             } },
181         { DOM_TRANSLATE_X,
__anonc5ef80110302() 182             [](const std::string& typeValue, const double& time, TransformConvertor& convertor) {
183                 auto dx = StringUtils::StringToDimension(typeValue);
184                 convertor.AddKeyframe(AnimationType::TRANSLATE_X, time, TranslateOperation(dx, Dimension {}));
185             } },
186         { DOM_TRANSLATE_Y,
__anonc5ef80110402() 187             [](const std::string& typeValue, const double& time, TransformConvertor& convertor) {
188                 auto dy = StringUtils::StringToDimension(typeValue);
189                 convertor.AddKeyframe(AnimationType::TRANSLATE_Y, time, TranslateOperation(Dimension {}, dy));
190             } },
191         { DOM_TRANSLATE_Z,
__anonc5ef80110502() 192             [](const std::string& typeValue, const double& time, TransformConvertor& convertor) {
193                 auto dz = StringUtils::StringToDimension(typeValue);
194 
195                 convertor.AddKeyframe(
196                     AnimationType::TRANSLATE_Z, time, TranslateOperation(Dimension {}, Dimension {}, dz));
197             } },
198         { DOM_TRANSLATE_3D,
__anonc5ef80110602() 199             [](const std::string& typeValue, const double& time, TransformConvertor& convertor) {
200                 std::vector<std::string> offsets;
201                 StringUtils::StringSplitter(typeValue, ' ', offsets);
202                 if (offsets.size() == PARAM_THREE) {
203                     auto dx = StringUtils::StringToDimension(offsets[0]);
204                     auto dy = StringUtils::StringToDimension(offsets[1]);
205                     auto dz = StringUtils::StringToDimension(offsets[2]);
206 
207                     convertor.AddKeyframe(AnimationType::TRANSLATE_3D, time, TranslateOperation(dx, dy, dz));
208                 }
209             } },
210         { DOM_ROTATE_3D,
__anonc5ef80110702() 211             [](const std::string& typeValue, const double& time, TransformConvertor& convertor) {
212                 std::vector<std::string> offsets;
213                 StringUtils::StringSplitter(typeValue, ' ', offsets);
214                 if (offsets.size() == PARAM_FOUR) {
215                     auto dx = static_cast<float>(StringUtils::StringToDouble(offsets[0]));
216                     auto dy = static_cast<float>(StringUtils::StringToDouble(offsets[1]));
217                     auto dz = static_cast<float>(StringUtils::StringToDouble(offsets[2]));
218                     auto degree = StringUtils::StringToDegree(offsets[3]);
219                     convertor.AddKeyframe(
220                         AnimationType::ROTATE_3D, time, RotateOperation { dx, dy, dz, static_cast<float>(degree) });
221                 }
222             } },
223         { DOM_ROTATE,
__anonc5ef80110802() 224             [](const std::string& typeValue, const double& time, TransformConvertor& convertor) {
225                 auto degree = StringUtils::StringToDegree(typeValue);
226                 convertor.AddKeyframe(
227                     AnimationType::ROTATE, time, RotateOperation { 0, 0, 1, static_cast<float>(degree) });
228             } },
229         { DOM_ROTATE_X,
__anonc5ef80110902() 230             [](const std::string& typeValue, const double& time, TransformConvertor& convertor) {
231                 auto degree = StringUtils::StringToDegree(typeValue);
232                 convertor.AddKeyframe(
233                     AnimationType::ROTATE_X, time, RotateOperation { 1, 0, 0, static_cast<float>(degree) });
234             } },
235         { DOM_ROTATE_Y,
__anonc5ef80110a02() 236             [](const std::string& typeValue, const double& time, TransformConvertor& convertor) {
237                 auto degree = StringUtils::StringToDegree(typeValue);
238                 convertor.AddKeyframe(
239                     AnimationType::ROTATE_Y, time, RotateOperation { 0, 1, 0, static_cast<float>(degree) });
240             } },
241         { DOM_ROTATE_Z,
__anonc5ef80110b02() 242             [](const std::string& typeValue, const double& time, TransformConvertor& convertor) {
243                 auto degree = StringUtils::StringToDegree(typeValue);
244                 convertor.AddKeyframe(
245                     AnimationType::ROTATE_Z, time, RotateOperation { 0, 0, 1, static_cast<float>(degree) });
246             } },
247         { DOM_SCALE,
__anonc5ef80110c02() 248             [](const std::string& typeValue, const double& time, TransformConvertor& convertor) {
249                 if (typeValue.find(' ') != std::string::npos) {
250                     std::vector<std::string> values;
251                     StringUtils::StringSplitter(typeValue, ' ', values);
252                     if (values.size() == PARAM_DOUBLE) {
253                         double scaleValueX = StringUtils::StringToDouble(values[0]);
254                         double scaleValueY = StringUtils::StringToDouble(values[1]);
255                         convertor.AddKeyframe(
256                             AnimationType::SCALE, time, ScaleOperation(scaleValueX, scaleValueY, 1.0f));
257                     }
258                 } else {
259                     auto scale = static_cast<float>(StringUtils::StringToDouble(typeValue));
260                     convertor.AddKeyframe(AnimationType::SCALE, time, ScaleOperation(scale, scale, 1.0f));
261                 }
262             } },
263         { DOM_SCALE_X,
__anonc5ef80110d02() 264             [](const std::string& typeValue, const double& time, TransformConvertor& convertor) {
265                 auto scaleX = static_cast<float>(StringUtils::StringToDouble(typeValue));
266                 convertor.AddKeyframe(AnimationType::SCALE_X, time, ScaleOperation(scaleX, 1.0f, 1.0f));
267             } },
268         { DOM_SCALE_Y,
__anonc5ef80110e02() 269             [](const std::string& typeValue, const double& time, TransformConvertor& convertor) {
270                 auto scaleY = static_cast<float>(StringUtils::StringToDouble(typeValue));
271                 convertor.AddKeyframe(AnimationType::SCALE_Y, time, ScaleOperation(1.0f, scaleY, 1.0f));
272             } },
273         { DOM_SCALE_Z,
__anonc5ef80110f02() 274             [](const std::string& typeValue, const double& time, TransformConvertor& convertor) {
275                 auto scaleZ = static_cast<float>(StringUtils::StringToDouble(typeValue));
276                 convertor.AddKeyframe(AnimationType::SCALE_Z, time, ScaleOperation(1.0f, 1.0f, scaleZ));
277             } },
278         { DOM_SCALE_3D,
__anonc5ef80111002() 279             [](const std::string& typeValue, const double& time, TransformConvertor& convertor) {
280                 std::vector<std::string> offsets;
281                 StringUtils::StringSplitter(typeValue, ' ', offsets);
282                 if (offsets.size() == PARAM_THREE) {
283                     auto scaleX = static_cast<float>(StringUtils::StringToDouble(offsets[0]));
284                     auto scaleY = static_cast<float>(StringUtils::StringToDouble(offsets[1]));
285                     auto scaleZ = static_cast<float>(StringUtils::StringToDouble(offsets[2]));
286                     convertor.AddKeyframe(AnimationType::SCALE_3D, time, ScaleOperation(scaleX, scaleY, scaleZ));
287                 }
288             } },
289         { DOM_SKEW,
__anonc5ef80111102() 290             [](const std::string& typeValue, const double& time, TransformConvertor& convertor) {
291                 std::vector<std::string> offsets;
292                 StringUtils::StringSplitter(typeValue, ' ', offsets);
293                 if (offsets.size() == PARAM_DOUBLE) {
294                     auto degreeX = static_cast<float>(StringUtils::StringToDegree(offsets[0]));
295                     auto degreeY = static_cast<float>(StringUtils::StringToDegree(offsets[1]));
296                     convertor.AddKeyframe(AnimationType::SKEW, time, SkewOperation { degreeX, degreeY });
297                 } else if (offsets.size() == PARAM_SINGLE) {
298                     auto degreeX = static_cast<float>(StringUtils::StringToDegree(typeValue));
299                     convertor.AddKeyframe(AnimationType::SKEW, time, SkewOperation { degreeX, 0.0f });
300                 }
301             } },
302         { DOM_SKEW_X,
__anonc5ef80111202() 303             [](const std::string& typeValue, const double& time, TransformConvertor& convertor) {
304                 auto degreeX = static_cast<float>(StringUtils::StringToDegree(typeValue));
305                 convertor.AddKeyframe(AnimationType::SKEW_X, time, SkewOperation { degreeX, 0.0f });
306             } },
307         { DOM_SKEW_Y,
__anonc5ef80111302() 308             [](const std::string& typeValue, const double& time, TransformConvertor& convertor) {
309                 auto degreeY = static_cast<float>(StringUtils::StringToDegree(typeValue));
310                 convertor.AddKeyframe(AnimationType::SKEW_Y, time, SkewOperation { 0.0f, degreeY });
311             } },
312         { DOM_MATRIX_3D,
__anonc5ef80111402() 313             [](const std::string& typeValue, const double& time, TransformConvertor& convertor) {
314                 std::vector<std::string> offsets;
315                 StringUtils::StringSplitter(typeValue, ' ', offsets);
316                 if (offsets.size() == PARAM_SIXTEEN) {
317                     std::vector<double> matrix;
318                     for (const auto& offset : offsets) {
319                         matrix.push_back(StringUtils::StringToDouble(offset));
320                     }
321                     Matrix4 m(matrix[0], matrix[4], matrix[8], matrix[12],
322                               matrix[1], matrix[5], matrix[9], matrix[13],
323                               matrix[2], matrix[6], matrix[10], matrix[14],
324                               matrix[3], matrix[7], matrix[11], matrix[15]);
325                     convertor.AddKeyframe(AnimationType::MATRIX_3D, time, m);
326                 }
327             } },
328         { DOM_MATRIX,
__anonc5ef80111502() 329             [](const std::string& typeValue, const double& time, TransformConvertor& convertor) {
330                 std::vector<std::string> offsets;
331                 StringUtils::StringSplitter(typeValue, ' ', offsets);
332                 if (offsets.size() == PARAM_SIX) {
333                     double scaleX = StringUtils::StringToDouble(offsets[0]);
334                     double skewY = StringUtils::StringToDouble(offsets[1]);
335                     double skewX = StringUtils::StringToDouble(offsets[2]);
336                     double scaleY = StringUtils::StringToDouble(offsets[3]);
337                     double translateX = StringUtils::StringToDouble(offsets[4]);
338                     double translateY = StringUtils::StringToDouble(offsets[5]);
339                     Matrix4 matrix = Matrix4::CreateMatrix2D(scaleX, skewY, skewX, scaleY, translateX, translateY);
340                     convertor.AddKeyframe(AnimationType::MATRIX_2D, time, matrix);
341                 }
342             } },
343         { DOM_PERSPECTIVE,
__anonc5ef80111602() 344             [](const std::string& typeValue, const double& time, TransformConvertor& convertor) {
345                 auto distance = StringUtils::StringToDimension(typeValue);
346                 convertor.AddKeyframe(AnimationType::PERSPECTIVE, time, PerspectiveOperation(distance));
347             } },
348     };
349 
350 } // namespace OHOS::Ace
351