1 /*
2  * Copyright (c) 2021-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 #ifndef FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_SVG_RENDER_SVG_BASE_H
17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_SVG_RENDER_SVG_BASE_H
18 
19 #include "frameworks/core/animation/animator.h"
20 #include "frameworks/core/animation/keyframe_animation.h"
21 #include "frameworks/core/animation/svg_animate.h"
22 #include "frameworks/core/components/common/properties/svg_paint_state.h"
23 #include "frameworks/core/components/declaration/svg/svg_base_declaration.h"
24 #include "frameworks/core/components/svg/svg_animate_component.h"
25 #include "frameworks/core/components/svg/svg_transform.h"
26 #include "frameworks/core/pipeline/base/render_node.h"
27 
28 namespace OHOS::Ace {
29 
30 const char ATTR_NAME_WIDTH[] = "width";
31 const char ATTR_NAME_HEIGHT[] = "height";
32 const char ATTR_NAME_X[] = "x";
33 const char ATTR_NAME_Y[] = "y";
34 const char ATTR_NAME_RX[] = "rx";
35 const char ATTR_NAME_RY[] = "ry";
36 const char ATTR_NAME_OPACITY[] = "opacity";
37 
38 enum class LengthType {
39     HORIZONTAL,
40     VERTICAL,
41     OTHER,
42 };
43 
44 class RenderSvgBase : public RenderNode {
45     DECLARE_ACE_TYPE(RenderSvgBase, RenderNode);
46 
47 public:
48     ~RenderSvgBase() override;
49 
50     virtual void PaintDirectly(RenderContext& context, const Offset& offset);
51 
UpdateMotion(const std::string & path,const std::string & rotate,double percent)52     virtual void UpdateMotion(const std::string& path, const std::string& rotate, double percent) {}
53 
PrepareSelfAnimation(const RefPtr<SvgAnimate> & SvgAnimate)54     virtual bool PrepareSelfAnimation(const RefPtr<SvgAnimate>& SvgAnimate)
55     {
56         return false;
57     }
58 
59     // return paint bounds of svg element path
GetPaintBounds(const Offset & offset)60     virtual Rect GetPaintBounds(const Offset& offset)
61     {
62         return GetPaintRect();
63     }
64 
GetFillState()65     const FillState& GetFillState() const
66     {
67         return fillState_;
68     }
69 
GetStrokeState()70     const StrokeState GetStrokeState() const
71     {
72         return strokeState_;
73     }
74 
GetTextStyle()75     const SvgTextStyle GetTextStyle() const
76     {
77         return textStyle_;
78     }
79 
GetClipState()80     const ClipState GetClipState() const
81     {
82         return clipState_;
83     }
84 
IsSvgNode()85     bool IsSvgNode() const
86     {
87         return isSvgNode_;
88     }
89 
NeedTransform()90     bool NeedTransform() const
91     {
92         return (!animateTransformAttrs_.empty() || !transform_.empty());
93     }
94 
GetAnimators()95     const std::unordered_map<std::string, RefPtr<Animator>>& GetAnimators() const
96     {
97         return animators_;
98     }
99 
SetSvgRoot(const RefPtr<RenderSvgBase> & svgRoot)100     void SetSvgRoot(const RefPtr<RenderSvgBase>& svgRoot)
101     {
102         rootSvgNode_ = svgRoot;
103     }
104 
105     RefPtr<Component> GetComponentHrefFromRoot(const std::string& id);
106     RefPtr<SvgBaseDeclaration> GetDeclarationHrefFromRoot(const std::string& id);
107     RefPtr<RenderSvgBase> GetHrefFromRoot(const std::string& id);
108     RefPtr<RenderSvgBase> GetMaskFromRoot(const std::string& id);
109     RefPtr<RenderSvgBase> GetPatternFromRoot(const std::string& id);
110     RefPtr<RenderSvgBase> GetFilterFromRoot(const std::string& id);
111 
112     void Inherit(const RefPtr<SvgBaseDeclaration>& parent, const RefPtr<SvgBaseDeclaration>& self);
113 
114 protected:
115     bool PrepareBaseAnimation(const RefPtr<SvgAnimate>& animateComponent);
116     template<typename T>
117     bool CreatePropertyAnimation(
118         const RefPtr<SvgAnimate>& component, const T& originalValue, std::function<void(T value)>&& callback);
119     template<typename T>
120     bool SetPresentationProperty(const std::string& attrName, const T& val, bool isSelf = true);
121 
122     bool SetTransformProperty(
123         const std::string& type, const std::vector<float>& from, const std::vector<float>& to, double value);
124 
125     double ConvertDimensionToPx(const Dimension& value, double baseValue);
126 
127     double ConvertDimensionToPx(const Dimension& value, LengthType type, bool isRoot = false);
128 
129     void SetPresentationAttrs(const RefPtr<SvgBaseDeclaration>& baseDeclaration);
130     void SetPresentationAttrs(const RefPtr<Component>& component, const RefPtr<SvgBaseDeclaration>& baseDeclaration);
131 
132     void PrepareWeightAnimate(const RefPtr<SvgAnimate>& svgAnimate, std::vector<std::string>& valueVector,
133         const std::string& originalValue, bool& isBy);
134 
135     void PrepareAnimation(const std::list<RefPtr<Component>>& componentChildren);
136     bool PreparePropertyAnimation(const RefPtr<SvgAnimate>& svgAnimate);
137 
138     std::tuple<const Matrix4, float, float> GetRawTransformInfo();
139     const Matrix4 GetTransformMatrix4();
140     const Matrix4 GetTransformMatrix4Raw(); // for directly paint
141     const Matrix4 UpdateTransformMatrix4();
142 
143     void AddComponentHrefToRoot(const std::string& id, const RefPtr<Component>& component);
144     void AddDeclarationHrefToRoot(const std::string& id, const RefPtr<SvgBaseDeclaration>& declaration);
145     void AddHrefToRoot(const std::string& id, const RefPtr<RenderSvgBase>& node);
146     void AddMaskToRoot(const std::string& id, const RefPtr<RenderSvgBase>& mask);
147     void AddPatternToRoot(const std::string& id, const RefPtr<RenderSvgBase>& pattern);
148     void AddFilterToRoot(const std::string& id, const RefPtr<RenderSvgBase>& filter);
149     const Rect GetViewBoxFromRoot();
150 
151     void PaintMaskLayer(RenderContext& context, const Offset& svg, const Offset& current);
152     void PaintMaskLayer(RenderContext& context, const Offset& svg, const Rect& bounds); // used for tspan on textpath
153     void UpdateGradient(FillState& fillState);
154     std::pair<Dimension, Dimension> CreateTransformOrigin(const std::string& transformOrigin_) const;
155     Offset GetTransformOffset(bool isRoot = false);
156 
157     FillState fillState_;
158     StrokeState strokeState_;
159     SvgTextStyle textStyle_;
160     ClipState clipState_;
161     std::unordered_map<std::string, RefPtr<Animator>> animators_;
162     bool isSvgNode_ = false;
163     Size svgViewPort_;
164     std::string maskId_;
165     std::string filterId_;
166     std::string transform_;
167     std::pair<Dimension, Dimension> transformOrigin_;
168     std::map<std::string, std::vector<float>> transformAttrs_;
169     std::map<std::string, std::vector<float>> animateTransformAttrs_;
170     std::optional<TransformInfo> transformInfo_ = std::nullopt;
171     WeakPtr<RenderSvgBase> rootSvgNode_ = nullptr;
172     std::optional<Rect> svgViewBox_ = std::nullopt; // which contains viewBox
173     std::string id_;
174 
OnNotifyRender()175     virtual void OnNotifyRender()
176     {
177         MarkNeedRender(true);
178     }
179 
180 private:
181     template<typename T>
182     void PreparePresentationAnimation(const RefPtr<SvgAnimate>& svgAnimate, const T& originalValue);
183     bool PrepareAnimateMotion(const RefPtr<SvgAnimate>& svgAnimate);
184     void PrepareTransformAnimation(const RefPtr<SvgAnimate>& svgAnimate, double originalValue);
185     void PrepareTransformValueAnimation(const RefPtr<SvgAnimate>& svgAnimate, double originalValue);
186     void PrepareTransformFrameAnimation(const RefPtr<SvgAnimate>& svgAnimate, double originalValue);
187     template<typename T>
188     void ChangeChildInheritValue(const RefPtr<RenderNode>& svgBase, const std::string& attrName, T value);
189     bool IsSelfValue(const std::string& attrName);
190     bool HasAnimator(const std::string& attrName);
191     std::string ParseIdFromUrl(const std::string& url);
192 };
193 
194 } // namespace OHOS::Ace
195 
196 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_SVG_RENDER_SVG_BASE_H
197