Bug 1358966 - Make intervelProgress an array. r?birtles draft
authorHiroyuki Ikezoe <hikezoe@mozilla.com>
Tue, 06 Jun 2017 12:54:57 +0900
changeset 589369 d6ab3ce4236442ce3845b94c2dd7c669597bb699
parent 589368 7b0bb8148f9a3f55b6e181eab1f384bc374b4063
child 589370 f3e0a29fc1d293ec973a8e9b7d5ae00a287e0a75
push id62344
push userhikezoe@mozilla.com
push dateTue, 06 Jun 2017 03:58:54 +0000
reviewersbirtles
bugs1358966
milestone55.0a1
Bug 1358966 - Make intervelProgress an array. r?birtles MozReview-Commit-ID: 3uO72Hy8x0C
dom/smil/nsSMILAnimationFunction.cpp
dom/smil/nsSMILAnimationFunction.h
--- a/dom/smil/nsSMILAnimationFunction.cpp
+++ b/dom/smil/nsSMILAnimationFunction.cpp
@@ -394,53 +394,53 @@ nsSMILAnimationFunction::InterpolateResu
   }
 
   if (calcMode != CALC_DISCRETE) {
     // Get the normalised progress between adjacent values
     const nsSMILValue* from = nullptr;
     const nsSMILValue* to = nullptr;
     // Init to -1 to make sure that if we ever forget to set this, the
     // MOZ_ASSERT that tests that intervalProgress is in range will fail.
-    double intervalProgress = -1.f;
+    AutoTArray<double, 1> intervalProgress = { -1.f };
     if (IsToAnimation()) {
       from = &aBaseValue;
       to = &aValues[0];
       if (calcMode == CALC_PACED) {
         // Note: key[Times/Splines/Points] are ignored for calcMode="paced"
-        intervalProgress = simpleProgress;
+        intervalProgress[0] = simpleProgress;
       } else {
         double scaledSimpleProgress =
           ScaleSimpleProgress(simpleProgress, calcMode);
-        intervalProgress = ScaleIntervalProgress(scaledSimpleProgress, 0);
+        intervalProgress[0] = ScaleIntervalProgress(scaledSimpleProgress, 0);
       }
     } else if (calcMode == CALC_PACED) {
       rv = ComputePacedPosition(aValues, simpleProgress,
                                 intervalProgress, from, to);
       // Note: If the above call fails, we'll skip the "from->Interpolate"
       // call below, and we'll drop into the CALC_DISCRETE section
       // instead. (as the spec says we should, because our failure was
       // presumably due to the values being non-additive)
     } else { // calcMode == CALC_LINEAR or calcMode == CALC_SPLINE
       double scaledSimpleProgress =
         ScaleSimpleProgress(simpleProgress, calcMode);
       uint32_t index = (uint32_t)floor(scaledSimpleProgress *
                                        (aValues.Length() - 1));
       from = &aValues[index];
       to = &aValues[index + 1];
-      intervalProgress =
+      intervalProgress[0] =
         scaledSimpleProgress * (aValues.Length() - 1) - index;
-      intervalProgress = ScaleIntervalProgress(intervalProgress, index);
+      intervalProgress[0] = ScaleIntervalProgress(intervalProgress[0], index);
     }
 
     if (NS_SUCCEEDED(rv)) {
       MOZ_ASSERT(from, "NULL from-value during interpolation");
       MOZ_ASSERT(to, "NULL to-value during interpolation");
-      MOZ_ASSERT(0.0f <= intervalProgress && intervalProgress < 1.0f,
+      MOZ_ASSERT(0.0f <= intervalProgress[0] && intervalProgress[0] < 1.0f,
                  "Interval progress should be in the range [0, 1)");
-      rv = from->Interpolate(*to, intervalProgress, aResult);
+      rv = from->Interpolate(*to, intervalProgress[0], aResult);
     }
   }
 
   // Discrete-CalcMode case
   // Note: If interpolation failed (isn't supported for this type), the SVG
   // spec says to force discrete mode.
   if (calcMode == CALC_DISCRETE || NS_FAILED(rv)) {
     double scaledSimpleProgress =
@@ -508,31 +508,31 @@ ClampDistances(AutoTArray<double, 1>& aD
  *    (returned as aIntervalProgress)
  *
  * Returns NS_OK, or NS_ERROR_FAILURE if our values don't support distance
  * computation.
  */
 nsresult
 nsSMILAnimationFunction::ComputePacedPosition(const nsSMILValueArray& aValues,
                                               double aSimpleProgress,
-                                              double& aIntervalProgress,
+                                              AutoTArray<double, 1>& aIntervalProgress,
                                               const nsSMILValue*& aFrom,
                                               const nsSMILValue*& aTo)
 {
   NS_ASSERTION(0.0f <= aSimpleProgress && aSimpleProgress < 1.0f,
                "aSimpleProgress is out of bounds");
   NS_ASSERTION(GetCalcMode() == CALC_PACED,
                "Calling paced-specific function, but not in paced mode");
   MOZ_ASSERT(aValues.Length() >= 2, "Unexpected number of values");
 
   // Trivial case: If we have just 2 values, then there's only one interval
   // for us to traverse, and our progress across that interval is the exact
   // same as our overall progress.
   if (aValues.Length() == 2) {
-    aIntervalProgress = aSimpleProgress;
+    aIntervalProgress[0] = aSimpleProgress;
     aFrom = &aValues[0];
     aTo = &aValues[1];
     return NS_OK;
   }
 
   AutoTArray<double, 1> totalDistances;
   if (!ComputePacedTotalDistances(aValues, totalDistances)) {
     return NS_ERROR_FAILURE;
@@ -574,33 +574,44 @@ nsSMILAnimationFunction::ComputePacedPos
 #endif
       aValues[i].ComputeDistance(aValues[i+1], curIntervalDists);
     MOZ_ASSERT(NS_SUCCEEDED(rv),
                "If we got through ComputePacedTotalDistances, we should "
                "be able to recompute each sub-distance without errors");
 
     ClampDistances(curIntervalDists);
 
-    if (remainingDists[0] >= curIntervalDists[0]) {
-      remainingDists[0] -= curIntervalDists[0];
-    } else {
-      // NOTE: If we get here, then curIntervalDist necessarily is not 0. Why?
-      // Because this clause is only hit when remainingDist < curIntervalDist,
-      // and if curIntervalDist were 0, that would mean remainingDist would
-      // have to be < 0.  But that can't happen, because remainingDist (as
-      // a distance) is non-negative by definition.
-      NS_ASSERTION(curIntervalDists[0] != 0,
-                   "We should never get here with this set to 0...");
+    for (size_t j = 0; j < len; j++) {
+      // FIXME: Below code does not work well for sub properties of shorthand.
+      // For example, when we met the condition that a remaining distance is
+      // lesser than curIntervalDist but another remaining distance is still
+      // greater than curIntervalDist, what should we do?
+      // Currently this happens only if font shorthand propery is specified and
+      // if some sub properties of font (e.g. font-size, font-size-adjust) are
+      // specifed in different paced.
+      // To fix this properly we should migrate SMIL stuff onto script animation
+      // stuff.
+      if (remainingDists[j] >= curIntervalDists[j]) {
+        remainingDists[j] -= curIntervalDists[j];
+      } else {
+        // NOTE: If we get here, then curIntervalDist necessarily is not 0. Why?
+        // Because this clause is only hit when remainingDist < curIntervalDist,
+        // and if curIntervalDist were 0, that would mean remainingDist would
+        // have to be < 0.  But that can't happen, because remainingDist (as
+        // a distance) is non-negative by definition.
+        NS_ASSERTION(curIntervalDists[j] != 0,
+                     "We should never get here with this set to 0...");
 
-      // We found the right spot -- an interpolated position between
-      // values i and i+1.
-      aFrom = &aValues[i];
-      aTo = &aValues[i+1];
-      aIntervalProgress = remainingDists[0] / curIntervalDists[0];
-      return NS_OK;
+        // We found the right spot -- an interpolated position between
+        // values i and i+1.
+        aFrom = &aValues[i];
+        aTo = &aValues[i+1];
+        aIntervalProgress[j] = remainingDists[j] / curIntervalDists[j];
+        return NS_OK;
+      }
     }
   }
 
   NS_NOTREACHED("shouldn't complete loop & get here -- if we do, "
                 "then aSimpleProgress was probably out of bounds");
   return NS_ERROR_FAILURE;
 }
 
--- a/dom/smil/nsSMILAnimationFunction.h
+++ b/dom/smil/nsSMILAnimationFunction.h
@@ -305,17 +305,17 @@ protected:
   virtual nsresult InterpolateResult(const nsSMILValueArray& aValues,
                                      nsSMILValue& aResult,
                                      nsSMILValue& aBaseValue);
   nsresult AccumulateResult(const nsSMILValueArray& aValues,
                             nsSMILValue& aResult);
 
   nsresult ComputePacedPosition(const nsSMILValueArray& aValues,
                                 double aSimpleProgress,
-                                double& aIntervalProgress,
+                                AutoTArray<double, 1>& aIntervalProgress,
                                 const nsSMILValue*& aFrom,
                                 const nsSMILValue*& aTo);
   bool ComputePacedTotalDistances(const nsSMILValueArray& aValues,
                                   AutoTArray<double, 1>& aTotalDistances) const;
 
   /**
    * Adjust the simple progress, that is, the point within the simple duration,
    * by applying any keyTimes.