mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-08-28 21:26:22 +00:00
LibWeb: Don't clip descendants outside stacking context root rect
Skia allows you to pass a bounding rect to its saveLayer() function as an optimization when you know that you won't paint outside those bounds. Unfortunately, we were passing a too-small rectangle that didn't take into account transformed descendants, etc. For now, simply pass null instead of a bounding rect. This way, Skia figures it out internally. It may allocate larger temporary bitmaps than needed this way, but at least we get more correct results. I've left re-enabling the optimization as a FIXME in the code. This fixes unwanted clipping in various parts of the Discord UI.
This commit is contained in:
parent
b1c3ce807b
commit
b4435bd50c
Notes:
github-actions[bot]
2025-07-24 15:17:25 +00:00
Author: https://github.com/awesomekling
Commit: b4435bd50c
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/5588
Reviewed-by: https://github.com/kalenikaliaksandr ✅
7 changed files with 29 additions and 11 deletions
|
@ -130,15 +130,12 @@ struct PushStackingContext {
|
|||
float opacity;
|
||||
Gfx::CompositingAndBlendingOperator compositing_and_blending_operator;
|
||||
bool isolate;
|
||||
// The bounding box of the source paintable (pre-transform).
|
||||
Gfx::IntRect source_paintable_rect;
|
||||
// A translation to be applied after the stacking context has been transformed.
|
||||
StackingContextTransform transform;
|
||||
Optional<Gfx::Path> clip_path = {};
|
||||
|
||||
void translate_by(Gfx::IntPoint const& offset)
|
||||
{
|
||||
source_paintable_rect.translate_by(offset);
|
||||
transform.origin.translate_by(offset.to_type<float>());
|
||||
if (clip_path.has_value()) {
|
||||
clip_path.value().transform(Gfx::AffineTransform().translate(offset.to_type<float>()));
|
||||
|
|
|
@ -211,14 +211,13 @@ void DisplayListPlayerSkia::push_stacking_context(PushStackingContext const& com
|
|||
auto matrix = to_skia_matrix(new_transform);
|
||||
|
||||
if (command.opacity < 1 || command.compositing_and_blending_operator != Gfx::CompositingAndBlendingOperator::Normal || command.isolate) {
|
||||
auto source_paintable_rect = to_skia_rect(command.source_paintable_rect);
|
||||
SkRect dest;
|
||||
matrix.mapRect(&dest, source_paintable_rect);
|
||||
|
||||
SkPaint paint;
|
||||
paint.setAlphaf(command.opacity);
|
||||
paint.setBlender(Gfx::to_skia_blender(command.compositing_and_blending_operator));
|
||||
canvas.saveLayer(&dest, &paint);
|
||||
|
||||
// FIXME: If we knew the bounds of the stacking context including any transformed descendants etc,
|
||||
// we could use saveLayer with a bounds rect. For now, we pass nullptr and let Skia figure it out.
|
||||
canvas.saveLayer(nullptr, &paint);
|
||||
} else {
|
||||
canvas.save();
|
||||
}
|
||||
|
|
|
@ -330,7 +330,6 @@ void DisplayListRecorder::push_stacking_context(PushStackingContextParams params
|
|||
.opacity = params.opacity,
|
||||
.compositing_and_blending_operator = params.compositing_and_blending_operator,
|
||||
.isolate = params.isolate,
|
||||
.source_paintable_rect = params.source_paintable_rect,
|
||||
.transform = {
|
||||
.origin = params.transform.origin,
|
||||
.matrix = params.transform.matrix,
|
||||
|
|
|
@ -124,7 +124,6 @@ public:
|
|||
Gfx::CompositingAndBlendingOperator compositing_and_blending_operator;
|
||||
bool isolate;
|
||||
bool is_fixed_position;
|
||||
Gfx::IntRect source_paintable_rect;
|
||||
StackingContextTransform transform;
|
||||
Optional<Gfx::Path> clip_path = {};
|
||||
};
|
||||
|
|
|
@ -324,7 +324,6 @@ void StackingContext::paint(PaintContext& context) const
|
|||
.compositing_and_blending_operator = compositing_and_blending_operator,
|
||||
.isolate = paintable_box().computed_values().isolation() == CSS::Isolation::Isolate,
|
||||
.is_fixed_position = paintable_box().is_fixed_position(),
|
||||
.source_paintable_rect = source_paintable_rect,
|
||||
.transform = {
|
||||
.origin = transform_origin.scaled(to_device_pixels_scale),
|
||||
.matrix = matrix_with_scaled_translation(transform_matrix, to_device_pixels_scale),
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
<!doctype html><style>
|
||||
html {
|
||||
background-color: white;
|
||||
}
|
||||
body {
|
||||
background-color: red;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
translate: 30px 30px;
|
||||
}
|
||||
</style><body>
|
|
@ -0,0 +1,14 @@
|
|||
<!doctype html>
|
||||
<link rel="match" href="../../expected/css/stacking-context-with-unclipped-transformed-descendant-ref.html" />
|
||||
<style>
|
||||
html {
|
||||
isolation: isolate;
|
||||
background-color: white;
|
||||
}
|
||||
body {
|
||||
background-color: red;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
translate: 30px 30px;
|
||||
}
|
||||
</style><body>
|
Loading…
Add table
Add a link
Reference in a new issue