1/*
2 * Copyright (C) Research In Motion Limited 2010. All rights reserved.
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12 * Library General Public License for more details.
13 *
14 * You should have received a copy of the GNU Library General Public License
15 * along with this library; see the file COPYING.LIB.  If not, write to
16 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 * Boston, MA 02110-1301, USA.
18 */
19
20#ifndef SVGResources_h
21#define SVGResources_h
22
23#include <memory>
24#include <wtf/HashSet.h>
25#include <wtf/Noncopyable.h>
26
27namespace WebCore {
28
29class Document;
30class RenderElement;
31class RenderObject;
32class RenderSVGResourceClipper;
33class RenderSVGResourceContainer;
34class RenderSVGResourceFilter;
35class RenderSVGResourceMarker;
36class RenderSVGResourceMasker;
37class SVGRenderStyle;
38
39// Holds a set of resources associated with a RenderObject
40class SVGResources {
41    WTF_MAKE_NONCOPYABLE(SVGResources); WTF_MAKE_FAST_ALLOCATED;
42public:
43    SVGResources();
44
45    bool buildCachedResources(const RenderElement&, const SVGRenderStyle&);
46
47    // Ordinary resources
48    RenderSVGResourceClipper* clipper() const { return m_clipperFilterMaskerData ? m_clipperFilterMaskerData->clipper : 0; }
49    RenderSVGResourceMarker* markerStart() const { return m_markerData ? m_markerData->markerStart : 0; }
50    RenderSVGResourceMarker* markerMid() const { return m_markerData ? m_markerData->markerMid : 0; }
51    RenderSVGResourceMarker* markerEnd() const { return m_markerData ? m_markerData->markerEnd : 0; }
52    RenderSVGResourceMasker* masker() const { return m_clipperFilterMaskerData ? m_clipperFilterMaskerData->masker : 0; }
53
54    RenderSVGResourceFilter* filter() const
55    {
56#if ENABLE(FILTERS)
57        if (m_clipperFilterMaskerData)
58            return m_clipperFilterMaskerData->filter;
59#endif
60        return 0;
61    }
62
63    // Paint servers
64    RenderSVGResourceContainer* fill() const { return m_fillStrokeData ? m_fillStrokeData->fill : 0; }
65    RenderSVGResourceContainer* stroke() const { return m_fillStrokeData ? m_fillStrokeData->stroke : 0; }
66
67    // Chainable resources - linked through xlink:href
68    RenderSVGResourceContainer* linkedResource() const { return m_linkedResource; }
69
70    void buildSetOfResources(HashSet<RenderSVGResourceContainer*>&);
71
72    // Methods operating on all cached resources
73    void removeClientFromCache(RenderElement&, bool markForInvalidation = true) const;
74    void resourceDestroyed(RenderSVGResourceContainer&);
75
76#ifndef NDEBUG
77    void dump(const RenderObject*);
78#endif
79
80private:
81    friend class SVGResourcesCycleSolver;
82
83    // Only used by SVGResourcesCache cycle detection logic
84    void resetClipper();
85#if ENABLE(FILTERS)
86    void resetFilter();
87#endif
88    void resetMarkerStart();
89    void resetMarkerMid();
90    void resetMarkerEnd();
91    void resetMasker();
92    void resetFill();
93    void resetStroke();
94    void resetLinkedResource();
95
96private:
97    bool setClipper(RenderSVGResourceClipper*);
98#if ENABLE(FILTERS)
99    bool setFilter(RenderSVGResourceFilter*);
100#endif
101    bool setMarkerStart(RenderSVGResourceMarker*);
102    bool setMarkerMid(RenderSVGResourceMarker*);
103    bool setMarkerEnd(RenderSVGResourceMarker*);
104    bool setMasker(RenderSVGResourceMasker*);
105    bool setFill(RenderSVGResourceContainer*);
106    bool setStroke(RenderSVGResourceContainer*);
107    bool setLinkedResource(RenderSVGResourceContainer*);
108
109    // From SVG 1.1 2nd Edition
110    // clipper: 'container elements' and 'graphics elements'
111    // filter:  'container elements' and 'graphics elements'
112    // masker:  'container elements' and 'graphics elements'
113    // -> a, circle, defs, ellipse, glyph, g, image, line, marker, mask, missing-glyph, path, pattern, polygon, polyline, rect, svg, switch, symbol, text, use
114    struct ClipperFilterMaskerData {
115        WTF_MAKE_FAST_ALLOCATED;
116    public:
117        ClipperFilterMaskerData()
118            : clipper(0)
119#if ENABLE(FILTERS)
120            , filter(0)
121#endif
122            , masker(0)
123        {
124        }
125
126        RenderSVGResourceClipper* clipper;
127#if ENABLE(FILTERS)
128        RenderSVGResourceFilter* filter;
129#endif
130        RenderSVGResourceMasker* masker;
131    };
132
133    // From SVG 1.1 2nd Edition
134    // marker: line, path, polygon, polyline
135    struct MarkerData {
136        WTF_MAKE_FAST_ALLOCATED;
137    public:
138        MarkerData()
139            : markerStart(0)
140            , markerMid(0)
141            , markerEnd(0)
142        {
143        }
144
145        RenderSVGResourceMarker* markerStart;
146        RenderSVGResourceMarker* markerMid;
147        RenderSVGResourceMarker* markerEnd;
148    };
149
150    // From SVG 1.1 2nd Edition
151    // fill:       'shapes' and 'text content elements'
152    // stroke:     'shapes' and 'text content elements'
153    // -> altGlyph, circle, ellipse, line, path, polygon, polyline, rect, text, textPath, tref, tspan
154    struct FillStrokeData {
155        WTF_MAKE_FAST_ALLOCATED;
156    public:
157        FillStrokeData()
158            : fill(0)
159            , stroke(0)
160        {
161        }
162
163        RenderSVGResourceContainer* fill;
164        RenderSVGResourceContainer* stroke;
165    };
166
167    std::unique_ptr<ClipperFilterMaskerData> m_clipperFilterMaskerData;
168    std::unique_ptr<MarkerData> m_markerData;
169    std::unique_ptr<FillStrokeData> m_fillStrokeData;
170    RenderSVGResourceContainer* m_linkedResource;
171};
172
173}
174
175#endif
176