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

@ -10,13 +10,13 @@
<%namespace name="helpers" file="/helpers.mako.rs" />
#[cfg(feature = "servo")] use app_units::Au;
use servo_arc::{Arc, UniqueArc};
use std::borrow::Cow;
use std::collections::HashSet;
use std::{fmt, mem, ops};
#[cfg(feature = "gecko")] use std::ptr;
use app_units::Au;
#[cfg(feature = "servo")] use cssparser::RGBA;
use cssparser::{Parser, TokenSerializationType, serialize_identifier};
use cssparser::ParserInput;
@ -43,6 +43,7 @@ use stylesheets::{CssRuleType, MallocSizeOf, MallocSizeOfFn, Origin, UrlExtraDat
#[cfg(feature = "servo")] use values::Either;
use values::generics::text::LineHeight;
use values::computed;
use values::computed::NonNegativeAu;
use cascade_info::CascadeInfo;
use rule_tree::{CascadeLevel, StrongRuleNode};
use self::computed_value_flags::ComputedValueFlags;
@ -1646,12 +1647,12 @@ pub use gecko_properties::style_structs;
/// The module where all the style structs are defined.
#[cfg(feature = "servo")]
pub mod style_structs {
use app_units::Au;
use fnv::FnvHasher;
use super::longhands;
use std::hash::{Hash, Hasher};
use logical_geometry::WritingMode;
use media_queries::Device;
use values::computed::NonNegativeAu;
% for style_struct in data.active_style_structs():
% if style_struct.name == "Font":
@ -1751,7 +1752,7 @@ pub mod style_structs {
/// Whether the border-${side} property has nonzero width.
#[allow(non_snake_case)]
pub fn border_${side}_has_nonzero_width(&self) -> bool {
self.border_${side}_width != ::app_units::Au(0)
self.border_${side}_width != NonNegativeAu::zero()
}
% endfor
% elif style_struct.name == "Font":
@ -1769,7 +1770,8 @@ pub mod style_structs {
/// (Servo does not handle MathML, so this just calls copy_font_size_from)
pub fn inherit_font_size_from(&mut self, parent: &Self,
_: Option<Au>, _: &Device) -> bool {
_: Option<NonNegativeAu>,
_: &Device) -> bool {
self.copy_font_size_from(parent);
false
}
@ -1777,19 +1779,19 @@ pub mod style_structs {
pub fn apply_font_size(&mut self,
v: longhands::font_size::computed_value::T,
_: &Self,
_: &Device) -> Option<Au> {
_: &Device) -> Option<NonNegativeAu> {
self.set_font_size(v);
None
}
/// (Servo does not handle MathML, so this does nothing)
pub fn apply_unconstrained_font_size(&mut self, _: Au) {
pub fn apply_unconstrained_font_size(&mut self, _: NonNegativeAu) {
}
% elif style_struct.name == "Outline":
/// Whether the outline-width property is non-zero.
#[inline]
pub fn outline_has_nonzero_width(&self) -> bool {
self.outline_width != ::app_units::Au(0)
self.outline_width != NonNegativeAu::zero()
}
% elif style_struct.name == "Text":
/// Whether the text decoration has an underline.
@ -2189,10 +2191,10 @@ impl ComputedValuesInner {
pub fn logical_padding(&self) -> LogicalMargin<computed::LengthOrPercentage> {
let padding_style = self.get_padding();
LogicalMargin::from_physical(self.writing_mode, SideOffsets2D::new(
padding_style.padding_top,
padding_style.padding_right,
padding_style.padding_bottom,
padding_style.padding_left,
padding_style.padding_top.0,
padding_style.padding_right.0,
padding_style.padding_bottom.0,
padding_style.padding_left.0,
))
}
@ -2201,10 +2203,10 @@ impl ComputedValuesInner {
pub fn border_width_for_writing_mode(&self, writing_mode: WritingMode) -> LogicalMargin<Au> {
let border_style = self.get_border();
LogicalMargin::from_physical(writing_mode, SideOffsets2D::new(
border_style.border_top_width,
border_style.border_right_width,
border_style.border_bottom_width,
border_style.border_left_width,
border_style.border_top_width.0,
border_style.border_right_width.0,
border_style.border_bottom_width.0,
border_style.border_left_width.0,
))
}
@ -3359,7 +3361,7 @@ pub fn adjust_border_width(style: &mut StyleBuilder) {
// Like calling to_computed_value, which wouldn't type check.
if style.get_border().clone_border_${side}_style().none_or_hidden() &&
style.get_border().border_${side}_has_nonzero_width() {
style.set_border_${side}_width(Au(0));
style.set_border_${side}_width(NonNegativeAu::zero());
}
% endfor
}
@ -3383,7 +3385,7 @@ pub fn modify_border_style_for_inline_sides(style: &mut Arc<ComputedValues>,
PhysicalSide::Top => (border.border_top_width, border.border_top_style),
PhysicalSide::Bottom => (border.border_bottom_width, border.border_bottom_style),
};
if current_style == (Au(0), BorderStyle::none) {
if current_style == (NonNegativeAu::zero(), BorderStyle::none) {
return;
}
}
@ -3391,19 +3393,19 @@ pub fn modify_border_style_for_inline_sides(style: &mut Arc<ComputedValues>,
let border = Arc::make_mut(&mut style.border);
match side {
PhysicalSide::Left => {
border.border_left_width = Au(0);
border.border_left_width = NonNegativeAu::zero();
border.border_left_style = BorderStyle::none;
}
PhysicalSide::Right => {
border.border_right_width = Au(0);
border.border_right_width = NonNegativeAu::zero();
border.border_right_style = BorderStyle::none;
}
PhysicalSide::Bottom => {
border.border_bottom_width = Au(0);
border.border_bottom_width = NonNegativeAu::zero();
border.border_bottom_style = BorderStyle::none;
}
PhysicalSide::Top => {
border.border_top_width = Au(0);
border.border_top_width = NonNegativeAu::zero();
border.border_top_style = BorderStyle::none;
}
}