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 "RenderSVGRect.h" 29#include "RenderSVGResource.h" 30#include "SVGElementInstance.h" 31#include "SVGLength.h" 32#include "SVGNames.h" 33 34namespace WebCore { 35 36// Animated property definitions 37DEFINE_ANIMATED_LENGTH(SVGRectElement, SVGNames::xAttr, X, x) 38DEFINE_ANIMATED_LENGTH(SVGRectElement, SVGNames::yAttr, Y, y) 39DEFINE_ANIMATED_LENGTH(SVGRectElement, SVGNames::widthAttr, Width, width) 40DEFINE_ANIMATED_LENGTH(SVGRectElement, SVGNames::heightAttr, Height, height) 41DEFINE_ANIMATED_LENGTH(SVGRectElement, SVGNames::rxAttr, Rx, rx) 42DEFINE_ANIMATED_LENGTH(SVGRectElement, SVGNames::ryAttr, Ry, ry) 43DEFINE_ANIMATED_BOOLEAN(SVGRectElement, SVGNames::externalResourcesRequiredAttr, ExternalResourcesRequired, externalResourcesRequired) 44 45BEGIN_REGISTER_ANIMATED_PROPERTIES(SVGRectElement) 46 REGISTER_LOCAL_ANIMATED_PROPERTY(x) 47 REGISTER_LOCAL_ANIMATED_PROPERTY(y) 48 REGISTER_LOCAL_ANIMATED_PROPERTY(width) 49 REGISTER_LOCAL_ANIMATED_PROPERTY(height) 50 REGISTER_LOCAL_ANIMATED_PROPERTY(rx) 51 REGISTER_LOCAL_ANIMATED_PROPERTY(ry) 52 REGISTER_LOCAL_ANIMATED_PROPERTY(externalResourcesRequired) 53 REGISTER_PARENT_ANIMATED_PROPERTIES(SVGStyledTransformableElement) 54 REGISTER_PARENT_ANIMATED_PROPERTIES(SVGTests) 55END_REGISTER_ANIMATED_PROPERTIES 56 57inline SVGRectElement::SVGRectElement(const QualifiedName& tagName, Document* document) 58 : SVGStyledTransformableElement(tagName, document) 59 , m_x(LengthModeWidth) 60 , m_y(LengthModeHeight) 61 , m_width(LengthModeWidth) 62 , m_height(LengthModeHeight) 63 , m_rx(LengthModeWidth) 64 , m_ry(LengthModeHeight) 65{ 66 ASSERT(hasTagName(SVGNames::rectTag)); 67 registerAnimatedPropertiesForSVGRectElement(); 68} 69 70PassRefPtr<SVGRectElement> SVGRectElement::create(const QualifiedName& tagName, Document* document) 71{ 72 return adoptRef(new SVGRectElement(tagName, document)); 73} 74 75bool SVGRectElement::isSupportedAttribute(const QualifiedName& attrName) 76{ 77 DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, supportedAttributes, ()); 78 if (supportedAttributes.isEmpty()) { 79 SVGTests::addSupportedAttributes(supportedAttributes); 80 SVGLangSpace::addSupportedAttributes(supportedAttributes); 81 SVGExternalResourcesRequired::addSupportedAttributes(supportedAttributes); 82 supportedAttributes.add(SVGNames::xAttr); 83 supportedAttributes.add(SVGNames::yAttr); 84 supportedAttributes.add(SVGNames::widthAttr); 85 supportedAttributes.add(SVGNames::heightAttr); 86 supportedAttributes.add(SVGNames::rxAttr); 87 supportedAttributes.add(SVGNames::ryAttr); 88 } 89 return supportedAttributes.contains<QualifiedName, SVGAttributeHashTranslator>(attrName); 90} 91 92void SVGRectElement::parseAttribute(const QualifiedName& name, const AtomicString& value) 93{ 94 SVGParsingError parseError = NoError; 95 96 if (!isSupportedAttribute(name)) 97 SVGStyledTransformableElement::parseAttribute(name, value); 98 else if (name == SVGNames::xAttr) 99 setXBaseValue(SVGLength::construct(LengthModeWidth, value, parseError)); 100 else if (name == SVGNames::yAttr) 101 setYBaseValue(SVGLength::construct(LengthModeHeight, value, parseError)); 102 else if (name == SVGNames::rxAttr) 103 setRxBaseValue(SVGLength::construct(LengthModeWidth, value, parseError, ForbidNegativeLengths)); 104 else if (name == SVGNames::ryAttr) 105 setRyBaseValue(SVGLength::construct(LengthModeHeight, value, parseError, ForbidNegativeLengths)); 106 else if (name == SVGNames::widthAttr) 107 setWidthBaseValue(SVGLength::construct(LengthModeWidth, value, parseError, ForbidNegativeLengths)); 108 else if (name == SVGNames::heightAttr) 109 setHeightBaseValue(SVGLength::construct(LengthModeHeight, value, parseError, ForbidNegativeLengths)); 110 else if (SVGTests::parseAttribute(name, value) 111 || SVGLangSpace::parseAttribute(name, value) 112 || SVGExternalResourcesRequired::parseAttribute(name, value)) { 113 } else 114 ASSERT_NOT_REACHED(); 115 116 reportAttributeParsingError(parseError, name, value); 117} 118 119void SVGRectElement::svgAttributeChanged(const QualifiedName& attrName) 120{ 121 if (!isSupportedAttribute(attrName)) { 122 SVGStyledTransformableElement::svgAttributeChanged(attrName); 123 return; 124 } 125 126 SVGElementInstance::InvalidationGuard invalidationGuard(this); 127 128 bool isLengthAttribute = attrName == SVGNames::xAttr 129 || attrName == SVGNames::yAttr 130 || attrName == SVGNames::widthAttr 131 || attrName == SVGNames::heightAttr 132 || attrName == SVGNames::rxAttr 133 || attrName == SVGNames::ryAttr; 134 135 if (isLengthAttribute) 136 updateRelativeLengthsInformation(); 137 138 if (SVGTests::handleAttributeChange(this, attrName)) 139 return; 140 141 RenderSVGShape* renderer = toRenderSVGShape(this->renderer()); 142 if (!renderer) 143 return; 144 145 if (isLengthAttribute) { 146 renderer->setNeedsShapeUpdate(); 147 RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer); 148 return; 149 } 150 151 if (SVGLangSpace::isKnownAttribute(attrName) || SVGExternalResourcesRequired::isKnownAttribute(attrName)) { 152 RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer); 153 return; 154 } 155 156 ASSERT_NOT_REACHED(); 157} 158 159bool SVGRectElement::selfHasRelativeLengths() const 160{ 161 return x().isRelative() 162 || y().isRelative() 163 || width().isRelative() 164 || height().isRelative() 165 || rx().isRelative() 166 || ry().isRelative(); 167} 168 169RenderObject* SVGRectElement::createRenderer(RenderArena* arena, RenderStyle*) 170{ 171 return new (arena) RenderSVGRect(this); 172} 173 174} 175 176#endif // ENABLE(SVG) 177