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