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