blob: b0cf36023484a1943e31bf5c78e64351be33dcb6 [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,
Tyler Dennistondada9602020-11-03 10:04:25 -050027 kFeTurbulence,
Tyler Dennistondf208a32020-10-30 16:01:54 -040028 kFilter,
Florin Malitab3418102020-10-15 18:10:29 -040029 kG,
30 kLine,
31 kLinearGradient,
32 kPath,
33 kPattern,
34 kPolygon,
35 kPolyline,
36 kRadialGradient,
37 kRect,
38 kStop,
39 kSvg,
40 kText,
41 kUse
42};
43
Florin Malita39fe8c82020-10-20 10:43:03 -040044#define SVG_PRES_ATTR(attr_name, attr_type, attr_inherited) \
45 const attr_type* get##attr_name() const { \
46 return fPresentationAttributes.f##attr_name.getMaybeNull(); \
47 } \
48 void set##attr_name(const attr_type& v) { \
49 if (!attr_inherited || v.type() != attr_type::Type::kInherit) { \
50 fPresentationAttributes.f##attr_name.set(v); \
51 } else { \
52 /* kInherited values are semantically equivalent to \
53 the absence of a local presentation attribute.*/ \
54 fPresentationAttributes.f##attr_name.reset(); \
55 } \
56 } \
57 void set##attr_name(attr_type&& v) { \
58 if (!attr_inherited || v.type() != attr_type::Type::kInherit) { \
59 fPresentationAttributes.f##attr_name.set(std::move(v)); \
60 } else { \
61 /* kInherited values are semantically equivalent to \
62 the absence of a local presentation attribute.*/ \
63 fPresentationAttributes.f##attr_name.reset(); \
64 } \
65 }
66
Florin Malitab3418102020-10-15 18:10:29 -040067class SkSVGNode : public SkRefCnt {
68public:
69 ~SkSVGNode() override;
70
71 SkSVGTag tag() const { return fTag; }
72
73 virtual void appendChild(sk_sp<SkSVGNode>) = 0;
74
75 void render(const SkSVGRenderContext&) const;
76 bool asPaint(const SkSVGRenderContext&, SkPaint*) const;
77 SkPath asPath(const SkSVGRenderContext&) const;
Tyler Dennistonf548a022020-10-27 15:02:02 -040078 SkRect objectBoundingBox(const SkSVGRenderContext&) const;
Florin Malitab3418102020-10-15 18:10:29 -040079
80 void setAttribute(SkSVGAttribute, const SkSVGValue&);
81 bool setAttribute(const char* attributeName, const char* attributeValue);
82
83 void setClipPath(const SkSVGClip&);
84 void setClipRule(const SkSVGFillRule&);
85 void setColor(const SkSVGColorType&);
86 void setFill(const SkSVGPaint&);
87 void setFillOpacity(const SkSVGNumberType&);
88 void setFillRule(const SkSVGFillRule&);
89 void setOpacity(const SkSVGNumberType&);
90 void setStroke(const SkSVGPaint&);
91 void setStrokeDashArray(const SkSVGDashArray&);
92 void setStrokeDashOffset(const SkSVGLength&);
93 void setStrokeOpacity(const SkSVGNumberType&);
94 void setStrokeLineCap(const SkSVGLineCap&);
95 void setStrokeLineJoin(const SkSVGLineJoin&);
96 void setStrokeMiterLimit(const SkSVGNumberType&);
97 void setStrokeWidth(const SkSVGLength&);
98 void setVisibility(const SkSVGVisibility&);
99
Florin Malita39fe8c82020-10-20 10:43:03 -0400100 SVG_PRES_ATTR(FontFamily, SkSVGFontFamily, true)
101 SVG_PRES_ATTR(FontStyle , SkSVGFontStyle , true)
102 SVG_PRES_ATTR(FontSize , SkSVGFontSize , true)
103 SVG_PRES_ATTR(FontWeight, SkSVGFontWeight, true)
Florin Malita056385b2020-10-27 22:57:56 -0400104 SVG_PRES_ATTR(TextAnchor, SkSVGTextAnchor, true)
Tyler Dennistonb3cafbc2020-10-30 15:00:48 -0400105 SVG_PRES_ATTR(Filter , SkSVGFilterType, false)
Florin Malita39fe8c82020-10-20 10:43:03 -0400106
Florin Malitab3418102020-10-15 18:10:29 -0400107protected:
108 SkSVGNode(SkSVGTag);
109
110 // Called before onRender(), to apply local attributes to the context. Unlike onRender(),
111 // onPrepareToRender() bubbles up the inheritance chain: overriders should always call
112 // INHERITED::onPrepareToRender(), unless they intend to short-circuit rendering
113 // (return false).
114 // Implementations are expected to return true if rendering is to continue, or false if
115 // the node/subtree rendering is disabled.
116 virtual bool onPrepareToRender(SkSVGRenderContext*) const;
117
118 virtual void onRender(const SkSVGRenderContext&) const = 0;
119
120 virtual bool onAsPaint(const SkSVGRenderContext&, SkPaint*) const { return false; }
121
122 virtual SkPath onAsPath(const SkSVGRenderContext&) const = 0;
123
124 virtual void onSetAttribute(SkSVGAttribute, const SkSVGValue&);
125
126 virtual bool hasChildren() const { return false; }
127
Tyler Dennistonf548a022020-10-27 15:02:02 -0400128 virtual SkRect onObjectBoundingBox(const SkSVGRenderContext&) const {
Tyler Denniston53281c72020-10-22 15:54:24 -0400129 return SkRect::MakeEmpty();
130 }
131
Florin Malitab3418102020-10-15 18:10:29 -0400132private:
133 SkSVGTag fTag;
134
135 // FIXME: this should be sparse
136 SkSVGPresentationAttributes fPresentationAttributes;
137
138 using INHERITED = SkRefCnt;
139};
140
Florin Malita385e7442020-10-21 16:55:46 -0400141#undef SVG_PRES_ATTR // presentation attributes are only defined for the base class
142
143#define SVG_ATTR(attr_name, attr_type, attr_default) \
144 private: \
145 attr_type f##attr_name = attr_default; \
146 public: \
147 const attr_type& get##attr_name() const { return f##attr_name; } \
148 void set##attr_name(const attr_type& a) { f##attr_name = a; } \
149 void set##attr_name(attr_type&& a) { f##attr_name = std::move(a); }
150
Florin Malitab3418102020-10-15 18:10:29 -0400151#endif // SkSVGNode_DEFINED