1/* 2 * Copyright (C) 2006 Rob Buis <buis@kde.org> 3 * (C) 2008 Nikolas Zimmermann <zimmermann@kde.org> 4 * Copyright (C) 2008 Apple Inc. All rights reserved. 5 * 6 * This library is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU Library General Public 8 * License as published by the Free Software Foundation; either 9 * version 2 of the License, or (at your option) any later version. 10 * 11 * This library is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * Library General Public License for more details. 15 * 16 * You should have received a copy of the GNU Library General Public License 17 * along with this library; see the file COPYING.LIB. If not, write to 18 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 19 * Boston, MA 02110-1301, USA. 20 */ 21 22#include "config.h" 23#include "CSSCursorImageValue.h" 24 25#include "DocLoader.h" 26#include "Document.h" 27#include "PlatformString.h" 28#include <wtf/MathExtras.h> 29#include <wtf/UnusedParam.h> 30 31#if ENABLE(SVG) 32#include "SVGCursorElement.h" 33#include "SVGURIReference.h" 34#endif 35 36namespace WebCore { 37 38#if ENABLE(SVG) 39static inline bool isSVGCursorIdentifier(const String& url) 40{ 41 KURL kurl(ParsedURLString, url); 42 return kurl.hasFragmentIdentifier(); 43} 44 45static inline SVGCursorElement* resourceReferencedByCursorElement(const String& fragmentId, Document* document) 46{ 47 Element* element = document->getElementById(SVGURIReference::getTarget(fragmentId)); 48 if (element && element->hasTagName(SVGNames::cursorTag)) 49 return static_cast<SVGCursorElement*>(element); 50 51 return 0; 52} 53#endif 54 55CSSCursorImageValue::CSSCursorImageValue(const String& url, const IntPoint& hotspot) 56 : CSSImageValue(url) 57 , m_hotspot(hotspot) 58{ 59} 60 61CSSCursorImageValue::~CSSCursorImageValue() 62{ 63#if ENABLE(SVG) 64 const String& url = getStringValue(); 65 if (!isSVGCursorIdentifier(url)) 66 return; 67 68 HashSet<SVGElement*>::const_iterator it = m_referencedElements.begin(); 69 HashSet<SVGElement*>::const_iterator end = m_referencedElements.end(); 70 71 for (; it != end; ++it) { 72 SVGElement* referencedElement = *it; 73 referencedElement->setCursorImageValue(0); 74 if (SVGCursorElement* cursorElement = resourceReferencedByCursorElement(url, referencedElement->document())) 75 cursorElement->removeClient(referencedElement); 76 } 77#endif 78} 79 80bool CSSCursorImageValue::updateIfSVGCursorIsUsed(Element* element) 81{ 82#if !ENABLE(SVG) 83 UNUSED_PARAM(element); 84#else 85 if (!element || !element->isSVGElement()) 86 return false; 87 88 const String& url = getStringValue(); 89 if (!isSVGCursorIdentifier(url)) 90 return false; 91 92 if (SVGCursorElement* cursorElement = resourceReferencedByCursorElement(url, element->document())) { 93 float x = roundf(cursorElement->x().value(0)); 94 m_hotspot.setX(static_cast<int>(x)); 95 96 float y = roundf(cursorElement->y().value(0)); 97 m_hotspot.setY(static_cast<int>(y)); 98 99 if (cachedImageURL() != element->document()->completeURL(cursorElement->href())) 100 clearCachedImage(); 101 102 SVGElement* svgElement = static_cast<SVGElement*>(element); 103 m_referencedElements.add(svgElement); 104 svgElement->setCursorImageValue(this); 105 cursorElement->addClient(svgElement); 106 return true; 107 } 108#endif 109 110 return false; 111} 112 113StyleCachedImage* CSSCursorImageValue::cachedImage(DocLoader* loader) 114{ 115 String url = getStringValue(); 116 117#if ENABLE(SVG) 118 if (isSVGCursorIdentifier(url) && loader && loader->doc()) { 119 if (SVGCursorElement* cursorElement = resourceReferencedByCursorElement(url, loader->doc())) 120 url = cursorElement->href(); 121 } 122#endif 123 124 return CSSImageValue::cachedImage(loader, url); 125} 126 127#if ENABLE(SVG) 128void CSSCursorImageValue::removeReferencedElement(SVGElement* element) 129{ 130 m_referencedElements.remove(element); 131} 132#endif 133 134} // namespace WebCore 135