aboutsummaryrefslogtreecommitdiffstats
path: root/components/layout/model.rs
diff options
context:
space:
mode:
Diffstat (limited to 'components/layout/model.rs')
-rw-r--r--components/layout/model.rs280
1 files changed, 175 insertions, 105 deletions
diff --git a/components/layout/model.rs b/components/layout/model.rs
index 5d5238ece77..50959398f27 100644
--- a/components/layout/model.rs
+++ b/components/layout/model.rs
@@ -126,21 +126,22 @@ impl MarginCollapseInfo {
}
}
- pub fn finish_and_compute_collapsible_margins(mut self,
- fragment: &Fragment,
- containing_block_size: Option<Au>,
- can_collapse_block_end_margin_with_kids: bool,
- mut may_collapse_through: bool)
- -> (CollapsibleMargins, Au) {
+ pub fn finish_and_compute_collapsible_margins(
+ mut self,
+ fragment: &Fragment,
+ containing_block_size: Option<Au>,
+ can_collapse_block_end_margin_with_kids: bool,
+ mut may_collapse_through: bool,
+ ) -> (CollapsibleMargins, Au) {
let state = match self.state {
MarginCollapseState::AccumulatingCollapsibleTopMargin => {
- may_collapse_through = may_collapse_through &&
- match fragment.style().content_block_size() {
+ 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::Calc(_) => false,
};
@@ -156,14 +157,14 @@ impl MarginCollapseInfo {
// 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
// collapse through it.
FinalMarginState::BottomMarginCollapses
}
- }
+ },
MarginCollapseState::AccumulatingMarginIn => FinalMarginState::BottomMarginCollapses,
};
@@ -174,27 +175,41 @@ impl MarginCollapseInfo {
match state {
FinalMarginState::MarginsCollapseThrough => {
let advance = self.block_start_margin.collapse();
- self.margin_in.union(AdjoiningMargins::from_margin(block_end_margin));
- (CollapsibleMargins::Collapse(self.block_start_margin, self.margin_in),
- advance)
- }
+ self.margin_in
+ .union(AdjoiningMargins::from_margin(block_end_margin));
+ (
+ CollapsibleMargins::Collapse(self.block_start_margin, self.margin_in),
+ advance,
+ )
+ },
FinalMarginState::BottomMarginCollapses => {
let advance = self.margin_in.collapse();
- self.margin_in.union(AdjoiningMargins::from_margin(block_end_margin));
- (CollapsibleMargins::Collapse(self.block_start_margin, self.margin_in),
- advance)
- }
+ self.margin_in
+ .union(AdjoiningMargins::from_margin(block_end_margin));
+ (
+ CollapsibleMargins::Collapse(self.block_start_margin, self.margin_in),
+ advance,
+ )
+ },
}
} else {
match state {
FinalMarginState::MarginsCollapseThrough => {
- self.block_start_margin.union(AdjoiningMargins::from_margin(block_end_margin));
- (CollapsibleMargins::CollapseThrough(self.block_start_margin), Au(0))
- }
+ self.block_start_margin
+ .union(AdjoiningMargins::from_margin(block_end_margin));
+ (
+ CollapsibleMargins::CollapseThrough(self.block_start_margin),
+ Au(0),
+ )
+ },
FinalMarginState::BottomMarginCollapses => {
- self.margin_in.union(AdjoiningMargins::from_margin(block_end_margin));
- (CollapsibleMargins::Collapse(self.block_start_margin, self.margin_in), Au(0))
- }
+ self.margin_in
+ .union(AdjoiningMargins::from_margin(block_end_margin));
+ (
+ CollapsibleMargins::Collapse(self.block_start_margin, self.margin_in),
+ Au(0),
+ )
+ },
}
}
}
@@ -206,7 +221,7 @@ impl MarginCollapseInfo {
// needs to be positioned relative to our *border box*, not our margin box. See
// `tests/ref/float_under_top_margin_a.html`.
Au(0)
- }
+ },
MarginCollapseState::AccumulatingMarginIn => self.margin_in.collapse(),
}
}
@@ -214,78 +229,99 @@ impl MarginCollapseInfo {
/// Adds the child's potentially collapsible block-start margin to the current margin state and
/// advances the Y offset by the appropriate amount to handle that margin. Returns the amount
/// that should be added to the Y offset during block layout.
- pub fn advance_block_start_margin(&mut self,
- child_collapsible_margins: &CollapsibleMargins,
- can_collapse_block_start_margin: bool)
- -> Au {
+ pub fn advance_block_start_margin(
+ &mut self,
+ child_collapsible_margins: &CollapsibleMargins,
+ can_collapse_block_start_margin: bool,
+ ) -> Au {
if !can_collapse_block_start_margin {
self.state = MarginCollapseState::AccumulatingMarginIn
}
match (self.state, *child_collapsible_margins) {
- (MarginCollapseState::AccumulatingCollapsibleTopMargin,
- CollapsibleMargins::None(block_start, _)) => {
+ (
+ MarginCollapseState::AccumulatingCollapsibleTopMargin,
+ CollapsibleMargins::None(block_start, _),
+ ) => {
self.state = MarginCollapseState::AccumulatingMarginIn;
block_start
- }
- (MarginCollapseState::AccumulatingCollapsibleTopMargin,
- CollapsibleMargins::Collapse(block_start, _)) => {
+ },
+ (
+ MarginCollapseState::AccumulatingCollapsibleTopMargin,
+ CollapsibleMargins::Collapse(block_start, _),
+ ) => {
self.block_start_margin.union(block_start);
self.state = MarginCollapseState::AccumulatingMarginIn;
Au(0)
- }
- (MarginCollapseState::AccumulatingMarginIn,
- CollapsibleMargins::None(block_start, _)) => {
+ },
+ (
+ MarginCollapseState::AccumulatingMarginIn,
+ CollapsibleMargins::None(block_start, _),
+ ) => {
let previous_margin_value = self.margin_in.collapse();
self.margin_in = AdjoiningMargins::new();
previous_margin_value + block_start
- }
- (MarginCollapseState::AccumulatingMarginIn,
- CollapsibleMargins::Collapse(block_start, _)) => {
+ },
+ (
+ MarginCollapseState::AccumulatingMarginIn,
+ CollapsibleMargins::Collapse(block_start, _),
+ ) => {
self.margin_in.union(block_start);
let margin_value = self.margin_in.collapse();
self.margin_in = AdjoiningMargins::new();
margin_value
- }
+ },
(_, CollapsibleMargins::CollapseThrough(_)) => {
// For now, we ignore this; this will be handled by `advance_block_end_margin`
// below.
Au(0)
- }
+ },
}
}
/// Adds the child's potentially collapsible block-end margin to the current margin state and
/// advances the Y offset by the appropriate amount to handle that margin. Returns the amount
/// that should be added to the Y offset during block layout.
- pub fn advance_block_end_margin(&mut self, child_collapsible_margins: &CollapsibleMargins)
- -> Au {
+ pub fn advance_block_end_margin(
+ &mut self,
+ child_collapsible_margins: &CollapsibleMargins,
+ ) -> Au {
match (self.state, *child_collapsible_margins) {
- (MarginCollapseState::AccumulatingCollapsibleTopMargin, CollapsibleMargins::None(..)) |
- (MarginCollapseState::AccumulatingCollapsibleTopMargin,
- CollapsibleMargins::Collapse(..)) => {
+ (
+ MarginCollapseState::AccumulatingCollapsibleTopMargin,
+ CollapsibleMargins::None(..),
+ ) |
+ (
+ MarginCollapseState::AccumulatingCollapsibleTopMargin,
+ CollapsibleMargins::Collapse(..),
+ ) => {
// Can't happen because the state will have been replaced with
// `MarginCollapseState::AccumulatingMarginIn` above.
panic!("should not be accumulating collapsible block_start margins anymore!")
- }
- (MarginCollapseState::AccumulatingCollapsibleTopMargin,
- CollapsibleMargins::CollapseThrough(margin)) => {
+ },
+ (
+ MarginCollapseState::AccumulatingCollapsibleTopMargin,
+ CollapsibleMargins::CollapseThrough(margin),
+ ) => {
self.block_start_margin.union(margin);
Au(0)
- }
- (MarginCollapseState::AccumulatingMarginIn,
- CollapsibleMargins::None(_, block_end)) => {
+ },
+ (MarginCollapseState::AccumulatingMarginIn, CollapsibleMargins::None(_, block_end)) => {
assert_eq!(self.margin_in.most_positive, Au(0));
assert_eq!(self.margin_in.most_negative, Au(0));
block_end
- }
- (MarginCollapseState::AccumulatingMarginIn,
- CollapsibleMargins::Collapse(_, block_end)) |
- (MarginCollapseState::AccumulatingMarginIn,
- CollapsibleMargins::CollapseThrough(block_end)) => {
+ },
+ (
+ MarginCollapseState::AccumulatingMarginIn,
+ CollapsibleMargins::Collapse(_, block_end),
+ ) |
+ (
+ MarginCollapseState::AccumulatingMarginIn,
+ CollapsibleMargins::CollapseThrough(block_end),
+ ) => {
self.margin_in.union(block_end);
Au(0)
- }
+ },
}
}
}
@@ -309,7 +345,11 @@ pub struct IntrinsicISizes {
impl fmt::Debug for IntrinsicISizes {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- write!(f, "min={:?}, pref={:?}", self.minimum_inline_size, self.preferred_inline_size)
+ write!(
+ f,
+ "min={:?}, pref={:?}",
+ self.minimum_inline_size, self.preferred_inline_size
+ )
}
}
@@ -345,9 +385,9 @@ impl IntrinsicISizesContribution {
pub fn finish(self) -> IntrinsicISizes {
IntrinsicISizes {
minimum_inline_size: self.content_intrinsic_sizes.minimum_inline_size +
- self.surrounding_size,
+ self.surrounding_size,
preferred_inline_size: self.content_intrinsic_sizes.preferred_inline_size +
- self.surrounding_size,
+ self.surrounding_size,
}
}
@@ -358,8 +398,10 @@ impl IntrinsicISizesContribution {
/// FIXME(pcwalton): This is incorrect when the inline fragment contains forced line breaks
/// (e.g. `<br>` or `white-space: pre`).
pub fn union_inline(&mut self, sizes: &IntrinsicISizes) {
- self.content_intrinsic_sizes.minimum_inline_size =
- max(self.content_intrinsic_sizes.minimum_inline_size, sizes.minimum_inline_size);
+ self.content_intrinsic_sizes.minimum_inline_size = max(
+ self.content_intrinsic_sizes.minimum_inline_size,
+ sizes.minimum_inline_size,
+ );
self.content_intrinsic_sizes.preferred_inline_size =
self.content_intrinsic_sizes.preferred_inline_size + sizes.preferred_inline_size
}
@@ -382,10 +424,14 @@ impl IntrinsicISizesContribution {
///
/// This is used when contributing the intrinsic sizes for individual fragments.
pub fn union_block(&mut self, sizes: &IntrinsicISizes) {
- self.content_intrinsic_sizes.minimum_inline_size =
- max(self.content_intrinsic_sizes.minimum_inline_size, sizes.minimum_inline_size);
- self.content_intrinsic_sizes.preferred_inline_size =
- max(self.content_intrinsic_sizes.preferred_inline_size, sizes.preferred_inline_size)
+ self.content_intrinsic_sizes.minimum_inline_size = max(
+ self.content_intrinsic_sizes.minimum_inline_size,
+ sizes.minimum_inline_size,
+ );
+ self.content_intrinsic_sizes.preferred_inline_size = max(
+ self.content_intrinsic_sizes.preferred_inline_size,
+ sizes.preferred_inline_size,
+ )
}
}
@@ -398,17 +444,16 @@ pub enum MaybeAuto {
impl MaybeAuto {
#[inline]
- pub fn from_style(length: LengthOrPercentageOrAuto, containing_length: Au)
- -> 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::Calc(calc) => {
MaybeAuto::from_option(calc.to_used_value(Some(containing_length)))
- }
- LengthOrPercentageOrAuto::Length(length) => MaybeAuto::Specified(Au::from(length))
+ },
+ LengthOrPercentageOrAuto::Length(length) => MaybeAuto::Specified(Au::from(length)),
}
}
@@ -442,7 +487,10 @@ impl MaybeAuto {
}
#[inline]
- pub fn map<F>(&self, mapper: F) -> MaybeAuto where F: FnOnce(Au) -> Au {
+ pub fn map<F>(&self, mapper: F) -> MaybeAuto
+ where
+ F: FnOnce(Au) -> Au,
+ {
match *self {
MaybeAuto::Auto => MaybeAuto::Auto,
MaybeAuto::Specified(value) => MaybeAuto::Specified(mapper(value)),
@@ -453,15 +501,17 @@ impl MaybeAuto {
/// Receive an optional container size and return used value for width or height.
///
/// `style_length`: content size as given in the CSS.
-pub fn style_length(style_length: LengthOrPercentageOrAuto,
- container_size: Option<Au>) -> MaybeAuto {
+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
- }
+ },
}
}
@@ -475,25 +525,37 @@ pub fn style_length(style_length: LengthOrPercentageOrAuto,
/// [1]: https://drafts.csswg.org/css-backgrounds-3/#border-radius
pub fn specified_border_radius(
radius: BorderCornerRadius,
- containing_size: Size2D<Au>)
- -> Size2D<Au>
-{
+ containing_size: Size2D<Au>,
+) -> Size2D<Au> {
let w = radius.0.width().to_used_value(containing_size.width);
let h = radius.0.height().to_used_value(containing_size.height);
Size2D::new(w, h)
}
#[inline]
-pub fn padding_from_style(style: &ComputedValues,
- containing_block_inline_size: Au,
- writing_mode: WritingMode)
- -> LogicalMargin<Au> {
+pub fn padding_from_style(
+ style: &ComputedValues,
+ containing_block_inline_size: Au,
+ writing_mode: WritingMode,
+) -> LogicalMargin<Au> {
let padding_style = style.get_padding();
- LogicalMargin::from_physical(writing_mode, SideOffsets2D::new(
- padding_style.padding_top.to_used_value(containing_block_inline_size),
- padding_style.padding_right.to_used_value(containing_block_inline_size),
- padding_style.padding_bottom.to_used_value(containing_block_inline_size),
- padding_style.padding_left.to_used_value(containing_block_inline_size)))
+ LogicalMargin::from_physical(
+ writing_mode,
+ SideOffsets2D::new(
+ padding_style
+ .padding_top
+ .to_used_value(containing_block_inline_size),
+ padding_style
+ .padding_right
+ .to_used_value(containing_block_inline_size),
+ padding_style
+ .padding_bottom
+ .to_used_value(containing_block_inline_size),
+ padding_style
+ .padding_left
+ .to_used_value(containing_block_inline_size),
+ ),
+ )
}
/// Returns the explicitly-specified margin lengths from the given style. Percentage and auto
@@ -501,14 +563,20 @@ pub fn padding_from_style(style: &ComputedValues,
///
/// This is used when calculating intrinsic inline sizes.
#[inline]
-pub fn specified_margin_from_style(style: &ComputedValues,
- writing_mode: WritingMode) -> LogicalMargin<Au> {
+pub fn specified_margin_from_style(
+ style: &ComputedValues,
+ writing_mode: WritingMode,
+) -> LogicalMargin<Au> {
let margin_style = style.get_margin();
- LogicalMargin::from_physical(writing_mode, SideOffsets2D::new(
- MaybeAuto::from_style(margin_style.margin_top, Au(0)).specified_or_zero(),
- MaybeAuto::from_style(margin_style.margin_right, Au(0)).specified_or_zero(),
- MaybeAuto::from_style(margin_style.margin_bottom, Au(0)).specified_or_zero(),
- MaybeAuto::from_style(margin_style.margin_left, Au(0)).specified_or_zero()))
+ LogicalMargin::from_physical(
+ writing_mode,
+ SideOffsets2D::new(
+ MaybeAuto::from_style(margin_style.margin_top, Au(0)).specified_or_zero(),
+ MaybeAuto::from_style(margin_style.margin_right, Au(0)).specified_or_zero(),
+ MaybeAuto::from_style(margin_style.margin_bottom, Au(0)).specified_or_zero(),
+ MaybeAuto::from_style(margin_style.margin_left, Au(0)).specified_or_zero(),
+ ),
+ )
}
/// A min-size and max-size constraint. The constructor has a optional `border`
@@ -523,17 +591,19 @@ pub struct SizeConstraint {
impl SizeConstraint {
/// Create a `SizeConstraint` for an axis.
- pub fn new(container_size: Option<Au>,
- min_size: LengthOrPercentage,
- max_size: LengthOrPercentageOrNone,
- border: Option<Au>) -> SizeConstraint {
+ pub fn new(
+ container_size: Option<Au>,
+ min_size: LengthOrPercentage,
+ 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 max_size = match container_size {
@@ -542,7 +612,7 @@ impl SizeConstraint {
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));
@@ -554,7 +624,7 @@ impl SizeConstraint {
SizeConstraint {
min_size: min_size,
- max_size: max_size
+ max_size: max_size,
}
}
@@ -565,7 +635,7 @@ impl SizeConstraint {
} else {
match self.max_size {
Some(max_size) if max_size < other => max_size,
- _ => other
+ _ => other,
}
}
}