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_PARSE_SVG_DOM_H
17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_SVG_PARSE_SVG_DOM_H
18 
19 #include <unordered_map>
20 #include <stack>
21 #include "src/xml/SkDOM.h"
22 #include "src/xml/SkXMLParser.h"
23 #include "src/xml/SkXMLWriter.h"
24 
25 #include "base/log/log.h"
26 #include "base/memory/ace_type.h"
27 #include "core/animation/animator_group.h"
28 #include "frameworks/core/components/svg/parse/svg_context.h"
29 #include "frameworks/core/components/svg/parse/svg_node.h"
30 #include "frameworks/core/components/svg/parse/svg_style.h"
31 
32 namespace OHOS::Ace {
33 
34 struct SvgRadius {
35     Radius topLeft;
36     Radius topRight;
37     Radius bottomLeft;
38     Radius bottomRight;
39 
IsValidSvgRadius40     bool IsValid() const
41     {
42         return topLeft.IsValid() || topRight.IsValid() || bottomLeft.IsValid() || bottomRight.IsValid();
43     }
44 };
45 
46 struct SvgRenderTree {
47     RefPtr<RenderNode> root;
48     RefPtr<RenderNode> clipBox;
49     RefPtr<RenderNode> transform;
50     RefPtr<RenderNode> svgRoot;
51     Size svgSize;
52     Size containerSize;
53     bool svgAnimate = false;
54 
ClearRenderObjectSvgRenderTree55     void ClearRenderObject()
56     {
57         root = nullptr;
58         clipBox = nullptr;
59         transform = nullptr;
60     }
61 };
62 
63 class SvgDom : public AceType {
64     DECLARE_ACE_TYPE(SvgDom, AceType);
65 
66 public:
67     explicit SvgDom(const WeakPtr<PipelineContext>& context);
68     ~SvgDom() override;
69     static RefPtr<SvgDom> CreateSvgDom(SkStream& svgStream, const WeakPtr<PipelineContext>& context,
70         const std::optional<Color>& svgThemeColor);
71     bool ParseSvg(SkStream& svgStream);
72     void CreateRenderNode(ImageFit imageFit, const SvgRadius& svgRadius, bool useBox = true);
73     void UpdateLayout(ImageFit imageFit, const SvgRadius& svgRadius, bool useBox = true);
74     void PaintDirectly(RenderContext& context, const Offset& offset);
75 #ifdef ENABLE_ROSEN_BACKEND
76     void PaintDirectly(RenderContext& context, const Offset& offset, ImageFit imageFit, Size layout);
77 #endif
78     SvgRenderTree GetSvgRenderTree() const;
79     SvgRenderTree CreateRenderTree(ImageFit imageFit, const SvgRadius& svgRadius, bool useBox = true);
80     void SetSvgRenderTree(const SvgRenderTree& svgRenderTree);
81 
SetContainerSize(const Size & size)82     void SetContainerSize(const Size& size)
83     {
84         containerSize_ = size;
85     }
86 
GetContainerSize()87     const Size& GetContainerSize() const
88     {
89         return containerSize_;
90     }
91 
GetRootRenderNode()92     RefPtr<RenderNode> GetRootRenderNode() const
93     {
94         return renderNode_;
95     }
96 
GetRootSvgRenderNode()97     RefPtr<RenderNode> GetRootSvgRenderNode() const
98     {
99         return svgRoot_.Upgrade();
100     }
101 
SetFinishEvent(const EventMarker & finishEvent)102     void SetFinishEvent(const EventMarker& finishEvent)
103     {
104         finishEvent_ = finishEvent;
105     }
106 
SetHasClipPath(bool hasClipPath)107     void SetHasClipPath(bool hasClipPath)
108     {
109         hasClipPath_ = hasClipPath;
110     }
111 
HasClipPath()112     bool HasClipPath()
113     {
114         return hasClipPath_;
115     }
116 
HasAnimate()117     bool HasAnimate() const
118     {
119         return svgAnimate_;
120     }
121 
122 private:
123     void InitAnimatorGroup(const RefPtr<RenderNode>& node);
124     void AddToAnimatorGroup(const RefPtr<RenderNode>& node, RefPtr<AnimatorGroup>& animatorGroup);
125 
126     RefPtr<SvgNode> TranslateSvgNode(const SkDOM& dom, const SkDOM::Node* xmlNode, const RefPtr<SvgNode>& parent);
127     void ParseAttrs(const SkDOM& xmlDom, const SkDOM::Node* xmlNode, const RefPtr<SvgNode>& svgNode);
128     void SetAttrValue(const std::string& name, const std::string& value, const RefPtr<SvgNode>& svgNode);
129     void ParseIdAttr(const WeakPtr<SvgNode>& weakSvgNode, const std::string& value);
130     void ParseFillAttr(const WeakPtr<SvgNode>& weakSvgNode, const std::string& value);
131     void ParseClassAttr(const WeakPtr<SvgNode>& weakSvgNode, const std::string& value);
132     void ParseStyleAttr(const WeakPtr<SvgNode>& weakSvgNode, const std::string& value);
133     void ApplyImageFit(ImageFit imageFit, double& scaleX, double& scaleY);
134     void ApplyFill(double& scaleX, double& scaleY);
135     void ApplyContain(double& scaleX, double& scaleY);
136     void ApplyCover(double& scaleX, double& scaleY);
137     void SyncRSNode(const RefPtr<RenderNode>& renderNode);
138 
139     WeakPtr<PipelineContext> context_;
140     RefPtr<SvgContext> svgContext_;
141     RefPtr<SvgNode> root_;
142     RefPtr<RenderNode> renderNode_;
143     WeakPtr<RenderNode> svgRoot_;
144     WeakPtr<RenderNode> clipBox_;
145     WeakPtr<RenderNode> transform_;
146     Size containerSize_;
147     Size svgSize_;
148     RefPtr<AnimatorGroup> animatorGroup_ = nullptr;
149     EventMarker finishEvent_;
150     std::optional<Color> fillColor_;
151     PushAttr attrCallback_;
152     bool svgAnimate_ = false;
153     bool hasClipPath_ = false;
154 };
155 
156 } // namespace OHOS::Ace
157 
158 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_SVG_PARSE_SVG_DOM_H