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"
12#include "modules/svg/include/SkSVGAttribute.h"
13#include "modules/svg/include/SkSVGAttributeParser.h"
14
15class SkCanvas;
16class SkMatrix;
17class SkPaint;
18class SkPath;
19class SkSVGLengthContext;
20class SkSVGRenderContext;
21class SkSVGValue;
22
23enum class SkSVGTag {
24    kCircle,
25    kClipPath,
26    kDefs,
27    kEllipse,
28    kFeBlend,
29    kFeColorMatrix,
30    kFeComposite,
31    kFeDiffuseLighting,
32    kFeDisplacementMap,
33    kFeDistantLight,
34    kFeFlood,
35    kFeGaussianBlur,
36    kFeImage,
37    kFeMorphology,
38    kFeOffset,
39    kFePointLight,
40    kFeSpecularLighting,
41    kFeSpotLight,
42    kFeTurbulence,
43    kFilter,
44    kG,
45    kImage,
46    kLine,
47    kLinearGradient,
48    kMask,
49    kPath,
50    kPattern,
51    kPolygon,
52    kPolyline,
53    kRadialGradient,
54    kRect,
55    kStop,
56    kSvg,
57    kText,
58    kTextLiteral,
59    kTextPath,
60    kTSpan,
61    kUse
62};
63
64#define SVG_PRES_ATTR(attr_name, attr_type, attr_inherited)                  \
65private:                                                                     \
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                                                                             \
72public:                                                                      \
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
95class SK_API SkSVGNode : public SkRefCnt {
96public:
97    ~SkSVGNode() override;
98
99    SkSVGTag tag() const { return fTag; }
100
101    virtual void appendChild(sk_sp<SkSVGNode>) = 0;
102    virtual std::vector<sk_sp<SkSVGNode>> getChild() {
103        std::vector<sk_sp<SkSVGNode>> res;
104        return res;
105    }
106
107    void render(const SkSVGRenderContext&) const;
108    bool asPaint(const SkSVGRenderContext&, SkPaint*) const;
109    SkPath asPath(const SkSVGRenderContext&) const;
110    SkRect objectBoundingBox(const SkSVGRenderContext&) const;
111
112    void setAttribute(SkSVGAttribute, const SkSVGValue&);
113    bool setAttribute(const char* attributeName, const char* attributeValue);
114
115    // TODO: consolidate with existing setAttribute
116    virtual bool parseAndSetAttribute(const char* name, const char* value);
117
118    // inherited
119    SVG_PRES_ATTR(ClipRule                 , SkSVGFillRule  , true)
120    SVG_PRES_ATTR(Color                    , SkSVGColorType , true)
121    SVG_PRES_ATTR(ColorInterpolation       , SkSVGColorspace, true)
122    SVG_PRES_ATTR(ColorInterpolationFilters, SkSVGColorspace, true)
123    SVG_PRES_ATTR(FillRule                 , SkSVGFillRule  , true)
124    SVG_PRES_ATTR(Fill                     , SkSVGPaint     , true)
125    SVG_PRES_ATTR(FillOpacity              , SkSVGNumberType, true)
126    SVG_PRES_ATTR(FontFamily               , SkSVGFontFamily, true)
127    SVG_PRES_ATTR(FontSize                 , SkSVGFontSize  , true)
128    SVG_PRES_ATTR(FontStyle                , SkSVGFontStyle , true)
129    SVG_PRES_ATTR(FontWeight               , SkSVGFontWeight, true)
130    SVG_PRES_ATTR(Stroke                   , SkSVGPaint     , true)
131    SVG_PRES_ATTR(StrokeDashArray          , SkSVGDashArray , true)
132    SVG_PRES_ATTR(StrokeDashOffset         , SkSVGLength    , true)
133    SVG_PRES_ATTR(StrokeLineCap            , SkSVGLineCap   , true)
134    SVG_PRES_ATTR(StrokeLineJoin           , SkSVGLineJoin  , true)
135    SVG_PRES_ATTR(StrokeMiterLimit         , SkSVGNumberType, true)
136    SVG_PRES_ATTR(StrokeOpacity            , SkSVGNumberType, true)
137    SVG_PRES_ATTR(StrokeWidth              , SkSVGLength    , true)
138    SVG_PRES_ATTR(TextAnchor               , SkSVGTextAnchor, true)
139    SVG_PRES_ATTR(Visibility               , SkSVGVisibility, true)
140
141    // not inherited
142    SVG_PRES_ATTR(ClipPath                 , SkSVGFuncIRI   , false)
143    SVG_PRES_ATTR(Display                  , SkSVGDisplay   , false)
144    SVG_PRES_ATTR(Mask                     , SkSVGFuncIRI   , false)
145    SVG_PRES_ATTR(Filter                   , SkSVGFuncIRI   , false)
146    SVG_PRES_ATTR(Opacity                  , SkSVGNumberType, false)
147    SVG_PRES_ATTR(StopColor                , SkSVGColor     , false)
148    SVG_PRES_ATTR(StopOpacity              , SkSVGNumberType, false)
149    SVG_PRES_ATTR(FloodColor               , SkSVGColor     , false)
150    SVG_PRES_ATTR(FloodOpacity             , SkSVGNumberType, false)
151    SVG_PRES_ATTR(LightingColor            , SkSVGColor     , false)
152
153protected:
154    SkSVGNode(SkSVGTag);
155
156    static SkMatrix ComputeViewboxMatrix(const SkRect&, const SkRect&, SkSVGPreserveAspectRatio);
157
158    // Called before onRender(), to apply local attributes to the context.  Unlike onRender(),
159    // onPrepareToRender() bubbles up the inheritance chain: overriders should always call
160    // INHERITED::onPrepareToRender(), unless they intend to short-circuit rendering
161    // (return false).
162    // Implementations are expected to return true if rendering is to continue, or false if
163    // the node/subtree rendering is disabled.
164    virtual bool onPrepareToRender(SkSVGRenderContext*) const;
165
166    virtual void onRender(const SkSVGRenderContext&) const = 0;
167
168    virtual bool onAsPaint(const SkSVGRenderContext&, SkPaint*) const { return false; }
169
170    virtual SkPath onAsPath(const SkSVGRenderContext&) const = 0;
171
172    virtual void onSetAttribute(SkSVGAttribute, const SkSVGValue&) {}
173
174    virtual bool hasChildren() const { return false; }
175
176    virtual SkRect onObjectBoundingBox(const SkSVGRenderContext&) const {
177        return SkRect::MakeEmpty();
178    }
179
180private:
181    SkSVGTag                    fTag;
182
183    // FIXME: this should be sparse
184    SkSVGPresentationAttributes fPresentationAttributes;
185
186    using INHERITED = SkRefCnt;
187};
188
189#undef SVG_PRES_ATTR // presentation attributes are only defined for the base class
190
191#define _SVG_ATTR_SETTERS(attr_name, attr_type, attr_default, set_cp, set_mv) \
192    private:                                                                  \
193        bool set##attr_name(                                                  \
194                const SkSVGAttributeParser::ParseResult<attr_type>& pr) {     \
195            if (pr.isValid()) { this->set##attr_name(*pr); }                  \
196            return pr.isValid();                                              \
197        }                                                                     \
198        bool set##attr_name(                                                  \
199                SkSVGAttributeParser::ParseResult<attr_type>&& pr) {          \
200            if (pr.isValid()) { this->set##attr_name(std::move(*pr)); }       \
201            return pr.isValid();                                              \
202        }                                                                     \
203    public:                                                                   \
204        void set##attr_name(const attr_type& a) { set_cp(a); }                \
205        void set##attr_name(attr_type&& a) { set_mv(std::move(a)); }
206
207#define SVG_ATTR(attr_name, attr_type, attr_default)                        \
208    private:                                                                \
209        attr_type f##attr_name = attr_default;                              \
210    public:                                                                 \
211        const attr_type& get##attr_name() const { return f##attr_name; }    \
212    _SVG_ATTR_SETTERS(                                                      \
213            attr_name, attr_type, attr_default,                             \
214            [this](const attr_type& a) { this->f##attr_name = a; },         \
215            [this](attr_type&& a) { this->f##attr_name = std::move(a); })
216
217#define SVG_OPTIONAL_ATTR(attr_name, attr_type)                                   \
218    private:                                                                      \
219        SkTLazy<attr_type> f##attr_name;                                          \
220    public:                                                                       \
221        const SkTLazy<attr_type>& get##attr_name() const { return f##attr_name; } \
222    _SVG_ATTR_SETTERS(                                                            \
223            attr_name, attr_type, attr_default,                                   \
224            [this](const attr_type& a) { this->f##attr_name.set(a); },            \
225            [this](attr_type&& a) { this->f##attr_name.set(std::move(a)); })
226
227#endif // SkSVGNode_DEFINED
228