Auto merge of #17202 - BorisChiou:stylo/animation/mismatched_transform, r=Manishearth,birtles

stylo: Bug 1335998 - Handle interpolation and accumulation of mismatched transform lists

These are the interdependent patches of Bug 1335998. We want to do interpolation and accumulation for mismatched transform lists, so introduce ComputedOperation::InterpolateMatrix and ComputedOperation::Accumulation. Both arms store the from_list and to_list, and resolve them until we have the layout information. For the Servo part, we haven't implemented how to read the transform lists in layout/fragment.rs, but I think it would be easy. (related issue #13267)

---
- [X] `./mach build -d` does not report any errors
- [X] `./mach test-tidy` does not report any errors
- [X] These changes fix [Bug 1335998](https://bugzilla.mozilla.org/show_bug.cgi?id=1335998)
- [X] There are tests for these changes

<!-- Reviewable:start -->
---
This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/17202)
<!-- Reviewable:end -->
This commit is contained in:
bors-servo 2017-06-06 23:54:41 -07:00 committed by GitHub
commit f4a720483d
10 changed files with 4840 additions and 4085 deletions

View file

@ -2,8 +2,11 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use app_units::Au;
use cssparser::RGBA;
use style::properties::animated_properties::{Animatable, IntermediateRGBA};
use style::properties::longhands::transform::computed_value::ComputedOperation as TransformOperation;
use style::properties::longhands::transform::computed_value::T as TransformList;
fn interpolate_rgba(from: RGBA, to: RGBA, progress: f64) -> RGBA {
let from: IntermediateRGBA = from.into();
@ -11,6 +14,7 @@ fn interpolate_rgba(from: RGBA, to: RGBA, progress: f64) -> RGBA {
from.interpolate(&to, progress).unwrap().into()
}
// Color
#[test]
fn test_rgba_color_interepolation_preserves_transparent() {
assert_eq!(interpolate_rgba(RGBA::transparent(),
@ -54,3 +58,95 @@ fn test_rgba_color_interepolation_out_of_range_clamped_2() {
RGBA::from_floats(0.0, 1.0, 0.0, 0.2), 1.5),
RGBA::from_floats(0.0, 0.0, 0.0, 0.0));
}
// Transform
#[test]
fn test_transform_interpolation_on_translate() {
use style::values::computed::{CalcLengthOrPercentage, LengthOrPercentage};
let from = TransformList(Some(vec![
TransformOperation::Translate(LengthOrPercentage::Length(Au(0)),
LengthOrPercentage::Length(Au(100)),
Au(25))]));
let to = TransformList(Some(vec![
TransformOperation::Translate(LengthOrPercentage::Length(Au(100)),
LengthOrPercentage::Length(Au(0)),
Au(75))]));
assert_eq!(from.interpolate(&to, 0.5).unwrap(),
TransformList(Some(vec![
TransformOperation::Translate(LengthOrPercentage::Length(Au(50)),
LengthOrPercentage::Length(Au(50)),
Au(50))])));
let from = TransformList(Some(vec![
TransformOperation::Translate(LengthOrPercentage::Percentage(0.5),
LengthOrPercentage::Percentage(1.0),
Au(25))]));
let to = TransformList(Some(vec![
TransformOperation::Translate(LengthOrPercentage::Length(Au(100)),
LengthOrPercentage::Length(Au(50)),
Au(75))]));
assert_eq!(from.interpolate(&to, 0.5).unwrap(),
TransformList(Some(vec![
TransformOperation::Translate(LengthOrPercentage::Calc(
// calc(50px + 25%)
CalcLengthOrPercentage::new(Au(50),
Some(0.25))),
LengthOrPercentage::Calc(
// calc(25px + 50%)
CalcLengthOrPercentage::new(Au(25),
Some(0.5))),
Au(50))])));
}
#[test]
fn test_transform_interpolation_on_scale() {
let from = TransformList(Some(vec![TransformOperation::Scale(1.0, 2.0, 1.0)]));
let to = TransformList(Some(vec![TransformOperation::Scale(2.0, 4.0, 2.0)]));
assert_eq!(from.interpolate(&to, 0.5).unwrap(),
TransformList(Some(vec![TransformOperation::Scale(1.5, 3.0, 1.5)])));
}
#[test]
fn test_transform_interpolation_on_rotate() {
use style::values::computed::Angle;
let from = TransformList(Some(vec![TransformOperation::Rotate(0.0, 0.0, 1.0,
Angle::from_radians(0.0))]));
let to = TransformList(Some(vec![TransformOperation::Rotate(0.0, 0.0, 1.0,
Angle::from_radians(100.0))]));
assert_eq!(from.interpolate(&to, 0.5).unwrap(),
TransformList(Some(vec![TransformOperation::Rotate(0.0, 0.0, 1.0,
Angle::from_radians(50.0))])));
}
#[test]
fn test_transform_interpolation_on_skew() {
use style::values::computed::Angle;
let from = TransformList(Some(vec![TransformOperation::Skew(Angle::from_radians(0.0),
Angle::from_radians(100.0))]));
let to = TransformList(Some(vec![TransformOperation::Skew(Angle::from_radians(100.0),
Angle::from_radians(0.0))]));
assert_eq!(from.interpolate(&to, 0.5).unwrap(),
TransformList(Some(vec![TransformOperation::Skew(Angle::from_radians(50.0),
Angle::from_radians(50.0))])));
}
#[test]
fn test_transform_interpolation_on_mismatched_lists() {
use style::values::computed::{Angle, LengthOrPercentage, Percentage};
let from = TransformList(Some(vec![TransformOperation::Rotate(0.0, 0.0, 1.0,
Angle::from_radians(100.0))]));
let to = TransformList(Some(vec![
TransformOperation::Translate(LengthOrPercentage::Length(Au(100)),
LengthOrPercentage::Length(Au(0)),
Au(0))]));
assert_eq!(from.interpolate(&to, 0.5).unwrap(),
TransformList(Some(vec![TransformOperation::InterpolateMatrix {
from_list: from.clone(),
to_list: to.clone(),
progress: Percentage(0.5)
}])));
}