mirror of
https://github.com/storytold/deckcraft.git
synced 2026-10-28 04:27:06 -06:00
Geom/Render: brackets and braces fill; arrowheads follow open paths, not brackets
- Left/right brackets and braces drew only their curve: a filled bracket showed no fill. PowerPoint fills them out to the straight side they open to (the fill path is the curve closed), outlining only the curve. - Arrowheads were drawn on any shape with nothing filled (brackets among them) but not on open freeforms that had a fill. PowerPoint puts them on lines, arcs and open freeforms whether filled or not, never on brackets. Wild synthetic set: preset galleries 9.44 -> 4.65, 9.55 -> 4.94, 9.60 -> 5.38; extreme-adjust galleries 10.7 -> 6.6. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
47dfaaca61
commit
9a7e7e133e
@@ -974,7 +974,12 @@ impl Renderer {
|
||||
if line.fill.as_ref().is_some_and(|f| !f.is_none()) {
|
||||
let lw = line.width.unwrap_or(0.75).max(0.0);
|
||||
let (base, rel) = self.line_space(m, depth);
|
||||
let ends = s.is_line() || geo.is_open();
|
||||
// Arrowheads go on lines, arcs and open freeforms (filled or not), never on closed
|
||||
// outlines or on presets like brackets.
|
||||
let ends = s.is_line()
|
||||
|| geo.is_open()
|
||||
|| (matches!(s.geom, Geom::Custom { .. })
|
||||
&& geo.paths.iter().find(|p| p.stroke).is_some_and(|p| !p.path.elements().iter().any(|e| matches!(e, PathEl::ClosePath))));
|
||||
let trims = if ends { head_trims(&line, lw) } else { (0.0, 0.0) };
|
||||
let has_heads = ends && [&line.head, &line.tail].iter().any(|e| e.as_ref().is_some_and(|e| e.kind != "none"));
|
||||
// A see-through line and its arrowheads are one shape in PowerPoint: drawn opaque into
|
||||
|
||||
@@ -313,3 +313,21 @@ fn children_filled_with_the_group_fill_show_one_fill_across_the_group() {
|
||||
assert!(r[2] > 200 && r[0] < 60, "right end {r:?}");
|
||||
assert!(close(img.pixel(200, 150), WHITE, 5), "the gap between the children stays empty");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn open_freeforms_take_arrowheads_even_when_filled() {
|
||||
// An open custom path with a fill and a tail arrow: PowerPoint draws the arrow.
|
||||
let end = deckcraft_model::style::LineEnd { kind: "triangle".into(), w: "med".into(), len: "med".into() };
|
||||
let sh = Shape {
|
||||
id: ShapeId(19),
|
||||
xfrm: Some(Xfrm::new(100.0, 100.0, 200.0, 100.0)),
|
||||
geom: Geom::Custom { paths: vec![CustomPath { w: 100.0, h: 100.0, d: "M 0 100 L 50 0 L 100 100".into(), ..Default::default() }] },
|
||||
fill: solid(Rgba::rgb(0, 200, 0)),
|
||||
line: Some(Line { fill: solid(RED), width: Some(4.0), tail: Some(end), ..Default::default() }),
|
||||
..Default::default()
|
||||
};
|
||||
let img = render(vec![sh]);
|
||||
// The line ends at (300, 200) heading down-right at 45°; the 12 pt head's base corner reaches
|
||||
// (295.7, 187.3), 3.5 pt off the line's axis: outside the 4 pt line and outside the fill.
|
||||
assert!(close(img.pixel(294, 189), RED, 60), "arrowhead drawn {:?}", img.pixel(294, 189));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user