--- a/servo/components/style/properties/helpers/animated_properties.mako.rs
+++ b/servo/components/style/properties/helpers/animated_properties.mako.rs
@@ -41,17 +41,20 @@ use values::computed::{ClipRect, Context
use values::computed::{Length, LengthOrPercentage, LengthOrPercentageOrAuto};
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, Matrix, Matrix3D};
use values::computed::transform::TransformOperation as ComputedTransformOperation;
use values::computed::transform::Transform as ComputedTransform;
-use values::generics::transform::{self, Transform, TransformOperation};
+use values::computed::transform::Rotate as ComputedRotate;
+use values::computed::transform::Translate as ComputedTranslate;
+use values::computed::transform::Scale as ComputedScale;
+use values::generics::transform::{self, Transform, TransformOperation, Translate, Scale, Rotate};
use values::distance::{ComputeSquaredDistance, SquaredDistance};
#[cfg(feature = "gecko")] use values::generics::FontSettings as GenericFontSettings;
#[cfg(feature = "gecko")] use values::generics::FontSettingTag as GenericFontSettingTag;
#[cfg(feature = "gecko")] use values::generics::FontSettingTagFloat;
use values::generics::NonNegative;
use values::generics::effects::Filter;
use values::generics::position as generic_position;
use values::generics::svg::{SVGLength, SvgLengthOrPercentageOrNumber, SVGPaint};
@@ -2277,16 +2280,133 @@ impl Matrix3D {
self.m12*self.m21*self.m33 + self.m11*self.m22*self.m33),
};
Some(x)
}
}
/// <https://drafts.csswg.org/css-transforms/#interpolation-of-transforms>
+impl ComputedRotate {
+ fn fill_unspecified(rotate: &ComputedRotate)
+ -> Result<(Number, Number, Number, Angle), ()>{
+ // According to the spec:
+ // https://drafts.csswg.org/css-transforms-2/#individual-transforms
+ //
+ // If the axis is unspecified, it defaults to "0 0 1"
+ match rotate {
+ &Rotate::None =>
+ Ok((0., 0., 1., Angle::zero())),
+ &Rotate::Specified(None, angle) =>
+ Ok((0., 0., 1., angle)),
+ &Rotate::Specified(Some((rx, ry, rz)), angle) =>
+ Ok((rx, ry, rz, angle)),
+ }
+ }
+}
+
+impl Animate for ComputedRotate {
+ #[inline]
+ fn animate(
+ &self,
+ other: &Self,
+ procedure: Procedure,
+ ) -> Result<Self, ()> {
+ let from = ComputedRotate::fill_unspecified(self)?;
+ let to = ComputedRotate::fill_unspecified(other)?;
+
+ Ok(Rotate::Specified(Some((from.0.animate(&to.0, procedure)?,
+ from.1.animate(&to.1, procedure)?,
+ from.2.animate(&to.2, procedure)?)),
+ from.3.animate(&to.3, procedure)?))
+ }
+}
+
+impl ComputedTranslate {
+ fn fill_unspecified(translate: &ComputedTranslate)
+ -> Result<(LengthOrPercentage, LengthOrPercentage, Length), ()>{
+ // According to the spec:
+ // https://drafts.csswg.org/css-transforms-2/#individual-transforms
+ //
+ // Unspecified translations default to 0px
+ match translate {
+ &Translate::None => {
+ Ok((LengthOrPercentage::Length(Length::zero()),
+ LengthOrPercentage::Length(Length::zero()),
+ Length::zero()))
+ },
+ &Translate::Specified(tx, None, None) => {
+ Ok((tx, LengthOrPercentage::Length(Length::zero()),
+ Length::zero()))
+ },
+ &Translate::Specified(tx, Some(ty), None) =>
+ Ok((tx, ty, Length::zero())),
+ &Translate::Specified(tx, Some(ty), Some(tz)) =>
+ Ok((tx, ty, tz)),
+ _ =>
+ panic!("Found unexpected value for translate property: {:?}", translate),
+ }
+ }
+}
+
+impl Animate for ComputedTranslate {
+ #[inline]
+ fn animate(
+ &self,
+ other: &Self,
+ procedure: Procedure,
+ ) -> Result<Self, ()> {
+ let from = ComputedTranslate::fill_unspecified(self)?;
+ let to = ComputedTranslate::fill_unspecified(other)?;
+
+ Ok(Translate::Specified(from.0.animate(&to.0, procedure)?,
+ Some(from.1.animate(&to.1, procedure)?),
+ Some(from.2.animate(&to.2, procedure)?)))
+ }
+}
+
+impl ComputedScale {
+ fn fill_unspecified(scale: &ComputedScale)
+ -> Result<(Number, Number, Number), ()>{
+ // According to the spec:
+ // https://drafts.csswg.org/css-transforms-2/#individual-transforms
+ //
+ // Unspecified scales default to 1
+ match scale {
+ &Scale::None =>
+ Ok((1.0, 1.0, 1.0)),
+ &Scale::Specified(sx, None, None) =>
+ Ok((sx, 1.0, 1.0)),
+ &Scale::Specified(sx, Some(sy), None) =>
+ Ok((sx, sy, 1.0)),
+ &Scale::Specified(sx, Some(sy), Some(sz)) =>
+ Ok((sx, sy, sz)),
+ _ =>
+ panic!("Found unexpected value for scale property: {:?}", scale),
+ }
+ }
+}
+
+impl Animate for ComputedScale {
+ #[inline]
+ fn animate(
+ &self,
+ other: &Self,
+ procedure: Procedure,
+ ) -> Result<Self, ()> {
+ let from = ComputedScale::fill_unspecified(self)?;
+ let to = ComputedScale::fill_unspecified(other)?;
+
+ Ok(Scale::Specified(animate_multiplicative_factor(from.0, to.0, procedure)?,
+ Some(animate_multiplicative_factor(from.1, to.1, procedure)?),
+ Some(animate_multiplicative_factor(from.2, to.2, procedure)?)))
+ }
+}
+
+/// <https://drafts.csswg.org/css-transforms/#interpolation-of-transforms>
impl Animate for ComputedTransform {
#[inline]
fn animate(
&self,
other_: &Self,
procedure: Procedure,
) -> Result<Self, ()> {
--- a/servo/components/style/values/generics/transform.rs
+++ b/servo/components/style/values/generics/transform.rs
@@ -751,41 +751,41 @@ pub fn get_normalized_vector_and_angle<T
// rotation to not be applied, so we use identity matrix (i.e. rotate3d(0, 0, 1, 0)).
(0., 0., 1., T::zero())
} else {
let vector = vector.normalize();
(vector.x, vector.y, vector.z, angle)
}
}
-#[derive(ToComputedValue, Animate, ComputeSquaredDistance, ToAnimatedZero)]
+#[derive(ToComputedValue, ComputeSquaredDistance, ToAnimatedZero)]
#[derive(Clone, Debug, MallocSizeOf, PartialEq, ToCss)]
/// A value of the `Rotate` property
///
/// <https://drafts.csswg.org/css-transforms-2/#individual-transforms>
pub enum Rotate<Number, Angle> {
/// 'none'
None,
/// '<number>{3}? <angle>'
Specified(Option<(Number, Number, Number)>, Angle)
}
-#[derive(ToComputedValue, Animate, ComputeSquaredDistance, ToAnimatedZero)]
+#[derive(ToComputedValue, ComputeSquaredDistance, ToAnimatedZero)]
#[derive(Clone, Debug, MallocSizeOf, PartialEq, ToCss)]
/// A value of the `Translate` property
///
/// <https://drafts.csswg.org/css-transforms-2/#individual-transforms>
pub enum Translate<LengthOrPercentage, Length> {
/// 'none'
None,
/// '<length-percentage> [ <length-percentage> <length>? ]?'
Specified(LengthOrPercentage, Option<LengthOrPercentage>, Option<Length>)
}
-#[derive(ToComputedValue, Animate, ComputeSquaredDistance, ToAnimatedZero)]
+#[derive(ToComputedValue, ComputeSquaredDistance, ToAnimatedZero)]
#[derive(Clone, Debug, MallocSizeOf, PartialEq, ToCss)]
/// A value of the `Scale` property
///
/// <https://drafts.csswg.org/css-transforms-2/#individual-transforms>
pub enum Scale<Number> {
/// 'none'
None,
/// '<number>{1,3}'