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