mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-10-24 09:46:59 -06:00
Fix #3480: pattern edit preview honors Overlap stacking
## Summary In pattern editing mode, preview copies were drawn in row-major order and the centre tile was always composited on top, so Pattern Options Overlap had no visible effect when negative spacing made tiles overlap (as in Illustrator). Preview copies now paint in the same order as tiled pattern fills. ## Tests - vectorcraft-doc: preview_paint_order_respects_overlap Closes storytold/vectorcraft#3480 Co-authored-by: nrq6993-a11y <nrq6993-a11y@users.noreply.github.com>
This commit is contained in:
committed by
bflatastic
co-authored by
nrq6993-a11y
parent
db42a68e3f
commit
e87534342b
@@ -279,7 +279,7 @@ impl PatternDef {
|
||||
out
|
||||
}
|
||||
/// Offsets of the pattern-editing preview copies (`copies`×`copies` around the tile, the
|
||||
/// centre `(0, 0)` excluded).
|
||||
/// centre `(0, 0)` excluded), in row-major order (not paint order).
|
||||
pub fn preview_offsets(&self) -> Vec<Vec2> {
|
||||
let k = (self.copies.clamp(1, 15) / 2) as i64;
|
||||
let mut out = vec![];
|
||||
@@ -292,6 +292,21 @@ impl PatternDef {
|
||||
}
|
||||
out
|
||||
}
|
||||
/// Offsets of every pattern-editing preview copy, including the centre tile, in the same paint
|
||||
/// order [`offsets_covering`] uses for [`Overlap`].
|
||||
pub fn preview_offsets_in_paint_order(&self) -> Vec<Vec2> {
|
||||
let k = (self.copies.clamp(1, 15) / 2) as i64;
|
||||
let (i0, i1, j0, j1) = (-k, k, -k, k);
|
||||
let mut out = vec![];
|
||||
let rows: Vec<i64> = if self.overlap.bottom_in_front { (j0..=j1).collect() } else { (j0..=j1).rev().collect() };
|
||||
for &j in &rows {
|
||||
let cols: Vec<i64> = if self.overlap.right_in_front { (i0..=i1).collect() } else { (i0..=i1).rev().collect() };
|
||||
for i in cols {
|
||||
out.push(self.offset(i, j));
|
||||
}
|
||||
}
|
||||
out
|
||||
}
|
||||
/// Instances covering `region` (document space) as plain nodes for a pattern painted with
|
||||
/// `paint_xf` (pattern space → document), fresh-id-less (id 0). Used by exporters and Distort
|
||||
/// Pattern Fills; Expand uses [`Self::instances_in_with`].
|
||||
@@ -744,6 +759,17 @@ mod tests {
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn preview_paint_order_respects_overlap() {
|
||||
let mut def = PatternDef::new("p", vec![sq(0.0, 0.0, 10.0)]);
|
||||
def.copies = 3;
|
||||
assert!(close(*def.preview_offsets_in_paint_order().last().unwrap(), Vec2::new(-10.0, -10.0)));
|
||||
let mut d2 = def.clone();
|
||||
d2.overlap = Overlap { right_in_front: true, bottom_in_front: true };
|
||||
assert!(close(*d2.preview_offsets_in_paint_order().last().unwrap(), Vec2::new(10.0, 10.0)));
|
||||
assert_eq!(def.preview_offsets_in_paint_order().len(), 9);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn covering_offsets_and_overlap_order() {
|
||||
let def = PatternDef::new("p", vec![sq(0.0, 0.0, 10.0)]);
|
||||
|
||||
@@ -308,17 +308,23 @@ impl Renderer {
|
||||
let children: Vec<Arc<Node>> = layer.children().cloned().unwrap_or_default();
|
||||
if layer.visible && !children.is_empty() {
|
||||
let dim = (def.dim_copies / 100.0).clamp(0.0, 1.0);
|
||||
let comp = crate::group::Composite { opacity: dim, ..Default::default() };
|
||||
self.group(ctx, f, comp, &mut |r, c, fr| {
|
||||
for o in def.preview_offsets() {
|
||||
let frame = Frame { view: fr.view * Affine::translate(o), visible: fr.visible - o, ..*fr };
|
||||
for a in &children {
|
||||
r.draw_arc(c, &frame, a);
|
||||
}
|
||||
for o in def.preview_offsets_in_paint_order() {
|
||||
let is_center = o.x == 0.0 && o.y == 0.0;
|
||||
if is_center {
|
||||
self.draw_arc(ctx, f, layer);
|
||||
} else {
|
||||
let comp = crate::group::Composite { opacity: dim, ..Default::default() };
|
||||
self.group(ctx, f, comp, &mut |r, c, fr| {
|
||||
let frame = Frame { view: fr.view * Affine::translate(o), visible: fr.visible - o, ..*fr };
|
||||
for a in &children {
|
||||
r.draw_arc(c, &frame, a);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
} else {
|
||||
self.draw_arc(ctx, f, layer);
|
||||
}
|
||||
self.draw_arc(ctx, f, layer);
|
||||
// The tile edge and swatch bounds are editing aids: exports and thumbnails leave them out,
|
||||
// as they do guides (#3261).
|
||||
if f.opts.skip_templates {
|
||||
|
||||
Reference in New Issue
Block a user