diff --git a/Userland/Libraries/LibWeb/Painting/PaintableBox.h b/Userland/Libraries/LibWeb/Painting/PaintableBox.h index 8d79c3d956..c288cedf97 100644 --- a/Userland/Libraries/LibWeb/Painting/PaintableBox.h +++ b/Userland/Libraries/LibWeb/Painting/PaintableBox.h @@ -124,6 +124,14 @@ public: bool is_out_of_view(PaintContext&) const; void set_override_borders_data(BordersData const& override_borders_data) { m_override_borders_data = override_borders_data; }; + auto const& override_borders_data() const { return m_override_borders_data; } + + enum class ShrinkRadiiForBorders { + Yes, + No + }; + + BorderRadiiData normalized_border_radii_data(ShrinkRadiiForBorders shrink = ShrinkRadiiForBorders::No) const; protected: explicit PaintableBox(Layout::Box const&); @@ -136,13 +144,6 @@ protected: virtual CSSPixelRect compute_absolute_rect() const; virtual CSSPixelRect compute_absolute_paint_rect() const; - enum class ShrinkRadiiForBorders { - Yes, - No - }; - - BorderRadiiData normalized_border_radii_data(ShrinkRadiiForBorders shrink = ShrinkRadiiForBorders::No) const; - Vector resolve_box_shadow_data() const; private: diff --git a/Userland/Libraries/LibWeb/Painting/StackingContext.cpp b/Userland/Libraries/LibWeb/Painting/StackingContext.cpp index 52832e6284..1fc254d270 100644 --- a/Userland/Libraries/LibWeb/Painting/StackingContext.cpp +++ b/Userland/Libraries/LibWeb/Painting/StackingContext.cpp @@ -72,6 +72,33 @@ static PaintPhase to_paint_phase(StackingContext::StackingContextPaintPhase phas } } +static void collect_cell_boxes_with_collapsed_borders(Vector& cell_boxes, Layout::Node const& box) +{ + box.for_each_child([&](auto& child) { + if (child.display().is_table_cell() && child.computed_values().border_collapse() == CSS::BorderCollapse::Collapse) { + VERIFY(is(child) && child.paintable()); + cell_boxes.append(static_cast(child).paintable_box()); + } else { + collect_cell_boxes_with_collapsed_borders(cell_boxes, child); + } + }); +} + +static void paint_table_collapsed_borders(PaintContext& context, Layout::Node const& box) +{ + Vector cell_boxes; + collect_cell_boxes_with_collapsed_borders(cell_boxes, box); + for (auto const cell_box : cell_boxes) { + auto borders_data = cell_box->override_borders_data().has_value() ? cell_box->override_borders_data().value() : BordersData { + .top = cell_box->box_model().border.top == 0 ? CSS::BorderData() : cell_box->computed_values().border_top(), + .right = cell_box->box_model().border.right == 0 ? CSS::BorderData() : cell_box->computed_values().border_right(), + .bottom = cell_box->box_model().border.bottom == 0 ? CSS::BorderData() : cell_box->computed_values().border_bottom(), + .left = cell_box->box_model().border.left == 0 ? CSS::BorderData() : cell_box->computed_values().border_left(), + }; + paint_all_borders(context, cell_box->absolute_border_box_rect(), cell_box->normalized_border_radii_data(), borders_data); + } +} + void StackingContext::paint_descendants(PaintContext& context, Layout::Node const& box, StackingContextPaintPhase phase) const { if (auto* paintable = box.paintable()) { @@ -95,8 +122,11 @@ void StackingContext::paint_descendants(PaintContext& context, Layout::Node cons case StackingContextPaintPhase::BackgroundAndBorders: if (!child_is_inline_or_replaced && !child.is_floating()) { paint_node(child, context, PaintPhase::Background); - paint_node(child, context, PaintPhase::Border); + if ((!child.display().is_table_cell() && !child.display().is_table_inside()) || child.computed_values().border_collapse() == CSS::BorderCollapse::Separate) + paint_node(child, context, PaintPhase::Border); paint_descendants(context, child, phase); + if (child.computed_values().border_collapse() == CSS::BorderCollapse::Collapse) + paint_table_collapsed_borders(context, child); } break; case StackingContextPaintPhase::Floats: