Browse Source

LibWeb: Move background painting from Box to its own file

This makes the code accessible to things that aren't a Box, such as
InlineNode.
Sam Atkins 3 years ago
parent
commit
abc22b727c

+ 1 - 0
Userland/Libraries/LibWeb/CMakeLists.txt

@@ -221,6 +221,7 @@ set(SOURCES
     Page/EditEventHandler.cpp
     Page/EditEventHandler.cpp
     Page/EventHandler.cpp
     Page/EventHandler.cpp
     Page/Page.cpp
     Page/Page.cpp
+    Painting/BackgroundPainting.cpp
     Painting/BorderPainting.cpp
     Painting/BorderPainting.cpp
     Painting/ShadowPainting.cpp
     Painting/ShadowPainting.cpp
     Painting/StackingContext.cpp
     Painting/StackingContext.cpp

+ 9 - 47
Userland/Libraries/LibWeb/Layout/Box.cpp

@@ -13,6 +13,7 @@
 #include <LibWeb/Layout/Box.h>
 #include <LibWeb/Layout/Box.h>
 #include <LibWeb/Layout/FormattingContext.h>
 #include <LibWeb/Layout/FormattingContext.h>
 #include <LibWeb/Page/BrowsingContext.h>
 #include <LibWeb/Page/BrowsingContext.h>
+#include <LibWeb/Painting/BackgroundPainting.h>
 #include <LibWeb/Painting/BorderPainting.h>
 #include <LibWeb/Painting/BorderPainting.h>
 #include <LibWeb/Painting/ShadowPainting.h>
 #include <LibWeb/Painting/ShadowPainting.h>
 
 
@@ -175,7 +176,6 @@ void Box::paint_border(PaintContext& context)
 
 
 void Box::paint_background(PaintContext& context)
 void Box::paint_background(PaintContext& context)
 {
 {
-    auto padded_rect = this->padded_rect();
     // If the body's background properties were propagated to the root element, do no re-paint the body's background.
     // If the body's background properties were propagated to the root element, do no re-paint the body's background.
     if (is_body() && document().html_element()->should_use_body_background_properties())
     if (is_body() && document().html_element()->should_use_body_background_properties())
         return;
         return;
@@ -199,7 +199,7 @@ void Box::paint_background(PaintContext& context)
             background_repeat_y = document().background_repeat_y();
             background_repeat_y = document().background_repeat_y();
         }
         }
     } else {
     } else {
-        background_rect = enclosing_int_rect(padded_rect);
+        background_rect = enclosing_int_rect(padded_rect());
     }
     }
 
 
     // HACK: If the Box has a border, use the bordered_rect to paint the background.
     // HACK: If the Box has a border, use the bordered_rect to paint the background.
@@ -207,51 +207,13 @@ void Box::paint_background(PaintContext& context)
     if (computed_values().border_top().width || computed_values().border_right().width || computed_values().border_bottom().width || computed_values().border_left().width)
     if (computed_values().border_top().width || computed_values().border_right().width || computed_values().border_bottom().width || computed_values().border_left().width)
         background_rect = enclosing_int_rect(bordered_rect());
         background_rect = enclosing_int_rect(bordered_rect());
 
 
-    // FIXME: some values should be relative to the height() if specified, but which? For now, all relative values are relative to the width.
-    auto border_radius_data = normalized_border_radius_data();
-    auto top_left_radius = border_radius_data.top_left;
-    auto top_right_radius = border_radius_data.top_right;
-    auto bottom_right_radius = border_radius_data.bottom_right;
-    auto bottom_left_radius = border_radius_data.bottom_left;
-
-    context.painter().fill_rect_with_rounded_corners(background_rect, move(background_color), top_left_radius, top_right_radius, bottom_right_radius, bottom_left_radius);
-
-    if (background_image)
-        paint_background_image(context, *background_image, background_repeat_x, background_repeat_y, move(background_rect));
-}
-
-void Box::paint_background_image(
-    PaintContext& context,
-    const Gfx::Bitmap& background_image,
-    CSS::Repeat background_repeat_x,
-    CSS::Repeat background_repeat_y,
-    Gfx::IntRect background_rect)
-{
-    switch (background_repeat_x) {
-    case CSS::Repeat::Round:
-    case CSS::Repeat::Space:
-        // FIXME: Support 'round' and 'space'. Fall through to 'repeat' since that most closely resembles these.
-    case CSS::Repeat::Repeat:
-        // The background rect is already sized to align with 'repeat'.
-        break;
-    case CSS::Repeat::NoRepeat:
-        background_rect.set_width(background_image.width());
-        break;
-    }
-
-    switch (background_repeat_y) {
-    case CSS::Repeat::Round:
-    case CSS::Repeat::Space:
-        // FIXME: Support 'round' and 'space'. Fall through to 'repeat' since that most closely resembles these.
-    case CSS::Repeat::Repeat:
-        // The background rect is already sized to align with 'repeat'.
-        break;
-    case CSS::Repeat::NoRepeat:
-        background_rect.set_height(background_image.height());
-        break;
-    }
-
-    context.painter().blit_tiled(background_rect, background_image, background_image.rect());
+    auto background_data = Painting::BackgroundData {
+        .color = background_color,
+        .image = background_image,
+        .repeat_x = background_repeat_x,
+        .repeat_y = background_repeat_y
+    };
+    Painting::paint_background(context, background_rect, background_data, normalized_border_radius_data());
 }
 }
 
 
 void Box::paint_box_shadow(PaintContext& context)
 void Box::paint_box_shadow(PaintContext& context)

+ 0 - 2
Userland/Libraries/LibWeb/Layout/Box.h

@@ -141,8 +141,6 @@ protected:
 
 
     virtual void did_set_rect() { }
     virtual void did_set_rect() { }
 
 
-    void paint_background_image(PaintContext&, const Gfx::Bitmap&, CSS::Repeat, CSS::Repeat, Gfx::IntRect);
-
     Vector<LineBox> m_line_boxes;
     Vector<LineBox> m_line_boxes;
 
 
 private:
 private:

+ 51 - 0
Userland/Libraries/LibWeb/Painting/BackgroundPainting.cpp

@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
+ * Copyright (c) 2021, Sam Atkins <atkinssj@serenityos.org>
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#include <LibGfx/Painter.h>
+#include <LibWeb/Painting/BackgroundPainting.h>
+#include <LibWeb/Painting/PaintContext.h>
+
+namespace Web::Painting {
+
+void paint_background(PaintContext& context, Gfx::IntRect const& background_rect, BackgroundData const& background_data, BorderRadiusData const& border_radius)
+{
+    // FIXME: Support elliptical corners
+    context.painter().fill_rect_with_rounded_corners(background_rect, background_data.color, border_radius.top_left, border_radius.top_right, border_radius.bottom_right, border_radius.bottom_left);
+
+    // FIXME: Support multiple background layers
+    if (background_data.image) {
+        auto image_rect = background_rect;
+        switch (background_data.repeat_x) {
+        case CSS::Repeat::Round:
+        case CSS::Repeat::Space:
+            // FIXME: Support 'round' and 'space'. Fall through to 'repeat' since that most closely resembles these.
+        case CSS::Repeat::Repeat:
+            // The background rect is already sized to align with 'repeat'.
+            break;
+        case CSS::Repeat::NoRepeat:
+            image_rect.set_width(background_data.image->width());
+            break;
+        }
+
+        switch (background_data.repeat_y) {
+        case CSS::Repeat::Round:
+        case CSS::Repeat::Space:
+            // FIXME: Support 'round' and 'space'. Fall through to 'repeat' since that most closely resembles these.
+        case CSS::Repeat::Repeat:
+            // The background rect is already sized to align with 'repeat'.
+            break;
+        case CSS::Repeat::NoRepeat:
+            image_rect.set_height(background_data.image->height());
+            break;
+        }
+
+        // FIXME: Handle rounded corners
+        context.painter().blit_tiled(image_rect, *background_data.image, background_data.image->rect());
+    }
+}
+
+}

+ 25 - 0
Userland/Libraries/LibWeb/Painting/BackgroundPainting.h

@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2021, Sam Atkins <atkinssj@serenityos.org>
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#pragma once
+
+#include <LibGfx/Forward.h>
+#include <LibWeb/CSS/StyleValue.h>
+#include <LibWeb/Painting/BorderPainting.h>
+#include <LibWeb/Painting/PaintContext.h>
+
+namespace Web::Painting {
+
+struct BackgroundData {
+    Color color;
+    Gfx::Bitmap const* image;
+    CSS::Repeat repeat_x;
+    CSS::Repeat repeat_y;
+};
+
+void paint_background(PaintContext&, Gfx::IntRect const&, BackgroundData const&, BorderRadiusData const&);
+
+}