blob: 001b5ca67901fddedcbadc6ac36a2d4236ed6c8c [file] [log] [blame]
Florin Malitab3418102020-10-15 18:10:29 -04001/*
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
14class SkCanvas;
15class SkMatrix;
16class SkPaint;
17class SkPath;
Tyler Denniston53281c72020-10-22 15:54:24 -040018class SkSVGLengthContext;
Florin Malitab3418102020-10-15 18:10:29 -040019class SkSVGRenderContext;
20class SkSVGValue;
21
22enum class SkSVGTag {
23 kCircle,
24 kClipPath,
25 kDefs,
26 kEllipse,
27 kG,
28 kLine,
29 kLinearGradient,
30 kPath,
31 kPattern,
32 kPolygon,
33 kPolyline,
34 kRadialGradient,
35 kRect,
36 kStop,
37 kSvg,
38 kText,
39 kUse
40};
41
Florin Malita39fe8c82020-10-20 10:43:03 -040042#define SVG_PRES_ATTR(attr_name, attr_type, attr_inherited) \
43 const attr_type* get##attr_name() const { \
44 return fPresentationAttributes.f##attr_name.getMaybeNull(); \
45 } \
46 void set##attr_name(const attr_type& v) { \
47 if (!attr_inherited || v.type() != attr_type::Type::kInherit) { \
48 fPresentationAttributes.f##attr_name.set(v); \
49 } else { \
50 /* kInherited values are semantically equivalent to \
51 the absence of a local presentation attribute.*/ \
52 fPresentationAttributes.f##attr_name.reset(); \
53 } \
54 } \
55 void set##attr_name(attr_type&& v) { \
56 if (!attr_inherited || v.type() != attr_type::Type::kInherit) { \
57 fPresentationAttributes.f##attr_name.set(std::move(v)); \
58 } else { \
59 /* kInherited values are semantically equivalent to \
60 the absence of a local presentation attribute.*/ \
61 fPresentationAttributes.f##attr_name.reset(); \
62 } \
63 }
64
Florin Malitab3418102020-10-15 18:10:29 -040065class SkSVGNode : public SkRefCnt {
66public:
67 ~SkSVGNode() override;
68
69 SkSVGTag tag() const { return fTag; }
70
71 virtual void appendChild(sk_sp<SkSVGNode>) = 0;
72
73 void render(const SkSVGRenderContext&) const;
74 bool asPaint(const SkSVGRenderContext&, SkPaint*) const;
75 SkPath asPath(const SkSVGRenderContext&) const;
Tyler Denniston53281c72020-10-22 15:54:24 -040076 SkRect objectBoundingBox(const SkSVGLengthContext&) const;
Florin Malitab3418102020-10-15 18:10:29 -040077
78 void setAttribute(SkSVGAttribute, const SkSVGValue&);
79 bool setAttribute(const char* attributeName, const char* attributeValue);
80
81 void setClipPath(const SkSVGClip&);
82 void setClipRule(const SkSVGFillRule&);
83 void setColor(const SkSVGColorType&);
84 void setFill(const SkSVGPaint&);
85 void setFillOpacity(const SkSVGNumberType&);
86 void setFillRule(const SkSVGFillRule&);
87 void setOpacity(const SkSVGNumberType&);
88 void setStroke(const SkSVGPaint&);
89 void setStrokeDashArray(const SkSVGDashArray&);
90 void setStrokeDashOffset(const SkSVGLength&);
91 void setStrokeOpacity(const SkSVGNumberType&);
92 void setStrokeLineCap(const SkSVGLineCap&);
93 void setStrokeLineJoin(const SkSVGLineJoin&);
94 void setStrokeMiterLimit(const SkSVGNumberType&);
95 void setStrokeWidth(const SkSVGLength&);
96 void setVisibility(const SkSVGVisibility&);
97
Florin Malita39fe8c82020-10-20 10:43:03 -040098 SVG_PRES_ATTR(FontFamily, SkSVGFontFamily, true)
99 SVG_PRES_ATTR(FontStyle , SkSVGFontStyle , true)
100 SVG_PRES_ATTR(FontSize , SkSVGFontSize , true)
101 SVG_PRES_ATTR(FontWeight, SkSVGFontWeight, true)
102
Florin Malitab3418102020-10-15 18:10:29 -0400103protected:
104 SkSVGNode(SkSVGTag);
105
106 // Called before onRender(), to apply local attributes to the context. Unlike onRender(),
107 // onPrepareToRender() bubbles up the inheritance chain: overriders should always call
108 // INHERITED::onPrepareToRender(), unless they intend to short-circuit rendering
109 // (return false).
110 // Implementations are expected to return true if rendering is to continue, or false if
111 // the node/subtree rendering is disabled.
112 virtual bool onPrepareToRender(SkSVGRenderContext*) const;
113
114 virtual void onRender(const SkSVGRenderContext&) const = 0;
115
116 virtual bool onAsPaint(const SkSVGRenderContext&, SkPaint*) const { return false; }
117
118 virtual SkPath onAsPath(const SkSVGRenderContext&) const = 0;
119
120 virtual void onSetAttribute(SkSVGAttribute, const SkSVGValue&);
121
122 virtual bool hasChildren() const { return false; }
123
Tyler Denniston53281c72020-10-22 15:54:24 -0400124 virtual SkRect onObjectBoundingBox(const SkSVGLengthContext&) const {
125 return SkRect::MakeEmpty();
126 }
127
Florin Malitab3418102020-10-15 18:10:29 -0400128private:
129 SkSVGTag fTag;
130
131 // FIXME: this should be sparse
132 SkSVGPresentationAttributes fPresentationAttributes;
133
134 using INHERITED = SkRefCnt;
135};
136
Florin Malita385e7442020-10-21 16:55:46 -0400137#undef SVG_PRES_ATTR // presentation attributes are only defined for the base class
138
139#define SVG_ATTR(attr_name, attr_type, attr_default) \
140 private: \
141 attr_type f##attr_name = attr_default; \
142 public: \
143 const attr_type& get##attr_name() const { return f##attr_name; } \
144 void set##attr_name(const attr_type& a) { f##attr_name = a; } \
145 void set##attr_name(attr_type&& a) { f##attr_name = std::move(a); }
146
Florin Malitab3418102020-10-15 18:10:29 -0400147#endif // SkSVGNode_DEFINED