summaryrefslogtreecommitdiff
path: root/Userland/Libraries/LibWeb/Painting/ShadowPainting.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Userland/Libraries/LibWeb/Painting/ShadowPainting.cpp')
-rw-r--r--Userland/Libraries/LibWeb/Painting/ShadowPainting.cpp68
1 files changed, 38 insertions, 30 deletions
diff --git a/Userland/Libraries/LibWeb/Painting/ShadowPainting.cpp b/Userland/Libraries/LibWeb/Painting/ShadowPainting.cpp
index 91c09737d5..5fa8eafdf5 100644
--- a/Userland/Libraries/LibWeb/Painting/ShadowPainting.cpp
+++ b/Userland/Libraries/LibWeb/Painting/ShadowPainting.cpp
@@ -1,6 +1,6 @@
/*
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
- * Copyright (c) 2021, Sam Atkins <atkinssj@serenityos.org>
+ * Copyright (c) 2021-2022, Sam Atkins <atkinssj@serenityos.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
@@ -13,42 +13,50 @@
namespace Web::Painting {
-void paint_box_shadow(PaintContext& context, Gfx::IntRect const& content_rect, BoxShadowData const& box_shadow_data)
+void paint_box_shadow(PaintContext& context, Gfx::IntRect const& content_rect, Vector<BoxShadowData> const& box_shadow_layers)
{
- 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())
+ if (box_shadow_layers.is_empty())
return;
- auto bitmap_or_error = Gfx::Bitmap::try_create(Gfx::BitmapFormat::BGRA8888, bitmap_rect.size());
- if (bitmap_or_error.is_error()) {
- dbgln("Unable to allocate temporary bitmap for box-shadow rendering: {}", bitmap_or_error.error());
- return;
- }
- auto new_bitmap = bitmap_or_error.release_value_but_fixme_should_propagate_errors();
+ // Note: Box-shadow layers are ordered front-to-back, so we paint them in reverse
+ for (int layer_index = box_shadow_layers.size() - 1; layer_index >= 0; layer_index--) {
+ auto& box_shadow_data = box_shadow_layers[layer_index];
+
+ 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
+ };
- 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);
+ if (bitmap_rect.is_empty())
+ return;
- Gfx::FastBoxBlurFilter filter(*new_bitmap);
- filter.apply_three_passes(box_shadow_data.blur_radius);
+ auto bitmap_or_error = Gfx::Bitmap::try_create(Gfx::BitmapFormat::BGRA8888, bitmap_rect.size());
+ if (bitmap_or_error.is_error()) {
+ dbgln("Unable to allocate temporary bitmap for box-shadow rendering: {}", bitmap_or_error.error());
+ return;
+ }
+ auto new_bitmap = bitmap_or_error.release_value_but_fixme_should_propagate_errors();
- Gfx::DisjointRectSet rect_set;
- rect_set.add(bitmap_rect);
- auto shattered = rect_set.shatter({ content_rect.location() - blur_rect_position, content_rect.size() });
+ 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);
- for (auto& rect : shattered.rects())
- context.painter().blit(rect.location() + blur_rect_position, *new_bitmap, rect);
+ 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);
+ }
}
}