1 /* 2 Copyright (C) 2004, 2005, 2006, 2008 Nikolas Zimmermann <zimmermann (at) kde.org> 3 2004, 2005, 2006, 2007 Rob Buis <buis (at) kde.org> 4 5 This library is free software; you can redistribute it and/or 6 modify it under the terms of the GNU Library General Public 7 License as published by the Free Software Foundation; either 8 version 2 of the License, or (at your option) any later version. 9 10 This library is distributed in the hope that it will be useful, 11 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 Library General Public License for more details. 14 15 You should have received a copy of the GNU Library General Public License 16 along with this library; see the file COPYING.LIB. If not, write to 17 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 18 Boston, MA 02110-1301, USA. 19 */ 20 21 #include "config.h" 22 23 #if ENABLE(SVG) 24 #include "SVGRectElement.h" 25 26 #include "MappedAttribute.h" 27 #include "RenderPath.h" 28 #include "SVGLength.h" 29 #include "SVGNames.h" 30 31 namespace WebCore { 32 33 SVGRectElement::SVGRectElement(const QualifiedName& tagName, Document *doc) 34 : SVGStyledTransformableElement(tagName, doc) 35 , SVGTests() 36 , SVGLangSpace() 37 , SVGExternalResourcesRequired() 38 , m_x(LengthModeWidth) 39 , m_y(LengthModeHeight) 40 , m_width(LengthModeWidth) 41 , m_height(LengthModeHeight) 42 , m_rx(LengthModeWidth) 43 , m_ry(LengthModeHeight) 44 { 45 } 46 47 SVGRectElement::~SVGRectElement() 48 { 49 } 50 51 void SVGRectElement::parseMappedAttribute(MappedAttribute* attr) 52 { 53 if (attr->name() == SVGNames::xAttr) 54 setXBaseValue(SVGLength(LengthModeWidth, attr->value())); 55 else if (attr->name() == SVGNames::yAttr) 56 setYBaseValue(SVGLength(LengthModeHeight, attr->value())); 57 else if (attr->name() == SVGNames::rxAttr) { 58 setRxBaseValue(SVGLength(LengthModeWidth, attr->value())); 59 if (rxBaseValue().value(this) < 0.0) 60 document()->accessSVGExtensions()->reportError("A negative value for rect <rx> is not allowed"); 61 } else if (attr->name() == SVGNames::ryAttr) { 62 setRyBaseValue(SVGLength(LengthModeHeight, attr->value())); 63 if (ryBaseValue().value(this) < 0.0) 64 document()->accessSVGExtensions()->reportError("A negative value for rect <ry> is not allowed"); 65 } else if (attr->name() == SVGNames::widthAttr) { 66 setWidthBaseValue(SVGLength(LengthModeWidth, attr->value())); 67 if (widthBaseValue().value(this) < 0.0) 68 document()->accessSVGExtensions()->reportError("A negative value for rect <width> is not allowed"); 69 } else if (attr->name() == SVGNames::heightAttr) { 70 setHeightBaseValue(SVGLength(LengthModeHeight, attr->value())); 71 if (heightBaseValue().value(this) < 0.0) 72 document()->accessSVGExtensions()->reportError("A negative value for rect <height> is not allowed"); 73 } else { 74 if (SVGTests::parseMappedAttribute(attr)) 75 return; 76 if (SVGLangSpace::parseMappedAttribute(attr)) 77 return; 78 if (SVGExternalResourcesRequired::parseMappedAttribute(attr)) 79 return; 80 SVGStyledTransformableElement::parseMappedAttribute(attr); 81 } 82 } 83 84 void SVGRectElement::svgAttributeChanged(const QualifiedName& attrName) 85 { 86 SVGStyledTransformableElement::svgAttributeChanged(attrName); 87 88 if (!renderer()) 89 return; 90 91 if (attrName == SVGNames::xAttr || attrName == SVGNames::yAttr || 92 attrName == SVGNames::widthAttr || attrName == SVGNames::heightAttr || 93 attrName == SVGNames::rxAttr || attrName == SVGNames::ryAttr || 94 SVGTests::isKnownAttribute(attrName) || 95 SVGLangSpace::isKnownAttribute(attrName) || 96 SVGExternalResourcesRequired::isKnownAttribute(attrName) || 97 SVGStyledTransformableElement::isKnownAttribute(attrName)) 98 renderer()->setNeedsLayout(true); 99 } 100 101 void SVGRectElement::synchronizeProperty(const QualifiedName& attrName) 102 { 103 SVGStyledTransformableElement::synchronizeProperty(attrName); 104 105 if (attrName == anyQName()) { 106 synchronizeX(); 107 synchronizeY(); 108 synchronizeWidth(); 109 synchronizeHeight(); 110 synchronizeRx(); 111 synchronizeRy(); 112 synchronizeExternalResourcesRequired(); 113 return; 114 } 115 116 if (attrName == SVGNames::xAttr) 117 synchronizeX(); 118 else if (attrName == SVGNames::yAttr) 119 synchronizeY(); 120 else if (attrName == SVGNames::widthAttr) 121 synchronizeWidth(); 122 else if (attrName == SVGNames::heightAttr) 123 synchronizeHeight(); 124 else if (attrName == SVGNames::rxAttr) 125 synchronizeRx(); 126 else if (attrName == SVGNames::ryAttr) 127 synchronizeRy(); 128 else if (SVGExternalResourcesRequired::isKnownAttribute(attrName)) 129 synchronizeExternalResourcesRequired(); 130 } 131 132 Path SVGRectElement::toPathData() const 133 { 134 FloatRect rect(x().value(this), y().value(this), width().value(this), height().value(this)); 135 136 bool hasRx = hasAttribute(SVGNames::rxAttr); 137 bool hasRy = hasAttribute(SVGNames::ryAttr); 138 if (hasRx || hasRy) { 139 float _rx = hasRx ? rx().value(this) : ry().value(this); 140 float _ry = hasRy ? ry().value(this) : rx().value(this); 141 return Path::createRoundedRectangle(rect, FloatSize(_rx, _ry)); 142 } 143 144 return Path::createRectangle(rect); 145 } 146 147 bool SVGRectElement::hasRelativeValues() const 148 { 149 return (x().isRelative() || width().isRelative() || 150 y().isRelative() || height().isRelative() || 151 rx().isRelative() || ry().isRelative()); 152 } 153 154 } 155 156 #endif // ENABLE(SVG) 157