File indexing completed on 2024-04-28 15:24:40

0001 /*
0002     Copyright (C) 2004, 2005, 2006, 2008 Nikolas Zimmermann <zimmermann@kde.org>
0003                   2004, 2005, 2006, 2007 Rob Buis <buis@kde.org>
0004 
0005     This file is part of the KDE project
0006 
0007     This library is free software; you can redistribute it and/or
0008     modify it under the terms of the GNU Library General Public
0009     License as published by the Free Software Foundation; either
0010     version 2 of the License, or (at your option) any later version.
0011 
0012     This library is distributed in the hope that it will be useful,
0013     but WITHOUT ANY WARRANTY; without even the implied warranty of
0014     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0015     Library General Public License for more details.
0016 
0017     You should have received a copy of the GNU Library General Public License
0018     along with this library; see the file COPYING.LIB.  If not, write to
0019     the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
0020     Boston, MA 02110-1301, USA.
0021 */
0022 
0023 #include "wtf/Platform.h"
0024 
0025 #if ENABLE(SVG)
0026 #include "SVGRectElement.h"
0027 
0028 #include "RenderPath.h"
0029 #include "SVGLength.h"
0030 #include "SVGNames.h"
0031 
0032 namespace WebCore
0033 {
0034 
0035 SVGRectElement::SVGRectElement(const QualifiedName &tagName, Document *doc)
0036     : SVGStyledTransformableElement(tagName, doc)
0037     , SVGTests()
0038     , SVGLangSpace()
0039     , SVGExternalResourcesRequired()
0040     , m_x(this, LengthModeWidth)
0041     , m_y(this, LengthModeHeight)
0042     , m_width(this, LengthModeWidth)
0043     , m_height(this, LengthModeHeight)
0044     , m_rx(this, LengthModeWidth)
0045     , m_ry(this, LengthModeHeight)
0046 {
0047 }
0048 
0049 SVGRectElement::~SVGRectElement()
0050 {
0051 }
0052 
0053 ANIMATED_PROPERTY_DEFINITIONS(SVGRectElement, SVGLength, Length, length, X, x, SVGNames::xAttr, m_x)
0054 ANIMATED_PROPERTY_DEFINITIONS(SVGRectElement, SVGLength, Length, length, Y, y, SVGNames::yAttr, m_y)
0055 ANIMATED_PROPERTY_DEFINITIONS(SVGRectElement, SVGLength, Length, length, Width, width, SVGNames::widthAttr, m_width)
0056 ANIMATED_PROPERTY_DEFINITIONS(SVGRectElement, SVGLength, Length, length, Height, height, SVGNames::heightAttr, m_height)
0057 ANIMATED_PROPERTY_DEFINITIONS(SVGRectElement, SVGLength, Length, length, Rx, rx, SVGNames::rxAttr, m_rx)
0058 ANIMATED_PROPERTY_DEFINITIONS(SVGRectElement, SVGLength, Length, length, Ry, ry, SVGNames::ryAttr, m_ry)
0059 
0060 void SVGRectElement::parseMappedAttribute(MappedAttribute *attr)
0061 {
0062     // qCDebug(KHTML_LOG) << "called with" << attr->localName() << attr->value();
0063     if (attr->name() == SVGNames::xAttr) {
0064         setXBaseValue(SVGLength(this, LengthModeWidth, attr->value()));
0065     } else if (attr->name() == SVGNames::yAttr) {
0066         setYBaseValue(SVGLength(this, LengthModeHeight, attr->value()));
0067     } else if (attr->name() == SVGNames::rxAttr) {
0068         setRxBaseValue(SVGLength(this, LengthModeWidth, attr->value()));
0069         if (rx().value() < 0.0) {
0070             document()->accessSVGExtensions()->reportError("A negative value for rect <rx> is not allowed");
0071         }
0072     } else if (attr->name() == SVGNames::ryAttr) {
0073         setRyBaseValue(SVGLength(this, LengthModeHeight, attr->value()));
0074         if (ry().value() < 0.0) {
0075             document()->accessSVGExtensions()->reportError("A negative value for rect <ry> is not allowed");
0076         }
0077     } else if (attr->name() == SVGNames::widthAttr) {
0078         setWidthBaseValue(SVGLength(this, LengthModeWidth, attr->value()));
0079         if (width().value() < 0.0) {
0080             document()->accessSVGExtensions()->reportError("A negative value for rect <width> is not allowed");
0081         }
0082     } else if (attr->name() == SVGNames::heightAttr) {
0083         setHeightBaseValue(SVGLength(this, LengthModeHeight, attr->value()));
0084         if (height().value() < 0.0) {
0085             document()->accessSVGExtensions()->reportError("A negative value for rect <height> is not allowed");
0086         }
0087     } else {
0088         if (SVGTests::parseMappedAttribute(attr)) {
0089             return;
0090         }
0091         if (SVGLangSpace::parseMappedAttribute(attr)) {
0092             return;
0093         }
0094         if (SVGExternalResourcesRequired::parseMappedAttribute(attr)) {
0095             return;
0096         }
0097         SVGStyledTransformableElement::parseMappedAttribute(attr);
0098     }
0099 }
0100 
0101 void SVGRectElement::svgAttributeChanged(const QualifiedName &attrName)
0102 {
0103     SVGStyledTransformableElement::svgAttributeChanged(attrName);
0104 
0105     if (!renderer()) {
0106         return;
0107     }
0108 
0109     if (attrName == SVGNames::xAttr || attrName == SVGNames::yAttr ||
0110             attrName == SVGNames::widthAttr || attrName == SVGNames::heightAttr ||
0111             attrName == SVGNames::rxAttr || attrName == SVGNames::ryAttr ||
0112             SVGTests::isKnownAttribute(attrName) ||
0113             SVGLangSpace::isKnownAttribute(attrName) ||
0114             SVGExternalResourcesRequired::isKnownAttribute(attrName) ||
0115             SVGStyledTransformableElement::isKnownAttribute(attrName)) {
0116         renderer()->setNeedsLayout(true);
0117     }
0118 }
0119 
0120 Path SVGRectElement::toPathData() const
0121 {
0122     FloatRect rect(x().value(), y().value(), width().value(), height().value());
0123 
0124     bool hasRx = hasAttribute(SVGNames::rxAttr);
0125     bool hasRy = hasAttribute(SVGNames::ryAttr);
0126     if (hasRx || hasRy) {
0127         float _rx = hasRx ? rx().value() : ry().value();
0128         float _ry = hasRy ? ry().value() : rx().value();
0129         return Path::createRoundedRectangle(rect, FloatSize(_rx, _ry));
0130     }
0131 
0132     return Path::createRectangle(rect);
0133 }
0134 
0135 bool SVGRectElement::hasRelativeValues() const
0136 {
0137     return (x().isRelative() || width().isRelative() ||
0138             y().isRelative() || height().isRelative() ||
0139             rx().isRelative() || ry().isRelative());
0140 }
0141 
0142 // KHTML ElementImpl pure virtual method
0143 quint32 SVGRectElement::id() const
0144 {
0145     return SVGNames::rectTag.id();
0146 }
0147 
0148 }
0149 
0150 #endif // ENABLE(SVG)