2008-11-04 Anders Carlsson <andersca@apple.com>
[webkit/qt.git] / WebCore / svg / graphics / SVGResource.cpp
blob10d6648404f13e47271d72d9cce619026c9d78c3
1 /*
2 * Copyright (C) 2006, 2008 Nikolas Zimmermann <zimmermann@kde.org>
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
13 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 #include "config.h"
28 #if ENABLE(SVG)
29 #include "SVGResource.h"
31 #include "RenderPath.h"
32 #include "SVGElement.h"
33 #include "SVGStyledElement.h"
35 namespace WebCore {
37 SVGResource::SVGResource()
41 struct ResourceSet {
42 ResourceSet()
44 for (int i = 0; i < _ResourceTypeCount; i++)
45 resources[i] = 0;
47 SVGResource* resources[_ResourceTypeCount];
50 static HashMap<SVGStyledElement*, ResourceSet*>& clientMap() {
51 static HashMap<SVGStyledElement*, ResourceSet*> map;
52 return map;
55 SVGResource::~SVGResource()
57 int type = -1;
58 HashSet<SVGStyledElement*>::iterator itr = m_clients.begin();
60 for (; type < 0 && itr != m_clients.end(); ++itr) {
61 ResourceSet* target = clientMap().get(*itr);
62 if (!target)
63 continue;
65 for (int i = 0; i < _ResourceTypeCount; i++) {
66 if (target->resources[i] != this)
67 continue;
68 type = i;
69 target->resources[i] = 0;
70 break;
74 if (type < 0)
75 return;
77 for (; itr != m_clients.end(); ++itr) {
78 ResourceSet* target = clientMap().get(*itr);
79 if (!target)
80 continue;
82 if (target->resources[type] == this)
83 target->resources[type] = 0;
87 void SVGResource::invalidate()
89 HashSet<SVGStyledElement*>::const_iterator it = m_clients.begin();
90 const HashSet<SVGStyledElement*>::const_iterator end = m_clients.end();
92 for (; it != end; ++it) {
93 SVGStyledElement* cur = *it;
95 if (cur->renderer())
96 cur->renderer()->setNeedsLayout(true);
98 cur->invalidateResourcesInAncestorChain();
102 void SVGResource::invalidateClients(HashSet<SVGStyledElement*> clients)
104 HashSet<SVGStyledElement*>::const_iterator it = clients.begin();
105 const HashSet<SVGStyledElement*>::const_iterator end = clients.end();
107 for (; it != end; ++it) {
108 SVGStyledElement* cur = *it;
110 if (cur->renderer())
111 cur->renderer()->setNeedsLayout(true);
113 cur->invalidateResourcesInAncestorChain();
117 void SVGResource::removeClient(SVGStyledElement* item)
119 HashMap<SVGStyledElement*, ResourceSet*>::iterator resourcePtr = clientMap().find(item);
120 if (resourcePtr == clientMap().end())
121 return;
123 ResourceSet* set = resourcePtr->second;
124 ASSERT(set);
126 clientMap().remove(resourcePtr);
128 for (int i = 0; i < _ResourceTypeCount; i++)
129 if (set->resources[i])
130 set->resources[i]->m_clients.remove(item);
132 delete set;
135 void SVGResource::addClient(SVGStyledElement* item)
137 if (m_clients.contains(item))
138 return;
140 m_clients.add(item);
142 ResourceSet* target = clientMap().get(item);
143 if (!target)
144 target = new ResourceSet;
146 SVGResourceType type = resourceType();
147 if (SVGResource* oldResource = target->resources[type])
148 oldResource->m_clients.remove(item);
150 target->resources[type] = this;
151 clientMap().set(item, target);
154 TextStream& SVGResource::externalRepresentation(TextStream& ts) const
156 return ts;
159 SVGResource* getResourceById(Document* document, const AtomicString& id)
161 if (id.isEmpty())
162 return 0;
164 Element* element = document->getElementById(id);
165 SVGElement* svgElement = 0;
166 if (element && element->isSVGElement())
167 svgElement = static_cast<SVGElement*>(element);
169 if (svgElement && svgElement->isStyled())
170 return static_cast<SVGStyledElement*>(svgElement)->canvasResource();
172 return 0;
175 TextStream& operator<<(TextStream& ts, const SVGResource& r)
177 return r.externalRepresentation(ts);
182 #endif