diff options
Diffstat (limited to 'components/layout/flex.rs')
-rw-r--r-- | components/layout/flex.rs | 583 |
1 files changed, 351 insertions, 232 deletions
diff --git a/components/layout/flex.rs b/components/layout/flex.rs index 2864c922874..e1baa390382 100644 --- a/components/layout/flex.rs +++ b/components/layout/flex.rs @@ -45,25 +45,25 @@ enum AxisSize { impl AxisSize { /// Generate a new available cross or main axis size from the specified size of the container, /// containing block size, min constraint, and max constraint - pub fn new(size: LengthOrPercentageOrAuto, content_size: Option<Au>, min: LengthOrPercentage, - max: LengthOrPercentageOrNone) -> AxisSize { + pub fn new( + size: LengthOrPercentageOrAuto, + content_size: Option<Au>, + min: LengthOrPercentage, + 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::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)) - } + }, } } } @@ -112,7 +112,7 @@ struct FlexItem { /// Whether the main size has met its constraint. pub is_frozen: bool, /// True if this flow has property 'visibility::collapse'. - pub is_strut: bool + pub is_strut: bool, } impl FlexItem { @@ -133,7 +133,7 @@ impl FlexItem { flex_shrink: flex_shrink.into(), order: order, is_frozen: false, - is_strut: false + is_strut: false, } } @@ -147,41 +147,61 @@ impl FlexItem { // should change to LengthOrPercentageOrAuto for automatic implied minimal size. // https://drafts.csswg.org/css-flexbox-1/#min-size-auto Direction::Inline => { - let basis = from_flex_basis(block.fragment.style.get_position().flex_basis, - block.fragment.style.content_inline_size(), - containing_length); + let basis = from_flex_basis( + block.fragment.style.get_position().flex_basis, + block.fragment.style.content_inline_size(), + containing_length, + ); // These methods compute auto margins to zero length, which is exactly what we want. block.fragment.compute_border_and_padding(containing_length); - block.fragment.compute_inline_direction_margins(containing_length); - block.fragment.compute_block_direction_margins(containing_length); + block + .fragment + .compute_inline_direction_margins(containing_length); + block + .fragment + .compute_block_direction_margins(containing_length); let (border_padding, margin) = block.fragment.surrounding_intrinsic_inline_size(); - let content_size = block.base.intrinsic_inline_sizes.preferred_inline_size - - border_padding - - margin - + block.fragment.box_sizing_boundary(direction); + let content_size = block.base.intrinsic_inline_sizes.preferred_inline_size - + border_padding - + margin + + block.fragment.box_sizing_boundary(direction); self.base_size = basis.specified_or_default(content_size); - self.max_size = - block.fragment.style.max_inline_size() - .to_used_value(containing_length) - .unwrap_or(MAX_AU); - self.min_size = block.fragment.style.min_inline_size().to_used_value(containing_length); - } + self.max_size = block + .fragment + .style + .max_inline_size() + .to_used_value(containing_length) + .unwrap_or(MAX_AU); + self.min_size = block + .fragment + .style + .min_inline_size() + .to_used_value(containing_length); + }, Direction::Block => { - let basis = from_flex_basis(block.fragment.style.get_position().flex_basis, - block.fragment.style.content_block_size(), - containing_length); - let content_size = block.fragment.border_box.size.block - - block.fragment.border_padding.block_start_end() - + block.fragment.box_sizing_boundary(direction); + let basis = from_flex_basis( + block.fragment.style.get_position().flex_basis, + block.fragment.style.content_block_size(), + containing_length, + ); + let content_size = block.fragment.border_box.size.block - + block.fragment.border_padding.block_start_end() + + block.fragment.box_sizing_boundary(direction); self.base_size = basis.specified_or_default(content_size); - self.max_size = - block.fragment.style.max_block_size() - .to_used_value(containing_length) - .unwrap_or(MAX_AU); - self.min_size = block.fragment.style.min_block_size().to_used_value(containing_length); - } + self.max_size = block + .fragment + .style + .max_block_size() + .to_used_value(containing_length) + .unwrap_or(MAX_AU); + self.min_size = block + .fragment + .style + .min_block_size() + .to_used_value(containing_length); + }, } } @@ -192,13 +212,14 @@ impl FlexItem { let outer_width = match direction { Direction::Inline => { fragment.border_padding.inline_start_end() + fragment.margin.inline_start_end() - } + }, Direction::Block => { fragment.border_padding.block_start_end() + fragment.margin.block_start_end() - } + }, }; - max(self.min_size, min(self.base_size, self.max_size)) - - fragment.box_sizing_boundary(direction) + outer_width + max(self.min_size, min(self.base_size, self.max_size)) - + fragment.box_sizing_boundary(direction) + + outer_width } /// Returns the number of auto margins in given direction. @@ -213,7 +234,7 @@ impl FlexItem { if margin.inline_end == LengthOrPercentageOrAuto::Auto { margin_count += 1; } - } + }, Direction::Block => { if margin.block_start == LengthOrPercentageOrAuto::Auto { margin_count += 1; @@ -221,7 +242,7 @@ impl FlexItem { if margin.block_end == LengthOrPercentageOrAuto::Auto { margin_count += 1; } - } + }, } margin_count } @@ -247,7 +268,7 @@ impl FlexLine { range: range, auto_margin_count: auto_margin_count, free_space: free_space, - cross_size: Au(0) + cross_size: Au(0), } } @@ -265,17 +286,20 @@ impl FlexLine { // https://drafts.csswg.org/css-flexbox/#resolve-flexible-lengths for item in items.iter_mut().filter(|i| !(i.is_strut && collapse)) { item.main_size = max(item.min_size, min(item.base_size, item.max_size)); - if (self.free_space > Au(0) && (item.flex_grow == 0.0 || item.base_size >= item.max_size)) || - (self.free_space < Au(0) && (item.flex_shrink == 0.0 || item.base_size <= item.min_size)) { - item.is_frozen = true; - } else { - item.is_frozen = false; - total_grow += item.flex_grow; - total_shrink += item.flex_shrink; - // The scaled factor is used to calculate flex shrink - total_scaled += item.flex_shrink * item.base_size.0 as f32; - active_count += 1; - } + if (self.free_space > Au(0) && + (item.flex_grow == 0.0 || item.base_size >= item.max_size)) || + (self.free_space < Au(0) && + (item.flex_shrink == 0.0 || item.base_size <= item.min_size)) + { + item.is_frozen = true; + } else { + item.is_frozen = false; + total_grow += item.flex_grow; + total_shrink += item.flex_shrink; + // The scaled factor is used to calculate flex shrink + total_scaled += item.flex_shrink * item.base_size.0 as f32; + active_count += 1; + } } let initial_free_space = self.free_space; @@ -291,12 +315,19 @@ impl FlexLine { }; total_variation = Au(0); - for item in items.iter_mut().filter(|i| !i.is_frozen).filter(|i| !(i.is_strut && collapse)) { + for item in items + .iter_mut() + .filter(|i| !i.is_frozen) + .filter(|i| !(i.is_strut && collapse)) + { // Use this and the 'abs()' below to make the code work in both grow and shrink scenarios. let (factor, end_size) = if self.free_space > Au(0) { (item.flex_grow / total_grow, item.max_size) } else { - (item.flex_shrink * item.base_size.0 as f32 / total_scaled, item.min_size) + ( + item.flex_shrink * item.base_size.0 as f32 / total_scaled, + item.min_size, + ) }; let variation = self.free_space.scale_by(factor); if variation.0.abs() >= (end_size - item.main_size).0.abs() { @@ -343,13 +374,11 @@ pub struct FlexFlow { /// True if this flex container can be multiline. is_wrappable: bool, /// True if the cross direction is reversed. - cross_reverse: bool + cross_reverse: bool, } impl FlexFlow { - pub fn from_fragment(fragment: Fragment, - flotation: Option<FloatKind>) - -> FlexFlow { + pub fn from_fragment(fragment: Fragment, flotation: Option<FloatKind>) -> FlexFlow { let main_mode; let main_reverse; let is_wrappable; @@ -363,8 +392,7 @@ impl FlexFlow { FlexDirection::ColumnReverse => (Direction::Block, true), }; main_mode = mode; - main_reverse = - reverse == style.writing_mode.is_bidi_ltr(); + main_reverse = reverse == style.writing_mode.is_bidi_ltr(); let (wrappable, reverse) = match fragment.style.get_position().flex_wrap { FlexWrap::Nowrap => (false, false), FlexWrap::Wrap => (true, false), @@ -384,7 +412,7 @@ impl FlexFlow { items: Vec::new(), main_reverse: main_reverse, is_wrappable: is_wrappable, - cross_reverse: cross_reverse + cross_reverse: cross_reverse, } } @@ -414,7 +442,10 @@ impl FlexFlow { let kid = children.get(item.index); item.init_sizes(kid, container_size, self.main_mode); let outer_main_size = item.outer_main_size(kid, self.main_mode); - if total_line_size + outer_main_size > container_size && end != start && self.is_wrappable { + if total_line_size + outer_main_size > container_size && + end != start && + self.is_wrappable + { break; } margin_count += item.auto_margin_count(kid, self.main_mode); @@ -439,7 +470,8 @@ impl FlexFlow { if !fixed_width { for kid in self.block_flow.base.children.iter_mut() { let base = kid.mut_base(); - let is_absolutely_positioned = base.flags.contains(FlowFlags::IS_ABSOLUTELY_POSITIONED); + let is_absolutely_positioned = + base.flags.contains(FlowFlags::IS_ABSOLUTELY_POSITIONED); if !is_absolutely_positioned { let flex_item_inline_sizes = IntrinsicISizes { minimum_inline_size: base.intrinsic_inline_sizes.minimum_inline_size, @@ -465,15 +497,18 @@ impl FlexFlow { if !fixed_width { for kid in self.block_flow.base.children.iter_mut() { let base = kid.mut_base(); - let is_absolutely_positioned = base.flags.contains(FlowFlags::IS_ABSOLUTELY_POSITIONED); + let is_absolutely_positioned = + base.flags.contains(FlowFlags::IS_ABSOLUTELY_POSITIONED); if !is_absolutely_positioned { - computation.content_intrinsic_sizes.minimum_inline_size = - max(computation.content_intrinsic_sizes.minimum_inline_size, - base.intrinsic_inline_sizes.minimum_inline_size); - - computation.content_intrinsic_sizes.preferred_inline_size = - max(computation.content_intrinsic_sizes.preferred_inline_size, - base.intrinsic_inline_sizes.preferred_inline_size); + computation.content_intrinsic_sizes.minimum_inline_size = max( + computation.content_intrinsic_sizes.minimum_inline_size, + base.intrinsic_inline_sizes.minimum_inline_size, + ); + + computation.content_intrinsic_sizes.preferred_inline_size = max( + computation.content_intrinsic_sizes.preferred_inline_size, + base.intrinsic_inline_sizes.preferred_inline_size, + ); } } } @@ -483,11 +518,13 @@ impl FlexFlow { // TODO(zentner): This function needs to be radically different for multi-line flexbox. // Currently, this is the core of BlockFlow::propagate_assigned_inline_size_to_children() with // all float and table logic stripped out. - fn block_mode_assign_inline_sizes(&mut self, - _layout_context: &LayoutContext, - inline_start_content_edge: Au, - inline_end_content_edge: Au, - content_inline_size: Au) { + fn block_mode_assign_inline_sizes( + &mut self, + _layout_context: &LayoutContext, + inline_start_content_edge: Au, + inline_end_content_edge: Au, + content_inline_size: Au, + ) { let _scope = layout_debug_scope!("flex::block_mode_assign_inline_sizes"); debug!("flex::block_mode_assign_inline_sizes"); @@ -496,19 +533,22 @@ impl FlexFlow { let container_block_size = match self.available_main_size { AxisSize::Definite(length) => Some(length), - _ => None + _ => None, }; let container_inline_size = match self.available_cross_size { AxisSize::Definite(length) => length, AxisSize::MinMax(ref constraint) => constraint.clamp(content_inline_size), - AxisSize::Infinite => content_inline_size + AxisSize::Infinite => content_inline_size, }; let mut children = self.block_flow.base.children.random_access_mut(); for kid in &mut self.items { let kid_base = children.get(kid.index).mut_base(); kid_base.block_container_explicit_block_size = container_block_size; - if kid_base.flags.contains(FlowFlags::INLINE_POSITION_IS_STATIC) { + if kid_base + .flags + .contains(FlowFlags::INLINE_POSITION_IS_STATIC) + { // The inline-start margin edge of the child flow is at our inline-start content // edge, and its inline-size is our content inline-size. kid_base.position.start.i = @@ -525,11 +565,13 @@ impl FlexFlow { } } - fn inline_mode_assign_inline_sizes(&mut self, - layout_context: &LayoutContext, - inline_start_content_edge: Au, - _inline_end_content_edge: Au, - content_inline_size: Au) { + fn inline_mode_assign_inline_sizes( + &mut self, + layout_context: &LayoutContext, + inline_start_content_edge: Au, + _inline_end_content_edge: Au, + content_inline_size: Au, + ) { let _scope = layout_debug_scope!("flex::inline_mode_assign_inline_sizes"); debug!("inline_mode_assign_inline_sizes"); @@ -551,17 +593,25 @@ impl FlexFlow { self.block_flow.base.position.size.inline = inline_size; // Calculate non-auto block size to pass to children. - let box_border = self.block_flow.fragment.box_sizing_boundary(Direction::Block); - - let parent_container_size = - self.block_flow.explicit_block_containing_size(layout_context.shared_context()); + let box_border = self + .block_flow + .fragment + .box_sizing_boundary(Direction::Block); + + let parent_container_size = self + .block_flow + .explicit_block_containing_size(layout_context.shared_context()); // https://drafts.csswg.org/css-ui-3/#box-sizing let explicit_content_size = self - .block_flow - .explicit_block_size(parent_container_size) - .map(|x| max(x - box_border, Au(0))); - let containing_block_text_align = - self.block_flow.fragment.style().get_inherited_text().text_align; + .block_flow + .explicit_block_size(parent_container_size) + .map(|x| max(x - box_border, Au(0))); + let containing_block_text_align = self + .block_flow + .fragment + .style() + .get_inherited_text() + .text_align; while let Some(mut line) = self.get_flex_line(inline_size) { let items = &mut self.items[line.range.clone()]; @@ -572,32 +622,42 @@ impl FlexFlow { let item_count = items.len() as i32; let mut cur_i = inline_start_content_edge; let item_interval = if line.free_space >= Au(0) && line.auto_margin_count == 0 { - match self.block_flow.fragment.style().get_position().justify_content { + match self + .block_flow + .fragment + .style() + .get_position() + .justify_content + { JustifyContent::SpaceBetween => { if item_count == 1 { Au(0) } else { line.free_space / (item_count - 1) } - } - JustifyContent::SpaceAround => { - line.free_space / item_count - } + }, + JustifyContent::SpaceAround => line.free_space / item_count, _ => Au(0), } } else { Au(0) }; - match self.block_flow.fragment.style().get_position().justify_content { + match self + .block_flow + .fragment + .style() + .get_position() + .justify_content + { // Overflow equally in both ends of line. JustifyContent::Center | JustifyContent::SpaceAround => { cur_i += (line.free_space - item_interval * (item_count - 1)) / 2; - } + }, JustifyContent::FlexEnd => { cur_i += line.free_space; - } - _ => {} + }, + _ => {}, } let mut children = self.block_flow.base.children.random_access_mut(); @@ -613,19 +673,18 @@ impl FlexFlow { block.base.flags.set_text_align(containing_block_text_align); let margin = block.fragment.style().logical_margin(); - let auto_len = - if line.auto_margin_count == 0 || line.free_space <= Au(0) { - Au(0) - } else { - line.free_space / line.auto_margin_count - }; + let auto_len = if line.auto_margin_count == 0 || line.free_space <= Au(0) { + Au(0) + } else { + line.free_space / line.auto_margin_count + }; let margin_inline_start = MaybeAuto::from_style(margin.inline_start, inline_size) .specified_or_default(auto_len); let margin_inline_end = MaybeAuto::from_style(margin.inline_end, inline_size) .specified_or_default(auto_len); - let item_inline_size = item.main_size - - block.fragment.box_sizing_boundary(self.main_mode) - + block.fragment.border_padding.inline_start_end(); + let item_inline_size = item.main_size - + block.fragment.box_sizing_boundary(self.main_mode) + + block.fragment.border_padding.inline_start_end(); let item_outer_size = item_inline_size + block.fragment.margin.inline_start_end(); block.fragment.margin.inline_start = margin_inline_start; @@ -635,7 +694,7 @@ impl FlexFlow { block.base.position.start.i = if !self.main_reverse { cur_i } else { - inline_start_content_edge * 2 + content_inline_size - cur_i - item_outer_size + inline_start_content_edge * 2 + content_inline_size - cur_i - item_outer_size }; block.base.position.size.inline = item_outer_size; cur_i += item_outer_size + item_interval; @@ -669,7 +728,12 @@ impl FlexFlow { let _scope = layout_debug_scope!("flex::inline_mode_assign_block_size"); let line_count = self.lines.len() as i32; - let line_align = self.block_flow.fragment.style().get_position().align_content; + let line_align = self + .block_flow + .fragment + .style() + .get_position() + .align_content; let mut cur_b = self.block_flow.fragment.border_padding.block_start; let mut total_cross_size = Au(0); let mut line_interval = Au(0); @@ -679,22 +743,27 @@ impl FlexFlow { for line in self.lines.iter_mut() { for item in &self.items[line.range.clone()] { let fragment = &children.get(item.index).as_block().fragment; - line.cross_size = max(line.cross_size, - fragment.border_box.size.block + - fragment.margin.block_start_end()); + line.cross_size = max( + line.cross_size, + fragment.border_box.size.block + fragment.margin.block_start_end(), + ); } total_cross_size += line.cross_size; } } - let box_border = self.block_flow.fragment.box_sizing_boundary(Direction::Block); - let parent_container_size = - self.block_flow.explicit_block_containing_size(layout_context.shared_context()); + let box_border = self + .block_flow + .fragment + .box_sizing_boundary(Direction::Block); + let parent_container_size = self + .block_flow + .explicit_block_containing_size(layout_context.shared_context()); // https://drafts.csswg.org/css-ui-3/#box-sizing let explicit_content_size = self - .block_flow - .explicit_block_size(parent_container_size) - .map(|x| max(x - box_border, Au(0))); + .block_flow + .explicit_block_size(parent_container_size) + .map(|x| max(x - box_border, Au(0))); if let Some(container_block_size) = explicit_content_size { let free_space = container_block_size - total_cross_size; @@ -713,25 +782,25 @@ impl FlexFlow { } else { free_space / (line_count - 1) } - } + }, AlignContent::SpaceAround => { if line_count == 0 { Au(0) } else { free_space / line_count } - } + }, _ => Au(0), }; match line_align { AlignContent::Center | AlignContent::SpaceAround => { cur_b += (free_space - line_interval * (line_count - 1)) / 2; - } + }, AlignContent::FlexEnd => { cur_b += free_space; - } - _ => {} + }, + _ => {}, } } @@ -744,8 +813,9 @@ impl FlexFlow { let mut margin_block_start = block.fragment.margin.block_start; let mut margin_block_end = block.fragment.margin.block_end; - let mut free_space = line.cross_size - block.base.position.size.block - - block.fragment.margin.block_start_end(); + let mut free_space = line.cross_size - + block.base.position.size.block - + block.fragment.margin.block_start_end(); // The spec is a little vague here, but if I understand it correctly, the outer // cross size of item should equal to the line size if any auto margin exists. @@ -758,29 +828,31 @@ impl FlexFlow { free_space / auto_margin_count }; } - margin_block_end = line.cross_size - margin_block_start - block.base.position.size.block; + margin_block_end = + line.cross_size - margin_block_start - block.base.position.size.block; free_space = Au(0); } let self_align = block.fragment.style().get_position().align_self; if self_align == AlignSelf::Stretch && - block.fragment.style().content_block_size() == LengthOrPercentageOrAuto::Auto { - free_space = Au(0); - block.base.block_container_explicit_block_size = Some(line.cross_size); - block.base.position.size.block = - line.cross_size - margin_block_start - margin_block_end; - block.fragment.border_box.size.block = block.base.position.size.block; - // FIXME(stshine): item with 'align-self: stretch' and auto cross size should act - // as if it has a fixed cross size, all child blocks should resolve against it. - // block.assign_block_size(layout_context); - } - block.base.position.start.b = margin_block_start + - if !self.cross_reverse { - cur_b - } else { - self.block_flow.fragment.border_padding.block_start * 2 - + total_cross_size - cur_b - line.cross_size - }; + block.fragment.style().content_block_size() == LengthOrPercentageOrAuto::Auto + { + free_space = Au(0); + block.base.block_container_explicit_block_size = Some(line.cross_size); + block.base.position.size.block = + line.cross_size - margin_block_start - margin_block_end; + block.fragment.border_box.size.block = block.base.position.size.block; + // FIXME(stshine): item with 'align-self: stretch' and auto cross size should act + // as if it has a fixed cross size, all child blocks should resolve against it. + // block.assign_block_size(layout_context); + } + block.base.position.start.b = margin_block_start + if !self.cross_reverse { + cur_b + } else { + self.block_flow.fragment.border_padding.block_start * 2 + total_cross_size - + cur_b - + line.cross_size + }; // TODO(stshine): support baseline alignment. if free_space != Au(0) { let flex_cross = match self_align { @@ -788,17 +860,17 @@ impl FlexFlow { AlignSelf::Center => free_space / 2, _ => Au(0), }; - block.base.position.start.b += - if !self.cross_reverse { - flex_cross - } else { - free_space - flex_cross - }; + block.base.position.start.b += if !self.cross_reverse { + flex_cross + } else { + free_space - flex_cross + }; } } cur_b += line_interval + line.cross_size; } - let total_block_size = total_cross_size + self.block_flow.fragment.border_padding.block_start_end(); + let total_block_size = + total_cross_size + self.block_flow.fragment.border_padding.block_start_end(); self.block_flow.fragment.border_box.size.block = total_block_size; self.block_flow.base.position.size.block = total_block_size; } @@ -830,72 +902,96 @@ impl Flow for FlexFlow { } fn bubble_inline_sizes(&mut self) { - let _scope = layout_debug_scope!("flex::bubble_inline_sizes {:x}", - self.block_flow.base.debug_id()); + let _scope = layout_debug_scope!( + "flex::bubble_inline_sizes {:x}", + self.block_flow.base.debug_id() + ); // Flexbox Section 9.0: Generate anonymous flex items: // This part was handled in the flow constructor. // Flexbox Section 9.1: Re-order flex items according to their order. // FIXME(stshine): This should be done during flow construction. - let mut items: Vec<FlexItem> = - self.block_flow - .base - .children - .iter() - .enumerate() - .filter(|&(_, flow)| { - !flow.as_block().base.flags.contains(FlowFlags::IS_ABSOLUTELY_POSITIONED) - }) - .map(|(index, flow)| FlexItem::new(index, flow)) - .collect(); + let mut items: Vec<FlexItem> = self + .block_flow + .base + .children + .iter() + .enumerate() + .filter(|&(_, flow)| { + !flow + .as_block() + .base + .flags + .contains(FlowFlags::IS_ABSOLUTELY_POSITIONED) + }).map(|(index, flow)| FlexItem::new(index, flow)) + .collect(); items.sort_by_key(|item| item.order); self.items = items; match self.main_mode { Direction::Inline => self.inline_mode_bubble_inline_sizes(), - Direction::Block => self.block_mode_bubble_inline_sizes() + Direction::Block => self.block_mode_bubble_inline_sizes(), } } fn assign_inline_sizes(&mut self, layout_context: &LayoutContext) { - let _scope = layout_debug_scope!("flex::assign_inline_sizes {:x}", self.block_flow.base.debug_id()); + let _scope = layout_debug_scope!( + "flex::assign_inline_sizes {:x}", + self.block_flow.base.debug_id() + ); debug!("assign_inline_sizes"); - if !self.block_flow.base.restyle_damage.intersects(ServoRestyleDamage::REFLOW_OUT_OF_FLOW | - ServoRestyleDamage::REFLOW) { - return + if !self + .block_flow + .base + .restyle_damage + .intersects(ServoRestyleDamage::REFLOW_OUT_OF_FLOW | ServoRestyleDamage::REFLOW) + { + return; } - self.block_flow.initialize_container_size_for_root(layout_context.shared_context()); + self.block_flow + .initialize_container_size_for_root(layout_context.shared_context()); // Our inline-size was set to the inline-size of the containing block by the flow's parent. // Now compute the real value. let containing_block_inline_size = self.block_flow.base.block_container_inline_size; - self.block_flow.compute_used_inline_size(layout_context.shared_context(), - containing_block_inline_size); + self.block_flow.compute_used_inline_size( + layout_context.shared_context(), + containing_block_inline_size, + ); if self.block_flow.base.flags.is_float() { - self.block_flow.float.as_mut().unwrap().containing_inline_size = containing_block_inline_size + self.block_flow + .float + .as_mut() + .unwrap() + .containing_inline_size = containing_block_inline_size } let (available_block_size, available_inline_size) = { let style = &self.block_flow.fragment.style; - let (specified_block_size, specified_inline_size) = if style.writing_mode.is_vertical() { + let (specified_block_size, specified_inline_size) = if style.writing_mode.is_vertical() + { (style.get_position().width, style.get_position().height) } else { (style.get_position().height, style.get_position().width) }; - let available_inline_size = AxisSize::new(specified_inline_size, - Some(self.block_flow.base.block_container_inline_size), - style.min_inline_size(), - style.max_inline_size()); - - let available_block_size = AxisSize::new(specified_block_size, - self.block_flow.base.block_container_explicit_block_size, - style.min_block_size(), - style.max_block_size()); + let available_inline_size = AxisSize::new( + specified_inline_size, + Some(self.block_flow.base.block_container_inline_size), + style.min_inline_size(), + style.max_inline_size(), + ); + + let available_block_size = AxisSize::new( + specified_block_size, + self.block_flow.base.block_container_explicit_block_size, + style.min_block_size(), + style.max_block_size(), + ); (available_block_size, available_inline_size) }; @@ -903,37 +999,46 @@ impl Flow for FlexFlow { let inline_start_content_edge = self.block_flow.fragment.border_box.start.i + self.block_flow.fragment.border_padding.inline_start; - debug!("inline_start_content_edge = {:?}", inline_start_content_edge); + debug!( + "inline_start_content_edge = {:?}", + inline_start_content_edge + ); let padding_and_borders = self.block_flow.fragment.border_padding.inline_start_end(); // Distance from the inline-end margin edge to the inline-end content edge. - let inline_end_content_edge = - self.block_flow.fragment.margin.inline_end + + let inline_end_content_edge = self.block_flow.fragment.margin.inline_end + self.block_flow.fragment.border_padding.inline_end; debug!("padding_and_borders = {:?}", padding_and_borders); - debug!("self.block_flow.fragment.border_box.size.inline = {:?}", - self.block_flow.fragment.border_box.size.inline); - let content_inline_size = self.block_flow.fragment.border_box.size.inline - padding_and_borders; + debug!( + "self.block_flow.fragment.border_box.size.inline = {:?}", + self.block_flow.fragment.border_box.size.inline + ); + let content_inline_size = + self.block_flow.fragment.border_box.size.inline - padding_and_borders; match self.main_mode { Direction::Inline => { self.available_main_size = available_inline_size; self.available_cross_size = available_block_size; - self.inline_mode_assign_inline_sizes(layout_context, - inline_start_content_edge, - inline_end_content_edge, - content_inline_size) - } - Direction::Block => { + self.inline_mode_assign_inline_sizes( + layout_context, + inline_start_content_edge, + inline_end_content_edge, + content_inline_size, + ) + }, + Direction::Block => { self.available_main_size = available_block_size; self.available_cross_size = available_inline_size; - self.block_mode_assign_inline_sizes(layout_context, - inline_start_content_edge, - inline_end_content_edge, - content_inline_size) - } + self.block_mode_assign_inline_sizes( + layout_context, + inline_start_content_edge, + inline_end_content_edge, + content_inline_size, + ) + }, } } @@ -941,31 +1046,37 @@ impl Flow for FlexFlow { match self.main_mode { Direction::Inline => { self.inline_mode_assign_block_size(layout_context); - let block_start = AdjoiningMargins::from_margin(self.block_flow.fragment.margin.block_start); - let block_end = AdjoiningMargins::from_margin(self.block_flow.fragment.margin.block_end); - self.block_flow.base.collapsible_margins = CollapsibleMargins::Collapse(block_start, block_end); + let block_start = + AdjoiningMargins::from_margin(self.block_flow.fragment.margin.block_start); + let block_end = + AdjoiningMargins::from_margin(self.block_flow.fragment.margin.block_end); + self.block_flow.base.collapsible_margins = + CollapsibleMargins::Collapse(block_start, block_end); // TODO(stshine): assign proper static position for absolute descendants. if (&*self as &Flow).contains_roots_of_absolute_flow_tree() { // Assign block-sizes for all flows in this absolute flow tree. // This is preorder because the block-size of an absolute flow may depend on // the block-size of its containing block, which may also be an absolute flow. - let assign_abs_b_sizes = AbsoluteAssignBSizesTraversal(layout_context.shared_context()); + let assign_abs_b_sizes = + AbsoluteAssignBSizesTraversal(layout_context.shared_context()); assign_abs_b_sizes.traverse_absolute_flows(&mut *self); } - } - Direction::Block =>{ - self.block_flow - .assign_block_size_block_base(layout_context, - None, - MarginsMayCollapseFlag::MarginsMayNotCollapse); + }, + Direction::Block => { + self.block_flow.assign_block_size_block_base( + layout_context, + None, + MarginsMayCollapseFlag::MarginsMayNotCollapse, + ); self.block_mode_assign_block_size(); - } + }, } } fn compute_stacking_relative_position(&mut self, layout_context: &LayoutContext) { - self.block_flow.compute_stacking_relative_position(layout_context) + self.block_flow + .compute_stacking_relative_position(layout_context) } fn place_float_if_applicable<'a>(&mut self) { @@ -973,11 +1084,13 @@ impl Flow for FlexFlow { } fn update_late_computed_inline_position_if_necessary(&mut self, inline_position: Au) { - self.block_flow.update_late_computed_inline_position_if_necessary(inline_position) + self.block_flow + .update_late_computed_inline_position_if_necessary(inline_position) } fn update_late_computed_block_position_if_necessary(&mut self, block_position: Au) { - self.block_flow.update_late_computed_block_position_if_necessary(block_position) + self.block_flow + .update_late_computed_block_position_if_necessary(block_position) } fn build_display_list(&mut self, state: &mut DisplayListBuildState) { @@ -1008,11 +1121,17 @@ impl Flow for FlexFlow { self.block_flow.generated_containing_block_size(flow) } - fn iterate_through_fragment_border_boxes(&self, - iterator: &mut FragmentBorderBoxIterator, - level: i32, - stacking_context_position: &Point2D<Au>) { - self.block_flow.iterate_through_fragment_border_boxes(iterator, level, stacking_context_position); + fn iterate_through_fragment_border_boxes( + &self, + iterator: &mut FragmentBorderBoxIterator, + level: i32, + stacking_context_position: &Point2D<Au>, + ) { + self.block_flow.iterate_through_fragment_border_boxes( + iterator, + level, + stacking_context_position, + ); } fn mutate_fragments(&mut self, mutator: &mut FnMut(&mut Fragment)) { |