1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-26 02:27:43 +00:00

LibWeb: Do not crash when svg mask calculation failed

Currently `calculate_mask()` fails to create bitmap when
`maskContentUnits="objectBoundingBox"` is present.

Fixes https://github.com/SerenityOS/serenity/issues/22316
This commit is contained in:
Aliaksandr Kalenik 2023-12-16 18:54:50 +01:00 committed by Andreas Kling
parent 4c81414b14
commit 2753075830
3 changed files with 39 additions and 5 deletions

View file

@ -0,0 +1,23 @@
Viewport <#document> at (0,0) content-size 800x600 children: not-inline
BlockContainer <html> at (0,0) content-size 800x216 [BFC] children: not-inline
BlockContainer <body> at (8,8) content-size 784x200 children: inline
line 0 width: 200, height: 200, bottom: 200, baseline: 200
frag 0 from SVGSVGBox start: 0, length: 0, rect: [8,8 200x200]
SVGSVGBox <svg> at (8,8) content-size 200x200 [SVG] children: inline
TextNode <#text>
SVGGraphicsBox <mask#myMask> at (8,8) content-size 1x1 children: inline
TextNode <#text>
SVGGeometryBox <rect> at (8,8) content-size 1x1 children: not-inline
TextNode <#text>
SVGGeometryBox <circle> at (8.09375,8.09375) content-size 0.796875x0.796875 children: not-inline
TextNode <#text>
TextNode <#text>
SVGGeometryBox <rect> at (8,8) content-size 200x200 children: not-inline
TextNode <#text>
TextNode <#text>
ViewportPaintable (Viewport<#document>) [0,0 800x600]
PaintableWithLines (BlockContainer<HTML>) [0,0 800x216]
PaintableWithLines (BlockContainer<BODY>) [8,8 784x200]
SVGSVGPaintable (SVGSVGBox<svg>) [8,8 200x200]
SVGPathPaintable (SVGGeometryBox<rect>) [8,8 200x200]

View file

@ -0,0 +1,8 @@
<!DOCTYPE html>
<svg width="200" height="200">
<mask id="myMask" maskContentUnits="objectBoundingBox">
<rect x="0" y="0" width="1" height="1" fill="white"/>
<circle cx="0.5" cy="0.5" r="0.4" fill="black"/>
</mask>
<rect x="0" y="0" width="200" height="200" fill="green" mask="url(#myMask)"/>
</svg>

View file

@ -333,11 +333,14 @@ void StackingContext::paint(PaintContext& context) const
if (masking_area->is_empty())
return;
auto mask_bitmap = paintable_box().calculate_mask(context, *masking_area);
push_stacking_context_params.source_paintable_rect = context.enclosing_device_rect(*masking_area).to_type<int>();
push_stacking_context_params.mask = StackingContextMask {
.mask_bitmap = mask_bitmap.release_nonnull(),
.mask_kind = *paintable_box().get_mask_type()
};
if (mask_bitmap) {
auto source_paintable_rect = context.enclosing_device_rect(*masking_area).to_type<int>();
push_stacking_context_params.source_paintable_rect = source_paintable_rect;
push_stacking_context_params.mask = StackingContextMask {
.mask_bitmap = mask_bitmap.release_nonnull(),
.mask_kind = *paintable_box().get_mask_type()
};
}
}
context.recording_painter().push_stacking_context(push_stacking_context_params);