Bug 1286151 - Part 2: Implement filter distance for drop-shadow. r=hiro
authorBoris Chiou <boris.chiou@gmail.com>
Thu, 10 Nov 2016 17:46:35 +0800
changeset 323441 38140192cbc9f666dcc3ce101fd88ed99389eace
parent 323440 46dbee3c3988f5bf3ccf8d1a997241671362eb8b
child 323442 74f17142693ec860f9066786a427872800a4a90c
push id21
push usermaklebus@msu.edu
push dateThu, 01 Dec 2016 06:22:08 +0000
reviewershiro
bugs1286151
milestone53.0a1
Bug 1286151 - Part 2: Implement filter distance for drop-shadow. r=hiro MozReview-Commit-ID: 5Ad0GiWGkJg
layout/style/StyleAnimationValue.cpp
--- a/layout/style/StyleAnimationValue.cpp
+++ b/layout/style/StyleAnimationValue.cpp
@@ -806,19 +806,64 @@ ComputeFilterSquareDistance(const nsCSSV
     case eCSSKeyword_contrast:
     case eCSSKeyword_opacity:
     case eCSSKeyword_saturate:
       // TODO
       break;
     case eCSSKeyword_hue_rotate:
       // TODO
       break;
-    case eCSSKeyword_drop_shadow:
-      // TODO
+    case eCSSKeyword_drop_shadow: {
+      MOZ_ASSERT(!func1.GetListValue()->mNext && !func2.GetListValue()->mNext,
+                 "drop-shadow filter func doesn't support lists");
+      const nsCSSValue& shadow1 = func1.GetListValue()->mValue;
+      const nsCSSValue& shadow2 = func2.GetListValue()->mValue;
+
+      MOZ_ASSERT(shadow1.GetUnit() == eCSSUnit_Array, "wrong unit");
+      MOZ_ASSERT(shadow2.GetUnit() == eCSSUnit_Array, "wrong unit");
+      const nsCSSValue::Array* array1 = shadow1.GetArrayValue();
+      const nsCSSValue::Array* array2 = shadow2.GetArrayValue();
+      double squareDistance = 0.0;
+
+      // X, Y, Radius, Spread
+      for (size_t i = 0; i < 4; ++i) {
+        MOZ_ASSERT(array1->Item(i).GetUnit() == eCSSUnit_Pixel,
+                   "unexpected unit");
+        MOZ_ASSERT(array2->Item(i).GetUnit() == eCSSUnit_Pixel,
+                   "unexpected unit");
+        double diff = array1->Item(i).GetFloatValue() -
+                      array2->Item(i).GetFloatValue();
+        squareDistance += diff * diff;
+      }
+
+      // Color, Inset
+      const nsCSSValue& colorValue1 = array1->Item(4);
+      const nsCSSValue& colorValue2 = array2->Item(4);
+      const nsCSSValue& inset1 = array1->Item(5);
+      const nsCSSValue& inset2 = array2->Item(5);
+      if ((colorValue1.GetUnit() != colorValue2.GetUnit() &&
+            (!colorValue1.IsNumericColorUnit() ||
+             !colorValue2.IsNumericColorUnit())) ||
+          inset1.GetUnit() != inset2.GetUnit()) {
+        // We don't know how to animate between color and no-color, or
+        // between inset and not-inset.
+        // NOTE: In case when both colors' units are eCSSUnit_Null, that means
+        // neither color value was specified, so we can interpolate.
+        return false;
+      }
+
+      if (colorValue1.GetUnit() != eCSSUnit_Null) {
+        double diff =
+          StyleAnimationValue::ComputeColorDistance(ExtractColor(colorValue1),
+                                                    ExtractColor(colorValue2));
+        squareDistance += diff * diff;
+      }
+      aSquareDistance = squareDistance;
       break;
+    }
     default:
       MOZ_ASSERT_UNREACHABLE("unknown filter function");
       return false;
   }
   return true;
 }
 
 static bool