mirror of
https://github.com/servo/servo.git
synced 2025-07-16 03:43:38 +01:00
Auto merge of #11924 - emilio:interpolate-cleanup, r=nox,Ms2ger
style: Cleanup `Interpolate` code. <!-- Please describe your changes on the following line: --> --- <!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `__` with appropriate data: --> - [x] `./mach build -d` does not report any errors - [x] `./mach test-tidy` does not report any errors <!-- Either: --> - [x] These changes do not require tests because refactoring. <!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. --> <!-- Reviewable:start --> --- This change is [<img src="https://reviewable.io/review_button.svg" height="35" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/11924) <!-- Reviewable:end -->
This commit is contained in:
commit
c54c405c1c
1 changed files with 148 additions and 242 deletions
|
@ -25,9 +25,8 @@ use properties::longhands::vertical_align::computed_value::T as VerticalAlign;
|
|||
use properties::longhands::visibility::computed_value::T as Visibility;
|
||||
use properties::longhands::z_index::computed_value::T as ZIndex;
|
||||
use properties::style_struct_traits::*;
|
||||
use std::cmp::{self, Ordering};
|
||||
use std::cmp;
|
||||
use std::fmt;
|
||||
use std::iter::repeat;
|
||||
use super::ComputedValues;
|
||||
use values::computed::{Angle, LengthOrPercentageOrAuto, LengthOrPercentageOrNone};
|
||||
use values::computed::{BorderRadiusSize, LengthOrNone};
|
||||
|
@ -119,7 +118,7 @@ impl AnimatedProperty {
|
|||
% for prop in data.longhands:
|
||||
% if prop.animatable:
|
||||
AnimatedProperty::${prop.camel_case}(ref from, ref to) => {
|
||||
if let Some(value) = from.interpolate(to, progress) {
|
||||
if let Ok(value) = from.interpolate(to, progress) {
|
||||
style.mutate_${prop.style_struct.ident.strip("_")}().set_${prop.ident}(value);
|
||||
}
|
||||
}
|
||||
|
@ -155,27 +154,25 @@ impl AnimatedProperty {
|
|||
///
|
||||
/// [interpolated-types]: https://drafts.csswg.org/css-transitions/#interpolated-types
|
||||
pub trait Interpolate: Sized {
|
||||
fn interpolate(&self, other: &Self, time: f64) -> Option<Self>;
|
||||
fn interpolate(&self, other: &Self, time: f64) -> Result<Self, ()>;
|
||||
}
|
||||
|
||||
/// https://drafts.csswg.org/css-transitions/#animtype-number
|
||||
impl Interpolate for Au {
|
||||
#[inline]
|
||||
fn interpolate(&self, other: &Au, time: f64) -> Option<Au> {
|
||||
Some(Au((self.0 as f64 + (other.0 as f64 - self.0 as f64) * time).round() as i32))
|
||||
fn interpolate(&self, other: &Self, time: f64) -> Result<Self, ()> {
|
||||
Ok(Au((self.0 as f64 + (other.0 as f64 - self.0 as f64) * time).round() as i32))
|
||||
}
|
||||
}
|
||||
|
||||
impl <T> Interpolate for Option<T> where T: Interpolate {
|
||||
#[inline]
|
||||
fn interpolate(&self, other: &Option<T>, time: f64) -> Option<Option<T>> {
|
||||
fn interpolate(&self, other: &Option<T>, time: f64) -> Result<Option<T>, ()> {
|
||||
match (self, other) {
|
||||
(&Some(ref this), &Some(ref other)) => {
|
||||
this.interpolate(other, time).and_then(|value| {
|
||||
Some(Some(value))
|
||||
})
|
||||
Ok(this.interpolate(other, time).ok())
|
||||
}
|
||||
(_, _) => None
|
||||
_ => Err(()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -183,33 +180,33 @@ impl <T> Interpolate for Option<T> where T: Interpolate {
|
|||
/// https://drafts.csswg.org/css-transitions/#animtype-number
|
||||
impl Interpolate for f32 {
|
||||
#[inline]
|
||||
fn interpolate(&self, other: &f32, time: f64) -> Option<f32> {
|
||||
Some(((*self as f64) + ((*other as f64) - (*self as f64)) * time) as f32)
|
||||
fn interpolate(&self, other: &f32, time: f64) -> Result<Self, ()> {
|
||||
Ok(((*self as f64) + ((*other as f64) - (*self as f64)) * time) as f32)
|
||||
}
|
||||
}
|
||||
|
||||
/// https://drafts.csswg.org/css-transitions/#animtype-number
|
||||
impl Interpolate for f64 {
|
||||
#[inline]
|
||||
fn interpolate(&self, other: &f64, time: f64) -> Option<f64> {
|
||||
Some(*self + (*other - *self) * time)
|
||||
fn interpolate(&self, other: &f64, time: f64) -> Result<Self, ()> {
|
||||
Ok(*self + (*other - *self) * time)
|
||||
}
|
||||
}
|
||||
|
||||
/// https://drafts.csswg.org/css-transitions/#animtype-number
|
||||
impl Interpolate for i32 {
|
||||
#[inline]
|
||||
fn interpolate(&self, other: &i32, time: f64) -> Option<i32> {
|
||||
fn interpolate(&self, other: &i32, time: f64) -> Result<Self, ()> {
|
||||
let a = *self as f64;
|
||||
let b = *other as f64;
|
||||
Some((a + (b - a) * time).round() as i32)
|
||||
Ok((a + (b - a) * time).round() as i32)
|
||||
}
|
||||
}
|
||||
|
||||
/// https://drafts.csswg.org/css-transitions/#animtype-number
|
||||
impl Interpolate for Angle {
|
||||
#[inline]
|
||||
fn interpolate(&self, other: &Angle, time: f64) -> Option<Angle> {
|
||||
fn interpolate(&self, other: &Angle, time: f64) -> Result<Self, ()> {
|
||||
self.radians().interpolate(&other.radians(), time).map(Angle)
|
||||
}
|
||||
}
|
||||
|
@ -217,19 +214,18 @@ impl Interpolate for Angle {
|
|||
/// https://drafts.csswg.org/css-transitions/#animtype-visibility
|
||||
impl Interpolate for Visibility {
|
||||
#[inline]
|
||||
fn interpolate(&self, other: &Visibility, time: f64)
|
||||
-> Option<Visibility> {
|
||||
fn interpolate(&self, other: &Self, time: f64) -> Result<Self, ()> {
|
||||
match (*self, *other) {
|
||||
(Visibility::visible, _) | (_, Visibility::visible) => {
|
||||
if time >= 0.0 && time <= 1.0 {
|
||||
Some(Visibility::visible)
|
||||
Ok(if time >= 0.0 && time <= 1.0 {
|
||||
Visibility::visible
|
||||
} else if time < 0.0 {
|
||||
Some(*self)
|
||||
*self
|
||||
} else {
|
||||
Some(*other)
|
||||
}
|
||||
*other
|
||||
})
|
||||
}
|
||||
(_, _) => None,
|
||||
_ => Err(()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -237,56 +233,40 @@ impl Interpolate for Visibility {
|
|||
/// https://drafts.csswg.org/css-transitions/#animtype-integer
|
||||
impl Interpolate for ZIndex {
|
||||
#[inline]
|
||||
fn interpolate(&self, other: &ZIndex, time: f64)
|
||||
-> Option<ZIndex> {
|
||||
fn interpolate(&self, other: &Self, time: f64) -> Result<Self, ()> {
|
||||
match (*self, *other) {
|
||||
(ZIndex::Number(ref this),
|
||||
ZIndex::Number(ref other)) => {
|
||||
this.interpolate(other, time).and_then(|value| {
|
||||
Some(ZIndex::Number(value))
|
||||
})
|
||||
this.interpolate(other, time).map(ZIndex::Number)
|
||||
}
|
||||
(_, _) => None,
|
||||
_ => Err(()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Interpolate + Clone> Interpolate for Size2D<T> {
|
||||
#[inline]
|
||||
fn interpolate(&self, other: &Self, time: f64) -> Option<Self> {
|
||||
let width = match self.width.interpolate(&other.width, time) {
|
||||
Some(width) => width,
|
||||
None => return None,
|
||||
};
|
||||
fn interpolate(&self, other: &Self, time: f64) -> Result<Self, ()> {
|
||||
let width = try!(self.width.interpolate(&other.width, time));
|
||||
let height = try!(self.height.interpolate(&other.height, time));
|
||||
|
||||
let height = match self.height.interpolate(&other.height, time) {
|
||||
Some(height) => height,
|
||||
None => return None,
|
||||
};
|
||||
Some(Size2D::new(width, height))
|
||||
Ok(Size2D::new(width, height))
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Interpolate + Clone> Interpolate for Point2D<T> {
|
||||
#[inline]
|
||||
fn interpolate(&self, other: &Self, time: f64) -> Option<Self> {
|
||||
let x = match self.x.interpolate(&other.x, time) {
|
||||
Some(x) => x,
|
||||
None => return None,
|
||||
};
|
||||
fn interpolate(&self, other: &Self, time: f64) -> Result<Self, ()> {
|
||||
let x = try!(self.x.interpolate(&other.x, time));
|
||||
let y = try!(self.y.interpolate(&other.y, time));
|
||||
|
||||
let y = match self.y.interpolate(&other.y, time) {
|
||||
Some(y) => y,
|
||||
None => return None,
|
||||
};
|
||||
|
||||
Some(Point2D::new(x, y))
|
||||
Ok(Point2D::new(x, y))
|
||||
}
|
||||
}
|
||||
|
||||
impl Interpolate for BorderRadiusSize {
|
||||
#[inline]
|
||||
fn interpolate(&self, other: &Self, time: f64) -> Option<Self> {
|
||||
fn interpolate(&self, other: &Self, time: f64) -> Result<Self, ()> {
|
||||
self.0.interpolate(&other.0, time).map(BorderRadiusSize)
|
||||
}
|
||||
}
|
||||
|
@ -294,16 +274,15 @@ impl Interpolate for BorderRadiusSize {
|
|||
/// https://drafts.csswg.org/css-transitions/#animtype-length
|
||||
impl Interpolate for VerticalAlign {
|
||||
#[inline]
|
||||
fn interpolate(&self, other: &VerticalAlign, time: f64)
|
||||
-> Option<VerticalAlign> {
|
||||
fn interpolate(&self, other: &Self, time: f64) -> Result<Self, ()> {
|
||||
match (*self, *other) {
|
||||
(VerticalAlign::LengthOrPercentage(LengthOrPercentage::Length(ref this)),
|
||||
VerticalAlign::LengthOrPercentage(LengthOrPercentage::Length(ref other))) => {
|
||||
this.interpolate(other, time).and_then(|value| {
|
||||
Some(VerticalAlign::LengthOrPercentage(LengthOrPercentage::Length(value)))
|
||||
this.interpolate(other, time).map(|value| {
|
||||
VerticalAlign::LengthOrPercentage(LengthOrPercentage::Length(value))
|
||||
})
|
||||
}
|
||||
(_, _) => None,
|
||||
_ => Err(()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -311,12 +290,10 @@ impl Interpolate for VerticalAlign {
|
|||
/// https://drafts.csswg.org/css-transitions/#animtype-simple-list
|
||||
impl Interpolate for BorderSpacing {
|
||||
#[inline]
|
||||
fn interpolate(&self, other: &BorderSpacing, time: f64)
|
||||
-> Option<BorderSpacing> {
|
||||
self.horizontal.interpolate(&other.horizontal, time).and_then(|horizontal| {
|
||||
self.vertical.interpolate(&other.vertical, time).and_then(|vertical| {
|
||||
Some(BorderSpacing { horizontal: horizontal, vertical: vertical })
|
||||
})
|
||||
fn interpolate(&self, other: &Self, time: f64) -> Result<Self, ()> {
|
||||
Ok(BorderSpacing {
|
||||
horizontal: try!(self.horizontal.interpolate(&other.horizontal, time)),
|
||||
vertical: try!(self.vertical.interpolate(&other.vertical, time)),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -324,30 +301,25 @@ impl Interpolate for BorderSpacing {
|
|||
/// https://drafts.csswg.org/css-transitions/#animtype-color
|
||||
impl Interpolate for RGBA {
|
||||
#[inline]
|
||||
fn interpolate(&self, other: &RGBA, time: f64) -> Option<RGBA> {
|
||||
match (self.red.interpolate(&other.red, time),
|
||||
self.green.interpolate(&other.green, time),
|
||||
self.blue.interpolate(&other.blue, time),
|
||||
self.alpha.interpolate(&other.alpha, time)) {
|
||||
(Some(red), Some(green), Some(blue), Some(alpha)) => {
|
||||
Some(RGBA { red: red, green: green, blue: blue, alpha: alpha })
|
||||
}
|
||||
(_, _, _, _) => None
|
||||
}
|
||||
fn interpolate(&self, other: &RGBA, time: f64) -> Result<Self, ()> {
|
||||
Ok(RGBA {
|
||||
red: try!(self.red.interpolate(&other.red, time)),
|
||||
green: try!(self.green.interpolate(&other.green, time)),
|
||||
blue: try!(self.blue.interpolate(&other.blue, time)),
|
||||
alpha: try!(self.alpha.interpolate(&other.alpha, time)),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/// https://drafts.csswg.org/css-transitions/#animtype-color
|
||||
impl Interpolate for CSSParserColor {
|
||||
#[inline]
|
||||
fn interpolate(&self, other: &Self, time: f64) -> Option<Self> {
|
||||
fn interpolate(&self, other: &Self, time: f64) -> Result<Self, ()> {
|
||||
match (*self, *other) {
|
||||
(CSSParserColor::RGBA(ref this), CSSParserColor::RGBA(ref other)) => {
|
||||
this.interpolate(other, time).and_then(|value| {
|
||||
Some(CSSParserColor::RGBA(value))
|
||||
})
|
||||
this.interpolate(other, time).map(CSSParserColor::RGBA)
|
||||
}
|
||||
(_, _) => None,
|
||||
_ => Err(()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -355,11 +327,10 @@ impl Interpolate for CSSParserColor {
|
|||
/// https://drafts.csswg.org/css-transitions/#animtype-lpcalc
|
||||
impl Interpolate for CalcLengthOrPercentage {
|
||||
#[inline]
|
||||
fn interpolate(&self, other: &CalcLengthOrPercentage, time: f64)
|
||||
-> Option<CalcLengthOrPercentage> {
|
||||
Some(CalcLengthOrPercentage {
|
||||
length: self.length().interpolate(&other.length(), time),
|
||||
percentage: self.percentage().interpolate(&other.percentage(), time),
|
||||
fn interpolate(&self, other: &Self, time: f64) -> Result<Self, ()> {
|
||||
Ok(CalcLengthOrPercentage {
|
||||
length: try!(self.length.interpolate(&other.length, time)),
|
||||
percentage: try!(self.percentage.interpolate(&other.percentage, time)),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -367,27 +338,21 @@ impl Interpolate for CalcLengthOrPercentage {
|
|||
/// https://drafts.csswg.org/css-transitions/#animtype-lpcalc
|
||||
impl Interpolate for LengthOrPercentage {
|
||||
#[inline]
|
||||
fn interpolate(&self, other: &LengthOrPercentage, time: f64)
|
||||
-> Option<LengthOrPercentage> {
|
||||
fn interpolate(&self, other: &Self, time: f64) -> Result<Self, ()> {
|
||||
match (*self, *other) {
|
||||
(LengthOrPercentage::Length(ref this),
|
||||
LengthOrPercentage::Length(ref other)) => {
|
||||
this.interpolate(other, time).and_then(|value| {
|
||||
Some(LengthOrPercentage::Length(value))
|
||||
})
|
||||
this.interpolate(other, time).map(LengthOrPercentage::Length)
|
||||
}
|
||||
(LengthOrPercentage::Percentage(ref this),
|
||||
LengthOrPercentage::Percentage(ref other)) => {
|
||||
this.interpolate(other, time).and_then(|value| {
|
||||
Some(LengthOrPercentage::Percentage(value))
|
||||
})
|
||||
this.interpolate(other, time).map(LengthOrPercentage::Percentage)
|
||||
}
|
||||
(this, other) => {
|
||||
let this: CalcLengthOrPercentage = From::from(this);
|
||||
let other: CalcLengthOrPercentage = From::from(other);
|
||||
this.interpolate(&other, time).and_then(|value| {
|
||||
Some(LengthOrPercentage::Calc(value))
|
||||
})
|
||||
this.interpolate(&other, time)
|
||||
.map(LengthOrPercentage::Calc)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -396,30 +361,26 @@ impl Interpolate for LengthOrPercentage {
|
|||
/// https://drafts.csswg.org/css-transitions/#animtype-lpcalc
|
||||
impl Interpolate for LengthOrPercentageOrAuto {
|
||||
#[inline]
|
||||
fn interpolate(&self, other: &LengthOrPercentageOrAuto, time: f64)
|
||||
-> Option<LengthOrPercentageOrAuto> {
|
||||
fn interpolate(&self, other: &Self, time: f64) -> Result<Self, ()> {
|
||||
match (*self, *other) {
|
||||
(LengthOrPercentageOrAuto::Length(ref this),
|
||||
LengthOrPercentageOrAuto::Length(ref other)) => {
|
||||
this.interpolate(other, time).and_then(|value| {
|
||||
Some(LengthOrPercentageOrAuto::Length(value))
|
||||
})
|
||||
this.interpolate(other, time).map(LengthOrPercentageOrAuto::Length)
|
||||
}
|
||||
(LengthOrPercentageOrAuto::Percentage(ref this),
|
||||
LengthOrPercentageOrAuto::Percentage(ref other)) => {
|
||||
this.interpolate(other, time).and_then(|value| {
|
||||
Some(LengthOrPercentageOrAuto::Percentage(value))
|
||||
})
|
||||
this.interpolate(other, time).map(LengthOrPercentageOrAuto::Percentage)
|
||||
}
|
||||
(LengthOrPercentageOrAuto::Auto, LengthOrPercentageOrAuto::Auto) => {
|
||||
Some(LengthOrPercentageOrAuto::Auto)
|
||||
Ok(LengthOrPercentageOrAuto::Auto)
|
||||
}
|
||||
(this, other) => {
|
||||
let this: Option<CalcLengthOrPercentage> = From::from(this);
|
||||
let other: Option<CalcLengthOrPercentage> = From::from(other);
|
||||
this.interpolate(&other, time).unwrap_or(None).and_then(|value| {
|
||||
Some(LengthOrPercentageOrAuto::Calc(value))
|
||||
})
|
||||
match this.interpolate(&other, time) {
|
||||
Ok(Some(result)) => Ok(LengthOrPercentageOrAuto::Calc(result)),
|
||||
_ => Err(()),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -428,25 +389,20 @@ impl Interpolate for LengthOrPercentageOrAuto {
|
|||
/// https://drafts.csswg.org/css-transitions/#animtype-lpcalc
|
||||
impl Interpolate for LengthOrPercentageOrNone {
|
||||
#[inline]
|
||||
fn interpolate(&self, other: &LengthOrPercentageOrNone, time: f64)
|
||||
-> Option<LengthOrPercentageOrNone> {
|
||||
fn interpolate(&self, other: &Self, time: f64) -> Result<Self, ()> {
|
||||
match (*self, *other) {
|
||||
(LengthOrPercentageOrNone::Length(ref this),
|
||||
LengthOrPercentageOrNone::Length(ref other)) => {
|
||||
this.interpolate(other, time).and_then(|value| {
|
||||
Some(LengthOrPercentageOrNone::Length(value))
|
||||
})
|
||||
this.interpolate(other, time).map(LengthOrPercentageOrNone::Length)
|
||||
}
|
||||
(LengthOrPercentageOrNone::Percentage(ref this),
|
||||
LengthOrPercentageOrNone::Percentage(ref other)) => {
|
||||
this.interpolate(other, time).and_then(|value| {
|
||||
Some(LengthOrPercentageOrNone::Percentage(value))
|
||||
})
|
||||
this.interpolate(other, time).map(LengthOrPercentageOrNone::Percentage)
|
||||
}
|
||||
(LengthOrPercentageOrNone::None, LengthOrPercentageOrNone::None) => {
|
||||
Some(LengthOrPercentageOrNone::None)
|
||||
Ok(LengthOrPercentageOrNone::None)
|
||||
}
|
||||
(_, _) => None,
|
||||
_ => Err(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -455,25 +411,20 @@ impl Interpolate for LengthOrPercentageOrNone {
|
|||
/// https://drafts.csswg.org/css-transitions/#animtype-length
|
||||
impl Interpolate for LineHeight {
|
||||
#[inline]
|
||||
fn interpolate(&self, other: &LineHeight, time: f64)
|
||||
-> Option<LineHeight> {
|
||||
fn interpolate(&self, other: &Self, time: f64) -> Result<Self, ()> {
|
||||
match (*self, *other) {
|
||||
(LineHeight::Length(ref this),
|
||||
LineHeight::Length(ref other)) => {
|
||||
this.interpolate(other, time).and_then(|value| {
|
||||
Some(LineHeight::Length(value))
|
||||
})
|
||||
this.interpolate(other, time).map(LineHeight::Length)
|
||||
}
|
||||
(LineHeight::Number(ref this),
|
||||
LineHeight::Number(ref other)) => {
|
||||
this.interpolate(other, time).and_then(|value| {
|
||||
Some(LineHeight::Number(value))
|
||||
})
|
||||
this.interpolate(other, time).map(LineHeight::Number)
|
||||
}
|
||||
(LineHeight::Normal, LineHeight::Normal) => {
|
||||
Some(LineHeight::Normal)
|
||||
Ok(LineHeight::Normal)
|
||||
}
|
||||
(_, _) => None,
|
||||
_ => Err(()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -481,12 +432,11 @@ impl Interpolate for LineHeight {
|
|||
/// http://dev.w3.org/csswg/css-transitions/#animtype-font-weight
|
||||
impl Interpolate for FontWeight {
|
||||
#[inline]
|
||||
fn interpolate(&self, other: &FontWeight, time: f64)
|
||||
-> Option<FontWeight> {
|
||||
fn interpolate(&self, other: &Self, time: f64) -> Result<Self, ()> {
|
||||
let a = (*self as u32) as f64;
|
||||
let b = (*other as u32) as f64;
|
||||
let weight = a + (b - a) * time;
|
||||
Some(if weight < 150. {
|
||||
Ok(if weight < 150. {
|
||||
FontWeight::Weight100
|
||||
} else if weight < 250. {
|
||||
FontWeight::Weight200
|
||||
|
@ -511,48 +461,38 @@ impl Interpolate for FontWeight {
|
|||
/// https://drafts.csswg.org/css-transitions/#animtype-rect
|
||||
impl Interpolate for ClipRect {
|
||||
#[inline]
|
||||
fn interpolate(&self, other: &ClipRect, time: f64)
|
||||
-> Option<ClipRect> {
|
||||
match (self.top.interpolate(&other.top, time),
|
||||
self.right.interpolate(&other.right, time),
|
||||
self.bottom.interpolate(&other.bottom, time),
|
||||
self.left.interpolate(&other.left, time)) {
|
||||
(Some(top), Some(right), Some(bottom), Some(left)) => {
|
||||
Some(ClipRect { top: top, right: right, bottom: bottom, left: left })
|
||||
},
|
||||
(_, _, _, _) => None,
|
||||
}
|
||||
fn interpolate(&self, other: &Self, time: f64) -> Result<Self, ()> {
|
||||
Ok(ClipRect {
|
||||
top: try!(self.top.interpolate(&other.top, time)),
|
||||
right: try!(self.right.interpolate(&other.right, time)),
|
||||
bottom: try!(self.bottom.interpolate(&other.bottom, time)),
|
||||
left: try!(self.left.interpolate(&other.left, time)),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/// https://drafts.csswg.org/css-transitions/#animtype-simple-list
|
||||
impl Interpolate for BackgroundPosition {
|
||||
#[inline]
|
||||
fn interpolate(&self, other: &BackgroundPosition, time: f64)
|
||||
-> Option<BackgroundPosition> {
|
||||
match (self.horizontal.interpolate(&other.horizontal, time),
|
||||
self.vertical.interpolate(&other.vertical, time)) {
|
||||
(Some(horizontal), Some(vertical)) => {
|
||||
Some(BackgroundPosition { horizontal: horizontal, vertical: vertical })
|
||||
},
|
||||
(_, _) => None,
|
||||
}
|
||||
fn interpolate(&self, other: &Self, time: f64) -> Result<Self, ()> {
|
||||
Ok(BackgroundPosition {
|
||||
horizontal: try!(self.horizontal.interpolate(&other.horizontal, time)),
|
||||
vertical: try!(self.vertical.interpolate(&other.vertical, time)),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl Interpolate for BackgroundSize {
|
||||
fn interpolate(&self, other: &Self, time: f64) -> Option<Self> {
|
||||
fn interpolate(&self, other: &Self, time: f64) -> Result<Self, ()> {
|
||||
use properties::longhands::background_size::computed_value::ExplicitSize;
|
||||
match (self, other) {
|
||||
(&BackgroundSize::Explicit(ref me), &BackgroundSize::Explicit(ref other))
|
||||
=> match (me.width.interpolate(&other.width, time),
|
||||
me.height.interpolate(&other.height, time)) {
|
||||
(Some(width), Some(height))
|
||||
=> Some(BackgroundSize::Explicit(
|
||||
ExplicitSize { width: width, height: height })),
|
||||
_ => None,
|
||||
},
|
||||
_ => None
|
||||
(&BackgroundSize::Explicit(ref me), &BackgroundSize::Explicit(ref other)) => {
|
||||
Ok(BackgroundSize::Explicit(ExplicitSize {
|
||||
width: try!(me.width.interpolate(&other.width, time)),
|
||||
height: try!(me.height.interpolate(&other.height, time)),
|
||||
}))
|
||||
}
|
||||
_ => Err(()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -560,25 +500,20 @@ impl Interpolate for BackgroundSize {
|
|||
/// https://drafts.csswg.org/css-transitions/#animtype-shadow-list
|
||||
impl Interpolate for TextShadow {
|
||||
#[inline]
|
||||
fn interpolate(&self, other: &TextShadow, time: f64)
|
||||
-> Option<TextShadow> {
|
||||
match (self.offset_x.interpolate(&other.offset_x, time),
|
||||
self.offset_y.interpolate(&other.offset_y, time),
|
||||
self.blur_radius.interpolate(&other.blur_radius, time),
|
||||
self.color.interpolate(&other.color, time)) {
|
||||
(Some(offset_x), Some(offset_y), Some(blur_radius), Some(color)) => {
|
||||
Some(TextShadow { offset_x: offset_x, offset_y: offset_y, blur_radius: blur_radius, color: color })
|
||||
},
|
||||
_ => None,
|
||||
}
|
||||
fn interpolate(&self, other: &Self, time: f64) -> Result<Self, ()> {
|
||||
Ok(TextShadow {
|
||||
offset_x: try!(self.offset_x.interpolate(&other.offset_x, time)),
|
||||
offset_y: try!(self.offset_y.interpolate(&other.offset_y, time)),
|
||||
blur_radius: try!(self.blur_radius.interpolate(&other.blur_radius, time)),
|
||||
color: try!(self.color.interpolate(&other.color, time)),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/// https://drafts.csswg.org/css-transitions/#animtype-shadow-list
|
||||
impl Interpolate for TextShadowList {
|
||||
#[inline]
|
||||
fn interpolate(&self, other: &TextShadowList, time: f64)
|
||||
-> Option<TextShadowList> {
|
||||
fn interpolate(&self, other: &Self, time: f64) -> Result<Self, ()> {
|
||||
let zero = TextShadow {
|
||||
offset_x: Au(0),
|
||||
offset_y: Au(0),
|
||||
|
@ -588,14 +523,25 @@ impl Interpolate for TextShadowList {
|
|||
})
|
||||
};
|
||||
|
||||
let interpolate_each = |(a, b): (&TextShadow, &TextShadow)| {
|
||||
a.interpolate(b, time).unwrap()
|
||||
};
|
||||
let max_len = cmp::max(self.0.len(), other.0.len());
|
||||
let mut result = Vec::with_capacity(max_len);
|
||||
|
||||
Some(TextShadowList(match self.0.len().cmp(&other.0.len()) {
|
||||
Ordering::Less => other.0.iter().chain(repeat(&zero)).zip(other.0.iter()).map(interpolate_each).collect(),
|
||||
_ => self.0.iter().zip(other.0.iter().chain(repeat(&zero))).map(interpolate_each).collect(),
|
||||
}))
|
||||
for i in 0..max_len {
|
||||
let shadow = match (self.0.get(i), other.0.get(i)) {
|
||||
(Some(shadow), Some(other))
|
||||
=> try!(shadow.interpolate(other, time)),
|
||||
(Some(shadow), None) => {
|
||||
shadow.interpolate(&zero, time).unwrap()
|
||||
}
|
||||
(None, Some(shadow)) => {
|
||||
zero.interpolate(&shadow, time).unwrap()
|
||||
}
|
||||
(None, None) => unreachable!(),
|
||||
};
|
||||
result.push(shadow);
|
||||
}
|
||||
|
||||
Ok(TextShadowList(result))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -725,8 +671,7 @@ fn build_identity_transform_list(list: &[TransformOperation]) -> Vec<TransformOp
|
|||
|
||||
impl Interpolate for BoxShadowList {
|
||||
#[inline]
|
||||
fn interpolate(&self, other: &Self, time: f64)
|
||||
-> Option<Self> {
|
||||
fn interpolate(&self, other: &Self, time: f64) -> Result<Self, ()> {
|
||||
// The inset value must change
|
||||
let mut zero = BoxShadow {
|
||||
offset_x: Au(0),
|
||||
|
@ -744,12 +689,8 @@ impl Interpolate for BoxShadowList {
|
|||
|
||||
for i in 0..max_len {
|
||||
let shadow = match (self.0.get(i), other.0.get(i)) {
|
||||
(Some(shadow), Some(other)) => {
|
||||
match shadow.interpolate(other, time) {
|
||||
Some(shadow) => shadow,
|
||||
None => return None,
|
||||
}
|
||||
}
|
||||
(Some(shadow), Some(other))
|
||||
=> try!(shadow.interpolate(other, time)),
|
||||
(Some(shadow), None) => {
|
||||
zero.inset = shadow.inset;
|
||||
shadow.interpolate(&zero, time).unwrap()
|
||||
|
@ -763,45 +704,25 @@ impl Interpolate for BoxShadowList {
|
|||
result.push(shadow);
|
||||
}
|
||||
|
||||
Some(BoxShadowList(result))
|
||||
Ok(BoxShadowList(result))
|
||||
}
|
||||
}
|
||||
|
||||
/// https://drafts.csswg.org/css-transitions/#animtype-shadow-list
|
||||
impl Interpolate for BoxShadow {
|
||||
#[inline]
|
||||
fn interpolate(&self, other: &Self, time: f64)
|
||||
-> Option<Self> {
|
||||
fn interpolate(&self, other: &Self, time: f64) -> Result<Self, ()> {
|
||||
if self.inset != other.inset {
|
||||
return None;
|
||||
return Err(());
|
||||
}
|
||||
|
||||
let x = match self.offset_x.interpolate(&other.offset_x, time) {
|
||||
Some(x) => x,
|
||||
None => return None,
|
||||
};
|
||||
let x = try!(self.offset_x.interpolate(&other.offset_x, time));
|
||||
let y = try!(self.offset_y.interpolate(&other.offset_y, time));
|
||||
let color = try!(self.color.interpolate(&other.color, time));
|
||||
let spread = try!(self.spread_radius.interpolate(&other.spread_radius, time));
|
||||
let blur = try!(self.blur_radius.interpolate(&other.blur_radius, time));
|
||||
|
||||
let y = match self.offset_y.interpolate(&other.offset_y, time) {
|
||||
Some(y) => y,
|
||||
None => return None,
|
||||
};
|
||||
|
||||
let color = match self.color.interpolate(&other.color, time) {
|
||||
Some(c) => c,
|
||||
None => return None,
|
||||
};
|
||||
|
||||
let spread = match self.spread_radius.interpolate(&other.spread_radius, time) {
|
||||
Some(s) => s,
|
||||
None => return None,
|
||||
};
|
||||
|
||||
let blur = match self.blur_radius.interpolate(&other.blur_radius, time) {
|
||||
Some(r) => r,
|
||||
None => return None,
|
||||
};
|
||||
|
||||
Some(BoxShadow {
|
||||
Ok(BoxShadow {
|
||||
offset_x: x,
|
||||
offset_y: y,
|
||||
blur_radius: blur,
|
||||
|
@ -813,36 +734,21 @@ impl Interpolate for BoxShadow {
|
|||
}
|
||||
|
||||
impl Interpolate for LengthOrNone {
|
||||
fn interpolate(&self, other: &Self, time: f64) -> Option<Self> {
|
||||
fn interpolate(&self, other: &Self, time: f64) -> Result<Self, ()> {
|
||||
match (*self, *other) {
|
||||
(LengthOrNone::Length(ref len), LengthOrNone::Length(ref other)) =>
|
||||
len.interpolate(&other, time).map(LengthOrNone::Length),
|
||||
_ => None,
|
||||
_ => Err(()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Interpolate for TransformOrigin {
|
||||
fn interpolate(&self, other: &Self, time: f64) -> Option<Self> {
|
||||
let horizontal = match self.horizontal.interpolate(&other.horizontal, time) {
|
||||
Some(h) => h,
|
||||
None => return None,
|
||||
};
|
||||
|
||||
let vertical = match self.vertical.interpolate(&other.vertical, time) {
|
||||
Some(v) => v,
|
||||
None => return None,
|
||||
};
|
||||
|
||||
let depth = match self.depth.interpolate(&other.depth, time) {
|
||||
Some(d) => d,
|
||||
None => return None,
|
||||
};
|
||||
|
||||
Some(TransformOrigin {
|
||||
horizontal: horizontal,
|
||||
vertical: vertical,
|
||||
depth: depth,
|
||||
fn interpolate(&self, other: &Self, time: f64) -> Result<Self, ()> {
|
||||
Ok(TransformOrigin {
|
||||
horizontal: try!(self.horizontal.interpolate(&other.horizontal, time)),
|
||||
vertical: try!(self.vertical.interpolate(&other.vertical, time)),
|
||||
depth: try!(self.depth.interpolate(&other.depth, time)),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -850,7 +756,7 @@ impl Interpolate for TransformOrigin {
|
|||
/// https://drafts.csswg.org/css-transforms/#interpolation-of-transforms
|
||||
impl Interpolate for TransformList {
|
||||
#[inline]
|
||||
fn interpolate(&self, other: &TransformList, time: f64) -> Option<TransformList> {
|
||||
fn interpolate(&self, other: &TransformList, time: f64) -> Result<Self, ()> {
|
||||
// http://dev.w3.org/csswg/css-transforms/#interpolation-of-transforms
|
||||
let result = match (&self.0, &other.0) {
|
||||
(&Some(ref from_list), &Some(ref to_list)) => {
|
||||
|
@ -873,6 +779,6 @@ impl Interpolate for TransformList {
|
|||
}
|
||||
};
|
||||
|
||||
Some(result)
|
||||
Ok(result)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue