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 "core/components/declaration/svg/svg_animate_declaration.h"
17 
18 #include "core/components/declaration/common/declaration_constants.h"
19 #include "frameworks/bridge/common/utils/utils.h"
20 
21 namespace OHOS::Ace {
22 
23 using namespace Framework;
24 
25 using SvgMap = std::unordered_map<std::string, void (*)(const std::string&, SvgAnimateDeclaration&)>;
26 
InitSpecialized()27 void SvgAnimateDeclaration::InitSpecialized()
28 {
29     AddSpecializedAttribute(DeclarationConstants::DEFAULT_SVG_ANIMATE_ATTR);
30 }
31 
SetSpecializedAttr(const std::pair<std::string,std::string> & attr)32 bool SvgAnimateDeclaration::SetSpecializedAttr(const std::pair<std::string, std::string>& attr)
33 {
34     return SetAnimateAttr(attr);
35 }
36 
SetAnimateAttr(const std::pair<std::string,std::string> & attr)37 bool SvgAnimateDeclaration::SetAnimateAttr(const std::pair<std::string, std::string>& attr)
38 {
39     static const SvgMap svgMap = {
40         { DOM_SVG_ANIMATION_BEGIN,
41             [](const std::string& val, SvgAnimateDeclaration& declaration) {
42                 declaration.SetBegin(ConvertTimeStr(val));
43             } },
44         { DOM_SVG_ANIMATION_DUR,
45             [](const std::string& val, SvgAnimateDeclaration& declaration) {
46                 if (val == "indefinite") {
47                     declaration.SetDur(0);
48                 } else {
49                     declaration.SetDur(ConvertTimeStr(val));
50                 }
51             } },
52         { DOM_SVG_ANIMATION_END,
53             [](const std::string& val, SvgAnimateDeclaration& declaration) {
54                 declaration.SetEnd(ConvertTimeStr(val));
55             } },
56         { DOM_SVG_ANIMATION_REPEAT_COUNT,
57             [](const std::string& val, SvgAnimateDeclaration& declaration) {
58                 if (val == "indefinite") {
59                     declaration.SetRepeatCount(-1);
60                 } else {
61                     declaration.SetRepeatCount(StringToInt(val));
62                 }
63             } },
64         { DOM_SVG_ANIMATION_FILL,
65             [](const std::string& val, SvgAnimateDeclaration& declaration) {
66                 declaration.SetFillMode(val);
67             } },
68         { DOM_SVG_ANIMATION_CALC_MODE,
69             [](const std::string& val, SvgAnimateDeclaration& declaration) {
70                 declaration.SetCalcMode(val);
71             } },
72         { DOM_SVG_ANIMATION_VALUES,
73             [](const std::string& val, SvgAnimateDeclaration& declaration) {
74                 auto& attrs = declaration.MaybeResetAttribute<SvgAnimateAttribute>(AttributeTag::SPECIALIZED_ATTR);
75                 StringUtils::SplitStr(val, ";", attrs.values);
76             } },
77         { DOM_SVG_ANIMATION_KEY_TIMES,
78             [](const std::string& val, SvgAnimateDeclaration& declaration) {
79                 if (val.empty()) {
80                     return;
81                 }
82                 auto& attrs = declaration.MaybeResetAttribute<SvgAnimateAttribute>(AttributeTag::SPECIALIZED_ATTR);
83                 StringUtils::StringSplitter(val, ';', attrs.keyTimes);
84             } },
85         { DOM_SVG_ANIMATION_KEY_SPLINES,
86             [](const std::string& val, SvgAnimateDeclaration& declaration) {
87                 if (val.empty()) {
88                     return;
89                 }
90                 auto& attrs = declaration.MaybeResetAttribute<SvgAnimateAttribute>(AttributeTag::SPECIALIZED_ATTR);
91                 StringUtils::SplitStr(val, ";", attrs.keySplines);
92             } },
93         { DOM_SVG_ANIMATION_FROM,
94             [](const std::string& val, SvgAnimateDeclaration& declaration) {
95                 declaration.SetFrom(val);
96             } },
97         { DOM_SVG_ANIMATION_TO,
98             [](const std::string& val, SvgAnimateDeclaration& declaration) {
99                 declaration.SetTo(val);
100             } },
101         { DOM_SVG_ANIMATION_ATTRIBUTE_NAME,
102             [](const std::string& val, SvgAnimateDeclaration& declaration) {
103                 declaration.SetAttributeName(val);
104             } },
105         { DOM_SVG_ANIMATION_KEY_POINTS,
106             [](const std::string& val, SvgAnimateDeclaration& declaration) {
107                 if (val.empty()) {
108                     return;
109                 }
110                 auto& attrs = declaration.MaybeResetAttribute<SvgAnimateAttribute>(
111                     AttributeTag::SPECIALIZED_ATTR);
112                 StringUtils::StringSplitter(val, ';', attrs.keyPoints);
113             } },
114         { DOM_SVG_ANIMATION_PATH,
115             [](const std::string& val, SvgAnimateDeclaration& declaration) {
116                 declaration.SetPath(val);
117             } },
118         { DOM_SVG_ANIMATION_ROTATE,
119             [](const std::string& val, SvgAnimateDeclaration& declaration) {
120                 declaration.SetRotate(val);
121             } },
122         { DOM_SVG_ANIMATION_TYPE,
123             [](const std::string& val, SvgAnimateDeclaration& declaration) {
124                 declaration.SetTransformType(val);
125             } },
126     };
127     std::string key = attr.first;
128     // convert key to lower case to match dom_type strings
129     std::transform(key.begin(), key.end(), key.begin(), ::tolower);
130     auto attrIter = svgMap.find(key);
131     if (attrIter != svgMap.end()) {
132         attrIter->second(attr.second, *this);
133         return true;
134     }
135     return false;
136 }
137 
138 } // namespace OHOS::Ace