From f079214b18ff08037fed143bea6f0722fb9d7dd3 Mon Sep 17 00:00:00 2001 From: MacDue Date: Tue, 19 Jul 2022 11:02:56 +0100 Subject: [PATCH] LibWeb: Apply overflow: hidden to all (relevant) child paint phases Previously, before/after_children_paint() was only called for the "Foreground" paint phase, this meant the backgrounds and other features of child nodes of a element with overflow: hidden were not clipped. --- .../LibWeb/Painting/PaintableBox.cpp | 11 +++++-- .../LibWeb/Painting/StackingContext.cpp | 29 ++++++++++++++----- 2 files changed, 30 insertions(+), 10 deletions(-) diff --git a/Userland/Libraries/LibWeb/Painting/PaintableBox.cpp b/Userland/Libraries/LibWeb/Painting/PaintableBox.cpp index 2c33f7125a..b2450c97dc 100644 --- a/Userland/Libraries/LibWeb/Painting/PaintableBox.cpp +++ b/Userland/Libraries/LibWeb/Painting/PaintableBox.cpp @@ -4,6 +4,7 @@ * SPDX-License-Identifier: BSD-2-Clause */ +#include #include #include #include @@ -242,8 +243,11 @@ BorderRadiiData PaintableBox::normalized_border_radii_data() const computed_values().border_bottom_left_radius()); } -void PaintableBox::before_children_paint(PaintContext& context, PaintPhase) const +void PaintableBox::before_children_paint(PaintContext& context, PaintPhase phase) const { + if (!AK::first_is_one_of(phase, PaintPhase::Background, PaintPhase::Border, PaintPhase::Foreground)) + return; + // FIXME: Support more overflow variations. auto clip_rect = absolute_padding_box_rect().to_rounded(); auto overflow_x = computed_values().overflow_x(); @@ -277,8 +281,11 @@ void PaintableBox::before_children_paint(PaintContext& context, PaintPhase) cons } } -void PaintableBox::after_children_paint(PaintContext& context, PaintPhase) const +void PaintableBox::after_children_paint(PaintContext& context, PaintPhase phase) const { + if (!AK::first_is_one_of(phase, PaintPhase::Background, PaintPhase::Border, PaintPhase::Foreground)) + return; + // FIXME: Support more overflow variations. if (m_clipping_overflow) { context.painter().restore(); diff --git a/Userland/Libraries/LibWeb/Painting/StackingContext.cpp b/Userland/Libraries/LibWeb/Painting/StackingContext.cpp index cbb78986a9..36568edd5c 100644 --- a/Userland/Libraries/LibWeb/Painting/StackingContext.cpp +++ b/Userland/Libraries/LibWeb/Painting/StackingContext.cpp @@ -48,12 +48,27 @@ void StackingContext::sort() child->sort(); } +static PaintPhase to_paint_phase(StackingContext::StackingContextPaintPhase phase) +{ + // There are not a fully correct mapping since some stacking context phases are combind. + switch (phase) { + case StackingContext::StackingContextPaintPhase::Floats: + case StackingContext::StackingContextPaintPhase::BackgroundAndBordersForInlineLevelAndReplaced: + case StackingContext::StackingContextPaintPhase::BackgroundAndBorders: + return PaintPhase::Background; + case StackingContext::StackingContextPaintPhase::Foreground: + return PaintPhase::Foreground; + case StackingContext::StackingContextPaintPhase::FocusAndOverlay: + return PaintPhase::Overlay; + default: + VERIFY_NOT_REACHED(); + } +} + void StackingContext::paint_descendants(PaintContext& context, Layout::Node& box, StackingContextPaintPhase phase) const { - if (phase == StackingContextPaintPhase::Foreground) { - if (auto* paintable = box.paintable()) - paintable->before_children_paint(context, PaintPhase::Foreground); - } + if (auto* paintable = box.paintable()) + paintable->before_children_paint(context, to_paint_phase(phase)); box.for_each_child([&](auto& child) { // If `child` establishes its own stacking context, skip over it. @@ -104,10 +119,8 @@ void StackingContext::paint_descendants(PaintContext& context, Layout::Node& box } }); - if (phase == StackingContextPaintPhase::Foreground) { - if (auto* paintable = box.paintable()) - paintable->after_children_paint(context, PaintPhase::Foreground); - } + if (auto* paintable = box.paintable()) + paintable->after_children_paint(context, to_paint_phase(phase)); } void StackingContext::paint_internal(PaintContext& context) const