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