Select: select.color reads compound paths and empty type as document.inspect does

A compound path holds its members, so select.color passed over it and
looked at the members instead, whose paint inspect doesn't report: a
black compound path (art with holes, as PDFs bring in) never matched
"#000000". It now matches by its own fill and stroke, and its members
never do. Type without characters reads as the default character fill,
as inspect reports it (CodeRabbit on #2939).
This commit is contained in:
MortenHusted
2026-10-18 23:50:58 +07:00
committed by bflatastic
parent d25289a3be
commit 36aecff81d
3 changed files with 28 additions and 3 deletions
+8 -1
View File
@@ -550,7 +550,14 @@ fn select_color(s: &mut Session, p: &Value) -> Result<Value> {
return Err(bad(C, "give `fill`, `stroke` or both"));
}
let reads_as = |paint: Paint, hex: Option<&str>| hex.is_none_or(|h| paint.color().is_some_and(|c| c.to_hex() == h));
select_where(s, C, p, |_, n| !n.is_container() && reads_as(fill_of(n), fill.as_deref()) && reads_as(stroke_of(n).0, stroke.as_deref()))
select_where(s, C, p, |d, n| paint_reported(d, n) && reads_as(fill_of(n), fill.as_deref()) && reads_as(stroke_of(n).0, stroke.as_deref()))
}
/// Does `document.inspect` report a fill and stroke for `n`? A compound path's are its own, though
/// it holds its members, and its members report none.
fn paint_reported(d: &Document, n: &Node) -> bool {
let compound = |n: &Node| matches!(n.kind, NodeKind::Compound { .. });
compound(n) || (!n.is_container() && !d.parent_of(n.id).and_then(|p| d.node(p)).is_some_and(compound))
}
fn same(s: &mut Session, cmd: &str, eq: impl Fn(&Node, &Node) -> bool) -> Result<Value> {
+3 -2
View File
@@ -87,10 +87,11 @@ fn set(s: &mut Session, p: &Value) -> Result<Value> {
Ok(json!(s.menu.wand))
}
/// The fill an object shows: type's comes from its characters (the first run speaks for all).
/// The fill an object shows: type's comes from its characters (the first run speaks for all; type
/// without any, the default character fill, as `document.inspect` reports it).
pub(crate) fn fill_of(n: &Node) -> Paint {
match &n.kind {
NodeKind::Text(t) => t.runs.first().map(|r| r.style.fill.clone()).unwrap_or_default(),
NodeKind::Text(t) => t.runs.first().map(|r| r.style.fill.clone()).unwrap_or_else(|| vectorcraft_doc::CharStyle::default().fill),
_ => n.appearance.fill_paint(),
}
}