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 #include "base/memory/ace_type.h" 22 #include "base/utils/noncopyable.h" 23 #include "core/animation/svg_animate.h" 24 #include "core/components_ng/image_provider/svg_dom_base.h" 25 #include "core/components_ng/render/drawing_forward.h" 26 #include "core/components_ng/render/drawing.h" 27 #include "core/components_ng/svg/svg_context.h" 28 #include "core/components_ng/svg/base/svg_bounding_box_context.h" 29 #include "core/components_ng/svg/parse/svg_attributes_parser.h" 30 31 namespace OHOS::Ace::NG { 32 33 class SvgContext; 34 class SvgAnimation; 35 36 struct SvgInitStyleProcessInfo { 37 SvgInitStyleProcessInfo() = default; SvgInitStyleProcessInfoSvgInitStyleProcessInfo38 SvgInitStyleProcessInfo(RefPtr<SvgNode> svgNode) : svgNode(svgNode) {} 39 RefPtr<SvgNode> svgNode = nullptr; // The SVG node currently being processed 40 int32_t childIndex = 0; // Index of the next child node to traverse for the current node 41 }; 42 43 // three level inherit class, for example: 44 // 1. SvgMask::SvgQuote::SvgNode 45 // 2. SvgPath::SvgGraphic::SvgNode 46 class SvgNode : public AceType { 47 DECLARE_ACE_TYPE(SvgNode, AceType); 48 49 public: 50 SvgNode() = default; 51 ~SvgNode() override = default; 52 53 void InitStyle(const SvgBaseAttribute& attr); 54 void ProcessSvgStyle(RefPtr<SvgNode> svgNode, const SvgBaseAttribute& attr); 55 void ProcessChildAnimations(const RefPtr<SvgNode>& currentSvgNode); 56 bool ProcessChildStyle(SvgInitStyleProcessInfo& currentSvgNodeInfo, 57 std::stack<std::pair<SvgInitStyleProcessInfo, const SvgBaseAttribute*>>& initStyleTaskSt); 58 void InitStyleDfs(const WeakPtr<SvgNode>& root, const SvgBaseAttribute& attr); 59 60 // draw entrance function, approve override by second level class. 61 virtual void Draw(RSCanvas& canvas, const Size& viewPort, const std::optional<Color>& color); 62 virtual void Draw(RSCanvas& canvas, const SvgLengthScaleRule& lengthRule); 63 virtual void SetAttr(const std::string& name, const std::string& value); 64 ParseAndSetSpecializedAttr(const std::string & name,const std::string & value)65 virtual bool ParseAndSetSpecializedAttr(const std::string& name, const std::string& value) 66 { 67 return false; 68 } 69 AppendChild(const RefPtr<SvgNode> & child)70 virtual void AppendChild(const RefPtr<SvgNode>& child) 71 { 72 children_.emplace_back(child); 73 OnAppendChild(child); 74 } 75 InheritAttr(const SvgBaseAttribute & parent)76 void InheritAttr(const SvgBaseAttribute& parent) 77 { 78 attributes_.Inherit(parent); 79 } 80 InheritUseAttr(const SvgBaseAttribute & parent)81 void InheritUseAttr(const SvgBaseAttribute& parent) 82 { 83 attributes_.InheritFromUse(parent); 84 } 85 AsPath(const Size & viewPort)86 virtual RSRecordingPath AsPath(const Size& viewPort) const 87 { 88 return {}; 89 } 90 AsPath(const SvgLengthScaleRule & lengthRule)91 virtual RSRecordingPath AsPath(const SvgLengthScaleRule& lengthRule) 92 { 93 return {}; 94 } 95 96 virtual RSPath AsRSPath(const Size& viewPort) const; 97 AsBounds(const Size & viewPort)98 Rect AsBounds(const Size& viewPort) const 99 { 100 auto bounds = AsPath(viewPort).GetBounds(); 101 return { bounds.GetLeft(), bounds.GetTop(), bounds.GetWidth(), bounds.GetHeight() }; 102 } 103 SetContext(const WeakPtr<SvgContext> & svgContext)104 void SetContext(const WeakPtr<SvgContext>& svgContext) 105 { 106 svgContext_ = svgContext; 107 } 108 GetContext()109 WeakPtr<SvgContext>& GetContext() 110 { 111 return svgContext_; 112 } 113 SetNodeId(const std::string & value)114 void SetNodeId(const std::string& value) 115 { 116 nodeId_ = value; 117 } 118 SetSmoothEdge(float value)119 void SetSmoothEdge(float value) 120 { 121 smoothEdge_ = value; 122 } 123 GetSmoothEdge()124 float GetSmoothEdge() const 125 { 126 return smoothEdge_; 127 } 128 SetColorFilter(const std::optional<ImageColorFilter> & colorFilter)129 void SetColorFilter(const std::optional<ImageColorFilter>& colorFilter) 130 { 131 colorFilter_ = colorFilter; 132 } 133 SetEffectFilterArea(const Rect & effectFilterArea)134 void SetEffectFilterArea(const Rect& effectFilterArea) 135 { 136 effectFilterArea_ = effectFilterArea; 137 } 138 GetEffectFilterArea()139 Rect GetEffectFilterArea() const 140 { 141 return effectFilterArea_; 142 } 143 GetColorFilter()144 std::optional<ImageColorFilter> GetColorFilter() const 145 { 146 return colorFilter_; 147 } 148 GetBaseAttributes()149 SvgBaseAttribute GetBaseAttributes() const 150 { 151 return attributes_; 152 } 153 SetBaseAttributes(const SvgBaseAttribute & attr)154 void SetBaseAttributes(const SvgBaseAttribute& attr) 155 { 156 attributes_ = attr; 157 } 158 SetImagePath(const std::string & path)159 void SetImagePath(const std::string& path) 160 { 161 imagePath_ = path; 162 } 163 GetImagePath()164 std::string GetImagePath() const 165 { 166 return imagePath_; 167 } SetIsRootNode(bool isRoot)168 void SetIsRootNode(bool isRoot) 169 { 170 isRootNode_ = isRoot; 171 } 172 Offset CalcGlobalPivot(const std::pair<Dimension, Dimension>& transformOrigin, 173 const SvgLengthScaleRule& lengthRule); 174 float GetRegionLength(Dimension origin, const SvgLengthScaleRule& boxMeasureRule, SvgLengthType lengthType); 175 float GetRegionPosition(Dimension origin, const SvgLengthScaleRule& boxMeasureRule, SvgLengthType lengthType); 176 float GetMeasuredLength(Dimension origin, const SvgLengthScaleRule& boxMeasureRule, SvgLengthType lengthType); 177 float GetMeasuredPosition(Dimension origin, const SvgLengthScaleRule& boxMeasureRule, SvgLengthType lengthType); 178 Rect GetSvgContainerRect() const; 179 void ApplyTransform(RSRecordingPath& path, const SvgLengthScaleRule& contentRule); 180 bool drawTraversed_ = true; // enable OnDraw, TAGS mask/defs/pattern/filter = false 181 protected: 182 // override as need by derived class 183 // called by function AppendChild OnAppendChild(const RefPtr<SvgNode> & child)184 virtual void OnAppendChild(const RefPtr<SvgNode>& child) {} 185 // called by function InitStyle OnInitStyle()186 virtual void OnInitStyle() {} 187 // function override by graphic tag OnDraw(RSCanvas & canvas,const Size & viewPort,const std::optional<Color> & color)188 virtual void OnDraw(RSCanvas& canvas, const Size& viewPort, const std::optional<Color>& color) {} OnDraw(RSCanvas & canvas,const SvgLengthScaleRule & lengthRule)189 virtual void OnDraw(RSCanvas& canvas, const SvgLengthScaleRule& lengthRule) {} 190 virtual void OnDrawTraversed(RSCanvas& canvas, const SvgLengthScaleRule& lengthRule); 191 virtual void OnDrawTraversed(RSCanvas& canvas, const Size& viewPort, const std::optional<Color>& color); AdjustContentAreaByViewBox(RSCanvas & canvas,const Size & viewPort)192 virtual void AdjustContentAreaByViewBox(RSCanvas& canvas, const Size& viewPort) {} 193 bool OnCanvas(RSCanvas& canvas); 194 void OnClipPath(RSCanvas& canvas, const Size& viewPort); 195 void OnFilter(RSCanvas& canvas, const Size& viewPort); 196 void OnMask(RSCanvas& canvas, const Size& viewPort); 197 void OnTransform(RSCanvas& canvas, const Size& viewPort); OnClipEffect(RSCanvas & canvas,const SvgCoordinateSystemContext & svgCoordinateSystemContext)198 virtual void OnClipEffect(RSCanvas& canvas, const SvgCoordinateSystemContext& svgCoordinateSystemContext) {} OnMaskEffect(RSCanvas & canvas,const SvgCoordinateSystemContext & svgCoordinateSystemContext)199 virtual void OnMaskEffect(RSCanvas& canvas, const SvgCoordinateSystemContext& svgCoordinateSystemContext) {} OnFilterEffect(RSCanvas & canvas,const SvgCoordinateSystemContext & svgCoordinateSystemContext,float useOffsetX,float useOffsetY)200 virtual void OnFilterEffect(RSCanvas& canvas, const SvgCoordinateSystemContext& svgCoordinateSystemContext, 201 float useOffsetX, float useOffsetY) {} 202 void OnClipPath(RSCanvas& canvas, const SvgCoordinateSystemContext& svgCoordinateSystemContext); 203 void OnFilter(RSCanvas& canvas, const SvgCoordinateSystemContext& svgCoordinateSystemContext); 204 void OnMask(RSCanvas& canvas, const SvgCoordinateSystemContext& svgCoordinateSystemContext); 205 void OnTransform(RSCanvas& canvas, const SvgLengthScaleRule& lengthRule); 206 double ConvertDimensionToPx(const Dimension& value, const Size& viewPort, SvgLengthType type) const; 207 double ConvertDimensionToPx(const Dimension& value, double baseValue) const; 208 209 std::optional<Gradient> GetGradient(const std::string& href); 210 const Rect& GetRootViewBox() const; 211 virtual void PrepareAnimation(const RefPtr<SvgAnimation>& animate); 212 // create animation that changes an attribute 213 template<typename T> 214 void AnimateOnAttribute(const RefPtr<SvgAnimation>& animate, const T& originalValue); 215 // animate a transformation attribute 216 void AnimateTransform(const RefPtr<SvgAnimation>& animate, double originalValue); 217 void AnimateFromToTransform(const RefPtr<SvgAnimation>& animate, double originalValue); 218 void AnimateFrameTransform(const RefPtr<SvgAnimation>& animate, double originalValue); 219 220 // update svg attribute in animation 221 template<typename T> 222 void UpdateAttr(const std::string& name, const T& val); 223 void UpdateAttrHelper(const std::string& name, const std::string& val); 224 SvgLengthScaleRule BuildContentScaleRule(const SvgCoordinateSystemContext& parentContext, 225 SvgLengthScaleUnit contentUnits); 226 void TransformForCurrentOBB(RSCanvas& canvas, const SvgLengthScaleRule& contentRule, 227 const Size& ContainerSize, const Offset& offset); 228 229 // defs gradient animation InitNoneFlag()230 void InitNoneFlag() 231 { 232 hrefFill_ = false; 233 hrefRender_ = false; 234 passStyle_ = false; 235 inheritStyle_ = false; 236 drawTraversed_ = false; 237 } 238 239 WeakPtr<SvgContext> svgContext_; 240 std::vector<RefPtr<SvgNode>> children_; 241 std::string nodeId_; 242 std::string transform_; 243 std::map<std::string, std::vector<float>> animateTransform_; 244 245 SvgBaseAttribute attributes_; 246 247 std::string hrefClipPath_; 248 std::string hrefMaskId_; 249 std::string hrefFilterId_; 250 std::string imagePath_; 251 uint8_t opacity_ = 0xFF; 252 float smoothEdge_ = 0.0f; 253 std::optional<ImageColorFilter> colorFilter_; 254 Rect effectFilterArea_; 255 float useOffsetX_ = 0.0f; 256 float useOffsetY_ = 0.0f; 257 258 bool hrefFill_ = true; // get fill attributes from reference 259 bool hrefRender_ = true; // get render attr (mask, filter, transform, opacity, clip path) from reference 260 bool passStyle_ = true; // pass style attributes to child node, TAGS circle/path/line/... = false 261 bool inheritStyle_ = true; // inherit style attributes from parent node, TAGS mask/defs/pattern/filter = false 262 bool isRootNode_ = false; 263 RSCanvas* rsCanvas_ = nullptr; 264 bool isDrawing_ = false; // Indicates if the current node is being drawn in the SVG rendering process. 265 SvgLengthScaleRule lengthRule_; 266 ACE_DISALLOW_COPY_AND_MOVE(SvgNode); 267 }; 268 269 } // namespace OHOS::Ace::NG 270 271 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_SVG_PARSE_SVG_NODE_H