Bug 1362897 - Add compute distance for Filter. r?boris draft
authorMantaroh Yoshinaga <mantaroh@gmail.com>
Mon, 12 Jun 2017 15:59:14 +0900
changeset 592390 f64277218f457094fabf1dcb30f497950fe085d6
parent 592389 1b1ba5e6f3caa241417f1d23d718c150a501a79c
child 592391 4ca2868a6d764d2c21313b496b6461c2ce51733b
push id63367
push usermantaroh@gmail.com
push dateMon, 12 Jun 2017 06:59:45 +0000
reviewersboris
bugs1362897
milestone55.0a1
Bug 1362897 - Add compute distance for Filter. r?boris MozReview-Commit-ID: 81Z1yJbENeR
servo/components/style/properties/helpers/animated_properties.mako.rs
--- a/servo/components/style/properties/helpers/animated_properties.mako.rs
+++ b/servo/components/style/properties/helpers/animated_properties.mako.rs
@@ -3302,16 +3302,37 @@ fn add_weighted_filter_function(from: Op
         },
         (None, Some(t)) => {
             add_weighted_filter_function_impl(t, t, other_portion, 0.0)
         },
         _ => { Err(()) }
     }
 }
 
+fn compute_filter_square_distance(from: &IntermediateFilter,
+                                  to: &IntermediateFilter)
+                                  -> Result<f64, ()> {
+    match (from, to) {
+        % for func in FILTER_FUNCTIONS :
+            (&IntermediateFilter::${func}(f),
+             &IntermediateFilter::${func}(t)) => {
+                Ok(try!(f.compute_squared_distance(&t)))
+            },
+        % endfor
+        % if product == "gecko":
+            (&IntermediateFilter::DropShadow(f),
+             &IntermediateFilter::DropShadow(t)) => {
+                Ok(try!(f.compute_squared_distance(&t)))
+            },
+        % endif
+        _ => {
+            Err(())
+        }
+    }
+}
 
 impl Animatable for IntermediateFilters {
     #[inline]
     fn add_weighted(&self, other: &Self,
                     self_portion: f64, other_portion: f64) -> Result<Self, ()> {
         let mut filters: IntermediateFilters = Vec::new();
         let mut from_iter = self.iter();
         let mut to_iter = (&other).iter();
@@ -3336,9 +3357,49 @@ impl Animatable for IntermediateFilters 
 
     fn add(&self, other: &Self) -> Result<Self, ()> {
         let from_list = &self;
         let to_list = &other;
         let filters: IntermediateFilters =
             vec![&from_list[..], &to_list[..]].concat();
         Ok(filters)
     }
+
+    #[inline]
+    fn compute_distance(&self, other: &Self) -> Result<f64, ()> {
+        self.compute_squared_distance(other).map(|sd| sd.sqrt())
+    }
+
+    #[inline]
+    fn compute_squared_distance(&self, other: &Self) -> Result<f64, ()> {
+        let mut square_distance: f64 = 0.0;
+        let mut from_iter = self.iter();
+        let mut to_iter = (&other).iter();
+
+        let mut from = from_iter.next();
+        let mut to = to_iter.next();
+        while (from,to) != (None, None) {
+            let current_square_distance: f64 ;
+            if from == None {
+                let none = try!(add_weighted_filter_function(to, to, 0.0, 0.0));
+                current_square_distance =
+                    compute_filter_square_distance(&none, &(to.unwrap())).unwrap();
+
+                to = to_iter.next();
+            } else if to == None {
+                let none = try!(add_weighted_filter_function(from, from, 0.0, 0.0));
+                current_square_distance =
+                    compute_filter_square_distance(&none, &(from.unwrap())).unwrap();
+
+                from = from_iter.next();
+            } else {
+                current_square_distance =
+                    compute_filter_square_distance(&(from.unwrap()),
+                                                   &(to.unwrap())).unwrap();
+
+                from = from_iter.next();
+                to = to_iter.next();
+            }
+            square_distance += current_square_distance;
+        }
+        Ok(square_distance.sqrt())
+    }
 }