SVGRectElement.cpp revision 2fc2651226baac27029e38c9d6ef883fa32084db
1/* 2 * Copyright (C) 2004, 2005, 2006, 2008 Nikolas Zimmermann <zimmermann@kde.org> 3 * Copyright (C) 2004, 2005, 2006, 2007 Rob Buis <buis@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 "Attribute.h" 27#include "RenderSVGPath.h" 28#include "RenderSVGResource.h" 29#include "SVGLength.h" 30#include "SVGNames.h" 31 32namespace WebCore { 33 34// Animated property definitions 35DEFINE_ANIMATED_LENGTH(SVGRectElement, SVGNames::xAttr, X, x) 36DEFINE_ANIMATED_LENGTH(SVGRectElement, SVGNames::yAttr, Y, y) 37DEFINE_ANIMATED_LENGTH(SVGRectElement, SVGNames::widthAttr, Width, width) 38DEFINE_ANIMATED_LENGTH(SVGRectElement, SVGNames::heightAttr, Height, height) 39DEFINE_ANIMATED_LENGTH(SVGRectElement, SVGNames::rxAttr, Rx, rx) 40DEFINE_ANIMATED_LENGTH(SVGRectElement, SVGNames::ryAttr, Ry, ry) 41DEFINE_ANIMATED_BOOLEAN(SVGRectElement, SVGNames::externalResourcesRequiredAttr, ExternalResourcesRequired, externalResourcesRequired) 42 43inline SVGRectElement::SVGRectElement(const QualifiedName& tagName, Document* document) 44 : SVGStyledTransformableElement(tagName, document) 45 , m_x(LengthModeWidth) 46 , m_y(LengthModeHeight) 47 , m_width(LengthModeWidth) 48 , m_height(LengthModeHeight) 49 , m_rx(LengthModeWidth) 50 , m_ry(LengthModeHeight) 51{ 52} 53 54PassRefPtr<SVGRectElement> SVGRectElement::create(const QualifiedName& tagName, Document* document) 55{ 56 return adoptRef(new SVGRectElement(tagName, document)); 57} 58 59void SVGRectElement::parseMappedAttribute(Attribute* attr) 60{ 61 if (attr->name() == SVGNames::xAttr) 62 setXBaseValue(SVGLength(LengthModeWidth, attr->value())); 63 else if (attr->name() == SVGNames::yAttr) 64 setYBaseValue(SVGLength(LengthModeHeight, attr->value())); 65 else if (attr->name() == SVGNames::rxAttr) { 66 setRxBaseValue(SVGLength(LengthModeWidth, attr->value())); 67 if (rxBaseValue().value(this) < 0.0) 68 document()->accessSVGExtensions()->reportError("A negative value for rect <rx> is not allowed"); 69 } else if (attr->name() == SVGNames::ryAttr) { 70 setRyBaseValue(SVGLength(LengthModeHeight, attr->value())); 71 if (ryBaseValue().value(this) < 0.0) 72 document()->accessSVGExtensions()->reportError("A negative value for rect <ry> is not allowed"); 73 } else if (attr->name() == SVGNames::widthAttr) { 74 setWidthBaseValue(SVGLength(LengthModeWidth, attr->value())); 75 if (widthBaseValue().value(this) < 0.0) 76 document()->accessSVGExtensions()->reportError("A negative value for rect <width> is not allowed"); 77 } else if (attr->name() == SVGNames::heightAttr) { 78 setHeightBaseValue(SVGLength(LengthModeHeight, attr->value())); 79 if (heightBaseValue().value(this) < 0.0) 80 document()->accessSVGExtensions()->reportError("A negative value for rect <height> is not allowed"); 81 } else { 82 if (SVGTests::parseMappedAttribute(attr)) 83 return; 84 if (SVGLangSpace::parseMappedAttribute(attr)) 85 return; 86 if (SVGExternalResourcesRequired::parseMappedAttribute(attr)) 87 return; 88 SVGStyledTransformableElement::parseMappedAttribute(attr); 89 } 90} 91 92void SVGRectElement::svgAttributeChanged(const QualifiedName& attrName) 93{ 94 SVGStyledTransformableElement::svgAttributeChanged(attrName); 95 96 bool isLengthAttribute = attrName == SVGNames::xAttr 97 || attrName == SVGNames::yAttr 98 || attrName == SVGNames::widthAttr 99 || attrName == SVGNames::heightAttr 100 || attrName == SVGNames::rxAttr 101 || attrName == SVGNames::ryAttr; 102 103 if (isLengthAttribute) 104 updateRelativeLengthsInformation(); 105 106 if (SVGTests::handleAttributeChange(this, attrName)) 107 return; 108 109 RenderSVGPath* renderer = static_cast<RenderSVGPath*>(this->renderer()); 110 if (!renderer) 111 return; 112 113 if (SVGStyledTransformableElement::isKnownAttribute(attrName)) { 114 renderer->setNeedsTransformUpdate(); 115 RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer); 116 return; 117 } 118 119 if (isLengthAttribute) { 120 renderer->setNeedsPathUpdate(); 121 RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer); 122 return; 123 } 124 125 if (SVGLangSpace::isKnownAttribute(attrName) 126 || SVGExternalResourcesRequired::isKnownAttribute(attrName)) 127 RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer); 128} 129 130void SVGRectElement::synchronizeProperty(const QualifiedName& attrName) 131{ 132 SVGStyledTransformableElement::synchronizeProperty(attrName); 133 134 if (attrName == anyQName()) { 135 synchronizeX(); 136 synchronizeY(); 137 synchronizeWidth(); 138 synchronizeHeight(); 139 synchronizeRx(); 140 synchronizeRy(); 141 synchronizeExternalResourcesRequired(); 142 SVGTests::synchronizeProperties(this, attrName); 143 return; 144 } 145 146 if (attrName == SVGNames::xAttr) 147 synchronizeX(); 148 else if (attrName == SVGNames::yAttr) 149 synchronizeY(); 150 else if (attrName == SVGNames::widthAttr) 151 synchronizeWidth(); 152 else if (attrName == SVGNames::heightAttr) 153 synchronizeHeight(); 154 else if (attrName == SVGNames::rxAttr) 155 synchronizeRx(); 156 else if (attrName == SVGNames::ryAttr) 157 synchronizeRy(); 158 else if (SVGExternalResourcesRequired::isKnownAttribute(attrName)) 159 synchronizeExternalResourcesRequired(); 160 else if (SVGTests::isKnownAttribute(attrName)) 161 SVGTests::synchronizeProperties(this, attrName); 162} 163 164AttributeToPropertyTypeMap& SVGRectElement::attributeToPropertyTypeMap() 165{ 166 DEFINE_STATIC_LOCAL(AttributeToPropertyTypeMap, s_attributeToPropertyTypeMap, ()); 167 return s_attributeToPropertyTypeMap; 168} 169 170void SVGRectElement::fillAttributeToPropertyTypeMap() 171{ 172 AttributeToPropertyTypeMap& attributeToPropertyTypeMap = this->attributeToPropertyTypeMap(); 173 174 SVGStyledTransformableElement::fillPassedAttributeToPropertyTypeMap(attributeToPropertyTypeMap); 175 attributeToPropertyTypeMap.set(SVGNames::xAttr, AnimatedLength); 176 attributeToPropertyTypeMap.set(SVGNames::yAttr, AnimatedLength); 177 attributeToPropertyTypeMap.set(SVGNames::widthAttr, AnimatedLength); 178 attributeToPropertyTypeMap.set(SVGNames::heightAttr, AnimatedLength); 179 attributeToPropertyTypeMap.set(SVGNames::rxAttr, AnimatedLength); 180 attributeToPropertyTypeMap.set(SVGNames::ryAttr, AnimatedLength); 181} 182 183void SVGRectElement::toPathData(Path& path) const 184{ 185 ASSERT(path.isEmpty()); 186 187 float widthValue = width().value(this); 188 if (widthValue <= 0) 189 return; 190 191 float heightValue = height().value(this); 192 if (heightValue <= 0) 193 return; 194 195 float xValue = x().value(this); 196 float yValue = y().value(this); 197 198 FloatRect rect(xValue, yValue, widthValue, heightValue); 199 200 bool hasRx = hasAttribute(SVGNames::rxAttr); 201 bool hasRy = hasAttribute(SVGNames::ryAttr); 202 if (hasRx || hasRy) { 203 float rxValue = rx().value(this); 204 float ryValue = ry().value(this); 205 if (!hasRx) 206 rxValue = ryValue; 207 else if (!hasRy) 208 ryValue = rxValue; 209 path.addRoundedRect(rect, FloatSize(rxValue, ryValue)); 210 return; 211 } 212 213 path.addRect(rect); 214} 215 216bool SVGRectElement::selfHasRelativeLengths() const 217{ 218 return x().isRelative() 219 || y().isRelative() 220 || width().isRelative() 221 || height().isRelative() 222 || rx().isRelative() 223 || ry().isRelative(); 224} 225 226} 227 228#endif // ENABLE(SVG) 229