mirror of
https://github.com/RGBCube/serenity
synced 2025-07-26 02:07:35 +00:00
LibWeb: Add blurring support to box-shadow
Now the box-shadow-rendering is done by using the new Gfx::FastBoxBlurFilter. :^)
This commit is contained in:
parent
d1844e424d
commit
5745e8e18c
1 changed files with 29 additions and 15 deletions
|
@ -5,6 +5,8 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <LibGfx/DisjointRectSet.h>
|
#include <LibGfx/DisjointRectSet.h>
|
||||||
|
#include <LibGfx/Filters/FastBoxBlurFilter.h>
|
||||||
|
#include <LibGfx/Filters/SpatialGaussianBlurFilter.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>
|
||||||
|
@ -256,29 +258,41 @@ void Box::paint_background_image(
|
||||||
|
|
||||||
void Box::paint_box_shadow(PaintContext& context)
|
void Box::paint_box_shadow(PaintContext& context)
|
||||||
{
|
{
|
||||||
// FIXME: Implement support for blurring the shadow.
|
|
||||||
auto box_shadow_data = computed_values().box_shadow();
|
auto box_shadow_data = computed_values().box_shadow();
|
||||||
if (!box_shadow_data.has_value())
|
if (!box_shadow_data.has_value())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
auto offset_x_px = box_shadow_data->offset_x.resolved_or_zero(*this, width()).to_px(*this);
|
auto enclosed_int_rect = enclosing_int_rect(bordered_rect());
|
||||||
auto offset_y_px = box_shadow_data->offset_y.resolved_or_zero(*this, width()).to_px(*this);
|
|
||||||
|
|
||||||
Gfx::IntRect shifted_box_rect = {
|
auto offset_x_px = (int)box_shadow_data->offset_x.resolved_or_zero(*this, width()).to_px(*this);
|
||||||
bordered_rect().x() + offset_x_px,
|
auto offset_y_px = (int)box_shadow_data->offset_y.resolved_or_zero(*this, width()).to_px(*this);
|
||||||
bordered_rect().y() + offset_y_px,
|
auto blur_radius = (int)box_shadow_data->blur_radius.resolved_or_zero(*this, width()).to_px(*this);
|
||||||
bordered_rect().width(),
|
|
||||||
bordered_rect().height()
|
Gfx::IntRect bitmap_rect = {
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
enclosed_int_rect.width() + 4 * blur_radius,
|
||||||
|
enclosed_int_rect.height() + 4 * blur_radius
|
||||||
};
|
};
|
||||||
|
|
||||||
Gfx::DisjointRectSet rect_set;
|
Gfx::IntPoint blur_rect_position = {
|
||||||
rect_set.add(shifted_box_rect);
|
enclosed_int_rect.x() - 2 * blur_radius + offset_x_px,
|
||||||
auto shattered = rect_set.shatter(enclosing_int_rect(bordered_rect()));
|
enclosed_int_rect.y() - 2 * blur_radius + offset_y_px
|
||||||
|
};
|
||||||
|
|
||||||
for (auto& rect : shattered.rects()) {
|
auto new_bitmap = Gfx::Bitmap::try_create(Gfx::BitmapFormat::BGRA8888, bitmap_rect.size());
|
||||||
context.painter().fill_rect(rect, box_shadow_data->color);
|
Gfx::Painter painter(*new_bitmap);
|
||||||
(void)rect;
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
Box::BorderRadiusData Box::normalized_border_radius_data()
|
Box::BorderRadiusData Box::normalized_border_radius_data()
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue