mirror of
https://github.com/RGBCube/serenity
synced 2025-07-27 20:27:45 +00:00
LibWeb: Fix inset shadow with zero offset and blur
Before this change, we only blurred the shadows which would've been generated without blur. This meant that we didn't generate a shadow when the offset was zero, even with blur. However, other browsers generate a shadow when blur is set. Instead, always generate a rectangular contour of sufficient thickness, blur it if needed and blit it into the right position at the very end. Thanks to the blur radius, we'll have a shadow even when the offset is zero.
This commit is contained in:
parent
e0cf52b024
commit
6b649af447
1 changed files with 16 additions and 8 deletions
|
@ -32,8 +32,12 @@ static void paint_inner_box_shadow(PaintContext& context, CSSPixelRect const& co
|
||||||
DevicePixels offset_y = context.rounded_device_pixels(box_shadow_data.offset_y);
|
DevicePixels offset_y = context.rounded_device_pixels(box_shadow_data.offset_y);
|
||||||
DevicePixels blur_radius = context.rounded_device_pixels(box_shadow_data.blur_radius);
|
DevicePixels blur_radius = context.rounded_device_pixels(box_shadow_data.blur_radius);
|
||||||
DevicePixels spread_distance = context.rounded_device_pixels(box_shadow_data.spread_distance);
|
DevicePixels spread_distance = context.rounded_device_pixels(box_shadow_data.spread_distance);
|
||||||
auto spread_distance_value = spread_distance.value();
|
auto shadows_bitmap_rect = device_content_rect.inflated(
|
||||||
auto shadows_bitmap = Gfx::Bitmap::create(Gfx::BitmapFormat::BGRA8888, device_content_rect.size().to_type<int>());
|
blur_radius.value() + offset_y.value(),
|
||||||
|
blur_radius.value() + abs(offset_x.value()),
|
||||||
|
blur_radius.value() + abs(offset_y.value()),
|
||||||
|
blur_radius.value() + offset_x.value());
|
||||||
|
auto shadows_bitmap = Gfx::Bitmap::create(Gfx::BitmapFormat::BGRA8888, shadows_bitmap_rect.size().to_type<int>());
|
||||||
if (shadows_bitmap.is_error()) {
|
if (shadows_bitmap.is_error()) {
|
||||||
dbgln("Unable to allocate temporary bitmap {} for box-shadow rendering: {}", device_content_rect, shadows_bitmap.error());
|
dbgln("Unable to allocate temporary bitmap {} for box-shadow rendering: {}", device_content_rect, shadows_bitmap.error());
|
||||||
return;
|
return;
|
||||||
|
@ -42,11 +46,15 @@ static void paint_inner_box_shadow(PaintContext& context, CSSPixelRect const& co
|
||||||
Gfx::Painter shadow_painter { *shadow_bitmap };
|
Gfx::Painter shadow_painter { *shadow_bitmap };
|
||||||
Gfx::AntiAliasingPainter shadow_aa_painter { shadow_painter };
|
Gfx::AntiAliasingPainter shadow_aa_painter { shadow_painter };
|
||||||
auto device_content_rect_int = device_content_rect.to_type<int>();
|
auto device_content_rect_int = device_content_rect.to_type<int>();
|
||||||
auto outer_shadow_rect = device_content_rect_int.translated(-device_content_rect_int.x(), -device_content_rect_int.y());
|
auto origin_device_content_rect = device_content_rect_int.translated(-device_content_rect_int.x(), -device_content_rect_int.y());
|
||||||
auto inner_shadow_rect = outer_shadow_rect.translated({ offset_x, offset_y });
|
auto outer_shadow_rect = origin_device_content_rect.translated({ offset_x + blur_radius.value(), offset_y + blur_radius.value() });
|
||||||
inner_shadow_rect.inflate(-spread_distance_value, -spread_distance_value, -spread_distance_value, -spread_distance_value);
|
auto spread_distance_value = spread_distance.value();
|
||||||
outer_shadow_rect = outer_shadow_rect.translated(-blur_radius.value(), -blur_radius.value());
|
auto inner_shadow_rect = outer_shadow_rect.inflated(-spread_distance_value, -spread_distance_value, -spread_distance_value, -spread_distance_value);
|
||||||
outer_shadow_rect.set_size(outer_shadow_rect.width() + blur_radius.value(), outer_shadow_rect.height() + blur_radius.value());
|
outer_shadow_rect.inflate(
|
||||||
|
blur_radius.value() + offset_y.value(),
|
||||||
|
blur_radius.value() + abs(offset_x.value()),
|
||||||
|
blur_radius.value() + abs(offset_y.value()),
|
||||||
|
blur_radius.value() + offset_x.value());
|
||||||
auto top_left_corner = border_radii_shrunken.top_left.as_corner(context);
|
auto top_left_corner = border_radii_shrunken.top_left.as_corner(context);
|
||||||
auto top_right_corner = border_radii_shrunken.top_right.as_corner(context);
|
auto top_right_corner = border_radii_shrunken.top_right.as_corner(context);
|
||||||
auto bottom_right_corner = border_radii_shrunken.bottom_right.as_corner(context);
|
auto bottom_right_corner = border_radii_shrunken.bottom_right.as_corner(context);
|
||||||
|
@ -63,7 +71,7 @@ static void paint_inner_box_shadow(PaintContext& context, CSSPixelRect const& co
|
||||||
filter.process_rgba(blur_radius.value(), box_shadow_data.color);
|
filter.process_rgba(blur_radius.value(), box_shadow_data.color);
|
||||||
Gfx::PainterStateSaver save { painter };
|
Gfx::PainterStateSaver save { painter };
|
||||||
painter.add_clip_rect(device_content_rect_int);
|
painter.add_clip_rect(device_content_rect_int);
|
||||||
painter.blit({ device_content_rect_int.left(), device_content_rect_int.top() },
|
painter.blit({ device_content_rect_int.left() - blur_radius.value(), device_content_rect_int.top() - blur_radius.value() },
|
||||||
*shadow_bitmap, shadow_bitmap->rect(), box_shadow_data.color.alpha() / 255.);
|
*shadow_bitmap, shadow_bitmap->rect(), box_shadow_data.color.alpha() / 255.);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue