File: SkSVGNode.h

package info (click to toggle)
webkit2gtk 2.48.5-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 429,764 kB
  • sloc: cpp: 3,697,587; javascript: 194,444; ansic: 169,997; python: 46,499; asm: 19,295; ruby: 18,528; perl: 16,602; xml: 4,650; yacc: 2,360; sh: 2,098; java: 1,993; lex: 1,327; pascal: 366; makefile: 298
file content (234 lines) | stat: -rw-r--r-- 10,458 bytes parent folder | download | duplicates (13)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
/*
 * Copyright 2016 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#ifndef SkSVGNode_DEFINED
#define SkSVGNode_DEFINED

#include "include/core/SkRect.h"
#include "include/core/SkRefCnt.h"
#include "include/private/base/SkAPI.h"
#include "modules/svg/include/SkSVGAttribute.h"
#include "modules/svg/include/SkSVGAttributeParser.h"
#include "modules/svg/include/SkSVGTypes.h"

#include <utility>

class SkMatrix;
class SkPaint;
class SkPath;
class SkSVGNode;
class SkSVGRenderContext;
class SkSVGValue;

enum class SkSVGTag {
    kCircle,
    kClipPath,
    kDefs,
    kEllipse,
    kFeBlend,
    kFeColorMatrix,
    kFeComponentTransfer,
    kFeComposite,
    kFeDiffuseLighting,
    kFeDisplacementMap,
    kFeDistantLight,
    kFeFlood,
    kFeFuncA,
    kFeFuncR,
    kFeFuncG,
    kFeFuncB,
    kFeGaussianBlur,
    kFeImage,
    kFeMerge,
    kFeMergeNode,
    kFeMorphology,
    kFeOffset,
    kFePointLight,
    kFeSpecularLighting,
    kFeSpotLight,
    kFeTurbulence,
    kFilter,
    kG,
    kImage,
    kLine,
    kLinearGradient,
    kMask,
    kPath,
    kPattern,
    kPolygon,
    kPolyline,
    kRadialGradient,
    kRect,
    kStop,
    kSvg,
    kText,
    kTextLiteral,
    kTextPath,
    kTSpan,
    kUse
};

#define SVG_PRES_ATTR(attr_name, attr_type, attr_inherited)                  \
private:                                                                     \
    bool set##attr_name(SkSVGAttributeParser::ParseResult<                   \
                            SkSVGProperty<attr_type, attr_inherited>>&& pr) {\
        if (pr.isValid()) { this->set##attr_name(std::move(*pr)); }          \
        return pr.isValid();                                                 \
    }                                                                        \
                                                                             \
public:                                                                      \
    const SkSVGProperty<attr_type, attr_inherited>& get##attr_name() const { \
        return fPresentationAttributes.f##attr_name;                         \
    }                                                                        \
    void set##attr_name(const SkSVGProperty<attr_type, attr_inherited>& v) { \
        auto* dest = &fPresentationAttributes.f##attr_name;                  \
        if (!dest->isInheritable() || v.isValue()) {                         \
            /* TODO: If dest is not inheritable, handle v == "inherit" */    \
            *dest = v;                                                       \
        } else {                                                             \
            dest->set(SkSVGPropertyState::kInherit);                         \
        }                                                                    \
    }                                                                        \
    void set##attr_name(SkSVGProperty<attr_type, attr_inherited>&& v) {      \
        auto* dest = &fPresentationAttributes.f##attr_name;                  \
        if (!dest->isInheritable() || v.isValue()) {                         \
            /* TODO: If dest is not inheritable, handle v == "inherit" */    \
            *dest = std::move(v);                                            \
        } else {                                                             \
            dest->set(SkSVGPropertyState::kInherit);                         \
        }                                                                    \
    }

class SK_API SkSVGNode : public SkRefCnt {
public:
    ~SkSVGNode() override;

    SkSVGTag tag() const { return fTag; }

    virtual void appendChild(sk_sp<SkSVGNode>) = 0;

    void render(const SkSVGRenderContext&) const;
    bool asPaint(const SkSVGRenderContext&, SkPaint*) const;
    SkPath asPath(const SkSVGRenderContext&) const;
    SkRect objectBoundingBox(const SkSVGRenderContext&) const;

    void setAttribute(SkSVGAttribute, const SkSVGValue&);
    bool setAttribute(const char* attributeName, const char* attributeValue);

    // TODO: consolidate with existing setAttribute
    virtual bool parseAndSetAttribute(const char* name, const char* value);

    // inherited
    SVG_PRES_ATTR(ClipRule                 , SkSVGFillRule  , true)
    SVG_PRES_ATTR(Color                    , SkSVGColorType , true)
    SVG_PRES_ATTR(ColorInterpolation       , SkSVGColorspace, true)
    SVG_PRES_ATTR(ColorInterpolationFilters, SkSVGColorspace, true)
    SVG_PRES_ATTR(FillRule                 , SkSVGFillRule  , true)
    SVG_PRES_ATTR(Fill                     , SkSVGPaint     , true)
    SVG_PRES_ATTR(FillOpacity              , SkSVGNumberType, true)
    SVG_PRES_ATTR(FontFamily               , SkSVGFontFamily, true)
    SVG_PRES_ATTR(FontSize                 , SkSVGFontSize  , true)
    SVG_PRES_ATTR(FontStyle                , SkSVGFontStyle , true)
    SVG_PRES_ATTR(FontWeight               , SkSVGFontWeight, true)
    SVG_PRES_ATTR(Stroke                   , SkSVGPaint     , true)
    SVG_PRES_ATTR(StrokeDashArray          , SkSVGDashArray , true)
    SVG_PRES_ATTR(StrokeDashOffset         , SkSVGLength    , true)
    SVG_PRES_ATTR(StrokeLineCap            , SkSVGLineCap   , true)
    SVG_PRES_ATTR(StrokeLineJoin           , SkSVGLineJoin  , true)
    SVG_PRES_ATTR(StrokeMiterLimit         , SkSVGNumberType, true)
    SVG_PRES_ATTR(StrokeOpacity            , SkSVGNumberType, true)
    SVG_PRES_ATTR(StrokeWidth              , SkSVGLength    , true)
    SVG_PRES_ATTR(TextAnchor               , SkSVGTextAnchor, true)
    SVG_PRES_ATTR(Visibility               , SkSVGVisibility, true)

    // not inherited
    SVG_PRES_ATTR(ClipPath                 , SkSVGFuncIRI   , false)
    SVG_PRES_ATTR(Display                  , SkSVGDisplay   , false)
    SVG_PRES_ATTR(Mask                     , SkSVGFuncIRI   , false)
    SVG_PRES_ATTR(Filter                   , SkSVGFuncIRI   , false)
    SVG_PRES_ATTR(Opacity                  , SkSVGNumberType, false)
    SVG_PRES_ATTR(StopColor                , SkSVGColor     , false)
    SVG_PRES_ATTR(StopOpacity              , SkSVGNumberType, false)
    SVG_PRES_ATTR(FloodColor               , SkSVGColor     , false)
    SVG_PRES_ATTR(FloodOpacity             , SkSVGNumberType, false)
    SVG_PRES_ATTR(LightingColor            , SkSVGColor     , false)

protected:
    SkSVGNode(SkSVGTag);

    static SkMatrix ComputeViewboxMatrix(const SkRect&, const SkRect&, SkSVGPreserveAspectRatio);

    // Called before onRender(), to apply local attributes to the context.  Unlike onRender(),
    // onPrepareToRender() bubbles up the inheritance chain: overriders should always call
    // INHERITED::onPrepareToRender(), unless they intend to short-circuit rendering
    // (return false).
    // Implementations are expected to return true if rendering is to continue, or false if
    // the node/subtree rendering is disabled.
    virtual bool onPrepareToRender(SkSVGRenderContext*) const;

    virtual void onRender(const SkSVGRenderContext&) const = 0;

    virtual bool onAsPaint(const SkSVGRenderContext&, SkPaint*) const { return false; }

    virtual SkPath onAsPath(const SkSVGRenderContext&) const = 0;

    virtual void onSetAttribute(SkSVGAttribute, const SkSVGValue&) {}

    virtual bool hasChildren() const { return false; }

    virtual SkRect onObjectBoundingBox(const SkSVGRenderContext&) const {
        return SkRect::MakeEmpty();
    }

private:
    SkSVGTag                    fTag;

    // FIXME: this should be sparse
    SkSVGPresentationAttributes fPresentationAttributes;

    using INHERITED = SkRefCnt;
};

#undef SVG_PRES_ATTR // presentation attributes are only defined for the base class

#define _SVG_ATTR_SETTERS(attr_name, attr_type, attr_default, set_cp, set_mv) \
    private:                                                                  \
        bool set##attr_name(                                                  \
                const SkSVGAttributeParser::ParseResult<attr_type>& pr) {     \
            if (pr.isValid()) { this->set##attr_name(*pr); }                  \
            return pr.isValid();                                              \
        }                                                                     \
        bool set##attr_name(                                                  \
                SkSVGAttributeParser::ParseResult<attr_type>&& pr) {          \
            if (pr.isValid()) { this->set##attr_name(std::move(*pr)); }       \
            return pr.isValid();                                              \
        }                                                                     \
    public:                                                                   \
        void set##attr_name(const attr_type& a) { set_cp(a); }                \
        void set##attr_name(attr_type&& a) { set_mv(std::move(a)); }

#define SVG_ATTR(attr_name, attr_type, attr_default)                        \
    private:                                                                \
        attr_type f##attr_name = attr_default;                              \
    public:                                                                 \
        const attr_type& get##attr_name() const { return f##attr_name; }    \
    _SVG_ATTR_SETTERS(                                                      \
            attr_name, attr_type, attr_default,                             \
            [this](const attr_type& a) { this->f##attr_name = a; },         \
            [this](attr_type&& a) { this->f##attr_name = std::move(a); })

#define SVG_OPTIONAL_ATTR(attr_name, attr_type)                                   \
    private:                                                                      \
        SkTLazy<attr_type> f##attr_name;                                          \
    public:                                                                       \
        const SkTLazy<attr_type>& get##attr_name() const { return f##attr_name; } \
    _SVG_ATTR_SETTERS(                                                            \
            attr_name, attr_type, attr_default,                                   \
            [this](const attr_type& a) { this->f##attr_name.set(a); },            \
            [this](attr_type&& a) { this->f##attr_name.set(std::move(a)); })

#endif // SkSVGNode_DEFINED