mirror of
https://github.com/servo/servo.git
synced 2025-08-03 20:50:07 +01:00
Share more code for non-replaced float-avoiding blocks (#34585)
Block-level elements that establish an independent formatting context (or are replaced) need to avoid overlapping floats. In the non-replaced case, we have two different subcases, depending on whether the inline size of the element is known. This patch makes them share more logic. Then `solve_clearance_and_inline_margins_avoiding_floats()` would only be used in the replaced case, so it's removed, inlining its logic. Signed-off-by: Oriol Brufau <obrufau@igalia.com>
This commit is contained in:
parent
0ffa5fa277
commit
acf0074f8a
2 changed files with 46 additions and 86 deletions
|
@ -1103,11 +1103,8 @@ impl SequentialLayoutState {
|
|||
let placement_rect = placement.place();
|
||||
let position = &placement_rect.start_corner;
|
||||
let has_clearance = clear_position.is_some() || position.block > ceiling;
|
||||
let clearance = if has_clearance {
|
||||
Some(position.block - self.position_with_zero_clearance(block_start_margin))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
let clearance = has_clearance
|
||||
.then(|| position.block - self.position_with_zero_clearance(block_start_margin));
|
||||
(clearance, placement_rect)
|
||||
}
|
||||
|
||||
|
|
|
@ -1121,9 +1121,6 @@ impl IndependentNonReplacedContents {
|
|||
.clamp_between_extremums(content_min_box_size.block, content_max_box_size.block)
|
||||
});
|
||||
|
||||
let margin_inline_start;
|
||||
let margin_inline_end;
|
||||
let effective_margin_inline_start;
|
||||
let (margin_block_start, margin_block_end) =
|
||||
solve_block_margins_for_in_flow_block_level(&pbm);
|
||||
let collapsed_margin_block_start = CollapsedMargin::new(margin_block_start);
|
||||
|
@ -1138,10 +1135,22 @@ impl IndependentNonReplacedContents {
|
|||
// sufficient space. They may even make the border box of said element narrower
|
||||
// than defined by section 10.3.3. CSS 2 does not define when a UA may put said
|
||||
// element next to the float or by how much said element may become narrower."
|
||||
let clearance;
|
||||
let mut content_size;
|
||||
let mut layout;
|
||||
let mut placement_rect;
|
||||
let style = &base.style;
|
||||
|
||||
// First compute the clear position required by the 'clear' property.
|
||||
// The code below may then add extra clearance when the element can't fit
|
||||
// next to floats not covered by 'clear'.
|
||||
let clear_position = sequential_layout_state.calculate_clear_position(
|
||||
Clear::from_style_and_container_writing_mode(style, containing_block_writing_mode),
|
||||
&collapsed_margin_block_start,
|
||||
);
|
||||
let ceiling = clear_position.unwrap_or_else(|| {
|
||||
sequential_layout_state.position_without_clearance(&collapsed_margin_block_start)
|
||||
});
|
||||
|
||||
if let AuOrAuto::LengthPercentage(ref inline_size) = content_box_size.inline {
|
||||
let inline_size = inline_size
|
||||
.clamp_between_extremums(content_min_box_size.inline, content_max_box_size.inline);
|
||||
|
@ -1175,30 +1184,14 @@ impl IndependentNonReplacedContents {
|
|||
};
|
||||
}
|
||||
|
||||
(
|
||||
clearance,
|
||||
(margin_inline_start, margin_inline_end),
|
||||
effective_margin_inline_start,
|
||||
) = solve_clearance_and_inline_margins_avoiding_floats(
|
||||
sequential_layout_state,
|
||||
&collapsed_margin_block_start,
|
||||
containing_block,
|
||||
&pbm,
|
||||
let mut placement = PlacementAmongFloats::new(
|
||||
&sequential_layout_state.floats,
|
||||
ceiling,
|
||||
content_size + pbm.padding_border_sums,
|
||||
style,
|
||||
&pbm,
|
||||
);
|
||||
placement_rect = placement.place();
|
||||
} else {
|
||||
// First compute the clear position required by the 'clear' property.
|
||||
// The code below may then add extra clearance when the element can't fit
|
||||
// next to floats not covered by 'clear'.
|
||||
let clear_position = sequential_layout_state.calculate_clear_position(
|
||||
Clear::from_style_and_container_writing_mode(style, containing_block_writing_mode),
|
||||
&collapsed_margin_block_start,
|
||||
);
|
||||
let ceiling = clear_position.unwrap_or_else(|| {
|
||||
sequential_layout_state.position_without_clearance(&collapsed_margin_block_start)
|
||||
});
|
||||
|
||||
// Create a PlacementAmongFloats using the minimum size in all dimensions as the object size.
|
||||
let minimum_size_of_block = LogicalVec2 {
|
||||
inline: content_min_box_size.inline,
|
||||
|
@ -1210,7 +1203,6 @@ impl IndependentNonReplacedContents {
|
|||
minimum_size_of_block,
|
||||
&pbm,
|
||||
);
|
||||
let mut placement_rect;
|
||||
|
||||
loop {
|
||||
// First try to place the block using the minimum size as the object size.
|
||||
|
@ -1284,31 +1276,26 @@ impl IndependentNonReplacedContents {
|
|||
// attempt.
|
||||
positioning_context.truncate(&positioning_context_length);
|
||||
}
|
||||
}
|
||||
|
||||
// Only set clearance if we would have cleared or the placement among floats moves
|
||||
// the block further in the block direction. These two situations are the ones that
|
||||
// prevent margin collapse.
|
||||
clearance = if clear_position.is_some() || placement_rect.start_corner.block > ceiling {
|
||||
Some(
|
||||
let has_clearance = clear_position.is_some() || placement_rect.start_corner.block > ceiling;
|
||||
let clearance = has_clearance.then(|| {
|
||||
placement_rect.start_corner.block -
|
||||
sequential_layout_state
|
||||
.position_with_zero_clearance(&collapsed_margin_block_start),
|
||||
)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
.position_with_zero_clearance(&collapsed_margin_block_start)
|
||||
});
|
||||
|
||||
(
|
||||
(margin_inline_start, margin_inline_end),
|
||||
effective_margin_inline_start,
|
||||
) = solve_inline_margins_avoiding_floats(
|
||||
let ((margin_inline_start, margin_inline_end), effective_margin_inline_start) =
|
||||
solve_inline_margins_avoiding_floats(
|
||||
sequential_layout_state,
|
||||
containing_block,
|
||||
&pbm,
|
||||
content_size.inline + pbm.padding_border_sums.inline,
|
||||
placement_rect,
|
||||
);
|
||||
}
|
||||
|
||||
let margin = LogicalSides {
|
||||
inline_start: margin_inline_start,
|
||||
|
@ -1409,17 +1396,26 @@ impl ReplacedContents {
|
|||
// element next to the float or by how much said element may become narrower."
|
||||
let collapsed_margin_block_start = CollapsedMargin::new(margin_block_start);
|
||||
let size = content_size + pbm.padding_border_sums;
|
||||
(
|
||||
clearance,
|
||||
(margin_inline_start, margin_inline_end),
|
||||
effective_margin_inline_start,
|
||||
) = solve_clearance_and_inline_margins_avoiding_floats(
|
||||
sequential_layout_state,
|
||||
let placement_rect;
|
||||
(clearance, placement_rect) = sequential_layout_state
|
||||
.calculate_clearance_and_inline_adjustment(
|
||||
Clear::from_style_and_container_writing_mode(
|
||||
&base.style,
|
||||
containing_block.style.writing_mode,
|
||||
),
|
||||
&collapsed_margin_block_start,
|
||||
containing_block,
|
||||
pbm,
|
||||
size,
|
||||
&base.style,
|
||||
);
|
||||
(
|
||||
(margin_inline_start, margin_inline_end),
|
||||
effective_margin_inline_start,
|
||||
) = solve_inline_margins_avoiding_floats(
|
||||
sequential_layout_state,
|
||||
containing_block,
|
||||
pbm,
|
||||
size.inline,
|
||||
placement_rect,
|
||||
);
|
||||
|
||||
// Clearance prevents margin collapse between this block and previous ones,
|
||||
|
@ -1738,39 +1734,6 @@ fn solve_inline_margins_avoiding_floats(
|
|||
(inline_margins, effective_margin_inline_start)
|
||||
}
|
||||
|
||||
/// A block-level element that establishes an independent formatting context (or is replaced)
|
||||
/// must not overlap floats.
|
||||
/// This can be achieved by adding clearance (to adjust the position in the block axis)
|
||||
/// and/or modifying the margins in the inline axis.
|
||||
/// This function takes care of calculating them.
|
||||
fn solve_clearance_and_inline_margins_avoiding_floats(
|
||||
sequential_layout_state: &SequentialLayoutState,
|
||||
block_start_margin: &CollapsedMargin,
|
||||
containing_block: &ContainingBlock,
|
||||
pbm: &PaddingBorderMargin,
|
||||
size: LogicalVec2<Au>,
|
||||
style: &Arc<ComputedValues>,
|
||||
) -> (Option<Au>, (Au, Au), Au) {
|
||||
let (clearance, placement_rect) = sequential_layout_state
|
||||
.calculate_clearance_and_inline_adjustment(
|
||||
Clear::from_style_and_container_writing_mode(
|
||||
style,
|
||||
containing_block.style.writing_mode,
|
||||
),
|
||||
block_start_margin,
|
||||
pbm,
|
||||
size,
|
||||
);
|
||||
let (inline_margins, effective_margin_inline_start) = solve_inline_margins_avoiding_floats(
|
||||
sequential_layout_state,
|
||||
containing_block,
|
||||
pbm,
|
||||
size.inline,
|
||||
placement_rect,
|
||||
);
|
||||
(clearance, inline_margins, effective_margin_inline_start)
|
||||
}
|
||||
|
||||
/// State that we maintain when placing blocks.
|
||||
///
|
||||
/// In parallel mode, this placement is done after all child blocks are laid out. In
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue