Procházet zdrojové kódy

LibWeb: Fix clip box calculation in PaintableWithLines

All painting commands except SetClipRect are shifted by scroll offset
before command list execution. This change removes scroll offset
translation for sample/blit corner commands in
`PaintableWithLines::paint` so it is only applied once in
`CommandList::apply_scroll_offsets()`.
Aliaksandr Kalenik před 1 rokem
rodič
revize
663cc753a7

+ 50 - 0
Tests/LibWeb/Ref/paintablewithlines-corner-clip-in-scroll-container.html

@@ -0,0 +1,50 @@
+<!DOCTYPE html>
+<link rel="match" href="reference/paintablewithlines-corner-clip-in-scroll-container-ref.html" />
+<style>
+  body {
+    margin: 0;
+    padding: 0;
+  }
+
+  * {
+    scrollbar-width: none;
+  }
+
+  #container {
+    height: 500px;
+    overflow: scroll;
+    border: 1px solid black;
+  }
+
+  #padding {
+    height: 300px;
+  }
+
+  #rounded-corners-mask {
+    width: 300px;
+    height: 300px;
+    border-radius: 50%;
+    overflow: hidden;
+    overflow: scroll;
+    font-size: 40px;
+    background-color: orangered;
+  }
+</style>
+<div id="container">
+  <div id="padding"></div>
+  <div id="rounded-corners-mask">
+    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut ultrices neque
+    eu nisi facilisis viverra. Integer lacinia, lacus vel condimentum suscipit,
+    lacus felis porta nulla, eget lacinia sem neque ut neque. In sagittis, eros
+    vel interdum porta, quam ex rhoncus lectus, vitae suscipit risus orci sit
+    amet velit. Praesent imperdiet condimentum rutrum. Cras vitae nisl sapien.
+    Curabitur ligula diam, tincidunt congue tincidunt nec, sodales nec orci.
+    Vestibulum tincidunt non elit in vehicula. Etiam malesuada neque eu porta
+    rhoncus. Curabitur vel nunc finibus ligula posuere venenatis.
+  </div>
+  <div id="padding"></div>
+</div>
+<script>
+    const scrollContainer = document.getElementById("container");
+    scrollContainer.scrollTop = 300;
+</script>

+ 43 - 0
Tests/LibWeb/Ref/reference/paintablewithlines-corner-clip-in-scroll-container-ref.html

@@ -0,0 +1,43 @@
+<!DOCTYPE html>
+<style>
+  body {
+    margin: 0;
+    padding: 0;
+  }
+
+  * {
+    scrollbar-width: none;
+  }
+
+  #container {
+    height: 500px;
+    overflow: scroll;
+    border: 1px solid black;
+  }
+
+  #padding {
+    height: 300px;
+  }
+
+  #rounded-corners-mask {
+    width: 300px;
+    height: 300px;
+    border-radius: 50%;
+    overflow: hidden;
+    overflow: scroll;
+    font-size: 40px;
+    background-color: orangered;
+  }
+</style>
+<div id="container">
+  <div id="rounded-corners-mask">
+    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut ultrices neque
+    eu nisi facilisis viverra. Integer lacinia, lacus vel condimentum suscipit,
+    lacus felis porta nulla, eget lacinia sem neque ut neque. In sagittis, eros
+    vel interdum porta, quam ex rhoncus lectus, vitae suscipit risus orci sit
+    amet velit. Praesent imperdiet condimentum rutrum. Cras vitae nisl sapien.
+    Curabitur ligula diam, tincidunt congue tincidunt nec, sodales nec orci.
+    Vestibulum tincidunt non elit in vehicula. Etiam malesuada neque eu porta
+    rhoncus. Curabitur vel nunc finibus ligula posuere venenatis.
+  </div>
+</div>

+ 4 - 3
Userland/Libraries/LibWeb/Painting/PaintableBox.cpp

@@ -673,12 +673,13 @@ void PaintableWithLines::paint(PaintContext& context, PaintPhase phase) const
         clip_box.intersect(get_clip_rect().value());
         clip_box.intersect(get_clip_rect().value());
         should_clip_overflow = true;
         should_clip_overflow = true;
     }
     }
-    if (enclosing_scroll_frame_offset().has_value())
-        clip_box.translate_by(enclosing_scroll_frame_offset().value());
     if (should_clip_overflow) {
     if (should_clip_overflow) {
         context.recording_painter().save();
         context.recording_painter().save();
         // FIXME: Handle overflow-x and overflow-y being different values.
         // FIXME: Handle overflow-x and overflow-y being different values.
-        context.recording_painter().add_clip_rect(context.rounded_device_rect(clip_box).to_type<int>());
+        auto clip_box_with_enclosing_scroll_frame_offset = clip_box;
+        if (enclosing_scroll_frame_offset().has_value())
+            clip_box_with_enclosing_scroll_frame_offset.translate_by(enclosing_scroll_frame_offset().value());
+        context.recording_painter().add_clip_rect(context.rounded_device_rect(clip_box_with_enclosing_scroll_frame_offset).to_type<int>());
 
 
         auto border_radii = normalized_border_radii_data(ShrinkRadiiForBorders::Yes);
         auto border_radii = normalized_border_radii_data(ShrinkRadiiForBorders::Yes);
         CornerRadii corner_radii {
         CornerRadii corner_radii {