Fix #3089: a stroked line with an effect expands to a stroked line, then Expand outlines it

Squashed from #4169 onto main.
This commit is contained in:
Taha-Mahmoodi
2026-10-29 18:54:59 +07:00
committed by bflatastic
parent 3cfdb58b90
commit b41599f657
38 changed files with 377 additions and 51 deletions
+12 -9
View File
@@ -14,7 +14,8 @@
//! and [`container_keeping_type`] list the other conditions). The renderer still draws its outlines.
//!
//! Object → Expand Appearance goes further ([`expand_leaf`]): every fill and stroke becomes an
//! object of its own, strokes turned into filled art by the caller (their outlines or brush art).
//! object of its own, a stroke a path stroked by it alone (brushed strokes their brush art, made by
//! the caller).
use std::collections::HashMap;
use std::sync::Arc;
@@ -440,15 +441,17 @@ fn bake_leaf(d: &mut Document, n: &Node) -> Option<Node> {
Some(m)
}
/// Turns one stroke of a path (the path after its geometry effects, its fill rule, the stroke
/// without geometry effects) into filled art for [`expand_leaf`]: its outline filled with its
/// paint, or its brush art. `None` when it paints nothing.
/// Turns one brushed stroke of a path (the path after its geometry effects, its fill rule, the
/// stroke without geometry effects) into its brush art for [`expand_leaf`]. `None` when it paints
/// nothing.
pub type StrokeArt<'a> = &'a mut dyn FnMut(&mut Document, &PathData, FillRule, &StrokeLayer) -> Option<Node>;
/// Object → Expand Appearance of a path or compound path `n`: its geometry effects applied, every
/// visible fill becomes a copy of the path painted by that fill alone and every visible stroke the
/// filled art `stroke_art` makes of it (each with its fill's or stroke's opacity and blend mode as
/// its own), in paint order, as the members of a group that keeps
/// visible fill becomes a copy of the path painted by that fill alone and every visible stroke a
/// copy stroked by that stroke alone (its weight, caps, joins, dashes, arrowheads, alignment and
/// width profile stay stroke attributes, which Object → Expand or Outline Stroke outline later,
/// #3089), or for a brushed stroke the brush art `stroke_art` makes of it; each with its fill's or
/// stroke's opacity and blend mode as its own, in paint order, as the members of a group that keeps
/// `n`'s id, name, transparency, opacity mask and remaining (raster) effects. A single piece
/// without transparency or effects of its own takes `n`'s place itself. Hidden fills, strokes and
/// effects are dropped. `None` for other kinds of objects.
@@ -466,8 +469,8 @@ pub fn expand_leaf(d: &mut Document, n: &Node, stroke_art: StrokeArt) -> Option<
clear_item_effects(&mut it);
it.effects_mut().retain(|e| e.visible);
let p = match &it {
AppearanceItem::Stroke(st) => stroke_art(d, &ig, rule, st),
AppearanceItem::Fill(_) => Some(piece(d, n, ig, rule, it)),
AppearanceItem::Stroke(st) if st.brush.is_some() => stroke_art(d, &ig, rule, st),
_ => Some(piece(d, n, ig, rule, it)),
};
pieces.extend(p.map(hoist_transparency));
}