SVGEllipseElement.cpp revision cad810f21b803229eb11403f9209855525a25d57
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 (SVGStyledTransformableElement::isKnownAttribute(attrName)) {
101        renderer->setNeedsTransformUpdate();
102        RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer);
103        return;
104    }
105
106    if (isLengthAttribute) {
107        renderer->setNeedsPathUpdate();
108        RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer);
109        return;
110    }
111
112    if (SVGLangSpace::isKnownAttribute(attrName)
113        || SVGExternalResourcesRequired::isKnownAttribute(attrName))
114        RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer);
115}
116
117void SVGEllipseElement::synchronizeProperty(const QualifiedName& attrName)
118{
119    SVGStyledTransformableElement::synchronizeProperty(attrName);
120
121    if (attrName == anyQName()) {
122        synchronizeCx();
123        synchronizeCy();
124        synchronizeRx();
125        synchronizeRy();
126        synchronizeExternalResourcesRequired();
127        SVGTests::synchronizeProperties(this, attrName);
128        return;
129    }
130
131    if (attrName == SVGNames::cxAttr)
132        synchronizeCx();
133    else if (attrName == SVGNames::cyAttr)
134        synchronizeCy();
135    else if (attrName == SVGNames::rxAttr)
136        synchronizeRx();
137    else if (attrName == SVGNames::ryAttr)
138        synchronizeRy();
139    else if (SVGExternalResourcesRequired::isKnownAttribute(attrName))
140        synchronizeExternalResourcesRequired();
141    else if (SVGTests::isKnownAttribute(attrName))
142        SVGTests::synchronizeProperties(this, attrName);
143}
144
145void SVGEllipseElement::toPathData(Path& path) const
146{
147    ASSERT(path.isEmpty());
148
149    float radiusX = rx().value(this);
150    if (radiusX <= 0)
151        return;
152
153    float radiusY = ry().value(this);
154    if (radiusY <= 0)
155        return;
156
157    path.addEllipse(FloatRect(cx().value(this) - radiusX, cy().value(this) - radiusY, radiusX * 2, radiusY * 2));
158}
159
160bool SVGEllipseElement::selfHasRelativeLengths() const
161{
162    return cx().isRelative()
163        || cy().isRelative()
164        || rx().isRelative()
165        || ry().isRelative();
166}
167
168}
169
170#endif // ENABLE(SVG)
171