Auto merge of #17783 - BorisChiou:stylo/animation/restrictions, r=nox

stylo: Bug 1374233 - Clamp interpolated values for properties which need to be restricted

Some properties only accept non-negative values, or values greater than or equal to one. It is possible to produce an negative interpolated values while using negative timing functions, so we have to apply a restriction to these values to avoid getting invalid values.

For example, line-height must be non-negative, but the output progress of some timing functions (e,g. cubic-bezier(0.25, -2, 0.75, 1)) may be a negative value, so the interpolated result of line-height is also negative.

---
- [X] `./mach build -d` does not report any errors
- [X] `./mach test-tidy` does not report any errors
- [X] These changes fix Bug 1374233.
- [X] These changes do not require tests because we have tests in Gecko side already.

<!-- 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/17783)
<!-- Reviewable:end -->
This commit is contained in:
bors-servo 2017-08-07 11:05:17 -05:00 committed by GitHub
commit 016ea11cba
56 changed files with 1039 additions and 371 deletions

View file

@ -16,8 +16,11 @@ use euclid::{Point2D, Size2D};
#[cfg(feature = "gecko")] use gecko_string_cache::Atom;
use properties::{CSSWideKeyword, PropertyDeclaration};
use properties::longhands;
use properties::longhands::background_size::computed_value::T as BackgroundSizeList;
use properties::longhands::border_spacing::computed_value::T as BorderSpacing;
use properties::longhands::font_weight::computed_value::T as FontWeight;
use properties::longhands::font_stretch::computed_value::T as FontStretch;
use properties::longhands::line_height::computed_value::T as LineHeight;
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;
@ -43,6 +46,10 @@ use values::computed::{Angle, LengthOrPercentageOrAuto, LengthOrPercentageOrNone
use values::computed::{BorderCornerRadius, ClipRect};
use values::computed::{CalcLengthOrPercentage, Color, Context, ComputedValueAsSpecified};
use values::computed::{LengthOrPercentage, MaxLength, MozLength, Percentage, ToComputedValue};
use values::computed::{NonNegativeAu, NonNegativeNumber, PositiveIntegerOrAuto};
use values::computed::length::{NonNegativeLengthOrAuto, NonNegativeLengthOrNormal};
use values::computed::length::NonNegativeLengthOrPercentage;
use values::generics::{GreaterThanOrEqualToOne, NonNegative};
use values::generics::border::BorderCornerRadius as GenericBorderCornerRadius;
use values::generics::effects::Filter;
use values::generics::position as generic_position;
@ -777,6 +784,7 @@ impl ToAnimatedZero for AnimationValue {
impl RepeatableListAnimatable for LengthOrPercentage {}
impl RepeatableListAnimatable for Either<f32, LengthOrPercentage> {}
impl RepeatableListAnimatable for Either<NonNegativeNumber, NonNegativeLengthOrPercentage> {}
macro_rules! repeated_vec_impl {
($($ty:ty),*) => {
@ -3191,7 +3199,7 @@ fn add_weighted_filter_function_impl(from: &AnimatedFilter,
&to_value,
self_portion,
other_portion,
&0.0,
&NonNegative::<CSSFloat>(0.0),
)?))
},
% endfor
@ -3202,7 +3210,7 @@ fn add_weighted_filter_function_impl(from: &AnimatedFilter,
&to_value,
self_portion,
other_portion,
&1.0,
&NonNegative::<CSSFloat>(1.0),
)?))
},
% endfor
@ -3373,3 +3381,49 @@ sorted_shorthands = [(p, position) for position, p in enumerate(sorted_shorthand
% endfor
}
}
impl<T> Animatable for NonNegative<T>
where T: Animatable + Clone
{
#[inline]
fn add_weighted(&self, other: &Self, self_portion: f64, other_portion: f64) -> Result<Self, ()> {
self.0.add_weighted(&other.0, self_portion, other_portion).map(NonNegative::<T>)
}
#[inline]
fn compute_distance(&self, other: &Self) -> Result<f64, ()> {
self.0.compute_distance(&other.0)
}
}
impl<T> ToAnimatedZero for NonNegative<T>
where T: ToAnimatedZero
{
#[inline]
fn to_animated_zero(&self) -> Result<Self, ()> {
self.0.to_animated_zero().map(NonNegative::<T>)
}
}
impl<T> Animatable for GreaterThanOrEqualToOne<T>
where T: Animatable + Clone
{
#[inline]
fn add_weighted(&self, other: &Self, self_portion: f64, other_portion: f64) -> Result<Self, ()> {
self.0.add_weighted(&other.0, self_portion, other_portion).map(GreaterThanOrEqualToOne::<T>)
}
#[inline]
fn compute_distance(&self, other: &Self) -> Result<f64, ()> {
self.0.compute_distance(&other.0)
}
}
impl<T> ToAnimatedZero for GreaterThanOrEqualToOne<T>
where T: ToAnimatedZero
{
#[inline]
fn to_animated_zero(&self) -> Result<Self, ()> {
self.0.to_animated_zero().map(GreaterThanOrEqualToOne::<T>)
}
}