• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
33 namespace WebCore {
34 
35 // Animated property definitions
DEFINE_ANIMATED_LENGTH(SVGEllipseElement,SVGNames::cxAttr,Cx,cx)36 DEFINE_ANIMATED_LENGTH(SVGEllipseElement, SVGNames::cxAttr, Cx, cx)
37 DEFINE_ANIMATED_LENGTH(SVGEllipseElement, SVGNames::cyAttr, Cy, cy)
38 DEFINE_ANIMATED_LENGTH(SVGEllipseElement, SVGNames::rxAttr, Rx, rx)
39 DEFINE_ANIMATED_LENGTH(SVGEllipseElement, SVGNames::ryAttr, Ry, ry)
40 DEFINE_ANIMATED_BOOLEAN(SVGEllipseElement, SVGNames::externalResourcesRequiredAttr, ExternalResourcesRequired, externalResourcesRequired)
41 
42 inline 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 
create(const QualifiedName & tagName,Document * document)51 PassRefPtr<SVGEllipseElement> SVGEllipseElement::create(const QualifiedName& tagName, Document* document)
52 {
53     return adoptRef(new SVGEllipseElement(tagName, document));
54 }
55 
parseMappedAttribute(Attribute * attr)56 void 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 
svgAttributeChanged(const QualifiedName & attrName)81 void 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 
synchronizeProperty(const QualifiedName & attrName)111 void 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 
attributeToPropertyTypeMap()139 AttributeToPropertyTypeMap& SVGEllipseElement::attributeToPropertyTypeMap()
140 {
141     DEFINE_STATIC_LOCAL(AttributeToPropertyTypeMap, s_attributeToPropertyTypeMap, ());
142     return s_attributeToPropertyTypeMap;
143 }
144 
fillAttributeToPropertyTypeMap()145 void 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 
toPathData(Path & path) const156 void 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 
selfHasRelativeLengths() const171 bool 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