1 /* 2 * Copyright (c) 2022-2023 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_NG_SVG_PARSE_SVG_NODE_H 17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_SVG_PARSE_SVG_NODE_H 18 19 #include <vector> 20 21 #ifndef USE_ROSEN_DRAWING 22 #include "include/core/SkCanvas.h" 23 #include "include/core/SkPath.h" 24 #endif 25 26 #include "base/memory/ace_type.h" 27 #include "base/utils/noncopyable.h" 28 #include "core/animation/svg_animate.h" 29 #include "core/components/declaration/svg/svg_base_declaration.h" 30 #include "core/components_ng/render/drawing_forward.h" 31 #ifdef USE_ROSEN_DRAWING 32 #include "core/components_ng/render/drawing.h" 33 #endif 34 #include "core/components_ng/svg/svg_context.h" 35 36 namespace OHOS::Ace::NG { 37 enum class SvgLengthType { 38 HORIZONTAL, 39 VERTICAL, 40 OTHER, 41 }; 42 43 class SvgContext; 44 class SvgAnimation; 45 46 // three level inherit class, for example: 47 // 1. SvgMask::SvgQuote::SvgNode 48 // 2. SvgPath::SvgGraphic::SvgNode 49 class SvgNode : public AceType { 50 DECLARE_ACE_TYPE(SvgNode, AceType); 51 52 public: 53 SvgNode() = default; 54 ~SvgNode() override = default; 55 56 void InitStyle(const RefPtr<SvgBaseDeclaration>& parent); 57 58 // draw entrance function, approve override by second level class. 59 virtual void Draw(RSCanvas& canvas, const Size& viewPort, const std::optional<Color>& color); 60 61 virtual void SetAttr(const std::string& name, const std::string& value); 62 AppendChild(const RefPtr<SvgNode> & child)63 virtual void AppendChild(const RefPtr<SvgNode>& child) 64 { 65 children_.emplace_back(child); 66 OnAppendChild(child); 67 } 68 Inherit(const RefPtr<SvgBaseDeclaration> & parent)69 virtual void Inherit(const RefPtr<SvgBaseDeclaration>& parent) 70 { 71 if (declaration_) { 72 declaration_->Inherit(parent); 73 } 74 } 75 76 #ifndef USE_ROSEN_DRAWING AsPath(const Size & viewPort)77 virtual SkPath AsPath(const Size& viewPort) const 78 #else 79 virtual RSRecordingPath AsPath(const Size& viewPort) const 80 #endif 81 { 82 return {}; 83 } 84 85 virtual RSPath AsRSPath(const Size& viewPort) const; 86 AsBounds(const Size & viewPort)87 Rect AsBounds(const Size& viewPort) const 88 { 89 #ifndef USE_ROSEN_DRAWING 90 auto bounds = AsPath(viewPort).getBounds(); 91 return { bounds.left(), bounds.top(), bounds.width(), bounds.height() }; 92 #else 93 auto bounds = AsPath(viewPort).GetBounds(); 94 return { bounds.GetLeft(), bounds.GetTop(), bounds.GetWidth(), bounds.GetHeight() }; 95 #endif 96 } 97 SetContext(const WeakPtr<SvgContext> & svgContext)98 void SetContext(const WeakPtr<SvgContext>& svgContext) 99 { 100 svgContext_ = svgContext; 101 } 102 SetNodeId(const std::string & value)103 void SetNodeId(const std::string& value) 104 { 105 nodeId_ = value; 106 } 107 SetText(const std::string & text)108 void SetText(const std::string& text) 109 { 110 text_ = text; 111 } 112 SetSmoothEdge(float value)113 void SetSmoothEdge(float value) 114 { 115 smoothEdge_ = value; 116 } 117 GetSmoothEdge()118 float GetSmoothEdge() const 119 { 120 return smoothEdge_; 121 } 122 GetDeclaration()123 RefPtr<SvgBaseDeclaration> GetDeclaration() 124 { 125 return declaration_; 126 } 127 128 protected: 129 // override as need by derived class 130 // called by function AppendChild OnAppendChild(const RefPtr<SvgNode> & child)131 virtual void OnAppendChild(const RefPtr<SvgNode>& child) {} 132 // called by function InitStyle OnInitStyle()133 virtual void OnInitStyle() {} 134 // function override by graphic tag OnDraw(RSCanvas & canvas,const Size & viewPort,const std::optional<Color> & color)135 virtual void OnDraw(RSCanvas& canvas, const Size& viewPort, const std::optional<Color>& color) {} 136 137 virtual void OnDrawTraversed(RSCanvas& canvas, const Size& viewPort, const std::optional<Color>& color); 138 bool OnCanvas(RSCanvas& canvas); 139 void OnClipPath(RSCanvas& canvas, const Size& viewPort); 140 void OnFilter(RSCanvas& canvas, const Size& viewPort); 141 void OnMask(RSCanvas& canvas, const Size& viewPort); 142 void OnTransform(RSCanvas& canvas, const Size& viewPort); 143 144 double ConvertDimensionToPx(const Dimension& value, const Size& viewPort, SvgLengthType type) const; 145 double ConvertDimensionToPx(const Dimension& value, double baseValue) const; 146 147 std::optional<Gradient> GetGradient(const std::string& href); 148 const Rect& GetRootViewBox() const; 149 150 virtual void PrepareAnimation(const RefPtr<SvgAnimation>& animate); 151 // create animation that changes an attribute 152 template<typename T> 153 void AnimateOnAttribute(const RefPtr<SvgAnimation>& animate, const T& originalValue); 154 // animate a transformation attribute 155 void AnimateTransform(const RefPtr<SvgAnimation>& animate, double originalValue); 156 void AnimateFromToTransform(const RefPtr<SvgAnimation>& animate, double originalValue); 157 void AnimateFrameTransform(const RefPtr<SvgAnimation>& animate, double originalValue); 158 159 // update svg attribute in animation 160 template<typename T> 161 void UpdateAttr(const std::string& name, const T& val); 162 void UpdateAttrHelper(const std::string& name, const std::string& val); 163 164 // defs gradient animation InitNoneFlag()165 void InitNoneFlag() 166 { 167 hrefFill_ = false; 168 hrefRender_ = false; 169 passStyle_ = false; 170 inheritStyle_ = false; 171 drawTraversed_ = false; 172 } 173 174 WeakPtr<SvgContext> svgContext_; 175 RefPtr<SvgBaseDeclaration> declaration_; 176 std::vector<RefPtr<SvgNode>> children_; 177 std::string nodeId_; 178 std::string text_; 179 std::string transform_; 180 std::map<std::string, std::vector<float>> animateTransform_; 181 182 std::string hrefClipPath_; 183 std::string hrefMaskId_; 184 std::string hrefFilterId_; 185 uint8_t opacity_ = 0xFF; 186 float smoothEdge_ = 0.0f; 187 188 bool hrefFill_ = true; // get fill attributes from reference 189 bool hrefRender_ = true; // get render attr (mask, filter, transform, opacity, clip path) from reference 190 bool passStyle_ = true; // pass style attributes to child node, TAGS circle/path/line/... = false 191 bool inheritStyle_ = true; // inherit style attributes from parent node, TAGS mask/defs/pattern/filter = false 192 bool drawTraversed_ = true; // enable OnDraw, TAGS mask/defs/pattern/filter = false 193 194 #ifndef USE_ROSEN_DRAWING 195 SkCanvas* skCanvas_ = nullptr; 196 #else 197 RSCanvas* rsCanvas_ = nullptr; 198 #endif 199 200 ACE_DISALLOW_COPY_AND_MOVE(SvgNode); 201 }; 202 203 } // namespace OHOS::Ace::NG 204 205 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_SVG_PARSE_SVG_NODE_H