1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-25 16:27:35 +00:00

LibWeb: Create list-item markers during layout tree construction

Previously, these were added during layout. This didn't fit into the new
world where layout doesn't mutate the tree incrementally, so this patch
adds logic to Layout::TreeBuilder for adding a marker to each list-item
box after its children have been constructed.
This commit is contained in:
Andreas Kling 2022-02-21 01:43:37 +01:00
parent c9700e100e
commit 92266d2247
8 changed files with 65 additions and 54 deletions

View file

@ -405,10 +405,9 @@ void BlockFormattingContext::layout_block_level_children(BlockContainer const& b
if (is<ReplacedBox>(child_box) || is<BlockContainer>(child_box))
place_block_level_element_in_normal_flow_horizontally(child_box, block_container);
// FIXME: This should be factored differently. It's uncool that we mutate the tree *during* layout!
// Instead, we should generate the marker box during the tree build.
if (is<ListItemBox>(child_box))
verify_cast<ListItemBox>(child_box).layout_marker();
if (is<ListItemBox>(child_box)) {
layout_list_item_marker(static_cast<ListItemBox const&>(child_box));
}
content_height = max(content_height, box_state.offset.y() + box_state.content_height + box_state.margin_box_bottom());
content_width = max(content_width, box_state.content_width);
@ -663,4 +662,36 @@ void BlockFormattingContext::layout_floating_child(Box const& box, BlockContaine
float_box(FloatSide::Right, m_right_floats);
}
}
void BlockFormattingContext::layout_list_item_marker(ListItemBox const& list_item_box)
{
if (!list_item_box.marker())
return;
auto& marker = *list_item_box.marker();
auto& marker_state = m_state.ensure(marker);
auto& list_item_state = m_state.ensure(list_item_box);
int image_width = 0;
int image_height = 0;
if (auto const* list_style_image = marker.list_style_image_bitmap()) {
image_width = list_style_image->rect().width();
image_height = list_style_image->rect().height();
}
if (marker.text().is_empty()) {
marker_state.content_width = image_width + 4;
} else {
auto text_width = marker.font().width(marker.text());
marker_state.content_width = image_width + text_width;
}
marker_state.content_height = max(image_height, marker.line_height());
marker_state.offset = { -(marker_state.content_width + 4), 0 };
if (marker_state.content_height > list_item_state.content_height)
list_item_state.content_height = marker_state.content_height;
}
}