Browse Source

LibWeb+LibGfx: Fix 'halo' effect around the fringes of shadows

This now allows passing a 'fill_color' to the blur, any fully
transparent pixels will be replaced with this color (with the alpha
set to 0).

For box-shadows, if this color is set to the same as the shadow,
the issues around the fringes are fixed. This also fixes some places
where dark shadows appeared light / the wrong color.
MacDue 3 years ago
parent
commit
cb010fd1f8

+ 5 - 5
Userland/Libraries/LibGfx/Filters/StackBlurFilter.cpp

@@ -96,14 +96,14 @@ private:
 
 
 // This is an implementation of StackBlur by Mario Klingemann (https://observablehq.com/@jobleonard/mario-klingemans-stackblur)
 // This is an implementation of StackBlur by Mario Klingemann (https://observablehq.com/@jobleonard/mario-klingemans-stackblur)
 // (Link is to a secondary source as the original site is now down)
 // (Link is to a secondary source as the original site is now down)
-FLATTEN void StackBlurFilter::process_rgba(u8 radius)
+FLATTEN void StackBlurFilter::process_rgba(u8 radius, Color fill_color)
 {
 {
     // TODO: Implement a plain RGB version of this (if required)
     // TODO: Implement a plain RGB version of this (if required)
 
 
     if (radius == 0)
     if (radius == 0)
         return;
         return;
 
 
-    constexpr auto transparent_white = Color(Color::White).with_alpha(0);
+    fill_color = fill_color.with_alpha(0);
 
 
     uint width = m_bitmap.width();
     uint width = m_bitmap.width();
     uint height = m_bitmap.height();
     uint height = m_bitmap.height();
@@ -115,7 +115,7 @@ FLATTEN void StackBlurFilter::process_rgba(u8 radius)
     auto get_pixel = [&](int x, int y) {
     auto get_pixel = [&](int x, int y) {
         auto color = m_bitmap.get_pixel<StorageFormat::BGRA8888>(x, y);
         auto color = m_bitmap.get_pixel<StorageFormat::BGRA8888>(x, y);
         if (color.alpha() == 0)
         if (color.alpha() == 0)
-            return transparent_white;
+            return fill_color;
         return color;
         return color;
     };
     };
 
 
@@ -179,7 +179,7 @@ FLATTEN void StackBlurFilter::process_rgba(u8 radius)
             if (alpha != 0)
             if (alpha != 0)
                 set_pixel(x, y, Color((red_sum * sum_mult) >> sum_shift, (green_sum * sum_mult) >> sum_shift, (blue_sum * sum_mult) >> sum_shift, alpha));
                 set_pixel(x, y, Color((red_sum * sum_mult) >> sum_shift, (green_sum * sum_mult) >> sum_shift, (blue_sum * sum_mult) >> sum_shift, alpha));
             else
             else
-                set_pixel(x, y, transparent_white);
+                set_pixel(x, y, fill_color);
 
 
             red_sum -= red_out_sum;
             red_sum -= red_out_sum;
             green_sum -= green_out_sum;
             green_sum -= green_out_sum;
@@ -266,7 +266,7 @@ FLATTEN void StackBlurFilter::process_rgba(u8 radius)
             if (alpha != 0)
             if (alpha != 0)
                 set_pixel(x, y, Color((red_sum * sum_mult) >> sum_shift, (green_sum * sum_mult) >> sum_shift, (blue_sum * sum_mult) >> sum_shift, alpha));
                 set_pixel(x, y, Color((red_sum * sum_mult) >> sum_shift, (green_sum * sum_mult) >> sum_shift, (blue_sum * sum_mult) >> sum_shift, alpha));
             else
             else
-                set_pixel(x, y, transparent_white);
+                set_pixel(x, y, fill_color);
 
 
             red_sum -= red_out_sum;
             red_sum -= red_out_sum;
             green_sum -= green_out_sum;
             green_sum -= green_out_sum;

+ 1 - 1
Userland/Libraries/LibGfx/Filters/StackBlurFilter.h

@@ -18,7 +18,7 @@ public:
     }
     }
 
 
     // Note: The radius is a u8 for reason! This implementation can only handle radii from 0 to 255.
     // Note: The radius is a u8 for reason! This implementation can only handle radii from 0 to 255.
-    void process_rgba(u8 radius);
+    void process_rgba(u8 radius, Color fill_color = Color::NamedColor::White);
 
 
 private:
 private:
     Bitmap& m_bitmap;
     Bitmap& m_bitmap;

+ 2 - 2
Userland/Libraries/LibWeb/Painting/ShadowPainting.cpp

@@ -147,7 +147,7 @@ void paint_box_shadow(PaintContext& context, Gfx::IntRect const& content_rect, B
 
 
         aa_corner_painter.fill_rect_with_rounded_corners(shadow_bitmap_rect.shrunken(double_radius, double_radius, double_radius, double_radius), box_shadow_data.color, top_left_shadow_corner, top_right_shadow_corner, bottom_right_shadow_corner, bottom_left_shadow_corner);
         aa_corner_painter.fill_rect_with_rounded_corners(shadow_bitmap_rect.shrunken(double_radius, double_radius, double_radius, double_radius), box_shadow_data.color, top_left_shadow_corner, top_right_shadow_corner, bottom_right_shadow_corner, bottom_left_shadow_corner);
         Gfx::StackBlurFilter filter(*shadow_bitmap);
         Gfx::StackBlurFilter filter(*shadow_bitmap);
-        filter.process_rgba(box_shadow_data.blur_radius);
+        filter.process_rgba(box_shadow_data.blur_radius, box_shadow_data.color);
 
 
         auto paint_shadow_infill = [&] {
         auto paint_shadow_infill = [&] {
             if (!border_radii.has_any_radius())
             if (!border_radii.has_any_radius())
@@ -342,7 +342,7 @@ void paint_text_shadow(PaintContext& context, Layout::LineBoxFragment const& fra
 
 
         // Blur
         // Blur
         Gfx::StackBlurFilter filter(*shadow_bitmap);
         Gfx::StackBlurFilter filter(*shadow_bitmap);
-        filter.process_rgba(layer.blur_radius);
+        filter.process_rgba(layer.blur_radius, layer.color);
 
 
         auto draw_rect = Gfx::enclosing_int_rect(fragment.absolute_rect());
         auto draw_rect = Gfx::enclosing_int_rect(fragment.absolute_rect());
         Gfx::IntPoint draw_location {
         Gfx::IntPoint draw_location {