mirror of
https://github.com/penpot/penpot.git
synced 2026-10-29 14:00:37 +00:00
🐛 Fix mask group drop shadow in PDF export (#12362)
This commit is contained in:
parent
f4f581ab74
commit
c401151541
@ -42,6 +42,7 @@ pub fn render_to_pdf(
|
||||
let metadata = skia::pdf::Metadata {
|
||||
creator: "Penpot".to_string(),
|
||||
producer: "Penpot (Skia PDF)".to_string(),
|
||||
raster_dpi: Some(300.0),
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
|
||||
@ -822,34 +822,7 @@ fn render_group(
|
||||
let child_opts = opts.for_children_of(element);
|
||||
|
||||
if masked {
|
||||
// Mirror the GPU mask: render all children (including the mask shape)
|
||||
// as content, then re-draw the mask silhouette (the group's first child)
|
||||
// with DstIn to clip everything to it.
|
||||
let paint = Paint::default();
|
||||
let subtree_bounds = element.extrect(tree, scale);
|
||||
canvas.save_layer(
|
||||
&skia::canvas::SaveLayerRec::default()
|
||||
.bounds(&subtree_bounds)
|
||||
.paint(&paint),
|
||||
);
|
||||
|
||||
for child_id in &children {
|
||||
render_tree_inner(shared, canvas, child_id, tree, scale, &child_opts)?;
|
||||
}
|
||||
|
||||
if let Some(mask_id) = element.mask_id() {
|
||||
let mut mask_paint = Paint::default();
|
||||
mask_paint.set_blend_mode(skia::BlendMode::DstIn);
|
||||
canvas.save_layer(
|
||||
&skia::canvas::SaveLayerRec::default()
|
||||
.bounds(&subtree_bounds)
|
||||
.paint(&mask_paint),
|
||||
);
|
||||
render_tree_inner(shared, canvas, mask_id, tree, scale, &child_opts)?;
|
||||
canvas.restore(); // mask layer
|
||||
}
|
||||
|
||||
canvas.restore(); // composition layer
|
||||
render_masked_children(shared, canvas, element, &children, tree, scale, &child_opts)?;
|
||||
} else {
|
||||
for child_id in &children {
|
||||
render_tree_inner(shared, canvas, child_id, tree, scale, &child_opts)?;
|
||||
@ -863,6 +836,42 @@ fn render_group(
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn render_masked_children(
|
||||
shared: &mut RenderResources,
|
||||
canvas: &Canvas,
|
||||
element: &Shape,
|
||||
children: &[Uuid],
|
||||
tree: ShapesPoolRef,
|
||||
scale: f32,
|
||||
child_opts: &TreeOpts,
|
||||
) -> Result<()> {
|
||||
let subtree_bounds = element.extrect(tree, scale);
|
||||
canvas.save_layer(
|
||||
&skia::canvas::SaveLayerRec::default()
|
||||
.bounds(&subtree_bounds)
|
||||
.paint(&Paint::default()),
|
||||
);
|
||||
|
||||
for child_id in children {
|
||||
render_tree_inner(shared, canvas, child_id, tree, scale, child_opts)?;
|
||||
}
|
||||
|
||||
if let Some(mask_id) = element.mask_id() {
|
||||
let mut mask_paint = Paint::default();
|
||||
mask_paint.set_blend_mode(skia::BlendMode::DstIn);
|
||||
canvas.save_layer(
|
||||
&skia::canvas::SaveLayerRec::default()
|
||||
.bounds(&subtree_bounds)
|
||||
.paint(&mask_paint),
|
||||
);
|
||||
render_tree_inner(shared, canvas, mask_id, tree, scale, child_opts)?;
|
||||
canvas.restore(); // mask layer
|
||||
}
|
||||
|
||||
canvas.restore(); // composition layer
|
||||
Ok(())
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Frames
|
||||
// ---------------------------------------------------------------------------
|
||||
@ -991,8 +1000,12 @@ fn render_container_drop_shadows(
|
||||
|
||||
let children = children_paint_order(tree, element);
|
||||
let child_opts = opts.for_children_of(element);
|
||||
for child_id in &children {
|
||||
render_tree_inner(shared, canvas, child_id, tree, scale, &child_opts)?;
|
||||
if element.is_masked_group() {
|
||||
render_masked_children(shared, canvas, element, &children, tree, scale, &child_opts)?;
|
||||
} else {
|
||||
for child_id in &children {
|
||||
render_tree_inner(shared, canvas, child_id, tree, scale, &child_opts)?;
|
||||
}
|
||||
}
|
||||
|
||||
canvas.restore();
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user