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, const Rect& baseRect); 173 float GetRegionLength(Dimension origin, const SvgLengthScaleRule& boxMeasureRule, SvgLengthType lengthType); 174 float GetRegionPosition(Dimension origin, const SvgLengthScaleRule& boxMeasureRule, SvgLengthType lengthType); 175 float GetMeasuredLength(Dimension origin, const SvgLengthScaleRule& boxMeasureRule, SvgLengthType lengthType); 176 float GetMeasuredPosition(Dimension origin, const SvgLengthScaleRule& boxMeasureRule, SvgLengthType lengthType); 177 Rect GetSvgContainerRect() const; 178 bool drawTraversed_ = true; // enable OnDraw, TAGS mask/defs/pattern/filter = false 179 protected: 180 // override as need by derived class 181 // called by function AppendChild OnAppendChild(const RefPtr<SvgNode> & child)182 virtual void OnAppendChild(const RefPtr<SvgNode>& child) {} 183 // called by function InitStyle OnInitStyle()184 virtual void OnInitStyle() {} 185 // function override by graphic tag OnDraw(RSCanvas & canvas,const Size & viewPort,const std::optional<Color> & color)186 virtual void OnDraw(RSCanvas& canvas, const Size& viewPort, const std::optional<Color>& color) {} OnDraw(RSCanvas & canvas,const SvgLengthScaleRule & lengthRule)187 virtual void OnDraw(RSCanvas& canvas, const SvgLengthScaleRule& lengthRule) {} 188 virtual void OnDrawTraversed(RSCanvas& canvas, const SvgLengthScaleRule& lengthRule); 189 virtual void OnDrawTraversed(RSCanvas& canvas, const Size& viewPort, const std::optional<Color>& color); AdjustContentAreaByViewBox(RSCanvas & canvas,const Size & viewPort)190 virtual void AdjustContentAreaByViewBox(RSCanvas& canvas, const Size& viewPort) {} 191 bool OnCanvas(RSCanvas& canvas); 192 void OnClipPath(RSCanvas& canvas, const Size& viewPort); 193 void OnFilter(RSCanvas& canvas, const Size& viewPort); 194 void OnMask(RSCanvas& canvas, const Size& viewPort); 195 void OnTransform(RSCanvas& canvas, const Size& viewPort); OnClipEffect(RSCanvas & canvas,const SvgCoordinateSystemContext & svgCoordinateSystemContext)196 virtual void OnClipEffect(RSCanvas& canvas, const SvgCoordinateSystemContext& svgCoordinateSystemContext) {} OnMaskEffect(RSCanvas & canvas,const SvgCoordinateSystemContext & svgCoordinateSystemContext)197 virtual void OnMaskEffect(RSCanvas& canvas, const SvgCoordinateSystemContext& svgCoordinateSystemContext) {} OnFilterEffect(RSCanvas & canvas,const SvgCoordinateSystemContext & svgCoordinateSystemContext,float useOffsetX,float useOffsetY)198 virtual void OnFilterEffect(RSCanvas& canvas, const SvgCoordinateSystemContext& svgCoordinateSystemContext, 199 float useOffsetX, float useOffsetY) {} 200 void OnClipPath(RSCanvas& canvas, const SvgCoordinateSystemContext& svgCoordinateSystemContext); 201 void OnFilter(RSCanvas& canvas, const SvgCoordinateSystemContext& svgCoordinateSystemContext); 202 void OnMask(RSCanvas& canvas, const SvgCoordinateSystemContext& svgCoordinateSystemContext); 203 void OnTransform(RSCanvas& canvas, const SvgLengthScaleRule& lengthRule); 204 double ConvertDimensionToPx(const Dimension& value, const Size& viewPort, SvgLengthType type) const; 205 double ConvertDimensionToPx(const Dimension& value, double baseValue) const; 206 207 std::optional<Gradient> GetGradient(const std::string& href); 208 const Rect& GetRootViewBox() const; 209 virtual void PrepareAnimation(const RefPtr<SvgAnimation>& animate); 210 // create animation that changes an attribute 211 template<typename T> 212 void AnimateOnAttribute(const RefPtr<SvgAnimation>& animate, const T& originalValue); 213 // animate a transformation attribute 214 void AnimateTransform(const RefPtr<SvgAnimation>& animate, double originalValue); 215 void AnimateFromToTransform(const RefPtr<SvgAnimation>& animate, double originalValue); 216 void AnimateFrameTransform(const RefPtr<SvgAnimation>& animate, double originalValue); 217 218 // update svg attribute in animation 219 template<typename T> 220 void UpdateAttr(const std::string& name, const T& val); 221 void UpdateAttrHelper(const std::string& name, const std::string& val); 222 SvgLengthScaleRule TransformForCurrentOBB(RSCanvas& canvas, const SvgCoordinateSystemContext& context, 223 SvgLengthScaleUnit contentUnits, float offsetX, float offsetY); 224 225 // defs gradient animation InitNoneFlag()226 void InitNoneFlag() 227 { 228 hrefFill_ = false; 229 hrefRender_ = false; 230 passStyle_ = false; 231 inheritStyle_ = false; 232 drawTraversed_ = false; 233 } 234 235 WeakPtr<SvgContext> svgContext_; 236 std::vector<RefPtr<SvgNode>> children_; 237 std::string nodeId_; 238 std::string transform_; 239 std::map<std::string, std::vector<float>> animateTransform_; 240 241 SvgBaseAttribute attributes_; 242 243 std::string hrefClipPath_; 244 std::string hrefMaskId_; 245 std::string hrefFilterId_; 246 std::string imagePath_; 247 uint8_t opacity_ = 0xFF; 248 float smoothEdge_ = 0.0f; 249 std::optional<ImageColorFilter> colorFilter_; 250 Rect effectFilterArea_; 251 float useOffsetX_ = 0.0f; 252 float useOffsetY_ = 0.0f; 253 254 bool hrefFill_ = true; // get fill attributes from reference 255 bool hrefRender_ = true; // get render attr (mask, filter, transform, opacity, clip path) from reference 256 bool passStyle_ = true; // pass style attributes to child node, TAGS circle/path/line/... = false 257 bool inheritStyle_ = true; // inherit style attributes from parent node, TAGS mask/defs/pattern/filter = false 258 bool isRootNode_ = false; 259 RSCanvas* rsCanvas_ = nullptr; 260 bool isDrawing_ = false; // Indicates if the current node is being drawn in the SVG rendering process. 261 SvgLengthScaleRule lengthRule_; 262 ACE_DISALLOW_COPY_AND_MOVE(SvgNode); 263 }; 264 265 } // namespace OHOS::Ace::NG 266 267 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_SVG_PARSE_SVG_NODE_H