mirror of
https://github.com/RGBCube/serenity
synced 2025-07-19 06:57:34 +00:00
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.
This commit is contained in:
parent
3b6325e787
commit
b047c1bc97
4 changed files with 83 additions and 37 deletions
|
@ -222,6 +222,7 @@ set(SOURCES
|
||||||
Page/EventHandler.cpp
|
Page/EventHandler.cpp
|
||||||
Page/Page.cpp
|
Page/Page.cpp
|
||||||
Painting/BorderPainting.cpp
|
Painting/BorderPainting.cpp
|
||||||
|
Painting/ShadowPainting.cpp
|
||||||
Painting/StackingContext.cpp
|
Painting/StackingContext.cpp
|
||||||
RequestIdleCallback/IdleDeadline.cpp
|
RequestIdleCallback/IdleDeadline.cpp
|
||||||
SVG/AttributeNames.cpp
|
SVG/AttributeNames.cpp
|
||||||
|
|
|
@ -5,8 +5,6 @@
|
||||||
* SPDX-License-Identifier: BSD-2-Clause
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <LibGfx/DisjointRectSet.h>
|
|
||||||
#include <LibGfx/Filters/FastBoxBlurFilter.h>
|
|
||||||
#include <LibGfx/Painter.h>
|
#include <LibGfx/Painter.h>
|
||||||
#include <LibWeb/DOM/Document.h>
|
#include <LibWeb/DOM/Document.h>
|
||||||
#include <LibWeb/HTML/HTMLBodyElement.h>
|
#include <LibWeb/HTML/HTMLBodyElement.h>
|
||||||
|
@ -16,6 +14,7 @@
|
||||||
#include <LibWeb/Layout/FormattingContext.h>
|
#include <LibWeb/Layout/FormattingContext.h>
|
||||||
#include <LibWeb/Page/BrowsingContext.h>
|
#include <LibWeb/Page/BrowsingContext.h>
|
||||||
#include <LibWeb/Painting/BorderPainting.h>
|
#include <LibWeb/Painting/BorderPainting.h>
|
||||||
|
#include <LibWeb/Painting/ShadowPainting.h>
|
||||||
|
|
||||||
namespace Web::Layout {
|
namespace Web::Layout {
|
||||||
|
|
||||||
|
@ -261,42 +260,13 @@ void Box::paint_box_shadow(PaintContext& context)
|
||||||
if (!box_shadow_data.has_value())
|
if (!box_shadow_data.has_value())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
auto enclosed_int_rect = enclosing_int_rect(bordered_rect());
|
auto resolved_box_shadow_data = Painting::BoxShadowData {
|
||||||
|
.offset_x = (int)box_shadow_data->offset_x.resolved_or_zero(*this, width()).to_px(*this),
|
||||||
auto offset_x_px = (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),
|
||||||
auto offset_y_px = (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),
|
||||||
auto blur_radius = (int)box_shadow_data->blur_radius.resolved_or_zero(*this, width()).to_px(*this);
|
.color = box_shadow_data->color
|
||||||
|
|
||||||
Gfx::IntRect bitmap_rect = {
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
enclosed_int_rect.width() + 4 * blur_radius,
|
|
||||||
enclosed_int_rect.height() + 4 * blur_radius
|
|
||||||
};
|
};
|
||||||
|
Painting::paint_box_shadow(context, enclosing_int_rect(bordered_rect()), resolved_box_shadow_data);
|
||||||
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 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::BorderRadiusData Box::normalized_border_radius_data()
|
Painting::BorderRadiusData Box::normalized_border_radius_data()
|
||||||
|
|
53
Userland/Libraries/LibWeb/Painting/ShadowPainting.cpp
Normal file
53
Userland/Libraries/LibWeb/Painting/ShadowPainting.cpp
Normal file
|
@ -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
Userland/Libraries/LibWeb/Painting/ShadowPainting.h
Normal file
22
Userland/Libraries/LibWeb/Painting/ShadowPainting.h
Normal file
|
@ -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&);
|
||||||
|
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue