Make transform property animatable.

This just changes animatable to True, drops 'if product == "servo" block
, fixes indentations and moves 'use' declarations at the top of the file.

MozReview-Commit-ID: A96oxYXmknV
This commit is contained in:
Hiroyuki Ikezoe 2017-02-03 13:52:22 +09:00
parent 10b6c1bb4f
commit 22ff72dfc0
2 changed files with 860 additions and 864 deletions

View file

@ -19,6 +19,9 @@ use properties::longhands::text_shadow::computed_value::T as TextShadowList;
use properties::longhands::text_shadow::computed_value::TextShadow; use properties::longhands::text_shadow::computed_value::TextShadow;
use properties::longhands::box_shadow::computed_value::T as BoxShadowList; use properties::longhands::box_shadow::computed_value::T as BoxShadowList;
use properties::longhands::box_shadow::single_value::computed_value::T as BoxShadow; use properties::longhands::box_shadow::single_value::computed_value::T as BoxShadow;
use properties::longhands::transform::computed_value::ComputedMatrix;
use properties::longhands::transform::computed_value::ComputedOperation as TransformOperation;
use properties::longhands::transform::computed_value::T as TransformList;
use properties::longhands::vertical_align::computed_value::T as VerticalAlign; use properties::longhands::vertical_align::computed_value::T as VerticalAlign;
use properties::longhands::visibility::computed_value::T as Visibility; use properties::longhands::visibility::computed_value::T as Visibility;
use properties::longhands::z_index::computed_value::T as ZIndex; use properties::longhands::z_index::computed_value::T as ZIndex;
@ -27,12 +30,14 @@ use std::cmp;
use std::fmt; use std::fmt;
use style_traits::ToCss; use style_traits::ToCss;
use super::ComputedValues; use super::ComputedValues;
use values::CSSFloat;
use values::Either; use values::Either;
use values::computed::{Angle, LengthOrPercentageOrAuto, LengthOrPercentageOrNone}; use values::computed::{Angle, LengthOrPercentageOrAuto, LengthOrPercentageOrNone};
use values::computed::{BorderRadiusSize, LengthOrNone}; use values::computed::{BorderRadiusSize, LengthOrNone};
use values::computed::{CalcLengthOrPercentage, Context, LengthOrPercentage}; use values::computed::{CalcLengthOrPercentage, Context, LengthOrPercentage};
use values::computed::position::{HorizontalPosition, Position, VerticalPosition}; use values::computed::position::{HorizontalPosition, Position, VerticalPosition};
use values::computed::ToComputedValue; use values::computed::ToComputedValue;
use values::specified::Angle as SpecifiedAngle;
@ -852,17 +857,10 @@ impl Interpolate for LengthOrNone {
} }
} }
% if product == "servo": /// Check if it's possible to do a direct numerical interpolation
use properties::longhands::transform::computed_value::ComputedMatrix; /// between these two transform lists.
use properties::longhands::transform::computed_value::ComputedOperation as TransformOperation; /// http://dev.w3.org/csswg/css-transforms/#transform-transform-animation
use properties::longhands::transform::computed_value::T as TransformList; fn can_interpolate_list(from_list: &[TransformOperation],
use values::CSSFloat;
use values::specified::Angle as SpecifiedAngle;
/// Check if it's possible to do a direct numerical interpolation
/// between these two transform lists.
/// http://dev.w3.org/csswg/css-transforms/#transform-transform-animation
fn can_interpolate_list(from_list: &[TransformOperation],
to_list: &[TransformOperation]) -> bool { to_list: &[TransformOperation]) -> bool {
// Lists must be equal length // Lists must be equal length
if from_list.len() != to_list.len() { if from_list.len() != to_list.len() {
@ -885,12 +883,12 @@ impl Interpolate for LengthOrNone {
} }
true true
} }
/// Build an equivalent 'identity transform function list' based /// Build an equivalent 'identity transform function list' based
/// on an existing transform list. /// on an existing transform list.
/// http://dev.w3.org/csswg/css-transforms/#none-transform-animation /// http://dev.w3.org/csswg/css-transforms/#none-transform-animation
fn build_identity_transform_list(list: &[TransformOperation]) -> Vec<TransformOperation> { fn build_identity_transform_list(list: &[TransformOperation]) -> Vec<TransformOperation> {
let mut result = vec!(); let mut result = vec!();
for operation in list { for operation in list {
@ -922,11 +920,11 @@ impl Interpolate for LengthOrNone {
} }
result result
} }
/// Interpolate two transform lists. /// Interpolate two transform lists.
/// http://dev.w3.org/csswg/css-transforms/#interpolation-of-transforms /// http://dev.w3.org/csswg/css-transforms/#interpolation-of-transforms
fn interpolate_transform_list(from_list: &[TransformOperation], fn interpolate_transform_list(from_list: &[TransformOperation],
to_list: &[TransformOperation], to_list: &[TransformOperation],
progress: f64) -> TransformList { progress: f64) -> TransformList {
let mut result = vec![]; let mut result = vec![];
@ -997,10 +995,10 @@ impl Interpolate for LengthOrNone {
} }
TransformList(Some(result)) TransformList(Some(result))
} }
/// https://drafts.csswg.org/css-transforms/#Rotate3dDefined /// https://drafts.csswg.org/css-transforms/#Rotate3dDefined
fn rotate_to_matrix(x: f32, y: f32, z: f32, a: SpecifiedAngle) -> ComputedMatrix { fn rotate_to_matrix(x: f32, y: f32, z: f32, a: SpecifiedAngle) -> ComputedMatrix {
let half_rad = a.radians() / 2.0; let half_rad = a.radians() / 2.0;
let sc = (half_rad).sin() * (half_rad).cos(); let sc = (half_rad).sin() * (half_rad).cos();
let sq = (half_rad).sin().powi(2); let sq = (half_rad).sin().powi(2);
@ -1026,31 +1024,31 @@ impl Interpolate for LengthOrNone {
m43: 0.0, m43: 0.0,
m44: 1.0 m44: 1.0
} }
} }
/// A 2d matrix for interpolation. /// A 2d matrix for interpolation.
#[derive(Clone, Copy, Debug)] #[derive(Clone, Copy, Debug)]
#[cfg_attr(feature = "servo", derive(HeapSizeOf))] #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
#[allow(missing_docs)] #[allow(missing_docs)]
pub struct InnerMatrix2D { pub struct InnerMatrix2D {
pub m11: CSSFloat, pub m12: CSSFloat, pub m11: CSSFloat, pub m12: CSSFloat,
pub m21: CSSFloat, pub m22: CSSFloat, pub m21: CSSFloat, pub m22: CSSFloat,
} }
/// A 2d translation function. /// A 2d translation function.
#[derive(Clone, Copy, Debug)] #[derive(Clone, Copy, Debug)]
#[cfg_attr(feature = "servo", derive(HeapSizeOf))] #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
pub struct Translate2D(f32, f32); pub struct Translate2D(f32, f32);
/// A 2d scale function. /// A 2d scale function.
#[derive(Clone, Copy, Debug)] #[derive(Clone, Copy, Debug)]
#[cfg_attr(feature = "servo", derive(HeapSizeOf))] #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
pub struct Scale2D(f32, f32); pub struct Scale2D(f32, f32);
/// A decomposed 2d matrix. /// A decomposed 2d matrix.
#[derive(Clone, Copy, Debug)] #[derive(Clone, Copy, Debug)]
#[cfg_attr(feature = "servo", derive(HeapSizeOf))] #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
pub struct MatrixDecomposed2D { pub struct MatrixDecomposed2D {
/// The translation function. /// The translation function.
pub translate: Translate2D, pub translate: Translate2D,
/// The scale function. /// The scale function.
@ -1059,9 +1057,9 @@ impl Interpolate for LengthOrNone {
pub angle: f32, pub angle: f32,
/// The inner matrix. /// The inner matrix.
pub matrix: InnerMatrix2D, pub matrix: InnerMatrix2D,
} }
impl Interpolate for InnerMatrix2D { impl Interpolate for InnerMatrix2D {
fn interpolate(&self, other: &Self, progress: f64) -> Result<Self, ()> { fn interpolate(&self, other: &Self, progress: f64) -> Result<Self, ()> {
Ok(InnerMatrix2D { Ok(InnerMatrix2D {
m11: try!(self.m11.interpolate(&other.m11, progress)), m11: try!(self.m11.interpolate(&other.m11, progress)),
@ -1070,27 +1068,27 @@ impl Interpolate for LengthOrNone {
m22: try!(self.m22.interpolate(&other.m22, progress)), m22: try!(self.m22.interpolate(&other.m22, progress)),
}) })
} }
} }
impl Interpolate for Translate2D { impl Interpolate for Translate2D {
fn interpolate(&self, other: &Self, progress: f64) -> Result<Self, ()> { fn interpolate(&self, other: &Self, progress: f64) -> Result<Self, ()> {
Ok(Translate2D( Ok(Translate2D(
try!(self.0.interpolate(&other.0, progress)), try!(self.0.interpolate(&other.0, progress)),
try!(self.1.interpolate(&other.1, progress)) try!(self.1.interpolate(&other.1, progress))
)) ))
} }
} }
impl Interpolate for Scale2D { impl Interpolate for Scale2D {
fn interpolate(&self, other: &Self, progress: f64) -> Result<Self, ()> { fn interpolate(&self, other: &Self, progress: f64) -> Result<Self, ()> {
Ok(Scale2D( Ok(Scale2D(
try!(self.0.interpolate(&other.0, progress)), try!(self.0.interpolate(&other.0, progress)),
try!(self.1.interpolate(&other.1, progress)) try!(self.1.interpolate(&other.1, progress))
)) ))
} }
} }
impl Interpolate for MatrixDecomposed2D { impl Interpolate for MatrixDecomposed2D {
/// https://drafts.csswg.org/css-transforms/#interpolation-of-decomposed-2d-matrix-values /// https://drafts.csswg.org/css-transforms/#interpolation-of-decomposed-2d-matrix-values
fn interpolate(&self, other: &Self, progress: f64) -> Result<Self, ()> { fn interpolate(&self, other: &Self, progress: f64) -> Result<Self, ()> {
// If x-axis of one is flipped, and y-axis of the other, // If x-axis of one is flipped, and y-axis of the other,
@ -1134,9 +1132,9 @@ impl Interpolate for LengthOrNone {
matrix: matrix, matrix: matrix,
}) })
} }
} }
impl Interpolate for ComputedMatrix { impl Interpolate for ComputedMatrix {
fn interpolate(&self, other: &Self, progress: f64) -> Result<Self, ()> { fn interpolate(&self, other: &Self, progress: f64) -> Result<Self, ()> {
if self.is_3d() || other.is_3d() { if self.is_3d() || other.is_3d() {
let decomposed_from = decompose_3d_matrix(*self); let decomposed_from = decompose_3d_matrix(*self);
@ -1158,9 +1156,9 @@ impl Interpolate for LengthOrNone {
Ok(ComputedMatrix::from(interpolated)) Ok(ComputedMatrix::from(interpolated))
} }
} }
} }
impl From<ComputedMatrix> for MatrixDecomposed2D { impl From<ComputedMatrix> for MatrixDecomposed2D {
/// Decompose a 2D matrix. /// Decompose a 2D matrix.
/// https://drafts.csswg.org/css-transforms/#decomposing-a-2d-matrix /// https://drafts.csswg.org/css-transforms/#decomposing-a-2d-matrix
fn from(matrix: ComputedMatrix) -> MatrixDecomposed2D { fn from(matrix: ComputedMatrix) -> MatrixDecomposed2D {
@ -1222,9 +1220,9 @@ impl Interpolate for LengthOrNone {
matrix: m, matrix: m,
} }
} }
} }
impl From<MatrixDecomposed2D> for ComputedMatrix { impl From<MatrixDecomposed2D> for ComputedMatrix {
/// Recompose a 2D matrix. /// Recompose a 2D matrix.
/// https://drafts.csswg.org/css-transforms/#recomposing-to-a-2d-matrix /// https://drafts.csswg.org/css-transforms/#recomposing-to-a-2d-matrix
fn from(decomposed: MatrixDecomposed2D) -> ComputedMatrix { fn from(decomposed: MatrixDecomposed2D) -> ComputedMatrix {
@ -1259,37 +1257,37 @@ impl Interpolate for LengthOrNone {
computed_matrix.m22 *= decomposed.scale.1; computed_matrix.m22 *= decomposed.scale.1;
computed_matrix computed_matrix
} }
} }
/// A 3d translation. /// A 3d translation.
#[derive(Clone, Copy, Debug)] #[derive(Clone, Copy, Debug)]
#[cfg_attr(feature = "servo", derive(HeapSizeOf))] #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
pub struct Translate3D(f32, f32, f32); pub struct Translate3D(f32, f32, f32);
/// A 3d scale function. /// A 3d scale function.
#[derive(Clone, Copy, Debug)] #[derive(Clone, Copy, Debug)]
#[cfg_attr(feature = "servo", derive(HeapSizeOf))] #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
pub struct Scale3D(f32, f32, f32); pub struct Scale3D(f32, f32, f32);
/// A 3d skew function. /// A 3d skew function.
#[derive(Clone, Copy, Debug)] #[derive(Clone, Copy, Debug)]
#[cfg_attr(feature = "servo", derive(HeapSizeOf))] #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
pub struct Skew(f32, f32, f32); pub struct Skew(f32, f32, f32);
/// A 3d perspective transformation. /// A 3d perspective transformation.
#[derive(Clone, Copy, Debug)] #[derive(Clone, Copy, Debug)]
#[cfg_attr(feature = "servo", derive(HeapSizeOf))] #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
pub struct Perspective(f32, f32, f32, f32); pub struct Perspective(f32, f32, f32, f32);
/// A quaternion used to represent a rotation. /// A quaternion used to represent a rotation.
#[derive(Clone, Copy, Debug)] #[derive(Clone, Copy, Debug)]
#[cfg_attr(feature = "servo", derive(HeapSizeOf))] #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
pub struct Quaternion(f32, f32, f32, f32); pub struct Quaternion(f32, f32, f32, f32);
/// A decomposed 3d matrix. /// A decomposed 3d matrix.
#[derive(Clone, Copy, Debug)] #[derive(Clone, Copy, Debug)]
#[cfg_attr(feature = "servo", derive(HeapSizeOf))] #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
pub struct MatrixDecomposed3D { pub struct MatrixDecomposed3D {
/// A translation function. /// A translation function.
pub translate: Translate3D, pub translate: Translate3D,
/// A scale function. /// A scale function.
@ -1300,11 +1298,11 @@ impl Interpolate for LengthOrNone {
pub perspective: Perspective, pub perspective: Perspective,
/// The quaternion used to represent the rotation. /// The quaternion used to represent the rotation.
pub quaternion: Quaternion, pub quaternion: Quaternion,
} }
/// Decompose a 3D matrix. /// Decompose a 3D matrix.
/// https://drafts.csswg.org/css-transforms/#decomposing-a-3d-matrix /// https://drafts.csswg.org/css-transforms/#decomposing-a-3d-matrix
fn decompose_3d_matrix(mut matrix: ComputedMatrix) -> Result<MatrixDecomposed3D, ()> { fn decompose_3d_matrix(mut matrix: ComputedMatrix) -> Result<MatrixDecomposed3D, ()> {
// Normalize the matrix. // Normalize the matrix.
if matrix.m44 == 0.0 { if matrix.m44 == 0.0 {
return Err(()); return Err(());
@ -1445,32 +1443,32 @@ impl Interpolate for LengthOrNone {
perspective: perspective, perspective: perspective,
quaternion: quaternion quaternion: quaternion
}) })
} }
// Combine 2 point. // Combine 2 point.
fn combine(a: [f32; 3], b: [f32; 3], ascl: f32, bscl: f32) -> [f32; 3] { fn combine(a: [f32; 3], b: [f32; 3], ascl: f32, bscl: f32) -> [f32; 3] {
[ [
(ascl * a[0]) + (bscl * b[0]), (ascl * a[0]) + (bscl * b[0]),
(ascl * a[1]) + (bscl * b[1]), (ascl * a[1]) + (bscl * b[1]),
(ascl * a[2]) + (bscl * b[2]) (ascl * a[2]) + (bscl * b[2])
] ]
} }
// Dot product. // Dot product.
fn dot(a: [f32; 3], b: [f32; 3]) -> f32 { fn dot(a: [f32; 3], b: [f32; 3]) -> f32 {
a[0] * b[0] + a[1] * b[1] + a[2] * b[2] a[0] * b[0] + a[1] * b[1] + a[2] * b[2]
} }
// Cross product. // Cross product.
fn cross(row1: [f32; 3], row2: [f32; 3]) -> [f32; 3] { fn cross(row1: [f32; 3], row2: [f32; 3]) -> [f32; 3] {
[ [
row1[1] * row2[2] - row1[2] * row2[1], row1[1] * row2[2] - row1[2] * row2[1],
row1[2] * row2[0] - row1[0] * row2[2], row1[2] * row2[0] - row1[0] * row2[2],
row1[0] * row2[1] - row1[1] * row2[0] row1[0] * row2[1] - row1[1] * row2[0]
] ]
} }
impl Interpolate for Translate3D { impl Interpolate for Translate3D {
fn interpolate(&self, other: &Self, progress: f64) -> Result<Self, ()> { fn interpolate(&self, other: &Self, progress: f64) -> Result<Self, ()> {
Ok(Translate3D( Ok(Translate3D(
try!(self.0.interpolate(&other.0, progress)), try!(self.0.interpolate(&other.0, progress)),
@ -1478,9 +1476,9 @@ impl Interpolate for LengthOrNone {
try!(self.2.interpolate(&other.2, progress)) try!(self.2.interpolate(&other.2, progress))
)) ))
} }
} }
impl Interpolate for Scale3D { impl Interpolate for Scale3D {
fn interpolate(&self, other: &Self, progress: f64) -> Result<Self, ()> { fn interpolate(&self, other: &Self, progress: f64) -> Result<Self, ()> {
Ok(Scale3D( Ok(Scale3D(
try!(self.0.interpolate(&other.0, progress)), try!(self.0.interpolate(&other.0, progress)),
@ -1488,9 +1486,9 @@ impl Interpolate for LengthOrNone {
try!(self.2.interpolate(&other.2, progress)) try!(self.2.interpolate(&other.2, progress))
)) ))
} }
} }
impl Interpolate for Skew { impl Interpolate for Skew {
fn interpolate(&self, other: &Self, progress: f64) -> Result<Self, ()> { fn interpolate(&self, other: &Self, progress: f64) -> Result<Self, ()> {
Ok(Skew( Ok(Skew(
try!(self.0.interpolate(&other.0, progress)), try!(self.0.interpolate(&other.0, progress)),
@ -1498,9 +1496,9 @@ impl Interpolate for LengthOrNone {
try!(self.2.interpolate(&other.2, progress)) try!(self.2.interpolate(&other.2, progress))
)) ))
} }
} }
impl Interpolate for Perspective { impl Interpolate for Perspective {
fn interpolate(&self, other: &Self, progress: f64) -> Result<Self, ()> { fn interpolate(&self, other: &Self, progress: f64) -> Result<Self, ()> {
Ok(Perspective( Ok(Perspective(
try!(self.0.interpolate(&other.0, progress)), try!(self.0.interpolate(&other.0, progress)),
@ -1509,9 +1507,9 @@ impl Interpolate for LengthOrNone {
try!(self.3.interpolate(&other.3, progress)) try!(self.3.interpolate(&other.3, progress))
)) ))
} }
} }
impl Interpolate for MatrixDecomposed3D { impl Interpolate for MatrixDecomposed3D {
/// https://drafts.csswg.org/css-transforms/#interpolation-of-decomposed-3d-matrix-values /// https://drafts.csswg.org/css-transforms/#interpolation-of-decomposed-3d-matrix-values
fn interpolate(&self, other: &Self, progress: f64) -> Result<Self, ()> { fn interpolate(&self, other: &Self, progress: f64) -> Result<Self, ()> {
let mut interpolated = *self; let mut interpolated = *self;
@ -1549,9 +1547,9 @@ impl Interpolate for LengthOrNone {
Ok(interpolated) Ok(interpolated)
} }
} }
impl From<MatrixDecomposed3D> for ComputedMatrix { impl From<MatrixDecomposed3D> for ComputedMatrix {
/// Recompose a 3D matrix. /// Recompose a 3D matrix.
/// https://drafts.csswg.org/css-transforms/#recomposing-to-a-3d-matrix /// https://drafts.csswg.org/css-transforms/#recomposing-to-a-3d-matrix
fn from(decomposed: MatrixDecomposed3D) -> ComputedMatrix { fn from(decomposed: MatrixDecomposed3D) -> ComputedMatrix {
@ -1618,10 +1616,10 @@ impl Interpolate for LengthOrNone {
matrix matrix
} }
} }
// Multiplication of two 4x4 matrices. // Multiplication of two 4x4 matrices.
fn multiply(a: ComputedMatrix, b: ComputedMatrix) -> ComputedMatrix { fn multiply(a: ComputedMatrix, b: ComputedMatrix) -> ComputedMatrix {
let mut a_clone = a; let mut a_clone = a;
% for i in range(1, 5): % for i in range(1, 5):
% for j in range(1, 5): % for j in range(1, 5):
@ -1632,9 +1630,9 @@ impl Interpolate for LengthOrNone {
% endfor % endfor
% endfor % endfor
a_clone a_clone
} }
impl ComputedMatrix { impl ComputedMatrix {
fn is_3d(&self) -> bool { fn is_3d(&self) -> bool {
self.m13 != 0.0 || self.m14 != 0.0 || self.m13 != 0.0 || self.m14 != 0.0 ||
self.m23 != 0.0 || self.m24 != 0.0 || self.m23 != 0.0 || self.m24 != 0.0 ||
@ -1746,10 +1744,10 @@ impl Interpolate for LengthOrNone {
Some(x) Some(x)
} }
} }
/// https://drafts.csswg.org/css-transforms/#interpolation-of-transforms /// https://drafts.csswg.org/css-transforms/#interpolation-of-transforms
impl Interpolate for TransformList { impl Interpolate for TransformList {
#[inline] #[inline]
fn interpolate(&self, other: &TransformList, progress: f64) -> Result<Self, ()> { fn interpolate(&self, other: &TransformList, progress: f64) -> Result<Self, ()> {
// http://dev.w3.org/csswg/css-transforms/#interpolation-of-transforms // http://dev.w3.org/csswg/css-transforms/#interpolation-of-transforms
@ -1776,7 +1774,5 @@ impl Interpolate for LengthOrNone {
Ok(result) Ok(result)
} }
} }
% endif

View file

@ -1051,7 +1051,7 @@ ${helpers.single_keyword("animation-fill-mode",
<%helpers:longhand name="transform" products="gecko servo" extra_prefixes="webkit" <%helpers:longhand name="transform" products="gecko servo" extra_prefixes="webkit"
animatable="${product == 'servo'}" animatable="True"
spec="https://drafts.csswg.org/css-transforms/#propdef-transform"> spec="https://drafts.csswg.org/css-transforms/#propdef-transform">
use app_units::Au; use app_units::Au;
use style_traits::ToCss; use style_traits::ToCss;