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

@ -1860,10 +1860,10 @@ impl ComputedValueUtils for ComputedValues {
!padding.padding_right.is_definitely_zero() ||
!padding.padding_bottom.is_definitely_zero() ||
!padding.padding_left.is_definitely_zero() ||
border.border_top_width != Au(0) ||
border.border_right_width != Au(0) ||
border.border_bottom_width != Au(0) ||
border.border_left_width != Au(0)
border.border_top_width.0 != Au(0) ||
border.border_right_width.0 != Au(0) ||
border.border_bottom_width.0 != Au(0) ||
border.border_left_width.0 != Au(0)
}
}

View file

@ -1393,7 +1393,7 @@ impl FragmentDisplayListBuilding for Fragment {
box_shadow.base.horizontal,
box_shadow.base.vertical,
)),
box_shadow.base.blur,
box_shadow.base.blur.0,
box_shadow.spread,
);
@ -1408,7 +1408,7 @@ impl FragmentDisplayListBuilding for Fragment {
box_bounds: *absolute_bounds,
color: style.resolve_color(box_shadow.base.color).to_gfx_color(),
offset: Vector2D::new(box_shadow.base.horizontal, box_shadow.base.vertical),
blur_radius: box_shadow.base.blur,
blur_radius: box_shadow.base.blur.0,
spread_radius: box_shadow.spread,
border_radius: model::specified_border_radius(style.get_border()
.border_top_left_radius,
@ -1577,7 +1577,7 @@ impl FragmentDisplayListBuilding for Fragment {
clip: &Rect<Au>) {
use style::values::Either;
let width = style.get_outline().outline_width;
let width = style.get_outline().outline_width.0;
if width == Au(0) {
return
}
@ -2054,7 +2054,7 @@ impl FragmentDisplayListBuilding for Fragment {
let effects = self.style().get_effects();
let mut filters = effects.filter.0.clone();
if effects.opacity != 1.0 {
filters.push(Filter::Opacity(effects.opacity))
filters.push(Filter::Opacity(effects.opacity.into()))
}
let context_type = match mode {
@ -2129,7 +2129,7 @@ impl FragmentDisplayListBuilding for Fragment {
for shadow in text_shadows.iter().rev() {
state.add_display_item(DisplayItem::PushTextShadow(box PushTextShadowDisplayItem {
base: base.clone(),
blur_radius: shadow.blur,
blur_radius: shadow.blur.0,
offset: Vector2D::new(shadow.horizontal, shadow.vertical),
color: self.style().resolve_color(shadow.color).to_gfx_color(),
}));

View file

@ -137,8 +137,8 @@ impl FlexItem {
min_size: Au(0),
max_size: MAX_AU,
index: index,
flex_grow: flex_grow,
flex_shrink: flex_shrink,
flex_grow: flex_grow.into(),
flex_shrink: flex_shrink.into(),
order: order,
is_frozen: false,
is_strut: false

View file

@ -2570,13 +2570,13 @@ impl Fragment {
// Box shadows cause us to draw outside our border box.
for box_shadow in &self.style().get_effects().box_shadow.0 {
let offset = Vector2D::new(box_shadow.base.horizontal, box_shadow.base.vertical);
let inflation = box_shadow.spread + box_shadow.base.blur * BLUR_INFLATION_FACTOR;
let inflation = box_shadow.spread + box_shadow.base.blur.0 * BLUR_INFLATION_FACTOR;
overflow.paint = overflow.paint.union(&border_box.translate(&offset)
.inflate(inflation, inflation))
}
// Outlines cause us to draw outside our border box.
let outline_width = self.style.get_outline().outline_width;
let outline_width = self.style.get_outline().outline_width.0;
if outline_width != Au(0) {
overflow.paint = overflow.paint.union(&border_box.inflate(outline_width,
outline_width))

View file

@ -98,20 +98,20 @@ impl Flow for MulticolFlow {
let column_style = self.block_flow.fragment.style.get_column();
let column_gap = match column_style.column_gap {
Either::First(len) => len,
Either::Second(_normal) => self.block_flow.fragment.style.get_font().font_size,
Either::First(len) => len.0,
Either::Second(_normal) => self.block_flow.fragment.style.get_font().font_size.0,
};
let mut column_count;
if let Either::First(column_width) = column_style.column_width {
column_count =
max(1, (content_inline_size + column_gap).0 / (column_width + column_gap).0);
max(1, (content_inline_size + column_gap).0 / (column_width.0 + column_gap).0);
if let Either::First(specified_column_count) = column_style.column_count {
column_count = min(column_count, specified_column_count as i32);
column_count = min(column_count, specified_column_count.0 as i32);
}
} else {
column_count = match column_style.column_count {
Either::First(n) => n,
Either::First(n) => n.0,
_ => unreachable!(),
}
}

View file

@ -450,10 +450,10 @@ impl FragmentBorderBoxIterator for FragmentLocatingFragmentIterator {
border_left_width: left_width,
..
} = *fragment.style.get_border();
self.client_rect.origin.y = top_width.to_px();
self.client_rect.origin.x = left_width.to_px();
self.client_rect.size.width = (border_box.size.width - left_width - right_width).to_px();
self.client_rect.size.height = (border_box.size.height - top_width - bottom_width).to_px();
self.client_rect.origin.y = top_width.0.to_px();
self.client_rect.origin.x = left_width.0.to_px();
self.client_rect.size.width = (border_box.size.width - left_width.0 - right_width.0).to_px();
self.client_rect.size.height = (border_box.size.height - top_width.0 - bottom_width.0).to_px();
}
fn should_process(&mut self, fragment: &Fragment) -> bool {
@ -476,10 +476,10 @@ impl FragmentBorderBoxIterator for UnioningFragmentScrollAreaIterator {
border_left_width: left_border,
..
} = *fragment.style.get_border();
let right_padding = (border_box.size.width - right_border - left_border).to_px();
let bottom_padding = (border_box.size.height - bottom_border - top_border).to_px();
let top_padding = top_border.to_px();
let left_padding = left_border.to_px();
let right_padding = (border_box.size.width - right_border.0 - left_border.0).to_px();
let bottom_padding = (border_box.size.height - bottom_border.0 - top_border.0).to_px();
let top_padding = top_border.0.to_px();
let left_padding = left_border.0.to_px();
match self.level {
Some(start_level) if level <= start_level => { self.is_child = false; }

View file

@ -27,7 +27,7 @@ use style::logical_geometry::LogicalSize;
use style::properties::ComputedValues;
use style::servo::restyle_damage::{REFLOW, REFLOW_OUT_OF_FLOW};
use style::values::CSSFloat;
use style::values::computed::LengthOrPercentageOrAuto;
use style::values::computed::{LengthOrPercentageOrAuto, NonNegativeAu};
use table_row::{self, CellIntrinsicInlineSize, CollapsedBorder, CollapsedBorderProvenance};
use table_row::TableRowFlow;
use table_wrapper::TableLayout;
@ -190,8 +190,8 @@ impl TableFlow {
border_collapse::T::separate => style.get_inheritedtable().border_spacing,
border_collapse::T::collapse => {
border_spacing::T {
horizontal: Au(0),
vertical: Au(0),
horizontal: NonNegativeAu::zero(),
vertical: NonNegativeAu::zero(),
}
}
}
@ -202,7 +202,7 @@ impl TableFlow {
if num_columns == 0 {
return Au(0);
}
self.spacing().horizontal * (num_columns as i32 + 1)
self.spacing().horizontal.0 * (num_columns as i32 + 1)
}
}
@ -469,7 +469,7 @@ impl Flow for TableFlow {
fn assign_block_size(&mut self, _: &LayoutContext) {
debug!("assign_block_size: assigning block_size for table");
let vertical_spacing = self.spacing().vertical;
let vertical_spacing = self.spacing().vertical.0;
self.block_flow.assign_block_size_for_table_like_flow(vertical_spacing)
}

View file

@ -25,7 +25,7 @@ use style::computed_values::{border_collapse, border_spacing, border_top_style};
use style::logical_geometry::{LogicalSize, PhysicalSide, WritingMode};
use style::properties::ComputedValues;
use style::servo::restyle_damage::{REFLOW, REFLOW_OUT_OF_FLOW};
use style::values::computed::{Color, LengthOrPercentageOrAuto};
use style::values::computed::{Color, LengthOrPercentageOrAuto, NonNegativeAu};
use table::{ColumnComputedInlineSize, ColumnIntrinsicInlineSize, InternalTable, VecExt};
use table_cell::{CollapsedBordersForCell, TableCellFlow};
@ -93,8 +93,8 @@ impl TableRowFlow {
column_computed_inline_sizes: Vec::new(),
incoming_rowspan: Vec::new(),
spacing: border_spacing::T {
horizontal: Au(0),
vertical: Au(0),
horizontal: NonNegativeAu::zero(),
vertical: NonNegativeAu::zero(),
},
table_writing_mode: writing_mode,
preliminary_collapsed_borders: CollapsedBordersForRow::new(),
@ -395,7 +395,7 @@ impl Flow for TableRowFlow {
None => break,
};
column_computed_inline_size.size = column_computed_inline_size.size +
extra_column_computed_inline_size.size + self.spacing.horizontal;
extra_column_computed_inline_size.size + self.spacing.horizontal.0;
col += 1;
}
@ -616,7 +616,7 @@ impl CollapsedBorder {
-> CollapsedBorder {
CollapsedBorder {
style: css_style.get_border().border_top_style,
width: css_style.get_border().border_top_width,
width: css_style.get_border().border_top_width.0,
color: css_style.get_border().border_top_color,
provenance: provenance,
}
@ -628,7 +628,7 @@ impl CollapsedBorder {
-> CollapsedBorder {
CollapsedBorder {
style: css_style.get_border().border_right_style,
width: css_style.get_border().border_right_width,
width: css_style.get_border().border_right_width.0,
color: css_style.get_border().border_right_color,
provenance: provenance,
}
@ -640,7 +640,7 @@ impl CollapsedBorder {
-> CollapsedBorder {
CollapsedBorder {
style: css_style.get_border().border_bottom_style,
width: css_style.get_border().border_bottom_width,
width: css_style.get_border().border_bottom_width.0,
color: css_style.get_border().border_bottom_color,
provenance: provenance,
}
@ -652,7 +652,7 @@ impl CollapsedBorder {
-> CollapsedBorder {
CollapsedBorder {
style: css_style.get_border().border_left_style,
width: css_style.get_border().border_left_width,
width: css_style.get_border().border_left_width.0,
color: css_style.get_border().border_left_color,
provenance: provenance,
}
@ -818,7 +818,7 @@ fn set_inline_position_of_child_flow(
let column_inline_size = column_computed_inline_sizes[*column_index].size;
let border_inline_size = match *border_collapse_info {
Some(_) => Au(0), // FIXME: Make collapsed borders account for colspan/rowspan.
None => border_spacing.horizontal,
None => border_spacing.horizontal.0,
};
if reverse_column_order {
*inline_end_margin_edge += column_inline_size + border_inline_size;
@ -873,9 +873,9 @@ fn set_inline_position_of_child_flow(
None => {
// Take spacing into account.
if reverse_column_order {
*inline_end_margin_edge += border_spacing.horizontal;
*inline_end_margin_edge += border_spacing.horizontal.0;
} else {
*inline_start_margin_edge += border_spacing.horizontal;
*inline_start_margin_edge += border_spacing.horizontal.0;
}
}
}

View file

@ -21,6 +21,7 @@ use std::iter::{IntoIterator, Iterator, Peekable};
use style::computed_values::{border_collapse, border_spacing};
use style::logical_geometry::LogicalSize;
use style::properties::ComputedValues;
use style::values::computed::NonNegativeAu;
use table::{ColumnIntrinsicInlineSize, InternalTable, TableLikeFlow};
/// A table formatting context.
@ -55,8 +56,8 @@ impl TableRowGroupFlow {
block_flow: BlockFlow::from_fragment(fragment),
column_intrinsic_inline_sizes: Vec::new(),
spacing: border_spacing::T {
horizontal: Au(0),
vertical: Au(0),
horizontal: NonNegativeAu::zero(),
vertical: NonNegativeAu::zero(),
},
collapsed_inline_direction_border_widths_for_table: Vec::new(),
collapsed_block_direction_border_widths_for_table: Vec::new(),
@ -161,7 +162,7 @@ impl Flow for TableRowGroupFlow {
fn assign_block_size(&mut self, _: &LayoutContext) {
debug!("assign_block_size: assigning block_size for table_rowgroup");
self.block_flow.assign_block_size_for_table_like_flow(self.spacing.vertical)
self.block_flow.assign_block_size_for_table_like_flow(self.spacing.vertical.0)
}
fn compute_absolute_position(&mut self, layout_context: &LayoutContext) {

View file

@ -446,11 +446,11 @@ pub fn font_metrics_for_style(font_context: &mut FontContext, font_style: ::Serv
/// Returns the line block-size needed by the given computed style and font size.
pub fn line_height_from_style(style: &ComputedValues, metrics: &FontMetrics) -> Au {
let font_size = style.get_font().font_size;
let font_size = style.get_font().font_size.0;
match style.get_inheritedtext().line_height {
LineHeight::Normal => metrics.line_gap,
LineHeight::Number(l) => font_size.scale_by(l),
LineHeight::Length(l) => l
LineHeight::Number(l) => font_size.scale_by(l.0),
LineHeight::Length(l) => l.0
}
}

View file

@ -190,15 +190,15 @@ impl ToFilterOps for Vec<Filter> {
let mut result = Vec::with_capacity(self.len());
for filter in self.iter() {
match *filter {
GenericFilter::Blur(radius) => result.push(webrender_api::FilterOp::Blur(radius.to_f32_px())),
GenericFilter::Brightness(amount) => result.push(webrender_api::FilterOp::Brightness(amount)),
GenericFilter::Contrast(amount) => result.push(webrender_api::FilterOp::Contrast(amount)),
GenericFilter::Grayscale(amount) => result.push(webrender_api::FilterOp::Grayscale(amount)),
GenericFilter::Blur(radius) => result.push(webrender_api::FilterOp::Blur(radius.0.to_f32_px())),
GenericFilter::Brightness(amount) => result.push(webrender_api::FilterOp::Brightness(amount.0)),
GenericFilter::Contrast(amount) => result.push(webrender_api::FilterOp::Contrast(amount.0)),
GenericFilter::Grayscale(amount) => result.push(webrender_api::FilterOp::Grayscale(amount.0)),
GenericFilter::HueRotate(angle) => result.push(webrender_api::FilterOp::HueRotate(angle.radians())),
GenericFilter::Invert(amount) => result.push(webrender_api::FilterOp::Invert(amount)),
GenericFilter::Opacity(amount) => result.push(webrender_api::FilterOp::Opacity(amount.into())),
GenericFilter::Saturate(amount) => result.push(webrender_api::FilterOp::Saturate(amount)),
GenericFilter::Sepia(amount) => result.push(webrender_api::FilterOp::Sepia(amount)),
GenericFilter::Invert(amount) => result.push(webrender_api::FilterOp::Invert(amount.0)),
GenericFilter::Opacity(amount) => result.push(webrender_api::FilterOp::Opacity(amount.0.into())),
GenericFilter::Saturate(amount) => result.push(webrender_api::FilterOp::Saturate(amount.0)),
GenericFilter::Sepia(amount) => result.push(webrender_api::FilterOp::Sepia(amount.0)),
GenericFilter::DropShadow(ref shadow) => match *shadow {},
}
}