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