Skia
2D Graphics Library
SkSVGNode.h
Go to the documentation of this file.
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"
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,
34  kFeFlood,
36  kFeImage,
38  kFeOffset,
43  kFilter,
44  kG,
45  kImage,
46  kLine,
48  kMask,
49  kPath,
50  kPattern,
51  kPolygon,
52  kPolyline,
54  kRect,
55  kStop,
56  kSvg,
57  kText,
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 
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;
107 
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)
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:
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 
164  virtual bool onAsPaint(const SkSVGRenderContext&, SkPaint*) const { return false; }
165 
166  virtual SkPath onAsPath(const SkSVGRenderContext&) const = 0;
167 
168  virtual void onSetAttribute(SkSVGAttribute, const SkSVGValue&) {}
169 
170  virtual bool hasChildren() const { return false; }
171 
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
@ kLine
SkPath::RawIter returns 2 points.
SkSVGAttribute
Definition: SkSVGAttribute.h:16
SkSVGTag
Definition: SkSVGNode.h:23
@ kFeDistantLight
@ kFeColorMatrix
@ kFeSpecularLighting
@ kFeDisplacementMap
@ kFeGaussianBlur
@ kLinearGradient
@ kFeDiffuseLighting
@ kRadialGradient
#define SVG_PRES_ATTR(attr_name, attr_type, attr_inherited)
Definition: SkSVGNode.h:64
SkSVGDisplay
Definition: SkSVGTypes.h:726
SkSVGLineCap
Definition: SkSVGTypes.h:288
SkColor SkSVGColorType
Definition: SkSVGTypes.h:25
SkSVGColorspace
Definition: SkSVGTypes.h:719
SkScalar SkSVGNumberType
Definition: SkSVGTypes.h:27
SkCanvas provides an interface for drawing, and how the drawing is clipped and transformed.
Definition: SkCanvas.h:99
SkMatrix holds a 3x3 matrix for transforming coordinates.
Definition: SkMatrix.h:53
SkPaint controls options applied when drawing.
Definition: SkPaint.h:44
SkPath contain geometry.
Definition: SkPath.h:58
Definition: SkRefCnt.h:119
Definition: SkSVGTypes.h:177
Definition: SkSVGTypes.h:394
Definition: SkSVGTypes.h:342
Definition: SkSVGTypes.h:477
Definition: SkSVGTypes.h:526
Definition: SkSVGTypes.h:503
Definition: SkSVGTypes.h:552
Definition: SkSVGTypes.h:264
Definition: SkSVGRenderContext.h:27
Definition: SkSVGTypes.h:116
Definition: SkSVGTypes.h:294
Definition: SkSVGNode.h:95
SkRect objectBoundingBox(const SkSVGRenderContext &) const
void render(const SkSVGRenderContext &) const
bool setAttribute(const char *attributeName, const char *attributeValue)
virtual SkRect onObjectBoundingBox(const SkSVGRenderContext &) const
Definition: SkSVGNode.h:172
virtual bool parseAndSetAttribute(const char *name, const char *value)
~SkSVGNode() override
void setAttribute(SkSVGAttribute, const SkSVGValue &)
bool asPaint(const SkSVGRenderContext &, SkPaint *) const
SkPath asPath(const SkSVGRenderContext &) const
virtual void appendChild(sk_sp< SkSVGNode >)=0
virtual void onSetAttribute(SkSVGAttribute, const SkSVGValue &)
Definition: SkSVGNode.h:168
virtual bool hasChildren() const
Definition: SkSVGNode.h:170
SkSVGTag tag() const
Definition: SkSVGNode.h:99
virtual SkPath onAsPath(const SkSVGRenderContext &) const =0
Definition: SkSVGTypes.h:224
Definition: SkSVGRenderContext.h:61
Definition: SkSVGTypes.h:611
Definition: SkSVGValue.h:18
Definition: SkSVGTypes.h:370
SK_API sk_sp< SkShader > Color(SkColor)
SkRect holds four float coordinates describing the upper and lower bounds of a rectangle.
Definition: SkRect.h:582
static constexpr SkRect MakeEmpty()
Returns constructed SkRect set to (0, 0, 0, 0).
Definition: SkRect.h:595
Definition: SkSVGAttribute.h:69
Definition: SkSVGTypes.h:585