| 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 |