blob: c532de92b53830e65eff0a061affd4a4b525ec68 [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 Dennistonf548a022020-10-27 15:02:02 -040076 SkRect objectBoundingBox(const SkSVGRenderContext&) 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)
Florin Malita056385b2020-10-27 22:57:56 -0400102 SVG_PRES_ATTR(TextAnchor, SkSVGTextAnchor, true)
Tyler Dennistonb3cafbc2020-10-30 15:00:48 -0400103 SVG_PRES_ATTR(Filter , SkSVGFilterType, false)
Florin Malita39fe8c82020-10-20 10:43:03 -0400104
Florin Malitab3418102020-10-15 18:10:29 -0400105protected:
106 SkSVGNode(SkSVGTag);
107
108 // Called before onRender(), to apply local attributes to the context. Unlike onRender(),
109 // onPrepareToRender() bubbles up the inheritance chain: overriders should always call
110 // INHERITED::onPrepareToRender(), unless they intend to short-circuit rendering
111 // (return false).
112 // Implementations are expected to return true if rendering is to continue, or false if
113 // the node/subtree rendering is disabled.
114 virtual bool onPrepareToRender(SkSVGRenderContext*) const;
115
116 virtual void onRender(const SkSVGRenderContext&) const = 0;
117
118 virtual bool onAsPaint(const SkSVGRenderContext&, SkPaint*) const { return false; }
119
120 virtual SkPath onAsPath(const SkSVGRenderContext&) const = 0;
121
122 virtual void onSetAttribute(SkSVGAttribute, const SkSVGValue&);
123
124 virtual bool hasChildren() const { return false; }
125
Tyler Dennistonf548a022020-10-27 15:02:02 -0400126 virtual SkRect onObjectBoundingBox(const SkSVGRenderContext&) const {
Tyler Denniston53281c72020-10-22 15:54:24 -0400127 return SkRect::MakeEmpty();
128 }
129
Florin Malitab3418102020-10-15 18:10:29 -0400130private:
131 SkSVGTag fTag;
132
133 // FIXME: this should be sparse
134 SkSVGPresentationAttributes fPresentationAttributes;
135
136 using INHERITED = SkRefCnt;
137};
138
Florin Malita385e7442020-10-21 16:55:46 -0400139#undef SVG_PRES_ATTR // presentation attributes are only defined for the base class
140
141#define SVG_ATTR(attr_name, attr_type, attr_default) \
142 private: \
143 attr_type f##attr_name = attr_default; \
144 public: \
145 const attr_type& get##attr_name() const { return f##attr_name; } \
146 void set##attr_name(const attr_type& a) { f##attr_name = a; } \
147 void set##attr_name(attr_type&& a) { f##attr_name = std::move(a); }
148
Florin Malitab3418102020-10-15 18:10:29 -0400149#endif // SkSVGNode_DEFINED