浏览代码

LibWeb: Layout table-cell contents once again once final width is known

This makes centered and right-aligned table-cell contents position
itself correctly.
Andreas Kling 5 年之前
父节点
当前提交
dcc25f7d7a
共有 2 个文件被更改,包括 19 次插入9 次删除
  1. 2 1
      Libraries/LibWeb/Layout/LayoutBlock.h
  2. 17 8
      Libraries/LibWeb/Layout/LayoutTableRow.cpp

+ 2 - 1
Libraries/LibWeb/Layout/LayoutBlock.h

@@ -65,6 +65,8 @@ public:
 
     virtual void split_into_lines(LayoutBlock& container, LayoutMode) override;
 
+    void layout_inside(LayoutMode);
+
 protected:
     void compute_width();
     void compute_height();
@@ -89,7 +91,6 @@ private:
 
     NonnullRefPtr<StyleProperties> style_for_anonymous_block() const;
 
-    void layout_inside(LayoutMode);
     void layout_inline_children(LayoutMode);
     void layout_contained_boxes(LayoutMode);
 

+ 17 - 8
Libraries/LibWeb/Layout/LayoutTableRow.cpp

@@ -47,12 +47,13 @@ void LayoutTableRow::layout(LayoutMode)
 void LayoutTableRow::calculate_column_widths(Vector<float>& column_widths)
 {
     size_t column_index = 0;
+    auto* table = first_ancestor_of_type<LayoutTable>();
+    bool use_auto_layout = !table || table->style().width().is_undefined_or_auto();
     for_each_child_of_type<LayoutTableCell>([&](auto& cell) {
-        auto* table = first_ancestor_of_type<LayoutTable>();
-        if (table && !table->style().width().is_undefined_or_auto()) {
-            cell.layout(LayoutMode::Default);
-        } else {
+        if (use_auto_layout) {
             cell.layout(LayoutMode::OnlyRequiredLineBreaks);
+        } else {
+            cell.layout(LayoutMode::Default);
         }
         column_widths[column_index] = max(column_widths[column_index], cell.width());
         column_index += cell.colspan();
@@ -64,21 +65,29 @@ void LayoutTableRow::layout_row(const Vector<float>& column_widths)
     size_t column_index = 0;
     float tallest_cell_height = 0;
     float content_width = 0;
+    auto* table = first_ancestor_of_type<LayoutTable>();
+    bool use_auto_layout = !table || table->style().width().is_undefined_or_auto();
 
     for_each_child_of_type<LayoutTableCell>([&](auto& cell) {
         cell.set_offset(effective_offset().translated(content_width, 0));
 
+        // Layout the cell contents a second time, now that we know its final width.
+        if (use_auto_layout) {
+            cell.layout_inside(LayoutMode::OnlyRequiredLineBreaks);
+        } else {
+            cell.layout_inside(LayoutMode::Default);
+        }
+
         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());
     });
 
-    auto* table = first_ancestor_of_type<LayoutTable>();
-    if (table && !table->style().width().is_undefined_or_auto()) {
-        set_width(table->width());
-    } else {
+    if (use_auto_layout) {
         set_width(content_width);
+    } else {
+        set_width(table->width());
     }
 
     set_height(tallest_cell_height);