• 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 "SVGRectElement.h"
25 
26 #include "Attribute.h"
27 #include "RenderSVGPath.h"
28 #include "RenderSVGResource.h"
29 #include "SVGLength.h"
30 #include "SVGNames.h"
31 
32 namespace WebCore {
33 
34 // Animated property definitions
DEFINE_ANIMATED_LENGTH(SVGRectElement,SVGNames::xAttr,X,x)35 DEFINE_ANIMATED_LENGTH(SVGRectElement, SVGNames::xAttr, X, x)
36 DEFINE_ANIMATED_LENGTH(SVGRectElement, SVGNames::yAttr, Y, y)
37 DEFINE_ANIMATED_LENGTH(SVGRectElement, SVGNames::widthAttr, Width, width)
38 DEFINE_ANIMATED_LENGTH(SVGRectElement, SVGNames::heightAttr, Height, height)
39 DEFINE_ANIMATED_LENGTH(SVGRectElement, SVGNames::rxAttr, Rx, rx)
40 DEFINE_ANIMATED_LENGTH(SVGRectElement, SVGNames::ryAttr, Ry, ry)
41 DEFINE_ANIMATED_BOOLEAN(SVGRectElement, SVGNames::externalResourcesRequiredAttr, ExternalResourcesRequired, externalResourcesRequired)
42 
43 inline SVGRectElement::SVGRectElement(const QualifiedName& tagName, Document* document)
44     : SVGStyledTransformableElement(tagName, document)
45     , m_x(LengthModeWidth)
46     , m_y(LengthModeHeight)
47     , m_width(LengthModeWidth)
48     , m_height(LengthModeHeight)
49     , m_rx(LengthModeWidth)
50     , m_ry(LengthModeHeight)
51 {
52 }
53 
create(const QualifiedName & tagName,Document * document)54 PassRefPtr<SVGRectElement> SVGRectElement::create(const QualifiedName& tagName, Document* document)
55 {
56     return adoptRef(new SVGRectElement(tagName, document));
57 }
58 
parseMappedAttribute(Attribute * attr)59 void SVGRectElement::parseMappedAttribute(Attribute* attr)
60 {
61     if (attr->name() == SVGNames::xAttr)
62         setXBaseValue(SVGLength(LengthModeWidth, attr->value()));
63     else if (attr->name() == SVGNames::yAttr)
64         setYBaseValue(SVGLength(LengthModeHeight, attr->value()));
65     else if (attr->name() == SVGNames::rxAttr) {
66         setRxBaseValue(SVGLength(LengthModeWidth, attr->value()));
67         if (rxBaseValue().value(this) < 0.0)
68             document()->accessSVGExtensions()->reportError("A negative value for rect <rx> is not allowed");
69     } else if (attr->name() == SVGNames::ryAttr) {
70         setRyBaseValue(SVGLength(LengthModeHeight, attr->value()));
71         if (ryBaseValue().value(this) < 0.0)
72             document()->accessSVGExtensions()->reportError("A negative value for rect <ry> is not allowed");
73     } else if (attr->name() == SVGNames::widthAttr) {
74         setWidthBaseValue(SVGLength(LengthModeWidth, attr->value()));
75         if (widthBaseValue().value(this) < 0.0)
76             document()->accessSVGExtensions()->reportError("A negative value for rect <width> is not allowed");
77     } else if (attr->name() == SVGNames::heightAttr) {
78         setHeightBaseValue(SVGLength(LengthModeHeight, attr->value()));
79         if (heightBaseValue().value(this) < 0.0)
80             document()->accessSVGExtensions()->reportError("A negative value for rect <height> is not allowed");
81     } else {
82         if (SVGTests::parseMappedAttribute(attr))
83             return;
84         if (SVGLangSpace::parseMappedAttribute(attr))
85             return;
86         if (SVGExternalResourcesRequired::parseMappedAttribute(attr))
87             return;
88         SVGStyledTransformableElement::parseMappedAttribute(attr);
89     }
90 }
91 
svgAttributeChanged(const QualifiedName & attrName)92 void SVGRectElement::svgAttributeChanged(const QualifiedName& attrName)
93 {
94     SVGStyledTransformableElement::svgAttributeChanged(attrName);
95 
96     bool isLengthAttribute = attrName == SVGNames::xAttr
97                           || attrName == SVGNames::yAttr
98                           || attrName == SVGNames::widthAttr
99                           || attrName == SVGNames::heightAttr
100                           || attrName == SVGNames::rxAttr
101                           || attrName == SVGNames::ryAttr;
102 
103     if (isLengthAttribute)
104         updateRelativeLengthsInformation();
105 
106     if (SVGTests::handleAttributeChange(this, attrName))
107         return;
108 
109     RenderSVGPath* renderer = static_cast<RenderSVGPath*>(this->renderer());
110     if (!renderer)
111         return;
112 
113     if (isLengthAttribute) {
114         renderer->setNeedsPathUpdate();
115         RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer);
116         return;
117     }
118 
119     if (SVGLangSpace::isKnownAttribute(attrName)
120         || SVGExternalResourcesRequired::isKnownAttribute(attrName))
121         RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer);
122 }
123 
synchronizeProperty(const QualifiedName & attrName)124 void SVGRectElement::synchronizeProperty(const QualifiedName& attrName)
125 {
126     SVGStyledTransformableElement::synchronizeProperty(attrName);
127 
128     if (attrName == anyQName()) {
129         synchronizeX();
130         synchronizeY();
131         synchronizeWidth();
132         synchronizeHeight();
133         synchronizeRx();
134         synchronizeRy();
135         synchronizeExternalResourcesRequired();
136         SVGTests::synchronizeProperties(this, attrName);
137         return;
138     }
139 
140     if (attrName == SVGNames::xAttr)
141         synchronizeX();
142     else if (attrName == SVGNames::yAttr)
143         synchronizeY();
144     else if (attrName == SVGNames::widthAttr)
145         synchronizeWidth();
146     else if (attrName == SVGNames::heightAttr)
147         synchronizeHeight();
148     else if (attrName == SVGNames::rxAttr)
149         synchronizeRx();
150     else if (attrName == SVGNames::ryAttr)
151         synchronizeRy();
152     else if (SVGExternalResourcesRequired::isKnownAttribute(attrName))
153         synchronizeExternalResourcesRequired();
154     else if (SVGTests::isKnownAttribute(attrName))
155         SVGTests::synchronizeProperties(this, attrName);
156 }
157 
attributeToPropertyTypeMap()158 AttributeToPropertyTypeMap& SVGRectElement::attributeToPropertyTypeMap()
159 {
160     DEFINE_STATIC_LOCAL(AttributeToPropertyTypeMap, s_attributeToPropertyTypeMap, ());
161     return s_attributeToPropertyTypeMap;
162 }
163 
fillAttributeToPropertyTypeMap()164 void SVGRectElement::fillAttributeToPropertyTypeMap()
165 {
166     AttributeToPropertyTypeMap& attributeToPropertyTypeMap = this->attributeToPropertyTypeMap();
167 
168     SVGStyledTransformableElement::fillPassedAttributeToPropertyTypeMap(attributeToPropertyTypeMap);
169     attributeToPropertyTypeMap.set(SVGNames::xAttr, AnimatedLength);
170     attributeToPropertyTypeMap.set(SVGNames::yAttr, AnimatedLength);
171     attributeToPropertyTypeMap.set(SVGNames::widthAttr, AnimatedLength);
172     attributeToPropertyTypeMap.set(SVGNames::heightAttr, AnimatedLength);
173     attributeToPropertyTypeMap.set(SVGNames::rxAttr, AnimatedLength);
174     attributeToPropertyTypeMap.set(SVGNames::ryAttr, AnimatedLength);
175 }
176 
toPathData(Path & path) const177 void SVGRectElement::toPathData(Path& path) const
178 {
179     ASSERT(path.isEmpty());
180 
181     float widthValue = width().value(this);
182     if (widthValue <= 0)
183         return;
184 
185     float heightValue = height().value(this);
186     if (heightValue <= 0)
187         return;
188 
189     float xValue = x().value(this);
190     float yValue = y().value(this);
191 
192     FloatRect rect(xValue, yValue, widthValue, heightValue);
193 
194     bool hasRx = hasAttribute(SVGNames::rxAttr);
195     bool hasRy = hasAttribute(SVGNames::ryAttr);
196     if (hasRx || hasRy) {
197         float rxValue = rx().value(this);
198         float ryValue = ry().value(this);
199         if (!hasRx)
200             rxValue = ryValue;
201         else if (!hasRy)
202             ryValue = rxValue;
203         path.addRoundedRect(rect, FloatSize(rxValue, ryValue));
204         return;
205     }
206 
207     path.addRect(rect);
208 }
209 
selfHasRelativeLengths() const210 bool SVGRectElement::selfHasRelativeLengths() const
211 {
212     return x().isRelative()
213         || y().isRelative()
214         || width().isRelative()
215         || height().isRelative()
216         || rx().isRelative()
217         || ry().isRelative();
218 }
219 
220 }
221 
222 #endif // ENABLE(SVG)
223