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/SVGEllipseElement.h" 24 25 #include "SVGNames.h" 26 #include "core/rendering/svg/RenderSVGEllipse.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(SVGEllipseElement, SVGNames::cxAttr, Cx, cx) 35 DEFINE_ANIMATED_LENGTH(SVGEllipseElement, SVGNames::cyAttr, Cy, cy) 36 DEFINE_ANIMATED_LENGTH(SVGEllipseElement, SVGNames::rxAttr, Rx, rx) 37 DEFINE_ANIMATED_LENGTH(SVGEllipseElement, SVGNames::ryAttr, Ry, ry) 38 DEFINE_ANIMATED_BOOLEAN(SVGEllipseElement, SVGNames::externalResourcesRequiredAttr, ExternalResourcesRequired, externalResourcesRequired) 39 40 BEGIN_REGISTER_ANIMATED_PROPERTIES(SVGEllipseElement) 41 REGISTER_LOCAL_ANIMATED_PROPERTY(cx) 42 REGISTER_LOCAL_ANIMATED_PROPERTY(cy) 43 REGISTER_LOCAL_ANIMATED_PROPERTY(rx) 44 REGISTER_LOCAL_ANIMATED_PROPERTY(ry) 45 REGISTER_LOCAL_ANIMATED_PROPERTY(externalResourcesRequired) 46 REGISTER_PARENT_ANIMATED_PROPERTIES(SVGGraphicsElement) 47 END_REGISTER_ANIMATED_PROPERTIES 48 49 inline SVGEllipseElement::SVGEllipseElement(const QualifiedName& tagName, Document* document) 50 : SVGGraphicsElement(tagName, document) 51 , m_cx(LengthModeWidth) 52 , m_cy(LengthModeHeight) 53 , m_rx(LengthModeWidth) 54 , m_ry(LengthModeHeight) 55 { 56 ASSERT(hasTagName(SVGNames::ellipseTag)); 57 ScriptWrappable::init(this); 58 registerAnimatedPropertiesForSVGEllipseElement(); 59 } 60 61 PassRefPtr<SVGEllipseElement> SVGEllipseElement::create(const QualifiedName& tagName, Document* document) 62 { 63 return adoptRef(new SVGEllipseElement(tagName, document)); 64 } 65 66 bool SVGEllipseElement::isSupportedAttribute(const QualifiedName& attrName) 67 { 68 DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, supportedAttributes, ()); 69 if (supportedAttributes.isEmpty()) { 70 SVGLangSpace::addSupportedAttributes(supportedAttributes); 71 SVGExternalResourcesRequired::addSupportedAttributes(supportedAttributes); 72 supportedAttributes.add(SVGNames::cxAttr); 73 supportedAttributes.add(SVGNames::cyAttr); 74 supportedAttributes.add(SVGNames::rxAttr); 75 supportedAttributes.add(SVGNames::ryAttr); 76 } 77 return supportedAttributes.contains<SVGAttributeHashTranslator>(attrName); 78 } 79 80 void SVGEllipseElement::parseAttribute(const QualifiedName& name, const AtomicString& value) 81 { 82 SVGParsingError parseError = NoError; 83 84 if (!isSupportedAttribute(name)) 85 SVGGraphicsElement::parseAttribute(name, value); 86 else if (name == SVGNames::cxAttr) 87 setCxBaseValue(SVGLength::construct(LengthModeWidth, value, parseError)); 88 else if (name == SVGNames::cyAttr) 89 setCyBaseValue(SVGLength::construct(LengthModeHeight, value, parseError)); 90 else if (name == SVGNames::rxAttr) 91 setRxBaseValue(SVGLength::construct(LengthModeWidth, value, parseError, ForbidNegativeLengths)); 92 else if (name == SVGNames::ryAttr) 93 setRyBaseValue(SVGLength::construct(LengthModeHeight, value, parseError, ForbidNegativeLengths)); 94 else if (SVGLangSpace::parseAttribute(name, value) 95 || SVGExternalResourcesRequired::parseAttribute(name, value)) { 96 } else 97 ASSERT_NOT_REACHED(); 98 99 reportAttributeParsingError(parseError, name, value); 100 } 101 102 void SVGEllipseElement::svgAttributeChanged(const QualifiedName& attrName) 103 { 104 if (!isSupportedAttribute(attrName)) { 105 SVGGraphicsElement::svgAttributeChanged(attrName); 106 return; 107 } 108 109 SVGElementInstance::InvalidationGuard invalidationGuard(this); 110 111 bool isLengthAttribute = attrName == SVGNames::cxAttr 112 || attrName == SVGNames::cyAttr 113 || attrName == SVGNames::rxAttr 114 || attrName == SVGNames::ryAttr; 115 116 if (isLengthAttribute) 117 updateRelativeLengthsInformation(); 118 119 RenderSVGShape* renderer = toRenderSVGShape(this->renderer()); 120 if (!renderer) 121 return; 122 123 if (isLengthAttribute) { 124 renderer->setNeedsShapeUpdate(); 125 RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer); 126 return; 127 } 128 129 if (SVGLangSpace::isKnownAttribute(attrName) || SVGExternalResourcesRequired::isKnownAttribute(attrName)) { 130 RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer); 131 return; 132 } 133 134 ASSERT_NOT_REACHED(); 135 } 136 137 bool SVGEllipseElement::selfHasRelativeLengths() const 138 { 139 return cxCurrentValue().isRelative() 140 || cyCurrentValue().isRelative() 141 || rxCurrentValue().isRelative() 142 || ryCurrentValue().isRelative(); 143 } 144 145 RenderObject* SVGEllipseElement::createRenderer(RenderStyle*) 146 { 147 return new RenderSVGEllipse(this); 148 } 149 150 } 151