style: Fix servo build.

This also fixes a bunch of calc handling issues and such.

Also remove tests that no longer compile and are covered by WPT.
This commit is contained in:
Emilio Cobos Álvarez 2019-01-07 16:43:10 +01:00
parent ca503b4908
commit 4a31509215
17 changed files with 199 additions and 436 deletions

View file

@ -66,8 +66,7 @@ use style::context::SharedStyleContext;
use style::logical_geometry::{LogicalMargin, LogicalPoint, LogicalRect, LogicalSize, WritingMode};
use style::properties::ComputedValues;
use style::servo::restyle_damage::ServoRestyleDamage;
use style::values::computed::LengthOrPercentageOrAuto;
use style::values::computed::{LengthOrPercentage, LengthOrPercentageOrNone};
use style::values::computed::{LengthOrPercentageOrAuto, LengthOrPercentageOrNone};
/// Information specific to floated blocks.
#[derive(Clone, Serialize)]
@ -418,42 +417,23 @@ impl CandidateBSizeIterator {
// If that is not determined yet by the time we need to resolve
// `min-height` and `max-height`, percentage values are ignored.
let block_size = match (
fragment.style.content_block_size(),
block_container_block_size,
) {
(LengthOrPercentageOrAuto::Percentage(percent), Some(block_container_block_size)) => {
MaybeAuto::Specified(block_container_block_size.scale_by(percent.0))
let block_size = match fragment.style.content_block_size() {
LengthOrPercentageOrAuto::Auto => MaybeAuto::Auto,
LengthOrPercentageOrAuto::LengthOrPercentage(ref lp) => {
MaybeAuto::from_option(lp.maybe_to_used_value(block_container_block_size))
},
(LengthOrPercentageOrAuto::Calc(calc), _) => {
MaybeAuto::from_option(calc.to_used_value(block_container_block_size))
},
(LengthOrPercentageOrAuto::Percentage(_), None) |
(LengthOrPercentageOrAuto::Auto, _) => MaybeAuto::Auto,
(LengthOrPercentageOrAuto::Length(length), _) => MaybeAuto::Specified(Au::from(length)),
};
let max_block_size = match (fragment.style.max_block_size(), block_container_block_size) {
(LengthOrPercentageOrNone::Percentage(percent), Some(block_container_block_size)) => {
Some(block_container_block_size.scale_by(percent.0))
let max_block_size = match fragment.style.max_block_size() {
LengthOrPercentageOrNone::None => None,
LengthOrPercentageOrNone::LengthOrPercentage(ref lp) => {
lp.maybe_to_used_value(block_container_block_size)
},
(LengthOrPercentageOrNone::Calc(calc), _) => {
calc.to_used_value(block_container_block_size)
},
(LengthOrPercentageOrNone::Percentage(_), None) |
(LengthOrPercentageOrNone::None, _) => None,
(LengthOrPercentageOrNone::Length(length), _) => Some(Au::from(length)),
};
let min_block_size = match (fragment.style.min_block_size(), block_container_block_size) {
(LengthOrPercentage::Percentage(percent), Some(block_container_block_size)) => {
block_container_block_size.scale_by(percent.0)
},
(LengthOrPercentage::Calc(calc), _) => calc
.to_used_value(block_container_block_size)
.unwrap_or(Au(0)),
(LengthOrPercentage::Percentage(_), None) => Au(0),
(LengthOrPercentage::Length(length), _) => Au::from(length),
};
let min_block_size =
fragment.style.min_block_size().maybe_to_used_value(block_container_block_size).unwrap_or(Au(0));
// If the style includes `box-sizing: border-box`, subtract the border and padding.
let adjustment_for_box_sizing = match fragment.style.get_position().box_sizing {
BoxSizing::BorderBox => fragment.border_padding.block_start_end(),
@ -1415,15 +1395,9 @@ impl BlockFlow {
pub fn explicit_block_size(&self, containing_block_size: Option<Au>) -> Option<Au> {
let content_block_size = self.fragment.style().content_block_size();
match (content_block_size, containing_block_size) {
(LengthOrPercentageOrAuto::Calc(calc), _) => calc.to_used_value(containing_block_size),
(LengthOrPercentageOrAuto::Length(length), _) => Some(Au::from(length)),
(LengthOrPercentageOrAuto::Percentage(percent), Some(container_size)) => {
Some(container_size.scale_by(percent.0))
},
(LengthOrPercentageOrAuto::Percentage(_), None) |
(LengthOrPercentageOrAuto::Auto, None) => None,
(LengthOrPercentageOrAuto::Auto, Some(container_size)) => {
match content_block_size {
LengthOrPercentageOrAuto::Auto => {
let container_size = containing_block_size?;
let (block_start, block_end) = {
let position = self.fragment.style().logical_position();
(
@ -1454,10 +1428,12 @@ impl BlockFlow {
let sum = block_start + block_end + margin_block_start + margin_block_end;
Some(available_block_size - sum)
},
(_, _) => None,
}
},
LengthOrPercentageOrAuto::LengthOrPercentage(ref lp) => {
lp.maybe_to_used_value(containing_block_size)
},
}
}
@ -2177,8 +2153,8 @@ impl Flow for BlockFlow {
// If this block has a fixed width, just use that for the minimum and preferred width,
// rather than bubbling up children inline width.
let consult_children = match self.fragment.style().get_position().width {
LengthOrPercentageOrAuto::Length(_) => false,
_ => true,
LengthOrPercentageOrAuto::Auto => true,
LengthOrPercentageOrAuto::LengthOrPercentage(ref lp) => lp.maybe_to_used_value(None).is_none(),
};
self.bubble_inline_sizes_for_block(consult_children);
self.fragment

View file

@ -107,14 +107,14 @@ fn convert_gradient_stops(
{
let first = stop_items.first_mut().unwrap();
if first.position.is_none() {
first.position = Some(LengthOrPercentage::Percentage(Percentage(0.0)));
first.position = Some(LengthOrPercentage::new_percent(Percentage(0.)));
}
}
// If the last color stop does not have a position, set its position to 100%.
{
let last = stop_items.last_mut().unwrap();
if last.position.is_none() {
last.position = Some(LengthOrPercentage::Percentage(Percentage(1.0)));
last.position = Some(LengthOrPercentage::new_percent(Percentage(1.0)));
}
}
@ -214,13 +214,7 @@ fn position_to_offset(position: LengthOrPercentage, total_length: Au) -> f32 {
if total_length == Au(0) {
return 0.0;
}
match position {
LengthOrPercentage::Length(l) => l.to_i32_au() as f32 / total_length.0 as f32,
LengthOrPercentage::Percentage(percentage) => percentage.0 as f32,
LengthOrPercentage::Calc(calc) => {
calc.to_used_value(Some(total_length)).unwrap().0 as f32 / total_length.0 as f32
},
}
position.to_used_value(total_length).0 as f32 / total_length.0 as f32
}
pub fn linear(

View file

@ -12,7 +12,7 @@ use crate::floats::FloatKind;
use crate::flow::{Flow, FlowClass, FlowFlags, GetBaseFlow, ImmutableFlowUtils, OpaqueFlow};
use crate::fragment::{Fragment, FragmentBorderBoxIterator, Overflow};
use crate::layout_debug;
use crate::model::{AdjoiningMargins, CollapsibleMargins};
use crate::model::{self, AdjoiningMargins, CollapsibleMargins};
use crate::model::{IntrinsicISizes, MaybeAuto, SizeConstraint};
use crate::traversal::PreorderFlowTraversal;
use app_units::{Au, MAX_AU};
@ -52,18 +52,15 @@ impl AxisSize {
max: LengthOrPercentageOrNone,
) -> AxisSize {
match size {
LengthOrPercentageOrAuto::Length(length) => AxisSize::Definite(Au::from(length)),
LengthOrPercentageOrAuto::Percentage(percent) => match content_size {
Some(size) => AxisSize::Definite(size.scale_by(percent.0)),
None => AxisSize::Infinite,
},
LengthOrPercentageOrAuto::Calc(calc) => match calc.to_used_value(content_size) {
Some(length) => AxisSize::Definite(length),
None => AxisSize::Infinite,
},
LengthOrPercentageOrAuto::Auto => {
AxisSize::MinMax(SizeConstraint::new(content_size, min, max, None))
},
}
LengthOrPercentageOrAuto::LengthOrPercentage(ref lp) => {
match lp.maybe_to_used_value(content_size) {
Some(length) => AxisSize::Definite(length),
None => AxisSize::Infinite,
}
}
}
}
}
@ -461,10 +458,11 @@ impl FlexFlow {
// Currently, this is the core of BlockFlow::bubble_inline_sizes() with all float logic
// stripped out, and max replaced with union_nonbreaking_inline.
fn inline_mode_bubble_inline_sizes(&mut self) {
let fixed_width = match self.block_flow.fragment.style().get_position().width {
LengthOrPercentageOrAuto::Length(_) => true,
_ => false,
};
// FIXME(emilio): This doesn't handle at all writing-modes.
let fixed_width = !model::style_length(
self.block_flow.fragment.style().get_position().width,
None,
).is_auto();
let mut computation = self.block_flow.fragment.compute_intrinsic_inline_sizes();
if !fixed_width {
@ -488,10 +486,10 @@ impl FlexFlow {
// Currently, this is the core of BlockFlow::bubble_inline_sizes() with all float logic
// stripped out.
fn block_mode_bubble_inline_sizes(&mut self) {
let fixed_width = match self.block_flow.fragment.style().get_position().width {
LengthOrPercentageOrAuto::Length(_) => true,
_ => false,
};
let fixed_width = !model::style_length(
self.block_flow.fragment.style().get_position().width,
None,
).is_auto();
let mut computation = self.block_flow.fragment.compute_intrinsic_inline_sizes();
if !fixed_width {

View file

@ -542,16 +542,21 @@ impl SpeculatedFloatPlacement {
let mut float_inline_size = base_flow.intrinsic_inline_sizes.preferred_inline_size;
if float_inline_size == Au(0) {
if flow.is_block_like() {
// Hack: If the size of the float is a percentage, then there's no way we can guess
// at its size now. So just pick an arbitrary nonzero value (in this case, 1px) so
// that the layout traversal logic will know that objects later in the document
// Hack: If the size of the float is not fixed, then there's no
// way we can guess at its size now. So just pick an arbitrary
// nonzero value (in this case, 1px) so that the layout
// traversal logic will know that objects later in the document
// might flow around this float.
if let LengthOrPercentageOrAuto::Percentage(percentage) =
flow.as_block().fragment.style.content_inline_size()
{
if percentage.0 > 0.0 {
float_inline_size = Au::from_px(1)
let inline_size =
flow.as_block().fragment.style.content_inline_size();
let fixed = match inline_size {
LengthOrPercentageOrAuto::Auto => false,
LengthOrPercentageOrAuto::LengthOrPercentage(ref lp) => {
lp.is_definitely_zero() || lp.maybe_to_used_value(None).is_some()
}
};
if !fixed {
float_inline_size = Au::from_px(1)
}
}
}

View file

@ -61,7 +61,7 @@ use style::selector_parser::RestyleDamage;
use style::servo::restyle_damage::ServoRestyleDamage;
use style::str::char_is_whitespace;
use style::values::computed::counters::ContentItem;
use style::values::computed::{Length, LengthOrPercentage, LengthOrPercentageOrAuto};
use style::values::computed::{LengthOrPercentage, LengthOrPercentageOrAuto};
use style::values::generics::box_::{Perspective, VerticalAlign};
use style::values::generics::transform;
use webrender_api::{self, LayoutTransform};
@ -1610,33 +1610,32 @@ impl Fragment {
SpecificFragmentInfo::Canvas(_) |
SpecificFragmentInfo::Iframe(_) |
SpecificFragmentInfo::Svg(_) => {
let mut inline_size = match self.style.content_inline_size() {
LengthOrPercentageOrAuto::Auto | LengthOrPercentageOrAuto::Percentage(_) => {
// We have to initialize the `border_padding` field first to make
// the size constraints work properly.
// TODO(stshine): Find a cleaner way to do this.
let padding = self.style.logical_padding();
self.border_padding.inline_start =
padding.inline_start.to_used_value(Au(0));
self.border_padding.inline_end = padding.inline_end.to_used_value(Au(0));
self.border_padding.block_start = padding.block_start.to_used_value(Au(0));
self.border_padding.block_end = padding.block_end.to_used_value(Au(0));
let border = self.border_width();
self.border_padding.inline_start += border.inline_start;
self.border_padding.inline_end += border.inline_end;
self.border_padding.block_start += border.block_start;
self.border_padding.block_end += border.block_end;
let (result_inline, _) = self.calculate_replaced_sizes(None, None);
result_inline
},
LengthOrPercentageOrAuto::Length(length) => Au::from(length),
LengthOrPercentageOrAuto::Calc(calc) => {
// TODO(nox): This is probably wrong, because it accounts neither for
// clamping (not sure if necessary here) nor percentage.
Au::from(calc.unclamped_length())
},
let inline_size = match self.style.content_inline_size() {
LengthOrPercentageOrAuto::Auto => None,
LengthOrPercentageOrAuto::LengthOrPercentage(ref lp) => {
lp.maybe_to_used_value(None)
}
};
let mut inline_size = inline_size.unwrap_or_else(|| {
// We have to initialize the `border_padding` field first to make
// the size constraints work properly.
// TODO(stshine): Find a cleaner way to do this.
let padding = self.style.logical_padding();
self.border_padding.inline_start =
padding.inline_start.to_used_value(Au(0));
self.border_padding.inline_end = padding.inline_end.to_used_value(Au(0));
self.border_padding.block_start = padding.block_start.to_used_value(Au(0));
self.border_padding.block_end = padding.block_end.to_used_value(Au(0));
let border = self.border_width();
self.border_padding.inline_start += border.inline_start;
self.border_padding.inline_end += border.inline_end;
self.border_padding.block_start += border.block_start;
self.border_padding.block_end += border.block_end;
let (result_inline, _) = self.calculate_replaced_sizes(None, None);
result_inline
});
let size_constraint = self.size_constraint(None, Direction::Inline);
inline_size = size_constraint.clamp(inline_size);
@ -2432,16 +2431,8 @@ impl Fragment {
content_inline_metrics.space_below_baseline
}
},
VerticalAlign::Length(LengthOrPercentage::Length(length)) => {
offset -= Au::from(length)
},
VerticalAlign::Length(LengthOrPercentage::Percentage(percentage)) => {
offset -= minimum_line_metrics.space_needed().scale_by(percentage.0)
},
VerticalAlign::Length(LengthOrPercentage::Calc(formula)) => {
offset -= formula
.to_used_value(Some(minimum_line_metrics.space_needed()))
.unwrap()
VerticalAlign::Length(ref lp) => {
offset -= lp.to_used_value(minimum_line_metrics.space_needed());
},
}
}
@ -2519,12 +2510,12 @@ impl Fragment {
continue;
}
if inline_context_node.style.logical_margin().inline_end !=
LengthOrPercentageOrAuto::Length(Length::new(0.))
LengthOrPercentageOrAuto::zero()
{
return false;
}
if inline_context_node.style.logical_padding().inline_end !=
LengthOrPercentage::Length(Length::new(0.))
LengthOrPercentage::zero()
{
return false;
}
@ -2545,12 +2536,12 @@ impl Fragment {
continue;
}
if inline_context_node.style.logical_margin().inline_start !=
LengthOrPercentageOrAuto::Length(Length::new(0.))
LengthOrPercentageOrAuto::zero()
{
return false;
}
if inline_context_node.style.logical_padding().inline_start !=
LengthOrPercentage::Length(Length::new(0.))
LengthOrPercentage::zero()
{
return false;
}

View file

@ -136,26 +136,19 @@ impl MarginCollapseInfo {
may_collapse_through = may_collapse_through &&
match fragment.style().content_block_size() {
LengthOrPercentageOrAuto::Auto => true,
LengthOrPercentageOrAuto::Length(l) => l.px() == 0.,
LengthOrPercentageOrAuto::Percentage(v) => {
v.0 == 0. || containing_block_size.is_none()
LengthOrPercentageOrAuto::LengthOrPercentage(ref lp) => {
lp.is_definitely_zero() ||
lp.maybe_to_used_value(containing_block_size).is_none()
},
LengthOrPercentageOrAuto::Calc(_) => false,
};
if may_collapse_through {
match fragment.style().min_block_size() {
LengthOrPercentage::Length(l) if l.px() == 0. => {
FinalMarginState::MarginsCollapseThrough
},
LengthOrPercentage::Percentage(v) if v.0 == 0. => {
FinalMarginState::MarginsCollapseThrough
},
_ => {
// If the fragment has non-zero min-block-size, margins may not
// collapse through it.
FinalMarginState::BottomMarginCollapses
},
if fragment.style().min_block_size().is_definitely_zero() {
FinalMarginState::MarginsCollapseThrough
} else {
// If the fragment has non-zero min-block-size, margins may not
// collapse through it.
FinalMarginState::BottomMarginCollapses
}
} else {
// If the fragment has an explicitly specified block-size, margins may not
@ -445,13 +438,9 @@ impl MaybeAuto {
pub fn from_style(length: LengthOrPercentageOrAuto, containing_length: Au) -> MaybeAuto {
match length {
LengthOrPercentageOrAuto::Auto => MaybeAuto::Auto,
LengthOrPercentageOrAuto::Percentage(percent) => {
MaybeAuto::Specified(containing_length.scale_by(percent.0))
LengthOrPercentageOrAuto::LengthOrPercentage(ref lp) => {
MaybeAuto::Specified(lp.to_used_value(containing_length))
},
LengthOrPercentageOrAuto::Calc(calc) => {
MaybeAuto::from_option(calc.to_used_value(Some(containing_length)))
},
LengthOrPercentageOrAuto::Length(length) => MaybeAuto::Specified(Au::from(length)),
}
}
@ -484,6 +473,15 @@ impl MaybeAuto {
self.specified_or_default(Au::new(0))
}
#[inline]
pub fn is_auto(&self) -> bool {
match *self {
MaybeAuto::Auto => true,
MaybeAuto::Specified(..) => false,
}
}
#[inline]
pub fn map<F>(&self, mapper: F) -> MaybeAuto
where
@ -503,15 +501,11 @@ pub fn style_length(
style_length: LengthOrPercentageOrAuto,
container_size: Option<Au>,
) -> MaybeAuto {
match container_size {
Some(length) => MaybeAuto::from_style(style_length, length),
None => {
if let LengthOrPercentageOrAuto::Length(length) = style_length {
MaybeAuto::Specified(Au::from(length))
} else {
MaybeAuto::Auto
}
},
match style_length {
LengthOrPercentageOrAuto::Auto => MaybeAuto::Auto,
LengthOrPercentageOrAuto::LengthOrPercentage(ref lp) => {
MaybeAuto::from_option(lp.maybe_to_used_value(container_size))
}
}
}
@ -580,27 +574,16 @@ impl SizeConstraint {
max_size: LengthOrPercentageOrNone,
border: Option<Au>,
) -> SizeConstraint {
let mut min_size = match container_size {
Some(container_size) => min_size.to_used_value(container_size),
None => {
if let LengthOrPercentage::Length(length) = min_size {
Au::from(length)
} else {
Au(0)
}
let mut min_size =
min_size.maybe_to_used_value(container_size).unwrap_or(Au(0));
let mut max_size = match max_size {
LengthOrPercentageOrNone::None => None,
LengthOrPercentageOrNone::LengthOrPercentage(ref lp) => {
lp.maybe_to_used_value(container_size)
},
};
let mut max_size = match container_size {
Some(container_size) => max_size.to_used_value(container_size),
None => {
if let LengthOrPercentageOrNone::Length(length) = max_size {
Some(Au::from(length))
} else {
None
}
},
};
// Make sure max size is not smaller than min size.
max_size = max_size.map(|x| max(x, min_size));
@ -609,10 +592,7 @@ impl SizeConstraint {
max_size = max_size.map(|x| max(x - border, Au(0)));
}
SizeConstraint {
min_size: min_size,
max_size: max_size,
}
SizeConstraint { min_size, max_size }
}
/// Clamp the given size by the given min size and max size constraint.

View file

@ -154,11 +154,22 @@ impl Flow for MulticolFlow {
this_fragment_is_empty: true,
available_block_size: {
let style = &self.block_flow.fragment.style;
if let LengthOrPercentageOrAuto::Length(length) = style.content_block_size() {
Au::from(length)
} else if let LengthOrPercentageOrNone::Length(length) = style.max_block_size() {
Au::from(length)
} else {
let size = match style.content_block_size() {
LengthOrPercentageOrAuto::Auto => None,
LengthOrPercentageOrAuto::LengthOrPercentage(ref lp) => {
lp.maybe_to_used_value(None)
}
};
let size = size.or_else(|| {
match style.max_block_size() {
LengthOrPercentageOrNone::None => None,
LengthOrPercentageOrNone::LengthOrPercentage(ref lp) => {
lp.maybe_to_used_value(None)
}
}
});
size.unwrap_or_else(|| {
// FIXME: do column balancing instead
// FIXME: (until column balancing) substract margins/borders/padding
LogicalSize::from_physical(
@ -166,7 +177,7 @@ impl Flow for MulticolFlow {
ctx.shared_context().viewport_size(),
)
.block
}
})
},
});

View file

@ -301,16 +301,16 @@ impl Flow for TableFlow {
self.column_intrinsic_inline_sizes
.push(ColumnIntrinsicInlineSize {
minimum_length: match *specified_inline_size {
LengthOrPercentageOrAuto::Auto |
LengthOrPercentageOrAuto::Calc(_) |
LengthOrPercentageOrAuto::Percentage(_) => Au(0),
LengthOrPercentageOrAuto::Length(length) => Au::from(length),
LengthOrPercentageOrAuto::Auto => Au(0),
LengthOrPercentageOrAuto::LengthOrPercentage(ref lp) => {
lp.maybe_to_used_value(None).unwrap_or(Au(0))
},
},
percentage: match *specified_inline_size {
LengthOrPercentageOrAuto::Auto |
LengthOrPercentageOrAuto::Calc(_) |
LengthOrPercentageOrAuto::Length(_) => 0.0,
LengthOrPercentageOrAuto::Percentage(percentage) => percentage.0,
LengthOrPercentageOrAuto::Auto => 0.0,
LengthOrPercentageOrAuto::LengthOrPercentage(ref lp) => {
lp.as_percentage().map_or(0.0, |p| p.0)
},
},
preferred: Au(0),
constrained: false,

View file

@ -430,25 +430,24 @@ impl Flow for TableRowFlow {
let child_base = kid.mut_base();
let child_column_inline_size = ColumnIntrinsicInlineSize {
minimum_length: match child_specified_inline_size {
LengthOrPercentageOrAuto::Auto |
LengthOrPercentageOrAuto::Calc(_) |
LengthOrPercentageOrAuto::Percentage(_) => {
child_base.intrinsic_inline_sizes.minimum_inline_size
LengthOrPercentageOrAuto::Auto => None,
LengthOrPercentageOrAuto::LengthOrPercentage(ref lp) => {
lp.maybe_to_used_value(None)
},
LengthOrPercentageOrAuto::Length(length) => Au::from(length),
},
}
.unwrap_or(child_base.intrinsic_inline_sizes.minimum_inline_size),
percentage: match child_specified_inline_size {
LengthOrPercentageOrAuto::Auto |
LengthOrPercentageOrAuto::Calc(_) |
LengthOrPercentageOrAuto::Length(_) => 0.0,
LengthOrPercentageOrAuto::Percentage(percentage) => percentage.0,
LengthOrPercentageOrAuto::Auto => 0.0,
LengthOrPercentageOrAuto::LengthOrPercentage(ref lp) => {
lp.as_percentage().map_or(0.0, |p| p.0)
},
},
preferred: child_base.intrinsic_inline_sizes.preferred_inline_size,
constrained: match child_specified_inline_size {
LengthOrPercentageOrAuto::Length(_) => true,
LengthOrPercentageOrAuto::Auto |
LengthOrPercentageOrAuto::Calc(_) |
LengthOrPercentageOrAuto::Percentage(_) => false,
LengthOrPercentageOrAuto::Auto => false,
LengthOrPercentageOrAuto::LengthOrPercentage(ref lp) => {
lp.maybe_to_used_value(None).is_some()
},
},
};
min_inline_size = min_inline_size + child_column_inline_size.minimum_length;