2 * Copyright (C) 2004, 2005, 2006, 2008 Nikolas Zimmermann <zimmermann@kde.org>
3 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Rob Buis <buis@kde.org>
4 * Copyright (C) 2006 Alexander Kellett <lypanov@kde.org>
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.
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.
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.
25 #include "SVGImageElement.h"
27 #include "Attribute.h"
28 #include "CSSPropertyNames.h"
29 #include "RenderImageResource.h"
30 #include "RenderSVGImage.h"
31 #include "RenderSVGResource.h"
33 #include "SVGSVGElement.h"
34 #include "XLinkNames.h"
38 // Animated property definitions
39 DEFINE_ANIMATED_LENGTH(SVGImageElement, SVGNames::xAttr, X, x)
40 DEFINE_ANIMATED_LENGTH(SVGImageElement, SVGNames::yAttr, Y, y)
41 DEFINE_ANIMATED_LENGTH(SVGImageElement, SVGNames::widthAttr, Width, width)
42 DEFINE_ANIMATED_LENGTH(SVGImageElement, SVGNames::heightAttr, Height, height)
43 DEFINE_ANIMATED_PRESERVEASPECTRATIO(SVGImageElement, SVGNames::preserveAspectRatioAttr, PreserveAspectRatio, preserveAspectRatio)
44 DEFINE_ANIMATED_STRING(SVGImageElement, XLinkNames::hrefAttr, Href, href)
45 DEFINE_ANIMATED_BOOLEAN(SVGImageElement, SVGNames::externalResourcesRequiredAttr, ExternalResourcesRequired, externalResourcesRequired)
47 inline SVGImageElement::SVGImageElement(const QualifiedName& tagName, Document* document)
48 : SVGStyledTransformableElement(tagName, document)
49 , m_x(LengthModeWidth)
50 , m_y(LengthModeHeight)
51 , m_width(LengthModeWidth)
52 , m_height(LengthModeHeight)
57 PassRefPtr<SVGImageElement> SVGImageElement::create(const QualifiedName& tagName, Document* document)
59 return adoptRef(new SVGImageElement(tagName, document));
62 void SVGImageElement::parseMappedAttribute(Attribute* attr)
64 if (attr->name() == SVGNames::xAttr)
65 setXBaseValue(SVGLength(LengthModeWidth, attr->value()));
66 else if (attr->name() == SVGNames::yAttr)
67 setYBaseValue(SVGLength(LengthModeHeight, attr->value()));
68 else if (attr->name() == SVGNames::preserveAspectRatioAttr)
69 SVGPreserveAspectRatio::parsePreserveAspectRatio(this, attr->value());
70 else if (attr->name() == SVGNames::widthAttr) {
71 setWidthBaseValue(SVGLength(LengthModeWidth, attr->value()));
72 addCSSProperty(attr, CSSPropertyWidth, attr->value());
73 if (widthBaseValue().value(this) < 0.0)
74 document()->accessSVGExtensions()->reportError("A negative value for image attribute <width> is not allowed");
75 } else if (attr->name() == SVGNames::heightAttr) {
76 setHeightBaseValue(SVGLength(LengthModeHeight, attr->value()));
77 addCSSProperty(attr, CSSPropertyHeight, attr->value());
78 if (heightBaseValue().value(this) < 0.0)
79 document()->accessSVGExtensions()->reportError("A negative value for image attribute <height> is not allowed");
81 if (SVGTests::parseMappedAttribute(attr))
83 if (SVGLangSpace::parseMappedAttribute(attr))
85 if (SVGExternalResourcesRequired::parseMappedAttribute(attr))
87 if (SVGURIReference::parseMappedAttribute(attr))
89 SVGStyledTransformableElement::parseMappedAttribute(attr);
93 void SVGImageElement::svgAttributeChanged(const QualifiedName& attrName)
95 SVGStyledTransformableElement::svgAttributeChanged(attrName);
97 if (SVGURIReference::isKnownAttribute(attrName))
98 m_imageLoader.updateFromElementIgnoringPreviousError();
100 bool isLengthAttribute = attrName == SVGNames::xAttr
101 || attrName == SVGNames::yAttr
102 || attrName == SVGNames::widthAttr
103 || attrName == SVGNames::heightAttr;
105 if (isLengthAttribute)
106 updateRelativeLengthsInformation();
108 if (SVGTests::handleAttributeChange(this, attrName))
111 RenderObject* renderer = this->renderer();
115 if (SVGStyledTransformableElement::isKnownAttribute(attrName)) {
116 renderer->setNeedsTransformUpdate();
117 RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer);
121 if (isLengthAttribute) {
122 renderer->updateFromElement();
123 RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer, false);
127 if (attrName == SVGNames::preserveAspectRatioAttr
128 || SVGLangSpace::isKnownAttribute(attrName)
129 || SVGExternalResourcesRequired::isKnownAttribute(attrName))
130 RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer);
133 void SVGImageElement::synchronizeProperty(const QualifiedName& attrName)
135 SVGStyledTransformableElement::synchronizeProperty(attrName);
137 if (attrName == anyQName()) {
142 synchronizePreserveAspectRatio();
143 synchronizeExternalResourcesRequired();
145 SVGTests::synchronizeProperties(this, attrName);
149 if (attrName == SVGNames::xAttr)
151 else if (attrName == SVGNames::yAttr)
153 else if (attrName == SVGNames::widthAttr)
155 else if (attrName == SVGNames::heightAttr)
157 else if (attrName == SVGNames::preserveAspectRatioAttr)
158 synchronizePreserveAspectRatio();
159 else if (SVGExternalResourcesRequired::isKnownAttribute(attrName))
160 synchronizeExternalResourcesRequired();
161 else if (SVGURIReference::isKnownAttribute(attrName))
163 else if (SVGTests::isKnownAttribute(attrName))
164 SVGTests::synchronizeProperties(this, attrName);
167 AttributeToPropertyTypeMap& SVGImageElement::attributeToPropertyTypeMap()
169 DEFINE_STATIC_LOCAL(AttributeToPropertyTypeMap, s_attributeToPropertyTypeMap, ());
170 return s_attributeToPropertyTypeMap;
173 void SVGImageElement::fillAttributeToPropertyTypeMap()
175 AttributeToPropertyTypeMap& attributeToPropertyTypeMap = this->attributeToPropertyTypeMap();
177 SVGStyledTransformableElement::fillPassedAttributeToPropertyTypeMap(attributeToPropertyTypeMap);
178 attributeToPropertyTypeMap.set(SVGNames::xAttr, AnimatedLength);
179 attributeToPropertyTypeMap.set(SVGNames::yAttr, AnimatedLength);
180 attributeToPropertyTypeMap.set(SVGNames::widthAttr, AnimatedLength);
181 attributeToPropertyTypeMap.set(SVGNames::heightAttr, AnimatedLength);
182 attributeToPropertyTypeMap.set(SVGNames::preserveAspectRatioAttr, AnimatedPreserveAspectRatio);
183 attributeToPropertyTypeMap.set(XLinkNames::hrefAttr, AnimatedString);
186 bool SVGImageElement::selfHasRelativeLengths() const
188 return x().isRelative()
190 || width().isRelative()
191 || height().isRelative();
194 RenderObject* SVGImageElement::createRenderer(RenderArena* arena, RenderStyle*)
196 return new (arena) RenderSVGImage(this);
199 bool SVGImageElement::haveLoadedRequiredResources()
201 return !externalResourcesRequiredBaseValue() || m_imageLoader.haveFiredLoadEvent();
204 void SVGImageElement::attach()
206 SVGStyledTransformableElement::attach();
208 if (RenderSVGImage* imageObj = toRenderSVGImage(renderer())) {
209 if (imageObj->imageResource()->hasImage())
212 imageObj->imageResource()->setCachedImage(m_imageLoader.image());
216 void SVGImageElement::insertedIntoDocument()
218 SVGStyledTransformableElement::insertedIntoDocument();
220 // Update image loader, as soon as we're living in the tree.
221 // We can only resolve base URIs properly, after that!
222 m_imageLoader.updateFromElement();
225 const QualifiedName& SVGImageElement::imageSourceAttributeName() const
227 return XLinkNames::hrefAttr;
230 void SVGImageElement::addSubresourceAttributeURLs(ListHashSet<KURL>& urls) const
232 SVGStyledTransformableElement::addSubresourceAttributeURLs(urls);
234 addSubresourceURL(urls, document()->completeURL(href()));
237 void SVGImageElement::willMoveToNewOwnerDocument()
239 m_imageLoader.elementWillMoveToNewOwnerDocument();
240 SVGStyledTransformableElement::willMoveToNewOwnerDocument();
245 #endif // ENABLE(SVG)