From a6099d0fc0485cf19626317211236a9c701945a7 Mon Sep 17 00:00:00 2001 From: Boris Chiou Date: Thu, 25 May 2017 16:15:13 +0800 Subject: [PATCH] Define ComputedOperation::InterpolateMatrix. We use this arm to store the interpolated result of two mismatched transform lists, and we resolve it until we know the reference box size (on Gecko side). The conversion from ComputedOperation::InterpolateMatrix to eCSSKeyword_interpolatematrix will be implemented later in this patch series. --- components/layout/fragment.rs | 4 ++ components/style/properties/gecko.mako.rs | 5 +++ .../helpers/animated_properties.mako.rs | 12 +++++- .../style/properties/longhand/box.mako.rs | 39 ++++++++++++++++++- 4 files changed, 56 insertions(+), 4 deletions(-) diff --git a/components/layout/fragment.rs b/components/layout/fragment.rs index 9ba2f697e5a..b39a9816f07 100644 --- a/components/layout/fragment.rs +++ b/components/layout/fragment.rs @@ -2896,6 +2896,10 @@ impl Fragment { Matrix4D::create_skew(Radians::new(theta_x.radians()), Radians::new(theta_y.radians())) } + transform::ComputedOperation::InterpolateMatrix { .. } => { + // TODO: Convert InterpolateMatrix into a valid Matrix4D by the reference box. + Matrix4D::identity() + } }; transform = transform.pre_mul(&matrix); diff --git a/components/style/properties/gecko.mako.rs b/components/style/properties/gecko.mako.rs index 3c8e359e4de..b9b445ea5b6 100644 --- a/components/style/properties/gecko.mako.rs +++ b/components/style/properties/gecko.mako.rs @@ -2346,6 +2346,11 @@ fn static_assert() { ${transform_function_arm("Scale", "scale3d", ["number"] * 3)} ${transform_function_arm("Rotate", "rotate3d", ["number"] * 3 + ["angle"])} ${transform_function_arm("Perspective", "perspective", ["length"])} + _ => { + // TODO: Convert ComputedOperation::InterpolateMatrix into + // eCSSKeyword_interpolatematrix. + gecko_value.mUnit = structs::nsCSSUnit::eCSSUnit_None; + } } cur = (*cur).mNext; } diff --git a/components/style/properties/helpers/animated_properties.mako.rs b/components/style/properties/helpers/animated_properties.mako.rs index d98b66b8e29..cbb3296c042 100644 --- a/components/style/properties/helpers/animated_properties.mako.rs +++ b/components/style/properties/helpers/animated_properties.mako.rs @@ -1643,6 +1643,9 @@ fn build_identity_transform_list(list: &[TransformOperation]) -> Vec { + panic!("Building the identity matrix for InterpolateMatrix is not supported"); + } } } @@ -1744,8 +1747,13 @@ fn add_weighted_transform_lists(from_list: &[TransformOperation], } } } else { - // TODO(gw): Implement matrix decomposition and interpolation - result.extend_from_slice(from_list); + use values::specified::Percentage; + let from_transform_list = TransformList(Some(from_list.to_vec())); + let to_transform_list = TransformList(Some(to_list.to_vec())); + result.push( + TransformOperation::InterpolateMatrix { from_list: from_transform_list, + to_list: to_transform_list, + progress: Percentage(other_portion as f32) }); } TransformList(Some(result)) diff --git a/components/style/properties/longhand/box.mako.rs b/components/style/properties/longhand/box.mako.rs index 623810c8724..f94c31227d4 100644 --- a/components/style/properties/longhand/box.mako.rs +++ b/components/style/properties/longhand/box.mako.rs @@ -688,7 +688,7 @@ ${helpers.predefined_type("scroll-snap-coordinate", use app_units::Au; use values::computed::{LengthOrPercentageOrNumber as ComputedLoPoNumber, LengthOrNumber as ComputedLoN}; use values::computed::{LengthOrPercentage as ComputedLoP, Length as ComputedLength}; - use values::specified::{Angle, Length, LengthOrPercentage}; + use values::specified::{Angle, Length, LengthOrPercentage, Percentage}; use values::specified::{LengthOrNumber, LengthOrPercentageOrNumber as LoPoNumber, Number}; use style_traits::ToCss; use style_traits::values::Css; @@ -699,7 +699,7 @@ ${helpers.predefined_type("scroll-snap-coordinate", use app_units::Au; use values::CSSFloat; use values::computed; - use values::computed::{Length, LengthOrPercentage}; + use values::computed::{Length, LengthOrPercentage, Percentage}; #[derive(Clone, Copy, Debug, PartialEq)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] @@ -756,6 +756,20 @@ ${helpers.predefined_type("scroll-snap-coordinate", Scale(CSSFloat, CSSFloat, CSSFloat), Rotate(CSSFloat, CSSFloat, CSSFloat, computed::Angle), Perspective(computed::Length), + // For mismatched transform lists. + // A vector of |ComputedOperation| could contain an |InterpolateMatrix| and other + // |ComputedOperation|s, and multiple nested |InterpolateMatrix|s is acceptable. + // e.g. + // [ InterpolateMatrix { from_list: [ InterpolateMatrix { ... }, + // Scale(...) ], + // to_list: [ InterpolateMatrix { from_list: ..., + // to_list: [ InterpolateMatrix, + // ... ], + // progress: ... } ], + // progress: ... } ] + InterpolateMatrix { from_list: T, + to_list: T, + progress: Percentage }, } #[derive(Clone, Debug, PartialEq)] @@ -835,6 +849,10 @@ ${helpers.predefined_type("scroll-snap-coordinate", /// /// The value must be greater than or equal to zero. Perspective(specified::Length), + /// A intermediate type for interpolation of mismatched transform lists. + InterpolateMatrix { from_list: SpecifiedValue, + to_list: SpecifiedValue, + progress: Percentage }, } impl ToCss for computed_value::T { @@ -899,6 +917,7 @@ ${helpers.predefined_type("scroll-snap-coordinate", dest, "rotate3d({}, {}, {}, {})", Css(x), Css(y), Css(z), Css(theta)), Perspective(ref length) => write!(dest, "perspective({})", Css(length)), + _ => unreachable!(), } } } @@ -1440,6 +1459,13 @@ ${helpers.predefined_type("scroll-snap-coordinate", Perspective(ref d) => { result.push(computed_value::ComputedOperation::Perspective(d.to_computed_value(context))); } + InterpolateMatrix { ref from_list, ref to_list, progress } => { + result.push(computed_value::ComputedOperation::InterpolateMatrix { + from_list: from_list.to_computed_value(context), + to_list: to_list.to_computed_value(context), + progress: progress + }); + } }; } @@ -1523,6 +1549,15 @@ ${helpers.predefined_type("scroll-snap-coordinate", ToComputedValue::from_computed_value(d) )); } + computed_value::ComputedOperation::InterpolateMatrix { ref from_list, + ref to_list, + progress } => { + result.push(SpecifiedOperation::InterpolateMatrix { + from_list: SpecifiedValue::from_computed_value(from_list), + to_list: SpecifiedValue::from_computed_value(to_list), + progress: progress + }); + } }; } result