File indexing completed on 2024-04-28 11:39:15

0001 /*
0002     Copyright (C) 2004, 2005, 2006, 2008 Nikolas Zimmermann <zimmermann@kde.org>
0003                   2004, 2005, 2006, 2007, 2008 Rob Buis <buis@kde.org>
0004                   2006 Alexander Kellett <lypanov@kde.org>
0005 
0006     This file is part of the KDE project
0007 
0008     This library is free software; you can redistribute it and/or
0009     modify it under the terms of the GNU Library General Public
0010     License as published by the Free Software Foundation; either
0011     version 2 of the License, or (at your option) any later version.
0012 
0013     This library is distributed in the hope that it will be useful,
0014     but WITHOUT ANY WARRANTY; without even the implied warranty of
0015     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0016     Library General Public License for more details.
0017 
0018     You should have received a copy of the GNU Library General Public License
0019     along with this library; see the file COPYING.LIB.  If not, write to
0020     the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
0021     Boston, MA 02110-1301, USA.
0022 */
0023 
0024 #if ENABLE(SVG)
0025 #include "SVGImageElement.h"
0026 
0027 #include "CSSPropertyNames.h"
0028 #include "RenderSVGImage.h"
0029 #include "SVGDocument.h"
0030 #include "SVGLength.h"
0031 #include "SVGNames.h"
0032 #include "SVGPreserveAspectRatio.h"
0033 #include "SVGSVGElement.h"
0034 #include "XLinkNames.h"
0035 
0036 namespace WebCore
0037 {
0038 
0039 SVGImageElement::SVGImageElement(const QualifiedName &tagName, Document *doc)
0040     : SVGStyledTransformableElement(tagName, doc)
0041     , SVGTests()
0042     , SVGLangSpace()
0043     , SVGExternalResourcesRequired()
0044     , SVGURIReference()
0045     , m_x(this, LengthModeWidth)
0046     , m_y(this, LengthModeHeight)
0047     , m_width(this, LengthModeWidth)
0048     , m_height(this, LengthModeHeight)
0049     , m_preserveAspectRatio(SVGPreserveAspectRatio::create())
0050     , m_imageLoader(this)
0051 {
0052 }
0053 
0054 SVGImageElement::~SVGImageElement()
0055 {
0056 }
0057 
0058 ANIMATED_PROPERTY_DEFINITIONS(SVGImageElement, SVGLength, Length, length, X, x, SVGNames::xAttr, m_x)
0059 ANIMATED_PROPERTY_DEFINITIONS(SVGImageElement, SVGLength, Length, length, Y, y, SVGNames::yAttr, m_y)
0060 ANIMATED_PROPERTY_DEFINITIONS(SVGImageElement, SVGLength, Length, length, Width, width, SVGNames::widthAttr, m_width)
0061 ANIMATED_PROPERTY_DEFINITIONS(SVGImageElement, SVGLength, Length, length, Height, height, SVGNames::heightAttr, m_height)
0062 ANIMATED_PROPERTY_DEFINITIONS(SVGImageElement, SVGPreserveAspectRatio *, PreserveAspectRatio, preserveAspectRatio, PreserveAspectRatio, preserveAspectRatio, SVGNames::preserveAspectRatioAttr, m_preserveAspectRatio.get())
0063 
0064 void SVGImageElement::parseMappedAttribute(MappedAttribute *attr)
0065 {
0066     if (attr->name() == SVGNames::xAttr) {
0067         setXBaseValue(SVGLength(this, LengthModeWidth, attr->value()));
0068     } else if (attr->name() == SVGNames::yAttr) {
0069         setYBaseValue(SVGLength(this, LengthModeHeight, attr->value()));
0070     } else if (attr->name() == SVGNames::preserveAspectRatioAttr) {
0071         const UChar *c = attr->value().characters();
0072         const UChar *end = c + attr->value().length();
0073         preserveAspectRatioBaseValue()->parsePreserveAspectRatio(c, end);
0074     } else if (attr->name() == SVGNames::widthAttr) {
0075         setWidthBaseValue(SVGLength(this, LengthModeWidth, attr->value()));
0076         addCSSProperty(attr, CSSPropertyWidth, attr->value());
0077         if (width().value() < 0.0) {
0078             document()->accessSVGExtensions()->reportError("A negative value for image attribute <width> is not allowed");
0079         }
0080     } else if (attr->name() == SVGNames::heightAttr) {
0081         setHeightBaseValue(SVGLength(this, LengthModeHeight, attr->value()));
0082         addCSSProperty(attr, CSSPropertyHeight, attr->value());
0083         if (height().value() < 0.0) {
0084             document()->accessSVGExtensions()->reportError("A negative value for image attribute <height> is not allowed");
0085         }
0086     } else {
0087         if (SVGTests::parseMappedAttribute(attr)) {
0088             return;
0089         }
0090         if (SVGLangSpace::parseMappedAttribute(attr)) {
0091             return;
0092         }
0093         if (SVGExternalResourcesRequired::parseMappedAttribute(attr)) {
0094             return;
0095         }
0096         if (SVGURIReference::parseMappedAttribute(attr)) {
0097             return;
0098         }
0099         SVGStyledTransformableElement::parseMappedAttribute(attr);
0100     }
0101 }
0102 
0103 void SVGImageElement::svgAttributeChanged(const QualifiedName &attrName)
0104 {
0105     SVGStyledTransformableElement::svgAttributeChanged(attrName);
0106 
0107     if (!renderer()) {
0108         return;
0109     }
0110 
0111     bool isURIAttribute = SVGURIReference::isKnownAttribute(attrName);
0112 
0113     if (attrName == SVGNames::xAttr || attrName == SVGNames::yAttr ||
0114             attrName == SVGNames::widthAttr || attrName == SVGNames::heightAttr ||
0115             SVGTests::isKnownAttribute(attrName) ||
0116             SVGLangSpace::isKnownAttribute(attrName) ||
0117             SVGExternalResourcesRequired::isKnownAttribute(attrName) ||
0118             isURIAttribute ||
0119             SVGStyledTransformableElement::isKnownAttribute(attrName)) {
0120         renderer()->setNeedsLayout(true);
0121 
0122         if (isURIAttribute) {
0123             m_imageLoader.updateFromElement();
0124         }
0125     }
0126 }
0127 
0128 bool SVGImageElement::hasRelativeValues() const
0129 {
0130     return (x().isRelative() || width().isRelative() ||
0131             y().isRelative() || height().isRelative());
0132 }
0133 
0134 RenderObject *SVGImageElement::createRenderer(RenderArena *arena, RenderStyle *style)
0135 {
0136     return new(arena) RenderSVGImage(this);
0137 }
0138 
0139 bool SVGImageElement::haveLoadedRequiredResources()
0140 {
0141     return !externalResourcesRequiredBaseValue() || m_imageLoader.haveFiredLoadEvent();
0142 }
0143 
0144 void SVGImageElement::attach()
0145 {
0146     SVGStyledTransformableElement::attach();
0147     m_imageLoader.updateFromElement();
0148     if (RenderSVGImage *imageObj = static_cast<RenderSVGImage *>(renderer())) {
0149         imageObj->setCachedImage(m_imageLoader.image());
0150     }
0151 }
0152 
0153 void SVGImageElement::getSubresourceAttributeStrings(Vector<String> &urls) const
0154 {
0155     urls.append(href());
0156 }
0157 
0158 }
0159 
0160 #endif // ENABLE(SVG)