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/core/components/svg/parse/svg_animation.h"
17 
18 #include "frameworks/bridge/common/utils/utils.h"
19 
20 namespace OHOS::Ace {
21 
22 namespace {
23 
24 const char DOM_SVG_SRC_REPEAT_COUNT[] = "repeatCount";
25 const char DOM_SVG_SRC_ATTRIBUTE_NAME[] = "attributeName";
26 
27 } // namespace
28 
29 using namespace Framework;
30 using SvgMap = std::unordered_map<std::string, void (*)(const std::string&, const RefPtr<SvgAnimateComponent>&)>;
31 
SvgAnimation(SvgAnimateType svgAnimateType)32 SvgAnimation::SvgAnimation(SvgAnimateType svgAnimateType) : SvgNode()
33 {
34     component_ = AceType::MakeRefPtr<SvgAnimateComponent>("svg_animate_nodeId", "animate", svgAnimateType);
35 }
36 
CreateAnimate()37 RefPtr<SvgNode> SvgAnimation::CreateAnimate()
38 {
39     return AceType::MakeRefPtr<SvgAnimation>(SvgAnimateType::ANIMATE);
40 }
41 
CreateAnimateTransform()42 RefPtr<SvgNode> SvgAnimation::CreateAnimateTransform()
43 {
44     return AceType::MakeRefPtr<SvgAnimation>(SvgAnimateType::TRANSFORM);
45 }
46 
CreateAnimateMotion()47 RefPtr<SvgNode> SvgAnimation::CreateAnimateMotion()
48 {
49     return AceType::MakeRefPtr<SvgAnimation>(SvgAnimateType::MOTION);
50 }
51 
SetAttr(const std::string & name,const std::string & value)52 void SvgAnimation::SetAttr(const std::string& name, const std::string& value)
53 {
54     static const SvgMap svgMap = {
55         { DOM_SVG_ANIMATION_BEGIN,
56             [](const std::string& val, const RefPtr<SvgAnimateComponent>& animateComponent) {
57                 animateComponent->SetBegin(ConvertTimeStr(val));
58             } },
59         { DOM_SVG_ANIMATION_DUR,
60             [](const std::string& val, const RefPtr<SvgAnimateComponent>& animateComponent) {
61                 if (val == "indefinite") {
62                     animateComponent->SetDur(0);
63                 } else {
64                     animateComponent->SetDur(ConvertTimeStr(val));
65                 }
66             } },
67         { DOM_SVG_ANIMATION_END,
68             [](const std::string& val, const RefPtr<SvgAnimateComponent>& animateComponent) {
69                 animateComponent->SetEnd(ConvertTimeStr(val));
70             } },
71         { DOM_SVG_SRC_REPEAT_COUNT,
72             [](const std::string& val, const RefPtr<SvgAnimateComponent>& animateComponent) {
73                 if (val == "indefinite") {
74                     animateComponent->SetRepeatCount(-1);
75                 } else {
76                     animateComponent->SetRepeatCount(StringToInt(val));
77                 }
78             } },
79         { DOM_SVG_ANIMATION_FILL,
80             [](const std::string& val, const RefPtr<SvgAnimateComponent>& animateComponent) {
81                 Fill fillMode = (val == "freeze" ? Fill::FREEZE : Fill::REMOVE);
82                 animateComponent->SetFillMode(fillMode);
83             } },
84         { DOM_SVG_ANIMATION_CALC_MODE,
85             [](const std::string& val, const RefPtr<SvgAnimateComponent>& animateComponent) {
86                 CalcMode calcMode;
87                 if (val == "discrete") {
88                     calcMode = CalcMode::DISCRETE;
89                 } else if (val == "paced") {
90                     calcMode = CalcMode::PACED;
91                 } else if (val == "spline") {
92                     calcMode = CalcMode::SPLINE;
93                 } else {
94                     calcMode = CalcMode::LINEAR;
95                 }
96                 animateComponent->SetCalcMode(calcMode);
97             } },
98         { DOM_SVG_ANIMATION_VALUES,
99             [](const std::string& val, const RefPtr<SvgAnimateComponent>& animateComponent) {
100                 std::vector<std::string> values;
101                 StringUtils::SplitStr(val, ";", values);
102                 animateComponent->SetValues(values);
103             } },
104         { DOM_SVG_ANIMATION_KEY_TIMES,
105             [](const std::string& val, const RefPtr<SvgAnimateComponent>& animateComponent) {
106                 if (val.empty()) {
107                     return;
108                 }
109                 std::vector<double> keyTimes;
110                 StringUtils::StringSplitter(val, ';', keyTimes);
111                 animateComponent->SetKeyTimes(keyTimes);
112             } },
113         { DOM_SVG_ANIMATION_KEY_SPLINES,
114             [](const std::string& val, const RefPtr<SvgAnimateComponent>& animateComponent) {
115                 if (val.empty()) {
116                     return;
117                 }
118                 std::vector<std::string> keySplines;
119                 StringUtils::SplitStr(val, ";", keySplines);
120                 animateComponent->SetKeySplines(keySplines);
121             } },
122         { DOM_SVG_ANIMATION_FROM,
123             [](const std::string& val, const RefPtr<SvgAnimateComponent>& animateComponent) {
124                 animateComponent->SetFrom(val);
125             } },
126         { DOM_SVG_ANIMATION_TO,
127             [](const std::string& val, const RefPtr<SvgAnimateComponent>& animateComponent) {
128                 animateComponent->SetTo(val);
129             } },
130         { DOM_SVG_SRC_ATTRIBUTE_NAME,
131             [](const std::string& val, const RefPtr<SvgAnimateComponent>& animateComponent) {
132                 animateComponent->SetAttributeName(val);
133             } },
134         { DOM_SVG_ANIMATION_KEY_POINTS,
135             [](const std::string& val, const RefPtr<SvgAnimateComponent>& animateComponent) {
136                 if (val.empty()) {
137                     return;
138                 }
139                 std::vector<std::string> keyPoints;
140                 StringUtils::StringSplitter(val, ';', keyPoints);
141                 animateComponent->SetKeyPoints(keyPoints);
142             } },
143         { DOM_SVG_ANIMATION_PATH,
144             [](const std::string& val, const RefPtr<SvgAnimateComponent>& animateComponent) {
145                 animateComponent->SetPath(val);
146             } },
147         { DOM_SVG_ANIMATION_ROTATE,
148             [](const std::string& val, const RefPtr<SvgAnimateComponent>& animateComponent) {
149                 animateComponent->SetRotate(val);
150             } },
151         { DOM_SVG_ANIMATION_TYPE,
152             [](const std::string& val, const RefPtr<SvgAnimateComponent>& animateComponent) {
153                 animateComponent->SetTransformType(val);
154             } },
155     };
156     auto attrIter = svgMap.find(name);
157     if (attrIter != svgMap.end()) {
158         attrIter->second(value, component_);
159     }
160 }
161 
162 } // namespace OHOS::Ace
163