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; getChild()113 virtual std::vector<sk_sp<SkSVGNode>> getChild() { 114 std::vector<sk_sp<SkSVGNode>> res; 115 return res; 116 } 117 118 void render(const SkSVGRenderContext&) const; 119 bool asPaint(const SkSVGRenderContext&, SkPaint*) const; 120 SkPath asPath(const SkSVGRenderContext&) const; 121 SkRect objectBoundingBox(const SkSVGRenderContext&) const; 122 123 void setAttribute(SkSVGAttribute, const SkSVGValue&); 124 bool setAttribute(const char* attributeName, const char* attributeValue); 125 126 // TODO: consolidate with existing setAttribute 127 virtual bool parseAndSetAttribute(const char* name, const char* value); 128 129 // inherited 130 SVG_PRES_ATTR(ClipRule , SkSVGFillRule , true) 131 SVG_PRES_ATTR(Color , SkSVGColorType , true) 132 SVG_PRES_ATTR(ColorInterpolation , SkSVGColorspace, true) 133 SVG_PRES_ATTR(ColorInterpolationFilters, SkSVGColorspace, true) 134 SVG_PRES_ATTR(FillRule , SkSVGFillRule , true) 135 SVG_PRES_ATTR(Fill , SkSVGPaint , true) 136 SVG_PRES_ATTR(FillOpacity , SkSVGNumberType, true) 137 SVG_PRES_ATTR(FontFamily , SkSVGFontFamily, true) 138 SVG_PRES_ATTR(FontSize , SkSVGFontSize , true) 139 SVG_PRES_ATTR(FontStyle , SkSVGFontStyle , true) 140 SVG_PRES_ATTR(FontWeight , SkSVGFontWeight, true) 141 SVG_PRES_ATTR(Stroke , SkSVGPaint , true) 142 SVG_PRES_ATTR(StrokeDashArray , SkSVGDashArray , true) 143 SVG_PRES_ATTR(StrokeDashOffset , SkSVGLength , true) 144 SVG_PRES_ATTR(StrokeLineCap , SkSVGLineCap , true) 145 SVG_PRES_ATTR(StrokeLineJoin , SkSVGLineJoin , true) 146 SVG_PRES_ATTR(StrokeMiterLimit , SkSVGNumberType, true) 147 SVG_PRES_ATTR(StrokeOpacity , SkSVGNumberType, true) 148 SVG_PRES_ATTR(StrokeWidth , SkSVGLength , true) 149 SVG_PRES_ATTR(TextAnchor , SkSVGTextAnchor, true) 150 SVG_PRES_ATTR(Visibility , SkSVGVisibility, true) 151 152 // not inherited 153 SVG_PRES_ATTR(ClipPath , SkSVGFuncIRI , false) 154 SVG_PRES_ATTR(Display , SkSVGDisplay , false) 155 SVG_PRES_ATTR(Mask , SkSVGFuncIRI , false) 156 SVG_PRES_ATTR(Filter , SkSVGFuncIRI , false) 157 SVG_PRES_ATTR(Opacity , SkSVGNumberType, false) 158 SVG_PRES_ATTR(StopColor , SkSVGColor , false) 159 SVG_PRES_ATTR(StopOpacity , SkSVGNumberType, false) 160 SVG_PRES_ATTR(FloodColor , SkSVGColor , false) 161 SVG_PRES_ATTR(FloodOpacity , SkSVGNumberType, false) 162 SVG_PRES_ATTR(LightingColor , SkSVGColor , false) 163 164 protected: 165 SkSVGNode(SkSVGTag); 166 167 static SkMatrix ComputeViewboxMatrix(const SkRect&, const SkRect&, SkSVGPreserveAspectRatio); 168 169 // Called before onRender(), to apply local attributes to the context. Unlike onRender(), 170 // onPrepareToRender() bubbles up the inheritance chain: overriders should always call 171 // INHERITED::onPrepareToRender(), unless they intend to short-circuit rendering 172 // (return false). 173 // Implementations are expected to return true if rendering is to continue, or false if 174 // the node/subtree rendering is disabled. 175 virtual bool onPrepareToRender(SkSVGRenderContext*) const; 176 177 virtual void onRender(const SkSVGRenderContext&) const = 0; 178 onAsPaint(const SkSVGRenderContext &,SkPaint *)179 virtual bool onAsPaint(const SkSVGRenderContext&, SkPaint*) const { return false; } 180 181 virtual SkPath onAsPath(const SkSVGRenderContext&) const = 0; 182 onSetAttribute(SkSVGAttribute,const SkSVGValue &)183 virtual void onSetAttribute(SkSVGAttribute, const SkSVGValue&) {} 184 hasChildren()185 virtual bool hasChildren() const { return false; } 186 onObjectBoundingBox(const SkSVGRenderContext &)187 virtual SkRect onObjectBoundingBox(const SkSVGRenderContext&) const { 188 return SkRect::MakeEmpty(); 189 } 190 191 private: 192 SkSVGTag fTag; 193 194 // FIXME: this should be sparse 195 SkSVGPresentationAttributes fPresentationAttributes; 196 197 using INHERITED = SkRefCnt; 198 }; 199 200 #undef SVG_PRES_ATTR // presentation attributes are only defined for the base class 201 202 #define _SVG_ATTR_SETTERS(attr_name, attr_type, attr_default, set_cp, set_mv) \ 203 private: \ 204 bool set##attr_name( \ 205 const SkSVGAttributeParser::ParseResult<attr_type>& pr) { \ 206 if (pr.isValid()) { this->set##attr_name(*pr); } \ 207 return pr.isValid(); \ 208 } \ 209 bool set##attr_name( \ 210 SkSVGAttributeParser::ParseResult<attr_type>&& pr) { \ 211 if (pr.isValid()) { this->set##attr_name(std::move(*pr)); } \ 212 return pr.isValid(); \ 213 } \ 214 public: \ 215 void set##attr_name(const attr_type& a) { set_cp(a); } \ 216 void set##attr_name(attr_type&& a) { set_mv(std::move(a)); } 217 218 #define SVG_ATTR(attr_name, attr_type, attr_default) \ 219 private: \ 220 attr_type f##attr_name = attr_default; \ 221 public: \ 222 const attr_type& get##attr_name() const { return f##attr_name; } \ 223 _SVG_ATTR_SETTERS( \ 224 attr_name, attr_type, attr_default, \ 225 [this](const attr_type& a) { this->f##attr_name = a; }, \ 226 [this](attr_type&& a) { this->f##attr_name = std::move(a); }) 227 228 #define SVG_OPTIONAL_ATTR(attr_name, attr_type) \ 229 private: \ 230 SkTLazy<attr_type> f##attr_name; \ 231 public: \ 232 const SkTLazy<attr_type>& get##attr_name() const { return f##attr_name; } \ 233 _SVG_ATTR_SETTERS( \ 234 attr_name, attr_type, attr_default, \ 235 [this](const attr_type& a) { this->f##attr_name.set(a); }, \ 236 [this](attr_type&& a) { this->f##attr_name.set(std::move(a)); }) 237 238 #endif // SkSVGNode_DEFINED 239