diff options
Diffstat (limited to 'components/layout/model.rs')
-rw-r--r-- | components/layout/model.rs | 280 |
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, } } } |