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