KHTML
SVGResource.cpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include "config.h"
00027 #include "wtf/Platform.h"
00028
00029 #if ENABLE(SVG)
00030 #include "SVGResource.h"
00031
00032 #include "RenderPath.h"
00033 #include "SVGElement.h"
00034 #include "SVGStyledElement.h"
00035
00036 namespace WebCore {
00037
00038 SVGResource::SVGResource()
00039 {
00040 }
00041
00042 struct ResourceSet {
00043 ResourceSet()
00044 {
00045 for (int i = 0; i < _ResourceTypeCount; i++)
00046 resources[i] = 0;
00047 }
00048 SVGResource* resources[_ResourceTypeCount];
00049 };
00050
00051 static HashMap<SVGStyledElement*, ResourceSet*>& clientMap() {
00052 static HashMap<SVGStyledElement*, ResourceSet*> map;
00053 return map;
00054 }
00055
00056 SVGResource::~SVGResource()
00057 {
00058 int type = -1;
00059 HashSet<SVGStyledElement*>::iterator itr = m_clients.begin();
00060
00061 for (; type < 0 && itr != m_clients.end(); ++itr) {
00062 ResourceSet* target = clientMap().get(*itr);
00063 if (!target)
00064 continue;
00065
00066 for (int i = 0; i < _ResourceTypeCount; i++) {
00067 if (target->resources[i] != this)
00068 continue;
00069 type = i;
00070 target->resources[i] = 0;
00071 break;
00072 }
00073 }
00074
00075 if (type < 0)
00076 return;
00077
00078 for (; itr != m_clients.end(); ++itr) {
00079 ResourceSet* target = clientMap().get(*itr);
00080 if (!target)
00081 continue;
00082
00083 if (target->resources[type] == this)
00084 target->resources[type] = 0;
00085 }
00086 }
00087
00088 void SVGResource::invalidate()
00089 {
00090 HashSet<SVGStyledElement*>::const_iterator it = m_clients.begin();
00091 const HashSet<SVGStyledElement*>::const_iterator end = m_clients.end();
00092
00093 for (; it != end; ++it) {
00094 SVGStyledElement* cur = *it;
00095
00096 if (cur->renderer())
00097 cur->renderer()->setNeedsLayout(true);
00098
00099 cur->invalidateResourcesInAncestorChain();
00100 }
00101 }
00102
00103 void SVGResource::invalidateClients(HashSet<SVGStyledElement*> clients)
00104 {
00105 HashSet<SVGStyledElement*>::const_iterator it = clients.begin();
00106 const HashSet<SVGStyledElement*>::const_iterator end = clients.end();
00107
00108 for (; it != end; ++it) {
00109 SVGStyledElement* cur = *it;
00110
00111 if (cur->renderer())
00112 cur->renderer()->setNeedsLayout(true);
00113
00114 cur->invalidateResourcesInAncestorChain();
00115 }
00116 }
00117
00118 void SVGResource::removeClient(SVGStyledElement* item)
00119 {
00120 HashMap<SVGStyledElement*, ResourceSet*>::iterator resourcePtr = clientMap().find(item);
00121 if (resourcePtr == clientMap().end())
00122 return;
00123
00124 ResourceSet* set = resourcePtr->second;
00125 ASSERT(set);
00126
00127 clientMap().remove(resourcePtr);
00128
00129 for (int i = 0; i < _ResourceTypeCount; i++)
00130 if (set->resources[i])
00131 set->resources[i]->m_clients.remove(item);
00132
00133 delete set;
00134 }
00135
00136 void SVGResource::addClient(SVGStyledElement* item)
00137 {
00138 if (m_clients.contains(item))
00139 return;
00140
00141 m_clients.add(item);
00142
00143 ResourceSet* target = clientMap().get(item);
00144 if (!target)
00145 target = new ResourceSet;
00146
00147 SVGResourceType type = resourceType();
00148 if (SVGResource* oldResource = target->resources[type])
00149 oldResource->m_clients.remove(item);
00150
00151 target->resources[type] = this;
00152 clientMap().set(item, target);
00153 }
00154
00155
00156
00157
00158
00159
00160 SVGResource* getResourceById(Document* document, const AtomicString& id)
00161 {
00162 if (id.isEmpty())
00163 return 0;
00164
00165 Element* element = document->getElementById(id);
00166 SVGElement* svgElement = 0;
00167 if (element && element->isSVGElement())
00168 svgElement = static_cast<SVGElement*>(element);
00169
00170 if (svgElement && svgElement->isStyled())
00171 return static_cast<SVGStyledElement*>(svgElement)->canvasResource();
00172
00173 return 0;
00174 }
00175
00176
00177
00178
00179
00180
00181 }
00182
00183 #endif