mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-11-14 14:41:52 +00:00
PDF import: a knockout group in a form of its own opacity reads back as one group
PDF export writes a translucent knockout group as a form with its opacity around the /K group. PDF import now reads that pair back as one knockout group with the opacity, blend mode and isolation, instead of a translucent group holding a knockout group.
This commit is contained in:
@@ -387,6 +387,21 @@ impl<'p> Builder<'p> {
|
||||
only = fold_stop_opacity(&only, &m).unwrap_or_else(|| only.with_mask(Some(Box::new(m))));
|
||||
}
|
||||
Some(only)
|
||||
} else if let [only] = children.as_slice()
|
||||
&& matches!(only.kind, NodeKind::Group { clip: false, .. })
|
||||
&& only.knockout == Knockout::On
|
||||
&& only.opacity >= 0.999
|
||||
&& only.blend == BlendMode::Normal
|
||||
&& !only.isolate
|
||||
&& only.extras().mask.is_none()
|
||||
&& mask.is_none()
|
||||
&& !knockout
|
||||
{
|
||||
// A knockout group drawn in a form that carries its opacity, blend mode or
|
||||
// isolation: one knockout group with them.
|
||||
let mut only = (**only).clone();
|
||||
(only.opacity, only.blend, only.isolate) = (opacity, blend, isolate);
|
||||
Some(only)
|
||||
} else {
|
||||
let mut g = Node::group(self.id(), children);
|
||||
(g.opacity, g.blend, g.isolate) = (opacity, blend, isolate);
|
||||
|
||||
@@ -175,6 +175,32 @@ fn an_isolated_knockout_group_is_one_isolated_pdf_knockout_group() {
|
||||
}
|
||||
}
|
||||
|
||||
/// A translucent knockout group is written as a form with its opacity around the `/K` group, and
|
||||
/// reads back as one knockout group with that opacity and its isolation.
|
||||
#[test]
|
||||
fn a_translucent_knockout_group_reads_back_as_one_group() {
|
||||
for isolate in [false, true] {
|
||||
let mut d = knockout_squares(3, false, isolate);
|
||||
let g = d.layers[0].children().unwrap()[1].id;
|
||||
d.node_mut(g).unwrap().opacity = 0.5;
|
||||
let top = d.node(g).unwrap().children().unwrap()[2].id;
|
||||
d.node_mut(top).unwrap().blend = BlendMode::Multiply;
|
||||
let back = import(&export(&d, &PdfOptions::default()).unwrap()).unwrap();
|
||||
let mut found = vec![];
|
||||
back.walk(|n| {
|
||||
if matches!(n.kind, vectorcraft_doc::NodeKind::Group { .. }) {
|
||||
found.push((
|
||||
n.knockout == vectorcraft_doc::Knockout::On,
|
||||
n.isolate,
|
||||
(n.opacity * 100.0).round(),
|
||||
n.children().map_or(0, |c| c.len()),
|
||||
));
|
||||
}
|
||||
});
|
||||
assert_eq!(found, [(true, isolate, 50.0, 3)], "isolate {isolate}");
|
||||
}
|
||||
}
|
||||
|
||||
/// Elements whose opacity defines their knockout shape knock out less than a PDF knockout group
|
||||
/// knocks out: each is drawn through one soft mask of the elements above it, so that 200 of them
|
||||
/// still read back, every one of them.
|
||||
|
||||
Reference in New Issue
Block a user