1 /*
2 * Copyright (C) Research In Motion Limited 2011. All rights reserved.
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
13 *
14 * You should have received a copy of the GNU Library General Public License
15 * along with this library; see the file COPYING.LIB. If not, write to
16 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 * Boston, MA 02110-1301, USA.
18 */
19
20 #include "config.h"
21 #include "core/svg/SVGAnimatedType.h"
22
23 #include "bindings/v8/ExceptionState.h"
24 #include "core/svg/SVGParserUtilities.h"
25 #include "core/svg/SVGPathByteStream.h"
26
27 namespace WebCore {
28
SVGAnimatedType(AnimatedPropertyType type)29 SVGAnimatedType::SVGAnimatedType(AnimatedPropertyType type)
30 : m_type(type)
31 {
32 }
33
~SVGAnimatedType()34 SVGAnimatedType::~SVGAnimatedType()
35 {
36 switch (m_type) {
37 case AnimatedAngle:
38 delete m_data.angleAndEnumeration;
39 break;
40 case AnimatedBoolean:
41 delete m_data.boolean;
42 break;
43 case AnimatedColor:
44 delete m_data.color;
45 break;
46 case AnimatedEnumeration:
47 delete m_data.enumeration;
48 break;
49 case AnimatedInteger:
50 delete m_data.integer;
51 break;
52 case AnimatedIntegerOptionalInteger:
53 delete m_data.integerOptionalInteger;
54 break;
55 case AnimatedLength:
56 delete m_data.length;
57 break;
58 case AnimatedLengthList:
59 delete m_data.lengthList;
60 break;
61 case AnimatedNumber:
62 delete m_data.number;
63 break;
64 case AnimatedNumberList:
65 delete m_data.numberList;
66 break;
67 case AnimatedNumberOptionalNumber:
68 delete m_data.numberOptionalNumber;
69 break;
70 case AnimatedPath:
71 delete m_data.path;
72 break;
73 case AnimatedPoints:
74 delete m_data.pointList;
75 break;
76 case AnimatedPreserveAspectRatio:
77 delete m_data.preserveAspectRatio;
78 break;
79 case AnimatedRect:
80 delete m_data.rect;
81 break;
82 case AnimatedString:
83 delete m_data.string;
84 break;
85 case AnimatedTransformList:
86 delete m_data.transformList;
87 break;
88 case AnimatedUnknown:
89 ASSERT_NOT_REACHED();
90 break;
91 }
92 }
93
createAngleAndEnumeration(std::pair<SVGAngle,unsigned> * angleAndEnumeration)94 PassOwnPtr<SVGAnimatedType> SVGAnimatedType::createAngleAndEnumeration(std::pair<SVGAngle, unsigned>* angleAndEnumeration)
95 {
96 ASSERT(angleAndEnumeration);
97 OwnPtr<SVGAnimatedType> animatedType = adoptPtr(new SVGAnimatedType(AnimatedAngle));
98 animatedType->m_data.angleAndEnumeration = angleAndEnumeration;
99 return animatedType.release();
100 }
101
createBoolean(bool * boolean)102 PassOwnPtr<SVGAnimatedType> SVGAnimatedType::createBoolean(bool* boolean)
103 {
104 ASSERT(boolean);
105 OwnPtr<SVGAnimatedType> animatedType = adoptPtr(new SVGAnimatedType(AnimatedBoolean));
106 animatedType->m_data.boolean = boolean;
107 return animatedType.release();
108 }
109
createColor(Color * color)110 PassOwnPtr<SVGAnimatedType> SVGAnimatedType::createColor(Color* color)
111 {
112 ASSERT(color);
113 OwnPtr<SVGAnimatedType> animatedType = adoptPtr(new SVGAnimatedType(AnimatedColor));
114 animatedType->m_data.color = color;
115 return animatedType.release();
116 }
117
createEnumeration(unsigned * enumeration)118 PassOwnPtr<SVGAnimatedType> SVGAnimatedType::createEnumeration(unsigned* enumeration)
119 {
120 ASSERT(enumeration);
121 OwnPtr<SVGAnimatedType> animatedType = adoptPtr(new SVGAnimatedType(AnimatedEnumeration));
122 animatedType->m_data.enumeration = enumeration;
123 return animatedType.release();
124 }
125
createInteger(int * integer)126 PassOwnPtr<SVGAnimatedType> SVGAnimatedType::createInteger(int* integer)
127 {
128 ASSERT(integer);
129 OwnPtr<SVGAnimatedType> animatedType = adoptPtr(new SVGAnimatedType(AnimatedInteger));
130 animatedType->m_data.integer = integer;
131 return animatedType.release();
132 }
133
createIntegerOptionalInteger(pair<int,int> * integerOptionalInteger)134 PassOwnPtr<SVGAnimatedType> SVGAnimatedType::createIntegerOptionalInteger(pair<int, int>* integerOptionalInteger)
135 {
136 ASSERT(integerOptionalInteger);
137 OwnPtr<SVGAnimatedType> animatedType = adoptPtr(new SVGAnimatedType(AnimatedIntegerOptionalInteger));
138 animatedType->m_data.integerOptionalInteger = integerOptionalInteger;
139 return animatedType.release();
140 }
141
createLength(SVGLength * length)142 PassOwnPtr<SVGAnimatedType> SVGAnimatedType::createLength(SVGLength* length)
143 {
144 ASSERT(length);
145 OwnPtr<SVGAnimatedType> animatedType = adoptPtr(new SVGAnimatedType(AnimatedLength));
146 animatedType->m_data.length = length;
147 return animatedType.release();
148 }
149
createLengthList(SVGLengthList * lengthList)150 PassOwnPtr<SVGAnimatedType> SVGAnimatedType::createLengthList(SVGLengthList* lengthList)
151 {
152 ASSERT(lengthList);
153 OwnPtr<SVGAnimatedType> animatedType = adoptPtr(new SVGAnimatedType(AnimatedLengthList));
154 animatedType->m_data.lengthList = lengthList;
155 return animatedType.release();
156 }
157
createNumber(float * number)158 PassOwnPtr<SVGAnimatedType> SVGAnimatedType::createNumber(float* number)
159 {
160 ASSERT(number);
161 OwnPtr<SVGAnimatedType> animatedType = adoptPtr(new SVGAnimatedType(AnimatedNumber));
162 animatedType->m_data.number = number;
163 return animatedType.release();
164 }
165
createNumberList(SVGNumberList * numberList)166 PassOwnPtr<SVGAnimatedType> SVGAnimatedType::createNumberList(SVGNumberList* numberList)
167 {
168 ASSERT(numberList);
169 OwnPtr<SVGAnimatedType> animatedType = adoptPtr(new SVGAnimatedType(AnimatedNumberList));
170 animatedType->m_data.numberList = numberList;
171 return animatedType.release();
172 }
173
createNumberOptionalNumber(pair<float,float> * numberOptionalNumber)174 PassOwnPtr<SVGAnimatedType> SVGAnimatedType::createNumberOptionalNumber(pair<float, float>* numberOptionalNumber)
175 {
176 ASSERT(numberOptionalNumber);
177 OwnPtr<SVGAnimatedType> animatedType = adoptPtr(new SVGAnimatedType(AnimatedNumberOptionalNumber));
178 animatedType->m_data.numberOptionalNumber = numberOptionalNumber;
179 return animatedType.release();
180 }
181
createPath(PassOwnPtr<SVGPathByteStream> path)182 PassOwnPtr<SVGAnimatedType> SVGAnimatedType::createPath(PassOwnPtr<SVGPathByteStream> path)
183 {
184 ASSERT(path);
185 OwnPtr<SVGAnimatedType> animatedType = adoptPtr(new SVGAnimatedType(AnimatedPath));
186 animatedType->m_data.path = path.leakPtr();
187 return animatedType.release();
188 }
189
createPointList(SVGPointList * pointList)190 PassOwnPtr<SVGAnimatedType> SVGAnimatedType::createPointList(SVGPointList* pointList)
191 {
192 ASSERT(pointList);
193 OwnPtr<SVGAnimatedType> animatedType = adoptPtr(new SVGAnimatedType(AnimatedPoints));
194 animatedType->m_data.pointList = pointList;
195 return animatedType.release();
196 }
197
createPreserveAspectRatio(SVGPreserveAspectRatio * preserveAspectRatio)198 PassOwnPtr<SVGAnimatedType> SVGAnimatedType::createPreserveAspectRatio(SVGPreserveAspectRatio* preserveAspectRatio)
199 {
200 ASSERT(preserveAspectRatio);
201 OwnPtr<SVGAnimatedType> animatedType = adoptPtr(new SVGAnimatedType(AnimatedPreserveAspectRatio));
202 animatedType->m_data.preserveAspectRatio = preserveAspectRatio;
203 return animatedType.release();
204 }
205
createRect(SVGRect * rect)206 PassOwnPtr<SVGAnimatedType> SVGAnimatedType::createRect(SVGRect* rect)
207 {
208 ASSERT(rect);
209 OwnPtr<SVGAnimatedType> animatedType = adoptPtr(new SVGAnimatedType(AnimatedRect));
210 animatedType->m_data.rect = rect;
211 return animatedType.release();
212 }
213
createString(String * string)214 PassOwnPtr<SVGAnimatedType> SVGAnimatedType::createString(String* string)
215 {
216 ASSERT(string);
217 OwnPtr<SVGAnimatedType> animatedType = adoptPtr(new SVGAnimatedType(AnimatedString));
218 animatedType->m_data.string = string;
219 return animatedType.release();
220 }
221
createTransformList(SVGTransformList * transformList)222 PassOwnPtr<SVGAnimatedType> SVGAnimatedType::createTransformList(SVGTransformList* transformList)
223 {
224 ASSERT(transformList);
225 OwnPtr<SVGAnimatedType> animatedType = adoptPtr(new SVGAnimatedType(AnimatedTransformList));
226 animatedType->m_data.transformList = transformList;
227 return animatedType.release();
228 }
229
valueAsString()230 String SVGAnimatedType::valueAsString()
231 {
232 switch (m_type) {
233 case AnimatedColor:
234 ASSERT(m_data.color);
235 return m_data.color->serialized();
236 case AnimatedLength:
237 ASSERT(m_data.length);
238 return m_data.length->valueAsString();
239 case AnimatedLengthList:
240 ASSERT(m_data.lengthList);
241 return m_data.lengthList->valueAsString();
242 case AnimatedNumber:
243 ASSERT(m_data.number);
244 return String::number(*m_data.number);
245 case AnimatedRect:
246 ASSERT(m_data.rect);
247 return String::number(m_data.rect->x()) + ' ' + String::number(m_data.rect->y()) + ' '
248 + String::number(m_data.rect->width()) + ' ' + String::number(m_data.rect->height());
249 case AnimatedString:
250 ASSERT(m_data.string);
251 return *m_data.string;
252
253 // These types don't appear in the table in SVGElement::cssPropertyToTypeMap() and thus don't need valueAsString() support.
254 case AnimatedAngle:
255 case AnimatedBoolean:
256 case AnimatedEnumeration:
257 case AnimatedInteger:
258 case AnimatedIntegerOptionalInteger:
259 case AnimatedNumberList:
260 case AnimatedNumberOptionalNumber:
261 case AnimatedPath:
262 case AnimatedPoints:
263 case AnimatedPreserveAspectRatio:
264 case AnimatedTransformList:
265 case AnimatedUnknown:
266 // Only SVG DOM animations use these property types - that means valueAsString() is never used for those.
267 ASSERT_NOT_REACHED();
268 break;
269 }
270 ASSERT_NOT_REACHED();
271 return String();
272 }
273
setValueAsString(const QualifiedName & attrName,const String & value)274 bool SVGAnimatedType::setValueAsString(const QualifiedName& attrName, const String& value)
275 {
276 switch (m_type) {
277 case AnimatedColor:
278 ASSERT(m_data.color);
279 *m_data.color = value.isEmpty() ? Color() : SVGColor::colorFromRGBColorString(value);
280 break;
281 case AnimatedLength: {
282 ASSERT(m_data.length);
283 TrackExceptionState exceptionState;
284 m_data.length->setValueAsString(value, SVGLength::lengthModeForAnimatedLengthAttribute(attrName), exceptionState);
285 return !exceptionState.hadException();
286 }
287 case AnimatedLengthList:
288 ASSERT(m_data.lengthList);
289 m_data.lengthList->parse(value, SVGLength::lengthModeForAnimatedLengthAttribute(attrName));
290 break;
291 case AnimatedNumber:
292 ASSERT(m_data.number);
293 parseNumberFromString(value, *m_data.number);
294 break;
295 case AnimatedRect:
296 ASSERT(m_data.rect);
297 parseRect(value, *m_data.rect);
298 break;
299 case AnimatedString:
300 ASSERT(m_data.string);
301 *m_data.string = value;
302 break;
303
304 // These types don't appear in the table in SVGElement::cssPropertyToTypeMap() and thus don't need setValueAsString() support.
305 case AnimatedAngle:
306 case AnimatedBoolean:
307 case AnimatedEnumeration:
308 case AnimatedInteger:
309 case AnimatedIntegerOptionalInteger:
310 case AnimatedNumberList:
311 case AnimatedNumberOptionalNumber:
312 case AnimatedPath:
313 case AnimatedPoints:
314 case AnimatedPreserveAspectRatio:
315 case AnimatedTransformList:
316 case AnimatedUnknown:
317 // Only SVG DOM animations use these property types - that means setValueAsString() is never used for those.
318 ASSERT_NOT_REACHED();
319 break;
320 }
321 return true;
322 }
323
supportsAnimVal(AnimatedPropertyType type)324 bool SVGAnimatedType::supportsAnimVal(AnimatedPropertyType type)
325 {
326 // AnimatedColor is only used for CSS property animations.
327 return type != AnimatedUnknown && type != AnimatedColor;
328 }
329
330 } // namespace WebCore
331