mirror of
https://github.com/storytold/effectcraft.git
synced 2026-10-14 19:27:05 -04:00
Merge pull request #850 from Ni-zav/fix/838-script-importas-psd-20261011
fix(script): respect ImportOptions.importAs for layered PSD files # Conflicts: # crates/script/src/tests.rs
This commit is contained in:
commit
2599237ef5
3 files changed
+49
-3
No files matched your search
@@ -26,3 +26,4 @@ boa_engine = { workspace = true, features = ["js"] }
|
||||
|
||||
[dev-dependencies]
|
||||
effectcraft-expr = { workspace = true }
|
||||
effectcraft-psd = { workspace = true }
|
||||
@@ -86,6 +86,9 @@ var MaskMode = __enum("MaskMode", ["NONE", "ADD", "SUBTRACT", "INTERSECT", "LIGH
|
||||
var RQItemStatus = __enum("RQItemStatus", ["WILL_CONTINUE", "NEEDS_OUTPUT", "UNQUEUED", "QUEUED", "RENDERING", "USER_STOPPED", "ERR_STOPPED", "DONE"], 3012);
|
||||
var CloseOptions = __enum("CloseOptions", ["DO_NOT_SAVE_CHANGES", "PROMPT_TO_SAVE_CHANGES", "SAVE_CHANGES"], 1212);
|
||||
var ImportAsType = __enum("ImportAsType", ["COMP_CROPPED_LAYERS", "FOOTAGE", "COMP", "PROJECT"], 3812);
|
||||
// Accept the longer names used by some ExtendScript hosts.
|
||||
ImportAsType.COMPOSITION_CROPPED_LAYERS = ImportAsType.COMP_CROPPED_LAYERS;
|
||||
ImportAsType.COMPOSITION = ImportAsType.COMP;
|
||||
var TimeDisplayType = __enum("TimeDisplayType", ["FRAMES", "TIMECODE"], 2012);
|
||||
var LogType = __enum("LogType", ["ERRORS_ONLY", "ERRORS_AND_SETTINGS", "ERRORS_AND_PER_FRAME_INFO"], 3212);
|
||||
var KeyframeLabel = __enum("KeyframeLabel", ["NONE"], 0);
|
||||
@@ -1768,7 +1771,11 @@ function ImportOptions(file) {
|
||||
this.rangeStart = 0;
|
||||
this.rangeEnd = 0;
|
||||
}
|
||||
ImportOptions.prototype.canImportAs = function (t) { return t === ImportAsType.FOOTAGE; };
|
||||
ImportOptions.prototype.canImportAs = function (t) {
|
||||
if (t === ImportAsType.FOOTAGE) return true;
|
||||
return (t === ImportAsType.COMP || t === ImportAsType.COMP_CROPPED_LAYERS) &&
|
||||
/\.(psd|psb|pdf|ai|eps)$/i.test(__str(this.file));
|
||||
};
|
||||
|
||||
function Project() {}
|
||||
Project.prototype = {
|
||||
@@ -1822,10 +1829,19 @@ Project.prototype = {
|
||||
if (!f) throw __err("importFile(): no file");
|
||||
var args = { paths: [__str(f)] };
|
||||
// After Effects imports just the picked file unless ImportOptions.sequence is set.
|
||||
if (opts instanceof ImportOptions) args.sequence = !!opts.sequence;
|
||||
if (opts instanceof ImportOptions) {
|
||||
args.sequence = !!opts.sequence;
|
||||
switch (opts.importAs) {
|
||||
case ImportAsType.FOOTAGE: args.importAs = "footage"; break;
|
||||
case ImportAsType.COMP: args.importAs = "composition"; break;
|
||||
case ImportAsType.COMP_CROPPED_LAYERS: args.importAs = "compositionLayerSizes"; break;
|
||||
default: throw __err("importFile(): unsupported ImportOptions.importAs value " + opts.importAs);
|
||||
}
|
||||
}
|
||||
var r = __call("file.import", args);
|
||||
if (r.errors && r.errors.length) throw __err(r.errors.join("; "));
|
||||
return __item(r.items[0]);
|
||||
// Composition imports create several footage items, but callers need the comp.
|
||||
return __item(r.comps && r.comps.length ? r.comps[0] : r.items[0]);
|
||||
},
|
||||
importFileWithDialog: function () { return null; },
|
||||
importPlaceholder: function (name, w, h, rate, dur) {
|
||||
|
||||
@@ -901,3 +901,32 @@ fn extendscript_substr_keeps_start_and_length_semantics() {
|
||||
);
|
||||
assert_eq!(o.result, json!(["ab", "cde", "ef", "ab", "", "", "cd", "def", "", "ab", ""]));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn import_options_preserve_layered_psd_compositions() {
|
||||
use effectcraft_psd::Rect;
|
||||
use effectcraft_psd::write::{WDoc, WLayer, write};
|
||||
|
||||
let dir = std::env::temp_dir().join(format!("ec-script-import-as-{}", std::process::id()));
|
||||
std::fs::create_dir_all(&dir).unwrap();
|
||||
let source = dir.join("layers.psd");
|
||||
let mut doc = WDoc::new(12, 12);
|
||||
doc.layers.push(WLayer::solid("Background", Rect::new(0, 0, 12, 12), [1.0, 1.0, 1.0, 1.0]));
|
||||
doc.layers.push(WLayer::solid("Accent", Rect::new(2, 2, 4, 4), [0.0, 0.4, 1.0, 1.0]));
|
||||
std::fs::write(&source, write(&doc)).unwrap();
|
||||
let file = serde_json::to_string(&source.to_string_lossy()).unwrap();
|
||||
let mut s = session();
|
||||
let o = ok(
|
||||
&mut s,
|
||||
&format!(
|
||||
"var io = new ImportOptions(new File({file})); io.importAs = ImportAsType.COMPOSITION_CROPPED_LAYERS; \
|
||||
[io.canImportAs(io.importAs), app.project.importFile(io).typeName]"
|
||||
),
|
||||
);
|
||||
assert_eq!(o.result, json!([true, "Composition"]));
|
||||
let imported = s.project.comps().next().unwrap().1;
|
||||
assert_eq!(imported.layers.len(), 2);
|
||||
let bad = ok(&mut s, &format!("new ImportOptions(new File({file})).canImportAs(ImportAsType.PROJECT)"));
|
||||
assert_eq!(bad.result, json!(false));
|
||||
let _ = std::fs::remove_dir_all(&dir);
|
||||
}
|
||||
Reference in new issue
Block a user