1/* 2 * Copyright (C) 2004, 2005, 2007 Nikolas Zimmermann <zimmermann@kde.org> 3 * Copyright (C) 2004, 2005 Rob Buis <buis@kde.org> 4 * Copyright (C) 2010 Dirk Schulze <krit@webkit.org> 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 24#if ENABLE(SVG) && ENABLE(FILTERS) 25#include "SVGFEImageElement.h" 26 27#include "Attr.h" 28#include "CachedImage.h" 29#include "CachedResourceLoader.h" 30#include "ColorSpace.h" 31#include "Document.h" 32#include "Image.h" 33#include "RenderObject.h" 34#include "RenderSVGResource.h" 35#include "SVGImageBufferTools.h" 36#include "SVGNames.h" 37#include "SVGPreserveAspectRatio.h" 38 39namespace WebCore { 40 41// Animated property definitions 42DEFINE_ANIMATED_PRESERVEASPECTRATIO(SVGFEImageElement, SVGNames::preserveAspectRatioAttr, PreserveAspectRatio, preserveAspectRatio) 43DEFINE_ANIMATED_STRING(SVGFEImageElement, XLinkNames::hrefAttr, Href, href) 44DEFINE_ANIMATED_BOOLEAN(SVGFEImageElement, SVGNames::externalResourcesRequiredAttr, ExternalResourcesRequired, externalResourcesRequired) 45 46inline SVGFEImageElement::SVGFEImageElement(const QualifiedName& tagName, Document* document) 47 : SVGFilterPrimitiveStandardAttributes(tagName, document) 48{ 49} 50 51PassRefPtr<SVGFEImageElement> SVGFEImageElement::create(const QualifiedName& tagName, Document* document) 52{ 53 return adoptRef(new SVGFEImageElement(tagName, document)); 54} 55 56SVGFEImageElement::~SVGFEImageElement() 57{ 58 if (m_cachedImage) 59 m_cachedImage->removeClient(this); 60} 61 62void SVGFEImageElement::requestImageResource() 63{ 64 if (m_cachedImage) { 65 m_cachedImage->removeClient(this); 66 m_cachedImage = 0; 67 } 68 69 Element* hrefElement = document()->getElementById(SVGURIReference::getTarget(href())); 70 if (hrefElement && hrefElement->isSVGElement() && hrefElement->renderer()) 71 return; 72 73 m_cachedImage = ownerDocument()->cachedResourceLoader()->requestImage(href()); 74 75 if (m_cachedImage) 76 m_cachedImage->addClient(this); 77} 78 79void SVGFEImageElement::parseMappedAttribute(Attribute* attr) 80{ 81 const String& value = attr->value(); 82 if (attr->name() == SVGNames::preserveAspectRatioAttr) 83 SVGPreserveAspectRatio::parsePreserveAspectRatio(this, value); 84 else { 85 if (SVGURIReference::parseMappedAttribute(attr)) { 86 requestImageResource(); 87 return; 88 } 89 if (SVGLangSpace::parseMappedAttribute(attr)) 90 return; 91 if (SVGExternalResourcesRequired::parseMappedAttribute(attr)) 92 return; 93 94 SVGFilterPrimitiveStandardAttributes::parseMappedAttribute(attr); 95 } 96} 97 98void SVGFEImageElement::svgAttributeChanged(const QualifiedName& attrName) 99{ 100 SVGFilterPrimitiveStandardAttributes::svgAttributeChanged(attrName); 101 102 if (attrName == SVGNames::preserveAspectRatioAttr) 103 invalidate(); 104} 105 106void SVGFEImageElement::synchronizeProperty(const QualifiedName& attrName) 107{ 108 SVGFilterPrimitiveStandardAttributes::synchronizeProperty(attrName); 109 110 if (attrName == anyQName()) { 111 synchronizePreserveAspectRatio(); 112 synchronizeHref(); 113 synchronizeExternalResourcesRequired(); 114 return; 115 } 116 117 if (attrName == SVGNames::preserveAspectRatioAttr) 118 synchronizePreserveAspectRatio(); 119 else if (SVGURIReference::isKnownAttribute(attrName)) 120 synchronizeHref(); 121 else if (SVGExternalResourcesRequired::isKnownAttribute(attrName)) 122 synchronizeExternalResourcesRequired(); 123} 124 125AttributeToPropertyTypeMap& SVGFEImageElement::attributeToPropertyTypeMap() 126{ 127 DEFINE_STATIC_LOCAL(AttributeToPropertyTypeMap, s_attributeToPropertyTypeMap, ()); 128 return s_attributeToPropertyTypeMap; 129} 130 131void SVGFEImageElement::fillAttributeToPropertyTypeMap() 132{ 133 AttributeToPropertyTypeMap& attributeToPropertyTypeMap = this->attributeToPropertyTypeMap(); 134 135 SVGFilterPrimitiveStandardAttributes::fillPassedAttributeToPropertyTypeMap(attributeToPropertyTypeMap); 136 attributeToPropertyTypeMap.set(SVGNames::preserveAspectRatioAttr, AnimatedPreserveAspectRatio); 137 attributeToPropertyTypeMap.set(XLinkNames::hrefAttr, AnimatedString); 138} 139 140void SVGFEImageElement::notifyFinished(CachedResource*) 141{ 142 if (!inDocument()) 143 return; 144 145 Element* parent = parentElement(); 146 ASSERT(parent); 147 148 if (!parent->hasTagName(SVGNames::filterTag) || !parent->renderer()) 149 return; 150 151 RenderSVGResource::markForLayoutAndParentResourceInvalidation(parent->renderer()); 152} 153 154PassRefPtr<FilterEffect> SVGFEImageElement::build(SVGFilterBuilder*, Filter* filter) 155{ 156 if (!m_cachedImage && !m_targetImage) { 157 Element* hrefElement = document()->getElementById(SVGURIReference::getTarget(href())); 158 if (!hrefElement || !hrefElement->isSVGElement()) 159 return 0; 160 161 RenderObject* renderer = hrefElement->renderer(); 162 if (!renderer) 163 return 0; 164 165 IntRect targetRect = enclosingIntRect(renderer->objectBoundingBox()); 166 m_targetImage = ImageBuffer::create(targetRect.size(), ColorSpaceLinearRGB); 167 168 AffineTransform contentTransformation; 169 SVGImageBufferTools::renderSubtreeToImageBuffer(m_targetImage.get(), renderer, contentTransformation); 170 } 171 172 return FEImage::create(filter, m_targetImage ? m_targetImage->copyImage() : m_cachedImage->image(), preserveAspectRatio()); 173} 174 175void SVGFEImageElement::addSubresourceAttributeURLs(ListHashSet<KURL>& urls) const 176{ 177 SVGFilterPrimitiveStandardAttributes::addSubresourceAttributeURLs(urls); 178 179 addSubresourceURL(urls, document()->completeURL(href())); 180} 181 182} 183 184#endif // ENABLE(SVG) 185