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 
29 namespace WebCore {
30 
31 class Document;
32 class RenderObject;
33 class RenderSVGResourceClipper;
34 class RenderSVGResourceContainer;
35 class RenderSVGResourceFilter;
36 class RenderSVGResourceMarker;
37 class RenderSVGResourceMasker;
38 class SVGRenderStyle;
39 
40 // Holds a set of resources associated with a RenderObject
41 class SVGResources {
42     WTF_MAKE_NONCOPYABLE(SVGResources); WTF_MAKE_FAST_ALLOCATED;
43 public:
44     SVGResources();
45 
46     bool buildCachedResources(const RenderObject*, const SVGRenderStyle*);
47 
48     // Ordinary resources
clipper()49     RenderSVGResourceClipper* clipper() const { return m_clipperFilterMaskerData ? m_clipperFilterMaskerData->clipper : 0; }
50 #if ENABLE(FILTERS)
filter()51     RenderSVGResourceFilter* filter() const { return m_clipperFilterMaskerData ? m_clipperFilterMaskerData->filter : 0; }
52 #endif
markerStart()53     RenderSVGResourceMarker* markerStart() const { return m_markerData ? m_markerData->markerStart : 0; }
markerMid()54     RenderSVGResourceMarker* markerMid() const { return m_markerData ? m_markerData->markerMid : 0; }
markerEnd()55     RenderSVGResourceMarker* markerEnd() const { return m_markerData ? m_markerData->markerEnd : 0; }
masker()56     RenderSVGResourceMasker* masker() const { return m_clipperFilterMaskerData ? m_clipperFilterMaskerData->masker : 0; }
57 
58     // Paint servers
fill()59     RenderSVGResourceContainer* fill() const { return m_fillStrokeData ? m_fillStrokeData->fill : 0; }
stroke()60     RenderSVGResourceContainer* stroke() const { return m_fillStrokeData ? m_fillStrokeData->stroke : 0; }
61 
62     // Chainable resources - linked through xlink:href
linkedResource()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 
75 private:
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 
91 private:
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 {
ClipperFilterMaskerDataClipperFilterMaskerData110         ClipperFilterMaskerData()
111             : clipper(0)
112 #if ENABLE(FILTERS)
113             , filter(0)
114 #endif
115             , masker(0)
116         {
117         }
118 
createClipperFilterMaskerData119         static PassOwnPtr<ClipperFilterMaskerData> create()
120         {
121             return adoptPtr(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 {
MarkerDataMarkerData134         MarkerData()
135             : markerStart(0)
136             , markerMid(0)
137             , markerEnd(0)
138         {
139         }
140 
createMarkerData141         static PassOwnPtr<MarkerData> create()
142         {
143             return adoptPtr(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 {
FillStrokeDataFillStrokeData156         FillStrokeData()
157             : fill(0)
158             , stroke(0)
159         {
160         }
161 
createFillStrokeData162         static PassOwnPtr<FillStrokeData> create()
163         {
164             return adoptPtr(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