mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 06:37:43 +00:00
LibWeb: Rewrite CSS float implementation to use offset-from-edge
The previous implementation used relative X offsets for both left and right-side floats. This made right-side floats super awkward, since we could only determine their X position once the width of the BFC root was known, and for BFC roots with automatic width, this was not even working at all most of the time. This patch changes the way we deal with floats so that BFC keeps track of the offset-from-edge for each float. The offset is the distance from the BFC root edge (left or right, depending on float direction) to the "innermost" margin edge of the floating box. Floating box are now laid out in two passes: while going through the normal flow layout, we put floats in their *static* position (i.e the position they would have occupied if they weren't floating) and then update the Y position value to the final one. The second pass occurs later on, when the BFC root has had its width assigned by the parent context. Once we know the root width, we can set the X position value of floating boxes. (Because the X position of right-side floats is relative to the right edge of the BFC root.)
This commit is contained in:
parent
28642de6ed
commit
39b7fbfeb9
7 changed files with 245 additions and 83 deletions
|
@ -36,14 +36,30 @@ BlockFormattingContext const& InlineFormattingContext::parent() const
|
|||
return static_cast<BlockFormattingContext const&>(*FormattingContext::parent());
|
||||
}
|
||||
|
||||
FormattingContext::AvailableSpaceForLineInfo InlineFormattingContext::available_space_for_line(float y) const
|
||||
float InlineFormattingContext::leftmost_x_offset_at(float y) const
|
||||
{
|
||||
// NOTE: Floats are relative to the BFC root box, not necessarily the containing block of this IFC.
|
||||
auto box_in_root_rect = margin_box_rect_in_ancestor_coordinate_space(containing_block(), parent().root(), m_state);
|
||||
float y_in_root = box_in_root_rect.y() + y;
|
||||
auto space = parent().available_space_for_line(y_in_root);
|
||||
space.right = min(space.right, m_state.get(containing_block()).content_width);
|
||||
return space;
|
||||
auto space = parent().space_used_by_floats(y_in_root);
|
||||
float containing_block_x = m_state.get(containing_block()).offset.x();
|
||||
return max(space.left, containing_block_x) - containing_block_x;
|
||||
}
|
||||
|
||||
float InlineFormattingContext::available_space_for_line(float y) const
|
||||
{
|
||||
// NOTE: Floats are relative to the BFC root box, not necessarily the containing block of this IFC.
|
||||
auto box_in_root_rect = margin_box_rect_in_ancestor_coordinate_space(containing_block(), parent().root(), m_state);
|
||||
float y_in_root = box_in_root_rect.y() + y;
|
||||
auto space = parent().space_used_by_floats(y_in_root);
|
||||
|
||||
auto const& containing_block_state = m_state.get(containing_block());
|
||||
auto const& root_block_state = m_state.get(parent().root());
|
||||
|
||||
space.left = max(space.left, containing_block_state.offset.x());
|
||||
space.right = min(root_block_state.content_width - space.right, containing_block_state.offset.x() + containing_block_state.content_width);
|
||||
|
||||
return space.right - space.left;
|
||||
}
|
||||
|
||||
void InlineFormattingContext::run(Box const&, LayoutMode layout_mode)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue