1 /*
2  * Copyright (c) 2022 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_ng/svg/svg_context.h"
17 
18 #include "core/common/thread_checker.h"
19 #include "core/components_ng/svg/parse/svg_node.h"
20 
21 namespace OHOS::Ace::NG {
22 namespace {
23     constexpr int32_t MILLISECOND_DIVIDER = 1000;
24 }
GetSvgNodeById(const std::string & id) const25 RefPtr<SvgNode> SvgContext::GetSvgNodeById(const std::string& id) const
26 {
27     auto item = idMapper_.find(id);
28     if (item != idMapper_.end()) {
29         return item->second.Upgrade();
30     }
31     return nullptr;
32 }
33 
PushStyle(const std::string & styleName,const std::pair<std::string,std::string> & attrPair)34 void SvgContext::PushStyle(const std::string& styleName, const std::pair<std::string, std::string>& attrPair)
35 {
36     const auto& arrMapIter = styleMap_.find(styleName);
37     if (arrMapIter == styleMap_.end()) {
38         AttrMap attrMap;
39         attrMap.emplace(attrPair);
40         styleMap_.emplace(std::make_pair(styleName, attrMap));
41     } else {
42         if (arrMapIter->second.find(attrPair.first) != arrMapIter->second.end()) {
43             arrMapIter->second.erase(attrPair.first);
44         }
45         arrMapIter->second.emplace(attrPair);
46     }
47 }
48 
GetAttrMap(const std::string & key) const49 const AttrMap& SvgContext::GetAttrMap(const std::string& key) const
50 {
51     auto styleClassIter = styleMap_.find(key);
52     if (styleClassIter != styleMap_.end()) {
53         return styleClassIter->second;
54     }
55     static AttrMap emptyMap;
56     return emptyMap;
57 }
58 
AddAnimator(int32_t key,const RefPtr<Animator> & animator)59 void SvgContext::AddAnimator(int32_t key, const RefPtr<Animator>& animator)
60 {
61     animators_[key] = animator;
62 }
63 
RemoveAnimator(int32_t key)64 void SvgContext::RemoveAnimator(int32_t key)
65 {
66     animators_.erase(key);
67 }
68 
ControlAnimators(bool play)69 void SvgContext::ControlAnimators(bool play)
70 {
71     for (auto it = animators_.begin(); it != animators_.end();) {
72         auto animator = it->second.Upgrade();
73         if (!animator) {
74             LOGW("null animator in map");
75             it = animators_.erase(it);
76             continue;
77         }
78         if (play) {
79             animator->Play();
80         } else {
81             animator->Pause();
82         }
83         ++it;
84     }
85 }
86 
SetOnAnimationFinished(const std::function<void ()> & onFinishCallback)87 void SvgContext::SetOnAnimationFinished(const std::function<void()>& onFinishCallback)
88 {
89     onFinishCallback_ = std::move(onFinishCallback);
90 }
91 
OnAnimationFinished()92 void SvgContext::OnAnimationFinished()
93 {
94     onFinishCallback_();
95 }
96 
SetFuncAnimateFlush(FuncAnimateFlush && funcAnimateFlush,const WeakPtr<CanvasImage> & imagePtr)97 void SvgContext::SetFuncAnimateFlush(FuncAnimateFlush&& funcAnimateFlush, const WeakPtr<CanvasImage>& imagePtr)
98 {
99     CHECK_NULL_VOID(funcAnimateFlush);
100     animateCallbacks_[imagePtr] = funcAnimateFlush;
101 }
102 
AnimateFlush()103 void SvgContext::AnimateFlush()
104 {
105     CHECK_RUN_ON(UI);
106     CHECK_NULL_VOID(!animateCallbacks_.empty());
107     for (auto it = animateCallbacks_.begin(); it != animateCallbacks_.end();) {
108         if (it->first.Upgrade()) {
109             it->second();
110             ++it;
111         } else {
112             it = animateCallbacks_.erase(it);
113         }
114     }
115 }
116 
SetFuncNormalizeToPx(const FuncNormalizeToPx & funcNormalizeToPx)117 void SvgContext::SetFuncNormalizeToPx(const FuncNormalizeToPx& funcNormalizeToPx)
118 {
119     funcNormalizeToPx_ = funcNormalizeToPx;
120 }
121 
CreateDumpInfo(SvgDumpInfo dumpInfo)122 void SvgContext::CreateDumpInfo(SvgDumpInfo dumpInfo)
123 {
124     dumpInfo_ = dumpInfo;
125 }
126 
GetDumpInfo()127 SvgDumpInfo& SvgContext::GetDumpInfo()
128 {
129     return dumpInfo_;
130 }
131 
NormalizeToPx(const Dimension & value)132 double SvgContext::NormalizeToPx(const Dimension& value)
133 {
134     if (funcNormalizeToPx_ == nullptr) {
135         return 0.0;
136     }
137     return funcNormalizeToPx_(value);
138 }
139 
GetCurrentTimeString()140 std::string SvgContext::GetCurrentTimeString()
141 {
142     auto now = std::chrono::system_clock::now();
143     std::time_t nowTime = std::chrono::system_clock::to_time_t(now);
144     std::tm* now_time = std::localtime(&nowTime);
145     std::chrono::milliseconds ms = std::chrono::duration_cast<std::chrono::milliseconds>(
146         now.time_since_epoch()) % MILLISECOND_DIVIDER;
147     std::ostringstream oss;
148     oss << std::put_time(now_time, "%Y-%m-%d %H:%M:%S:");
149     return oss.str().append(std::to_string(ms.count()));
150 }
151 } // namespace OHOS::Ace::NG
152