diff options
author | Andreas Kling <kling@serenityos.org> | 2020-06-13 00:12:23 +0200 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2020-06-13 00:12:23 +0200 |
commit | 62893a54cccf7dcd437e6c7b32453be36a238c36 (patch) | |
tree | 4a73a3f4886be3ea47133ddd4ce9621e891b20d6 | |
parent | 365703e3f3cb763427b355966457f6d946cfeaa4 (diff) | |
download | serenity-62893a54cccf7dcd437e6c7b32453be36a238c36.zip |
LibWeb: More work on table layout
Table row layout is now split into two phases:
1. Compute all the column widths (even taking colspan into account!)
2. Place all cells at the correct x,y offsets based on column widths.
Both phases visit all rows and all cells.
-rw-r--r-- | Libraries/LibWeb/Layout/LayoutTableRow.cpp | 22 | ||||
-rw-r--r-- | Libraries/LibWeb/Layout/LayoutTableRow.h | 6 | ||||
-rw-r--r-- | Libraries/LibWeb/Layout/LayoutTableRowGroup.cpp | 28 | ||||
-rw-r--r-- | Libraries/LibWeb/Layout/LayoutTableRowGroup.h | 2 |
4 files changed, 52 insertions, 6 deletions
diff --git a/Libraries/LibWeb/Layout/LayoutTableRow.cpp b/Libraries/LibWeb/Layout/LayoutTableRow.cpp index e241e642de..e571d398f1 100644 --- a/Libraries/LibWeb/Layout/LayoutTableRow.cpp +++ b/Libraries/LibWeb/Layout/LayoutTableRow.cpp @@ -41,12 +41,30 @@ LayoutTableRow::~LayoutTableRow() void LayoutTableRow::layout(LayoutMode) { +} + +void LayoutTableRow::calculate_column_widths(Vector<float>& column_widths) +{ + size_t column_index = 0; + for_each_child_of_type<LayoutTableCell>([&](auto& cell) { + cell.layout(LayoutMode::OnlyRequiredLineBreaks); + column_widths[column_index] = max(column_widths[column_index], cell.width()); + column_index += cell.colspan(); + }); +} + +void LayoutTableRow::layout_row(const Vector<float>& column_widths) +{ + size_t column_index = 0; float tallest_cell_height = 0; float content_width = 0; + for_each_child_of_type<LayoutTableCell>([&](auto& cell) { - cell.layout(LayoutMode::OnlyRequiredLineBreaks); cell.set_offset(effective_offset().translated(content_width, 0)); - content_width += cell.width(); + + size_t cell_colspan = cell.colspan(); + for (size_t i = 0; i < cell_colspan; ++i) + content_width += column_widths[column_index++]; tallest_cell_height = max(tallest_cell_height, cell.height()); }); set_width(content_width); diff --git a/Libraries/LibWeb/Layout/LayoutTableRow.h b/Libraries/LibWeb/Layout/LayoutTableRow.h index ded261d16f..fe88582587 100644 --- a/Libraries/LibWeb/Layout/LayoutTableRow.h +++ b/Libraries/LibWeb/Layout/LayoutTableRow.h @@ -37,7 +37,7 @@ public: LayoutTableRow(const Element&, NonnullRefPtr<StyleProperties>); virtual ~LayoutTableRow() override; - virtual void layout(LayoutMode = LayoutMode::Default) override; + LayoutTableCell* first_cell(); const LayoutTableCell* first_cell() const; @@ -45,7 +45,11 @@ public: LayoutTableRow* next_row(); const LayoutTableRow* next_row() const; + void layout_row(const Vector<float>& column_widths); + void calculate_column_widths(Vector<float>& column_widths); + private: + virtual void layout(LayoutMode) override; virtual bool is_table_row() const override { return true; } virtual const char* class_name() const override { return "LayoutTableRow"; } }; diff --git a/Libraries/LibWeb/Layout/LayoutTableRowGroup.cpp b/Libraries/LibWeb/Layout/LayoutTableRowGroup.cpp index 1ae56218a0..57db85120b 100644 --- a/Libraries/LibWeb/Layout/LayoutTableRowGroup.cpp +++ b/Libraries/LibWeb/Layout/LayoutTableRowGroup.cpp @@ -25,8 +25,9 @@ */ #include <LibWeb/DOM/Element.h> -#include <LibWeb/Layout/LayoutTableRowGroup.h> +#include <LibWeb/Layout/LayoutTableCell.h> #include <LibWeb/Layout/LayoutTableRow.h> +#include <LibWeb/Layout/LayoutTableRowGroup.h> namespace Web { @@ -39,18 +40,39 @@ LayoutTableRowGroup::~LayoutTableRowGroup() { } -void LayoutTableRowGroup::layout(LayoutMode layout_mode) +size_t LayoutTableRowGroup::column_count() const +{ + size_t table_column_count = 0; + for_each_child_of_type<LayoutTableRow>([&](auto& row) { + size_t row_column_count = 0; + row.template for_each_child_of_type<LayoutTableCell>([&](auto& cell) { + row_column_count += cell.colspan(); + }); + table_column_count = max(table_column_count, row_column_count); + }); + return table_column_count; +} + +void LayoutTableRowGroup::layout(LayoutMode) { compute_width(); if (!is_inline()) compute_position(); + auto column_count = this->column_count(); + Vector<float> column_widths; + column_widths.resize(column_count); + + for_each_child_of_type<LayoutTableRow>([&](auto& row) { + row.calculate_column_widths(column_widths); + }); + float content_height = 0; for_each_child_of_type<LayoutTableRow>([&](auto& row) { row.set_offset(0, content_height); - row.layout(layout_mode); + row.layout_row(column_widths); content_height += row.height(); }); diff --git a/Libraries/LibWeb/Layout/LayoutTableRowGroup.h b/Libraries/LibWeb/Layout/LayoutTableRowGroup.h index f35f4571e7..ea535dc86d 100644 --- a/Libraries/LibWeb/Layout/LayoutTableRowGroup.h +++ b/Libraries/LibWeb/Layout/LayoutTableRowGroup.h @@ -38,6 +38,8 @@ public: virtual void layout(LayoutMode = LayoutMode::Default) override; private: + size_t column_count() const; + virtual bool is_table_row_group() const override { return true; } virtual const char* class_name() const override { return "LayoutTableRowGroup"; } }; |