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