File indexing completed on 2024-05-12 11:51:55
0001 /* 0002 * Copyright (C) 2006, 2008 Nikolas Zimmermann <zimmermann@kde.org> 0003 * 0004 * Redistribution and use in source and binary forms, with or without 0005 * modification, are permitted provided that the following conditions 0006 * are met: 0007 * 1. Redistributions of source code must retain the above copyright 0008 * notice, this list of conditions and the following disclaimer. 0009 * 2. Redistributions in binary form must reproduce the above copyright 0010 * notice, this list of conditions and the following disclaimer in the 0011 * documentation and/or other materials provided with the distribution. 0012 * 0013 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY 0014 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 0015 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 0016 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR 0017 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 0018 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 0019 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 0020 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 0021 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 0022 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 0023 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 0024 */ 0025 0026 #include "wtf/Platform.h" 0027 0028 #if ENABLE(SVG) 0029 #include "SVGResource.h" 0030 0031 #include "RenderPath.h" 0032 #include "SVGElement.h" 0033 #include "SVGStyledElement.h" 0034 0035 namespace WebCore 0036 { 0037 0038 SVGResource::SVGResource() 0039 { 0040 } 0041 0042 struct ResourceSet { 0043 ResourceSet() 0044 { 0045 for (int i = 0; i < _ResourceTypeCount; i++) { 0046 resources[i] = nullptr; 0047 } 0048 } 0049 SVGResource *resources[_ResourceTypeCount]; 0050 }; 0051 0052 static HashMap<SVGStyledElement *, ResourceSet *> &clientMap() 0053 { 0054 static HashMap<SVGStyledElement *, ResourceSet *> map; 0055 return map; 0056 } 0057 0058 SVGResource::~SVGResource() 0059 { 0060 int type = -1; 0061 HashSet<SVGStyledElement *>::iterator itr = m_clients.begin(); 0062 0063 for (; type < 0 && itr != m_clients.end(); ++itr) { 0064 ResourceSet *target = clientMap().get(*itr); 0065 if (!target) { 0066 continue; 0067 } 0068 0069 for (int i = 0; i < _ResourceTypeCount; i++) { 0070 if (target->resources[i] != this) { 0071 continue; 0072 } 0073 type = i; 0074 target->resources[i] = nullptr; 0075 break; 0076 } 0077 } 0078 0079 if (type < 0) { 0080 return; 0081 } 0082 0083 for (; itr != m_clients.end(); ++itr) { 0084 ResourceSet *target = clientMap().get(*itr); 0085 if (!target) { 0086 continue; 0087 } 0088 0089 if (target->resources[type] == this) { 0090 target->resources[type] = nullptr; 0091 } 0092 } 0093 } 0094 0095 void SVGResource::invalidate() 0096 { 0097 HashSet<SVGStyledElement *>::const_iterator it = m_clients.begin(); 0098 const HashSet<SVGStyledElement *>::const_iterator end = m_clients.end(); 0099 0100 for (; it != end; ++it) { 0101 SVGStyledElement *cur = *it; 0102 0103 if (cur->renderer()) { 0104 cur->renderer()->setNeedsLayout(true); 0105 } 0106 0107 cur->invalidateResourcesInAncestorChain(); 0108 } 0109 } 0110 0111 void SVGResource::invalidateClients(HashSet<SVGStyledElement *> clients) 0112 { 0113 HashSet<SVGStyledElement *>::const_iterator it = clients.begin(); 0114 const HashSet<SVGStyledElement *>::const_iterator end = clients.end(); 0115 0116 for (; it != end; ++it) { 0117 SVGStyledElement *cur = *it; 0118 0119 if (cur->renderer()) { 0120 cur->renderer()->setNeedsLayout(true); 0121 } 0122 0123 cur->invalidateResourcesInAncestorChain(); 0124 } 0125 } 0126 0127 void SVGResource::removeClient(SVGStyledElement *item) 0128 { 0129 HashMap<SVGStyledElement *, ResourceSet *>::iterator resourcePtr = clientMap().find(item); 0130 if (resourcePtr == clientMap().end()) { 0131 return; 0132 } 0133 0134 ResourceSet *set = resourcePtr->second; 0135 ASSERT(set); 0136 0137 clientMap().remove(resourcePtr); 0138 0139 for (int i = 0; i < _ResourceTypeCount; i++) 0140 if (set->resources[i]) { 0141 set->resources[i]->m_clients.remove(item); 0142 } 0143 0144 delete set; 0145 } 0146 0147 void SVGResource::addClient(SVGStyledElement *item) 0148 { 0149 if (m_clients.contains(item)) { 0150 return; 0151 } 0152 0153 m_clients.add(item); 0154 0155 ResourceSet *target = clientMap().get(item); 0156 if (!target) { 0157 target = new ResourceSet; 0158 } 0159 0160 SVGResourceType type = resourceType(); 0161 if (SVGResource *oldResource = target->resources[type]) { 0162 oldResource->m_clients.remove(item); 0163 } 0164 0165 target->resources[type] = this; 0166 clientMap().set(item, target); 0167 } 0168 0169 /*TextStream& SVGResource::externalRepresentation(TextStream& ts) const 0170 { 0171 return ts; 0172 }*/ 0173 0174 SVGResource *getResourceById(Document *document, const AtomicString &id) 0175 { 0176 if (id.isEmpty()) { 0177 return nullptr; 0178 } 0179 0180 Element *element = document->getElementById(id); 0181 SVGElement *svgElement = nullptr; 0182 if (element && element->isSVGElement()) { 0183 svgElement = static_cast<SVGElement *>(element); 0184 } 0185 0186 if (svgElement && svgElement->isStyled()) { 0187 return static_cast<SVGStyledElement *>(svgElement)->canvasResource(); 0188 } 0189 0190 return nullptr; 0191 } 0192 0193 /*TextStream& operator<<(TextStream& ts, const SVGResource& r) 0194 { 0195 return r.externalRepresentation(ts); 0196 }*/ 0197 0198 } 0199 0200 #endif