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

LibWeb: Reorganize layout algorithm

Previously, layout recursively performed these steps (roughly):

1. Compute own width
2. Compute own position
3. Layout in-flow children
4. Compute own height
5. Layout absolutely positioned descendants

However, step (2) was pretty inconsistent. Some things computed their
own position, others had their parent do it for them, etc.
To get closer to CSS spec language, and make things easier in general,
this patch reorganizes the algorithm into:

1. Compute own width & height
2. Compute width & height of in-flow managed descendants
3. Move in-flow managed descendants to their final position
4. Layout absolutely positioned descendants

Block layout is now driven by the containing block, which will iterate
the descendants it's responsible for. There are a lot of inefficient
patterns in this logic right now, but they can easily be replaced with
better iteration functions once we settle on a long-term architecture.

Since the ICB (LayoutDocument) is at (0, 0), it doesn't rely on a
containing block to move it into place.

This code is still evolving along with my understanding of CSS layout,
so it's likely that we'll reorganize this again sooner or later. :^)
This commit is contained in:
Andreas Kling 2020-06-14 18:48:10 +02:00
parent 2b47ba6c3f
commit c7d9229a0f
8 changed files with 144 additions and 162 deletions

View file

@ -65,26 +65,25 @@ public:
virtual void split_into_lines(LayoutBlock& container, LayoutMode) override;
void add_absolutely_positioned_descendant(LayoutBox&);
size_t absolutely_positioned_descendant_count() const { return m_absolutely_positioned_descendants.size(); }
protected:
void compute_width();
void compute_position();
void compute_height();
void layout_absolutely_positioned_descendants();
private:
virtual bool is_block() const override { return true; }
void place_block_level_non_replaced_element_in_normal_flow(LayoutBlock&);
void place_block_level_replaced_element_in_normal_flow(LayoutReplaced&);
void layout_absolutely_positioned_descendant(LayoutBox&);
NonnullRefPtr<StyleProperties> style_for_anonymous_block() const;
void layout_children(LayoutMode);
void layout_inside(LayoutMode);
void layout_inline_children(LayoutMode);
void layout_block_children(LayoutMode);
void layout_contained_boxes(LayoutMode);
Vector<LineBox> m_line_boxes;
HashTable<RefPtr<LayoutBox>> m_absolutely_positioned_descendants;
};
template<typename Callback>