From f699b8cfb265bdd99bf509bce9bd205ce1923c62 Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Mon, 30 Oct 2017 17:03:03 -0700 Subject: [PATCH] Handle animating 2D matrices --- .../helpers/animated_properties.mako.rs | 37 ++++++++++++++- components/style/values/computed/transform.rs | 46 ++++++++++++++----- 2 files changed, 70 insertions(+), 13 deletions(-) diff --git a/components/style/properties/helpers/animated_properties.mako.rs b/components/style/properties/helpers/animated_properties.mako.rs index 691b57845da..7563dc3979e 100644 --- a/components/style/properties/helpers/animated_properties.mako.rs +++ b/components/style/properties/helpers/animated_properties.mako.rs @@ -44,7 +44,7 @@ use values::computed::{LengthOrPercentageOrNone, MaxLength}; use values::computed::{NonNegativeNumber, Number, NumberOrPercentage, Percentage}; use values::computed::length::NonNegativeLengthOrPercentage; use values::computed::ToComputedValue; -use values::computed::transform::{DirectionVector, Matrix3D}; +use values::computed::transform::{DirectionVector, Matrix, Matrix3D}; use values::generics::transform::{Transform, TransformOperation}; use values::distance::{ComputeSquaredDistance, SquaredDistance}; #[cfg(feature = "gecko")] use values::generics::FontSettings as GenericFontSettings; @@ -1033,7 +1033,14 @@ impl Animate for ComputedTransformOperation { this.animate(other, procedure)?, )) }, - // XXXManishearth handle 2D matrix + ( + &TransformOperation::Matrix(ref this), + &TransformOperation::Matrix(ref other), + ) => { + Ok(TransformOperation::Matrix( + this.animate(other, procedure)?, + )) + }, ( &TransformOperation::Skew(ref fx, ref fy), &TransformOperation::Skew(ref tx, ref ty), @@ -1444,6 +1451,32 @@ impl Animate for Matrix3D { } } +impl Animate for Matrix { + #[cfg(feature = "servo")] + fn animate(&self, other: &Self, procedure: Procedure) -> Result { + let this = Matrix3D::from(*self); + let other = Matrix3D::from(*other); + let this = MatrixDecomposed2D::from(this); + let other = MatrixDecomposed2D::from(other); + Ok(Matrix3D::from(this.animate(&other, procedure)?).into_2d()?) + } + + #[cfg(feature = "gecko")] + fn animate(&self, other: &Self, procedure: Procedure) -> Result { + let from = decompose_2d_matrix(&(*self).into()); + let to = decompose_2d_matrix(&(*other).into()); + match (from, to) { + (Ok(from), Ok(to)) => { + Matrix3D::from(from.animate(&to, procedure)?).into_2d() + }, + // Matrices can be undecomposable due to couple reasons, e.g., + // non-invertible matrices. In this case, we should report Err here, + // and let the caller do the fallback procedure. + _ => Err(()) + } + } +} + impl ComputeSquaredDistance for Matrix3D { #[inline] #[cfg(feature = "servo")] diff --git a/components/style/values/computed/transform.rs b/components/style/values/computed/transform.rs index 4c90a01b3d1..4c909a53585 100644 --- a/components/style/values/computed/transform.rs +++ b/components/style/values/computed/transform.rs @@ -63,6 +63,22 @@ impl Matrix3D { m41: 0., m42: 0., m43: 0., m44: 1.0 } } + + /// Convert to a 2D Matrix + pub fn into_2d(self) -> Result { + if self.m13 == 0. && self.m23 == 0. && + self.m31 == 0. && self.m32 == 0. && + self.m33 == 1. && self.m34 == 0. && + self.m14 == 0. && self.m24 == 0. && + self.m43 == 0. && self.m44 == 1. { + Ok(Matrix { + a: self.m11, c: self.m21, e: self.m41, + b: self.m12, d: self.m22, f: self.m42, + }) + } else { + Err(()) + } + } } impl PrefixedMatrix3D { @@ -84,10 +100,21 @@ impl Matrix { /// Get an identity matrix pub fn identity() -> Self { Self { - a: 1., c: 0., /* 0 */e: 0., - b: 0., d: 1., /* 0 */f: 0., + a: 1., c: 0., /* 0 0*/ + b: 0., d: 1., /* 0 0*/ /* 0 0 1 0 */ - /* 0 0 0 1 */ + e: 0., f: 0., /* 0 1 */ + } + } +} + +impl From for Matrix3D { + fn from(m: Matrix) -> Self { + Self { + m11: m.a, m12: m.b, m13: 0.0, m14: 0.0, + m21: m.c, m22: m.d, m23: 0.0, m24: 0.0, + m31: 0.0, m32: 0.0, m33: 1.0, m34: 0.0, + m41: m.e, m42: m.f, m43: 0.0, m44: 1.0 } } } @@ -97,10 +124,10 @@ impl PrefixedMatrix { /// Get an identity matrix pub fn identity() -> Self { Self { - a: 1., c: 0., /* 0 */e: Either::First(0.), - b: 0., d: 1., /* 0 */f: Either::First(0.), - /* 0 0 1 0 */ - /* 0 0 0 1 */ + a: 1., c: 0., /* 0 0 */ + b: 0., d: 1., /* 0 0 */ + /* 0 0 1 0 */ + e: Either::First(0.), f: Either::First(0.), /* 0 1 */ } } } @@ -240,10 +267,7 @@ impl ToAnimatedZero for TransformOperation { GenericTransformOperation::Scale3D(..) => { Ok(GenericTransformOperation::Scale3D(1.0, 1.0, 1.0)) }, - GenericTransformOperation::Scale(_, None) => { - Ok(GenericTransformOperation::Scale(1.0, None)) - }, - GenericTransformOperation::Scale(_, Some(_)) => { + GenericTransformOperation::Scale(_, _) => { Ok(GenericTransformOperation::Scale(1.0, Some(1.0))) }, GenericTransformOperation::ScaleX(..) => {