OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2004, 2005, 2008 Nikolas Zimmermann <zimmermann@kde.org> | 2 * Copyright (C) 2004, 2005, 2008 Nikolas Zimmermann <zimmermann@kde.org> |
3 * Copyright (C) 2004, 2005, 2006, 2007 Rob Buis <buis@kde.org> | 3 * Copyright (C) 2004, 2005, 2006, 2007 Rob Buis <buis@kde.org> |
4 * Copyright (C) 2007 Eric Seidel <eric@webkit.org> | 4 * Copyright (C) 2007 Eric Seidel <eric@webkit.org> |
5 * Copyright (C) 2008 Apple Inc. All rights reserved. | 5 * Copyright (C) 2008 Apple Inc. All rights reserved. |
6 * Copyright (C) Research In Motion Limited 2012. All rights reserved. | 6 * Copyright (C) Research In Motion Limited 2012. All rights reserved. |
7 * | 7 * |
8 * This library is free software; you can redistribute it and/or | 8 * This library is free software; you can redistribute it and/or |
9 * modify it under the terms of the GNU Library General Public | 9 * modify it under the terms of the GNU Library General Public |
10 * License as published by the Free Software Foundation; either | 10 * License as published by the Free Software Foundation; either |
(...skipping 17 matching lines...) Expand all Loading... |
28 #include "core/SVGNames.h" | 28 #include "core/SVGNames.h" |
29 #include "core/svg/SVGAnimateTransformElement.h" | 29 #include "core/svg/SVGAnimateTransformElement.h" |
30 #include "core/svg/SVGAnimatedNumber.h" | 30 #include "core/svg/SVGAnimatedNumber.h" |
31 #include "core/svg/SVGParserUtilities.h" | 31 #include "core/svg/SVGParserUtilities.h" |
32 #include "core/svg/SVGTransformDistance.h" | 32 #include "core/svg/SVGTransformDistance.h" |
33 #include "wtf/text/StringBuilder.h" | 33 #include "wtf/text/StringBuilder.h" |
34 #include "wtf/text/WTFString.h" | 34 #include "wtf/text/WTFString.h" |
35 | 35 |
36 namespace blink { | 36 namespace blink { |
37 | 37 |
38 inline PassRefPtr<SVGTransformList> toSVGTransformList(PassRefPtr<SVGPropertyBas
e> passBase) | 38 inline PassRefPtrWillBeRawPtr<SVGTransformList> toSVGTransformList(PassRefPtrWil
lBeRawPtr<SVGPropertyBase> passBase) |
39 { | 39 { |
40 RefPtr<SVGPropertyBase> base = passBase; | 40 RefPtrWillBeRawPtr<SVGPropertyBase> base = passBase; |
41 ASSERT(base->type() == SVGTransformList::classType()); | 41 ASSERT(base->type() == SVGTransformList::classType()); |
42 return static_pointer_cast<SVGTransformList>(base.release()); | 42 return static_pointer_cast<SVGTransformList>(base.release()); |
43 } | 43 } |
44 | 44 |
45 SVGTransformList::SVGTransformList() | 45 SVGTransformList::SVGTransformList() |
46 { | 46 { |
47 } | 47 } |
48 | 48 |
49 SVGTransformList::~SVGTransformList() | 49 SVGTransformList::~SVGTransformList() |
50 { | 50 { |
51 } | 51 } |
52 | 52 |
53 PassRefPtr<SVGTransform> SVGTransformList::consolidate() | 53 PassRefPtrWillBeRawPtr<SVGTransform> SVGTransformList::consolidate() |
54 { | 54 { |
55 AffineTransform matrix; | 55 AffineTransform matrix; |
56 if (!concatenate(matrix)) | 56 if (!concatenate(matrix)) |
57 return SVGTransform::create(); | 57 return SVGTransform::create(); |
58 | 58 |
59 RefPtr<SVGTransform> transform = SVGTransform::create(matrix); | 59 RefPtrWillBeRawPtr<SVGTransform> transform = SVGTransform::create(matrix); |
60 clear(); | 60 clear(); |
61 return appendItem(transform); | 61 return appendItem(transform); |
62 } | 62 } |
63 | 63 |
64 bool SVGTransformList::concatenate(AffineTransform& result) const | 64 bool SVGTransformList::concatenate(AffineTransform& result) const |
65 { | 65 { |
66 if (isEmpty()) | 66 if (isEmpty()) |
67 return false; | 67 return false; |
68 | 68 |
69 ConstIterator it = begin(); | 69 ConstIterator it = begin(); |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
105 return -1; | 105 return -1; |
106 | 106 |
107 return parsedParams; | 107 return parsedParams; |
108 } | 108 } |
109 | 109 |
110 // These should be kept in sync with enum SVGTransformType | 110 // These should be kept in sync with enum SVGTransformType |
111 static const int requiredValuesForType[] = {0, 6, 1, 1, 1, 1, 1}; | 111 static const int requiredValuesForType[] = {0, 6, 1, 1, 1, 1, 1}; |
112 static const int optionalValuesForType[] = {0, 0, 1, 1, 2, 0, 0}; | 112 static const int optionalValuesForType[] = {0, 0, 1, 1, 2, 0, 0}; |
113 | 113 |
114 template<typename CharType> | 114 template<typename CharType> |
115 PassRefPtr<SVGTransform> parseTransformOfType(unsigned type, const CharType*& pt
r, const CharType* end) | 115 PassRefPtrWillBeRawPtr<SVGTransform> parseTransformOfType(unsigned type, const C
harType*& ptr, const CharType* end) |
116 { | 116 { |
117 if (type == SVG_TRANSFORM_UNKNOWN) | 117 if (type == SVG_TRANSFORM_UNKNOWN) |
118 return nullptr; | 118 return nullptr; |
119 | 119 |
120 int valueCount = 0; | 120 int valueCount = 0; |
121 float values[] = {0, 0, 0, 0, 0, 0}; | 121 float values[] = {0, 0, 0, 0, 0, 0}; |
122 if ((valueCount = parseTransformParamList(ptr, end, values, requiredValuesFo
rType[type], optionalValuesForType[type])) < 0) { | 122 if ((valueCount = parseTransformParamList(ptr, end, values, requiredValuesFo
rType[type], optionalValuesForType[type])) < 0) { |
123 return nullptr; | 123 return nullptr; |
124 } | 124 } |
125 | 125 |
126 RefPtr<SVGTransform> transform = SVGTransform::create(); | 126 RefPtrWillBeRawPtr<SVGTransform> transform = SVGTransform::create(); |
127 | 127 |
128 switch (type) { | 128 switch (type) { |
129 case SVG_TRANSFORM_SKEWX: | 129 case SVG_TRANSFORM_SKEWX: |
130 transform->setSkewX(values[0]); | 130 transform->setSkewX(values[0]); |
131 break; | 131 break; |
132 case SVG_TRANSFORM_SKEWY: | 132 case SVG_TRANSFORM_SKEWY: |
133 transform->setSkewY(values[0]); | 133 transform->setSkewY(values[0]); |
134 break; | 134 break; |
135 case SVG_TRANSFORM_SCALE: | 135 case SVG_TRANSFORM_SCALE: |
136 if (valueCount == 1) // Spec: if only one param given, assume uniform sc
aling | 136 if (valueCount == 1) // Spec: if only one param given, assume uniform sc
aling |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
171 SVGTransformType transformType = SVG_TRANSFORM_UNKNOWN; | 171 SVGTransformType transformType = SVG_TRANSFORM_UNKNOWN; |
172 skipOptionalSVGSpaces(ptr, end); | 172 skipOptionalSVGSpaces(ptr, end); |
173 | 173 |
174 if (!parseAndSkipTransformType(ptr, end, transformType)) | 174 if (!parseAndSkipTransformType(ptr, end, transformType)) |
175 return false; | 175 return false; |
176 | 176 |
177 if (!skipOptionalSVGSpaces(ptr, end) || *ptr != '(') | 177 if (!skipOptionalSVGSpaces(ptr, end) || *ptr != '(') |
178 return false; | 178 return false; |
179 ptr++; | 179 ptr++; |
180 | 180 |
181 RefPtr<SVGTransform> transform = parseTransformOfType(transformType, ptr
, end); | 181 RefPtrWillBeRawPtr<SVGTransform> transform = parseTransformOfType(transf
ormType, ptr, end); |
182 if (!transform) | 182 if (!transform) |
183 return false; | 183 return false; |
184 | 184 |
185 if (!skipOptionalSVGSpaces(ptr, end) || *ptr != ')') | 185 if (!skipOptionalSVGSpaces(ptr, end) || *ptr != ')') |
186 return false; | 186 return false; |
187 ptr++; | 187 ptr++; |
188 | 188 |
189 append(transform.release()); | 189 append(transform.release()); |
190 | 190 |
191 skipOptionalSVGSpaces(ptr, end); | 191 skipOptionalSVGSpaces(ptr, end); |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
242 const UChar* end = ptr + value.length(); | 242 const UChar* end = ptr + value.length(); |
243 valid = parse(ptr, end); | 243 valid = parse(ptr, end); |
244 } | 244 } |
245 | 245 |
246 if (!valid) { | 246 if (!valid) { |
247 clear(); | 247 clear(); |
248 exceptionState.throwDOMException(SyntaxError, "Problem parsing transform
list=\""+value+"\""); | 248 exceptionState.throwDOMException(SyntaxError, "Problem parsing transform
list=\""+value+"\""); |
249 } | 249 } |
250 } | 250 } |
251 | 251 |
252 PassRefPtr<SVGPropertyBase> SVGTransformList::cloneForAnimation(const String& va
lue) const | 252 PassRefPtrWillBeRawPtr<SVGPropertyBase> SVGTransformList::cloneForAnimation(cons
t String& value) const |
253 { | 253 { |
254 ASSERT_NOT_REACHED(); | 254 ASSERT_NOT_REACHED(); |
255 return nullptr; | 255 return nullptr; |
256 } | 256 } |
257 | 257 |
258 PassRefPtr<SVGTransformList> SVGTransformList::create(SVGTransformType transform
Type, const String& value) | 258 PassRefPtrWillBeRawPtr<SVGTransformList> SVGTransformList::create(SVGTransformTy
pe transformType, const String& value) |
259 { | 259 { |
260 RefPtr<SVGTransform> transform; | 260 RefPtrWillBeRawPtr<SVGTransform> transform = nullptr; |
261 if (value.isEmpty()) { | 261 if (value.isEmpty()) { |
262 } else if (value.is8Bit()) { | 262 } else if (value.is8Bit()) { |
263 const LChar* ptr = value.characters8(); | 263 const LChar* ptr = value.characters8(); |
264 const LChar* end = ptr + value.length(); | 264 const LChar* end = ptr + value.length(); |
265 transform = parseTransformOfType(transformType, ptr, end); | 265 transform = parseTransformOfType(transformType, ptr, end); |
266 } else { | 266 } else { |
267 const UChar* ptr = value.characters16(); | 267 const UChar* ptr = value.characters16(); |
268 const UChar* end = ptr + value.length(); | 268 const UChar* end = ptr + value.length(); |
269 transform = parseTransformOfType(transformType, ptr, end); | 269 transform = parseTransformOfType(transformType, ptr, end); |
270 } | 270 } |
271 | 271 |
272 RefPtr<SVGTransformList> svgTransformList = SVGTransformList::create(); | 272 RefPtrWillBeRawPtr<SVGTransformList> svgTransformList = SVGTransformList::cr
eate(); |
273 if (transform) | 273 if (transform) |
274 svgTransformList->append(transform); | 274 svgTransformList->append(transform); |
275 return svgTransformList.release(); | 275 return svgTransformList.release(); |
276 } | 276 } |
277 | 277 |
278 void SVGTransformList::add(PassRefPtrWillBeRawPtr<SVGPropertyBase> other, SVGEle
ment* contextElement) | 278 void SVGTransformList::add(PassRefPtrWillBeRawPtr<SVGPropertyBase> other, SVGEle
ment* contextElement) |
279 { | 279 { |
280 if (isEmpty()) | 280 if (isEmpty()) |
281 return; | 281 return; |
282 | 282 |
283 RefPtr<SVGTransformList> otherList = toSVGTransformList(other); | 283 RefPtrWillBeRawPtr<SVGTransformList> otherList = toSVGTransformList(other); |
284 if (length() != otherList->length()) | 284 if (length() != otherList->length()) |
285 return; | 285 return; |
286 | 286 |
287 ASSERT(length() == 1); | 287 ASSERT(length() == 1); |
288 RefPtr<SVGTransform> fromTransform = at(0); | 288 RefPtrWillBeRawPtr<SVGTransform> fromTransform = at(0); |
289 RefPtr<SVGTransform> toTransform = otherList->at(0); | 289 RefPtrWillBeRawPtr<SVGTransform> toTransform = otherList->at(0); |
290 | 290 |
291 ASSERT(fromTransform->transformType() == toTransform->transformType()); | 291 ASSERT(fromTransform->transformType() == toTransform->transformType()); |
292 clear(); | 292 clear(); |
293 append(SVGTransformDistance::addSVGTransforms(fromTransform, toTransform)); | 293 append(SVGTransformDistance::addSVGTransforms(fromTransform, toTransform)); |
294 } | 294 } |
295 | 295 |
296 void SVGTransformList::calculateAnimatedValue(SVGAnimationElement* animationElem
ent, float percentage, unsigned repeatCount, PassRefPtr<SVGPropertyBase> fromVal
ue, PassRefPtr<SVGPropertyBase> toValue, PassRefPtr<SVGPropertyBase> toAtEndOfDu
rationValue, SVGElement* contextElement) | 296 void SVGTransformList::calculateAnimatedValue(SVGAnimationElement* animationElem
ent, float percentage, unsigned repeatCount, PassRefPtrWillBeRawPtr<SVGPropertyB
ase> fromValue, PassRefPtrWillBeRawPtr<SVGPropertyBase> toValue, PassRefPtrWillB
eRawPtr<SVGPropertyBase> toAtEndOfDurationValue, SVGElement* contextElement) |
297 { | 297 { |
298 ASSERT(animationElement); | 298 ASSERT(animationElement); |
299 bool isToAnimation = animationElement->animationMode() == ToAnimation; | 299 bool isToAnimation = animationElement->animationMode() == ToAnimation; |
300 | 300 |
301 // Spec: To animations provide specific functionality to get a smooth change
from the underlying value to the | 301 // Spec: To animations provide specific functionality to get a smooth change
from the underlying value to the |
302 // ‘to’ attribute value, which conflicts mathematically with the requirement
for additive transform animations | 302 // ‘to’ attribute value, which conflicts mathematically with the requirement
for additive transform animations |
303 // to be post-multiplied. As a consequence, in SVG 1.1 the behavior of to an
imations for ‘animateTransform’ is undefined | 303 // to be post-multiplied. As a consequence, in SVG 1.1 the behavior of to an
imations for ‘animateTransform’ is undefined |
304 // FIXME: This is not taken into account yet. | 304 // FIXME: This is not taken into account yet. |
305 RefPtr<SVGTransformList> fromList = isToAnimation ? this : toSVGTransformLis
t(fromValue); | 305 RefPtrWillBeRawPtr<SVGTransformList> fromList = isToAnimation ? PassRefPtrWi
llBeRawPtr<SVGTransformList>(this) : toSVGTransformList(fromValue); |
306 RefPtr<SVGTransformList> toList = toSVGTransformList(toValue); | 306 RefPtrWillBeRawPtr<SVGTransformList> toList = toSVGTransformList(toValue); |
307 RefPtr<SVGTransformList> toAtEndOfDurationList = toSVGTransformList(toAtEndO
fDurationValue); | 307 RefPtrWillBeRawPtr<SVGTransformList> toAtEndOfDurationList = toSVGTransformL
ist(toAtEndOfDurationValue); |
308 | 308 |
309 size_t toListSize = toList->length(); | 309 size_t toListSize = toList->length(); |
310 if (!toListSize) | 310 if (!toListSize) |
311 return; | 311 return; |
312 | 312 |
313 // Get a reference to the from value before potentially cleaning it out (in
the case of a To animation.) | 313 // Get a reference to the from value before potentially cleaning it out (in
the case of a To animation.) |
314 RefPtr<SVGTransform> toTransform = toList->at(0); | 314 RefPtrWillBeRawPtr<SVGTransform> toTransform = toList->at(0); |
315 RefPtr<SVGTransform> effectiveFrom; | 315 RefPtrWillBeRawPtr<SVGTransform> effectiveFrom = nullptr; |
316 // If there's an existing 'from'/underlying value of the same type use that,
else use a "zero transform". | 316 // If there's an existing 'from'/underlying value of the same type use that,
else use a "zero transform". |
317 if (fromList->length() && fromList->at(0)->transformType() == toTransform->t
ransformType()) | 317 if (fromList->length() && fromList->at(0)->transformType() == toTransform->t
ransformType()) |
318 effectiveFrom = fromList->at(0); | 318 effectiveFrom = fromList->at(0); |
319 else | 319 else |
320 effectiveFrom = SVGTransform::create(toTransform->transformType(), SVGTr
ansform::ConstructZeroTransform); | 320 effectiveFrom = SVGTransform::create(toTransform->transformType(), SVGTr
ansform::ConstructZeroTransform); |
321 | 321 |
322 // Never resize the animatedTransformList to the toList size, instead either
clear the list or append to it. | 322 // Never resize the animatedTransformList to the toList size, instead either
clear the list or append to it. |
323 if (!isEmpty() && (!animationElement->isAdditive() || isToAnimation)) | 323 if (!isEmpty() && (!animationElement->isAdditive() || isToAnimation)) |
324 clear(); | 324 clear(); |
325 | 325 |
326 RefPtr<SVGTransform> currentTransform = SVGTransformDistance(effectiveFrom,
toTransform).scaledDistance(percentage).addToSVGTransform(effectiveFrom); | 326 RefPtrWillBeRawPtr<SVGTransform> currentTransform = SVGTransformDistance(eff
ectiveFrom, toTransform).scaledDistance(percentage).addToSVGTransform(effectiveF
rom); |
327 if (animationElement->isAccumulated() && repeatCount) { | 327 if (animationElement->isAccumulated() && repeatCount) { |
328 RefPtr<SVGTransform> effectiveToAtEnd = !toAtEndOfDurationList->isEmpty(
) ? toAtEndOfDurationList->at(0) : SVGTransform::create(toTransform->transformTy
pe(), SVGTransform::ConstructZeroTransform); | 328 RefPtrWillBeRawPtr<SVGTransform> effectiveToAtEnd = !toAtEndOfDurationLi
st->isEmpty() ? PassRefPtrWillBeRawPtr<SVGTransform>(toAtEndOfDurationList->at(0
)) : SVGTransform::create(toTransform->transformType(), SVGTransform::ConstructZ
eroTransform); |
329 append(SVGTransformDistance::addSVGTransforms(currentTransform, effectiv
eToAtEnd, repeatCount)); | 329 append(SVGTransformDistance::addSVGTransforms(currentTransform, effectiv
eToAtEnd, repeatCount)); |
330 } else { | 330 } else { |
331 append(currentTransform); | 331 append(currentTransform); |
332 } | 332 } |
333 } | 333 } |
334 | 334 |
335 float SVGTransformList::calculateDistance(PassRefPtr<SVGPropertyBase> toValue, S
VGElement*) | 335 float SVGTransformList::calculateDistance(PassRefPtrWillBeRawPtr<SVGPropertyBase
> toValue, SVGElement*) |
336 { | 336 { |
337 // FIXME: This is not correct in all cases. The spec demands that each compo
nent (translate x and y for example) | 337 // FIXME: This is not correct in all cases. The spec demands that each compo
nent (translate x and y for example) |
338 // is paced separately. To implement this we need to treat each component as
individual animation everywhere. | 338 // is paced separately. To implement this we need to treat each component as
individual animation everywhere. |
339 | 339 |
340 RefPtr<SVGTransformList> toList = toSVGTransformList(toValue); | 340 RefPtrWillBeRawPtr<SVGTransformList> toList = toSVGTransformList(toValue); |
341 if (isEmpty() || length() != toList->length()) | 341 if (isEmpty() || length() != toList->length()) |
342 return -1; | 342 return -1; |
343 | 343 |
344 ASSERT(length() == 1); | 344 ASSERT(length() == 1); |
345 if (at(0)->transformType() == toList->at(0)->transformType()) | 345 if (at(0)->transformType() == toList->at(0)->transformType()) |
346 return -1; | 346 return -1; |
347 | 347 |
348 // Spec: http://www.w3.org/TR/SVG/animate.html#complexDistances | 348 // Spec: http://www.w3.org/TR/SVG/animate.html#complexDistances |
349 // Paced animations assume a notion of distance between the various animatio
n values defined by the ‘to’, ‘from’, ‘by’ and ‘values’ attributes. | 349 // Paced animations assume a notion of distance between the various animatio
n values defined by the ‘to’, ‘from’, ‘by’ and ‘values’ attributes. |
350 // Distance is defined only for scalar types (such as <length>), colors and
the subset of transformation types that are supported by ‘animateTransform’. | 350 // Distance is defined only for scalar types (such as <length>), colors and
the subset of transformation types that are supported by ‘animateTransform’. |
351 return SVGTransformDistance(at(0), toList->at(0)).distance(); | 351 return SVGTransformDistance(at(0), toList->at(0)).distance(); |
352 } | 352 } |
353 | 353 |
354 } | 354 } |
OLD | NEW |