From 7f3b23126a5e0d0d1f058162ca442e9567926f50 Mon Sep 17 00:00:00 2001 From: Boris Chiou Date: Fri, 16 Nov 2018 18:58:41 +0000 Subject: [PATCH] style: Implement ComputeSquaredDistance for individual transforms. We manually implement ComputeSquaredDistance for Translate, Rotate, and Scale because we have to handle mismatch cases, and actually we don't need to implement it for specified types. Differential Revision: https://phabricator.services.mozilla.com/D11935 --- components/style/values/animated/transform.rs | 84 +++++++++++++++---- components/style/values/generics/transform.rs | 3 - 2 files changed, 70 insertions(+), 17 deletions(-) diff --git a/components/style/values/animated/transform.rs b/components/style/values/animated/transform.rs index 7d0c0e94ff38..7cd2b32e61eb 100644 --- a/components/style/values/animated/transform.rs +++ b/components/style/values/animated/transform.rs @@ -1309,19 +1309,8 @@ impl ComputeSquaredDistance for ComputedTransformOperation { &TransformOperation::Rotate3D(fx, fy, fz, fa), &TransformOperation::Rotate3D(tx, ty, tz, ta), ) => { - let (fx, fy, fz, angle1) = - transform::get_normalized_vector_and_angle(fx, fy, fz, fa); - let (tx, ty, tz, angle2) = - transform::get_normalized_vector_and_angle(tx, ty, tz, ta); - if (fx, fy, fz) == (tx, ty, tz) { - angle1.compute_squared_distance(&angle2) - } else { - let v1 = DirectionVector::new(fx, fy, fz); - let v2 = DirectionVector::new(tx, ty, tz); - let q1 = Quaternion::from_direction_and_angle(&v1, angle1.radians64()); - let q2 = Quaternion::from_direction_and_angle(&v2, angle2.radians64()); - q1.compute_squared_distance(&q2) - } + Rotate::Rotate3D(fx, fy, fz, fa) + .compute_squared_distance(&Rotate::Rotate3D(tx, ty, tz, ta)) }, ( &TransformOperation::RotateX(fa), @@ -1390,7 +1379,7 @@ impl ComputedRotate { // // If the axis is unspecified, it defaults to "0 0 1" match *self { - Rotate::None => unreachable!("None is handled by the caller"), + Rotate::None => (0., 0., 1., Angle::zero()), Rotate::Rotate3D(rx, ry, rz, angle) => (rx, ry, rz, angle), Rotate::Rotate(angle) => (0., 0., 1., angle), } @@ -1459,6 +1448,49 @@ impl Animate for ComputedRotate { } } +impl ComputeSquaredDistance for ComputedRotate { + #[inline] + fn compute_squared_distance(&self, other: &Self) -> Result { + match (self, other) { + (&Rotate::None, &Rotate::None) => Ok(SquaredDistance::from_sqrt(0.)), + (&Rotate::Rotate3D(_, _, _, a), &Rotate::None) | + (&Rotate::None, &Rotate::Rotate3D(_, _, _, a)) => { + a.compute_squared_distance(&Angle::zero()) + }, + (&Rotate::Rotate3D(_, ..), _) | (_, &Rotate::Rotate3D(_, ..)) => { + let (from, to) = (self.resolve(), other.resolve()); + let (mut fx, mut fy, mut fz, angle1) = + transform::get_normalized_vector_and_angle(from.0, from.1, from.2, from.3); + let (mut tx, mut ty, mut tz, angle2) = + transform::get_normalized_vector_and_angle(to.0, to.1, to.2, to.3); + + if angle1 == Angle::zero() { + fx = tx; + fy = ty; + fz = tz; + } else if angle2 == Angle::zero() { + tx = fx; + ty = fy; + tz = fz; + } + + if (fx, fy, fz) == (tx, ty, tz) { + angle1.compute_squared_distance(&angle2) + } else { + let v1 = DirectionVector::new(fx, fy, fz); + let v2 = DirectionVector::new(tx, ty, tz); + let q1 = Quaternion::from_direction_and_angle(&v1, angle1.radians64()); + let q2 = Quaternion::from_direction_and_angle(&v2, angle2.radians64()); + q1.compute_squared_distance(&q2) + } + }, + (&Rotate::Rotate(_), _) | (_, &Rotate::Rotate(_)) => { + self.resolve().3.compute_squared_distance(&other.resolve().3) + }, + } + } +} + /// impl ComputedTranslate { fn resolve(&self) -> (LengthOrPercentage, LengthOrPercentage, Length) { @@ -1500,6 +1532,18 @@ impl Animate for ComputedTranslate { } } +impl ComputeSquaredDistance for ComputedTranslate { + #[inline] + fn compute_squared_distance(&self, other: &Self) -> Result { + let (from, to) = (self.resolve(), other.resolve()); + Ok( + from.0.compute_squared_distance(&to.0)? + + from.1.compute_squared_distance(&to.1)? + + from.2.compute_squared_distance(&to.2)? + ) + } +} + /// impl ComputedScale { fn resolve(&self) -> (Number, Number, Number) { @@ -1554,3 +1598,15 @@ impl Animate for ComputedScale { } } } + +impl ComputeSquaredDistance for ComputedScale { + #[inline] + fn compute_squared_distance(&self, other: &Self) -> Result { + let (from, to) = (self.resolve(), other.resolve()); + Ok( + from.0.compute_squared_distance(&to.0)? + + from.1.compute_squared_distance(&to.1)? + + from.2.compute_squared_distance(&to.2)? + ) + } +} diff --git a/components/style/values/generics/transform.rs b/components/style/values/generics/transform.rs index 0cf8f490bb3b..09f95cd58a20 100644 --- a/components/style/values/generics/transform.rs +++ b/components/style/values/generics/transform.rs @@ -530,7 +530,6 @@ pub fn get_normalized_vector_and_angle( #[derive( Clone, - ComputeSquaredDistance, Copy, Debug, MallocSizeOf, @@ -600,7 +599,6 @@ where #[derive( Clone, - ComputeSquaredDistance, Copy, Debug, MallocSizeOf, @@ -649,7 +647,6 @@ impl ToCss for Scale { #[derive( Clone, - ComputeSquaredDistance, Debug, MallocSizeOf, PartialEq,