mirror of
https://github.com/storytold/photocraft.git
synced 2026-10-24 09:57:08 -06:00
Refuse strict .atn export of a mask/channel-targeted Free Transform
Fixes #7195 Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com> Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Haiku 5.5
parent
3a896a5efc
commit
47f7c97a3b
@@ -1651,6 +1651,9 @@ fn transform_to(id: &str, p: &Value) -> Option<Descriptor> {
|
||||
return None;
|
||||
}
|
||||
let target = match id {
|
||||
// The `Trnf` descriptor has no field for a mask, Quick Mask or alpha channel target; a
|
||||
// layer reference would transform the layer's pixels instead.
|
||||
"edit.transform" if !pixel_target(p) => return None,
|
||||
"edit.transform" => layer_ref(p),
|
||||
"select.transformSelection" => D::Reference(vec![ReferenceItem::Property { class: class("Chnl"), key: code("fsel") }]),
|
||||
_ => return None,
|
||||
|
||||
@@ -1387,3 +1387,32 @@ fn function_keys_keep_shift_and_command() {
|
||||
}
|
||||
assert_eq!(super::function_key_name(7, false, false), "F7");
|
||||
}
|
||||
|
||||
/// A Free Transform recorded against an unlinked mask or an alpha channel must not export as a
|
||||
/// layer transform that moves the layer's pixels on replay (#7195).
|
||||
#[test]
|
||||
fn transform_with_mask_or_channel_target_is_not_exported_as_layer_transform() {
|
||||
for target in [json!("mask"), json!({"channel": 0}), json!("quickMask")] {
|
||||
let a = Action {
|
||||
name: "Probe".into(),
|
||||
steps: vec![("edit.transform".into(), json!({"target": target, "dx": 3, "dy": 2, "scaleX": 100, "interpolation": "nearest"}))],
|
||||
..Default::default()
|
||||
};
|
||||
assert!(export("Targets", &[&a], &[], false).is_err(), "{target} exported");
|
||||
let (_, skipped) = export("Targets", &[&a], &[], true).unwrap();
|
||||
assert_eq!(skipped, vec![Skipped { action: "Probe".into(), step: 0, id: "edit.transform".into() }]);
|
||||
}
|
||||
for params in [
|
||||
json!({"dx": 3, "dy": 2, "scaleX": 50, "interpolation": "nearest"}),
|
||||
json!({"target": "pixels", "dx": 3, "dy": 2, "scaleX": 50, "interpolation": "nearest"}),
|
||||
] {
|
||||
let plain = Action { name: "Plain".into(), steps: vec![("edit.transform".into(), params)], ..Default::default() };
|
||||
let (bytes, skipped) = export("Targets", &[&plain], &[], false).unwrap();
|
||||
assert!(skipped.is_empty());
|
||||
let imported = import(&bytes).unwrap();
|
||||
assert_eq!(imported.actions[0].steps, vec![("edit.transform".to_string(), json!({"dx": 3, "dy": 2, "scaleX": 50, "interpolation": "nearest"}))]);
|
||||
}
|
||||
for form in [json!({"quad": [[0, 0], [1, 0], [1, 1], [0, 1]]}), json!({"matrix": [1, 0, 0, 1, 0, 0]}), json!({"rect": [0, 0, 1, 1]})] {
|
||||
assert!(transform_to("edit.transform", &form).is_none());
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user