1 /* 2 * Copyright 2016 Google Inc. 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8 #ifndef SkSVGNode_DEFINED 9 #define SkSVGNode_DEFINED 10 11 #include "include/core/SkRect.h" 12 #include "include/core/SkRefCnt.h" 13 #include "include/private/base/SkAPI.h" 14 #include "modules/svg/include/SkSVGAttribute.h" 15 #include "modules/svg/include/SkSVGAttributeParser.h" 16 #include "modules/svg/include/SkSVGTypes.h" 17 18 #include <utility> 19 20 class SkMatrix; 21 class SkPaint; 22 class SkPath; 23 class SkSVGNode; 24 class SkSVGRenderContext; 25 class SkSVGValue; 26 27 enum class SkSVGTag { 28 kCircle, 29 kClipPath, 30 kDefs, 31 kEllipse, 32 kFeBlend, 33 kFeColorMatrix, 34 kFeComponentTransfer, 35 kFeComposite, 36 kFeDiffuseLighting, 37 kFeDisplacementMap, 38 kFeDistantLight, 39 kFeFlood, 40 kFeFuncA, 41 kFeFuncR, 42 kFeFuncG, 43 kFeFuncB, 44 kFeGaussianBlur, 45 kFeImage, 46 kFeMerge, 47 kFeMergeNode, 48 kFeMorphology, 49 kFeOffset, 50 kFePointLight, 51 kFeSpecularLighting, 52 kFeSpotLight, 53 kFeTurbulence, 54 kFilter, 55 kG, 56 kImage, 57 kLine, 58 kLinearGradient, 59 kMask, 60 kPath, 61 kPattern, 62 kPolygon, 63 kPolyline, 64 kRadialGradient, 65 kRect, 66 kStop, 67 kSvg, 68 kText, 69 kTextLiteral, 70 kTextPath, 71 kTSpan, 72 kUse 73 }; 74 75 #define SVG_PRES_ATTR(attr_name, attr_type, attr_inherited) \ 76 private: \ 77 bool set##attr_name(SkSVGAttributeParser::ParseResult< \ 78 SkSVGProperty<attr_type, attr_inherited>>&& pr) {\ 79 if (pr.isValid()) { this->set##attr_name(std::move(*pr)); } \ 80 return pr.isValid(); \ 81 } \ 82 \ 83 public: \ 84 const SkSVGProperty<attr_type, attr_inherited>& get##attr_name() const { \ 85 return fPresentationAttributes.f##attr_name; \ 86 } \ 87 void set##attr_name(const SkSVGProperty<attr_type, attr_inherited>& v) { \ 88 auto* dest = &fPresentationAttributes.f##attr_name; \ 89 if (!dest->isInheritable() || v.isValue()) { \ 90 /* TODO: If dest is not inheritable, handle v == "inherit" */ \ 91 *dest = v; \ 92 } else { \ 93 dest->set(SkSVGPropertyState::kInherit); \ 94 } \ 95 } \ 96 void set##attr_name(SkSVGProperty<attr_type, attr_inherited>&& v) { \ 97 auto* dest = &fPresentationAttributes.f##attr_name; \ 98 if (!dest->isInheritable() || v.isValue()) { \ 99 /* TODO: If dest is not inheritable, handle v == "inherit" */ \ 100 *dest = std::move(v); \ 101 } else { \ 102 dest->set(SkSVGPropertyState::kInherit); \ 103 } \ 104 } 105 106 class SK_API SkSVGNode : public SkRefCnt { 107 public: 108 ~SkSVGNode() override; 109 tag()110 SkSVGTag tag() const { return fTag; } 111 112 virtual void appendChild(sk_sp<SkSVGNode>) = 0; 113 114 void render(const SkSVGRenderContext&) const; 115 bool asPaint(const SkSVGRenderContext&, SkPaint*) const; 116 SkPath asPath(const SkSVGRenderContext&) const; 117 SkRect objectBoundingBox(const SkSVGRenderContext&) const; 118 119 void setAttribute(SkSVGAttribute, const SkSVGValue&); 120 bool setAttribute(const char* attributeName, const char* attributeValue); 121 122 // TODO: consolidate with existing setAttribute 123 virtual bool parseAndSetAttribute(const char* name, const char* value); 124 125 // inherited 126 SVG_PRES_ATTR(ClipRule , SkSVGFillRule , true) 127 SVG_PRES_ATTR(Color , SkSVGColorType , true) 128 SVG_PRES_ATTR(ColorInterpolation , SkSVGColorspace, true) 129 SVG_PRES_ATTR(ColorInterpolationFilters, SkSVGColorspace, true) 130 SVG_PRES_ATTR(FillRule , SkSVGFillRule , true) 131 SVG_PRES_ATTR(Fill , SkSVGPaint , true) 132 SVG_PRES_ATTR(FillOpacity , SkSVGNumberType, true) 133 SVG_PRES_ATTR(FontFamily , SkSVGFontFamily, true) 134 SVG_PRES_ATTR(FontSize , SkSVGFontSize , true) 135 SVG_PRES_ATTR(FontStyle , SkSVGFontStyle , true) 136 SVG_PRES_ATTR(FontWeight , SkSVGFontWeight, true) 137 SVG_PRES_ATTR(Stroke , SkSVGPaint , true) 138 SVG_PRES_ATTR(StrokeDashArray , SkSVGDashArray , true) 139 SVG_PRES_ATTR(StrokeDashOffset , SkSVGLength , true) 140 SVG_PRES_ATTR(StrokeLineCap , SkSVGLineCap , true) 141 SVG_PRES_ATTR(StrokeLineJoin , SkSVGLineJoin , true) 142 SVG_PRES_ATTR(StrokeMiterLimit , SkSVGNumberType, true) 143 SVG_PRES_ATTR(StrokeOpacity , SkSVGNumberType, true) 144 SVG_PRES_ATTR(StrokeWidth , SkSVGLength , true) 145 SVG_PRES_ATTR(TextAnchor , SkSVGTextAnchor, true) 146 SVG_PRES_ATTR(Visibility , SkSVGVisibility, true) 147 148 // not inherited 149 SVG_PRES_ATTR(ClipPath , SkSVGFuncIRI , false) 150 SVG_PRES_ATTR(Display , SkSVGDisplay , false) 151 SVG_PRES_ATTR(Mask , SkSVGFuncIRI , false) 152 SVG_PRES_ATTR(Filter , SkSVGFuncIRI , false) 153 SVG_PRES_ATTR(Opacity , SkSVGNumberType, false) 154 SVG_PRES_ATTR(StopColor , SkSVGColor , false) 155 SVG_PRES_ATTR(StopOpacity , SkSVGNumberType, false) 156 SVG_PRES_ATTR(FloodColor , SkSVGColor , false) 157 SVG_PRES_ATTR(FloodOpacity , SkSVGNumberType, false) 158 SVG_PRES_ATTR(LightingColor , SkSVGColor , false) 159 160 protected: 161 SkSVGNode(SkSVGTag); 162 163 static SkMatrix ComputeViewboxMatrix(const SkRect&, const SkRect&, SkSVGPreserveAspectRatio); 164 165 // Called before onRender(), to apply local attributes to the context. Unlike onRender(), 166 // onPrepareToRender() bubbles up the inheritance chain: overriders should always call 167 // INHERITED::onPrepareToRender(), unless they intend to short-circuit rendering 168 // (return false). 169 // Implementations are expected to return true if rendering is to continue, or false if 170 // the node/subtree rendering is disabled. 171 virtual bool onPrepareToRender(SkSVGRenderContext*) const; 172 173 virtual void onRender(const SkSVGRenderContext&) const = 0; 174 onAsPaint(const SkSVGRenderContext &,SkPaint *)175 virtual bool onAsPaint(const SkSVGRenderContext&, SkPaint*) const { return false; } 176 177 virtual SkPath onAsPath(const SkSVGRenderContext&) const = 0; 178 onSetAttribute(SkSVGAttribute,const SkSVGValue &)179 virtual void onSetAttribute(SkSVGAttribute, const SkSVGValue&) {} 180 hasChildren()181 virtual bool hasChildren() const { return false; } 182 onObjectBoundingBox(const SkSVGRenderContext &)183 virtual SkRect onObjectBoundingBox(const SkSVGRenderContext&) const { 184 return SkRect::MakeEmpty(); 185 } 186 187 private: 188 SkSVGTag fTag; 189 190 // FIXME: this should be sparse 191 SkSVGPresentationAttributes fPresentationAttributes; 192 193 using INHERITED = SkRefCnt; 194 }; 195 196 #undef SVG_PRES_ATTR // presentation attributes are only defined for the base class 197 198 #define _SVG_ATTR_SETTERS(attr_name, attr_type, attr_default, set_cp, set_mv) \ 199 private: \ 200 bool set##attr_name( \ 201 const SkSVGAttributeParser::ParseResult<attr_type>& pr) { \ 202 if (pr.isValid()) { this->set##attr_name(*pr); } \ 203 return pr.isValid(); \ 204 } \ 205 bool set##attr_name( \ 206 SkSVGAttributeParser::ParseResult<attr_type>&& pr) { \ 207 if (pr.isValid()) { this->set##attr_name(std::move(*pr)); } \ 208 return pr.isValid(); \ 209 } \ 210 public: \ 211 void set##attr_name(const attr_type& a) { set_cp(a); } \ 212 void set##attr_name(attr_type&& a) { set_mv(std::move(a)); } 213 214 #define SVG_ATTR(attr_name, attr_type, attr_default) \ 215 private: \ 216 attr_type f##attr_name = attr_default; \ 217 public: \ 218 const attr_type& get##attr_name() const { return f##attr_name; } \ 219 _SVG_ATTR_SETTERS( \ 220 attr_name, attr_type, attr_default, \ 221 [this](const attr_type& a) { this->f##attr_name = a; }, \ 222 [this](attr_type&& a) { this->f##attr_name = std::move(a); }) 223 224 #define SVG_OPTIONAL_ATTR(attr_name, attr_type) \ 225 private: \ 226 SkTLazy<attr_type> f##attr_name; \ 227 public: \ 228 const SkTLazy<attr_type>& get##attr_name() const { return f##attr_name; } \ 229 _SVG_ATTR_SETTERS( \ 230 attr_name, attr_type, attr_default, \ 231 [this](const attr_type& a) { this->f##attr_name.set(a); }, \ 232 [this](attr_type&& a) { this->f##attr_name.set(std::move(a)); }) 233 234 #endif // SkSVGNode_DEFINED 235