From f4625ed9de71bd5b396b170dc6551cd21d20ae45 Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Mon, 14 Feb 2022 16:39:45 +0100 Subject: [PATCH] LibWeb: Paint inline-level and replaced elements on top of floats This matches CSS 2.1 appendix E, and fixes an instance of red face border on ACID2. :^) --- .../LibWeb/Painting/StackingContext.cpp | 17 +++++++++++++++-- .../Libraries/LibWeb/Painting/StackingContext.h | 1 + 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/Userland/Libraries/LibWeb/Painting/StackingContext.cpp b/Userland/Libraries/LibWeb/Painting/StackingContext.cpp index 1cc1ab4b75e..9bb75100693 100644 --- a/Userland/Libraries/LibWeb/Painting/StackingContext.cpp +++ b/Userland/Libraries/LibWeb/Painting/StackingContext.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, Andreas Kling + * Copyright (c) 2020-2022, Andreas Kling * * SPDX-License-Identifier: BSD-2-Clause */ @@ -9,6 +9,7 @@ #include #include #include +#include #include namespace Web::Layout { @@ -40,9 +41,10 @@ void StackingContext::paint_descendants(PaintContext& context, Node& box, Stacki box.for_each_child([&](auto& child) { if (child.establishes_stacking_context()) return; + bool child_is_inline_or_replaced = child.is_inline() || is(child); switch (phase) { case StackingContextPaintPhase::BackgroundAndBorders: - if (!child.is_floating() && !child.is_positioned()) { + if (!child_is_inline_or_replaced && !child.is_floating() && !child.is_positioned()) { child.paint(context, PaintPhase::Background); child.paint(context, PaintPhase::Border); paint_descendants(context, child, phase); @@ -58,6 +60,16 @@ void StackingContext::paint_descendants(PaintContext& context, Node& box, Stacki paint_descendants(context, child, phase); } break; + case StackingContextPaintPhase::BackgroundAndBordersForInlineLevelAndReplaced: + if (!child.is_positioned()) { + if (child_is_inline_or_replaced) { + child.paint(context, PaintPhase::Background); + child.paint(context, PaintPhase::Border); + paint_descendants(context, child, StackingContextPaintPhase::BackgroundAndBorders); + } + paint_descendants(context, child, phase); + } + break; case StackingContextPaintPhase::Foreground: if (!child.is_positioned()) { child.paint(context, PaintPhase::Foreground); @@ -94,6 +106,7 @@ void StackingContext::paint_internal(PaintContext& context) // Draw the non-positioned floats (step 5) paint_descendants(context, m_box, StackingContextPaintPhase::Floats); // Draw inline content, replaced content, etc. (steps 6, 7) + paint_descendants(context, m_box, StackingContextPaintPhase::BackgroundAndBordersForInlineLevelAndReplaced); m_box.paint(context, PaintPhase::Foreground); paint_descendants(context, m_box, StackingContextPaintPhase::Foreground); // Draw other positioned descendants (steps 8, 9) diff --git a/Userland/Libraries/LibWeb/Painting/StackingContext.h b/Userland/Libraries/LibWeb/Painting/StackingContext.h index 1e8142718bd..980b0a13e1b 100644 --- a/Userland/Libraries/LibWeb/Painting/StackingContext.h +++ b/Userland/Libraries/LibWeb/Painting/StackingContext.h @@ -21,6 +21,7 @@ public: enum class StackingContextPaintPhase { BackgroundAndBorders, Floats, + BackgroundAndBordersForInlineLevelAndReplaced, Foreground, FocusAndOverlay, };