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