Browse Source

LibWeb: Avoid painting background-images under opaque borders

Without this the background-image can be painted up to 8 extra
times, that contribute nothing to the final image.
MacDue 3 years ago
parent
commit
d0511ec650
1 changed files with 26 additions and 0 deletions
  1. 26 0
      Userland/Libraries/LibWeb/Painting/BackgroundPainting.cpp

+ 26 - 0
Userland/Libraries/LibWeb/Painting/BackgroundPainting.cpp

@@ -82,6 +82,26 @@ void paint_background(PaintContext& context, Layout::NodeWithStyleAndBoxModelMet
     if (!has_paintable_layers)
     if (!has_paintable_layers)
         return;
         return;
 
 
+    struct {
+        int top { 0 };
+        int bottom { 0 };
+        int left { 0 };
+        int right { 0 };
+    } clip_shrink;
+
+    auto border_top = layout_node.computed_values().border_top();
+    auto border_bottom = layout_node.computed_values().border_bottom();
+    auto border_left = layout_node.computed_values().border_left();
+    auto border_right = layout_node.computed_values().border_right();
+
+    if (border_top.color.alpha() == 255 && border_bottom.color.alpha() == 255
+        && border_left.color.alpha() == 255 && border_right.color.alpha() == 255) {
+        clip_shrink.top = border_top.width;
+        clip_shrink.bottom = border_bottom.width;
+        clip_shrink.left = border_left.width;
+        clip_shrink.right = border_right.width;
+    }
+
     // Note: Background layers are ordered front-to-back, so we paint them in reverse
     // Note: Background layers are ordered front-to-back, so we paint them in reverse
     for (auto& layer : background_layers->in_reverse()) {
     for (auto& layer : background_layers->in_reverse()) {
         // TODO: Gradients!
         // TODO: Gradients!
@@ -96,6 +116,12 @@ void paint_background(PaintContext& context, Layout::NodeWithStyleAndBoxModelMet
         painter.add_clip_rect(clip_rect);
         painter.add_clip_rect(clip_rect);
         ScopedCornerRadiusClip corner_clip { painter, clip_rect, clip_box.radii };
         ScopedCornerRadiusClip corner_clip { painter, clip_rect, clip_box.radii };
 
 
+        if (layer.clip == CSS::BackgroundBox::BorderBox) {
+            // Shrink the effective clip rect if to account for the bits the borders will definitely paint over
+            // (if they all have alpha == 255).
+            clip_rect.shrink(clip_shrink.top, clip_shrink.right, clip_shrink.bottom, clip_shrink.left);
+        }
+
         auto& image = *layer.background_image;
         auto& image = *layer.background_image;
         Gfx::FloatRect background_positioning_area;
         Gfx::FloatRect background_positioning_area;