Files
effectcraft/Cargo.toml
T
.CooCoo 7cbefaf70f Import: VectorCraft documents import through the PDF they carry (#2901)
* Import: VectorCraft documents import through the PDF they carry

File > Import reads a .vectorcraft file through the PDF that VectorCraft
saves in it with Create PDF-Compatible File, one page per artboard, as
footage or as a composition with one layer per PDF layer. The PDF is read
with craft-doc from craft-libs (plain or compressed files, the PDF inline
or after the JSON). A PDF after the JSON may be as large as a PDF file
EffectCraft imports (512 MiB). A document saved without that option gives
an import error that names it.

craft-doc, craft-vectorcraft-format (tests only) and craft-ecproj-format
are pinned to craft-libs fa1a6574; craft-ecproj-format is unchanged
between ca1b5e2e and that commit.

* Import: show file errors returned by the import dialog

* Keep dropped-file import errors alongside local drop errors

* Import: preserve every file error across background jobs and UI notices

* Import: queue pending errors with bounded notification details

* Import: a damaged VectorCraft preview no longer stops the carried PDF

The importer read every rendition with craft_doc::renditions and then
picked the PDF, so a preview whose base64 was invalid or whose data lay
past the end of the file made the whole import fail. It now reads only
the PDF with craft_doc::rendition, from storytold/craft-libs#546, and
never decodes the preview. A document without a PDF still reports
NoCarriedPdf.

* Import: dismissing a picked import's error status acknowledges its details

A picked or menu import queued its error details with the status
report_import_errors set ("first (and 1 more)"), and show_result_errors
then replaced that status with "first; second". The two never matched,
so clicking the status left the details queued and they showed again.
Import commands now move the queued details to the status that replaces
it, also when After Effects project errors lead it. Other commands'
statuses never take over an import's details.
2026-11-15 03:45:56 -05:00

252 lines
14 KiB
TOML

[workspace]
resolver = "3"
members = ["crates/*", "apps/*", "xtask"]
default-members = ["crates/*", "apps/*"]
[workspace.package]
version = "0.24.1"
edition = "2024"
license = "MIT OR Apache-2.0"
rust-version = "1.95"
repository = "https://github.com/storytold/effectcraft"
[workspace.dependencies]
craft-pdf = { git = "https://github.com/storytold/craft-libs", rev = "47107f660191de2f0b425569506f4daa4faadac9", version = "=0.1.0", default-features = false, features = ["read"] }
craft-docpath = { version = "0.1.0", git = "https://github.com/storytold/craft-libs", rev = "47107f660191de2f0b425569506f4daa4faadac9" }
craft-quit = { version = "0.1.0", git = "https://github.com/storytold/craft-libs", rev = "47107f660191de2f0b425569506f4daa4faadac9" }
craft-ecproj-format = { version = "0.1.0", git = "https://github.com/storytold/craft-libs", rev = "47107f660191de2f0b425569506f4daa4faadac9" }
craft-dpx = { version = "0.1.0", git = "https://github.com/storytold/craft-libs", rev = "47107f660191de2f0b425569506f4daa4faadac9" }
craft-eps = { version = "0.1.0", git = "https://github.com/storytold/craft-libs", rev = "47107f660191de2f0b425569506f4daa4faadac9" }
craft-exr = { version = "0.1.0", git = "https://github.com/storytold/craft-libs", rev = "47107f660191de2f0b425569506f4daa4faadac9" }
craft-gif = { version = "0.1.0", git = "https://github.com/storytold/craft-libs", rev = "47107f660191de2f0b425569506f4daa4faadac9" }
craft-psd = { version = "0.1.0", git = "https://github.com/storytold/craft-libs", rev = "47107f660191de2f0b425569506f4daa4faadac9" }
craft-svg = { version = "0.1.0", git = "https://github.com/storytold/craft-libs", rev = "47107f660191de2f0b425569506f4daa4faadac9" }
craft-webp = { version = "0.1.0", git = "https://github.com/storytold/craft-libs", rev = "47107f660191de2f0b425569506f4daa4faadac9" }
craft-lottie = { version = "0.1.0", git = "https://github.com/storytold/craft-libs", rev = "47107f660191de2f0b425569506f4daa4faadac9" }
craft-mesh = { version = "0.1.0", git = "https://github.com/storytold/craft-libs", rev = "47107f660191de2f0b425569506f4daa4faadac9", default-features = false, features = ["stl", "obj", "gltf", "fbx"] }
craft-aep = { version = "0.1.0", git = "https://github.com/storytold/craft-libs", rev = "47107f660191de2f0b425569506f4daa4faadac9" }
craft-doc = { version = "0.1.0", git = "https://github.com/storytold/craft-libs", rev = "47107f660191de2f0b425569506f4daa4faadac9" }
craft-vectorcraft-format = { version = "0.1.0", git = "https://github.com/storytold/craft-libs", rev = "47107f660191de2f0b425569506f4daa4faadac9" }
# craft-update: app-specific pretend versions apply to startup and manual checks.
craft-update = { git = "https://github.com/storytold/craft-libs", version = "=0.1.0", rev = "47107f660191de2f0b425569506f4daa4faadac9", features = ["egui"] }
# internal
effectcraft-time = { path = "crates/time" }
effectcraft-geom = { path = "crates/geom" }
effectcraft-color = { path = "crates/color" }
effectcraft-raster = { path = "crates/raster" }
effectcraft-path = { path = "crates/path" }
effectcraft-keyframe = { path = "crates/keyframe" }
effectcraft-project = { path = "crates/project" }
effectcraft-text = { path = "crates/text" }
effectcraft-effects = { path = "crates/effects" }
effectcraft-track = { path = "crates/track" }
effectcraft-segment = { path = "crates/segment" }
effectcraft-sam2 = { path = "crates/sam2" }
effectcraft-model = { path = "crates/model" }
effectcraft-render = { path = "crates/render" }
effectcraft-gpu = { path = "crates/gpu" }
effectcraft-media = { path = "crates/media" }
effectcraft-export = { path = "crates/export" }
effectcraft-expr = { path = "crates/expr" }
effectcraft-lottie = { path = "crates/lottie" }
effectcraft-interchange = { path = "crates/interchange" }
effectcraft-pdf = { path = "crates/pdf" }
effectcraft-psd = { path = "crates/psd" }
effectcraft-aep = { path = "crates/aep" }
effectcraft-svg = { path = "crates/svg" }
effectcraft-engine = { path = "crates/engine" }
effectcraft-host = { path = "crates/host" }
effectcraft-ui-egui = { path = "crates/ui-egui" }
effectcraft-automation = { path = "crates/automation" }
effectcraft-opusenc = { path = "crates/opusenc" }
effectcraft-script = { path = "crates/script" }
effectcraft-plugin = { path = "crates/plugin" }
effectcraft-helper-host = { path = "crates/helper-host" }
# foundation
thiserror = "2"
serde = { version = "1", features = ["derive", "rc"] }
serde_json = { version = "1", features = ["float_roundtrip"] }
log = "0.4"
# All date/time conversion goes through chrono (no hand-rolled calendar code beyond the 400-year range extension; AGENTS.md).
chrono = { version = "0.4.45", default-features = false, features = ["std"] }
rayon = "1"
# std::time::Instant/SystemTime on native; the browser clock on wasm32 (std's panic there).
web-time = "1"
gif = "0.14"
proptest = "1"
# scripting (expressions)
boa_engine = { version = "0.22", default-features = false }
# WebAssembly effect plug-ins (sandboxed interpreter; MIT/Apache-2.0, pure Rust)
wasmi = { version = "2", default-features = false, features = ["std", "validate", "wat", "deterministic", "portable-dispatch"] }
# geometry / fonts
kurbo = { version = "0.13", features = ["serde"] }
tiny-skia = { version = "0.12", default-features = false, features = ["std", "simd"] }
skrifa = { version = "0.44", default-features = false, features = ["std"] }
harfrust = { version = "0.12", default-features = false, features = ["std"] }
exr = "1.74"
image = { version = "0.25", default-features = false, features = ["png", "jpeg"] }
same-file = "1.0"
tempfile = "3.27"
# codecs + containers shared by the Craft apps (crates/media, crates/export); keep all three on one rev.
craft-media = { version = "0.1.0", git = "https://github.com/storytold/craft-libs", rev = "47107f660191de2f0b425569506f4daa4faadac9", default-features = false, features = ["isobmff", "matroska"] }
craft-audio = { version = "0.1.0", git = "https://github.com/storytold/craft-libs", rev = "47107f660191de2f0b425569506f4daa4faadac9", default-features = false, features = ["aac-decode", "aac-encode", "opus-decode"] }
craft-video = { version = "0.1.0", git = "https://github.com/storytold/craft-libs", rev = "47107f660191de2f0b425569506f4daa4faadac9", features = ["h264-encode", "prores", "hevc-encode", "vp9-encode", "av1", "threads"] }
# footage decoding: FilmCraft's pure-Rust crates, pinned to a revision (plan/adr/0001).
# Only `crates/media`, `crates/export` and `crates/interchange` may depend on these.
filmcraft-codecs = { git = "https://github.com/storytold/filmcraft", rev = "d5ead4ba1ee2f1cd13cb86a4239aee2730a3d9f5" }
filmcraft-media = { git = "https://github.com/storytold/filmcraft", rev = "d5ead4ba1ee2f1cd13cb86a4239aee2730a3d9f5" }
filmcraft-frame = { git = "https://github.com/storytold/filmcraft", rev = "d5ead4ba1ee2f1cd13cb86a4239aee2730a3d9f5" }
filmcraft-color = { git = "https://github.com/storytold/filmcraft", rev = "d5ead4ba1ee2f1cd13cb86a4239aee2730a3d9f5" }
filmcraft-time = { git = "https://github.com/storytold/filmcraft", rev = "d5ead4ba1ee2f1cd13cb86a4239aee2730a3d9f5" }
# MPEG TS / PS headers read for AAC channel layouts (crates/media); craft-media has no MPEG TS reader
filmcraft-mpegts = { git = "https://github.com/storytold/filmcraft", rev = "d5ead4ba1ee2f1cd13cb86a4239aee2730a3d9f5" }
# decoders used as the round-trip oracles of craft-video's VP9, HEVC and AV1 encoders (crates/export
# dev-dependencies only); craft-video has no decoder for them
filmcraft-vp9 = { git = "https://github.com/storytold/filmcraft", rev = "d5ead4ba1ee2f1cd13cb86a4239aee2730a3d9f5" }
filmcraft-hevc = { git = "https://github.com/storytold/filmcraft", rev = "d5ead4ba1ee2f1cd13cb86a4239aee2730a3d9f5" }
filmcraft-av1 = { git = "https://github.com/storytold/filmcraft", rev = "d5ead4ba1ee2f1cd13cb86a4239aee2730a3d9f5" }
# timeline interchange (EDL, FCP7 XML, FCPXML, OTIO) for Premiere Pro interop (crates/interchange only)
filmcraft-interchange = { git = "https://github.com/storytold/filmcraft", rev = "d5ead4ba1ee2f1cd13cb86a4239aee2730a3d9f5" }
filmcraft-project = { git = "https://github.com/storytold/filmcraft", rev = "d5ead4ba1ee2f1cd13cb86a4239aee2730a3d9f5" }
filmcraft-geom = { git = "https://github.com/storytold/filmcraft", rev = "d5ead4ba1ee2f1cd13cb86a4239aee2730a3d9f5" }
# gpu (the same wgpu eframe / egui-wgpu use)
wgpu = { version = "30.0.1", features = ["fragile-send-sync-non-atomic-wasm"] }
bytemuck = "1"
pollster = "1"
half = "2.7"
# ui
# Shared frontend components; keep this dependency above the engine boundary.
# Shared UI and the complete egui family select reviewed immutable commits below.
craft-ui = { version = "0.1.0", git = "https://github.com/storytold/craft-libs", rev = "47107f660191de2f0b425569506f4daa4faadac9", features = ["serde"] }
# `default_fonts` and `monochrome_emoji_fonts` are explicit: the app's `FontDefinitions::default()`
# and its `✔`/`▣` chrome glyphs need both, and kittest's own dev-dependencies do not propagate.
egui = { version = "0.37", default-features = false, features = ["default_fonts", "monochrome_emoji_fonts"] }
eframe = { version = "0.37", default-features = false }
# Resizable table columns (About ▸ Contributors / Models); no image loaders.
egui_extras = { version = "0.37", default-features = false }
egui_kittest = "0.37"
rfd = "0.17"
cpal = "0.16"
# The operating system's interface language (MIT/Apache-2.0, no dependencies on desktop).
sys-locale = "0.3"
# Local co-development against a FilmCraft checkout next to this repo: uncomment.
# [patch."https://github.com/storytold/filmcraft"]
# filmcraft-codecs = { path = "../filmcraft/crates/codecs" }
# filmcraft-media = { path = "../filmcraft/crates/media" }
# filmcraft-frame = { path = "../filmcraft/crates/frame" }
# filmcraft-color = { path = "../filmcraft/crates/color" }
# filmcraft-time = { path = "../filmcraft/crates/time" }
# filmcraft-mpegts = { path = "../filmcraft/crates/mpegts" }
[workspace.lints.rust]
unsafe_code = "forbid"
[workspace.lints.clippy]
cognitive_complexity = "deny"
too_many_arguments = "deny"
wildcard_imports = "deny"
dbg_macro = "warn"
todo = "warn"
needless_range_loop = "allow"
type_complexity = "allow"
[profile.dev.package."*"]
opt-level = 2
debug = false
[profile.dev]
opt-level = 1
# Panics and backtraces keep file and line; full debug info only made the many test binaries large.
debug = "line-tables-only"
# Same settings as `dev`, but with full debug info for interactive debugger sessions: local
# variables, parameters and column breakpoints work. Use `--profile dev-full` when debugging;
# everything else stays on the fast default. See CONTRIBUTING.md, "Setup".
[profile.dev-full]
inherits = "dev"
debug = true
# Pixel hot loops: keep debug builds interactive.
[profile.dev.package.effectcraft-raster]
opt-level = 3
[profile.dev.package.effectcraft-render]
opt-level = 3
[profile.dev.package.effectcraft-gpu]
opt-level = 3
[profile.dev.package.effectcraft-effects]
opt-level = 3
[profile.dev.package.effectcraft-track]
opt-level = 3
[profile.dev.package.effectcraft-path]
opt-level = 3
[profile.dev.package.effectcraft-media]
opt-level = 3
[profile.dev.package.effectcraft-opusenc]
opt-level = 3
[profile.dev.package.effectcraft-export]
opt-level = 3
# craft-libs codec hot loops.
[profile.dev.package.craft-video]
opt-level = 3
[profile.dev.package.craft-audio]
opt-level = 3
[profile.dev.package.craft-media]
opt-level = 3
# FilmCraft codec hot loops (same settings as FilmCraft's own workspace).
[profile.dev.package.filmcraft-h264]
opt-level = 3
[profile.dev.package.filmcraft-hevc]
opt-level = 3
[profile.dev.package.filmcraft-vp9]
opt-level = 3
[profile.dev.package.filmcraft-dnx]
opt-level = 3
[profile.dev.package.filmcraft-av1]
opt-level = 3
[profile.release]
lto = "thin"
codegen-units = 1
[patch.crates-io]
hayro-syntax = { git = "https://github.com/storytold/craft-libs", rev = "47107f660191de2f0b425569506f4daa4faadac9", version = "=0.7.2" }
hayro-jbig2 = { git = "https://github.com/storytold/craft-libs", rev = "47107f660191de2f0b425569506f4daa4faadac9", version = "=0.3.0" }
ecolor = { git = "https://github.com/storytold/egui.git", rev = "6d518fc799681571963842f95b55a6b68431b15a" }
emath = { git = "https://github.com/storytold/egui.git", rev = "6d518fc799681571963842f95b55a6b68431b15a" }
epaint = { git = "https://github.com/storytold/egui.git", rev = "6d518fc799681571963842f95b55a6b68431b15a" }
epaint_default_fonts = { git = "https://github.com/storytold/egui.git", rev = "6d518fc799681571963842f95b55a6b68431b15a" }
egui = { git = "https://github.com/storytold/egui.git", rev = "6d518fc799681571963842f95b55a6b68431b15a" }
egui-winit = { git = "https://github.com/storytold/egui.git", rev = "6d518fc799681571963842f95b55a6b68431b15a" }
egui-wgpu = { git = "https://github.com/storytold/egui.git", rev = "6d518fc799681571963842f95b55a6b68431b15a" }
egui_glow = { git = "https://github.com/storytold/egui.git", rev = "6d518fc799681571963842f95b55a6b68431b15a" }
egui_extras = { git = "https://github.com/storytold/egui.git", rev = "6d518fc799681571963842f95b55a6b68431b15a" }
egui_kittest = { git = "https://github.com/storytold/egui.git", rev = "6d518fc799681571963842f95b55a6b68431b15a" }
eframe = { git = "https://github.com/storytold/egui.git", rev = "6d518fc799681571963842f95b55a6b68431b15a" }
# Patch a crate only together with the dependency that needs it: an unused patch makes the Nix
# build, which uses vendored sources, fail (`cargo xtask lock-patches`).
winit = { git = "https://github.com/storytold/winit.git", rev = "a517b3846ee8457d84ee4975110bfda6797c44dc" }