| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2004, 2005 Nikolas Zimmermann <zimmermann@kde.org> | 2 * Copyright (C) 2004, 2005 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) 2009 Cameron McCormack <cam@mcc.id.au> | 6 * Copyright (C) 2009 Cameron McCormack <cam@mcc.id.au> |
| 7 * Copyright (C) Research In Motion Limited 2010. All rights reserved. | 7 * Copyright (C) Research In Motion Limited 2010. All rights reserved. |
| 8 * | 8 * |
| 9 * This library is free software; you can redistribute it and/or | 9 * This library is free software; you can redistribute it and/or |
| 10 * modify it under the terms of the GNU Library General Public | 10 * modify it under the terms of the GNU Library General Public |
| (...skipping 331 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 342 | 342 |
| 343 String SVGAnimationElement::fromValue() const | 343 String SVGAnimationElement::fromValue() const |
| 344 { | 344 { |
| 345 return fastGetAttribute(SVGNames::fromAttr); | 345 return fastGetAttribute(SVGNames::fromAttr); |
| 346 } | 346 } |
| 347 | 347 |
| 348 bool SVGAnimationElement::isAdditive() | 348 bool SVGAnimationElement::isAdditive() |
| 349 { | 349 { |
| 350 DEFINE_STATIC_LOCAL(const AtomicString, sum, ("sum", AtomicString::Construct
FromLiteral)); | 350 DEFINE_STATIC_LOCAL(const AtomicString, sum, ("sum", AtomicString::Construct
FromLiteral)); |
| 351 const AtomicString& value = fastGetAttribute(SVGNames::additiveAttr); | 351 const AtomicString& value = fastGetAttribute(SVGNames::additiveAttr); |
| 352 return value == sum || animationMode() == ByAnimation; | 352 return value == sum || getAnimationMode() == ByAnimation; |
| 353 } | 353 } |
| 354 | 354 |
| 355 bool SVGAnimationElement::isAccumulated() const | 355 bool SVGAnimationElement::isAccumulated() const |
| 356 { | 356 { |
| 357 DEFINE_STATIC_LOCAL(const AtomicString, sum, ("sum", AtomicString::Construct
FromLiteral)); | 357 DEFINE_STATIC_LOCAL(const AtomicString, sum, ("sum", AtomicString::Construct
FromLiteral)); |
| 358 const AtomicString& value = fastGetAttribute(SVGNames::accumulateAttr); | 358 const AtomicString& value = fastGetAttribute(SVGNames::accumulateAttr); |
| 359 return value == sum && animationMode() != ToAnimation; | 359 return value == sum && getAnimationMode() != ToAnimation; |
| 360 } | 360 } |
| 361 | 361 |
| 362 bool SVGAnimationElement::isTargetAttributeCSSProperty(SVGElement* targetElement
, const QualifiedName& attributeName) | 362 bool SVGAnimationElement::isTargetAttributeCSSProperty(SVGElement* targetElement
, const QualifiedName& attributeName) |
| 363 { | 363 { |
| 364 ASSERT(targetElement); | 364 ASSERT(targetElement); |
| 365 | 365 |
| 366 return SVGElement::isAnimatableCSSProperty(attributeName) || targetElement->
isPresentationAttribute(attributeName); | 366 return SVGElement::isAnimatableCSSProperty(attributeName) || targetElement->
isPresentationAttribute(attributeName); |
| 367 } | 367 } |
| 368 | 368 |
| 369 SVGAnimationElement::ShouldApplyAnimation SVGAnimationElement::shouldApplyAnimat
ion(SVGElement* targetElement, const QualifiedName& attributeName) | 369 SVGAnimationElement::ShouldApplyAnimation SVGAnimationElement::shouldApplyAnimat
ion(SVGElement* targetElement, const QualifiedName& attributeName) |
| 370 { | 370 { |
| 371 if (!hasValidAttributeType() || !targetElement || attributeName == anyQName(
) || !targetElement->inActiveDocument()) | 371 if (!hasValidAttributeType() || !targetElement || attributeName == anyQName(
) || !targetElement->inActiveDocument()) |
| 372 return DontApplyAnimation; | 372 return DontApplyAnimation; |
| 373 | 373 |
| 374 // Always animate CSS properties, using the ApplyCSSAnimation code path, reg
ardless of the attributeType value. | 374 // Always animate CSS properties, using the ApplyCSSAnimation code path, reg
ardless of the attributeType value. |
| 375 if (isTargetAttributeCSSProperty(targetElement, attributeName)) { | 375 if (isTargetAttributeCSSProperty(targetElement, attributeName)) { |
| 376 if (targetElement->isPresentationAttributeWithSVGDOM(attributeName)) | 376 if (targetElement->isPresentationAttributeWithSVGDOM(attributeName)) |
| 377 return ApplyXMLandCSSAnimation; | 377 return ApplyXMLandCSSAnimation; |
| 378 | 378 |
| 379 return ApplyCSSAnimation; | 379 return ApplyCSSAnimation; |
| 380 } | 380 } |
| 381 // If attributeType="CSS" and attributeName doesn't point to a CSS property,
ignore the animation. | 381 // If attributeType="CSS" and attributeName doesn't point to a CSS property,
ignore the animation. |
| 382 if (attributeType() == AttributeTypeCSS) | 382 if (getAttributeType() == AttributeTypeCSS) |
| 383 return DontApplyAnimation; | 383 return DontApplyAnimation; |
| 384 | 384 |
| 385 return ApplyXMLAnimation; | 385 return ApplyXMLAnimation; |
| 386 } | 386 } |
| 387 | 387 |
| 388 void SVGAnimationElement::calculateKeyTimesForCalcModePaced() | 388 void SVGAnimationElement::calculateKeyTimesForCalcModePaced() |
| 389 { | 389 { |
| 390 ASSERT(calcMode() == CalcModePaced); | 390 ASSERT(getCalcMode() == CalcModePaced); |
| 391 ASSERT(animationMode() == ValuesAnimation); | 391 ASSERT(getAnimationMode() == ValuesAnimation); |
| 392 | 392 |
| 393 unsigned valuesCount = m_values.size(); | 393 unsigned valuesCount = m_values.size(); |
| 394 ASSERT(valuesCount >= 1); | 394 ASSERT(valuesCount >= 1); |
| 395 if (valuesCount == 1) | 395 if (valuesCount == 1) |
| 396 return; | 396 return; |
| 397 | 397 |
| 398 // FIXME, webkit.org/b/109010: m_keyTimes should not be modified in this fun
ction. | 398 // FIXME, webkit.org/b/109010: m_keyTimes should not be modified in this fun
ction. |
| 399 m_keyTimes.clear(); | 399 m_keyTimes.clear(); |
| 400 | 400 |
| 401 Vector<float> keyTimesForPaced; | 401 Vector<float> keyTimesForPaced; |
| (...skipping 21 matching lines...) Expand all Loading... |
| 423 | 423 |
| 424 static inline double solveEpsilon(double duration) { return 1 / (200 * duration)
; } | 424 static inline double solveEpsilon(double duration) { return 1 / (200 * duration)
; } |
| 425 | 425 |
| 426 unsigned SVGAnimationElement::calculateKeyTimesIndex(float percent) const | 426 unsigned SVGAnimationElement::calculateKeyTimesIndex(float percent) const |
| 427 { | 427 { |
| 428 unsigned index; | 428 unsigned index; |
| 429 unsigned keyTimesCount = m_keyTimes.size(); | 429 unsigned keyTimesCount = m_keyTimes.size(); |
| 430 // For linear and spline animations, the last value must be '1'. In those | 430 // For linear and spline animations, the last value must be '1'. In those |
| 431 // cases we don't need to consider the last value, since |percent| is never | 431 // cases we don't need to consider the last value, since |percent| is never |
| 432 // greater than one. | 432 // greater than one. |
| 433 if (keyTimesCount && calcMode() != CalcModeDiscrete) | 433 if (keyTimesCount && getCalcMode() != CalcModeDiscrete) |
| 434 keyTimesCount--; | 434 keyTimesCount--; |
| 435 for (index = 1; index < keyTimesCount; ++index) { | 435 for (index = 1; index < keyTimesCount; ++index) { |
| 436 if (m_keyTimes[index] > percent) | 436 if (m_keyTimes[index] > percent) |
| 437 break; | 437 break; |
| 438 } | 438 } |
| 439 return --index; | 439 return --index; |
| 440 } | 440 } |
| 441 | 441 |
| 442 float SVGAnimationElement::calculatePercentForSpline(float percent, unsigned spl
ineIndex) const | 442 float SVGAnimationElement::calculatePercentForSpline(float percent, unsigned spl
ineIndex) const |
| 443 { | 443 { |
| 444 ASSERT(calcMode() == CalcModeSpline); | 444 ASSERT(getCalcMode() == CalcModeSpline); |
| 445 ASSERT_WITH_SECURITY_IMPLICATION(splineIndex < m_keySplines.size()); | 445 ASSERT_WITH_SECURITY_IMPLICATION(splineIndex < m_keySplines.size()); |
| 446 UnitBezier bezier = m_keySplines[splineIndex]; | 446 UnitBezier bezier = m_keySplines[splineIndex]; |
| 447 SMILTime duration = simpleDuration(); | 447 SMILTime duration = simpleDuration(); |
| 448 if (!duration.isFinite()) | 448 if (!duration.isFinite()) |
| 449 duration = 100.0; | 449 duration = 100.0; |
| 450 return narrowPrecisionToFloat(bezier.solve(percent, solveEpsilon(duration.va
lue()))); | 450 return narrowPrecisionToFloat(bezier.solve(percent, solveEpsilon(duration.va
lue()))); |
| 451 } | 451 } |
| 452 | 452 |
| 453 float SVGAnimationElement::calculatePercentFromKeyPoints(float percent) const | 453 float SVGAnimationElement::calculatePercentFromKeyPoints(float percent) const |
| 454 { | 454 { |
| 455 ASSERT(!m_keyPoints.isEmpty()); | 455 ASSERT(!m_keyPoints.isEmpty()); |
| 456 ASSERT(calcMode() != CalcModePaced); | 456 ASSERT(getCalcMode() != CalcModePaced); |
| 457 ASSERT(m_keyTimes.size() > 1); | 457 ASSERT(m_keyTimes.size() > 1); |
| 458 ASSERT(m_keyPoints.size() == m_keyTimes.size()); | 458 ASSERT(m_keyPoints.size() == m_keyTimes.size()); |
| 459 | 459 |
| 460 if (percent == 1) | 460 if (percent == 1) |
| 461 return m_keyPoints[m_keyPoints.size() - 1]; | 461 return m_keyPoints[m_keyPoints.size() - 1]; |
| 462 | 462 |
| 463 unsigned index = calculateKeyTimesIndex(percent); | 463 unsigned index = calculateKeyTimesIndex(percent); |
| 464 float fromKeyPoint = m_keyPoints[index]; | 464 float fromKeyPoint = m_keyPoints[index]; |
| 465 | 465 |
| 466 if (calcMode() == CalcModeDiscrete) | 466 if (getCalcMode() == CalcModeDiscrete) |
| 467 return fromKeyPoint; | 467 return fromKeyPoint; |
| 468 | 468 |
| 469 ASSERT(index + 1 < m_keyTimes.size()); | 469 ASSERT(index + 1 < m_keyTimes.size()); |
| 470 float fromPercent = m_keyTimes[index]; | 470 float fromPercent = m_keyTimes[index]; |
| 471 float toPercent = m_keyTimes[index + 1]; | 471 float toPercent = m_keyTimes[index + 1]; |
| 472 float toKeyPoint = m_keyPoints[index + 1]; | 472 float toKeyPoint = m_keyPoints[index + 1]; |
| 473 float keyPointPercent = (percent - fromPercent) / (toPercent - fromPercent); | 473 float keyPointPercent = (percent - fromPercent) / (toPercent - fromPercent); |
| 474 | 474 |
| 475 if (calcMode() == CalcModeSpline) { | 475 if (getCalcMode() == CalcModeSpline) { |
| 476 ASSERT(m_keySplines.size() == m_keyPoints.size() - 1); | 476 ASSERT(m_keySplines.size() == m_keyPoints.size() - 1); |
| 477 keyPointPercent = calculatePercentForSpline(keyPointPercent, index); | 477 keyPointPercent = calculatePercentForSpline(keyPointPercent, index); |
| 478 } | 478 } |
| 479 return (toKeyPoint - fromKeyPoint) * keyPointPercent + fromKeyPoint; | 479 return (toKeyPoint - fromKeyPoint) * keyPointPercent + fromKeyPoint; |
| 480 } | 480 } |
| 481 | 481 |
| 482 float SVGAnimationElement::calculatePercentForFromTo(float percent) const | 482 float SVGAnimationElement::calculatePercentForFromTo(float percent) const |
| 483 { | 483 { |
| 484 if (calcMode() == CalcModeDiscrete && m_keyTimes.size() == 2) | 484 if (getCalcMode() == CalcModeDiscrete && m_keyTimes.size() == 2) |
| 485 return percent > m_keyTimes[1] ? 1 : 0; | 485 return percent > m_keyTimes[1] ? 1 : 0; |
| 486 | 486 |
| 487 return percent; | 487 return percent; |
| 488 } | 488 } |
| 489 | 489 |
| 490 void SVGAnimationElement::currentValuesFromKeyPoints(float percent, float& effec
tivePercent, String& from, String& to) const | 490 void SVGAnimationElement::currentValuesFromKeyPoints(float percent, float& effec
tivePercent, String& from, String& to) const |
| 491 { | 491 { |
| 492 ASSERT(!m_keyPoints.isEmpty()); | 492 ASSERT(!m_keyPoints.isEmpty()); |
| 493 ASSERT(m_keyPoints.size() == m_keyTimes.size()); | 493 ASSERT(m_keyPoints.size() == m_keyTimes.size()); |
| 494 ASSERT(calcMode() != CalcModePaced); | 494 ASSERT(getCalcMode() != CalcModePaced); |
| 495 effectivePercent = calculatePercentFromKeyPoints(percent); | 495 effectivePercent = calculatePercentFromKeyPoints(percent); |
| 496 unsigned index = effectivePercent == 1 ? m_values.size() - 2 : static_cast<u
nsigned>(effectivePercent * (m_values.size() - 1)); | 496 unsigned index = effectivePercent == 1 ? m_values.size() - 2 : static_cast<u
nsigned>(effectivePercent * (m_values.size() - 1)); |
| 497 from = m_values[index]; | 497 from = m_values[index]; |
| 498 to = m_values[index + 1]; | 498 to = m_values[index + 1]; |
| 499 } | 499 } |
| 500 | 500 |
| 501 void SVGAnimationElement::currentValuesForValuesAnimation(float percent, float&
effectivePercent, String& from, String& to) | 501 void SVGAnimationElement::currentValuesForValuesAnimation(float percent, float&
effectivePercent, String& from, String& to) |
| 502 { | 502 { |
| 503 unsigned valuesCount = m_values.size(); | 503 unsigned valuesCount = m_values.size(); |
| 504 ASSERT(m_animationValid); | 504 ASSERT(m_animationValid); |
| 505 ASSERT(valuesCount >= 1); | 505 ASSERT(valuesCount >= 1); |
| 506 | 506 |
| 507 if (percent == 1 || valuesCount == 1) { | 507 if (percent == 1 || valuesCount == 1) { |
| 508 from = m_values[valuesCount - 1]; | 508 from = m_values[valuesCount - 1]; |
| 509 to = m_values[valuesCount - 1]; | 509 to = m_values[valuesCount - 1]; |
| 510 effectivePercent = 1; | 510 effectivePercent = 1; |
| 511 return; | 511 return; |
| 512 } | 512 } |
| 513 | 513 |
| 514 CalcMode calcMode = this->calcMode(); | 514 CalcMode calcMode = this->getCalcMode(); |
| 515 if (isSVGAnimateElement(*this)) { | 515 if (isSVGAnimateElement(*this)) { |
| 516 SVGAnimateElement& animateElement = toSVGAnimateElement(*this); | 516 SVGAnimateElement& animateElement = toSVGAnimateElement(*this); |
| 517 if (!animateElement.animatedPropertyTypeSupportsAddition()) { | 517 if (!animateElement.animatedPropertyTypeSupportsAddition()) { |
| 518 ASSERT(animateElement.animatedPropertyType() != AnimatedTransformLis
t || isSVGAnimateTransformElement(*this)); | 518 ASSERT(animateElement.animatedPropertyType() != AnimatedTransformLis
t || isSVGAnimateTransformElement(*this)); |
| 519 ASSERT(animateElement.animatedPropertyType() != AnimatedUnknown); | 519 ASSERT(animateElement.animatedPropertyType() != AnimatedUnknown); |
| 520 calcMode = CalcModeDiscrete; | 520 calcMode = CalcModeDiscrete; |
| 521 } | 521 } |
| 522 } | 522 } |
| 523 if (!m_keyPoints.isEmpty() && calcMode != CalcModePaced) | 523 if (!m_keyPoints.isEmpty() && calcMode != CalcModePaced) |
| 524 return currentValuesFromKeyPoints(percent, effectivePercent, from, to); | 524 return currentValuesFromKeyPoints(percent, effectivePercent, from, to); |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 568 if (!isValid()) | 568 if (!isValid()) |
| 569 return; | 569 return; |
| 570 | 570 |
| 571 if (!hasValidAttributeType()) | 571 if (!hasValidAttributeType()) |
| 572 return; | 572 return; |
| 573 | 573 |
| 574 // These validations are appropriate for all animation modes. | 574 // These validations are appropriate for all animation modes. |
| 575 if (fastHasAttribute(SVGNames::keyPointsAttr) && m_keyPoints.size() != m_key
Times.size()) | 575 if (fastHasAttribute(SVGNames::keyPointsAttr) && m_keyPoints.size() != m_key
Times.size()) |
| 576 return; | 576 return; |
| 577 | 577 |
| 578 AnimationMode animationMode = this->animationMode(); | 578 AnimationMode animationMode = this->getAnimationMode(); |
| 579 CalcMode calcMode = this->calcMode(); | 579 CalcMode calcMode = this->getCalcMode(); |
| 580 if (calcMode == CalcModeSpline) { | 580 if (calcMode == CalcModeSpline) { |
| 581 unsigned splinesCount = m_keySplines.size(); | 581 unsigned splinesCount = m_keySplines.size(); |
| 582 if (!splinesCount | 582 if (!splinesCount |
| 583 || (fastHasAttribute(SVGNames::keyPointsAttr) && m_keyPoints.size()
- 1 != splinesCount) | 583 || (fastHasAttribute(SVGNames::keyPointsAttr) && m_keyPoints.size()
- 1 != splinesCount) |
| 584 || (animationMode == ValuesAnimation && m_values.size() - 1 != splin
esCount) | 584 || (animationMode == ValuesAnimation && m_values.size() - 1 != splin
esCount) |
| 585 || (fastHasAttribute(SVGNames::keyTimesAttr) && m_keyTimes.size() -
1 != splinesCount)) | 585 || (fastHasAttribute(SVGNames::keyTimesAttr) && m_keyTimes.size() -
1 != splinesCount)) |
| 586 return; | 586 return; |
| 587 } | 587 } |
| 588 | 588 |
| 589 String from = fromValue(); | 589 String from = fromValue(); |
| (...skipping 28 matching lines...) Expand all Loading... |
| 618 m_animationValid = calcMode == CalcModePaced || !fastHasAttribute(SVGNam
es::keyPointsAttr) || (m_keyTimes.size() > 1 && m_keyTimes.size() == m_keyPoints
.size()); | 618 m_animationValid = calcMode == CalcModePaced || !fastHasAttribute(SVGNam
es::keyPointsAttr) || (m_keyTimes.size() > 1 && m_keyTimes.size() == m_keyPoints
.size()); |
| 619 } | 619 } |
| 620 } | 620 } |
| 621 | 621 |
| 622 void SVGAnimationElement::updateAnimation(float percent, unsigned repeatCount, S
VGSMILElement* resultElement) | 622 void SVGAnimationElement::updateAnimation(float percent, unsigned repeatCount, S
VGSMILElement* resultElement) |
| 623 { | 623 { |
| 624 if (!m_animationValid) | 624 if (!m_animationValid) |
| 625 return; | 625 return; |
| 626 | 626 |
| 627 float effectivePercent; | 627 float effectivePercent; |
| 628 CalcMode calcMode = this->calcMode(); | 628 CalcMode calcMode = this->getCalcMode(); |
| 629 AnimationMode animationMode = this->animationMode(); | 629 AnimationMode animationMode = this->getAnimationMode(); |
| 630 if (animationMode == ValuesAnimation) { | 630 if (animationMode == ValuesAnimation) { |
| 631 String from; | 631 String from; |
| 632 String to; | 632 String to; |
| 633 currentValuesForValuesAnimation(percent, effectivePercent, from, to); | 633 currentValuesForValuesAnimation(percent, effectivePercent, from, to); |
| 634 if (from != m_lastValuesAnimationFrom || to != m_lastValuesAnimationTo)
{ | 634 if (from != m_lastValuesAnimationFrom || to != m_lastValuesAnimationTo)
{ |
| 635 m_animationValid = calculateFromAndToValues(from, to); | 635 m_animationValid = calculateFromAndToValues(from, to); |
| 636 if (!m_animationValid) | 636 if (!m_animationValid) |
| 637 return; | 637 return; |
| 638 m_lastValuesAnimationFrom = from; | 638 m_lastValuesAnimationFrom = from; |
| 639 m_lastValuesAnimationTo = to; | 639 m_lastValuesAnimationTo = to; |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 706 } | 706 } |
| 707 | 707 |
| 708 void SVGAnimationElement::setAttributeName(const QualifiedName& attributeName) | 708 void SVGAnimationElement::setAttributeName(const QualifiedName& attributeName) |
| 709 { | 709 { |
| 710 SVGSMILElement::setAttributeName(attributeName); | 710 SVGSMILElement::setAttributeName(attributeName); |
| 711 checkInvalidCSSAttributeType(); | 711 checkInvalidCSSAttributeType(); |
| 712 } | 712 } |
| 713 | 713 |
| 714 void SVGAnimationElement::checkInvalidCSSAttributeType() | 714 void SVGAnimationElement::checkInvalidCSSAttributeType() |
| 715 { | 715 { |
| 716 bool hasInvalidCSSAttributeType = targetElement() && hasValidAttributeName()
&& attributeType() == AttributeTypeCSS && !isTargetAttributeCSSProperty(targetE
lement(), attributeName()); | 716 bool hasInvalidCSSAttributeType = targetElement() && hasValidAttributeName()
&& getAttributeType() == AttributeTypeCSS && !isTargetAttributeCSSProperty(targ
etElement(), attributeName()); |
| 717 | 717 |
| 718 if (hasInvalidCSSAttributeType != m_hasInvalidCSSAttributeType) { | 718 if (hasInvalidCSSAttributeType != m_hasInvalidCSSAttributeType) { |
| 719 if (hasInvalidCSSAttributeType) | 719 if (hasInvalidCSSAttributeType) |
| 720 unscheduleIfScheduled(); | 720 unscheduleIfScheduled(); |
| 721 | 721 |
| 722 m_hasInvalidCSSAttributeType = hasInvalidCSSAttributeType; | 722 m_hasInvalidCSSAttributeType = hasInvalidCSSAttributeType; |
| 723 | 723 |
| 724 if (!hasInvalidCSSAttributeType) | 724 if (!hasInvalidCSSAttributeType) |
| 725 schedule(); | 725 schedule(); |
| 726 } | 726 } |
| 727 | 727 |
| 728 // Clear values that may depend on the previous target. | 728 // Clear values that may depend on the previous target. |
| 729 if (targetElement()) | 729 if (targetElement()) |
| 730 clearAnimatedType(); | 730 clearAnimatedType(); |
| 731 } | 731 } |
| 732 | 732 |
| 733 } // namespace blink | 733 } // namespace blink |
| OLD | NEW |