Commit Graph
145 Commits
Author SHA1 Message Date
FredApps 35ce9b2694 Merge pull request #2920 from vangel76/perf/exr-decode-cache-474
Multi-layer EXR: one decode per frame shared by the picture and EXtractoR / Cryptomatte, picture-only decode for footage alone (#474)
2026-11-06 00:10:05 +01:00
611a282bea Plug-ins: external effect helpers (safe, out-of-process native effects) + plug-in API 2 (#889)
* Plug-ins: API 2 (PluginHost, padding, layer_span)

Split out of the OpenFX work so it can be reviewed on its own. Additive; the WebAssembly ABI
stays at 1.

- point3 / layer / text / hidden parameters, integer sliders, parameter groups.
- EffectPlugin::padding (transparent pixels around the buffer, at most 4096 per side).
- EffectPlugin::render_v2 with a PluginHost: the input at other times, other layers, parameters
  at other times, frame rate, per-instance key, the layer's source range.
- EffectEnv::layer_span from the renderer; MAX_PLUGINS 1024.
- plugin_error: a plug-in effect's last render error, for the UI.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KxacwTpUwqyfpcLgKW8yjS

* Plug-ins: external effect helpers (crates/helper-host)

Native plug-in formats run in separate helper programs, never in EffectCraft's process
(docs/adr/0001-external-effect-helpers.md). New safe-Rust crate effectcraft-helper-host (L3,
native only, unsafe forbidden): it finds helper programs, starts each as a child process and
registers its effects through plug-in API 2, so the UI and command surface need nothing new.

- Protocol v1 (docs/external-helpers.md): JSON lines over stdin / stdout (helper replies are
  prefixed so plug-in chatter is ignored); pixels go through a frame exchange file (/dev/shm on
  Linux), never through the pipe. Render-time callbacks for the input at other times, other layers
  and parameters at other times, with nested renders through the same helper.
- A helper that exits, hangs past its timeout or breaks the protocol is stopped. The render fails
  with a message, the frame is left as it was, and the helper restarts for the next render. An
  effect that stops its helper 3 times is turned off (helper_blocklist.txt).
- Opt-in: nothing starts helpers unless the user asks (Effect > Scan for Effect Helpers), or opts
  in to starting them at launch with EFFECTCRAFT_HELPERS=1, an environment variable, so writing
  to the settings folder alone can't run code. effect.helpers.scan / load are refused for
  confined agent sessions (confine.rs), like file.executeFile.
- Discovery: helpers/ next to the app (Contents/Helpers on macOS), helpers/ in the settings
  folder, EFFECTCRAFT_HELPER_PATH.
- Commands effect.helpers.list / scan / load; Effect menu entries (translated); the last render
  error of an effect shows as a warning sign after its name in Effect Controls.
- serve(): the helper side for Rust helpers. tests/it/main.rs runs the whole protocol (render,
  padding, callbacks, nesting, threads, crash, restart, block list, hang) against a fake helper,
  with nothing to install.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KxacwTpUwqyfpcLgKW8yjS

* Effect helpers: address review (start failures, frame file mode, nextest listing)

- A helper that can't start (not installed any more, restarting too often, no frame exchange
  file) is reported but no longer charged to the effect being rendered: it is Failure::Refused,
  not Failure::Broken, so it never counts toward turning that effect off. New check in
  tests/it: once the helper is out of restarts, renders of an effect fail without blocking it
  (fails without the fix: the effect was turned off after 3 such renders).
- The frame exchange file is created owner-only (0o600) on Unix: it holds the user's frames and
  /dev/shm is shared. Asserted in the frames unit test.
- tests/it (harness = false) speaks the libtest listing protocol cargo-nextest uses:
  `--list --format terse` prints `helper_protocol: test` (nothing with `--ignored`), and
  `helper_protocol --exact` runs the checks.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KxacwTpUwqyfpcLgKW8yjS

* Effect helpers: bound writes to a helper, drain stderr, keep callbacks in step

- Writes to a helper go through a writer thread with the request timeout: a
  helper that stops reading its stdin (hung with a large callback answer or
  render request pending) no longer blocks the render thread forever while
  holding the helper.
- stderr is drained as bytes (lossy, in 64 KiB pieces) to the end: output that
  isn't UTF-8 stopped the reader, closing the pipe under the helper (EPIPE /
  SIGPIPE on its next write); lines were unbounded.
- Callback images that can't be written are answered with `null` instead of
  failing the render while the helper waits (which left the protocol out of
  step); a frame that can't be written before the request is sent is not
  charged to the effect.
- Mid-render calls use the render's own process: no respawn or heartbeat ping
  while the helper is waiting for an answer.
- Waiting for a busy helper is bounded (load timeout) instead of forever;
  status() no longer blocks on a running render.
- Reap the child when start-up fails after spawning; cap the block list read.
- Scripts start helpers only with Allow Scripts to Write Files and Access
  Network on (they run native code), as for File.execute().
- helper-host declares the workspace's no-panic crate lints; the desktop
  main() keeps its doc comment.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Effect helpers: rustfmt the fake provider, build the test session in its initializer (clippy)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Plug-in Library: offer WebAssembly API 1 releases only; a helper already stopped mid-render isn't charged again

- WasmPlugin loads only modules at the WebAssembly ABI version, which stays 1 while
  PLUGIN_API_VERSION is 2: share it as effects::plugin::WASM_API_VERSION and have the
  library's compatibility check use it, so it never installs an API 2 release that
  can't load.
- with_running: a process that is already gone was stopped by what broke it (a nested
  render, charged there), so this render fails without charging its own effect.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* frames: plug-in effects count as reading other frames (plug-in API 2)

With main's narrowed frame invalidation (#2795), an edit inside a precomp under an
effect that reads its layer at other times must reach the layer's whole span.
Plug-in API 2 gives every plug-in effect the input at other times, so any effect
outside ec. counts.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: FredApps <153173854+FredApps@users.noreply.github.com>
2026-11-05 11:11:57 +01:00
4e8398f8ca G8: Plug-in Library: install, preview and update community WebAssembly effects (#2524)
* G8: plug-in library

Community Plug-in Library for WebAssembly effect plug-ins (#376): one
reviewed catalog (index.json), install / update / remove from Settings >
Plug-in Library (also Effect > Plug-in Library...), library.* commands,
start-up loading of installed packages with SHA-256 checks. Downloads go
through the system curl (https, GitHub hosts), as trained models do.

Preview before installing (library.preview): the release is downloaded,
checked like an install, and rendered in the sandbox on a built-in sample
frame at default settings (2 s at 12 fps) with a Before/After split, plus
the effect's parameters, "Open on GitHub" and an optional author video
link (catalog field preview.video). Authors need to do nothing for it.

Hardening: a module that fails to load leaves the installed copy alone,
Update All updates every package in one job, minApp also applies to an
explicit version, curl ignores ~/.curlrc and URL globbing, unique temp
files, percent-decoded file URLs. Plug-in effect slots grow from 64 to
256 with a clearer overflow error.

Docs: plugins.md "Plug-in Library", publishing-plugins.md (author guide
from zero to listed), gaps.md; examples/plugin-catalog is the starting
content of the catalog repository (schema, validation workflow).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* contributors: credit iseemhlyfta

* G8: plug-in library: doc comments on the library's functions

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* G8: plug-in catalog check: require one object with schema 1 and a packages array

An empty file or several JSON values passed jq empty, and with
SKIP_SCHEMA=1 nothing else checked the catalog's shape.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* G8: plug-in library: one preview texture set; catalog schema requires effects

The preview kept a texture set per package version previewed (about
6 MB each) for the whole session; it now keeps one, replaced when
another package is previewed. Releases in the catalog schema must list
at least one effect id, as the author guide says.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* G8: plug-in catalog schema: effect ids follow the manifest's id rules

Letters, digits, '.', '_' and '-', and not the reserved 'ec.' prefix,
so library.missing can match them.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* G8: refuse Plug-in Library jobs while automation file access is confined

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* G8: split the Plug-in Library page into toolbar, card, links and actions

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* G8: show Plug-in Library toasts without a Roto job; cache preview frame checks

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* G8: log Plug-in Library packages that fail to load at start-up

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* G8: check an update before replacing a loaded package; Update All past failures

- An update to a package that is already loaded is now compiled and its manifest checked
  (through the previewer, without registering it) before the new file is written and the old
  version's folder deleted. Before, a release with the right SHA-256 that didn't load replaced
  the working version and failed at the next start.
- Package ids that differ only in case, or end in a dot, would share one folder on Windows and
  macOS: the catalog keeps the first of them, and ids can't end in a dot (schema too).
- Update All: a package that can't be picked or installed no longer stops the others; the
  result names what was updated and what wasn't.
- Downloads: at most 5 redirects, and one that ends off GitHub's hosts is refused, as the module
  docs say.
- A job that panics no longer leaves the library busy; poisoned status locks are used, not
  dropped.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* G8: rustfmt the update test

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: FredApps <153173854+FredApps@users.noreply.github.com>
2026-11-05 05:51:17 +01:00
vangel76andClaude Sonnet 5.5 2b3d76c5fd Merge upstream/main into perf/exr-decode-cache-474
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-03 19:18:12 +01:00
Brandon Thomas 3ae9c8dbc2 Merge PR #2981 2026-11-03 09:41:24 -05:00
SHXJ b77db389af #2037: complete the Traditional Chinese effect-name catalog
Add 308 Traditional Chinese effect names and 21 category labels, written from the English source with Taiwan creative-software terms. Update the completeness tests to require the zh-hant table and recount the localization docs.
2026-11-03 22:34:55 +08:00
Matej Kozlovský 0d1c5c08bf Docs: the Cryptomatte Selection is picked in the viewer (#473)
effects-parity.md and gaps.md: the Selection is picked in the viewer. control-protocol.md: the
viewer.cryptoPick element ids. footage.md: a paragraph on the eyedropper.
2026-11-03 07:37:53 +01:00
vangel76andClaude Opus 5.5 eedd64906c #474: keep files in use in the channel cache, cap plane memory, fall back on a missing cache entry
Review follow-ups:
- Files in use are never dropped from the channel cache: planes an effect
  holds, the files of the last 4 pictures made of their planes until their
  effects ask for the channels, and decodes in progress, which now count
  the planes they will allocate (from the header) against the budget. With
  4 frames at once over a budget of one file, each file decodes once (test).
- A decode that panics removes its entry instead of leaving it decoding.
- One decode allocates at most 8 GiB of planes (512 MiB on 32-bit and
  wasm); a header asking for more is refused with the reason.
- A shared picture whose file has no cached channels (a failed read, a
  broken part it doesn't use) is decoded from its own channels.
- Comment why waiting on a decode may block a rayon worker; drop the
  subsampling check and test (the exr crate refuses subsampled files).
- Docs: the cache is a soft bound; a single-part file still decompresses
  every channel; the first frame and the image crate's route decode twice.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-03 02:25:07 +01:00
vangel76andClaude Opus 5.5 8add8ac7b4 #474: decode a multi-layer EXR once per frame, and only its picture when nothing else reads it
- The channel cache decodes a file once however many callers ask for it at
  the same time (the others wait for that decode), and is bounded by the
  bytes of its planes (1 GiB, least recently used out first, a file counting
  as used when its decode finishes, the newest file always kept) instead of
  four files of any size.
- Once an effect has read a footage item's channels, its pictures are made
  of the cached planes, also for files with an unnamed RGB layer (bit for
  bit what the image crate shows, which still decodes the files the planes
  can't stand in for); footage alone decodes only its picture's channels
  (a multi-layer file's were all decoded and cached for every frame).
- Channels are decoded straight into their display-window planes, and the
  picture is converted from the planes without two interleaved copies.

Measured on a 30-frame 2560x1440 sequence of 32 channels (DWAA), one frame
at a time: footage alone 0.185 -> 0.073 s per frame and 4.4 -> 1.8 GB peak;
with an unnamed RGB layer plus Cryptomatte 0.244 -> 0.159 s; multi-part
plus EXtractoR 0.194 -> 0.127 s.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-03 02:06:02 +01:00
Patrik LermonandClaude Opus 5.5 46881e0d5f Swedish interface translation (sv)
Adds Swedish (Svenska) as an interface language in the menu, panel and
effect catalogs, written from the English source. The effect rows are
partial like Japanese and Georgian: an effect without a Swedish row draws
its English name, so a new effect does not block other PRs (#2244).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-30 10:35:36 +01:00
bflatasticandClaude Opus 5.5 b66a83389d docs: gaps.md says the CI gate runs on pull requests (gap 4 closed)
Since #2204, ci.yml runs `cargo xtask ci` through craft-common-actions' shared gate on every
pull request and push to main; gaps.md still listed "No CI gate on pull requests" as gap 4 and
in the Stability row.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-30 13:29:10 +07:00
bflatasticandClaude Opus 5.5 eef9997889 Merge origin/main into #1339
header.rs, render_queue.rs: main's drag-toggle checkboxes report `.changed()`; the
Snapping, Notify and per-item Render check boxes keep this PR's AccessKit names and use
`.changed()`, the per-item one inside main's `add_enabled_ui`. The Render button keeps its
name with main's translated label.
effects_presets.rs: kept this PR's row_focus/nav_click and main's rows_before_presets;
main's reveal of Animation Presets with this PR's folder_row (nav, level), and the nav's
offset follows the scroll it moves; the search field keeps its name.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-30 11:34:05 +07:00
bflatasticandClaude Opus 5.5 9e6332ea27 Merge main into #1739; keep both footage re-exports (Cineon + VIDEO_EXTENSIONS) and main's gaps.md localization row with the PR's AVI row
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-30 07:44:20 +07:00
bflatastic 42876133d5 Merge remote-tracking branch 'origin/main' into HEAD
# Conflicts:
#	docs/gaps.md
2026-10-30 07:05:43 +07:00
bflatastic 33ce4bbbed Merge remote-tracking branch 'origin/main' into HEAD 2026-10-30 07:05:19 +07:00
tylerjenningsw 852f98d6a5 Merge enhance/filmcraft-avi-backend into enhance/avi-import
# Conflicts:
#	crates/export/tests/it/movie_bytes.rs
2026-10-29 18:58:57 -04:00
bflatastic 0754a754ae Merge main into #2300; Cineon conversion kept in footage_frame_raw (main routes proxies through footage_frame), frame-blend cache key hashes both premul colour and Cineon settings, spec strings combined 2026-10-30 05:41:52 +07:00
bflatastic e3c57f4fda Merge main into #2356; plugins.md keeps main's ScriptUI subfolder row and the PR's script-shortcuts row 2026-10-30 05:35:06 +07:00
bflatastic bd34ab21b6 Merge main into #2279; keep main's Scripts subfolders (RESERVED_FOLDERS) next to the Startup/Shutdown constants, merge docs rows 2026-10-30 05:34:26 +07:00
BFlat faab5b1c81 Merge pull request #2039 from midasdf/jp/cjk-composition-rendering
Text: Chinese Han text uses the installed Chinese face (#453)
2026-10-30 05:10:35 +07:00
BFlat 7043fde70a Merge pull request #1314 from tylerjenningsw/fix/expression-value-color
UI: colour expression-driven numeric values consistently (refs #1072)
2026-10-30 04:08:14 +07:00
tylerjenningsw 4439770a05 Merge main into enhance/avi-import
Conflicts:
- viewer.rs: the undecodable-footage notice moved into phase_scene on main; it now
  collects its layers in footage_problems, which keeps the proxy and collapsed-precomp
  rules of #1701.
- project.rs: main's row layout, with the problem marker going by item_problem.
- movie_bytes.rs: the H.264 pin is FilmCraft 09aaf9b's bytes plus main's 19-byte
  BT.709 colr box (104_322 + 19 = 104_341).
render/footage.rs imports ItemKind now that main names its imports.
2026-10-29 15:11:20 -04:00
bflatastic 6ab7bd31dd Merge main into #1513; resolve docs/effects-parity.md 2026-10-30 01:25:24 +07:00
midasdf cbd67baf36 Text: the zh-hans Han order test replaces the skipping render test (#2039)
The CJK render test skipped wherever no Japanese face was installed, which
is every CI runner, and on a Mac it drew glyphs with or without the fix, so
it caught nothing. Replace it with a fallback-order test: fixture faces for
`Hiragino Sans` and `Hiragino Sans GB` show that a zh-hans Han lookup tries
the Chinese family first, that ja tries the Japanese one, and that a layout
gets Hiragino Sans GB. Synthetic fonts in an isolated child process keep it
independent of the host's fonts; with the Simplified list reverted it fails
on `[7]` against `[8, 7]`.

Delete `TEST_CJK_LOCALE`: the locale-mutating tests moved to an isolated
child process, so nothing used the lock and the test-only static failed
clippy's `-D warnings` gate.

Trim the documentation edits to the single docs/gaps.md gap-11 row: revert
the header and changelog edits in ROADMAP.md, docs/roadmap.md,
docs/localization-parity.md and docs/target-app-parity.md, and the gaps.md
header and changelog row, which conflict with other PRs.

Tests: cargo clippy -p effectcraft-text -p effectcraft-render --all-targets
-- -D warnings, cargo clippy --workspace --all-targets -- -D warnings,
cargo test -p effectcraft-text (79 lib), cargo test -p effectcraft-render
(264 passed, 1 ignored perf test), cargo fmt --all -- --check.
2026-10-29 14:47:22 +09:00
dotCooCoo e0dc5eb2ff Merge main and retain Cineon Settings in the extracted modules 2026-10-27 11:41:43 -07:00
dotCooCoo 5e32a2a39c Merge main and preserve Startup script tasks across project changes 2026-10-27 11:41:43 -07:00
tylerjenningsw 2dcd1b27a9 Merge remote-tracking branch 'origin/main' into fix/947-preview-opening-audio
# Conflicts:
#	crates/ui-egui/src/lib.rs
2026-10-27 14:13:31 -04:00
tylerjenningsw 74b309e6cf Merge remote-tracking branch 'origin/main' into enhance/avi-import
# Conflicts:
#	crates/project/src/lib.rs
#	crates/render/src/lib.rs
#	crates/ui-egui/src/menus.rs
2026-10-27 14:13:31 -04:00
tylerjenningsw 8c7990c65f Merge remote-tracking branch 'origin/main' into fix/expression-value-color
# Conflicts:
#	crates/ui-egui/src/panels/effect_controls.rs
2026-10-27 14:05:11 -04:00
dotCooCoo 572ed5d17f Preserve script keyboard shortcuts across menu module changes 2026-10-27 10:25:26 -07:00
vangel76 92e33beef0 Merge remote-tracking branch 'upstream/main' into gap-behaviors-presets 2026-10-27 16:51:00 +01:00
midasdf 5aadb0df80 Merge remote-tracking branch 'origin/main' into pr
# Conflicts:
#	crates/text/src/fonts.rs
#	crates/text/src/layout.rs
2026-10-27 22:33:32 +09:00
vangel76andClaude Opus 5.5 9ed448d75c Merge main into feat-gap25-a11y-audit
Conflict: docs/ui-parity.md (Estimate). Kept main's 60-110 h total
without the multi-monitor line and this branch's accessibility figure
(12-25 h, first slice done).

Adapted to main's shared docking layout (#2432):
- tests/ui_accessibility_audit.rs: Preview now gets a short frame at the
  top of the right column and its controls below it stay in the tree,
  counted against the panel underneath. The harness closes Preview, and
  the per-panel pass closes it again after its own scenario. The
  not-yet-fixed BASELINE numbers are re-measured in the new layout
  (panels are taller, so more controls are visible); the fixed panels
  stay at zero.
- tests/ui_effects_presets_keyboard.rs: the taller Effects & Presets list
  now draws the starred Gaussian Blur row in Blur & Sharpen, so the
  closed-Favorites check counts Gaussian Blur tree items (at most one)
  instead of requiring no "Remove from favorites" star at all.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-26 11:40:28 +01:00
dotCooCoo 924b755b72 Docs: gaps.md no longer lists keyboard shortcuts for scripts as missing
File ▸ Scripts entries take keys in Edit ▸ Keyboard Shortcuts, so G8 says so and keeps the Startup and Shutdown folders and .jsxbin as missing.
2026-10-26 02:06:53 -07:00
aiongg 6d063fc9de Merge upstream main into craft-ui-docking
craft-libs crates move to one rev, 37c907d2 (contains main's craft-update and craft-docpath pins).
Docs: native floating windows are Windows, macOS and X11 only; the UI estimate drops the
multi-monitor panel work that is done.
2026-10-26 01:59:50 +00:00
tylerjenningsw 0a2842be85 Merge main into fix/947-preview-opening-audio 2026-10-25 14:26:31 -04:00
tylerjenningsw 40a9173f17 Merge main into fix/expression-value-color 2026-10-25 14:26:30 -04:00
tylerjenningsw a2f3ac41b1 Merge main into enhance/avi-import 2026-10-25 14:26:28 -04:00
aiongg 38be76ddc4 D2: floating panels open in OS windows of their own on desktop; dialogs block them
craft-ui's native-windows feature is on for every non-wasm build. Keys and
dropped files from a floating window reach the main window's next frame, and
while a modal dialog is open the dock area blocks input in floating windows.
Move Panel to Main Window docks the panel again. The web, Wayland and embedded
viewports keep floating windows in the main window.
2026-10-25 05:32:15 +00:00
vangel76andClaude Opus 5.5 81f9d93b82 Merge upstream/main into feat-gap25-a11y-audit
settings.rs: keep upstream's measured page-list width, text_fit and
translated page titles, and the PR's per-page ids, list-item roles,
keyboard focus and focus ring.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-24 20:29:48 +02:00
vangel76andClaude Opus 5.5 c8dc0fca8c Merge upstream/main into gap-behaviors-presets
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-24 20:11:09 +02:00
dotCooCoo 9de2c5ee8a Interpret Footage: Cineon Settings convert DPX and Cineon log scans
DPX and Cineon footage showed its log code values as stored, with no
way to convert them. Interpret Footage now has the Cineon Settings that
After Effects' help page describes: Logarithmic Conversion, the
Converted Black and White Points, the 10 Bit Black and White Points,
Current Gamma, Highlight Rolloff and Units. With Logarithmic
Conversion on, the code values of each decoded frame are converted
from printing density to the Current Gamma between the converted
points, before Separate Fields, Frame Blending, Interpret As Linear
Light and the working space use them. With it off (the default), the
values stay as stored.

file.interpretFootage and file.interpretProxy take the settings as
parameters and report them. They return an error for out-of-range
values, and for Cineon parameters when none of the items is a DPX or
Cineon file. Apply Interpretation copies the settings between DPX and
Cineon files.
2026-10-24 08:37:15 -07:00
dotCooCoo efe7581f93 Scripts: the Startup and Shutdown folders run at launch and quit
Scripts in Scripts/Startup and Scripts/Shutdown in the settings folder
were never run. The desktop and web apps now run the Startup scripts at
launch, before a project opens, and the desktop app runs the Shutdown
scripts as it quits, after the project is closed. Each folder runs in
alphabetical order with case ignored, and files larger than 16 MiB are
not run. A Startup script that fails is reported in a toast and in the
log, a Shutdown script that fails is reported in the log, and the next
one still runs.

A Startup script that waits in a modal dialog goes on when the dialog
closes, while the next scripts run. A Shutdown script's dialogs close
as if canceled. With the settings folder on disk, each script runs as
its file, so #include, $.fileName and $.evalFile resolve against the
script's own folder.

The new commands file.runStartupScripts and file.runShutdownScripts
return the scripts that ran, those still waiting in a dialog, and those
that failed. Like script.run, both are refused in confined automation
sessions, in batches and in script steps, which now read one list of
script commands (RUNS_SCRIPTS). The list also holds window.scriptPanel
and window.restoreScriptPanels, which run ScriptUI panel scripts and
were not refused on main either. The apps still call
window.restoreScriptPanels at launch. plugins.md, scripting-parity.md,
gaps.md, target-app-parity.md and agents.md describe the folders. Each script
still runs in its own global scope, so a Startup script's variables are
not available to later scripts.
2026-10-24 02:44:05 -07:00
midasdf bf069fe4f9 Merge remote-tracking branch 'origin/main' into jp/cjk-composition-rendering
# Conflicts:
#	crates/text/src/fonts.rs
#	docs/localization-parity.md
2026-10-24 09:59:55 +09:00
midasdf 434258050a Text: Chinese Han text uses the installed Chinese face (#453)
macOS does not install the on-demand PingFang SC (macOS 27 on an English
install ships Hiragino Sans GB, Heiti SC, Songti SC and STSong instead),
and the Simplified Chinese fallback list named only Windows and Linux
families. A Chinese character therefore fell through to the exhaustive
search, which picks the first installed face that covers it — Hiragino
Sans, the Japanese face — so Chinese text in a composition was drawn
with Japanese glyph forms (#453). Japanese kana and kanji were already
handled, and a Chinese-only character the Japanese face lacks (e.g.
页) still found a Chinese face, which is why the symptom looked
selective.

Add the macOS Chinese faces to the fallback lists: Hiragino Sans GB,
Heiti SC, Songti SC and STSong for Simplified Chinese, Songti TC for
Traditional (Heiti TC was already named). The interface language still
chooses between the scripts and an English interface keeps the
Japanese-first order for shared Han ideographs, as designed in #312;
what changes is that a Chinese-locale request has an installed Chinese
family to answer it on macOS.

Tests: a text-layer render test draws Japanese and Chinese text and
checks glyph coverage (skipped where no CJK face is installed); a layout
test checks every CJK glyph comes from a face that has the character, so
a missing-glyph box cannot creep back; and the fonts test fails without
the list change ("Hiragino Sans GB missing from the Han list"), passes
with it, and walks the Han branch's list to prove the first installed
Simplified family is a Chinese face, not a Japanese one.

Verified with CARGO_BUILD_JOBS=2 RUST_TEST_THREADS=2:
effectcraft-text 64 passed; effectcraft-render 233 passed, 1 ignored;
cargo clippy -p effectcraft-text -p effectcraft-render --all-targets --
-D warnings clean; cargo fmt --all -- --check clean. A 900x240 render of
"骨直真具画 中文测试" with the zh-hans request now uses Hiragino Sans GB
and differs from the Japanese render, which still uses Hiragino Sans.
2026-10-22 01:00:20 +09:00
Davit MatchakhelidzeandClaude Opus 5.5 2447b54856 docs: Georgian catalog counts at this head
Menus 628 rows (every menu catalog), panels 886 (695 shared with the Chinese
catalogs plus 191 Georgian-only), effect names 307 + 21 categories; gaps.md
and localization-parity.md now agree.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YMTAbGNRxnMEzRvYnQGphF
2026-10-19 18:16:21 +04:00
vangel76andClaude Sonnet 5.5 4f3851206a Merge upstream/main into feat-gap25-a11y-audit
Resolve conflicts in the Effects & Presets panel, the arrow-key nudge and the
docs; update two a11y tests to the prefs-based favourites.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-19 02:06:49 +02:00
vangel76andClaude Sonnet 5.5 24612b0eaf Merge upstream/main into gap-behaviors-presets
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-19 02:02:16 +02:00
Davit MatchakhelidzeandClaude Opus 5.5 5a069af3fd Merge i18n-improvements (main merged)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YMTAbGNRxnMEzRvYnQGphF
2026-10-19 02:58:18 +04:00
tylerjenningsw d2ae0bd503 Merge main into enhance/avi-import 2026-10-18 12:45:36 -04:00