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 "SVGEllipseElement.h" 25 26#include "Attribute.h" 27#include "FloatPoint.h" 28#include "RenderSVGPath.h" 29#include "RenderSVGResource.h" 30#include "SVGLength.h" 31#include "SVGNames.h" 32 33namespace WebCore { 34 35// Animated property definitions 36DEFINE_ANIMATED_LENGTH(SVGEllipseElement, SVGNames::cxAttr, Cx, cx) 37DEFINE_ANIMATED_LENGTH(SVGEllipseElement, SVGNames::cyAttr, Cy, cy) 38DEFINE_ANIMATED_LENGTH(SVGEllipseElement, SVGNames::rxAttr, Rx, rx) 39DEFINE_ANIMATED_LENGTH(SVGEllipseElement, SVGNames::ryAttr, Ry, ry) 40DEFINE_ANIMATED_BOOLEAN(SVGEllipseElement, SVGNames::externalResourcesRequiredAttr, ExternalResourcesRequired, externalResourcesRequired) 41 42inline SVGEllipseElement::SVGEllipseElement(const QualifiedName& tagName, Document* document) 43 : SVGStyledTransformableElement(tagName, document) 44 , m_cx(LengthModeWidth) 45 , m_cy(LengthModeHeight) 46 , m_rx(LengthModeWidth) 47 , m_ry(LengthModeHeight) 48{ 49} 50 51PassRefPtr<SVGEllipseElement> SVGEllipseElement::create(const QualifiedName& tagName, Document* document) 52{ 53 return adoptRef(new SVGEllipseElement(tagName, document)); 54} 55 56void SVGEllipseElement::parseMappedAttribute(Attribute* attr) 57{ 58 if (attr->name() == SVGNames::cxAttr) 59 setCxBaseValue(SVGLength(LengthModeWidth, attr->value())); 60 else if (attr->name() == SVGNames::cyAttr) 61 setCyBaseValue(SVGLength(LengthModeHeight, attr->value())); 62 else if (attr->name() == SVGNames::rxAttr) { 63 setRxBaseValue(SVGLength(LengthModeWidth, attr->value())); 64 if (rxBaseValue().value(this) < 0.0) 65 document()->accessSVGExtensions()->reportError("A negative value for ellipse <rx> is not allowed"); 66 } else if (attr->name() == SVGNames::ryAttr) { 67 setRyBaseValue(SVGLength(LengthModeHeight, attr->value())); 68 if (ryBaseValue().value(this) < 0.0) 69 document()->accessSVGExtensions()->reportError("A negative value for ellipse <ry> is not allowed"); 70 } else { 71 if (SVGTests::parseMappedAttribute(attr)) 72 return; 73 if (SVGLangSpace::parseMappedAttribute(attr)) 74 return; 75 if (SVGExternalResourcesRequired::parseMappedAttribute(attr)) 76 return; 77 SVGStyledTransformableElement::parseMappedAttribute(attr); 78 } 79} 80 81void SVGEllipseElement::svgAttributeChanged(const QualifiedName& attrName) 82{ 83 SVGStyledTransformableElement::svgAttributeChanged(attrName); 84 85 bool isLengthAttribute = attrName == SVGNames::cxAttr 86 || attrName == SVGNames::cyAttr 87 || attrName == SVGNames::rxAttr 88 || attrName == SVGNames::ryAttr; 89 90 if (isLengthAttribute) 91 updateRelativeLengthsInformation(); 92 93 if (SVGTests::handleAttributeChange(this, attrName)) 94 return; 95 96 RenderSVGPath* renderer = static_cast<RenderSVGPath*>(this->renderer()); 97 if (!renderer) 98 return; 99 100 if (isLengthAttribute) { 101 renderer->setNeedsPathUpdate(); 102 RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer); 103 return; 104 } 105 106 if (SVGLangSpace::isKnownAttribute(attrName) 107 || SVGExternalResourcesRequired::isKnownAttribute(attrName)) 108 RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer); 109} 110 111void SVGEllipseElement::synchronizeProperty(const QualifiedName& attrName) 112{ 113 SVGStyledTransformableElement::synchronizeProperty(attrName); 114 115 if (attrName == anyQName()) { 116 synchronizeCx(); 117 synchronizeCy(); 118 synchronizeRx(); 119 synchronizeRy(); 120 synchronizeExternalResourcesRequired(); 121 SVGTests::synchronizeProperties(this, attrName); 122 return; 123 } 124 125 if (attrName == SVGNames::cxAttr) 126 synchronizeCx(); 127 else if (attrName == SVGNames::cyAttr) 128 synchronizeCy(); 129 else if (attrName == SVGNames::rxAttr) 130 synchronizeRx(); 131 else if (attrName == SVGNames::ryAttr) 132 synchronizeRy(); 133 else if (SVGExternalResourcesRequired::isKnownAttribute(attrName)) 134 synchronizeExternalResourcesRequired(); 135 else if (SVGTests::isKnownAttribute(attrName)) 136 SVGTests::synchronizeProperties(this, attrName); 137} 138 139AttributeToPropertyTypeMap& SVGEllipseElement::attributeToPropertyTypeMap() 140{ 141 DEFINE_STATIC_LOCAL(AttributeToPropertyTypeMap, s_attributeToPropertyTypeMap, ()); 142 return s_attributeToPropertyTypeMap; 143} 144 145void SVGEllipseElement::fillAttributeToPropertyTypeMap() 146{ 147 AttributeToPropertyTypeMap& attributeToPropertyTypeMap = this->attributeToPropertyTypeMap(); 148 149 SVGStyledTransformableElement::fillPassedAttributeToPropertyTypeMap(attributeToPropertyTypeMap); 150 attributeToPropertyTypeMap.set(SVGNames::cxAttr, AnimatedLength); 151 attributeToPropertyTypeMap.set(SVGNames::cyAttr, AnimatedLength); 152 attributeToPropertyTypeMap.set(SVGNames::rxAttr, AnimatedLength); 153 attributeToPropertyTypeMap.set(SVGNames::ryAttr, AnimatedLength); 154} 155 156void SVGEllipseElement::toPathData(Path& path) const 157{ 158 ASSERT(path.isEmpty()); 159 160 float radiusX = rx().value(this); 161 if (radiusX <= 0) 162 return; 163 164 float radiusY = ry().value(this); 165 if (radiusY <= 0) 166 return; 167 168 path.addEllipse(FloatRect(cx().value(this) - radiusX, cy().value(this) - radiusY, radiusX * 2, radiusY * 2)); 169} 170 171bool SVGEllipseElement::selfHasRelativeLengths() const 172{ 173 return cx().isRelative() 174 || cy().isRelative() 175 || rx().isRelative() 176 || ry().isRelative(); 177} 178 179} 180 181#endif // ENABLE(SVG) 182