Bug 1272549 - Part 4: Compute distance for none and a valid transform list. draft
authorBoris Chiou <boris.chiou@gmail.com>
Mon, 03 Oct 2016 17:43:20 +0800
changeset 428937 8b8a31b7c1dacda89ecf50117da417181c3f3b61
parent 426879 a5aaad05970d4e714e1ea28f1079d24462cbe924
child 428938 a77ab9f5d0e076783bb0b1cff449e8f5e28a2aad
push id33433
push userbmo:boris.chiou@gmail.com
push dateMon, 24 Oct 2016 19:01:16 +0000
bugs1272549
milestone52.0a1
Bug 1272549 - Part 4: Compute distance for none and a valid transform list. Reuse AddTransformLists to get the identity transform functions to replace none, and then treat them with another transform list as two matched ones. MozReview-Commit-ID: HwdBPCiUivg
layout/style/StyleAnimationValue.cpp
layout/style/nsStyleTransformMatrix.cpp
layout/style/nsStyleTransformMatrix.h
--- a/layout/style/StyleAnimationValue.cpp
+++ b/layout/style/StyleAnimationValue.cpp
@@ -713,16 +713,20 @@ StyleAnimationValue::ComputeColorDistanc
 
   double diffA = startA - endA;
   double diffR = startR - endR;
   double diffG = startG - endG;
   double diffB = startB - endB;
   return sqrt(diffA * diffA + diffR * diffR + diffG * diffG + diffB * diffB);
 }
 
+static nsCSSValueList*
+AddTransformLists(double aCoeff1, const nsCSSValueList* aList1,
+                  double aCoeff2, const nsCSSValueList* aList2);
+
 static double
 ComputeTransformDistance(nsCSSValue::Array* aArray1,
                          nsCSSValue::Array* aArray2)
 {
   MOZ_ASSERT(aArray1, "aArray1 should be non-null.");
   MOZ_ASSERT(aArray2, "aArray2 should be non-null.");
 
   // Normalize translate and scale functions to equivalent "translate3d" and
@@ -1251,23 +1255,21 @@ StyleAnimationValue::ComputeDistance(nsC
       MOZ_ASSERT(list1);
       MOZ_ASSERT(list2);
 
       if (list1->mValue.GetUnit() == eCSSUnit_None &&
           list2->mValue.GetUnit() == eCSSUnit_None) {
         // Both none, nothing happens.
         aDistance = 0.0;
       } else if (list1->mValue.GetUnit() == eCSSUnit_None) {
-        // TODO: Implement none transform list in the later patch.
-        aDistance = 0.0;
-        return false;
+        nsAutoPtr<nsCSSValueList> none(AddTransformLists(0, list2, 0, list2));
+        aDistance = ComputeTransformListDistance(none, list2);
       } else if (list2->mValue.GetUnit() == eCSSUnit_None) {
-        // TODO: Implement none transform list in the later patch.
-        aDistance = 0.0;
-        return false;
+        nsAutoPtr<nsCSSValueList> none(AddTransformLists(0, list1, 0, list1));
+        aDistance = ComputeTransformListDistance(list1, none);
       } else {
         const nsCSSValueList *item1 = list1, *item2 = list2;
         do {
           nsCSSKeyword func1 = nsStyleTransformMatrix::TransformFunctionOf(
             item1->mValue.GetArrayValue());
           nsCSSKeyword func2 = nsStyleTransformMatrix::TransformFunctionOf(
             item2->mValue.GetArrayValue());
           if (!TransformFunctionsMatch(func1, func2)) {
@@ -2509,18 +2511,39 @@ AddTransformLists(double aCoeff1, const 
           AddCSSValueAngle(aCoeff1, a1->Item(4), aCoeff2, a2->Item(4),
                            arr->Item(4));
           break;
         }
         MOZ_FALLTHROUGH;
       }
       case eCSSKeyword_matrix:
       case eCSSKeyword_matrix3d:
-      case eCSSKeyword_interpolatematrix:
-      case eCSSKeyword_perspective: {
+      case eCSSKeyword_perspective:
+        if (aCoeff1 == 0.0 && aCoeff2 == 0.0) {
+          // Special case. If both coefficients are 0.0, we should apply an
+          // identity transform function.
+          arr = StyleAnimationValue::AppendTransformFunction(tfunc, resultTail);
+
+          if (tfunc == eCSSKeyword_rotate3d) {
+            arr->Item(1).SetFloatValue(0.0, eCSSUnit_Number);
+            arr->Item(2).SetFloatValue(0.0, eCSSUnit_Number);
+            arr->Item(3).SetFloatValue(1.0, eCSSUnit_Number);
+            arr->Item(4).SetFloatValue(0.0, eCSSUnit_Radian);
+          } else if (tfunc == eCSSKeyword_perspective) {
+            // The parameter of the identity perspective function is
+            // positive infinite.
+            arr->Item(1).SetFloatValue(std::numeric_limits<float>::infinity(),
+                                       eCSSUnit_Pixel);
+          } else {
+            nsStyleTransformMatrix::SetIdentityMatrix(arr);
+          }
+          break;
+        }
+        MOZ_FALLTHROUGH;
+      case eCSSKeyword_interpolatematrix: {
         // FIXME: If the matrix contains only numbers then we could decompose
         // here.
 
         // Construct temporary lists with only this item in them.
         nsCSSValueList tempList1, tempList2;
         tempList1.mValue = aList1->mValue;
         tempList2.mValue = aList2->mValue;
 
--- a/layout/style/nsStyleTransformMatrix.cpp
+++ b/layout/style/nsStyleTransformMatrix.cpp
@@ -680,16 +680,42 @@ MatrixForTransformFunction(Matrix4x4& aM
  */
 nsCSSKeyword
 TransformFunctionOf(const nsCSSValue::Array* aData)
 {
   MOZ_ASSERT(aData->Item(0).GetUnit() == eCSSUnit_Enumerated);
   return aData->Item(0).GetKeywordValue();
 }
 
+void
+SetIdentityMatrix(nsCSSValue::Array* aMatrix)
+{
+  MOZ_ASSERT(aMatrix, "aMatrix should be non-null");
+
+  nsCSSKeyword tfunc = TransformFunctionOf(aMatrix);
+  MOZ_ASSERT(tfunc == eCSSKeyword_matrix ||
+             tfunc == eCSSKeyword_matrix3d,
+             "Only accept matrix and matrix3d");
+
+  if (tfunc == eCSSKeyword_matrix) {
+    MOZ_ASSERT(aMatrix->Count() == 7, "Invalid matrix");
+    Matrix m;
+    for (size_t i = 0; i < 6; ++i) {
+      aMatrix->Item(i + 1).SetFloatValue(m.components[i], eCSSUnit_Number);
+    }
+    return;
+  }
+
+  MOZ_ASSERT(aMatrix->Count() == 17, "Invalid matrix3d");
+  Matrix4x4 m;
+  for (size_t i = 0; i < 16; ++i) {
+    aMatrix->Item(i + 1).SetFloatValue(m.components[i], eCSSUnit_Number);
+  }
+}
+
 Matrix4x4
 ReadTransforms(const nsCSSValueList* aList,
                nsStyleContext* aContext,
                nsPresContext* aPresContext,
                RuleNodeCacheConditions& aConditions,
                TransformReferenceBox& aRefBox,
                float aAppUnitsPerMatrixUnit,
                bool* aContains3dTransform)
--- a/layout/style/nsStyleTransformMatrix.h
+++ b/layout/style/nsStyleTransformMatrix.h
@@ -122,16 +122,18 @@ namespace nsStyleTransformMatrix {
   };
 
   /**
    * Return the transform function, as an nsCSSKeyword, for the given
    * nsCSSValue::Array from a transform list.
    */
   nsCSSKeyword TransformFunctionOf(const nsCSSValue::Array* aData);
 
+  void SetIdentityMatrix(nsCSSValue::Array* aMatrix);
+
   float ProcessTranslatePart(const nsCSSValue& aValue,
                              nsStyleContext* aContext,
                              nsPresContext* aPresContext,
                              mozilla::RuleNodeCacheConditions& aConditions,
                              TransformReferenceBox* aRefBox,
                              TransformReferenceBox::DimensionGetter aDimensionGetter = nullptr);
 
   void