style: Use cbindgen to back CSS transforms.

This avoids the expensive conversion, and cleans up a bunch.

Further cleanup is possible, just not done yet to avoid growing the patch even
more.

Differential Revision: https://phabricator.services.mozilla.com/D30748
This commit is contained in:
Emilio Cobos Álvarez 2019-05-16 23:25:10 +00:00
parent 85752fa479
commit 3034d66eef
11 changed files with 59 additions and 356 deletions

View file

@ -861,7 +861,7 @@ impl Animate for ComputedTransform {
// animation procedures so we treat it separately here rather than
// handling it in TransformOperation.
if procedure == Procedure::Add {
let result = self.0.iter().chain(&other.0).cloned().collect::<Vec<_>>();
let result = self.0.iter().chain(&*other.0).cloned().collect();
return Ok(Transform(result));
}
@ -898,15 +898,15 @@ impl Animate for ComputedTransform {
},
Procedure::Interpolate { progress } => {
result.push(TransformOperation::InterpolateMatrix {
from_list: Transform(this_remainder.to_vec()),
to_list: Transform(other_remainder.to_vec()),
from_list: Transform(this_remainder.to_vec().into()),
to_list: Transform(other_remainder.to_vec().into()),
progress: Percentage(progress as f32),
});
},
Procedure::Accumulate { count } => {
result.push(TransformOperation::AccumulateMatrix {
from_list: Transform(this_remainder.to_vec()),
to_list: Transform(other_remainder.to_vec()),
from_list: Transform(this_remainder.to_vec().into()),
to_list: Transform(other_remainder.to_vec().into()),
count: cmp::min(count, i32::max_value() as u64) as i32,
});
},
@ -927,8 +927,8 @@ impl Animate for ComputedTransform {
// matrix. Instead we need to wrap it in another ___Matrix type.
TransformOperation::AccumulateMatrix { .. } |
TransformOperation::InterpolateMatrix { .. } => {
let transform_list = Transform(vec![transform.clone()]);
let identity_list = Transform(vec![identity]);
let transform_list = Transform(vec![transform.clone()].into());
let identity_list = Transform(vec![identity].into());
let (from_list, to_list) = if fill_right {
(transform_list, identity_list)
} else {
@ -970,7 +970,7 @@ impl Animate for ComputedTransform {
(None, None) => {},
}
Ok(Transform(result))
Ok(Transform(result.into()))
}
}

View file

@ -26,6 +26,7 @@ use style_traits::{CssWriter, ToCss};
ToAnimatedZero,
ToResolvedValue,
)]
#[repr(C)]
pub struct Angle(CSSFloat);
impl ToCss for Angle {

View file

@ -16,9 +16,9 @@ pub use crate::values::generics::transform::TransformStyle;
/// A single operation in a computed CSS `transform`
pub type TransformOperation =
generic::TransformOperation<Angle, Number, Length, Integer, LengthPercentage>;
generic::GenericTransformOperation<Angle, Number, Length, Integer, LengthPercentage>;
/// A computed CSS `transform`
pub type Transform = generic::Transform<TransformOperation>;
pub type Transform = generic::GenericTransform<TransformOperation>;
/// The computed value of a CSS `<transform-origin>`
pub type TransformOrigin =
@ -540,13 +540,13 @@ impl ToAnimatedZero for Transform {
self.0
.iter()
.map(|op| op.to_animated_zero())
.collect::<Result<Vec<_>, _>>()?,
.collect::<Result<crate::OwnedSlice<_>, _>>()?,
))
}
}
/// A computed CSS `rotate`
pub type Rotate = generic::Rotate<Number, Angle>;
pub type Rotate = generic::GenericRotate<Number, Angle>;
impl Rotate {
/// Convert TransformOperation to Rotate.
@ -573,7 +573,7 @@ impl Rotate {
}
/// A computed CSS `translate`
pub type Translate = generic::Translate<LengthPercentage, Length>;
pub type Translate = generic::GenericTranslate<LengthPercentage, Length>;
impl Translate {
/// Convert TransformOperation to Translate.
@ -602,7 +602,7 @@ impl Translate {
}
/// A computed CSS `scale`
pub type Scale = generic::Scale<Number>;
pub type Scale = generic::GenericScale<Number>;
impl Scale {
/// Convert TransformOperation to Scale.

View file

@ -30,8 +30,9 @@ use style_traits::{CssWriter, ToCss};
ToResolvedValue,
ToShmem,
)]
#[css(comma, function)]
pub struct Matrix<T> {
#[css(comma, function = "matrix")]
#[repr(C)]
pub struct GenericMatrix<T> {
pub a: T,
pub b: T,
pub c: T,
@ -40,6 +41,8 @@ pub struct Matrix<T> {
pub f: T,
}
pub use self::GenericMatrix as Matrix;
#[allow(missing_docs)]
#[cfg_attr(rustfmt, rustfmt_skip)]
#[css(comma, function = "matrix3d")]
@ -55,13 +58,16 @@ pub struct Matrix<T> {
ToResolvedValue,
ToShmem,
)]
pub struct Matrix3D<T> {
#[repr(C)]
pub struct GenericMatrix3D<T> {
pub m11: T, pub m12: T, pub m13: T, pub m14: T,
pub m21: T, pub m22: T, pub m23: T, pub m24: T,
pub m31: T, pub m32: T, pub m33: T, pub m34: T,
pub m41: T, pub m42: T, pub m43: T, pub m44: T,
}
pub use self::GenericMatrix3D as Matrix3D;
#[cfg_attr(rustfmt, rustfmt_skip)]
impl<T: Into<f64>> From<Matrix<T>> for Transform3D<f64> {
#[inline]
@ -142,17 +148,19 @@ fn is_same<N: PartialEq>(x: &N, y: &N) -> bool {
ToResolvedValue,
ToShmem,
)]
#[repr(C, u8)]
/// A single operation in the list of a `transform` value
pub enum TransformOperation<Angle, Number, Length, Integer, LengthPercentage>
/// cbindgen:derive-tagged-enum-copy-constructor=true
pub enum GenericTransformOperation<Angle, Number, Length, Integer, LengthPercentage>
where
Angle: Zero,
LengthPercentage: Zero,
Number: PartialEq,
{
/// Represents a 2D 2x3 matrix.
Matrix(Matrix<Number>),
Matrix(GenericMatrix<Number>),
/// Represents a 3D 4x4 matrix.
Matrix3D(Matrix3D<Number>),
Matrix3D(GenericMatrix3D<Number>),
/// A 2D skew.
///
/// If the second angle is not provided it is assumed zero.
@ -232,20 +240,22 @@ where
#[allow(missing_docs)]
#[css(comma, function = "interpolatematrix")]
InterpolateMatrix {
from_list: Transform<TransformOperation<Angle, Number, Length, Integer, LengthPercentage>>,
to_list: Transform<TransformOperation<Angle, Number, Length, Integer, LengthPercentage>>,
from_list: GenericTransform<GenericTransformOperation<Angle, Number, Length, Integer, LengthPercentage>>,
to_list: GenericTransform<GenericTransformOperation<Angle, Number, Length, Integer, LengthPercentage>>,
progress: computed::Percentage,
},
/// A intermediate type for accumulation of mismatched transform lists.
#[allow(missing_docs)]
#[css(comma, function = "accumulatematrix")]
AccumulateMatrix {
from_list: Transform<TransformOperation<Angle, Number, Length, Integer, LengthPercentage>>,
to_list: Transform<TransformOperation<Angle, Number, Length, Integer, LengthPercentage>>,
from_list: GenericTransform<GenericTransformOperation<Angle, Number, Length, Integer, LengthPercentage>>,
to_list: GenericTransform<GenericTransformOperation<Angle, Number, Length, Integer, LengthPercentage>>,
count: Integer,
},
}
pub use self::GenericTransformOperation as TransformOperation;
#[derive(
Clone,
Debug,
@ -257,8 +267,11 @@ where
ToResolvedValue,
ToShmem,
)]
#[repr(C)]
/// A value of the `transform` property
pub struct Transform<T>(#[css(if_empty = "none", iterable)] pub Vec<T>);
pub struct GenericTransform<T>(#[css(if_empty = "none", iterable)] pub crate::OwnedSlice<T>);
pub use self::GenericTransform as Transform;
impl<Angle, Number, Length, Integer, LengthPercentage>
TransformOperation<Angle, Number, Length, Integer, LengthPercentage>
@ -497,7 +510,7 @@ where
impl<T> Transform<T> {
/// `none`
pub fn none() -> Self {
Transform(vec![])
Transform(Default::default())
}
}
@ -529,7 +542,7 @@ impl<T: ToMatrix> Transform<T> {
let mut transform = Transform3D::<f64>::identity();
let mut contain_3d = false;
for operation in &self.0 {
for operation in &*self.0 {
let matrix = operation.to_3d_matrix(reference_box)?;
contain_3d |= operation.is_3d();
transform = transform.pre_mul(&matrix);
@ -589,10 +602,11 @@ pub fn get_normalized_vector_and_angle<T: Zero>(
ToResolvedValue,
ToShmem,
)]
#[repr(C, u8)]
/// A value of the `Rotate` property
///
/// <https://drafts.csswg.org/css-transforms-2/#individual-transforms>
pub enum Rotate<Number, Angle> {
pub enum GenericRotate<Number, Angle> {
/// 'none'
None,
/// '<angle>'
@ -601,6 +615,8 @@ pub enum Rotate<Number, Angle> {
Rotate3D(Number, Number, Number, Angle),
}
pub use self::GenericRotate as Rotate;
/// A trait to check if the current 3D vector is parallel to the DirectionVector.
/// This is especially for serialization on Rotate.
pub trait IsParallelTo {
@ -660,10 +676,11 @@ where
ToResolvedValue,
ToShmem,
)]
#[repr(C, u8)]
/// A value of the `Scale` property
///
/// <https://drafts.csswg.org/css-transforms-2/#individual-transforms>
pub enum Scale<Number> {
pub enum GenericScale<Number> {
/// 'none'
None,
/// '<number>{1,2}'
@ -672,6 +689,8 @@ pub enum Scale<Number> {
Scale3D(Number, Number, Number),
}
pub use self::GenericScale as Scale;
impl<Number: ToCss + PartialEq> ToCss for Scale<Number> {
fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
where
@ -710,6 +729,7 @@ impl<Number: ToCss + PartialEq> ToCss for Scale<Number> {
ToResolvedValue,
ToShmem,
)]
#[repr(C, u8)]
/// A value of the `translate` property
///
/// https://drafts.csswg.org/css-transforms-2/#individual-transform-serialization:
@ -724,7 +744,7 @@ impl<Number: ToCss + PartialEq> ToCss for Scale<Number> {
/// related spec issue is https://github.com/w3c/csswg-drafts/issues/3305
///
/// <https://drafts.csswg.org/css-transforms-2/#individual-transforms>
pub enum Translate<LengthPercentage, Length>
pub enum GenericTranslate<LengthPercentage, Length>
where
LengthPercentage: Zero,
{
@ -739,6 +759,8 @@ where
Translate3D(LengthPercentage, LengthPercentage, Length),
}
pub use self::GenericTranslate as Translate;
#[allow(missing_docs)]
#[derive(
Clone,

View file

@ -42,7 +42,7 @@ impl Transform {
.try(|input| input.expect_ident_matching("none"))
.is_ok()
{
return Ok(generic::Transform(Vec::new()));
return Ok(generic::Transform::none());
}
Ok(generic::Transform(Space::parse(input, |input| {
@ -218,7 +218,7 @@ impl Transform {
.new_custom_error(StyleParseErrorKind::UnexpectedFunction(function.clone()))
})
})
})?))
})?.into()))
}
}