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()`.
This commit is contained in:
Aliaksandr Kalenik 2024-05-26 11:09:43 +01:00 committed by Alexander Kalenik
parent 7855d4a8f5
commit 663cc753a7
3 changed files with 97 additions and 3 deletions

View file

@ -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>

View file

@ -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>

View file

@ -673,12 +673,13 @@ void PaintableWithLines::paint(PaintContext& context, PaintPhase phase) const
clip_box.intersect(get_clip_rect().value());
should_clip_overflow = true;
}
if (enclosing_scroll_frame_offset().has_value())
clip_box.translate_by(enclosing_scroll_frame_offset().value());
if (should_clip_overflow) {
context.recording_painter().save();
// 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);
CornerRadii corner_radii {