mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-10-24 09:46:59 -06:00
Merge pull request #1988 from MarekSpodBiedry/issue-1970
Paint: picking another pattern swatch keeps the pattern transform (#1970)
This commit is contained in:
@@ -560,7 +560,7 @@ fn set_item(s: &mut Session, p: &Value) -> Result<Value> {
|
||||
}
|
||||
};
|
||||
if let Some(pa) = &paint {
|
||||
*pp = super::gradient::place_paint(pa, p, bounds);
|
||||
*pp = super::gradient::place_paint(&super::paint::keep_pattern_xf(pa, p, Some(&*pp)), p, bounds);
|
||||
}
|
||||
if let Some(o) = p.get("opacity").and_then(Value::as_f64) {
|
||||
*op = percent(o);
|
||||
|
||||
@@ -457,7 +457,8 @@ fn apply_paint(s: &mut Session, p: &Value, paint: Paint, fill: bool) -> Result<V
|
||||
if !fill {
|
||||
restore_unpainted_stroke(&mut n.appearance, index, &paint);
|
||||
}
|
||||
let placed = place_paint(&paint, p, item_paint_bounds(n, index, fill));
|
||||
let new_paint = keep_pattern_xf(&paint, p, n.appearance.paint_at(index, fill));
|
||||
let placed = place_paint(&new_paint, p, item_paint_bounds(n, index, fill));
|
||||
n.appearance.set_paint_at(index, fill, placed);
|
||||
Ok(())
|
||||
},
|
||||
@@ -509,6 +510,17 @@ fn set_run_stroke(style: &mut CharStyle, paint: Paint) {
|
||||
style.stroke = paint;
|
||||
}
|
||||
|
||||
/// `paint` as it replaces `old`: a pattern swatch picked over a pattern keeps the placement that
|
||||
/// pattern already had, so only the pattern changes (#1970).
|
||||
pub(super) fn keep_pattern_xf(paint: &Paint, p: &Value, old: Option<&Paint>) -> Paint {
|
||||
match (paint, old) {
|
||||
(Paint::Pattern { pattern, xf }, Some(Paint::Pattern { xf: kept, .. })) if p.get("swatch").is_some() && *xf == Affine::IDENTITY => {
|
||||
Paint::Pattern { pattern: pattern.clone(), xf: *kept }
|
||||
}
|
||||
_ => paint.clone(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Use the existing 1 pt default when adding paint to an unpainted zero-width stroke.
|
||||
pub(super) fn restore_unpainted_stroke(ap: &mut Appearance, index: Option<usize>, paint: &Paint) {
|
||||
if !paint.is_none()
|
||||
|
||||
@@ -530,3 +530,31 @@ fn repeat_commands_validate() {
|
||||
s.execute("select.none", &json!({})).ok();
|
||||
assert!(s.execute("object.pattern.make", &json!({})).is_err());
|
||||
}
|
||||
|
||||
/// #1970: picking another pattern swatch keeps the transform the fill already had; a fill that was
|
||||
/// a colour gets the pattern untransformed.
|
||||
#[test]
|
||||
fn picking_another_pattern_swatch_keeps_the_pattern_transform() {
|
||||
let mut s = session();
|
||||
make_dots(&mut s);
|
||||
let bars = rect(&mut s, 0.0, 0.0, 20.0, 10.0);
|
||||
s.execute("paint.setFill", &json!({"ids": [bars.0], "color": "#0000ff"})).unwrap();
|
||||
s.execute("object.pattern.make", &json!({"ids": [bars.0], "name": "Bars", "edit": false})).unwrap();
|
||||
let big = rect(&mut s, 20.0, 20.0, 200.0, 200.0);
|
||||
s.execute("paint.setFill", &json!({"ids": [big.0], "color": "#00ff00"})).unwrap();
|
||||
s.execute("paint.setFill", &json!({"ids": [big.0], "swatch": "Bars"})).unwrap();
|
||||
let Paint::Pattern { xf, .. } = node(&s, big).appearance.fill_paint() else { panic!() };
|
||||
assert_eq!(xf.as_coeffs(), [1.0, 0.0, 0.0, 1.0, 0.0, 0.0]);
|
||||
s.execute("paint.setFill", &json!({"ids": [big.0], "swatch": "Dots"})).unwrap();
|
||||
s.execute("pattern.transform", &json!({"ids": [big.0], "matrix": [2, 0, 0, 2, 15, 10]})).unwrap();
|
||||
s.execute("paint.setFill", &json!({"ids": [big.0], "swatch": "Bars"})).unwrap();
|
||||
let Paint::Pattern { pattern, xf } = node(&s, big).appearance.fill_paint() else { panic!() };
|
||||
assert_eq!(pattern, "Bars");
|
||||
assert_eq!(xf.as_coeffs(), [2.0, 0.0, 0.0, 2.0, 15.0, 10.0]);
|
||||
// The Appearance panel picks the swatch for one fill through `appearance.setItem`.
|
||||
let index = node(&s, big).appearance.items.iter().position(|it| matches!(it, vectorcraft_doc::AppearanceItem::Fill(_))).unwrap();
|
||||
s.execute("appearance.setItem", &json!({"ids": [big.0], "index": index, "swatch": "Dots"})).unwrap();
|
||||
let Paint::Pattern { pattern, xf } = node(&s, big).appearance.fill_paint() else { panic!() };
|
||||
assert_eq!(pattern, "Dots");
|
||||
assert_eq!(xf.as_coeffs(), [2.0, 0.0, 0.0, 2.0, 15.0, 10.0]);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user