Revert "LibWeb: Fix clip of hidden overflow..."

This reverts commit eb1ef59603c13c43b87c099c43c4d118dc8441f6.

The idea of saving clip box to apply it to handle `overflow: hidden`
turned out to break painting if box is painted before it's containing
block (it is possible if box has negative z-index).
This commit is contained in:
Aliaksandr Kalenik 2023-02-24 01:07:00 +03:00 committed by Linus Groh
parent 8f3c343b88
commit 87fa1c5e66
Notes: sideshowbarker 2024-07-18 02:13:10 +09:00
4 changed files with 24 additions and 23 deletions
Userland/Libraries

View file

@ -2568,9 +2568,4 @@ void Painter::draw_scaled_bitmap_with_transform(IntRect const& dst_rect, Bitmap
}
}
void Painter::set_clip_rect(IntRect const& rect)
{
state().clip_rect = rect.intersected(m_target->rect());
}
}

View file

@ -177,7 +177,6 @@ public:
}
IntRect clip_rect() const { return state().clip_rect; }
void set_clip_rect(IntRect const&);
int scale() const { return state().scale; }

View file

@ -314,8 +314,24 @@ BorderRadiiData PaintableBox::normalized_border_radii_data(ShrinkRadiiForBorders
return border_radius_data;
}
Optional<Gfx::IntRect> PaintableBox::clip_rect() const
Optional<CSSPixelRect> PaintableBox::clip_rect() const
{
if (!m_clip_rect.has_value()) {
if (containing_block() && containing_block()->paint_box())
m_clip_rect = containing_block()->paint_box()->clip_rect();
auto overflow_x = computed_values().overflow_x();
auto overflow_y = computed_values().overflow_y();
if (overflow_x == CSS::Overflow::Hidden && overflow_y == CSS::Overflow::Hidden) {
if (m_clip_rect.has_value()) {
m_clip_rect->intersect(absolute_padding_box_rect());
} else {
m_clip_rect = absolute_padding_box_rect();
}
}
}
return m_clip_rect;
}
@ -324,36 +340,27 @@ void PaintableBox::apply_clip_overflow_rect(PaintContext& context, PaintPhase ph
if (!AK::first_is_one_of(phase, PaintPhase::Background, PaintPhase::Border, PaintPhase::Foreground))
return;
auto clip_rect = context.painter().clip_rect();
if (containing_block() && containing_block()->paint_box()) {
if (containing_block()->paint_box()->clip_rect().has_value()) {
clip_rect = *containing_block()->paint_box()->clip_rect();
}
}
context.painter().set_clip_rect(clip_rect);
// FIXME: Support more overflow variations.
auto clip_rect = this->clip_rect();
auto overflow_x = computed_values().overflow_x();
auto overflow_y = computed_values().overflow_y();
auto clip_overflow = [&] {
if (!m_clipping_overflow) {
context.painter().save();
context.painter().add_clip_rect(context.rounded_device_rect(absolute_padding_box_rect()).to_type<int>());
context.painter().add_clip_rect(context.rounded_device_rect(*clip_rect).to_type<int>());
m_clipping_overflow = true;
}
};
// FIXME: Support more overflow variations.
if (overflow_x == CSS::Overflow::Hidden && overflow_y == CSS::Overflow::Hidden) {
if (clip_rect.has_value()) {
clip_overflow();
}
m_clip_rect = context.painter().clip_rect();
if (overflow_y == CSS::Overflow::Hidden || overflow_x == CSS::Overflow::Hidden) {
auto border_radii_data = normalized_border_radii_data(ShrinkRadiiForBorders::Yes);
if (border_radii_data.has_any_radius()) {
auto corner_clipper = BorderRadiusCornerClipper::create(context, context.rounded_device_rect(absolute_padding_box_rect()), border_radii_data, CornerClip::Outside, BorderRadiusCornerClipper::UseCachedBitmap::No);
auto corner_clipper = BorderRadiusCornerClipper::create(context, context.rounded_device_rect(*clip_rect), border_radii_data, CornerClip::Outside, BorderRadiusCornerClipper::UseCachedBitmap::No);
if (corner_clipper.is_error()) {
dbgln("Failed to create overflow border-radius corner clipper: {}", corner_clipper.error());
return;

View file

@ -98,7 +98,7 @@ public:
return m_overflow_data->scrollable_overflow_rect;
}
Optional<Gfx::IntRect> clip_rect() const;
Optional<CSSPixelRect> clip_rect() const;
void set_overflow_data(Optional<OverflowData> data) { m_overflow_data = move(data); }
void set_containing_line_box_fragment(Optional<Layout::LineBoxFragmentCoordinate>);
@ -157,7 +157,7 @@ private:
Optional<CSSPixelRect> mutable m_absolute_rect;
Optional<CSSPixelRect> mutable m_absolute_paint_rect;
Gfx::IntRect mutable m_clip_rect;
Optional<CSSPixelRect> mutable m_clip_rect;
mutable bool m_clipping_overflow { false };
Optional<BorderRadiusCornerClipper> mutable m_overflow_corner_radius_clipper;