mirror of
https://github.com/storytold/photocraft.git
synced 2026-10-24 09:57:08 -06:00
Merge PR #8509: fix(atn): preserve unsupported event kinds
This commit is contained in:
@@ -3711,7 +3711,11 @@ pub struct Imported {
|
||||
|
||||
fn photoshop_step(item: &AtnItem) -> (String, Value) {
|
||||
let descriptor = item.descriptor.as_ref().map(|d| photocraft_paint::tile::b64_encode(&d.to_bytes()));
|
||||
(PHOTOSHOP_STEP.into(), json!({"event": item.event.id(), "name": item.label(), "descriptor": descriptor}))
|
||||
let event_kind = match &item.event {
|
||||
AtnEvent::Code(_) => "code",
|
||||
AtnEvent::Name(_) => "name",
|
||||
};
|
||||
(PHOTOSHOP_STEP.into(), json!({"event": item.event.id(), "eventKind": event_kind, "name": item.label(), "descriptor": descriptor}))
|
||||
}
|
||||
|
||||
/// Integral floats become integers (`2.0` → `2`), as the commands' own docs and recordings
|
||||
@@ -3795,9 +3799,16 @@ pub struct Skipped {
|
||||
fn export_item(id: &str, params: &Value, set: &str) -> Option<AtnItem> {
|
||||
if id == PHOTOSHOP_STEP {
|
||||
let event = jstr(params, "event")?;
|
||||
let event = match event.as_bytes() {
|
||||
[a, b, c, d] => AtnEvent::Code([*a, *b, *c, *d]),
|
||||
_ => AtnEvent::name(event),
|
||||
let event = match jstr(params, "eventKind") {
|
||||
Some("code") => AtnEvent::Code(event.as_bytes().try_into().ok()?),
|
||||
Some("name") => AtnEvent::name(event),
|
||||
Some(_) => return None,
|
||||
// Older PhotoCraft action data did not retain the event kind. Keep its previous
|
||||
// best-effort export behavior for compatibility.
|
||||
None => match event.as_bytes() {
|
||||
[a, b, c, d] => AtnEvent::Code([*a, *b, *c, *d]),
|
||||
_ => AtnEvent::name(event),
|
||||
},
|
||||
};
|
||||
let descriptor = match jstr(params, "descriptor") {
|
||||
Some(b64) => Some(Descriptor::from_bytes(&photocraft_paint::tile::b64_decode(b64)?).ok()?),
|
||||
|
||||
@@ -886,6 +886,34 @@ fn unsupported_shapes_become_photoshop_steps_not_errors() {
|
||||
assert!(imp.actions[0].disabled.is_empty(), "steps with a document effect stay on so playback reports them");
|
||||
}
|
||||
|
||||
/// #8482: four-byte string events must not become `long` event codes when retained and saved.
|
||||
#[test]
|
||||
fn save_preserves_the_kind_of_unsupported_atn_events() {
|
||||
let source = AtnFile {
|
||||
name: UnicodeString::new_nul("S"),
|
||||
expanded: false,
|
||||
actions: vec![AtnAction {
|
||||
name: UnicodeString::new_nul("A"),
|
||||
items: vec![
|
||||
AtnItem { event: AtnEvent::Name(b"make".to_vec()), dictionary: b"Make".to_vec(), ..Default::default() },
|
||||
AtnItem { event: AtnEvent::Code(*b"Qwer"), dictionary: b"Unknown code".to_vec(), ..Default::default() },
|
||||
],
|
||||
..Default::default()
|
||||
}],
|
||||
warnings: vec![],
|
||||
};
|
||||
let mut session = Session::new();
|
||||
session.execute("actions.load", json!({"data": b64(&atn::write(&source).unwrap())})).unwrap();
|
||||
let saved = session.execute("actions.save", json!({"set": "S"})).unwrap();
|
||||
let bytes = photocraft_paint::tile::b64_decode(saved["data"].as_str().unwrap()).unwrap();
|
||||
let round_trip = atn::parse(&bytes).unwrap();
|
||||
|
||||
assert_eq!(
|
||||
round_trip.actions[0].items.iter().map(|item| item.event.clone()).collect::<Vec<_>>(),
|
||||
[AtnEvent::Name(b"make".to_vec()), AtnEvent::Code(*b"Qwer")]
|
||||
);
|
||||
}
|
||||
|
||||
/// #6745: the events of a Photoshop 2026 retouching set (ID-photo background swap, whitening,
|
||||
/// highlight cleanup, high-pass sharpening), in the stringID form Photoshop wrote them.
|
||||
#[test]
|
||||
|
||||
Reference in New Issue
Block a user