Bladeren bron

LibWeb: Move box-shadow painting out of Box to its own file

This makes the code accessible to things that aren't a Box, such as
InlineNode.
Sam Atkins 3 jaren geleden
bovenliggende
commit
b047c1bc97

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

@@ -222,6 +222,7 @@ set(SOURCES
     Page/EventHandler.cpp
     Page/Page.cpp
     Painting/BorderPainting.cpp
+    Painting/ShadowPainting.cpp
     Painting/StackingContext.cpp
     RequestIdleCallback/IdleDeadline.cpp
     SVG/AttributeNames.cpp

+ 7 - 37
Userland/Libraries/LibWeb/Layout/Box.cpp

@@ -5,8 +5,6 @@
  * SPDX-License-Identifier: BSD-2-Clause
  */
 
-#include <LibGfx/DisjointRectSet.h>
-#include <LibGfx/Filters/FastBoxBlurFilter.h>
 #include <LibGfx/Painter.h>
 #include <LibWeb/DOM/Document.h>
 #include <LibWeb/HTML/HTMLBodyElement.h>
@@ -16,6 +14,7 @@
 #include <LibWeb/Layout/FormattingContext.h>
 #include <LibWeb/Page/BrowsingContext.h>
 #include <LibWeb/Painting/BorderPainting.h>
+#include <LibWeb/Painting/ShadowPainting.h>
 
 namespace Web::Layout {
 
@@ -261,42 +260,13 @@ void Box::paint_box_shadow(PaintContext& context)
     if (!box_shadow_data.has_value())
         return;
 
-    auto enclosed_int_rect = enclosing_int_rect(bordered_rect());
-
-    auto offset_x_px = (int)box_shadow_data->offset_x.resolved_or_zero(*this, width()).to_px(*this);
-    auto offset_y_px = (int)box_shadow_data->offset_y.resolved_or_zero(*this, width()).to_px(*this);
-    auto blur_radius = (int)box_shadow_data->blur_radius.resolved_or_zero(*this, width()).to_px(*this);
-
-    Gfx::IntRect bitmap_rect = {
-        0,
-        0,
-        enclosed_int_rect.width() + 4 * blur_radius,
-        enclosed_int_rect.height() + 4 * blur_radius
-    };
-
-    Gfx::IntPoint blur_rect_position = {
-        enclosed_int_rect.x() - 2 * blur_radius + offset_x_px,
-        enclosed_int_rect.y() - 2 * blur_radius + offset_y_px
+    auto resolved_box_shadow_data = Painting::BoxShadowData {
+        .offset_x = (int)box_shadow_data->offset_x.resolved_or_zero(*this, width()).to_px(*this),
+        .offset_y = (int)box_shadow_data->offset_y.resolved_or_zero(*this, width()).to_px(*this),
+        .blur_radius = (int)box_shadow_data->blur_radius.resolved_or_zero(*this, width()).to_px(*this),
+        .color = box_shadow_data->color
     };
-
-    auto new_bitmap = Gfx::Bitmap::try_create(Gfx::BitmapFormat::BGRA8888, bitmap_rect.size());
-    if (!new_bitmap) {
-        dbgln("Unable to allocate temporary bitmap for box-shadow rendering");
-        return;
-    }
-
-    Gfx::Painter painter(*new_bitmap);
-    painter.fill_rect({ { 2 * blur_radius, 2 * blur_radius }, enclosed_int_rect.size() }, box_shadow_data->color);
-
-    Gfx::FastBoxBlurFilter filter(*new_bitmap);
-    filter.apply_three_passes(blur_radius);
-
-    Gfx::DisjointRectSet rect_set;
-    rect_set.add(bitmap_rect);
-    auto shattered = rect_set.shatter({ enclosed_int_rect.location() - blur_rect_position, enclosed_int_rect.size() });
-
-    for (auto& rect : shattered.rects())
-        context.painter().blit(rect.location() + blur_rect_position, *new_bitmap, rect);
+    Painting::paint_box_shadow(context, enclosing_int_rect(bordered_rect()), resolved_box_shadow_data);
 }
 
 Painting::BorderRadiusData Box::normalized_border_radius_data()

+ 53 - 0
Userland/Libraries/LibWeb/Painting/ShadowPainting.cpp

@@ -0,0 +1,53 @@
+/*
+ * 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/DisjointRectSet.h>
+#include <LibGfx/Filters/FastBoxBlurFilter.h>
+#include <LibGfx/Painter.h>
+#include <LibWeb/Painting/PaintContext.h>
+#include <LibWeb/Painting/ShadowPainting.h>
+
+namespace Web::Painting {
+
+void paint_box_shadow(PaintContext& context, Gfx::IntRect const& content_rect, BoxShadowData const& box_shadow_data)
+{
+    Gfx::IntRect bitmap_rect = {
+        0,
+        0,
+        content_rect.width() + 4 * box_shadow_data.blur_radius,
+        content_rect.height() + 4 * box_shadow_data.blur_radius
+    };
+
+    Gfx::IntPoint blur_rect_position = {
+        content_rect.x() - 2 * box_shadow_data.blur_radius + box_shadow_data.offset_x,
+        content_rect.y() - 2 * box_shadow_data.blur_radius + box_shadow_data.offset_y
+    };
+
+    if (bitmap_rect.is_empty())
+        return;
+
+    auto new_bitmap = Gfx::Bitmap::try_create(Gfx::BitmapFormat::BGRA8888, bitmap_rect.size());
+    if (!new_bitmap) {
+        dbgln("Unable to allocate temporary bitmap for box-shadow rendering");
+        return;
+    }
+
+    Gfx::Painter painter(*new_bitmap);
+    painter.fill_rect({ { 2 * box_shadow_data.blur_radius, 2 * box_shadow_data.blur_radius }, content_rect.size() }, box_shadow_data.color);
+
+    Gfx::FastBoxBlurFilter filter(*new_bitmap);
+    filter.apply_three_passes(box_shadow_data.blur_radius);
+
+    Gfx::DisjointRectSet rect_set;
+    rect_set.add(bitmap_rect);
+    auto shattered = rect_set.shatter({ content_rect.location() - blur_rect_position, content_rect.size() });
+
+    for (auto& rect : shattered.rects())
+        context.painter().blit(rect.location() + blur_rect_position, *new_bitmap, rect);
+}
+
+}

+ 22 - 0
Userland/Libraries/LibWeb/Painting/ShadowPainting.h

@@ -0,0 +1,22 @@
+/*
+ * Copyright (c) 2021, Sam Atkins <atkinssj@serenityos.org>
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#pragma once
+
+#include <LibGfx/Forward.h>
+
+namespace Web::Painting {
+
+struct BoxShadowData {
+    int offset_x;
+    int offset_y;
+    int blur_radius;
+    Gfx::Color color;
+};
+
+void paint_box_shadow(PaintContext&, Gfx::IntRect const&, BoxShadowData const&);
+
+}