LibWeb: Apply clip frames even when transformation is identity

Clip frames for overflow were applied based on whether the box in
question had a non-identity matrix transformation associated with it.
That however is not correct, since specifying a no-op transform like
`scale(1)` still needs to apply clip overflow rectangles. So instead we
need to check whether the element associated with the box in question
has any CSS transforms.

This appears to have been a regression from
9bbc1cd618 and effectively reverts that
commit, but keeps its effect by unifying on the check for CSS transforms
instead.

This fixes some background boxes being rendered for the invisible items
of the carousels on https://computerbase.de/.
This commit is contained in:
InvalidUsernameException 2025-11-26 13:29:07 +01:00 committed by Alexander Kalenik
parent a08c175da2
commit fb9286eccb
Notes: github-actions[bot] 2025-12-01 16:47:58 +00:00
5 changed files with 39 additions and 8 deletions

View file

@ -112,8 +112,6 @@ public:
StackingContextTransform transform;
Optional<Gfx::Path> clip_path = {};
Optional<Gfx::IntRect> bounding_rect {};
bool has_effect() const { return opacity != 1.0f || compositing_and_blending_operator != Gfx::CompositingAndBlendingOperator::Normal || isolate || clip_path.has_value() || !transform.is_identity(); }
};
void push_stacking_context(PushStackingContextParams params);
void pop_stacking_context();

View file

@ -338,8 +338,10 @@ void StackingContext::paint(DisplayListRecordingContext& context) const
push_stacking_context_params.bounding_rect = context.enclosing_device_rect(paintable_box().overflow_clip_edge_rect());
}
if (!transform_matrix.is_identity())
auto has_css_transform = paintable_box().has_css_transform();
if (has_css_transform) {
paintable_box().apply_clip_overflow_rect(context, PaintPhase::Foreground);
}
paintable_box().apply_scroll_offset(context);
auto mask_image = computed_values.mask_image();
@ -349,7 +351,13 @@ void StackingContext::paint(DisplayListRecordingContext& context) const
bool needs_to_save_state = mask_image || paintable_box().get_masking_area().has_value();
if (push_stacking_context_params.has_effect()) {
bool needs_to_push_stacking_context = push_stacking_context_params.opacity != 1.0f
|| push_stacking_context_params.compositing_and_blending_operator != Gfx::CompositingAndBlendingOperator::Normal
|| push_stacking_context_params.isolate
|| push_stacking_context_params.clip_path.has_value()
|| has_css_transform;
if (needs_to_push_stacking_context) {
context.display_list_recorder().push_stacking_context(push_stacking_context_params);
} else if (needs_to_save_state) {
context.display_list_recorder().save();
@ -380,13 +388,13 @@ void StackingContext::paint(DisplayListRecordingContext& context) const
if (resolved_filter.has_value())
context.display_list_recorder().restore();
if (push_stacking_context_params.has_effect()) {
if (needs_to_push_stacking_context) {
context.display_list_recorder().pop_stacking_context();
} else if (needs_to_save_state) {
context.display_list_recorder().restore();
}
paintable_box().reset_scroll_offset(context);
if (!transform_matrix.is_identity())
if (has_css_transform)
paintable_box().clear_clip_overflow_rect(context, PaintPhase::Foreground);
}

View file

@ -147,8 +147,9 @@ void ViewportPaintable::assign_clip_frames()
}
break;
}
if (!block->transform().is_identity())
if (block->has_css_transform()) {
break;
}
}
return TraversalDecision::Continue;
});
@ -213,8 +214,9 @@ void ViewportPaintable::assign_clip_frames()
clip_frame.add_clip_rect(clip_rect, {}, block_paintable_box.enclosing_scroll_frame());
}
}
if (!block_paintable_box.transform().is_identity())
if (block->has_css_transform()) {
break;
}
}
}
}