Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / core / animation / TimedItemCalculations.h
index 174dd73..5226395 100644 (file)
 
 namespace WebCore {
 
+static inline double multiplyZeroAlwaysGivesZero(double x, double y)
+{
+    ASSERT(!isNull(x));
+    ASSERT(!isNull(y));
+    return x && y ? x * y : 0;
+}
+
 static inline TimedItem::Phase calculatePhase(double activeDuration, double localTime, const Timing& specified)
 {
     ASSERT(activeDuration >= 0);
@@ -65,22 +72,22 @@ static inline bool isActiveInParentPhase(TimedItem::Phase parentPhase, Timing::F
     }
 }
 
-static inline double calculateActiveTime(double activeDuration, double localTime, TimedItem::Phase parentPhase, TimedItem::Phase phase, const Timing& specified)
+static inline double calculateActiveTime(double activeDuration, Timing::FillMode fillMode, double localTime, TimedItem::Phase parentPhase, TimedItem::Phase phase, const Timing& specified)
 {
     ASSERT(activeDuration >= 0);
     ASSERT(phase == calculatePhase(activeDuration, localTime, specified));
 
     switch (phase) {
     case TimedItem::PhaseBefore:
-        if (specified.fillMode == Timing::FillModeBackwards || specified.fillMode == Timing::FillModeBoth)
+        if (fillMode == Timing::FillModeBackwards || fillMode == Timing::FillModeBoth)
             return 0;
         return nullValue();
     case TimedItem::PhaseActive:
-        if (isActiveInParentPhase(parentPhase, specified.fillMode))
+        if (isActiveInParentPhase(parentPhase, fillMode))
             return localTime - specified.startDelay;
         return nullValue();
     case TimedItem::PhaseAfter:
-        if (specified.fillMode == Timing::FillModeForwards || specified.fillMode == Timing::FillModeBoth)
+        if (fillMode == Timing::FillModeForwards || fillMode == Timing::FillModeBoth)
             return activeDuration;
         return nullValue();
     case TimedItem::PhaseNone:
@@ -100,20 +107,20 @@ static inline double calculateScaledActiveTime(double activeDuration, double act
     if (isNull(activeTime))
         return nullValue();
 
-    ASSERT(activeTime >= 0);
-
-    return (specified.playbackRate < 0 ? activeTime - activeDuration : activeTime) * specified.playbackRate + startOffset;
+    ASSERT(activeTime >= 0 && activeTime <= activeDuration);
+    return multiplyZeroAlwaysGivesZero(specified.playbackRate < 0 ? activeTime - activeDuration : activeTime, specified.playbackRate) + startOffset;
 }
 
 static inline bool endsOnIterationBoundary(double iterationCount, double iterationStart)
 {
+    ASSERT(std::isfinite(iterationCount));
     return !fmod(iterationCount + iterationStart, 1);
 }
 
 static inline double calculateIterationTime(double iterationDuration, double repeatedDuration, double scaledActiveTime, double startOffset, const Timing& specified)
 {
-    ASSERT(iterationDuration >= 0);
-    ASSERT(repeatedDuration == iterationDuration * specified.iterationCount);
+    ASSERT(iterationDuration > 0);
+    ASSERT(repeatedDuration == multiplyZeroAlwaysGivesZero(iterationDuration, specified.iterationCount));
 
     if (isNull(scaledActiveTime))
         return nullValue();
@@ -121,18 +128,17 @@ static inline double calculateIterationTime(double iterationDuration, double rep
     ASSERT(scaledActiveTime >= 0);
     ASSERT(scaledActiveTime <= repeatedDuration + startOffset);
 
-    if (!iterationDuration)
-        return 0;
-
-    if (scaledActiveTime - startOffset == repeatedDuration && specified.iterationCount && endsOnIterationBoundary(specified.iterationCount, specified.iterationStart))
+    if (!std::isfinite(scaledActiveTime)
+        || (scaledActiveTime - startOffset == repeatedDuration && specified.iterationCount && endsOnIterationBoundary(specified.iterationCount, specified.iterationStart)))
         return iterationDuration;
 
+    ASSERT(std::isfinite(scaledActiveTime));
     return fmod(scaledActiveTime, iterationDuration);
 }
 
 static inline double calculateCurrentIteration(double iterationDuration, double iterationTime, double scaledActiveTime, const Timing& specified)
 {
-    ASSERT(iterationDuration >= 0);
+    ASSERT(iterationDuration > 0);
     ASSERT(isNull(iterationTime) || iterationTime >= 0);
 
     if (isNull(scaledActiveTime))
@@ -145,9 +151,6 @@ static inline double calculateCurrentIteration(double iterationDuration, double
     if (!scaledActiveTime)
         return 0;
 
-    if (!iterationDuration)
-        return floor(specified.iterationStart + specified.iterationCount);
-
     if (iterationTime == iterationDuration)
         return specified.iterationStart + specified.iterationCount - 1;
 
@@ -183,9 +186,13 @@ static inline double calculateTransformedTime(double currentIteration, double it
     double directedTime = calculateDirectedTime(currentIteration, iterationDuration, iterationTime, specified);
     if (isNull(directedTime))
         return nullValue();
-    return specified.timingFunction ?
-        iterationDuration * specified.timingFunction->evaluate(directedTime / iterationDuration, accuracyForDuration(iterationDuration)) :
-        directedTime;
+    if (!std::isfinite(iterationDuration))
+        return directedTime;
+    double timeFraction = directedTime / iterationDuration;
+    ASSERT(timeFraction >= 0 && timeFraction <= 1);
+    return specified.timingFunction
+        ? multiplyZeroAlwaysGivesZero(iterationDuration, specified.timingFunction->evaluate(timeFraction, accuracyForDuration(iterationDuration)))
+        : directedTime;
 }
 
 } // namespace WebCore