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#if ENABLE(SVG)
24#include <wtf/HashSet.h>
25#include <wtf/Noncopyable.h>
26#include <wtf/OwnPtr.h>
27#include <wtf/PassOwnPtr.h>
28
29namespace WebCore {
30
31class Document;
32class RenderObject;
33class RenderSVGResourceClipper;
34class RenderSVGResourceContainer;
35class RenderSVGResourceFilter;
36class RenderSVGResourceMarker;
37class RenderSVGResourceMasker;
38class SVGRenderStyle;
39
40// Holds a set of resources associated with a RenderObject
41class SVGResources {
42    WTF_MAKE_NONCOPYABLE(SVGResources); WTF_MAKE_FAST_ALLOCATED;
43public:
44    SVGResources();
45
46    bool buildCachedResources(const RenderObject*, const SVGRenderStyle*);
47
48    // Ordinary resources
49    RenderSVGResourceClipper* clipper() const { return m_clipperFilterMaskerData ? m_clipperFilterMaskerData->clipper : 0; }
50#if ENABLE(FILTERS)
51    RenderSVGResourceFilter* filter() const { return m_clipperFilterMaskerData ? m_clipperFilterMaskerData->filter : 0; }
52#endif
53    RenderSVGResourceMarker* markerStart() const { return m_markerData ? m_markerData->markerStart : 0; }
54    RenderSVGResourceMarker* markerMid() const { return m_markerData ? m_markerData->markerMid : 0; }
55    RenderSVGResourceMarker* markerEnd() const { return m_markerData ? m_markerData->markerEnd : 0; }
56    RenderSVGResourceMasker* masker() const { return m_clipperFilterMaskerData ? m_clipperFilterMaskerData->masker : 0; }
57
58    // Paint servers
59    RenderSVGResourceContainer* fill() const { return m_fillStrokeData ? m_fillStrokeData->fill : 0; }
60    RenderSVGResourceContainer* stroke() const { return m_fillStrokeData ? m_fillStrokeData->stroke : 0; }
61
62    // Chainable resources - linked through xlink:href
63    RenderSVGResourceContainer* linkedResource() const { return m_linkedResource; }
64
65    void buildSetOfResources(HashSet<RenderSVGResourceContainer*>&);
66
67    // Methods operating on all cached resources
68    void removeClientFromCache(RenderObject*, bool markForInvalidation = true) const;
69    void resourceDestroyed(RenderSVGResourceContainer*);
70
71#ifndef NDEBUG
72    void dump(const RenderObject*);
73#endif
74
75private:
76    friend class SVGResourcesCycleSolver;
77
78    // Only used by SVGResourcesCache cycle detection logic
79    void resetClipper();
80#if ENABLE(FILTERS)
81    void resetFilter();
82#endif
83    void resetMarkerStart();
84    void resetMarkerMid();
85    void resetMarkerEnd();
86    void resetMasker();
87    void resetFill();
88    void resetStroke();
89    void resetLinkedResource();
90
91private:
92    bool setClipper(RenderSVGResourceClipper*);
93#if ENABLE(FILTERS)
94    bool setFilter(RenderSVGResourceFilter*);
95#endif
96    bool setMarkerStart(RenderSVGResourceMarker*);
97    bool setMarkerMid(RenderSVGResourceMarker*);
98    bool setMarkerEnd(RenderSVGResourceMarker*);
99    bool setMasker(RenderSVGResourceMasker*);
100    bool setFill(RenderSVGResourceContainer*);
101    bool setStroke(RenderSVGResourceContainer*);
102    bool setLinkedResource(RenderSVGResourceContainer*);
103
104    // From SVG 1.1 2nd Edition
105    // clipper: 'container elements' and 'graphics elements'
106    // filter:  'container elements' and 'graphics elements'
107    // masker:  'container elements' and 'graphics elements'
108    // -> a, circle, defs, ellipse, glyph, g, image, line, marker, mask, missing-glyph, path, pattern, polygon, polyline, rect, svg, switch, symbol, text, use
109    struct ClipperFilterMaskerData {
110        ClipperFilterMaskerData()
111            : clipper(0)
112#if ENABLE(FILTERS)
113            , filter(0)
114#endif
115            , masker(0)
116        {
117        }
118
119        static PassOwnPtr<ClipperFilterMaskerData> create()
120        {
121            return new ClipperFilterMaskerData;
122        }
123
124        RenderSVGResourceClipper* clipper;
125#if ENABLE(FILTERS)
126        RenderSVGResourceFilter* filter;
127#endif
128        RenderSVGResourceMasker* masker;
129    };
130
131    // From SVG 1.1 2nd Edition
132    // marker: line, path, polygon, polyline
133    struct MarkerData {
134        MarkerData()
135            : markerStart(0)
136            , markerMid(0)
137            , markerEnd(0)
138        {
139        }
140
141        static PassOwnPtr<MarkerData> create()
142        {
143            return new MarkerData;
144        }
145
146        RenderSVGResourceMarker* markerStart;
147        RenderSVGResourceMarker* markerMid;
148        RenderSVGResourceMarker* markerEnd;
149    };
150
151    // From SVG 1.1 2nd Edition
152    // fill:       'shapes' and 'text content elements'
153    // stroke:     'shapes' and 'text content elements'
154    // -> altGlyph, circle, ellipse, line, path, polygon, polyline, rect, text, textPath, tref, tspan
155    struct FillStrokeData {
156        FillStrokeData()
157            : fill(0)
158            , stroke(0)
159        {
160        }
161
162        static PassOwnPtr<FillStrokeData> create()
163        {
164            return new FillStrokeData;
165        }
166
167        RenderSVGResourceContainer* fill;
168        RenderSVGResourceContainer* stroke;
169    };
170
171    OwnPtr<ClipperFilterMaskerData> m_clipperFilterMaskerData;
172    OwnPtr<MarkerData> m_markerData;
173    OwnPtr<FillStrokeData> m_fillStrokeData;
174    RenderSVGResourceContainer* m_linkedResource;
175};
176
177}
178
179#endif
180#endif
181