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