, String> {
self.instance.get_typed_func::(&self.store, name).map_err(|_| missing(name))
}
+
+ /// Select the render export for `abi`.
+ fn finish(self, abi: u32) -> Result {
+ let render = match abi {
+ 1 => Renderer::V1(self.instance.get_typed_func::<_, i32>(&self.store, "ec_render").map_err(|_| missing("ec_render"))?),
+ 2 => Renderer::V2(self.instance.get_typed_func::<_, i32>(&self.store, "ec_render2").map_err(|_| missing("ec_render2"))?),
+ v => return Err(unsupported(v as i32)),
+ };
+ Ok(Inst { store: self.store, memory: self.memory, alloc: self.alloc, render })
+ }
}
+/// The error for a missing or mistyped export.
fn missing(name: &str) -> String {
format!("the module exports no `{name}` (or with the wrong signature)")
}
+/// The error for an ABI this build does not implement.
+fn unsupported(v: i32) -> String {
+ format!("the module implements WebAssembly ABI {v}, this build implements ABI {MIN_WASM_API_VERSION} to {WASM_API_VERSION}")
+}
+
+/// The module's `ec_api_version`, when this build implements it.
+fn abi_of(v: i32) -> Result {
+ match u32::try_from(v) {
+ Ok(v) if (MIN_WASM_API_VERSION..=WASM_API_VERSION).contains(&v) => Ok(v),
+ _ => Err(unsupported(v)),
+ }
+}
+
+/// The error for a wasmi or trap failure.
fn err(e: impl std::fmt::Display) -> String {
e.to_string()
}
-fn instantiate(engine: &Engine, module: &Module) -> Result {
+/// Instantiate `module` in a fresh, limited store and read its memory and allocator.
+fn begin(engine: &Engine, module: &Module) -> Result {
let mut store = Store::new(engine, StoreLimitsBuilder::new().memory_size(MAX_MEMORY).instances(1).build());
store.limiter(|l| l);
store.set_fuel(FUEL_BASE).map_err(err)?;
@@ -48,14 +91,20 @@ fn instantiate(engine: &Engine, module: &Module) -> Result {
let instance = linker.instantiate_and_start(&mut store, module).map_err(|e| format!("instantiation failed: {e}"))?;
let memory = instance.get_memory(&store, "memory").ok_or("the module exports no `memory`")?;
let alloc = instance.get_typed_func::(&store, "ec_alloc").map_err(|_| missing("ec_alloc"))?;
- let render = instance.get_typed_func::<(i32, i32, i32, i32, i32, f64, f64), i32>(&store, "ec_render").map_err(|_| missing("ec_render"))?;
- Ok(Inst { store, instance, memory, alloc, render })
+ Ok(Pending { store, instance, memory, alloc })
+}
+
+/// Instantiate `module` and select the render export for `abi`.
+fn instantiate(engine: &Engine, module: &Module, abi: u32) -> Result {
+ begin(engine, module)?.finish(abi)
}
/// A loaded WebAssembly effect plug-in.
pub struct WasmPlugin {
manifest: PluginManifest,
source: String,
+ /// The WebAssembly ABI the module implements (`ec_api_version`).
+ abi: u32,
engine: Engine,
module: Module,
/// Idle instances.
@@ -63,6 +112,7 @@ pub struct WasmPlugin {
}
impl WasmPlugin {
+ /// Load `bytes` and its manifest; errors on imports, a bad manifest or a missing export.
pub fn new(bytes: &[u8], source: &str) -> Result {
let mut config = Config::default();
config.consume_fuel(true);
@@ -71,51 +121,42 @@ impl WasmPlugin {
if let Some(i) = module.imports().next() {
return Err(format!("plug-ins can't import anything (the module imports `{}.{}`)", i.module(), i.name()));
}
- let mut inst = instantiate(&engine, &module)?;
- let version = inst.func::<(), i32>("ec_api_version")?;
- let v = version.call(&mut inst.store, ()).map_err(err)?;
- if u32::try_from(v).ok() != Some(WASM_API_VERSION) {
- return Err(format!("the module implements plug-in API {v}, this build implements API {WASM_API_VERSION} for WebAssembly"));
- }
- let ptr = inst.func::<(), i32>("ec_manifest_ptr")?.call(&mut inst.store, ()).map_err(err)?;
- let len = inst.func::<(), i32>("ec_manifest_len")?.call(&mut inst.store, ()).map_err(err)?;
+ let mut pending = begin(&engine, &module)?;
+ let version = pending.func::<(), i32>("ec_api_version")?;
+ let abi = abi_of(version.call(&mut pending.store, ()).map_err(err)?)?;
+ let ptr = pending.func::<(), i32>("ec_manifest_ptr")?.call(&mut pending.store, ()).map_err(err)?;
+ let len = pending.func::<(), i32>("ec_manifest_len")?.call(&mut pending.store, ()).map_err(err)?;
if !(0..=MAX_MANIFEST).contains(&len) {
return Err(format!("bad manifest length {len}"));
}
let mut text = vec![0u8; len as usize];
- inst.memory.read(&inst.store, ptr as u32 as usize, &mut text).map_err(|e| format!("manifest out of bounds: {e}"))?;
+ pending.memory.read(&pending.store, ptr as u32 as usize, &mut text).map_err(|e| format!("manifest out of bounds: {e}"))?;
let manifest: PluginManifest = serde_json::from_slice(&text).map_err(|e| format!("bad manifest JSON: {e}"))?;
manifest.validate()?;
if let Some(p) = manifest.params.iter().find(|p| p.kind.needs_v2()) {
return Err(format!("parameter `{}`: WebAssembly plug-ins use plug-in API 1 parameter types (no point3, layer, text or hidden)", p.id));
}
- Ok(WasmPlugin { manifest, source: source.to_string(), engine, module, pool: Mutex::new(vec![inst]) })
+ let inst = pending.finish(abi)?;
+ Ok(WasmPlugin { manifest, source: source.to_string(), abi, engine, module, pool: Mutex::new(vec![inst]) })
}
+ /// An idle instance, or a fresh one when the pool is empty.
fn take(&self) -> Result {
if let Some(i) = self.pool.lock().ok().and_then(|mut p| p.pop()) {
return Ok(i);
}
- instantiate(&self.engine, &self.module)
+ instantiate(&self.engine, &self.module, self.abi)
}
+ /// Return a working instance to the pool.
fn give_back(&self, inst: Inst) {
if let Ok(mut p) = self.pool.lock() {
p.push(inst);
}
}
-}
-impl EffectPlugin for WasmPlugin {
- fn manifest(&self) -> &PluginManifest {
- &self.manifest
- }
-
- fn source(&self) -> String {
- self.source.clone()
- }
-
- fn render(&self, frame: &mut PluginFrame, params: &PluginParams, time: f64) -> Result<(), String> {
+ /// ABI 1: parameters, then the pixels; `ec_render`.
+ fn render_v1(&self, frame: &mut PluginFrame, params: &PluginParams, time: f64) -> Result<(), String> {
let n = frame.pixels.len();
let params_bytes = params.flat.len() * 8;
let total = params_bytes + n * 16;
@@ -130,25 +171,19 @@ impl EffectPlugin for WasmPlugin {
for v in params.flat {
buf.extend_from_slice(&v.to_le_bytes());
}
- for px in frame.pixels.iter() {
- for c in px {
- buf.extend_from_slice(&c.to_le_bytes());
- }
- }
+ push_pixels(&mut buf, frame.pixels);
inst.memory.write(&mut inst.store, base, &buf).map_err(|e| format!("ec_alloc returned a buffer out of bounds: {e}"))?;
let px_ptr = (base + params_bytes) as i32;
- let r = inst
- .render
- .call(&mut inst.store, (px_ptr, frame.width as i32, frame.height as i32, base as i32, params.flat.len() as i32, time, frame.scale))
- .map_err(|e| format!("ec_render trapped: {e}"));
+ let r = match &inst.render {
+ Renderer::V1(f) => f
+ .call(&mut inst.store, (px_ptr, frame.width as i32, frame.height as i32, base as i32, params.flat.len() as i32, time, frame.scale))
+ .map_err(|e| format!("ec_render trapped: {e}")),
+ Renderer::V2(_) => return Err("the module implements WebAssembly ABI 1 but exports ec_render2".into()),
+ };
let r = match r {
Ok(0) => {
inst.memory.read(&inst.store, base + params_bytes, &mut buf[params_bytes..]).map_err(err)?;
- for (px, b) in frame.pixels.iter_mut().zip(buf[params_bytes..].as_chunks::<16>().0.iter()) {
- for (c, v) in px.iter_mut().zip(b.as_chunks::<4>().0.iter()) {
- *c = f32::from_le_bytes([v[0], v[1], v[2], v[3]]);
- }
- }
+ read_pixels(&buf[params_bytes..], frame.pixels);
Ok(())
}
Ok(code) => Err(format!("ec_render returned error {code}")),
@@ -159,4 +194,170 @@ impl EffectPlugin for WasmPlugin {
}
r
}
+
+ /// ABI 2: parameters, the current frame, then the previous and next frames; `ec_render2`.
+ /// The neighbour buffers are always allocated (zeroed when absent), so a module can read
+ /// both without a null check; `flags` says which hold real frames.
+ fn render_v2(
+ &self,
+ frame: &mut PluginFrame,
+ params: &PluginParams,
+ time: f64,
+ prev: Option<(f64, &PluginImage)>,
+ next: Option<(f64, &PluginImage)>,
+ ) -> Result<(), String> {
+ let n = frame.pixels.len();
+ let params_bytes = params.flat.len() * 8;
+ let frame_bytes = n * 16;
+ let total = params_bytes + frame_bytes * 3;
+ if total > i32::MAX as usize {
+ return Err("frame too large for a 32-bit plug-in".into());
+ }
+ let prev_px = prev.map(|(t, img)| (t, img.on_grid(frame.width, frame.height, frame.origin, frame.scale)));
+ let next_px = next.map(|(t, img)| (t, img.on_grid(frame.width, frame.height, frame.origin, frame.scale)));
+ let prev = prev_px.as_ref().filter(|(_, px)| px.len() == n);
+ let next = next_px.as_ref().filter(|(_, px)| px.len() == n);
+ let mut inst = self.take()?;
+ inst.store.set_fuel(FUEL_BASE + FUEL_PER_PIXEL * (n as u64 * 3)).map_err(err)?;
+ let base = inst.alloc.call(&mut inst.store, total as i32).map_err(err)? as u32 as usize;
+ let mut buf: Vec = Vec::with_capacity(total);
+ for v in params.flat {
+ buf.extend_from_slice(&v.to_le_bytes());
+ }
+ push_pixels(&mut buf, frame.pixels);
+ push_neighbour(&mut buf, prev, frame_bytes);
+ push_neighbour(&mut buf, next, frame_bytes);
+ inst.memory.write(&mut inst.store, base, &buf).map_err(|e| format!("ec_alloc returned a buffer out of bounds: {e}"))?;
+ let px_ptr = (base + params_bytes) as i32;
+ let prev_ptr = (base + params_bytes + frame_bytes) as i32;
+ let next_ptr = (base + params_bytes + frame_bytes * 2) as i32;
+ let flags = i32::from(prev.is_some()) | (i32::from(next.is_some()) << 1);
+ let prev_time = prev.map_or(0.0, |(t, _)| *t);
+ let next_time = next.map_or(0.0, |(t, _)| *t);
+ let r = match &inst.render {
+ Renderer::V2(f) => f
+ .call(
+ &mut inst.store,
+ (
+ px_ptr,
+ frame.width as i32,
+ frame.height as i32,
+ base as i32,
+ params.flat.len() as i32,
+ time,
+ frame.scale,
+ prev_ptr,
+ prev_time,
+ next_ptr,
+ next_time,
+ flags,
+ ),
+ )
+ .map_err(|e| format!("ec_render2 trapped: {e}")),
+ Renderer::V1(_) => return Err("the module implements WebAssembly ABI 2 but exports ec_render".into()),
+ };
+ let r = match r {
+ Ok(0) => {
+ let mut out = vec![0u8; frame_bytes];
+ inst.memory.read(&inst.store, base + params_bytes, &mut out).map_err(err)?;
+ read_pixels(&out, frame.pixels);
+ Ok(())
+ }
+ Ok(code) => Err(format!("ec_render2 returned error {code}")),
+ Err(e) => Err(e),
+ };
+ if r.is_ok() {
+ self.give_back(inst);
+ }
+ r
+ }
+}
+
+/// Append pixels to the little-endian buffer the module reads.
+fn push_pixels(buf: &mut Vec, px: &[[f32; 4]]) {
+ for p in px {
+ for c in p {
+ buf.extend_from_slice(&c.to_le_bytes());
+ }
+ }
+}
+
+/// The neighbour's pixels, or `frame_bytes` zeroed bytes when there is no frame.
+fn push_neighbour(buf: &mut Vec, neighbour: Option<&(f64, Vec<[f32; 4]>)>, frame_bytes: usize) {
+ match neighbour {
+ Some((_, px)) => push_pixels(buf, px),
+ None => buf.resize(buf.len() + frame_bytes, 0),
+ }
+}
+
+/// Read the little-endian pixels the module wrote back.
+fn read_pixels(bytes: &[u8], pixels: &mut [[f32; 4]]) {
+ for (px, b) in pixels.iter_mut().zip(bytes.as_chunks::<16>().0.iter()) {
+ for (c, v) in px.iter_mut().zip(b.as_chunks::<4>().0.iter()) {
+ *c = f32::from_le_bytes([v[0], v[1], v[2], v[3]]);
+ }
+ }
+}
+
+/// The layer times of the frames around `time` on a `fps` grid: the frame before and after it
+/// at a frame boundary, the two frames that bracket it between frames.
+fn neighbour_times(time: f64, fps: f64) -> (f64, f64) {
+ if !fps.is_finite() || fps <= 0.0 {
+ return (time - 1.0 / 30.0, time + 1.0 / 30.0);
+ }
+ let step = 1.0 / fps;
+ let at = time * fps;
+ // Frame times are not exact in floating point: at NTSC rates `time * fps` often lands a few
+ // ulps above or below an integer. Treat a near-integer as a frame boundary, so the current
+ // frame is never handed back as its own neighbour.
+ if (at - at.round()).abs() < 1e-6 { (time - step, time + step) } else { (at.floor() / fps, at.ceil() / fps) }
+}
+
+impl EffectPlugin for WasmPlugin {
+ fn manifest(&self) -> &PluginManifest {
+ &self.manifest
+ }
+
+ fn source(&self) -> String {
+ self.source.clone()
+ }
+
+ fn reads_other_times(&self) -> bool {
+ self.abi >= 2
+ }
+
+ fn render(&self, frame: &mut PluginFrame, params: &PluginParams, time: f64) -> Result<(), String> {
+ if self.abi == 1 { self.render_v1(frame, params, time) } else { self.render_v2(frame, params, time, None, None) }
+ }
+
+ fn render_v2(&self, frame: &mut PluginFrame, params: &PluginParams, time: f64, host: &dyn PluginHost) -> Result<(), String> {
+ if self.abi == 1 {
+ return self.render_v1(frame, params, time);
+ }
+ let (prev_time, next_time) = neighbour_times(time, host.frame_rate());
+ let prev = host.input_at(prev_time);
+ let next = host.input_at(next_time);
+ let prev = prev.as_ref().map(|img| (prev_time, img));
+ let next = next.as_ref().map(|img| (next_time, img));
+ self.render_v2(frame, params, time, prev, next)
+ }
+}
+
+#[cfg(test)]
+mod tests {
+ use super::neighbour_times;
+
+ /// NTSC frame times do not multiply back exactly; every frame boundary must still get the
+ /// frames either side of it, never the frame itself.
+ #[test]
+ fn frame_boundaries_get_their_neighbours_at_ntsc_rates() {
+ let fps = 24000.0 / 1001.0;
+ for n in 0..2400 {
+ // 24000/1001 fps at 254 016 000 000 ticks/s, as `Tick` stores it.
+ let time = (n * 10_594_584_000_i64) as f64 / 254_016_000_000.0;
+ let (prev, next) = neighbour_times(time, fps);
+ assert!((prev - (time - 1.0 / fps)).abs() < 1e-9, "frame {n}: prev {prev}, current {time}");
+ assert!((next - (time + 1.0 / fps)).abs() < 1e-9, "frame {n}: next {next}, current {time}");
+ }
+ }
}
diff --git a/crates/project/src/footage.rs b/crates/project/src/footage.rs
index 2cf887b1f..eeace5e81 100644
--- a/crates/project/src/footage.rs
+++ b/crates/project/src/footage.rs
@@ -269,6 +269,13 @@ pub struct Footage {
/// made from the footage starts with them, and Update Markers From Source copies new ones.
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub markers: Vec,
+ /// PDF / Illustrator footage (`.pdf`, `.ai`; not EPS) from an After Effects project: the page
+ /// is framed as After Effects places it (the ArtBox, `/Rotate` ignored) and drawn to fill
+ /// `width` × `height`, the size After Effects stored, which the layers' anchors and masks are
+ /// measured against (#3099). Other footage (and every project saved before this field) shows
+ /// the page as a PDF viewer does, at its own size.
+ #[serde(default, skip_serializing_if = "std::ops::Not::not")]
+ pub placed_page: bool,
}
fn is_default(v: &T) -> bool {
@@ -307,6 +314,7 @@ impl Default for Footage {
start_timecode: None,
file_timecode: None,
markers: vec![],
+ placed_page: false,
}
}
}
diff --git a/crates/render/src/accel.rs b/crates/render/src/accel.rs
index 7e91c6f62..d1ab70ab9 100644
--- a/crates/render/src/accel.rs
+++ b/crates/render/src/accel.rs
@@ -21,10 +21,13 @@ pub enum Backend {
}
impl Backend {
+ /// The backend `s` names, whatever case it is written in: the project's own values (`cpu`,
+ /// `gpu`, `auto`), the labels Project Settings ▸ Video Rendering and Effects draws
+ /// (`GPU Acceleration`, `Software Rendering`) and the older After Effects wording.
pub fn parse(s: &str) -> Option {
match s.to_ascii_lowercase().as_str() {
- "cpu" | "software" | "mercury software only" => Some(Backend::Cpu),
- "gpu" | "mercury gpu acceleration" => Some(Backend::Gpu),
+ "cpu" | "software" | "mercury software only" | "software rendering" => Some(Backend::Cpu),
+ "gpu" | "mercury gpu acceleration" | "gpu acceleration" => Some(Backend::Gpu),
"auto" => Some(Backend::Auto),
_ => None,
}
diff --git a/crates/render/src/cache.rs b/crates/render/src/cache.rs
index 4bbd4e198..7bc52606f 100644
--- a/crates/render/src/cache.rs
+++ b/crates/render/src/cache.rs
@@ -694,7 +694,9 @@ fn reads_other_times(layer: &Layer, effects: Option) -> bool {
fx.groups().take(effects.unwrap_or(usize::MAX)).any(|g| {
g.enabled
&& matches!(&g.kind, effectcraft_project::GroupKind::Effect { effect }
- if effect.starts_with("ec.time.") || effectcraft_effects::reads_param_history(effect))
+ if effect.starts_with("ec.time.")
+ || effectcraft_effects::reads_param_history(effect)
+ || (!effect.starts_with("ec.") && effectcraft_effects::plugin::reads_other_times(effect)))
})
})
}
diff --git a/crates/render/src/footage.rs b/crates/render/src/footage.rs
index 0e17f152d..6b7fdcbf8 100644
--- a/crates/render/src/footage.rs
+++ b/crates/render/src/footage.rs
@@ -76,8 +76,9 @@ pub trait FootageSource: Send + Sync {
fn cache_budget(&self) -> Option {
None
}
- /// Vector footage (SVG) rasterised at `scale` × its pixel size, for Continuously Rasterize.
- /// `None` when the footage is not vector or cannot be read.
+ /// Vector footage (SVG, PDF, Illustrator, EPS: [`is_vector_footage`]) rasterised at `scale` ×
+ /// its size as [`vector_fit`] draws it, for Continuously Rasterize. `None` when the footage
+ /// is not vector or cannot be read.
fn vector_frame(&self, _item: ItemId, _footage: &Footage, _scale: f64) -> Option> {
None
}
@@ -216,9 +217,31 @@ impl FootageSource for CancellableFootage<'_> {
}
}
-/// Footage that can be rasterised at any scale (SVG).
+/// Footage that can be rasterised at any scale: SVG, PDF, Illustrator and EPS files, and a
+/// placed page of an After Effects project (its codec is not stored there).
pub fn is_vector_footage(f: &Footage) -> bool {
- matches!(f.codec.as_str(), "SVG" | "PDF" | "AI" | "EPS")
+ matches!(f.codec.as_str(), "SVG" | "PDF" | "AI" | "EPS") || f.placed_page
+}
+
+/// How vector footage `f` is drawn at `scale` × its size: the image size, and the x and y scale
+/// from document pixels (`doc` = the document's width and height, `own` = its pixel size, the
+/// size rounded up) to image pixels.
+///
+/// Footage from an After Effects project ([`Footage::placed_page`]) fills its stored size, which
+/// can round or measure the page differently: the layer's anchor and masks are measured against
+/// that size, and the renderer resamples a reduced-resolution frame to it, so drawn at its own
+/// size the art was scaled by the width ratio alone at full resolution (off against the masks)
+/// and stretched to the stored aspect below 3/4 resolution (#3099). Other footage is drawn 1:1 at
+/// the document's own size, as it always was.
+pub fn vector_fit(f: &Footage, doc: [f64; 2], own: (u32, u32), scale: f64) -> ((u32, u32), [f64; 2]) {
+ let scale = if scale.is_finite() && scale > 0.0 { scale } else { 1.0 };
+ let side = |px: u32| (f64::from(px) * scale).ceil().clamp(1.0, f64::from(u32::MAX)) as u32;
+ let size = (f.width, f.height);
+ let fills = f.placed_page && size != own && size.0 > 0 && size.1 > 0 && doc.iter().all(|d| d.is_finite() && *d > 0.0);
+ if !fills {
+ return ((side(own.0), side(own.1)), [scale, scale]);
+ }
+ ((side(size.0), side(size.1)), [scale * f64::from(size.0) / doc[0], scale * f64::from(size.1) / doc[1]])
}
/// No footage available (renders footage layers as transparent).
diff --git a/crates/render/src/lib.rs b/crates/render/src/lib.rs
index 27fbf8cec..05b443763 100644
--- a/crates/render/src/lib.rs
+++ b/crates/render/src/lib.rs
@@ -47,7 +47,7 @@ mod opts;
mod pipeline;
pub use accel::{Accelerator, Backend, FrameMemory, FxStep, FxTarget};
-pub use footage::{CancellableFootage, FloatCurve, FootageSource, NoFootage, is_vector_footage, missing_item_problem};
+pub use footage::{CancellableFootage, FloatCurve, FootageSource, NoFootage, is_vector_footage, missing_item_problem, vector_fit};
pub use frames::{
adaptive_samples, blend_frames, cineon_frame, content_bounds, extended_region, field_frame, frame_position, frame_size, interpret_pixels, kurbo_path,
render_frame, roi_inside,
diff --git a/crates/render/src/tests.rs b/crates/render/src/tests.rs
index 50ed65c73..59fa0fadc 100644
--- a/crates/render/src/tests.rs
+++ b/crates/render/src/tests.rs
@@ -329,7 +329,7 @@ fn card_dance_comp_camera_matches_the_default_view() {
assert!(img.get(10, 50)[3] < 0.01);
}
-/// A black 2D solid with CC Particle World, under a camera layer panned right by `pan` px.
+/// A black 2D solid with Particle Emitter 3D, under a camera layer panned right by `pan` px.
fn particle_world_scene(pan: f64) -> (Project, ItemId) {
let (mut p, cid, comp) = setup();
let mut l = solid(&mut p, &comp, [0.0, 0.0, 0.0], 200, 100);
@@ -359,7 +359,7 @@ fn particles_x(img: &crate::Image) -> f32 {
sx / m
}
-/// #397: CC Particle World on a 2D layer is seen through the comp's camera layer, and the layer
+/// #397: Particle Emitter 3D on a 2D layer is seen through the comp's camera layer, and the layer
/// cache notices the camera moving.
#[test]
fn particle_world_follows_the_comp_camera() {
@@ -374,7 +374,7 @@ fn particle_world_follows_the_comp_camera() {
assert!(b < a - 20.0, "panning the camera right moves the particles left: {a} -> {b}");
}
-/// A black solid with CC Particle World whose Birth Rate is 3 until layer time `cut`, then 0 a
+/// A black solid with Particle Emitter 3D whose Birth Rate is 3 until layer time `cut`, then 0 a
/// frame later (`None`: 3 throughout); the layer starts at comp time `start`, stretched `stretch` %.
fn burst_scene(cut: Option, start: f64, stretch: f64) -> (Project, ItemId) {
burst_scene_keys(cut, start, stretch, false)
@@ -624,7 +624,7 @@ fn a_text_expression_selector_is_not_served_from_the_disk_cache() {
/// A Birth Rate expression reading another layer: changing that layer changes the history but
/// not the current rate (0) nor this layer's properties, which is all the layer cache key sees.
-/// CC Particle World layers with expressions therefore aren't layer cached.
+/// Particle Emitter 3D layers with expressions therefore aren't layer cached.
#[test]
fn particle_world_with_a_birth_rate_expression_is_not_served_from_the_layer_cache() {
let scene = |opacity: f64| {
@@ -657,8 +657,8 @@ fn particle_world_with_a_birth_rate_expression_is_not_served_from_the_layer_cach
assert!(light(&b) > 1.0 && light(&b) < light(&a), "fewer births: {} vs {}", light(&b), light(&a));
}
-/// A grey solid (CC Mr. Mercury shades its blobs from it) with effect `id` (CC Particle Systems
-/// II, CC Mr. Mercury): Birth Rate `rate`,
+/// A grey solid (Liquid Particles shades its blobs from it) with effect `id` (CC Particle Systems
+/// II, Liquid Particles): Birth Rate `rate`,
/// or keyed 3 until 0.5 s and 0 a frame later (`None`); Longevity 1 s.
fn system_scene(id: &str, rate: Option) -> (Project, ItemId) {
let (mut p, cid, comp) = setup();
@@ -677,7 +677,7 @@ fn system_scene(id: &str, rate: Option) -> (Project, ItemId) {
(p, cid)
}
-/// #1373 for CC Particle Systems II and CC Mr. Mercury through the renderer: a keyed burst
+/// #1373 for Particle Emitter 2D and Liquid Particles through the renderer: a keyed burst
/// draws as the constant rate during it, still draws after the rate drops to 0 (unlike a rate
/// of 0 throughout), and draws as nothing born once Longevity has run out.
#[test]
@@ -1057,6 +1057,27 @@ fn comp_frame_ends_the_frame_when_the_render_panics() {
assert_eq!(a.ends.load(Ordering::SeqCst), 1);
}
+/// The renderer labels Project Settings ▸ Video Rendering and Effects draws parse back as the
+/// backend they name (in any case), and the older spellings still work.
+#[test]
+fn renderer_labels_parse_back_and_keep_the_older_spellings() {
+ use crate::Backend;
+ for (label, backend) in [
+ ("GPU Acceleration", Backend::Gpu),
+ ("gpu acceleration", Backend::Gpu),
+ ("Mercury GPU Acceleration", Backend::Gpu),
+ ("gpu", Backend::Gpu),
+ ("Software Rendering", Backend::Cpu),
+ ("software rendering", Backend::Cpu),
+ ("Mercury Software Only", Backend::Cpu),
+ ("cpu", Backend::Cpu),
+ ("Auto", Backend::Auto),
+ ] {
+ assert_eq!(Backend::parse(label), Some(backend), "{label}");
+ }
+ assert_eq!(Backend::parse("Vulkan"), None);
+}
+
#[test]
fn auto_backend_sends_2d_and_3d_comps_to_the_gpu() {
let (mut p, cid, comp) = setup();
@@ -1223,11 +1244,11 @@ fn effects_on_text_reach_past_the_text_bounds() {
}
assert!(
painted > 50 && hi.saturating_sub(lo) > 100,
- "CC Tiler tiles the glyphs across the layer region, not just its text bounds: {painted} painted, x-span {lo}..{hi}"
+ "Scaled Tiles tiles the glyphs across the layer region, not just its text bounds: {painted} painted, x-span {lo}..{hi}"
);
}
-/// #658: CC Smear drags text glyphs beyond the text layer's own bounds. Pixels smeared past
+/// #658: Directional Smear drags text glyphs beyond the text layer's own bounds. Pixels smeared past
/// the painted rectangle used to fall off its edge, so the liquid trail never appeared.
#[test]
fn cc_smear_trails_text_past_its_bounds() {
@@ -1246,7 +1267,7 @@ fn cc_smear_trails_text_past_its_bounds() {
);
p.comp_mut(cid).unwrap().layers = vec![l].into();
let smeared = right(&render_frame(&p, cid, Tick::ZERO, 1.0));
- assert!(plain > 40 && smeared > plain + 25, "CC Smear trails the glyphs past the text bounds: right edge {plain} → {smeared}");
+ assert!(plain > 40 && smeared > plain + 25, "Directional Smear trails the glyphs past the text bounds: right edge {plain} → {smeared}");
}
/// A layer parameter pointing at a shape layer sees all of it (in its effect space), and the
@@ -1502,7 +1523,7 @@ fn solo_excludes_other_layers_outside_the_soloed_layers_range() {
assert_eq!(second.get(100, 50), [0.0, 0.0, 1.0, 1.0], "only B inside its range");
}
-/// #1252: a layer blended with a CC Particle World layer, under a camera panned by `pan` px.
+/// #1252: a layer blended with a Particle Emitter 3D layer, under a camera panned by `pan` px.
fn scene_reader_dependency(pan: f64) -> (Project, ItemId) {
let (mut p, cid, comp) = setup();
let mut source = solid(&mut p, &comp, [0.0, 0.0, 0.0], 200, 100);
diff --git a/crates/render/src/tests/time.rs b/crates/render/src/tests/time.rs
index 715c37ef0..f959401bb 100644
--- a/crates/render/src/tests/time.rs
+++ b/crates/render/src/tests/time.rs
@@ -1,7 +1,10 @@
//! Time effects through the renderer: neighbouring frames via `EffectHost::self_at`, and the
//! layer cache staying correct while scrubbing.
+use std::sync::Arc;
+
use effectcraft_color::Label;
+use effectcraft_effects::plugin::{EffectPlugin, PluginFrame, PluginManifest, PluginParams, register_plugin};
use effectcraft_keyframe::{Keyframe, ShapePath, Value};
use effectcraft_project::build::{self, Ids};
use effectcraft_project::{Comp, ItemId, ItemKind, LayerSource, MaskMode, Project, Solid};
@@ -157,3 +160,89 @@ fn input_keys_ignore_later_effects() {
set(&mut p, "effects/#1/blurriness", 8.0);
assert_ne!(key(&p).0, one);
}
+
+/// A plug-in that reads the layer's neighbouring frames (WebAssembly ABI 2) makes its layer's
+/// cache key depend on the layer time, even when the source and every property are static. A
+/// plug-in that does not keeps the old key (#1977: a static layer stays cached across a scrub).
+#[test]
+fn abi2_plugin_layers_key_on_layer_time() {
+ struct NeighbourReader {
+ m: PluginManifest,
+ }
+
+ impl EffectPlugin for NeighbourReader {
+ fn manifest(&self) -> &PluginManifest {
+ &self.m
+ }
+
+ fn render(&self, _frame: &mut PluginFrame, _params: &PluginParams, _time: f64) -> Result<(), String> {
+ Ok(())
+ }
+
+ fn reads_other_times(&self) -> bool {
+ true
+ }
+ }
+
+ struct Plain {
+ m: PluginManifest,
+ }
+
+ impl EffectPlugin for Plain {
+ fn manifest(&self) -> &PluginManifest {
+ &self.m
+ }
+
+ fn render(&self, _frame: &mut PluginFrame, _params: &PluginParams, _time: f64) -> Result<(), String> {
+ Ok(())
+ }
+ }
+
+ /// A static white solid with one plug-in effect, registered by `plugin`.
+ fn plugin_scene(plugin: Arc) -> (Project, ItemId) {
+ let mut p = Project::default();
+ let comp = Comp::new(200, 100, FrameRate::FPS_30, Tick::from_seconds_f64(2.0));
+ let cid = p.add_item("Comp", Label::Sandstone, None, ItemKind::Comp(comp.clone().into()));
+ let sid = p.add_item("Solid", Label::Red, None, ItemKind::Solid(Solid { color: [1.0, 1.0, 1.0], width: 200, height: 100, pixel_aspect: 1.0 }));
+ let mut l = build::layer(&mut p, &comp, "Solid", LayerSource::Solid { item: sid }, (200, 100), None);
+ let spec = register_plugin(plugin).unwrap();
+ let mut next = p.next_id;
+ let g = effectcraft_effects::instantiate(spec, &mut Ids(&mut next), spec.name, [200.0, 100.0]);
+ p.next_id = next;
+ l.props.sub_mut("effects").unwrap().children.push(g.into());
+ p.comp_mut(cid).unwrap().layers.push(l);
+ (p, cid)
+ }
+
+ fn key(p: &Project, cid: ItemId, t: f64) -> Option {
+ let comp = p.comp(cid).unwrap();
+ let ctx = crate::EvalCtx {
+ project: p,
+ comp_id: cid,
+ comp,
+ time: Tick::from_seconds_f64(t),
+ expr: None,
+ footage: None,
+ property_overrides: &[],
+ media_overrides: &[],
+ reads: None,
+ };
+ crate::cache::layer_key(&ctx, &comp.layers[0], 1.0, false, false)
+ }
+
+ let manifest = |id: &str| PluginManifest {
+ api: 2,
+ id: id.into(),
+ name: "Key".into(),
+ category: "Test Plug-ins".into(),
+ version: "1".into(),
+ author: String::new(),
+ description: String::new(),
+ params: vec![],
+ };
+
+ let (plain, c1) = plugin_scene(Arc::new(Plain { m: manifest("org.test.render.time-key.plain") }));
+ assert_eq!(key(&plain, c1, 0.25), key(&plain, c1, 0.5), "a plain plug-in keeps the old key");
+ let (reader, c2) = plugin_scene(Arc::new(NeighbourReader { m: manifest("org.test.render.time-key.reader") }));
+ assert_ne!(key(&reader, c2, 0.25), key(&reader, c2, 0.5), "an ABI 2 plug-in keys on the layer time");
+}
diff --git a/crates/ui-egui/src/dock.rs b/crates/ui-egui/src/dock.rs
index c8ada9bf8..f126db257 100644
--- a/crates/ui-egui/src/dock.rs
+++ b/crates/ui-egui/src/dock.rs
@@ -124,7 +124,7 @@ impl PanelKind {
PanelKind::EssentialGraphics => "Essential Graphics",
PanelKind::ScriptPanel(_) => "ScriptUI Panel",
PanelKind::Viewer(_) => "Composition",
- PanelKind::LumetriScopes => "Lumetri Scopes",
+ PanelKind::LumetriScopes => "Video Scopes",
PanelKind::Footage => "Footage",
PanelKind::MediaBrowser => "Media Browser",
PanelKind::Metadata => "Metadata",
@@ -709,6 +709,16 @@ mod tests {
w.apply(action, permissions).unwrap();
}
+ /// Only the title changes: existing saved workspace layouts still deserialize.
+ #[test]
+ fn scopes_label_is_descriptive_and_its_saved_identity_stays_compatible() {
+ let panel: PanelKind = serde_json::from_str("\"LumetriScopes\"").unwrap();
+ assert_eq!(panel, LumetriScopes);
+ assert_eq!(panel.title(), "Video Scopes");
+ assert_eq!(panel.id(), "LumetriScopes");
+ assert_eq!(serde_json::to_string(&panel).unwrap(), "\"LumetriScopes\"");
+ }
+
#[test]
fn after_effects_workspaces_exist_with_their_core_panels() {
for name in WORKSPACES {
diff --git a/crates/ui-egui/src/i18n.rs b/crates/ui-egui/src/i18n.rs
index 68e58f842..c998538d4 100644
--- a/crates/ui-egui/src/i18n.rs
+++ b/crates/ui-egui/src/i18n.rs
@@ -1054,7 +1054,7 @@ const SIMPLIFIED_CHINESE: &[(&str, &str, &str)] = &[
("window.panel", "Essential Graphics", "基本图形"),
("window.panel", "Info", "信息"),
("help.inAppTutorials", "Learn", "学习"),
- ("window.panel", "Lumetri Scopes", "Lumetri 范围"),
+ ("window.panel", "Video Scopes", "视频示波器"),
("window.panel", "Mask Interpolation", "蒙版插值"),
("window.panel", "Media Browser", "媒体浏览器"),
("window.panel", "Metadata", "元数据"),
@@ -1690,7 +1690,7 @@ const SWEDISH: &[(&str, &str, &str)] = &[
("window.panel", "Essential Graphics", "Grundläggande grafik"),
("window.panel", "Info", "Info"),
("help.inAppTutorials", "Learn", "Lär dig"),
- ("window.panel", "Lumetri Scopes", "Lumetri-scope"),
+ ("window.panel", "Video Scopes", "Videoskop"),
("window.panel", "Mask Interpolation", "Maskinterpolering"),
("window.panel", "Media Browser", "Mediebläddrare"),
("window.panel", "Metadata", "Metadata"),
@@ -2336,7 +2336,7 @@ const TRADITIONAL_CHINESE: &[(&str, &str, &str)] = &[
("window.panel", "Essential Graphics", "基本圖形"),
("window.panel", "Info", "資訊"),
("help.inAppTutorials", "Learn", "學習"),
- ("window.panel", "Lumetri Scopes", "Lumetri 示波器"),
+ ("window.panel", "Video Scopes", "視訊示波器"),
("window.panel", "Mask Interpolation", "遮色片插補"),
("window.panel", "Media Browser", "媒體瀏覽器"),
("window.panel", "Metadata", "中繼資料"),
@@ -2975,7 +2975,7 @@ const JAPANESE: &[(&str, &str, &str)] = &[
("window.panel", "Essential Graphics", "エッセンシャルグラフィックス"),
("window.panel", "Info", "情報"),
("help.inAppTutorials", "Learn", "学習"),
- ("window.panel", "Lumetri Scopes", "Lumetriスコープ"),
+ ("window.panel", "Video Scopes", "ビデオスコープ"),
("window.panel", "Mask Interpolation", "マスク補間"),
("window.panel", "Media Browser", "メディアブラウザー"),
("window.panel", "Metadata", "メタデータ"),
@@ -3617,7 +3617,7 @@ const UKRAINIAN: &[(&str, &str, &str)] = &[
("window.panel", "Essential Graphics", "Основна графіка"),
("window.panel", "Info", "Інформація"),
("help.inAppTutorials", "Learn", "Навчання"),
- ("window.panel", "Lumetri Scopes", "Вимірювачі Lumetri"),
+ ("window.panel", "Video Scopes", "Відеоскопи"),
("window.panel", "Mask Interpolation", "Інтерполяція маски"),
("window.panel", "Media Browser", "Браузер медіа"),
("window.panel", "Metadata", "Метадані"),
@@ -4260,7 +4260,7 @@ const SPANISH: &[(&str, &str, &str)] = &[
("window.panel", "Essential Graphics", "Gráficos esenciales"),
("window.panel", "Info", "Información"),
("help.inAppTutorials", "Learn", "Aprender"),
- ("window.panel", "Lumetri Scopes", "Ámbitos de Lumetri"),
+ ("window.panel", "Video Scopes", "Monitores de vídeo"),
("window.panel", "Mask Interpolation", "Interpolación de máscara"),
("window.panel", "Media Browser", "Navegador de medios"),
("window.panel", "Metadata", "Metadatos"),
@@ -4901,7 +4901,7 @@ const PORTUGUESE: &[(&str, &str, &str)] = &[
("window.panel", "Essential Graphics", "Gráficos essenciais"),
("window.panel", "Info", "Informações"),
("help.inAppTutorials", "Learn", "Aprender"),
- ("window.panel", "Lumetri Scopes", "Escopos Lumetri"),
+ ("window.panel", "Video Scopes", "Escopos de vídeo"),
("window.panel", "Mask Interpolation", "Interpolação de máscara"),
("window.panel", "Media Browser", "Navegador de mídia"),
("window.panel", "Metadata", "Metadados"),
@@ -5544,7 +5544,7 @@ const RUSSIAN: &[(&str, &str, &str)] = &[
("window.panel", "Essential Graphics", "Основная графика"),
("window.panel", "Info", "Информация"),
("help.inAppTutorials", "Learn", "Обучение"),
- ("window.panel", "Lumetri Scopes", "Измерители Lumetri"),
+ ("window.panel", "Video Scopes", "Видеоскопы"),
("window.panel", "Mask Interpolation", "Интерполяция маски"),
("window.panel", "Media Browser", "Обозреватель медиа"),
("window.panel", "Metadata", "Метаданные"),
@@ -6185,7 +6185,7 @@ const FRENCH: &[(&str, &str, &str)] = &[
("window.panel", "Essential Graphics", "Graphiques essentiels"),
("window.panel", "Info", "Informations"),
("help.inAppTutorials", "Learn", "Apprentissage"),
- ("window.panel", "Lumetri Scopes", "Oscilloscopes Lumetri"),
+ ("window.panel", "Video Scopes", "Oscilloscopes vidéo"),
("window.panel", "Mask Interpolation", "Interpolation de masque"),
("window.panel", "Media Browser", "Navigateur multimédia"),
("window.panel", "Metadata", "Métadonnées"),
@@ -6826,7 +6826,7 @@ const GERMAN: &[(&str, &str, &str)] = &[
("window.panel", "Essential Graphics", "Essential-Grafik"),
("window.panel", "Info", "Info"),
("help.inAppTutorials", "Learn", "Lernen"),
- ("window.panel", "Lumetri Scopes", "Lumetri-Scopes"),
+ ("window.panel", "Video Scopes", "Videoskope"),
("window.panel", "Mask Interpolation", "Maskeninterpolation"),
("window.panel", "Media Browser", "Medienbrowser"),
("window.panel", "Metadata", "Metadaten"),
@@ -7464,7 +7464,7 @@ const POLISH: &[(&str, &str, &str)] = &[
("window.panel", "Essential Graphics", "Essential Graphics"),
("window.panel", "Info", "Informacje"),
("help.inAppTutorials", "Learn", "Nauka"),
- ("window.panel", "Lumetri Scopes", "Zakresy Lumetri"),
+ ("window.panel", "Video Scopes", "Wskaźniki wideo"),
("window.panel", "Mask Interpolation", "Interpolacja maski"),
("window.panel", "Media Browser", "Przeglądarka multimediów"),
("window.panel", "Metadata", "Metadane"),
@@ -8106,7 +8106,7 @@ const CZECH: &[(&str, &str, &str)] = &[
("window.panel", "Essential Graphics", "Základní grafika"),
("window.panel", "Info", "Informace"),
("help.inAppTutorials", "Learn", "Výuka"),
- ("window.panel", "Lumetri Scopes", "Měřicí přístroje Lumetri"),
+ ("window.panel", "Video Scopes", "Videoskopy"),
("window.panel", "Mask Interpolation", "Interpolace masek"),
("window.panel", "Media Browser", "Prohlížeč médií"),
("window.panel", "Metadata", "Metadata"),
@@ -8748,7 +8748,7 @@ const GEORGIAN: &[(&str, &str, &str)] = &[
("window.panel", "Essential Graphics", "ძირითადი გრაფიკა"),
("window.panel", "Info", "ინფორმაცია"),
("help.inAppTutorials", "Learn", "სწავლა"),
- ("window.panel", "Lumetri Scopes", "Lumetri Scopes"),
+ ("window.panel", "Video Scopes", "ვიდეოსკოპები"),
("window.panel", "Mask Interpolation", "ნიღბის ინტერპოლაცია"),
("window.panel", "Media Browser", "მედიის ბრაუზერი"),
("window.panel", "Metadata", "მეტამონაცემები"),
@@ -8799,6 +8799,21 @@ mod tests {
use serde_json::json;
use std::collections::BTreeSet;
+ #[test]
+ fn renamed_menu_translations_do_not_reintroduce_vendor_names() {
+ for code in CATALOG_CODES {
+ set_current(code);
+ for (id, source) in [("window.panel", "Video Scopes")] {
+ let rendered = command_label(id, source);
+ let label = rendered.to_lowercase();
+ for mark in ["lumetri", "mercury"] {
+ assert!(!label.contains(mark), "{code}: {id} -> {rendered}");
+ }
+ }
+ }
+ set_current("en");
+ }
+
/// The four options at the foot of the header's workspace menu say what After Effects says,
/// read from its workspace button on 2026-10-31: reset, save over this one, save a copy, then
/// edit the list.
diff --git a/crates/ui-egui/src/i18n/effects.rs b/crates/ui-egui/src/i18n/effects.rs
index ec952ccb0..55893115a 100644
--- a/crates/ui-egui/src/i18n/effects.rs
+++ b/crates/ui-egui/src/i18n/effects.rs
@@ -18,14 +18,19 @@
//! another effect. An effect with no row draws the registry's English name; the
//! `missing_translations_report` test (run by `cargo xtask ci`) lists those per language.
//!
-//! A language decides for itself which names stay English: After Effects' Japanese interface
-//! leaves the `CC` series in English and gives the `VR` and `OCIO` sets a Japanese tail
-//! (`VR ブラー`, `OCIO CDL 変換`), while its Simplified Chinese one translates them (the `CC`
-//! names come from Adobe's Chinese *documentation*, which names 68 of the 69). Repeating the
-//! English name is therefore a language-level choice, not a missing row.
+//! Own feature names are descriptive. The renamed effects use original translations in every
+//! existing effect catalog; legacy vendor names remain search aliases in the effects crate.
+//! External format tokens and stored instance names are not localized or rewritten.
//!
-//! The Simplified Chinese names come from the installed After Effects 2026 (26.5.0.89)
-//! Simplified Chinese interface, its 21 category folder names included; `Cryptomatte`,
+//! The rows of the effects this cleanup did not rename keep the provenance they had. A language
+//! decides for itself which names stay English: After Effects' Japanese interface leaves the `CC`
+//! series in English and gives the `VR` and `OCIO` sets a Japanese tail (`VR ブラー`,
+//! `OCIO CDL 変換`), while its Simplified Chinese one translates them. Repeating the English name
+//! is therefore a language-level choice, not a missing row.
+//!
+//! The Simplified Chinese names of unchanged effects come from the installed After Effects 2026
+//! (26.5.0.89) Simplified Chinese interface, its 21 category folder names included (the `CC` names
+//! came from Adobe's Chinese *documentation*, which names 68 of the 69); `Cryptomatte`,
//! `EXtractoR`, `IDentifier`, `Key Light` and `Unmult` stay in English as brand names, and
//! `Face Measurements` / `Face Track Points` are EffectCraft's own effects, so their wording is
//! ours.
@@ -33,16 +38,15 @@
//! The Traditional Chinese names for Taiwan are written from the meaning of the English ones, with
//! the terms Taiwan's creative software uses (`圖層`, `遮罩`, `筆刷`, `雜訊`, `發光`, `漸層`); they
//! are not converted from the Simplified table. Brand and coined names (`Cryptomatte`,
-//! `EXtractoR`, `IDentifier`, `Key Light`, `Unmult`, `Lumetri Color`, `Colorama`, `Minimax`,
-//! `Vegas`, `Mocha`) stay in English; the `CC` series keeps its prefix and translates the
-//! descriptive tail, and the `VR` and `OCIO` sets keep their prefix in Chinese word order.
+//! `EXtractoR`, `IDentifier`, `Key Light`, `Unmult`, `Colorama`, `Minimax`, `Vegas`) stay in
+//! English, and the `VR` and `OCIO` sets keep their prefix in Chinese word order.
//!
//! The French names are written from the meaning of the English ones, with the vocabulary of the
//! French menus; they come from no other application's interface. Brand and coined names
-//! (`Cryptomatte`, `EXtractoR`, `IDentifier`, `Key Light`, `Unmult`, `Lumetri Color`, `Colorama`,
-//! `Minimax`, `Tritone`, `Vibrance`, `Vegas`) and the whole `CC` series stay in English; a series
-//! tag that prefixes a descriptive name (`VR`, `OCIO`, `PS`, `HDR`) stays and follows the
-//! French word order (`Flou VR`, `Transformation CDL OCIO`).
+//! (`Cryptomatte`, `EXtractoR`, `IDentifier`, `Key Light`, `Unmult`, `Colorama`, `Minimax`,
+//! `Tritone`, `Vibrance`, `Vegas`) stay in English; a series tag that prefixes a descriptive name
+//! (`VR`, `OCIO`, `PS`, `HDR`) stays and follows the French word order (`Flou VR`,
+//! `Transformation CDL OCIO`).
use std::collections::HashMap;
use std::sync::OnceLock;
@@ -122,19 +126,21 @@ pub(super) fn translated_rows(language: &str) -> usize {
/// The name to draw for an effect group the property tree stores as `stored`: the catalog name,
/// plus the instance index the engine appends to a repeat (`Gaussian Blur 2` → `高斯模糊 2`).
///
-/// A name that is neither the registry's nor the registry's plus an index was typed by the user
-/// (Effect Controls ▸ Rename), so it stays verbatim — as does the whole string in a language
-/// with no row.
+/// Current and legacy default names (including numeric instance suffixes) draw the current
+/// name. Other names were supplied by the user and stay verbatim. Stored data is never changed.
pub(crate) fn group(id: &str, stored: &str) -> String {
- let Some((english, translated)) = catalog(current()).and_then(|c| c.row(id)) else { return stored.to_string() };
- if stored == english {
- return translated.to_string();
- }
- if let Some(index) = stored.strip_prefix(english).and_then(|rest| rest.strip_prefix(' '))
- && !index.is_empty()
- && index.bytes().all(|b| b.is_ascii_digit())
- {
- return format!("{translated} {index}");
+ let Some(spec) = effectcraft_engine::effects::find(id) else { return stored.to_string() };
+ let translated = name(id, spec.name);
+ for source in std::iter::once(spec.name).chain(effectcraft_engine::effects::aliases(id).iter().copied()) {
+ if stored == source {
+ return translated;
+ }
+ if let Some(index) = stored.strip_prefix(source).and_then(|rest| rest.strip_prefix(' '))
+ && !index.is_empty()
+ && index.bytes().all(|b| b.is_ascii_digit())
+ {
+ return format!("{translated} {index}");
+ }
}
stored.to_string()
}
@@ -149,6 +155,7 @@ pub(crate) fn category(source: &str) -> String {
/// `query` (lowercase)? Both names match, so a translated interface can be searched either way.
pub(crate) fn matches(id: &str, english: &str, query: &str) -> bool {
english.to_lowercase().contains(query)
+ || effectcraft_engine::effects::find(id).is_some_and(|spec| effectcraft_engine::effects::name_matches(spec, query))
|| catalog(current()).and_then(|c| c.row(id)).is_some_and(|(_, translated)| translated.to_lowercase().contains(query))
}
@@ -192,10 +199,10 @@ const SIMPLIFIED_CHINESE: &[Row] = &[
("ec.blur.bilateral", "Bilateral Blur", "双向模糊"),
("ec.blur.cameralens", "Camera Lens Blur", "摄像机镜头模糊"),
("ec.blur.camerashakedeblur", "Camera-Shake Deblur", "摄像机抖动去模糊"),
- ("ec.blur.cccross", "CC Cross Blur", "CC 交叉模糊"),
- ("ec.blur.ccradial", "CC Radial Blur", "CC 径向模糊"),
- ("ec.blur.ccradialfast", "CC Radial Fast Blur", "CC 径向快速模糊"),
- ("ec.blur.ccvector", "CC Vector Blur", "CC 矢量模糊"),
+ ("ec.blur.cccross", "Cross Blur", "十字模糊"),
+ ("ec.blur.ccradial", "Variable Radial Blur", "可变径向模糊"),
+ ("ec.blur.ccradialfast", "Fast Radial Blur", "快速径向模糊"),
+ ("ec.blur.ccvector", "Vector Blur", "矢量模糊"),
("ec.blur.channel", "Channel Blur", "通道模糊"),
("ec.blur.compound", "Compound Blur", "复合模糊"),
("ec.blur.directional", "Directional Blur", "定向模糊"),
@@ -209,7 +216,7 @@ const SIMPLIFIED_CHINESE: &[Row] = &[
("ec.channel.arithmetic", "Arithmetic", "算术"),
("ec.channel.blend", "Blend", "混合"),
("ec.channel.calculations", "Calculations", "计算"),
- ("ec.channel.cccomposite", "CC Composite", "CC 合成"),
+ ("ec.channel.cccomposite", "Source Composite", "源图合成"),
("ec.channel.combiner", "Channel Combiner", "通道合成器"),
("ec.channel.compoundarithmetic", "Compound Arithmetic", "复合运算"),
("ec.channel.invert", "Invert", "反转"),
@@ -225,10 +232,10 @@ const SIMPLIFIED_CHINESE: &[Row] = &[
("ec.color.blackwhite", "Black & White", "黑色和白色"),
("ec.color.brightnesscontrast", "Brightness & Contrast", "亮度和对比度"),
("ec.color.broadcast", "Broadcast Colors", "广播颜色"),
- ("ec.color.cccolorneutralizer", "CC Color Neutralizer", "CC 颜色中和器"),
- ("ec.color.cccoloroffset", "CC Color Offset", "CC 颜色偏移"),
- ("ec.color.cckernel", "CC Kernel", "CC 内核"),
- ("ec.color.cctoner", "CC Toner", "CC 调色器"),
+ ("ec.color.cccolorneutralizer", "Color Neutralizer", "色偏校正"),
+ ("ec.color.cccoloroffset", "Channel Offset", "通道偏移"),
+ ("ec.color.cckernel", "Convolution Kernel", "卷积核"),
+ ("ec.color.cctoner", "Multi-Tone Tint", "多色调着色"),
("ec.color.changecolor", "Change Color", "更改颜色"),
("ec.color.changetocolor", "Change to Color", "更改为颜色"),
("ec.color.channelmixer", "Channel Mixer", "通道混合器"),
@@ -245,7 +252,7 @@ const SIMPLIFIED_CHINESE: &[Row] = &[
("ec.color.leavecolor", "Leave Color", "保留颜色"),
("ec.color.levels", "Levels", "色阶"),
("ec.color.levelsic", "Levels (Individual Controls)", "色阶 (单独控件)"),
- ("ec.color.lumetri", "Lumetri Color", "Lumetri 颜色"),
+ ("ec.color.lumetri", "Color Grading", "色彩分级"),
("ec.color.ociocdl", "OCIO CDL Transform", "OCIO CDL 变换"),
("ec.color.ociocolorspace", "OCIO Color Space Transform", "OCIO 颜色空间变换"),
("ec.color.ociodisplay", "OCIO Display Transform", "OCIO 显示变换"),
@@ -270,20 +277,20 @@ const SIMPLIFIED_CHINESE: &[Row] = &[
("ec.control.stereo3d", "Stereo 3D Controls", "立体 3D 控制"),
("ec.distort.bezierwarp", "Bezier Warp", "贝塞尔曲线变形"),
("ec.distort.bulge", "Bulge", "凸出"),
- ("ec.distort.ccbender", "CC Bender", "CC 弯曲器"),
- ("ec.distort.ccbendit", "CC Bend It", "CC 弯曲"),
- ("ec.distort.ccblobbylize", "CC Blobbylize", "CC 融化"),
- ("ec.distort.ccflomotion", "CC Flo Motion", "CC 流动运动"),
- ("ec.distort.ccgriddler", "CC Griddler", "CC 网格生成器"),
- ("ec.distort.cclens", "CC Lens", "CC 镜头"),
- ("ec.distort.ccpageturn", "CC Page Turn", "CC 翻页"),
- ("ec.distort.ccpowerpin", "CC Power Pin", "CC 强力边角定位"),
- ("ec.distort.ccripplepulse", "CC Ripple Pulse", "CC 波纹脉冲"),
- ("ec.distort.ccslant", "CC Slant", "CC 倾斜"),
- ("ec.distort.ccsmear", "CC Smear", "CC 漩涡条纹"),
- ("ec.distort.ccsplit", "CC Split", "CC 拆分"),
- ("ec.distort.ccsplit2", "CC Split 2", "CC 拆分 2"),
- ("ec.distort.cctiler", "CC Tiler", "CC 拼贴器"),
+ ("ec.distort.ccbender", "Flexible Bend", "柔性弯曲"),
+ ("ec.distort.ccbendit", "Two-Point Bend", "两点弯曲"),
+ ("ec.distort.ccblobbylize", "Organic Displacement", "有机置换"),
+ ("ec.distort.ccflomotion", "Dual Lens Warp", "双镜头变形"),
+ ("ec.distort.ccgriddler", "Tile Grid", "平铺网格"),
+ ("ec.distort.cclens", "Lens Distortion", "镜头畸变"),
+ ("ec.distort.ccpageturn", "Page Curl", "页面卷曲"),
+ ("ec.distort.ccpowerpin", "Perspective Pin", "透视定位"),
+ ("ec.distort.ccripplepulse", "Pulsed Ripple", "脉冲涟漪"),
+ ("ec.distort.ccslant", "Slant", "倾斜"),
+ ("ec.distort.ccsmear", "Directional Smear", "定向涂抹"),
+ ("ec.distort.ccsplit", "Split Warp", "分割变形"),
+ ("ec.distort.ccsplit2", "Dual Split Warp", "双重分割变形"),
+ ("ec.distort.cctiler", "Scaled Tiles", "缩放平铺"),
("ec.distort.cornerpin", "Corner Pin", "边角定位"),
("ec.distort.displacementmap", "Displacement Map", "置换图"),
("ec.distort.liquify", "Liquify", "液化"),
@@ -311,11 +318,11 @@ const SIMPLIFIED_CHINESE: &[Row] = &[
("ec.generate.audiospectrum", "Audio Spectrum", "音频频谱"),
("ec.generate.audiowaveform", "Audio Waveform", "音频波形"),
("ec.generate.beam", "Beam", "光束"),
- ("ec.generate.ccgluegun", "CC Glue Gun", "CC 胶水枪"),
- ("ec.generate.cclightburst", "CC Light Burst 2.5", "CC 光束放射 2.5"),
- ("ec.generate.cclightrays", "CC Light Rays", "CC 光线"),
- ("ec.generate.cclightsweep", "CC Light Sweep", "CC 光线扫描"),
- ("ec.generate.ccthreads", "CC Threads", "CC 编织条"),
+ ("ec.generate.ccgluegun", "Paint Beads", "颜料珠"),
+ ("ec.generate.cclightburst", "Radial Light Burst", "径向光芒"),
+ ("ec.generate.cclightrays", "Light Rays", "光线"),
+ ("ec.generate.cclightsweep", "Light Sweep", "扫光"),
+ ("ec.generate.ccthreads", "Woven Threads", "编织线"),
("ec.generate.cellpattern", "Cell Pattern", "单元格图案"),
("ec.generate.checkerboard", "Checkerboard", "棋盘"),
("ec.generate.circle", "Circle", "圆形"),
@@ -334,7 +341,7 @@ const SIMPLIFIED_CHINESE: &[Row] = &[
("ec.generate.vegas", "Vegas", "勾画"),
("ec.generate.writeon", "Write-on", "写入"),
("ec.key.advancedspill", "Advanced Spill Suppressor", "高级溢出抑制器"),
- ("ec.key.ccsimplewireremoval", "CC Simple Wire Removal", "CC 简单丝线移除"),
+ ("ec.key.ccsimplewireremoval", "Line Removal", "线条移除"),
("ec.key.colordifference", "Color Difference Key", "颜色差值键"),
("ec.key.colorkey", "Color Key", "颜色键"),
("ec.key.colorrange", "Color Range", "颜色范围"),
@@ -347,7 +354,7 @@ const SIMPLIFIED_CHINESE: &[Row] = &[
("ec.key.screen", "Screen Key", "屏幕键"),
("ec.key.spill", "Spill Suppressor", "溢出抑制"),
("ec.key.unmult", "Unmult", "Unmult"),
- ("ec.keying.keylight", "Key Light", "Key Light"),
+ ("ec.keying.keylight", "Screen Color Key", "屏幕色键"),
("ec.matte.mattechoker", "Matte Choker", "遮罩阻塞工具"),
("ec.matte.objectmatte", "Object Matte", "对象遮罩"),
("ec.matte.refinehard", "Refine Hard Matte", "调整实边遮罩"),
@@ -371,50 +378,50 @@ const SIMPLIFIED_CHINESE: &[Row] = &[
("ec.obsolete.basictext", "Basic Text", "基本文字"),
("ec.obsolete.gaussianlegacy", "Gaussian Blur (Legacy)", "高斯模糊 (旧版)"),
("ec.obsolete.lightning", "Lightning", "闪电"),
- ("ec.obsolete.mochashape", "Mocha shape", "Mocha 形状"),
+ ("ec.obsolete.mochashape", "Tracked Shape Matte", "跟踪形状遮罩"),
("ec.obsolete.pathtext", "Path Text", "路径文本"),
("ec.paint.paint", "Paint", "绘画"),
("ec.perspective.3dglasses", "3D Glasses", "3D 眼镜"),
("ec.perspective.bevelalpha", "Bevel Alpha", "斜面 Alpha"),
("ec.perspective.beveledges", "Bevel Edges", "边缘斜面"),
("ec.perspective.cameratracker", "3D Camera Tracker", "3D 摄像机跟踪器"),
- ("ec.perspective.cccylinder", "CC Cylinder", "CC 圆柱体"),
- ("ec.perspective.ccenvironment", "CC Environment", "CC 环境"),
- ("ec.perspective.ccsphere", "CC Sphere", "CC 球体"),
- ("ec.perspective.ccspotlight", "CC Spotlight", "CC 聚光"),
+ ("ec.perspective.cccylinder", "Cylinder Wrap", "圆柱包裹"),
+ ("ec.perspective.ccenvironment", "Environment Map", "环境映射"),
+ ("ec.perspective.ccsphere", "Sphere Wrap", "球面包裹"),
+ ("ec.perspective.ccspotlight", "Surface Spotlight", "表面聚光灯"),
("ec.perspective.dropshadow", "Drop Shadow", "投影"),
("ec.perspective.radialshadow", "Radial Shadow", "径向阴影"),
("ec.sim.carddance", "Card Dance", "卡片动画"),
("ec.sim.caustics", "Caustics", "焦散"),
- ("ec.sim.ccballaction", "CC Ball Action", "CC 球动作"),
- ("ec.sim.ccbubbles", "CC Bubbles", "CC 气泡"),
- ("ec.sim.ccdrizzle", "CC Drizzle", "CC 细雨波纹"),
- ("ec.sim.cchair", "CC Hair", "CC 毛发"),
- ("ec.sim.ccmrmercury", "CC Mr. Mercury", "CC 水银流体"),
- ("ec.sim.ccparticlesystems2", "CC Particle Systems II", "CC 粒子系统 II"),
- ("ec.sim.ccparticleworld", "CC Particle World", "CC 粒子世界"),
- ("ec.sim.ccpixelpolly", "CC Pixel Polly", "CC 像素多边形"),
- ("ec.sim.ccrainfall", "CC Rainfall", "CC 降雨"),
- ("ec.sim.ccscatterize", "CC Scatterize", "CC 散射"),
- ("ec.sim.ccsnowfall", "CC Snowfall", "CC 降雪"),
- ("ec.sim.ccstarburst", "CC Star Burst", "CC 星爆"),
+ ("ec.sim.ccballaction", "Ball Grid", "球体网格"),
+ ("ec.sim.ccbubbles", "Bubbles", "气泡"),
+ ("ec.sim.ccdrizzle", "Water Ripples", "水面涟漪"),
+ ("ec.sim.cchair", "Surface Fibers", "表面纤维"),
+ ("ec.sim.ccmrmercury", "Liquid Particles", "液体粒子"),
+ ("ec.sim.ccparticlesystems2", "Particle Emitter 2D", "二维粒子发射器"),
+ ("ec.sim.ccparticleworld", "Particle Emitter 3D", "三维粒子发射器"),
+ ("ec.sim.ccpixelpolly", "Pixel Shatter", "像素破碎"),
+ ("ec.sim.ccrainfall", "Rainfall", "降雨"),
+ ("ec.sim.ccscatterize", "Pixel Scatter", "像素散射"),
+ ("ec.sim.ccsnowfall", "Snowfall", "降雪"),
+ ("ec.sim.ccstarburst", "Starfield", "星空"),
("ec.sim.foam", "Foam", "泡沫"),
("ec.sim.particleplayground", "Particle Playground", "粒子运动场"),
("ec.sim.shatter", "Shatter", "碎片"),
("ec.sim.waveworld", "Wave World", "波形环境"),
("ec.stylize.brushstrokes", "Brush Strokes", "画笔描边"),
("ec.stylize.cartoon", "Cartoon", "卡通"),
- ("ec.stylize.ccblockload", "CC Block Load", "CC 块加载"),
- ("ec.stylize.ccburnfilm", "CC Burn Film", "CC 烧毁胶片"),
- ("ec.stylize.ccglass", "CC Glass", "CC 玻璃"),
- ("ec.stylize.cchextile", "CC HexTile", "CC 六边形拼贴"),
- ("ec.stylize.cckaleida", "CC Kaleida", "CC 万花筒"),
- ("ec.stylize.ccmrsmoothie", "CC Mr. Smoothie", "CC 像素溶解"),
- ("ec.stylize.ccplastic", "CC Plastic", "CC 塑料"),
- ("ec.stylize.ccrepetile", "CC RepeTile", "CC 重复拼贴"),
- ("ec.stylize.ccthreshold", "CC Threshold", "CC 阈值"),
- ("ec.stylize.ccthresholdrgb", "CC Threshold RGB", "CC 阈值 RGB"),
- ("ec.stylize.ccvignette", "CC Vignette", "CC 暗角"),
+ ("ec.stylize.ccblockload", "Block Reveal", "块状显现"),
+ ("ec.stylize.ccburnfilm", "Film Burn", "胶片灼烧"),
+ ("ec.stylize.ccglass", "Glass Relief", "玻璃浮雕"),
+ ("ec.stylize.cchextile", "Hexagonal Tiles", "六边形平铺"),
+ ("ec.stylize.cckaleida", "Kaleidoscope", "万花筒"),
+ ("ec.stylize.ccmrsmoothie", "Palette Map", "调色板映射"),
+ ("ec.stylize.ccplastic", "Plastic Shading", "塑料着色"),
+ ("ec.stylize.ccrepetile", "Edge Tile Repeat", "边缘平铺重复"),
+ ("ec.stylize.ccthreshold", "Channel Threshold", "通道阈值"),
+ ("ec.stylize.ccthresholdrgb", "RGB Threshold", "RGB 阈值"),
+ ("ec.stylize.ccvignette", "Vignette", "晕影"),
("ec.stylize.coloremboss", "Color Emboss", "彩色浮雕"),
("ec.stylize.emboss", "Emboss", "浮雕"),
("ec.stylize.findedges", "Find Edges", "查找边缘"),
@@ -429,8 +436,8 @@ const SIMPLIFIED_CHINESE: &[Row] = &[
("ec.stylize.threshold", "Threshold", "阈值"),
("ec.text.numbers", "Numbers", "编号"),
("ec.text.timecode", "Timecode", "时间码"),
- ("ec.time.ccforcemotionblur", "CC Force Motion Blur", "CC 强制运动模糊"),
- ("ec.time.ccwidetime", "CC Wide Time", "CC 宽泛时间"),
+ ("ec.time.ccforcemotionblur", "Temporal Motion Blur", "时间运动模糊"),
+ ("ec.time.ccwidetime", "Temporal Blend", "时间混合"),
("ec.time.echo", "Echo", "残影"),
("ec.time.pixelmotionblur", "Pixel Motion Blur", "像素运动模糊"),
("ec.time.posterizetime", "Posterize Time", "抽帧"),
@@ -439,23 +446,23 @@ const SIMPLIFIED_CHINESE: &[Row] = &[
("ec.time.timewarp", "Timewarp", "时间扭曲"),
("ec.transition.blockdissolve", "Block Dissolve", "块溶解"),
("ec.transition.cardwipe", "Card Wipe", "卡片擦除"),
- ("ec.transition.ccglasswipe", "CC Glass Wipe", "CC 玻璃擦除"),
- ("ec.transition.ccgridwipe", "CC Grid Wipe", "CC 网格擦除"),
- ("ec.transition.ccimagewipe", "CC Image Wipe", "CC 图像擦除"),
- ("ec.transition.ccjaws", "CC Jaws", "CC 锯齿"),
- ("ec.transition.cclightwipe", "CC Light Wipe", "CC 光线擦除"),
- ("ec.transition.cclinesweep", "CC Line Sweep", "CC 线条扫掠"),
- ("ec.transition.ccradialscalewipe", "CC Radial ScaleWipe", "CC 径向缩放擦除"),
- ("ec.transition.ccscalewipe", "CC Scale Wipe", "CC 缩放擦除"),
- ("ec.transition.cctwister", "CC Twister", "CC 扭曲器"),
- ("ec.transition.ccwarpomatic", "CC WarpoMatic", "CC 自动扭曲"),
+ ("ec.transition.ccglasswipe", "Glass Wipe", "玻璃擦除"),
+ ("ec.transition.ccgridwipe", "Grid Wipe", "网格擦除"),
+ ("ec.transition.ccimagewipe", "Luminance Image Wipe", "亮度图像擦除"),
+ ("ec.transition.ccjaws", "Serrated Wipe", "锯齿擦除"),
+ ("ec.transition.cclightwipe", "Light Wipe", "光线擦除"),
+ ("ec.transition.cclinesweep", "Line Sweep", "线条扫过"),
+ ("ec.transition.ccradialscalewipe", "Radial Scale Wipe", "径向缩放擦除"),
+ ("ec.transition.ccscalewipe", "Scale Wipe", "缩放擦除"),
+ ("ec.transition.cctwister", "Twist Wipe", "扭转擦除"),
+ ("ec.transition.ccwarpomatic", "Warp Dissolve", "变形溶解"),
("ec.transition.gradientwipe", "Gradient Wipe", "渐变擦除"),
("ec.transition.iriswipe", "Iris Wipe", "光圈擦除"),
("ec.transition.linearwipe", "Linear Wipe", "线性擦除"),
("ec.transition.radialwipe", "Radial Wipe", "径向擦除"),
("ec.transition.venetian", "Venetian Blinds", "百叶窗"),
("ec.utility.applylut", "Apply Color LUT", "应用颜色 LUT"),
- ("ec.utility.ccoverbrights", "CC Overbrights", "CC 高光溢出"),
+ ("ec.utility.ccoverbrights", "Out-of-Range Display", "超出范围显示"),
("ec.utility.cineon", "Cineon Converter", "Cineon 转换器"),
("ec.utility.colorprofileconverter", "Color Profile Converter", "颜色配置文件转换器"),
("ec.utility.facemeasurements", "Face Measurements", "面部测量"),
@@ -480,9 +487,9 @@ const SIMPLIFIED_CHINESE: &[Row] = &[
/// [`SIMPLIFIED_CHINESE`]. Written from the meaning of the English names with the vocabulary
/// Taiwan's creative software uses (圖層, 遮罩, 筆刷, 雜訊, 發光, 漸層), not converted from the
/// Simplified table. Brand and coined names (`Cryptomatte`, `EXtractoR`, `IDentifier`, `Key Light`,
-/// `Unmult`, `Lumetri Color`, `Colorama`, `Minimax`, `Vegas`, `Mocha`) stay in English; the `CC`
-/// series keeps its prefix and translates the descriptive tail, and the `VR` and `OCIO` sets keep
-/// their prefix in Chinese word order.
+/// `Unmult`, `Colorama`, `Minimax`, `Vegas`) stay in English; the `VR` and `OCIO` sets keep their
+/// prefix in Chinese word order. The effects this cleanup renamed are translated from their new
+/// descriptive names.
const TRADITIONAL_CHINESE: &[Row] = &[
("ec.3d.channelextract", "3D Channel Extract", "3D 通道擷取"),
("ec.3d.cryptomatte", "Cryptomatte", "Cryptomatte"),
@@ -509,10 +516,10 @@ const TRADITIONAL_CHINESE: &[Row] = &[
("ec.blur.bilateral", "Bilateral Blur", "雙邊模糊"),
("ec.blur.cameralens", "Camera Lens Blur", "相機鏡頭模糊"),
("ec.blur.camerashakedeblur", "Camera-Shake Deblur", "相機晃動去模糊"),
- ("ec.blur.cccross", "CC Cross Blur", "CC 十字模糊"),
- ("ec.blur.ccradial", "CC Radial Blur", "CC 徑向模糊"),
- ("ec.blur.ccradialfast", "CC Radial Fast Blur", "CC 徑向快速模糊"),
- ("ec.blur.ccvector", "CC Vector Blur", "CC 向量模糊"),
+ ("ec.blur.cccross", "Cross Blur", "十字模糊"),
+ ("ec.blur.ccradial", "Variable Radial Blur", "可變放射狀模糊"),
+ ("ec.blur.ccradialfast", "Fast Radial Blur", "快速放射狀模糊"),
+ ("ec.blur.ccvector", "Vector Blur", "向量模糊"),
("ec.blur.channel", "Channel Blur", "通道模糊"),
("ec.blur.compound", "Compound Blur", "複合模糊"),
("ec.blur.directional", "Directional Blur", "方向模糊"),
@@ -526,7 +533,7 @@ const TRADITIONAL_CHINESE: &[Row] = &[
("ec.channel.arithmetic", "Arithmetic", "算術"),
("ec.channel.blend", "Blend", "混合"),
("ec.channel.calculations", "Calculations", "運算"),
- ("ec.channel.cccomposite", "CC Composite", "CC 合成"),
+ ("ec.channel.cccomposite", "Source Composite", "來源影像合成"),
("ec.channel.combiner", "Channel Combiner", "通道合成器"),
("ec.channel.compoundarithmetic", "Compound Arithmetic", "複合算術"),
("ec.channel.invert", "Invert", "反轉"),
@@ -542,10 +549,10 @@ const TRADITIONAL_CHINESE: &[Row] = &[
("ec.color.blackwhite", "Black & White", "黑白"),
("ec.color.brightnesscontrast", "Brightness & Contrast", "亮度與對比"),
("ec.color.broadcast", "Broadcast Colors", "廣播色彩"),
- ("ec.color.cccolorneutralizer", "CC Color Neutralizer", "CC 色彩中和器"),
- ("ec.color.cccoloroffset", "CC Color Offset", "CC 色彩偏移"),
- ("ec.color.cckernel", "CC Kernel", "CC 核心"),
- ("ec.color.cctoner", "CC Toner", "CC 色調"),
+ ("ec.color.cccolorneutralizer", "Color Neutralizer", "色偏校正"),
+ ("ec.color.cccoloroffset", "Channel Offset", "色版偏移"),
+ ("ec.color.cckernel", "Convolution Kernel", "卷積核心"),
+ ("ec.color.cctoner", "Multi-Tone Tint", "多色調著色"),
("ec.color.changecolor", "Change Color", "變更色彩"),
("ec.color.changetocolor", "Change to Color", "變更為色彩"),
("ec.color.channelmixer", "Channel Mixer", "通道混合器"),
@@ -562,7 +569,7 @@ const TRADITIONAL_CHINESE: &[Row] = &[
("ec.color.leavecolor", "Leave Color", "保留色彩"),
("ec.color.levels", "Levels", "色階"),
("ec.color.levelsic", "Levels (Individual Controls)", "色階(個別控制項)"),
- ("ec.color.lumetri", "Lumetri Color", "Lumetri Color"),
+ ("ec.color.lumetri", "Color Grading", "色彩分級"),
("ec.color.ociocdl", "OCIO CDL Transform", "OCIO CDL 轉換"),
("ec.color.ociocolorspace", "OCIO Color Space Transform", "OCIO 色彩空間轉換"),
("ec.color.ociodisplay", "OCIO Display Transform", "OCIO 顯示轉換"),
@@ -587,20 +594,20 @@ const TRADITIONAL_CHINESE: &[Row] = &[
("ec.control.stereo3d", "Stereo 3D Controls", "立體 3D 控制"),
("ec.distort.bezierwarp", "Bezier Warp", "貝茲彎曲"),
("ec.distort.bulge", "Bulge", "凸出"),
- ("ec.distort.ccbender", "CC Bender", "CC 彎曲"),
- ("ec.distort.ccbendit", "CC Bend It", "CC 彎折"),
- ("ec.distort.ccblobbylize", "CC Blobbylize", "CC 團塊化"),
- ("ec.distort.ccflomotion", "CC Flo Motion", "CC 流動"),
- ("ec.distort.ccgriddler", "CC Griddler", "CC 格線"),
- ("ec.distort.cclens", "CC Lens", "CC 鏡頭"),
- ("ec.distort.ccpageturn", "CC Page Turn", "CC 翻頁"),
- ("ec.distort.ccpowerpin", "CC Power Pin", "CC 強力釘選"),
- ("ec.distort.ccripplepulse", "CC Ripple Pulse", "CC 漣漪脈衝"),
- ("ec.distort.ccslant", "CC Slant", "CC 傾斜"),
- ("ec.distort.ccsmear", "CC Smear", "CC 塗抹"),
- ("ec.distort.ccsplit", "CC Split", "CC 分割"),
- ("ec.distort.ccsplit2", "CC Split 2", "CC 分割 2"),
- ("ec.distort.cctiler", "CC Tiler", "CC 並排"),
+ ("ec.distort.ccbender", "Flexible Bend", "柔性彎曲"),
+ ("ec.distort.ccbendit", "Two-Point Bend", "兩點彎曲"),
+ ("ec.distort.ccblobbylize", "Organic Displacement", "有機置換"),
+ ("ec.distort.ccflomotion", "Dual Lens Warp", "雙鏡頭變形"),
+ ("ec.distort.ccgriddler", "Tile Grid", "拼貼網格"),
+ ("ec.distort.cclens", "Lens Distortion", "鏡頭畸變"),
+ ("ec.distort.ccpageturn", "Page Curl", "頁面捲曲"),
+ ("ec.distort.ccpowerpin", "Perspective Pin", "透視定位"),
+ ("ec.distort.ccripplepulse", "Pulsed Ripple", "脈衝漣漪"),
+ ("ec.distort.ccslant", "Slant", "傾斜"),
+ ("ec.distort.ccsmear", "Directional Smear", "定向塗抹"),
+ ("ec.distort.ccsplit", "Split Warp", "分割變形"),
+ ("ec.distort.ccsplit2", "Dual Split Warp", "雙重分割變形"),
+ ("ec.distort.cctiler", "Scaled Tiles", "縮放平鋪"),
("ec.distort.cornerpin", "Corner Pin", "邊角釘選"),
("ec.distort.displacementmap", "Displacement Map", "位移映射"),
("ec.distort.liquify", "Liquify", "液化"),
@@ -628,11 +635,11 @@ const TRADITIONAL_CHINESE: &[Row] = &[
("ec.generate.audiospectrum", "Audio Spectrum", "音訊頻譜"),
("ec.generate.audiowaveform", "Audio Waveform", "音訊波形"),
("ec.generate.beam", "Beam", "光束"),
- ("ec.generate.ccgluegun", "CC Glue Gun", "CC 膠水槍"),
- ("ec.generate.cclightburst", "CC Light Burst 2.5", "CC 光爆 2.5"),
- ("ec.generate.cclightrays", "CC Light Rays", "CC 光線"),
- ("ec.generate.cclightsweep", "CC Light Sweep", "CC 光線掃掠"),
- ("ec.generate.ccthreads", "CC Threads", "CC 絲線"),
+ ("ec.generate.ccgluegun", "Paint Beads", "顏料珠"),
+ ("ec.generate.cclightburst", "Radial Light Burst", "放射狀光芒"),
+ ("ec.generate.cclightrays", "Light Rays", "光線"),
+ ("ec.generate.cclightsweep", "Light Sweep", "掃光"),
+ ("ec.generate.ccthreads", "Woven Threads", "編織線"),
("ec.generate.cellpattern", "Cell Pattern", "細胞圖樣"),
("ec.generate.checkerboard", "Checkerboard", "棋盤格"),
("ec.generate.circle", "Circle", "圓形"),
@@ -651,7 +658,7 @@ const TRADITIONAL_CHINESE: &[Row] = &[
("ec.generate.vegas", "Vegas", "Vegas"),
("ec.generate.writeon", "Write-on", "書寫"),
("ec.key.advancedspill", "Advanced Spill Suppressor", "進階溢色抑制"),
- ("ec.key.ccsimplewireremoval", "CC Simple Wire Removal", "CC 簡易鋼絲移除"),
+ ("ec.key.ccsimplewireremoval", "Line Removal", "線條移除"),
("ec.key.colordifference", "Color Difference Key", "色彩差異去背"),
("ec.key.colorkey", "Color Key", "色彩去背"),
("ec.key.colorrange", "Color Range", "色彩範圍"),
@@ -664,7 +671,7 @@ const TRADITIONAL_CHINESE: &[Row] = &[
("ec.key.screen", "Screen Key", "螢幕去背"),
("ec.key.spill", "Spill Suppressor", "溢色抑制"),
("ec.key.unmult", "Unmult", "Unmult"),
- ("ec.keying.keylight", "Key Light", "Key Light"),
+ ("ec.keying.keylight", "Screen Color Key", "螢幕色鍵"),
("ec.matte.mattechoker", "Matte Choker", "遮罩收縮器"),
("ec.matte.objectmatte", "Object Matte", "物件遮罩"),
("ec.matte.refinehard", "Refine Hard Matte", "調整硬邊遮罩"),
@@ -688,50 +695,50 @@ const TRADITIONAL_CHINESE: &[Row] = &[
("ec.obsolete.basictext", "Basic Text", "基礎文字"),
("ec.obsolete.gaussianlegacy", "Gaussian Blur (Legacy)", "高斯模糊(舊版)"),
("ec.obsolete.lightning", "Lightning", "閃電"),
- ("ec.obsolete.mochashape", "Mocha shape", "Mocha 形狀"),
+ ("ec.obsolete.mochashape", "Tracked Shape Matte", "追蹤形狀遮罩"),
("ec.obsolete.pathtext", "Path Text", "路徑文字"),
("ec.paint.paint", "Paint", "繪畫"),
("ec.perspective.3dglasses", "3D Glasses", "3D 眼鏡"),
("ec.perspective.bevelalpha", "Bevel Alpha", "Alpha 斜角"),
("ec.perspective.beveledges", "Bevel Edges", "邊緣斜角"),
("ec.perspective.cameratracker", "3D Camera Tracker", "3D 攝影機追蹤"),
- ("ec.perspective.cccylinder", "CC Cylinder", "CC 圓柱"),
- ("ec.perspective.ccenvironment", "CC Environment", "CC 環境"),
- ("ec.perspective.ccsphere", "CC Sphere", "CC 球體"),
- ("ec.perspective.ccspotlight", "CC Spotlight", "CC 聚光燈"),
+ ("ec.perspective.cccylinder", "Cylinder Wrap", "圓柱包覆"),
+ ("ec.perspective.ccenvironment", "Environment Map", "環境貼圖"),
+ ("ec.perspective.ccsphere", "Sphere Wrap", "球面包覆"),
+ ("ec.perspective.ccspotlight", "Surface Spotlight", "表面聚光燈"),
("ec.perspective.dropshadow", "Drop Shadow", "陰影"),
("ec.perspective.radialshadow", "Radial Shadow", "徑向陰影"),
("ec.sim.carddance", "Card Dance", "卡片舞蹈"),
("ec.sim.caustics", "Caustics", "焦散"),
- ("ec.sim.ccballaction", "CC Ball Action", "CC 球狀動作"),
- ("ec.sim.ccbubbles", "CC Bubbles", "CC 泡泡"),
- ("ec.sim.ccdrizzle", "CC Drizzle", "CC 細雨"),
- ("ec.sim.cchair", "CC Hair", "CC 毛髮"),
- ("ec.sim.ccmrmercury", "CC Mr. Mercury", "CC 水銀先生"),
- ("ec.sim.ccparticlesystems2", "CC Particle Systems II", "CC 粒子系統 II"),
- ("ec.sim.ccparticleworld", "CC Particle World", "CC 粒子世界"),
- ("ec.sim.ccpixelpolly", "CC Pixel Polly", "CC 像素破碎"),
- ("ec.sim.ccrainfall", "CC Rainfall", "CC 下雨"),
- ("ec.sim.ccscatterize", "CC Scatterize", "CC 散開"),
- ("ec.sim.ccsnowfall", "CC Snowfall", "CC 下雪"),
- ("ec.sim.ccstarburst", "CC Star Burst", "CC 星爆"),
+ ("ec.sim.ccballaction", "Ball Grid", "球體網格"),
+ ("ec.sim.ccbubbles", "Bubbles", "氣泡"),
+ ("ec.sim.ccdrizzle", "Water Ripples", "水面漣漪"),
+ ("ec.sim.cchair", "Surface Fibers", "表面纖維"),
+ ("ec.sim.ccmrmercury", "Liquid Particles", "液體粒子"),
+ ("ec.sim.ccparticlesystems2", "Particle Emitter 2D", "二維粒子發射器"),
+ ("ec.sim.ccparticleworld", "Particle Emitter 3D", "三維粒子發射器"),
+ ("ec.sim.ccpixelpolly", "Pixel Shatter", "像素破碎"),
+ ("ec.sim.ccrainfall", "Rainfall", "降雨"),
+ ("ec.sim.ccscatterize", "Pixel Scatter", "像素散射"),
+ ("ec.sim.ccsnowfall", "Snowfall", "降雪"),
+ ("ec.sim.ccstarburst", "Starfield", "星空"),
("ec.sim.foam", "Foam", "泡沫"),
("ec.sim.particleplayground", "Particle Playground", "粒子遊樂場"),
("ec.sim.shatter", "Shatter", "粉碎"),
("ec.sim.waveworld", "Wave World", "波浪世界"),
("ec.stylize.brushstrokes", "Brush Strokes", "筆觸"),
("ec.stylize.cartoon", "Cartoon", "卡通"),
- ("ec.stylize.ccblockload", "CC Block Load", "CC 區塊載入"),
- ("ec.stylize.ccburnfilm", "CC Burn Film", "CC 燒灼底片"),
- ("ec.stylize.ccglass", "CC Glass", "CC 玻璃"),
- ("ec.stylize.cchextile", "CC HexTile", "CC 六角並排"),
- ("ec.stylize.cckaleida", "CC Kaleida", "CC 萬花筒"),
- ("ec.stylize.ccmrsmoothie", "CC Mr. Smoothie", "CC 平滑先生"),
- ("ec.stylize.ccplastic", "CC Plastic", "CC 塑膠"),
- ("ec.stylize.ccrepetile", "CC RepeTile", "CC 重複並排"),
- ("ec.stylize.ccthreshold", "CC Threshold", "CC 臨界值"),
- ("ec.stylize.ccthresholdrgb", "CC Threshold RGB", "CC 臨界值 RGB"),
- ("ec.stylize.ccvignette", "CC Vignette", "CC 暗角"),
+ ("ec.stylize.ccblockload", "Block Reveal", "區塊顯現"),
+ ("ec.stylize.ccburnfilm", "Film Burn", "膠片灼燒"),
+ ("ec.stylize.ccglass", "Glass Relief", "玻璃浮雕"),
+ ("ec.stylize.cchextile", "Hexagonal Tiles", "六角形拼貼"),
+ ("ec.stylize.cckaleida", "Kaleidoscope", "萬花筒"),
+ ("ec.stylize.ccmrsmoothie", "Palette Map", "調色盤對應"),
+ ("ec.stylize.ccplastic", "Plastic Shading", "塑膠著色"),
+ ("ec.stylize.ccrepetile", "Edge Tile Repeat", "邊緣拼貼重複"),
+ ("ec.stylize.ccthreshold", "Channel Threshold", "色版臨界值"),
+ ("ec.stylize.ccthresholdrgb", "RGB Threshold", "RGB 臨界值"),
+ ("ec.stylize.ccvignette", "Vignette", "暗角"),
("ec.stylize.coloremboss", "Color Emboss", "彩色浮雕"),
("ec.stylize.emboss", "Emboss", "浮雕"),
("ec.stylize.findedges", "Find Edges", "尋找邊緣"),
@@ -746,8 +753,8 @@ const TRADITIONAL_CHINESE: &[Row] = &[
("ec.stylize.threshold", "Threshold", "臨界值"),
("ec.text.numbers", "Numbers", "數字"),
("ec.text.timecode", "Timecode", "時間碼"),
- ("ec.time.ccforcemotionblur", "CC Force Motion Blur", "CC 強制動態模糊"),
- ("ec.time.ccwidetime", "CC Wide Time", "CC 寬廣時間"),
+ ("ec.time.ccforcemotionblur", "Temporal Motion Blur", "時間動態模糊"),
+ ("ec.time.ccwidetime", "Temporal Blend", "時間混合"),
("ec.time.echo", "Echo", "回音"),
("ec.time.pixelmotionblur", "Pixel Motion Blur", "像素動態模糊"),
("ec.time.posterizetime", "Posterize Time", "色調分離時間"),
@@ -756,23 +763,23 @@ const TRADITIONAL_CHINESE: &[Row] = &[
("ec.time.timewarp", "Timewarp", "時間扭曲"),
("ec.transition.blockdissolve", "Block Dissolve", "區塊溶解"),
("ec.transition.cardwipe", "Card Wipe", "卡片擦拭"),
- ("ec.transition.ccglasswipe", "CC Glass Wipe", "CC 玻璃擦拭"),
- ("ec.transition.ccgridwipe", "CC Grid Wipe", "CC 格線擦拭"),
- ("ec.transition.ccimagewipe", "CC Image Wipe", "CC 影像擦拭"),
- ("ec.transition.ccjaws", "CC Jaws", "CC 巨顎"),
- ("ec.transition.cclightwipe", "CC Light Wipe", "CC 光線擦拭"),
- ("ec.transition.cclinesweep", "CC Line Sweep", "CC 線條掃掠"),
- ("ec.transition.ccradialscalewipe", "CC Radial ScaleWipe", "CC 徑向縮放擦拭"),
- ("ec.transition.ccscalewipe", "CC Scale Wipe", "CC 縮放擦拭"),
- ("ec.transition.cctwister", "CC Twister", "CC 扭轉"),
- ("ec.transition.ccwarpomatic", "CC WarpoMatic", "CC 自動彎曲"),
+ ("ec.transition.ccglasswipe", "Glass Wipe", "玻璃擦拭"),
+ ("ec.transition.ccgridwipe", "Grid Wipe", "網格擦拭"),
+ ("ec.transition.ccimagewipe", "Luminance Image Wipe", "亮度影像擦拭"),
+ ("ec.transition.ccjaws", "Serrated Wipe", "鋸齒擦拭"),
+ ("ec.transition.cclightwipe", "Light Wipe", "光線擦拭"),
+ ("ec.transition.cclinesweep", "Line Sweep", "線條掃過"),
+ ("ec.transition.ccradialscalewipe", "Radial Scale Wipe", "放射狀縮放擦拭"),
+ ("ec.transition.ccscalewipe", "Scale Wipe", "縮放擦拭"),
+ ("ec.transition.cctwister", "Twist Wipe", "扭轉擦拭"),
+ ("ec.transition.ccwarpomatic", "Warp Dissolve", "變形溶解"),
("ec.transition.gradientwipe", "Gradient Wipe", "漸層擦拭"),
("ec.transition.iriswipe", "Iris Wipe", "光圈擦拭"),
("ec.transition.linearwipe", "Linear Wipe", "線性擦拭"),
("ec.transition.radialwipe", "Radial Wipe", "徑向擦拭"),
("ec.transition.venetian", "Venetian Blinds", "百葉窗"),
("ec.utility.applylut", "Apply Color LUT", "套用色彩 LUT"),
- ("ec.utility.ccoverbrights", "CC Overbrights", "CC 過亮"),
+ ("ec.utility.ccoverbrights", "Out-of-Range Display", "超出範圍顯示"),
("ec.utility.cineon", "Cineon Converter", "Cineon 轉換器"),
("ec.utility.colorprofileconverter", "Color Profile Converter", "色彩設定檔轉換器"),
("ec.utility.facemeasurements", "Face Measurements", "臉部測量"),
@@ -796,18 +803,18 @@ const TRADITIONAL_CHINESE: &[Row] = &[
/// Japanese (`ja`): reserved for the Japanese data point on #821, so both languages share this
/// one catalog instead of inventing a second mechanism. A translator fills one row per effect,
-/// ids from [`SIMPLIFIED_CHINESE`]; the names Adobe's Japanese interface leaves in English (the
-/// `CC` series, `Cryptomatte`, `EXtractoR`, `IDentifier` and `Key Light`) repeat that English name
-/// here rather than being left out; the `VR` and `OCIO` sets take a Japanese tail instead, and
-/// `Unmult` keeps its English name in both catalogs. An effect with no row draws its English name
-/// anyway, which is what `Twirl (Legacy)` and the two EffectCraft-only effects would do without
-/// their rows.
+/// ids from [`SIMPLIFIED_CHINESE`]; the names Adobe's Japanese interface leaves in English
+/// (`Cryptomatte`, `EXtractoR`, `IDentifier` and `Key Light`) repeat that English name here rather
+/// than being left out; the `VR` and `OCIO` sets take a Japanese tail instead, and `Unmult` keeps
+/// its English name in both catalogs. An effect with no row draws its English name anyway, which
+/// is what `Twirl (Legacy)` and the two EffectCraft-only effects would do without their rows.
///
-/// The rows below come from AE 2026's Japanese interface where it was read directly (its Effect menu
-/// and its Effects & Presets panel) and from Adobe's own Japanese help where the panel was not to
-/// hand. A published glossary is used to cross-check, never as the only source: it normalises the
-/// typography (half-width parentheses where AE draws full-width) and still carries CS6-era names for
-/// the `CC` series, which AE 2026 leaves in English.
+/// The rows of the effects this cleanup did not rename come from AE 2026's Japanese interface
+/// where it was read directly (its Effect menu and its Effects & Presets panel) and from Adobe's
+/// own Japanese help where the panel was not to hand. A published glossary is used to cross-check,
+/// never as the only source: it normalises the typography (half-width parentheses where AE draws
+/// full-width) and still carries CS6-era names for the `CC` series. The renamed effects are
+/// translated from their new descriptive names.
const JAPANESE_EFFECTS: &[Row] = &[
// Effects this application adds itself have no interface to read a name from, so they follow
// the Chinese catalog's choice to translate them (顔の測定, 顔のトラッキングポイント) rather than
@@ -847,10 +854,10 @@ const JAPANESE_EFFECTS: &[Row] = &[
("ec.blur.bilateral", "Bilateral Blur", "ブラー(バイラテラル)"),
("ec.blur.cameralens", "Camera Lens Blur", "ブラー(カメラレンズ)"),
("ec.blur.camerashakedeblur", "Camera-Shake Deblur", "カメラぶれ除去"),
- ("ec.blur.cccross", "CC Cross Blur", "CC Cross Blur"),
- ("ec.blur.ccradial", "CC Radial Blur", "CC Radial Blur"),
- ("ec.blur.ccradialfast", "CC Radial Fast Blur", "CC Radial Fast Blur"),
- ("ec.blur.ccvector", "CC Vector Blur", "CC Vector Blur"),
+ ("ec.blur.cccross", "Cross Blur", "十字ぼかし"),
+ ("ec.blur.ccradial", "Variable Radial Blur", "可変放射状ぼかし"),
+ ("ec.blur.ccradialfast", "Fast Radial Blur", "高速放射状ぼかし"),
+ ("ec.blur.ccvector", "Vector Blur", "ベクトルぼかし"),
("ec.blur.channel", "Channel Blur", "ブラー(チャンネル)"),
("ec.blur.compound", "Compound Blur", "ブラー(合成)"),
("ec.blur.directional", "Directional Blur", "ブラー(方向)"),
@@ -864,7 +871,7 @@ const JAPANESE_EFFECTS: &[Row] = &[
("ec.channel.arithmetic", "Arithmetic", "アリスマチック"),
("ec.channel.blend", "Blend", "ブレンド"),
("ec.channel.calculations", "Calculations", "計算"),
- ("ec.channel.cccomposite", "CC Composite", "CC Composite"),
+ ("ec.channel.cccomposite", "Source Composite", "元画像合成"),
("ec.channel.combiner", "Channel Combiner", "チャンネルコンバイナー"),
("ec.channel.compoundarithmetic", "Compound Arithmetic", "合成アリスマチック"),
("ec.channel.invert", "Invert", "反転"),
@@ -879,10 +886,10 @@ const JAPANESE_EFFECTS: &[Row] = &[
("ec.color.autolevels", "Auto Levels", "自動レベル補正"),
("ec.color.blackwhite", "Black & White", "白黒"),
("ec.color.brightnesscontrast", "Brightness & Contrast", "輝度&コントラスト"),
- ("ec.color.cccolorneutralizer", "CC Color Neutralizer", "CC Color Neutralizer"),
- ("ec.color.cccoloroffset", "CC Color Offset", "CC Color Offset"),
- ("ec.color.cckernel", "CC Kernel", "CC Kernel"),
- ("ec.color.cctoner", "CC Toner", "CC Toner"),
+ ("ec.color.cccolorneutralizer", "Color Neutralizer", "色かぶり補正"),
+ ("ec.color.cccoloroffset", "Channel Offset", "チャンネルオフセット"),
+ ("ec.color.cckernel", "Convolution Kernel", "畳み込みカーネル"),
+ ("ec.color.cctoner", "Multi-Tone Tint", "多色調ティント"),
("ec.color.changecolor", "Change Color", "色を変更"),
("ec.color.changetocolor", "Change to Color", "他のカラーへ変更"),
("ec.color.channelmixer", "Channel Mixer", "チャンネルミキサー"),
@@ -899,7 +906,7 @@ const JAPANESE_EFFECTS: &[Row] = &[
("ec.color.leavecolor", "Leave Color", "色抜き"),
("ec.color.levels", "Levels", "レベル補正"),
("ec.color.levelsic", "Levels (Individual Controls)", "レベル(個々の制御)"),
- ("ec.color.lumetri", "Lumetri Color", "Lumetri カラー"),
+ ("ec.color.lumetri", "Color Grading", "カラーグレーディング"),
("ec.color.ociocdl", "OCIO CDL Transform", "OCIO CDL 変換"),
("ec.color.ociocolorspace", "OCIO Color Space Transform", "OCIO 色空間変換"),
("ec.color.ociodisplay", "OCIO Display Transform", "OCIO 表示変換"),
@@ -909,7 +916,7 @@ const JAPANESE_EFFECTS: &[Row] = &[
("ec.color.psarbitrarymap", "PS Arbitrary Map", "PS不定マップ"),
("ec.color.selectivecolor", "Selective Color", "特定色域の選択"),
("ec.color.shadowhighlight", "Shadow/Highlight", "シャドウ・ハイライト"),
- ("ec.color.tint", "Tint", "色かぶり補正"),
+ ("ec.color.tint", "Tint", "着色"),
("ec.color.tritone", "Tritone", "トライトーン"),
("ec.color.vibrance", "Vibrance", "自然な彩度"),
("ec.color.videolimiter", "Video Limiter", "ビデオリミッター"),
@@ -923,20 +930,20 @@ const JAPANESE_EFFECTS: &[Row] = &[
("ec.control.slider", "Slider Control", "スライダー制御"),
("ec.distort.bezierwarp", "Bezier Warp", "ベジェワープ"),
("ec.distort.bulge", "Bulge", "バルジ"),
- ("ec.distort.ccbender", "CC Bender", "CC Bender"),
- ("ec.distort.ccbendit", "CC Bend It", "CC Bend It"),
- ("ec.distort.ccblobbylize", "CC Blobbylize", "CC Blobbylize"),
- ("ec.distort.ccflomotion", "CC Flo Motion", "CC Flo Motion"),
- ("ec.distort.ccgriddler", "CC Griddler", "CC Griddler"),
- ("ec.distort.cclens", "CC Lens", "CC Lens"),
- ("ec.distort.ccpageturn", "CC Page Turn", "CC Page Turn"),
- ("ec.distort.ccpowerpin", "CC Power Pin", "CC Power Pin"),
- ("ec.distort.ccripplepulse", "CC Ripple Pulse", "CC Ripple Pulse"),
- ("ec.distort.ccslant", "CC Slant", "CC Slant"),
- ("ec.distort.ccsmear", "CC Smear", "CC Smear"),
- ("ec.distort.ccsplit", "CC Split", "CC Split"),
- ("ec.distort.ccsplit2", "CC Split 2", "CC Split 2"),
- ("ec.distort.cctiler", "CC Tiler", "CC Tiler"),
+ ("ec.distort.ccbender", "Flexible Bend", "柔軟ベンド"),
+ ("ec.distort.ccbendit", "Two-Point Bend", "2点ベンド"),
+ ("ec.distort.ccblobbylize", "Organic Displacement", "有機変位"),
+ ("ec.distort.ccflomotion", "Dual Lens Warp", "ダブルレンズ変形"),
+ ("ec.distort.ccgriddler", "Tile Grid", "タイルグリッド"),
+ ("ec.distort.cclens", "Lens Distortion", "レンズ歪み"),
+ ("ec.distort.ccpageturn", "Page Curl", "ページカール"),
+ ("ec.distort.ccpowerpin", "Perspective Pin", "遠近ピン"),
+ ("ec.distort.ccripplepulse", "Pulsed Ripple", "パルス波紋"),
+ ("ec.distort.ccslant", "Slant", "傾斜"),
+ ("ec.distort.ccsmear", "Directional Smear", "方向性にじみ"),
+ ("ec.distort.ccsplit", "Split Warp", "分割変形"),
+ ("ec.distort.ccsplit2", "Dual Split Warp", "二重分割変形"),
+ ("ec.distort.cctiler", "Scaled Tiles", "スケールタイル"),
("ec.distort.cornerpin", "Corner Pin", "コーナーピン"),
("ec.distort.displacementmap", "Displacement Map", "ディスプレイスメントマップ"),
("ec.distort.liquify", "Liquify", "ゆがみ"),
@@ -963,11 +970,11 @@ const JAPANESE_EFFECTS: &[Row] = &[
("ec.generate.audiospectrum", "Audio Spectrum", "オーディオスペクトラム"),
("ec.generate.audiowaveform", "Audio Waveform", "オーディオウェーブフォーム"),
("ec.generate.beam", "Beam", "レーザー"),
- ("ec.generate.ccgluegun", "CC Glue Gun", "CC Glue Gun"),
- ("ec.generate.cclightburst", "CC Light Burst 2.5", "CC Light Burst 2.5"),
- ("ec.generate.cclightrays", "CC Light Rays", "CC Light Rays"),
- ("ec.generate.cclightsweep", "CC Light Sweep", "CC Light Sweep"),
- ("ec.generate.ccthreads", "CC Threads", "CC Threads"),
+ ("ec.generate.ccgluegun", "Paint Beads", "絵の具の粒"),
+ ("ec.generate.cclightburst", "Radial Light Burst", "放射状の光"),
+ ("ec.generate.cclightrays", "Light Rays", "光線"),
+ ("ec.generate.cclightsweep", "Light Sweep", "光のスイープ"),
+ ("ec.generate.ccthreads", "Woven Threads", "織り糸"),
("ec.generate.cellpattern", "Cell Pattern", "セルパターン"),
("ec.generate.checkerboard", "Checkerboard", "チェッカーボード"),
("ec.generate.circle", "Circle", "円"),
@@ -986,7 +993,7 @@ const JAPANESE_EFFECTS: &[Row] = &[
("ec.generate.vegas", "Vegas", "ベガス"),
("ec.generate.writeon", "Write-on", "ブラシアニメーション"),
("ec.key.advancedspill", "Advanced Spill Suppressor", "Advanced Spill Suppressor"),
- ("ec.key.ccsimplewireremoval", "CC Simple Wire Removal", "CC Simple Wire Removal"),
+ ("ec.key.ccsimplewireremoval", "Line Removal", "ライン除去"),
("ec.key.colordifference", "Color Difference Key", "カラー差キー"),
("ec.key.colorkey", "Color Key", "カラーキー"),
("ec.key.colorrange", "Color Range", "色範囲"),
@@ -997,7 +1004,7 @@ const JAPANESE_EFFECTS: &[Row] = &[
("ec.key.linearcolor", "Linear Color Key", "リニアカラーキー"),
("ec.key.luma", "Luma Key", "ルミナンスキー"),
("ec.key.spill", "Spill Suppressor", "スピルサプレッション"),
- ("ec.keying.keylight", "Key Light", "Keylight (1.2)"),
+ ("ec.keying.keylight", "Screen Color Key", "スクリーンカラーキー"),
("ec.matte.mattechoker", "Matte Choker", "マットチョーク"),
("ec.matte.refinehard", "Refine Hard Matte", "ハードマットを調整"),
("ec.matte.refinesoft", "Refine Soft Matte", "ソフトマットを調整"),
@@ -1019,49 +1026,49 @@ const JAPANESE_EFFECTS: &[Row] = &[
("ec.obsolete.basictext", "Basic Text", "基本テキスト"),
("ec.obsolete.gaussianlegacy", "Gaussian Blur (Legacy)", "ブラー(ガウス)(レガシー)"),
("ec.obsolete.lightning", "Lightning", "稲妻"),
- ("ec.obsolete.mochashape", "Mocha shape", "mocha shape"),
+ ("ec.obsolete.mochashape", "Tracked Shape Matte", "トラッキングシェイプマット"),
("ec.obsolete.pathtext", "Path Text", "パステキスト"),
("ec.perspective.3dglasses", "3D Glasses", "3Dメガネ"),
("ec.perspective.bevelalpha", "Bevel Alpha", "ベベルアルファ"),
("ec.perspective.beveledges", "Bevel Edges", "ベベルエッジ"),
("ec.perspective.cameratracker", "3D Camera Tracker", "3D カメラトラッカー"),
- ("ec.perspective.cccylinder", "CC Cylinder", "CC Cylinder"),
- ("ec.perspective.ccenvironment", "CC Environment", "CC Environment"),
- ("ec.perspective.ccsphere", "CC Sphere", "CC Sphere"),
- ("ec.perspective.ccspotlight", "CC Spotlight", "CC Spotlight"),
+ ("ec.perspective.cccylinder", "Cylinder Wrap", "円筒ラップ"),
+ ("ec.perspective.ccenvironment", "Environment Map", "環境マップ"),
+ ("ec.perspective.ccsphere", "Sphere Wrap", "球面ラップ"),
+ ("ec.perspective.ccspotlight", "Surface Spotlight", "表面スポットライト"),
("ec.perspective.dropshadow", "Drop Shadow", "ドロップシャドウ"),
("ec.perspective.radialshadow", "Radial Shadow", "放射状シャドウ"),
("ec.sim.carddance", "Card Dance", "カードダンス"),
("ec.sim.caustics", "Caustics", "コースティック"),
- ("ec.sim.ccballaction", "CC Ball Action", "CC Ball Action"),
- ("ec.sim.ccbubbles", "CC Bubbles", "CC Bubbles"),
- ("ec.sim.ccdrizzle", "CC Drizzle", "CC Drizzle"),
- ("ec.sim.cchair", "CC Hair", "CC Hair"),
- ("ec.sim.ccmrmercury", "CC Mr. Mercury", "CC Mr. Mercury"),
- ("ec.sim.ccparticlesystems2", "CC Particle Systems II", "CC Particle Systems II"),
- ("ec.sim.ccparticleworld", "CC Particle World", "CC Particle World"),
- ("ec.sim.ccpixelpolly", "CC Pixel Polly", "CC Pixel Polly"),
- ("ec.sim.ccrainfall", "CC Rainfall", "CC Rainfall"),
- ("ec.sim.ccscatterize", "CC Scatterize", "CC Scatterize"),
- ("ec.sim.ccsnowfall", "CC Snowfall", "CC Snowfall"),
- ("ec.sim.ccstarburst", "CC Star Burst", "CC Star Burst"),
+ ("ec.sim.ccballaction", "Ball Grid", "球体グリッド"),
+ ("ec.sim.ccbubbles", "Bubbles", "気泡"),
+ ("ec.sim.ccdrizzle", "Water Ripples", "水面の波紋"),
+ ("ec.sim.cchair", "Surface Fibers", "表面の繊維"),
+ ("ec.sim.ccmrmercury", "Liquid Particles", "液体パーティクル"),
+ ("ec.sim.ccparticlesystems2", "Particle Emitter 2D", "2Dパーティクルエミッター"),
+ ("ec.sim.ccparticleworld", "Particle Emitter 3D", "3Dパーティクルエミッター"),
+ ("ec.sim.ccpixelpolly", "Pixel Shatter", "ピクセル破砕"),
+ ("ec.sim.ccrainfall", "Rainfall", "雨"),
+ ("ec.sim.ccscatterize", "Pixel Scatter", "ピクセル散乱"),
+ ("ec.sim.ccsnowfall", "Snowfall", "雪"),
+ ("ec.sim.ccstarburst", "Starfield", "星空"),
("ec.sim.foam", "Foam", "泡"),
("ec.sim.particleplayground", "Particle Playground", "パーティクルプレイグラウンド"),
("ec.sim.shatter", "Shatter", "シャター"),
("ec.sim.waveworld", "Wave World", "ウェーブワールド"),
("ec.stylize.brushstrokes", "Brush Strokes", "ブラシストローク"),
("ec.stylize.cartoon", "Cartoon", "カートゥーン"),
- ("ec.stylize.ccblockload", "CC Block Load", "CC Block Load"),
- ("ec.stylize.ccburnfilm", "CC Burn Film", "CC Burn Film"),
- ("ec.stylize.ccglass", "CC Glass", "CC Glass"),
- ("ec.stylize.cchextile", "CC HexTile", "CC HexTile"),
- ("ec.stylize.cckaleida", "CC Kaleida", "CC Kaleida"),
- ("ec.stylize.ccmrsmoothie", "CC Mr. Smoothie", "CC Mr. Smoothie"),
- ("ec.stylize.ccplastic", "CC Plastic", "CC Plastic"),
- ("ec.stylize.ccrepetile", "CC RepeTile", "CC RepeTile"),
- ("ec.stylize.ccthreshold", "CC Threshold", "CC Threshold"),
- ("ec.stylize.ccthresholdrgb", "CC Threshold RGB", "CC Threshold RGB"),
- ("ec.stylize.ccvignette", "CC Vignette", "CC Vignette"),
+ ("ec.stylize.ccblockload", "Block Reveal", "ブロック表示"),
+ ("ec.stylize.ccburnfilm", "Film Burn", "フィルム焼け"),
+ ("ec.stylize.ccglass", "Glass Relief", "ガラスレリーフ"),
+ ("ec.stylize.cchextile", "Hexagonal Tiles", "六角形タイル"),
+ ("ec.stylize.cckaleida", "Kaleidoscope", "万華鏡"),
+ ("ec.stylize.ccmrsmoothie", "Palette Map", "パレットマップ"),
+ ("ec.stylize.ccplastic", "Plastic Shading", "プラスチックシェーディング"),
+ ("ec.stylize.ccrepetile", "Edge Tile Repeat", "エッジタイル反復"),
+ ("ec.stylize.ccthreshold", "Channel Threshold", "チャンネルしきい値"),
+ ("ec.stylize.ccthresholdrgb", "RGB Threshold", "RGBしきい値"),
+ ("ec.stylize.ccvignette", "Vignette", "ビネット"),
("ec.stylize.coloremboss", "Color Emboss", "カラーエンボス"),
("ec.stylize.emboss", "Emboss", "エンボス"),
("ec.stylize.findedges", "Find Edges", "輪郭検出"),
@@ -1076,8 +1083,8 @@ const JAPANESE_EFFECTS: &[Row] = &[
("ec.stylize.threshold", "Threshold", "しきい値"),
("ec.text.numbers", "Numbers", "番号"),
("ec.text.timecode", "Timecode", "タイムコード"),
- ("ec.time.ccforcemotionblur", "CC Force Motion Blur", "CC Force Motion Blur"),
- ("ec.time.ccwidetime", "CC Wide Time", "CC Wide Time"),
+ ("ec.time.ccforcemotionblur", "Temporal Motion Blur", "時間方向モーションブラー"),
+ ("ec.time.ccwidetime", "Temporal Blend", "時間ブレンド"),
("ec.time.echo", "Echo", "エコー"),
("ec.time.pixelmotionblur", "Pixel Motion Blur", "ピクセルモーションブラー"),
("ec.time.posterizetime", "Posterize Time", "ポスタリゼーション時間"),
@@ -1086,23 +1093,23 @@ const JAPANESE_EFFECTS: &[Row] = &[
("ec.time.timewarp", "Timewarp", "タイムワープ"),
("ec.transition.blockdissolve", "Block Dissolve", "ブロックディゾルブ"),
("ec.transition.cardwipe", "Card Wipe", "カードワイプ"),
- ("ec.transition.ccglasswipe", "CC Glass Wipe", "CC Glass Wipe"),
- ("ec.transition.ccgridwipe", "CC Grid Wipe", "CC Grid Wipe"),
- ("ec.transition.ccimagewipe", "CC Image Wipe", "CC Image Wipe"),
- ("ec.transition.ccjaws", "CC Jaws", "CC Jaws"),
- ("ec.transition.cclightwipe", "CC Light Wipe", "CC Light Wipe"),
- ("ec.transition.cclinesweep", "CC Line Sweep", "CC Line Sweep"),
- ("ec.transition.ccradialscalewipe", "CC Radial ScaleWipe", "CC Radial ScaleWipe"),
- ("ec.transition.ccscalewipe", "CC Scale Wipe", "CC Scale Wipe"),
- ("ec.transition.cctwister", "CC Twister", "CC Twister"),
- ("ec.transition.ccwarpomatic", "CC WarpoMatic", "CC WarpoMatic"),
+ ("ec.transition.ccglasswipe", "Glass Wipe", "ガラスワイプ"),
+ ("ec.transition.ccgridwipe", "Grid Wipe", "グリッドワイプ"),
+ ("ec.transition.ccimagewipe", "Luminance Image Wipe", "輝度画像ワイプ"),
+ ("ec.transition.ccjaws", "Serrated Wipe", "鋸歯状ワイプ"),
+ ("ec.transition.cclightwipe", "Light Wipe", "ライトワイプ"),
+ ("ec.transition.cclinesweep", "Line Sweep", "ラインスイープ"),
+ ("ec.transition.ccradialscalewipe", "Radial Scale Wipe", "放射状スケールワイプ"),
+ ("ec.transition.ccscalewipe", "Scale Wipe", "スケールワイプ"),
+ ("ec.transition.cctwister", "Twist Wipe", "ツイストワイプ"),
+ ("ec.transition.ccwarpomatic", "Warp Dissolve", "変形ディゾルブ"),
("ec.transition.gradientwipe", "Gradient Wipe", "グラデーションワイプ"),
("ec.transition.iriswipe", "Iris Wipe", "アイリスワイプ"),
("ec.transition.linearwipe", "Linear Wipe", "リニアワイプ"),
("ec.transition.radialwipe", "Radial Wipe", "放射状ワイプ"),
("ec.transition.venetian", "Venetian Blinds", "ブラインド"),
("ec.utility.applylut", "Apply Color LUT", "カラー LUT を適用"),
- ("ec.utility.ccoverbrights", "CC Overbrights", "CC Overbrights"),
+ ("ec.utility.ccoverbrights", "Out-of-Range Display", "範囲外表示"),
("ec.utility.cineon", "Cineon Converter", "Cineon コンバーター"),
("ec.utility.colorprofileconverter", "Color Profile Converter", "カラープロファイルコンバーター"),
("ec.utility.growbounds", "Grow Bounds", "範囲拡張"),
@@ -1176,9 +1183,9 @@ const JAPANESE_CATEGORIES: &[(&str, &str)] = &[
/// Georgian (`ka`): one row per effect, ids from [`SIMPLIFIED_CHINESE`]. Written from the meaning
/// of the English names, with the terms the Georgian menus and panels use (FilmCraft's Georgian
-/// for the effects the two apps share). The `CC` series and the brand names (`Cryptomatte`,
-/// `EXtractoR`, `IDentifier`, `Key Light`, `Unmult`, `Lumetri Color`) stay in English, as
-/// Adobe's Japanese interface keeps the `CC` series; `VR` and `OCIO` keep their prefix.
+/// for the effects the two apps share). The brand names (`Cryptomatte`, `EXtractoR`, `IDentifier`,
+/// `Key Light`, `Unmult`) stay in English; `VR` and `OCIO` keep their prefix. The renamed effects
+/// are translated from their new descriptive names.
const GEORGIAN: &[Row] = &[
("ec.3d.channelextract", "3D Channel Extract", "3D არხის ამოღება"),
("ec.3d.cryptomatte", "Cryptomatte", "Cryptomatte"),
@@ -1205,10 +1212,10 @@ const GEORGIAN: &[Row] = &[
("ec.blur.bilateral", "Bilateral Blur", "ბილატერალური გაბუნდოვნება"),
("ec.blur.cameralens", "Camera Lens Blur", "კამერის ობიექტივის გაბუნდოვნება"),
("ec.blur.camerashakedeblur", "Camera-Shake Deblur", "კამერის რყევით გაბუნდოვნების მოცილება"),
- ("ec.blur.cccross", "CC Cross Blur", "CC Cross Blur"),
- ("ec.blur.ccradial", "CC Radial Blur", "CC Radial Blur"),
- ("ec.blur.ccradialfast", "CC Radial Fast Blur", "CC Radial Fast Blur"),
- ("ec.blur.ccvector", "CC Vector Blur", "CC Vector Blur"),
+ ("ec.blur.cccross", "Cross Blur", "ჯვარედინი დაბინდვა"),
+ ("ec.blur.ccradial", "Variable Radial Blur", "ცვლადი რადიალური დაბინდვა"),
+ ("ec.blur.ccradialfast", "Fast Radial Blur", "სწრაფი რადიალური დაბინდვა"),
+ ("ec.blur.ccvector", "Vector Blur", "ვექტორული დაბინდვა"),
("ec.blur.channel", "Channel Blur", "არხის გაბუნდოვნება"),
("ec.blur.compound", "Compound Blur", "შედგენილი გაბუნდოვნება"),
("ec.blur.directional", "Directional Blur", "მიმართული გაბუნდოვნება"),
@@ -1222,7 +1229,7 @@ const GEORGIAN: &[Row] = &[
("ec.channel.arithmetic", "Arithmetic", "არითმეტიკა"),
("ec.channel.blend", "Blend", "შერევა"),
("ec.channel.calculations", "Calculations", "გამოთვლები"),
- ("ec.channel.cccomposite", "CC Composite", "CC Composite"),
+ ("ec.channel.cccomposite", "Source Composite", "წყაროს კომპოზიცია"),
("ec.channel.combiner", "Channel Combiner", "არხების გამაერთიანებელი"),
("ec.channel.compoundarithmetic", "Compound Arithmetic", "შედგენილი არითმეტიკა"),
("ec.channel.invert", "Invert", "ინვერსია"),
@@ -1238,10 +1245,10 @@ const GEORGIAN: &[Row] = &[
("ec.color.blackwhite", "Black & White", "შავ-თეთრი"),
("ec.color.brightnesscontrast", "Brightness & Contrast", "სიკაშკაშე და კონტრასტი"),
("ec.color.broadcast", "Broadcast Colors", "სამაუწყებლო ფერები"),
- ("ec.color.cccolorneutralizer", "CC Color Neutralizer", "CC Color Neutralizer"),
- ("ec.color.cccoloroffset", "CC Color Offset", "CC Color Offset"),
- ("ec.color.cckernel", "CC Kernel", "CC Kernel"),
- ("ec.color.cctoner", "CC Toner", "CC Toner"),
+ ("ec.color.cccolorneutralizer", "Color Neutralizer", "ფერის ნეიტრალიზაცია"),
+ ("ec.color.cccoloroffset", "Channel Offset", "არხების წანაცვლება"),
+ ("ec.color.cckernel", "Convolution Kernel", "კონვოლუციის ბირთვი"),
+ ("ec.color.cctoner", "Multi-Tone Tint", "მრავალტონიანი შეფერილობა"),
("ec.color.changecolor", "Change Color", "ფერის შეცვლა"),
("ec.color.changetocolor", "Change to Color", "ფერად შეცვლა"),
("ec.color.channelmixer", "Channel Mixer", "არხების მიქშერი"),
@@ -1258,7 +1265,7 @@ const GEORGIAN: &[Row] = &[
("ec.color.leavecolor", "Leave Color", "ფერის დატოვება"),
("ec.color.levels", "Levels", "დონეები"),
("ec.color.levelsic", "Levels (Individual Controls)", "დონეები (ცალკეული მართვა)"),
- ("ec.color.lumetri", "Lumetri Color", "Lumetri Color"),
+ ("ec.color.lumetri", "Color Grading", "ფერთა კორექცია"),
("ec.color.ociocdl", "OCIO CDL Transform", "OCIO CDL გარდაქმნა"),
("ec.color.ociocolorspace", "OCIO Color Space Transform", "OCIO ფერთა სივრცის გარდაქმნა"),
("ec.color.ociodisplay", "OCIO Display Transform", "OCIO ეკრანის გარდაქმნა"),
@@ -1283,20 +1290,20 @@ const GEORGIAN: &[Row] = &[
("ec.control.stereo3d", "Stereo 3D Controls", "სტერეო 3D მართვა"),
("ec.distort.bezierwarp", "Bezier Warp", "ბეზიეს დეფორმაცია"),
("ec.distort.bulge", "Bulge", "გამობერილობა"),
- ("ec.distort.ccbender", "CC Bender", "CC Bender"),
- ("ec.distort.ccbendit", "CC Bend It", "CC Bend It"),
- ("ec.distort.ccblobbylize", "CC Blobbylize", "CC Blobbylize"),
- ("ec.distort.ccflomotion", "CC Flo Motion", "CC Flo Motion"),
- ("ec.distort.ccgriddler", "CC Griddler", "CC Griddler"),
- ("ec.distort.cclens", "CC Lens", "CC Lens"),
- ("ec.distort.ccpageturn", "CC Page Turn", "CC Page Turn"),
- ("ec.distort.ccpowerpin", "CC Power Pin", "CC Power Pin"),
- ("ec.distort.ccripplepulse", "CC Ripple Pulse", "CC Ripple Pulse"),
- ("ec.distort.ccslant", "CC Slant", "CC Slant"),
- ("ec.distort.ccsmear", "CC Smear", "CC Smear"),
- ("ec.distort.ccsplit", "CC Split", "CC Split"),
- ("ec.distort.ccsplit2", "CC Split 2", "CC Split 2"),
- ("ec.distort.cctiler", "CC Tiler", "CC Tiler"),
+ ("ec.distort.ccbender", "Flexible Bend", "მოქნილი მოღუნვა"),
+ ("ec.distort.ccbendit", "Two-Point Bend", "ორწერტილიანი მოღუნვა"),
+ ("ec.distort.ccblobbylize", "Organic Displacement", "ორგანული გადაადგილება"),
+ ("ec.distort.ccflomotion", "Dual Lens Warp", "ორმაგი ლინზით დეფორმაცია"),
+ ("ec.distort.ccgriddler", "Tile Grid", "ფილების ბადე"),
+ ("ec.distort.cclens", "Lens Distortion", "ლინზის დამახინჯება"),
+ ("ec.distort.ccpageturn", "Page Curl", "გვერდის დახვევა"),
+ ("ec.distort.ccpowerpin", "Perspective Pin", "პერსპექტიული დამაგრება"),
+ ("ec.distort.ccripplepulse", "Pulsed Ripple", "პულსური ტალღა"),
+ ("ec.distort.ccslant", "Slant", "დახრა"),
+ ("ec.distort.ccsmear", "Directional Smear", "მიმართულებითი გაწელვა"),
+ ("ec.distort.ccsplit", "Split Warp", "გაყოფილი დეფორმაცია"),
+ ("ec.distort.ccsplit2", "Dual Split Warp", "ორმაგად გაყოფილი დეფორმაცია"),
+ ("ec.distort.cctiler", "Scaled Tiles", "მასშტაბირებული ფილები"),
("ec.distort.cornerpin", "Corner Pin", "კუთხეების მიმაგრება"),
("ec.distort.displacementmap", "Displacement Map", "წანაცვლების რუკა"),
("ec.distort.liquify", "Liquify", "გათხევადება"),
@@ -1324,11 +1331,11 @@ const GEORGIAN: &[Row] = &[
("ec.generate.audiospectrum", "Audio Spectrum", "აუდიოს სპექტრი"),
("ec.generate.audiowaveform", "Audio Waveform", "აუდიოს ტალღის ფორმა"),
("ec.generate.beam", "Beam", "სხივი"),
- ("ec.generate.ccgluegun", "CC Glue Gun", "CC Glue Gun"),
- ("ec.generate.cclightburst", "CC Light Burst 2.5", "CC Light Burst 2.5"),
- ("ec.generate.cclightrays", "CC Light Rays", "CC Light Rays"),
- ("ec.generate.cclightsweep", "CC Light Sweep", "CC Light Sweep"),
- ("ec.generate.ccthreads", "CC Threads", "CC Threads"),
+ ("ec.generate.ccgluegun", "Paint Beads", "საღებავის მარცვლები"),
+ ("ec.generate.cclightburst", "Radial Light Burst", "რადიალური ნათება"),
+ ("ec.generate.cclightrays", "Light Rays", "სინათლის სხივები"),
+ ("ec.generate.cclightsweep", "Light Sweep", "სინათლის გავლა"),
+ ("ec.generate.ccthreads", "Woven Threads", "ნაქსოვი ძაფები"),
("ec.generate.cellpattern", "Cell Pattern", "უჯრედების პატერნი"),
("ec.generate.checkerboard", "Checkerboard", "ჭადრაკის დაფა"),
("ec.generate.circle", "Circle", "წრე"),
@@ -1347,7 +1354,7 @@ const GEORGIAN: &[Row] = &[
("ec.generate.vegas", "Vegas", "ვეგასი"),
("ec.generate.writeon", "Write-on", "თანდათანობითი წერა"),
("ec.key.advancedspill", "Advanced Spill Suppressor", "ფერის გადაღვრის გაფართოებული ჩამხშობი"),
- ("ec.key.ccsimplewireremoval", "CC Simple Wire Removal", "CC Simple Wire Removal"),
+ ("ec.key.ccsimplewireremoval", "Line Removal", "ხაზის მოცილება"),
("ec.key.colordifference", "Color Difference Key", "ფერთა სხვაობის გასაღები"),
("ec.key.colorkey", "Color Key", "ფერის გასაღები"),
("ec.key.colorrange", "Color Range", "ფერების დიაპაზონი"),
@@ -1360,7 +1367,7 @@ const GEORGIAN: &[Row] = &[
("ec.key.screen", "Screen Key", "ეკრანის გასაღები"),
("ec.key.spill", "Spill Suppressor", "ფერის გადაღვრის ჩამხშობი"),
("ec.key.unmult", "Unmult", "Unmult"),
- ("ec.keying.keylight", "Key Light", "Key Light"),
+ ("ec.keying.keylight", "Screen Color Key", "ეკრანის ფერის გამოყოფა"),
("ec.matte.mattechoker", "Matte Choker", "მატის შემკუმშველი"),
("ec.matte.objectmatte", "Object Matte", "ობიექტის მატი"),
("ec.matte.refinehard", "Refine Hard Matte", "მკვეთრი მატის დახვეწა"),
@@ -1384,50 +1391,50 @@ const GEORGIAN: &[Row] = &[
("ec.obsolete.basictext", "Basic Text", "საბაზო ტექსტი"),
("ec.obsolete.gaussianlegacy", "Gaussian Blur (Legacy)", "გაუსის გაბუნდოვნება (მოძველებული)"),
("ec.obsolete.lightning", "Lightning", "ელვა"),
- ("ec.obsolete.mochashape", "Mocha shape", "Mocha-ს ფიგურა"),
+ ("ec.obsolete.mochashape", "Tracked Shape Matte", "თვალთვალის ფორმის ნიღაბი"),
("ec.obsolete.pathtext", "Path Text", "ტექსტი ტრაექტორიაზე"),
("ec.paint.paint", "Paint", "ხატვა"),
("ec.perspective.3dglasses", "3D Glasses", "3D სათვალე"),
("ec.perspective.bevelalpha", "Bevel Alpha", "ალფას ფასკა"),
("ec.perspective.beveledges", "Bevel Edges", "კიდეების ფასკა"),
("ec.perspective.cameratracker", "3D Camera Tracker", "3D კამერის ტრეკერი"),
- ("ec.perspective.cccylinder", "CC Cylinder", "CC Cylinder"),
- ("ec.perspective.ccenvironment", "CC Environment", "CC Environment"),
- ("ec.perspective.ccsphere", "CC Sphere", "CC Sphere"),
- ("ec.perspective.ccspotlight", "CC Spotlight", "CC Spotlight"),
+ ("ec.perspective.cccylinder", "Cylinder Wrap", "ცილინდრზე შემოხვევა"),
+ ("ec.perspective.ccenvironment", "Environment Map", "გარემოს რუკა"),
+ ("ec.perspective.ccsphere", "Sphere Wrap", "სფეროზე შემოხვევა"),
+ ("ec.perspective.ccspotlight", "Surface Spotlight", "ზედაპირის პროჟექტორი"),
("ec.perspective.dropshadow", "Drop Shadow", "ჩრდილი"),
("ec.perspective.radialshadow", "Radial Shadow", "რადიალური ჩრდილი"),
("ec.sim.carddance", "Card Dance", "მოცეკვავე ბარათები"),
("ec.sim.caustics", "Caustics", "კაუსტიკა"),
- ("ec.sim.ccballaction", "CC Ball Action", "CC Ball Action"),
- ("ec.sim.ccbubbles", "CC Bubbles", "CC Bubbles"),
- ("ec.sim.ccdrizzle", "CC Drizzle", "CC Drizzle"),
- ("ec.sim.cchair", "CC Hair", "CC Hair"),
- ("ec.sim.ccmrmercury", "CC Mr. Mercury", "CC Mr. Mercury"),
- ("ec.sim.ccparticlesystems2", "CC Particle Systems II", "CC Particle Systems II"),
- ("ec.sim.ccparticleworld", "CC Particle World", "CC Particle World"),
- ("ec.sim.ccpixelpolly", "CC Pixel Polly", "CC Pixel Polly"),
- ("ec.sim.ccrainfall", "CC Rainfall", "CC Rainfall"),
- ("ec.sim.ccscatterize", "CC Scatterize", "CC Scatterize"),
- ("ec.sim.ccsnowfall", "CC Snowfall", "CC Snowfall"),
- ("ec.sim.ccstarburst", "CC Star Burst", "CC Star Burst"),
+ ("ec.sim.ccballaction", "Ball Grid", "ბურთულების ბადე"),
+ ("ec.sim.ccbubbles", "Bubbles", "ბუშტები"),
+ ("ec.sim.ccdrizzle", "Water Ripples", "წყლის ტალღები"),
+ ("ec.sim.cchair", "Surface Fibers", "ზედაპირის ბოჭკოები"),
+ ("ec.sim.ccmrmercury", "Liquid Particles", "თხევადი ნაწილაკები"),
+ ("ec.sim.ccparticlesystems2", "Particle Emitter 2D", "ნაწილაკების 2D წყარო"),
+ ("ec.sim.ccparticleworld", "Particle Emitter 3D", "ნაწილაკების 3D წყარო"),
+ ("ec.sim.ccpixelpolly", "Pixel Shatter", "პიქსელების დაშლა"),
+ ("ec.sim.ccrainfall", "Rainfall", "წვიმა"),
+ ("ec.sim.ccscatterize", "Pixel Scatter", "პიქსელების გაფანტვა"),
+ ("ec.sim.ccsnowfall", "Snowfall", "თოვა"),
+ ("ec.sim.ccstarburst", "Starfield", "ვარსკვლავების ველი"),
("ec.sim.foam", "Foam", "ქაფი"),
("ec.sim.particleplayground", "Particle Playground", "ნაწილაკების სიმულაცია"),
("ec.sim.shatter", "Shatter", "დამსხვრევა"),
("ec.sim.waveworld", "Wave World", "ტალღების სამყარო"),
("ec.stylize.brushstrokes", "Brush Strokes", "ფუნჯის შტრიხები"),
("ec.stylize.cartoon", "Cartoon", "მულტფილმის სტილი"),
- ("ec.stylize.ccblockload", "CC Block Load", "CC Block Load"),
- ("ec.stylize.ccburnfilm", "CC Burn Film", "CC Burn Film"),
- ("ec.stylize.ccglass", "CC Glass", "CC Glass"),
- ("ec.stylize.cchextile", "CC HexTile", "CC HexTile"),
- ("ec.stylize.cckaleida", "CC Kaleida", "CC Kaleida"),
- ("ec.stylize.ccmrsmoothie", "CC Mr. Smoothie", "CC Mr. Smoothie"),
- ("ec.stylize.ccplastic", "CC Plastic", "CC Plastic"),
- ("ec.stylize.ccrepetile", "CC RepeTile", "CC RepeTile"),
- ("ec.stylize.ccthreshold", "CC Threshold", "CC Threshold"),
- ("ec.stylize.ccthresholdrgb", "CC Threshold RGB", "CC Threshold RGB"),
- ("ec.stylize.ccvignette", "CC Vignette", "CC Vignette"),
+ ("ec.stylize.ccblockload", "Block Reveal", "ბლოკებით გამოჩენა"),
+ ("ec.stylize.ccburnfilm", "Film Burn", "ფირის დაწვა"),
+ ("ec.stylize.ccglass", "Glass Relief", "მინის რელიეფი"),
+ ("ec.stylize.cchextile", "Hexagonal Tiles", "ექვსკუთხა ფილები"),
+ ("ec.stylize.cckaleida", "Kaleidoscope", "კალეიდოსკოპი"),
+ ("ec.stylize.ccmrsmoothie", "Palette Map", "პალიტრის რუკა"),
+ ("ec.stylize.ccplastic", "Plastic Shading", "პლასტმასის დაჩრდილვა"),
+ ("ec.stylize.ccrepetile", "Edge Tile Repeat", "კიდეების განმეორება"),
+ ("ec.stylize.ccthreshold", "Channel Threshold", "არხის ზღვარი"),
+ ("ec.stylize.ccthresholdrgb", "RGB Threshold", "RGB ზღვარი"),
+ ("ec.stylize.ccvignette", "Vignette", "ვინიეტირება"),
("ec.stylize.coloremboss", "Color Emboss", "ფერადი რელიეფი"),
("ec.stylize.emboss", "Emboss", "რელიეფი"),
("ec.stylize.findedges", "Find Edges", "კიდეების პოვნა"),
@@ -1442,8 +1449,8 @@ const GEORGIAN: &[Row] = &[
("ec.stylize.threshold", "Threshold", "ზღვარი"),
("ec.text.numbers", "Numbers", "რიცხვები"),
("ec.text.timecode", "Timecode", "თაიმკოდი"),
- ("ec.time.ccforcemotionblur", "CC Force Motion Blur", "CC Force Motion Blur"),
- ("ec.time.ccwidetime", "CC Wide Time", "CC Wide Time"),
+ ("ec.time.ccforcemotionblur", "Temporal Motion Blur", "დროითი მოძრაობის დაბინდვა"),
+ ("ec.time.ccwidetime", "Temporal Blend", "დროითი შერევა"),
("ec.time.echo", "Echo", "ექო"),
("ec.time.pixelmotionblur", "Pixel Motion Blur", "პიქსელების მოძრაობის გაბუნდოვნება"),
("ec.time.posterizetime", "Posterize Time", "დროის პოსტერიზაცია"),
@@ -1452,23 +1459,23 @@ const GEORGIAN: &[Row] = &[
("ec.time.timewarp", "Timewarp", "Timewarp"),
("ec.transition.blockdissolve", "Block Dissolve", "ბლოკური გადადნობა"),
("ec.transition.cardwipe", "Card Wipe", "ბარათებით წმენდა"),
- ("ec.transition.ccglasswipe", "CC Glass Wipe", "CC Glass Wipe"),
- ("ec.transition.ccgridwipe", "CC Grid Wipe", "CC Grid Wipe"),
- ("ec.transition.ccimagewipe", "CC Image Wipe", "CC Image Wipe"),
- ("ec.transition.ccjaws", "CC Jaws", "CC Jaws"),
- ("ec.transition.cclightwipe", "CC Light Wipe", "CC Light Wipe"),
- ("ec.transition.cclinesweep", "CC Line Sweep", "CC Line Sweep"),
- ("ec.transition.ccradialscalewipe", "CC Radial ScaleWipe", "CC Radial ScaleWipe"),
- ("ec.transition.ccscalewipe", "CC Scale Wipe", "CC Scale Wipe"),
- ("ec.transition.cctwister", "CC Twister", "CC Twister"),
- ("ec.transition.ccwarpomatic", "CC WarpoMatic", "CC WarpoMatic"),
+ ("ec.transition.ccglasswipe", "Glass Wipe", "მინის გადასვლა"),
+ ("ec.transition.ccgridwipe", "Grid Wipe", "ბადის გადასვლა"),
+ ("ec.transition.ccimagewipe", "Luminance Image Wipe", "სიკაშკაშის გამოსახულებით გადასვლა"),
+ ("ec.transition.ccjaws", "Serrated Wipe", "დაკბილული გადასვლა"),
+ ("ec.transition.cclightwipe", "Light Wipe", "სინათლის გადასვლა"),
+ ("ec.transition.cclinesweep", "Line Sweep", "ხაზების გავლა"),
+ ("ec.transition.ccradialscalewipe", "Radial Scale Wipe", "რადიალური მასშტაბის გადასვლა"),
+ ("ec.transition.ccscalewipe", "Scale Wipe", "მასშტაბის გადასვლა"),
+ ("ec.transition.cctwister", "Twist Wipe", "მოგრეხილი გადასვლა"),
+ ("ec.transition.ccwarpomatic", "Warp Dissolve", "დეფორმაციით გადასვლა"),
("ec.transition.gradientwipe", "Gradient Wipe", "გრადიენტული წმენდა"),
("ec.transition.iriswipe", "Iris Wipe", "დიაფრაგმული წმენდა"),
("ec.transition.linearwipe", "Linear Wipe", "წრფივი წმენდა"),
("ec.transition.radialwipe", "Radial Wipe", "რადიალური წმენდა"),
("ec.transition.venetian", "Venetian Blinds", "ჟალუზი"),
("ec.utility.applylut", "Apply Color LUT", "ფერის LUT-ის გამოყენება"),
- ("ec.utility.ccoverbrights", "CC Overbrights", "CC Overbrights"),
+ ("ec.utility.ccoverbrights", "Out-of-Range Display", "დიაპაზონის გარეთ ჩვენება"),
("ec.utility.cineon", "Cineon Converter", "Cineon-ის გარდამქმნელი"),
("ec.utility.colorprofileconverter", "Color Profile Converter", "ფერის პროფილის გარდამქმნელი"),
("ec.utility.facemeasurements", "Face Measurements", "სახის გაზომვები"),
@@ -1517,8 +1524,8 @@ const GEORGIAN_CATEGORIES: &[(&str, &str)] = &[
/// French (`fr`): one row per effect, ids from [`SIMPLIFIED_CHINESE`]. Written from the meaning of the
/// English names, with the terms the French menus use (calque, estampe for a matte, incrustation for
-/// keying). The `CC` series and the brand names stay in English, `VR`, `OCIO`, `PS` and `HDR` keep
-/// their tag after the translated name.
+/// keying). The brand names stay in English, `VR`, `OCIO`, `PS` and `HDR` keep their tag after the
+/// translated name.
const FRENCH: &[Row] = &[
("ec.3d.channelextract", "3D Channel Extract", "Extraction de canal 3D"),
("ec.3d.cryptomatte", "Cryptomatte", "Cryptomatte"),
@@ -1544,10 +1551,10 @@ const FRENCH: &[Row] = &[
("ec.blur.bilateral", "Bilateral Blur", "Flou bilatéral"),
("ec.blur.cameralens", "Camera Lens Blur", "Flou de l’objectif de la caméra"),
("ec.blur.camerashakedeblur", "Camera-Shake Deblur", "Correction du flou de bougé de caméra"),
- ("ec.blur.cccross", "CC Cross Blur", "CC Cross Blur"),
- ("ec.blur.ccradial", "CC Radial Blur", "CC Radial Blur"),
- ("ec.blur.ccradialfast", "CC Radial Fast Blur", "CC Radial Fast Blur"),
- ("ec.blur.ccvector", "CC Vector Blur", "CC Vector Blur"),
+ ("ec.blur.cccross", "Cross Blur", "Flou croisé"),
+ ("ec.blur.ccradial", "Variable Radial Blur", "Flou radial variable"),
+ ("ec.blur.ccradialfast", "Fast Radial Blur", "Flou radial rapide"),
+ ("ec.blur.ccvector", "Vector Blur", "Flou vectoriel"),
("ec.blur.channel", "Channel Blur", "Flou de canal"),
("ec.blur.compound", "Compound Blur", "Flou composé"),
("ec.blur.directional", "Directional Blur", "Flou directionnel"),
@@ -1561,7 +1568,7 @@ const FRENCH: &[Row] = &[
("ec.channel.arithmetic", "Arithmetic", "Arithmétique"),
("ec.channel.blend", "Blend", "Fusion"),
("ec.channel.calculations", "Calculations", "Calculs"),
- ("ec.channel.cccomposite", "CC Composite", "CC Composite"),
+ ("ec.channel.cccomposite", "Source Composite", "Composition de la source"),
("ec.channel.combiner", "Channel Combiner", "Combinateur de canaux"),
("ec.channel.compoundarithmetic", "Compound Arithmetic", "Arithmétique composée"),
("ec.channel.invert", "Invert", "Inversion"),
@@ -1577,10 +1584,10 @@ const FRENCH: &[Row] = &[
("ec.color.blackwhite", "Black & White", "Noir et blanc"),
("ec.color.brightnesscontrast", "Brightness & Contrast", "Luminosité et contraste"),
("ec.color.broadcast", "Broadcast Colors", "Couleurs de diffusion"),
- ("ec.color.cccolorneutralizer", "CC Color Neutralizer", "CC Color Neutralizer"),
- ("ec.color.cccoloroffset", "CC Color Offset", "CC Color Offset"),
- ("ec.color.cckernel", "CC Kernel", "CC Kernel"),
- ("ec.color.cctoner", "CC Toner", "CC Toner"),
+ ("ec.color.cccolorneutralizer", "Color Neutralizer", "Neutralisation des couleurs"),
+ ("ec.color.cccoloroffset", "Channel Offset", "Décalage des canaux"),
+ ("ec.color.cckernel", "Convolution Kernel", "Noyau de convolution"),
+ ("ec.color.cctoner", "Multi-Tone Tint", "Teinte multiton"),
("ec.color.changecolor", "Change Color", "Changer la couleur"),
("ec.color.changetocolor", "Change to Color", "Changer en couleur"),
("ec.color.channelmixer", "Channel Mixer", "Mélangeur de canaux"),
@@ -1597,7 +1604,7 @@ const FRENCH: &[Row] = &[
("ec.color.leavecolor", "Leave Color", "Conserver la couleur"),
("ec.color.levels", "Levels", "Niveaux"),
("ec.color.levelsic", "Levels (Individual Controls)", "Niveaux (contrôles individuels)"),
- ("ec.color.lumetri", "Lumetri Color", "Lumetri Color"),
+ ("ec.color.lumetri", "Color Grading", "Étalonnage des couleurs"),
("ec.color.ociocdl", "OCIO CDL Transform", "Transformation CDL OCIO"),
("ec.color.ociocolorspace", "OCIO Color Space Transform", "Transformation d’espace colorimétrique OCIO"),
("ec.color.ociodisplay", "OCIO Display Transform", "Transformation d’affichage OCIO"),
@@ -1622,20 +1629,20 @@ const FRENCH: &[Row] = &[
("ec.control.stereo3d", "Stereo 3D Controls", "Contrôles stéréo 3D"),
("ec.distort.bezierwarp", "Bezier Warp", "Déformation Bézier"),
("ec.distort.bulge", "Bulge", "Renflement"),
- ("ec.distort.ccbender", "CC Bender", "CC Bender"),
- ("ec.distort.ccbendit", "CC Bend It", "CC Bend It"),
- ("ec.distort.ccblobbylize", "CC Blobbylize", "CC Blobbylize"),
- ("ec.distort.ccflomotion", "CC Flo Motion", "CC Flo Motion"),
- ("ec.distort.ccgriddler", "CC Griddler", "CC Griddler"),
- ("ec.distort.cclens", "CC Lens", "CC Lens"),
- ("ec.distort.ccpageturn", "CC Page Turn", "CC Page Turn"),
- ("ec.distort.ccpowerpin", "CC Power Pin", "CC Power Pin"),
- ("ec.distort.ccripplepulse", "CC Ripple Pulse", "CC Ripple Pulse"),
- ("ec.distort.ccslant", "CC Slant", "CC Slant"),
- ("ec.distort.ccsmear", "CC Smear", "CC Smear"),
- ("ec.distort.ccsplit", "CC Split", "CC Split"),
- ("ec.distort.ccsplit2", "CC Split 2", "CC Split 2"),
- ("ec.distort.cctiler", "CC Tiler", "CC Tiler"),
+ ("ec.distort.ccbender", "Flexible Bend", "Courbure souple"),
+ ("ec.distort.ccbendit", "Two-Point Bend", "Courbure à deux points"),
+ ("ec.distort.ccblobbylize", "Organic Displacement", "Déplacement organique"),
+ ("ec.distort.ccflomotion", "Dual Lens Warp", "Déformation à deux lentilles"),
+ ("ec.distort.ccgriddler", "Tile Grid", "Grille de tuiles"),
+ ("ec.distort.cclens", "Lens Distortion", "Distorsion de lentille"),
+ ("ec.distort.ccpageturn", "Page Curl", "Page enroulée"),
+ ("ec.distort.ccpowerpin", "Perspective Pin", "Épinglage en perspective"),
+ ("ec.distort.ccripplepulse", "Pulsed Ripple", "Ondulation pulsée"),
+ ("ec.distort.ccslant", "Slant", "Inclinaison"),
+ ("ec.distort.ccsmear", "Directional Smear", "Étalement directionnel"),
+ ("ec.distort.ccsplit", "Split Warp", "Déformation divisée"),
+ ("ec.distort.ccsplit2", "Dual Split Warp", "Déformation à double division"),
+ ("ec.distort.cctiler", "Scaled Tiles", "Tuiles mises à l’échelle"),
("ec.distort.cornerpin", "Corner Pin", "Épinglage d’angles"),
("ec.distort.displacementmap", "Displacement Map", "Carte de déplacement"),
("ec.distort.liquify", "Liquify", "Liquéfier"),
@@ -1663,11 +1670,11 @@ const FRENCH: &[Row] = &[
("ec.generate.audiospectrum", "Audio Spectrum", "Spectre audio"),
("ec.generate.audiowaveform", "Audio Waveform", "Forme d’onde audio"),
("ec.generate.beam", "Beam", "Faisceau"),
- ("ec.generate.ccgluegun", "CC Glue Gun", "CC Glue Gun"),
- ("ec.generate.cclightburst", "CC Light Burst 2.5", "CC Light Burst 2.5"),
- ("ec.generate.cclightrays", "CC Light Rays", "CC Light Rays"),
- ("ec.generate.cclightsweep", "CC Light Sweep", "CC Light Sweep"),
- ("ec.generate.ccthreads", "CC Threads", "CC Threads"),
+ ("ec.generate.ccgluegun", "Paint Beads", "Perles de peinture"),
+ ("ec.generate.cclightburst", "Radial Light Burst", "Éclat lumineux radial"),
+ ("ec.generate.cclightrays", "Light Rays", "Rayons lumineux"),
+ ("ec.generate.cclightsweep", "Light Sweep", "Balayage lumineux"),
+ ("ec.generate.ccthreads", "Woven Threads", "Fils tissés"),
("ec.generate.cellpattern", "Cell Pattern", "Motif cellulaire"),
("ec.generate.checkerboard", "Checkerboard", "Damier"),
("ec.generate.circle", "Circle", "Cercle"),
@@ -1686,7 +1693,7 @@ const FRENCH: &[Row] = &[
("ec.generate.vegas", "Vegas", "Vegas"),
("ec.generate.writeon", "Write-on", "Écriture progressive"),
("ec.key.advancedspill", "Advanced Spill Suppressor", "Suppresseur de débordement avancé"),
- ("ec.key.ccsimplewireremoval", "CC Simple Wire Removal", "CC Simple Wire Removal"),
+ ("ec.key.ccsimplewireremoval", "Line Removal", "Suppression de ligne"),
("ec.key.colordifference", "Color Difference Key", "Incrustation par différence de couleur"),
("ec.key.colorkey", "Color Key", "Incrustation couleur"),
("ec.key.colorrange", "Color Range", "Plage de couleurs"),
@@ -1699,7 +1706,7 @@ const FRENCH: &[Row] = &[
("ec.key.screen", "Screen Key", "Incrustation d’écran"),
("ec.key.spill", "Spill Suppressor", "Suppresseur de débordement"),
("ec.key.unmult", "Unmult", "Unmult"),
- ("ec.keying.keylight", "Key Light", "Key Light"),
+ ("ec.keying.keylight", "Screen Color Key", "Incrustation par couleur d’écran"),
("ec.matte.mattechoker", "Matte Choker", "Réducteur d’estampe"),
("ec.matte.objectmatte", "Object Matte", "Estampe d’objet"),
("ec.matte.refinehard", "Refine Hard Matte", "Affiner l’estampe nette"),
@@ -1723,50 +1730,50 @@ const FRENCH: &[Row] = &[
("ec.obsolete.basictext", "Basic Text", "Texte de base"),
("ec.obsolete.gaussianlegacy", "Gaussian Blur (Legacy)", "Flou gaussien (hérité)"),
("ec.obsolete.lightning", "Lightning", "Foudre"),
- ("ec.obsolete.mochashape", "Mocha shape", "Forme Mocha"),
+ ("ec.obsolete.mochashape", "Tracked Shape Matte", "Cache de forme suivie"),
("ec.obsolete.pathtext", "Path Text", "Texte sur tracé"),
("ec.paint.paint", "Paint", "Peinture"),
("ec.perspective.3dglasses", "3D Glasses", "Lunettes 3D"),
("ec.perspective.bevelalpha", "Bevel Alpha", "Biseau alpha"),
("ec.perspective.beveledges", "Bevel Edges", "Biseau des bords"),
("ec.perspective.cameratracker", "3D Camera Tracker", "Suivi de caméra 3D"),
- ("ec.perspective.cccylinder", "CC Cylinder", "CC Cylinder"),
- ("ec.perspective.ccenvironment", "CC Environment", "CC Environment"),
- ("ec.perspective.ccsphere", "CC Sphere", "CC Sphere"),
- ("ec.perspective.ccspotlight", "CC Spotlight", "CC Spotlight"),
+ ("ec.perspective.cccylinder", "Cylinder Wrap", "Enroulement cylindrique"),
+ ("ec.perspective.ccenvironment", "Environment Map", "Carte d’environnement"),
+ ("ec.perspective.ccsphere", "Sphere Wrap", "Enroulement sphérique"),
+ ("ec.perspective.ccspotlight", "Surface Spotlight", "Projecteur de surface"),
("ec.perspective.dropshadow", "Drop Shadow", "Ombre portée"),
("ec.perspective.radialshadow", "Radial Shadow", "Ombre radiale"),
("ec.sim.carddance", "Card Dance", "Danse de cartes"),
("ec.sim.caustics", "Caustics", "Caustiques"),
- ("ec.sim.ccballaction", "CC Ball Action", "CC Ball Action"),
- ("ec.sim.ccbubbles", "CC Bubbles", "CC Bubbles"),
- ("ec.sim.ccdrizzle", "CC Drizzle", "CC Drizzle"),
- ("ec.sim.cchair", "CC Hair", "CC Hair"),
- ("ec.sim.ccmrmercury", "CC Mr. Mercury", "CC Mr. Mercury"),
- ("ec.sim.ccparticlesystems2", "CC Particle Systems II", "CC Particle Systems II"),
- ("ec.sim.ccparticleworld", "CC Particle World", "CC Particle World"),
- ("ec.sim.ccpixelpolly", "CC Pixel Polly", "CC Pixel Polly"),
- ("ec.sim.ccrainfall", "CC Rainfall", "CC Rainfall"),
- ("ec.sim.ccscatterize", "CC Scatterize", "CC Scatterize"),
- ("ec.sim.ccsnowfall", "CC Snowfall", "CC Snowfall"),
- ("ec.sim.ccstarburst", "CC Star Burst", "CC Star Burst"),
+ ("ec.sim.ccballaction", "Ball Grid", "Grille de sphères"),
+ ("ec.sim.ccbubbles", "Bubbles", "Bulles"),
+ ("ec.sim.ccdrizzle", "Water Ripples", "Ondulations de l’eau"),
+ ("ec.sim.cchair", "Surface Fibers", "Fibres de surface"),
+ ("ec.sim.ccmrmercury", "Liquid Particles", "Particules liquides"),
+ ("ec.sim.ccparticlesystems2", "Particle Emitter 2D", "Émetteur de particules 2D"),
+ ("ec.sim.ccparticleworld", "Particle Emitter 3D", "Émetteur de particules 3D"),
+ ("ec.sim.ccpixelpolly", "Pixel Shatter", "Éclatement des pixels"),
+ ("ec.sim.ccrainfall", "Rainfall", "Pluie"),
+ ("ec.sim.ccscatterize", "Pixel Scatter", "Dispersion des pixels"),
+ ("ec.sim.ccsnowfall", "Snowfall", "Neige"),
+ ("ec.sim.ccstarburst", "Starfield", "Champ d’étoiles"),
("ec.sim.foam", "Foam", "Mousse"),
("ec.sim.particleplayground", "Particle Playground", "Terrain de jeu de particules"),
("ec.sim.shatter", "Shatter", "Éclatement"),
("ec.sim.waveworld", "Wave World", "Monde des vagues"),
("ec.stylize.brushstrokes", "Brush Strokes", "Coups de pinceau"),
("ec.stylize.cartoon", "Cartoon", "Dessin animé"),
- ("ec.stylize.ccblockload", "CC Block Load", "CC Block Load"),
- ("ec.stylize.ccburnfilm", "CC Burn Film", "CC Burn Film"),
- ("ec.stylize.ccglass", "CC Glass", "CC Glass"),
- ("ec.stylize.cchextile", "CC HexTile", "CC HexTile"),
- ("ec.stylize.cckaleida", "CC Kaleida", "CC Kaleida"),
- ("ec.stylize.ccmrsmoothie", "CC Mr. Smoothie", "CC Mr. Smoothie"),
- ("ec.stylize.ccplastic", "CC Plastic", "CC Plastic"),
- ("ec.stylize.ccrepetile", "CC RepeTile", "CC RepeTile"),
- ("ec.stylize.ccthreshold", "CC Threshold", "CC Threshold"),
- ("ec.stylize.ccthresholdrgb", "CC Threshold RGB", "CC Threshold RGB"),
- ("ec.stylize.ccvignette", "CC Vignette", "CC Vignette"),
+ ("ec.stylize.ccblockload", "Block Reveal", "Révélation par blocs"),
+ ("ec.stylize.ccburnfilm", "Film Burn", "Brûlure de pellicule"),
+ ("ec.stylize.ccglass", "Glass Relief", "Relief de verre"),
+ ("ec.stylize.cchextile", "Hexagonal Tiles", "Tuiles hexagonales"),
+ ("ec.stylize.cckaleida", "Kaleidoscope", "Kaléidoscope"),
+ ("ec.stylize.ccmrsmoothie", "Palette Map", "Palettmappning"),
+ ("ec.stylize.ccplastic", "Plastic Shading", "Ombrage plastique"),
+ ("ec.stylize.ccrepetile", "Edge Tile Repeat", "Répétition des tuiles aux bords"),
+ ("ec.stylize.ccthreshold", "Channel Threshold", "Seuil de canal"),
+ ("ec.stylize.ccthresholdrgb", "RGB Threshold", "Seuil RVB"),
+ ("ec.stylize.ccvignette", "Vignette", "Vignettage"),
("ec.stylize.coloremboss", "Color Emboss", "Estampage couleur"),
("ec.stylize.emboss", "Emboss", "Estampage"),
("ec.stylize.findedges", "Find Edges", "Détection des contours"),
@@ -1781,8 +1788,8 @@ const FRENCH: &[Row] = &[
("ec.stylize.threshold", "Threshold", "Seuil"),
("ec.text.numbers", "Numbers", "Nombres"),
("ec.text.timecode", "Timecode", "Timecode"),
- ("ec.time.ccforcemotionblur", "CC Force Motion Blur", "CC Force Motion Blur"),
- ("ec.time.ccwidetime", "CC Wide Time", "CC Wide Time"),
+ ("ec.time.ccforcemotionblur", "Temporal Motion Blur", "Flou de mouvement temporel"),
+ ("ec.time.ccwidetime", "Temporal Blend", "Fusion temporelle"),
("ec.time.echo", "Echo", "Écho"),
("ec.time.pixelmotionblur", "Pixel Motion Blur", "Flou de mouvement des pixels"),
("ec.time.posterizetime", "Posterize Time", "Postérisation temporelle"),
@@ -1791,23 +1798,23 @@ const FRENCH: &[Row] = &[
("ec.time.timewarp", "Timewarp", "Déformation temporelle"),
("ec.transition.blockdissolve", "Block Dissolve", "Fondu par blocs"),
("ec.transition.cardwipe", "Card Wipe", "Volet de cartes"),
- ("ec.transition.ccglasswipe", "CC Glass Wipe", "CC Glass Wipe"),
- ("ec.transition.ccgridwipe", "CC Grid Wipe", "CC Grid Wipe"),
- ("ec.transition.ccimagewipe", "CC Image Wipe", "CC Image Wipe"),
- ("ec.transition.ccjaws", "CC Jaws", "CC Jaws"),
- ("ec.transition.cclightwipe", "CC Light Wipe", "CC Light Wipe"),
- ("ec.transition.cclinesweep", "CC Line Sweep", "CC Line Sweep"),
- ("ec.transition.ccradialscalewipe", "CC Radial ScaleWipe", "CC Radial ScaleWipe"),
- ("ec.transition.ccscalewipe", "CC Scale Wipe", "CC Scale Wipe"),
- ("ec.transition.cctwister", "CC Twister", "CC Twister"),
- ("ec.transition.ccwarpomatic", "CC WarpoMatic", "CC WarpoMatic"),
+ ("ec.transition.ccglasswipe", "Glass Wipe", "Volet de verre"),
+ ("ec.transition.ccgridwipe", "Grid Wipe", "Volet en grille"),
+ ("ec.transition.ccimagewipe", "Luminance Image Wipe", "Volet par luminance d’image"),
+ ("ec.transition.ccjaws", "Serrated Wipe", "Volet dentelé"),
+ ("ec.transition.cclightwipe", "Light Wipe", "Volet lumineux"),
+ ("ec.transition.cclinesweep", "Line Sweep", "Balayage de lignes"),
+ ("ec.transition.ccradialscalewipe", "Radial Scale Wipe", "Volet d’échelle radial"),
+ ("ec.transition.ccscalewipe", "Scale Wipe", "Volet d’échelle"),
+ ("ec.transition.cctwister", "Twist Wipe", "Volet torsadé"),
+ ("ec.transition.ccwarpomatic", "Warp Dissolve", "Fondu déformant"),
("ec.transition.gradientwipe", "Gradient Wipe", "Volet en dégradé"),
("ec.transition.iriswipe", "Iris Wipe", "Volet en iris"),
("ec.transition.linearwipe", "Linear Wipe", "Volet linéaire"),
("ec.transition.radialwipe", "Radial Wipe", "Volet radial"),
("ec.transition.venetian", "Venetian Blinds", "Stores vénitiens"),
("ec.utility.applylut", "Apply Color LUT", "Appliquer une LUT de couleur"),
- ("ec.utility.ccoverbrights", "CC Overbrights", "CC Overbrights"),
+ ("ec.utility.ccoverbrights", "Out-of-Range Display", "Affichage hors plage"),
("ec.utility.cineon", "Cineon Converter", "Convertisseur Cineon"),
("ec.utility.colorprofileconverter", "Color Profile Converter", "Convertisseur de profil colorimétrique"),
("ec.utility.facemeasurements", "Face Measurements", "Mesures du visage"),
@@ -1909,10 +1916,10 @@ const SWEDISH: &[Row] = &[
("ec.blur.bilateral", "Bilateral Blur", "Bilateral oskärpa"),
("ec.blur.cameralens", "Camera Lens Blur", "Kameralinsoskärpa"),
("ec.blur.camerashakedeblur", "Camera-Shake Deblur", "Ta bort oskärpa från kameraskakning"),
- ("ec.blur.cccross", "CC Cross Blur", "CC Korsoskärpa"),
- ("ec.blur.ccradial", "CC Radial Blur", "CC Radiell oskärpa"),
- ("ec.blur.ccradialfast", "CC Radial Fast Blur", "CC Snabb radiell oskärpa"),
- ("ec.blur.ccvector", "CC Vector Blur", "CC Vektoroskärpa"),
+ ("ec.blur.cccross", "Cross Blur", "Korsoskärpa"),
+ ("ec.blur.ccradial", "Variable Radial Blur", "Variabel radiell oskärpa"),
+ ("ec.blur.ccradialfast", "Fast Radial Blur", "Snabb radiell oskärpa"),
+ ("ec.blur.ccvector", "Vector Blur", "Vektoroskärpa"),
("ec.blur.channel", "Channel Blur", "Kanaloskärpa"),
("ec.blur.compound", "Compound Blur", "Sammansatt oskärpa"),
("ec.blur.directional", "Directional Blur", "Riktad oskärpa"),
@@ -1926,7 +1933,7 @@ const SWEDISH: &[Row] = &[
("ec.channel.arithmetic", "Arithmetic", "Aritmetik"),
("ec.channel.blend", "Blend", "Blanda"),
("ec.channel.calculations", "Calculations", "Beräkningar"),
- ("ec.channel.cccomposite", "CC Composite", "CC Komposit"),
+ ("ec.channel.cccomposite", "Source Composite", "Källkomposition"),
("ec.channel.combiner", "Channel Combiner", "Kanalkombinerare"),
("ec.channel.compoundarithmetic", "Compound Arithmetic", "Sammansatt aritmetik"),
("ec.channel.invert", "Invert", "Invertera"),
@@ -1942,10 +1949,10 @@ const SWEDISH: &[Row] = &[
("ec.color.blackwhite", "Black & White", "Svartvitt"),
("ec.color.brightnesscontrast", "Brightness & Contrast", "Ljusstyrka och kontrast"),
("ec.color.broadcast", "Broadcast Colors", "Broadcast-färger"),
- ("ec.color.cccolorneutralizer", "CC Color Neutralizer", "CC Färgneutraliserare"),
- ("ec.color.cccoloroffset", "CC Color Offset", "CC Färgförskjutning"),
- ("ec.color.cckernel", "CC Kernel", "CC Kärna"),
- ("ec.color.cctoner", "CC Toner", "CC Toner"),
+ ("ec.color.cccolorneutralizer", "Color Neutralizer", "Färgneutralisering"),
+ ("ec.color.cccoloroffset", "Channel Offset", "Kanalförskjutning"),
+ ("ec.color.cckernel", "Convolution Kernel", "Faltningskärna"),
+ ("ec.color.cctoner", "Multi-Tone Tint", "Flertonsfärgning"),
("ec.color.changecolor", "Change Color", "Ändra färg"),
("ec.color.changetocolor", "Change to Color", "Ändra till färg"),
("ec.color.channelmixer", "Channel Mixer", "Kanalmixer"),
@@ -1962,7 +1969,7 @@ const SWEDISH: &[Row] = &[
("ec.color.leavecolor", "Leave Color", "Behåll färg"),
("ec.color.levels", "Levels", "Nivåer"),
("ec.color.levelsic", "Levels (Individual Controls)", "Nivåer (individuella kontroller)"),
- ("ec.color.lumetri", "Lumetri Color", "Lumetri-färg"),
+ ("ec.color.lumetri", "Color Grading", "Färggradering"),
("ec.color.ociocdl", "OCIO CDL Transform", "OCIO CDL-transformering"),
("ec.color.ociocolorspace", "OCIO Color Space Transform", "OCIO färgrymdstransformering"),
("ec.color.ociodisplay", "OCIO Display Transform", "OCIO visningstransformering"),
@@ -1987,20 +1994,20 @@ const SWEDISH: &[Row] = &[
("ec.control.stereo3d", "Stereo 3D Controls", "Stereo 3D-kontroller"),
("ec.distort.bezierwarp", "Bezier Warp", "Bezierförvrängning"),
("ec.distort.bulge", "Bulge", "Utbuktning"),
- ("ec.distort.ccbender", "CC Bender", "CC Bender"),
- ("ec.distort.ccbendit", "CC Bend It", "CC Bend It"),
- ("ec.distort.ccblobbylize", "CC Blobbylize", "CC Blobbylize"),
- ("ec.distort.ccflomotion", "CC Flo Motion", "CC Flo Motion"),
- ("ec.distort.ccgriddler", "CC Griddler", "CC Griddler"),
- ("ec.distort.cclens", "CC Lens", "CC Objektiv"),
- ("ec.distort.ccpageturn", "CC Page Turn", "CC Sidvändning"),
- ("ec.distort.ccpowerpin", "CC Power Pin", "CC Power Pin"),
- ("ec.distort.ccripplepulse", "CC Ripple Pulse", "CC Krusningspuls"),
- ("ec.distort.ccslant", "CC Slant", "CC Lutning"),
- ("ec.distort.ccsmear", "CC Smear", "CC Utsmetning"),
- ("ec.distort.ccsplit", "CC Split", "CC Dela"),
- ("ec.distort.ccsplit2", "CC Split 2", "CC Dela 2"),
- ("ec.distort.cctiler", "CC Tiler", "CC Tiler"),
+ ("ec.distort.ccbender", "Flexible Bend", "Flexibel böjning"),
+ ("ec.distort.ccbendit", "Two-Point Bend", "Tvåpunktsböjning"),
+ ("ec.distort.ccblobbylize", "Organic Displacement", "Organisk förskjutning"),
+ ("ec.distort.ccflomotion", "Dual Lens Warp", "Dubbel linsförvrängning"),
+ ("ec.distort.ccgriddler", "Tile Grid", "Plattnät"),
+ ("ec.distort.cclens", "Lens Distortion", "Linsförvrängning"),
+ ("ec.distort.ccpageturn", "Page Curl", "Sidkrullning"),
+ ("ec.distort.ccpowerpin", "Perspective Pin", "Perspektivnålar"),
+ ("ec.distort.ccripplepulse", "Pulsed Ripple", "Pulserande krusning"),
+ ("ec.distort.ccslant", "Slant", "Lutning"),
+ ("ec.distort.ccsmear", "Directional Smear", "Riktningssmetning"),
+ ("ec.distort.ccsplit", "Split Warp", "Delad förvrängning"),
+ ("ec.distort.ccsplit2", "Dual Split Warp", "Dubbeldelad förvrängning"),
+ ("ec.distort.cctiler", "Scaled Tiles", "Skalade plattor"),
("ec.distort.cornerpin", "Corner Pin", "Hörnförankring"),
("ec.distort.displacementmap", "Displacement Map", "Förskjutningskarta"),
("ec.distort.liquify", "Liquify", "Gör flytande"),
@@ -2028,11 +2035,11 @@ const SWEDISH: &[Row] = &[
("ec.generate.audiospectrum", "Audio Spectrum", "Ljudspektrum"),
("ec.generate.audiowaveform", "Audio Waveform", "Ljudvågform"),
("ec.generate.beam", "Beam", "Stråle"),
- ("ec.generate.ccgluegun", "CC Glue Gun", "CC Glue Gun"),
- ("ec.generate.cclightburst", "CC Light Burst 2.5", "CC Ljusutbrott 2.5"),
- ("ec.generate.cclightrays", "CC Light Rays", "CC Ljusstrålar"),
- ("ec.generate.cclightsweep", "CC Light Sweep", "CC Ljussvep"),
- ("ec.generate.ccthreads", "CC Threads", "CC Trådar"),
+ ("ec.generate.ccgluegun", "Paint Beads", "Färgpärlor"),
+ ("ec.generate.cclightburst", "Radial Light Burst", "Radiellt ljusutbrott"),
+ ("ec.generate.cclightrays", "Light Rays", "Ljusstrålar"),
+ ("ec.generate.cclightsweep", "Light Sweep", "Ljussvep"),
+ ("ec.generate.ccthreads", "Woven Threads", "Vävda trådar"),
("ec.generate.cellpattern", "Cell Pattern", "Cellmönster"),
("ec.generate.checkerboard", "Checkerboard", "Schackbräde"),
("ec.generate.circle", "Circle", "Cirkel"),
@@ -2051,7 +2058,7 @@ const SWEDISH: &[Row] = &[
("ec.generate.vegas", "Vegas", "Vegas"),
("ec.generate.writeon", "Write-on", "Framskrivning"),
("ec.key.advancedspill", "Advanced Spill Suppressor", "Avancerad spilldämpning"),
- ("ec.key.ccsimplewireremoval", "CC Simple Wire Removal", "CC Enkel trådborttagning"),
+ ("ec.key.ccsimplewireremoval", "Line Removal", "Linjeborttagning"),
("ec.key.colordifference", "Color Difference Key", "Färgdifferensnyckel"),
("ec.key.colorkey", "Color Key", "Färgnyckel"),
("ec.key.colorrange", "Color Range", "Färgomfång"),
@@ -2064,7 +2071,7 @@ const SWEDISH: &[Row] = &[
("ec.key.screen", "Screen Key", "Skärmnyckel"),
("ec.key.spill", "Spill Suppressor", "Spilldämpning"),
("ec.key.unmult", "Unmult", "Unmult"),
- ("ec.keying.keylight", "Key Light", "Key Light"),
+ ("ec.keying.keylight", "Screen Color Key", "Skärmfärgsnyckling"),
("ec.matte.mattechoker", "Matte Choker", "Mattekrympning"),
("ec.matte.objectmatte", "Object Matte", "Objektmatte"),
("ec.matte.refinehard", "Refine Hard Matte", "Förfina hård matte"),
@@ -2088,50 +2095,50 @@ const SWEDISH: &[Row] = &[
("ec.obsolete.basictext", "Basic Text", "Grundläggande text"),
("ec.obsolete.gaussianlegacy", "Gaussian Blur (Legacy)", "Gaussisk oskärpa (äldre)"),
("ec.obsolete.lightning", "Lightning", "Blixt"),
- ("ec.obsolete.mochashape", "Mocha shape", "Mocha-form"),
+ ("ec.obsolete.mochashape", "Tracked Shape Matte", "Spårad formmask"),
("ec.obsolete.pathtext", "Path Text", "Text längs bana"),
("ec.paint.paint", "Paint", "Måla"),
("ec.perspective.3dglasses", "3D Glasses", "3D-glasögon"),
("ec.perspective.bevelalpha", "Bevel Alpha", "Alfafasning"),
("ec.perspective.beveledges", "Bevel Edges", "Fasade kanter"),
("ec.perspective.cameratracker", "3D Camera Tracker", "3D-kameraspårning"),
- ("ec.perspective.cccylinder", "CC Cylinder", "CC Cylinder"),
- ("ec.perspective.ccenvironment", "CC Environment", "CC Miljö"),
- ("ec.perspective.ccsphere", "CC Sphere", "CC Sfär"),
- ("ec.perspective.ccspotlight", "CC Spotlight", "CC Strålkastare"),
+ ("ec.perspective.cccylinder", "Cylinder Wrap", "Cylinderomslag"),
+ ("ec.perspective.ccenvironment", "Environment Map", "Miljökarta"),
+ ("ec.perspective.ccsphere", "Sphere Wrap", "Sfäromslag"),
+ ("ec.perspective.ccspotlight", "Surface Spotlight", "Ytstrålkastare"),
("ec.perspective.dropshadow", "Drop Shadow", "Slagskugga"),
("ec.perspective.radialshadow", "Radial Shadow", "Radiell skugga"),
("ec.sim.carddance", "Card Dance", "Kortdans"),
("ec.sim.caustics", "Caustics", "Kaustik"),
- ("ec.sim.ccballaction", "CC Ball Action", "CC Bollåtgärd"),
- ("ec.sim.ccbubbles", "CC Bubbles", "CC Bubblor"),
- ("ec.sim.ccdrizzle", "CC Drizzle", "CC Duggregn"),
- ("ec.sim.cchair", "CC Hair", "CC Hår"),
- ("ec.sim.ccmrmercury", "CC Mr. Mercury", "CC Mr. Mercury"),
- ("ec.sim.ccparticlesystems2", "CC Particle Systems II", "CC Partikelsystem II"),
- ("ec.sim.ccparticleworld", "CC Particle World", "CC Partikelvärld"),
- ("ec.sim.ccpixelpolly", "CC Pixel Polly", "CC Pixel Polly"),
- ("ec.sim.ccrainfall", "CC Rainfall", "CC Regn"),
- ("ec.sim.ccscatterize", "CC Scatterize", "CC Utspridning"),
- ("ec.sim.ccsnowfall", "CC Snowfall", "CC Snöfall"),
- ("ec.sim.ccstarburst", "CC Star Burst", "CC Stjärnexplosion"),
+ ("ec.sim.ccballaction", "Ball Grid", "Kulnät"),
+ ("ec.sim.ccbubbles", "Bubbles", "Bubblor"),
+ ("ec.sim.ccdrizzle", "Water Ripples", "Vattenkrusningar"),
+ ("ec.sim.cchair", "Surface Fibers", "Ytfibrer"),
+ ("ec.sim.ccmrmercury", "Liquid Particles", "Vätskepartiklar"),
+ ("ec.sim.ccparticlesystems2", "Particle Emitter 2D", "Partikelsändare 2D"),
+ ("ec.sim.ccparticleworld", "Particle Emitter 3D", "Partikelsändare 3D"),
+ ("ec.sim.ccpixelpolly", "Pixel Shatter", "Pixelsplittring"),
+ ("ec.sim.ccrainfall", "Rainfall", "Regn"),
+ ("ec.sim.ccscatterize", "Pixel Scatter", "Pixelspridning"),
+ ("ec.sim.ccsnowfall", "Snowfall", "Snöfall"),
+ ("ec.sim.ccstarburst", "Starfield", "Stjärnfält"),
("ec.sim.foam", "Foam", "Skum"),
("ec.sim.particleplayground", "Particle Playground", "Partikellekplats"),
("ec.sim.shatter", "Shatter", "Krossa"),
("ec.sim.waveworld", "Wave World", "Vågvärld"),
("ec.stylize.brushstrokes", "Brush Strokes", "Penseldrag"),
("ec.stylize.cartoon", "Cartoon", "Tecknat"),
- ("ec.stylize.ccblockload", "CC Block Load", "CC Blockladdning"),
- ("ec.stylize.ccburnfilm", "CC Burn Film", "CC Bränn film"),
- ("ec.stylize.ccglass", "CC Glass", "CC Glas"),
- ("ec.stylize.cchextile", "CC HexTile", "CC HexTile"),
- ("ec.stylize.cckaleida", "CC Kaleida", "CC Kaleida"),
- ("ec.stylize.ccmrsmoothie", "CC Mr. Smoothie", "CC Mr. Smoothie"),
- ("ec.stylize.ccplastic", "CC Plastic", "CC Plast"),
- ("ec.stylize.ccrepetile", "CC RepeTile", "CC RepeTile"),
- ("ec.stylize.ccthreshold", "CC Threshold", "CC Tröskel"),
- ("ec.stylize.ccthresholdrgb", "CC Threshold RGB", "CC Tröskel RGB"),
- ("ec.stylize.ccvignette", "CC Vignette", "CC Vinjett"),
+ ("ec.stylize.ccblockload", "Block Reveal", "Blockframträdande"),
+ ("ec.stylize.ccburnfilm", "Film Burn", "Filmbränning"),
+ ("ec.stylize.ccglass", "Glass Relief", "Glasrelief"),
+ ("ec.stylize.cchextile", "Hexagonal Tiles", "Sexkantiga plattor"),
+ ("ec.stylize.cckaleida", "Kaleidoscope", "Kalejdoskop"),
+ ("ec.stylize.ccmrsmoothie", "Palette Map", "Mappage de palette"),
+ ("ec.stylize.ccplastic", "Plastic Shading", "Plastskuggning"),
+ ("ec.stylize.ccrepetile", "Edge Tile Repeat", "Kantupprepning"),
+ ("ec.stylize.ccthreshold", "Channel Threshold", "Kanaltröskel"),
+ ("ec.stylize.ccthresholdrgb", "RGB Threshold", "RGB-tröskel"),
+ ("ec.stylize.ccvignette", "Vignette", "Vinjettering"),
("ec.stylize.coloremboss", "Color Emboss", "Färgrelief"),
("ec.stylize.emboss", "Emboss", "Relief"),
("ec.stylize.findedges", "Find Edges", "Hitta kanter"),
@@ -2146,8 +2153,8 @@ const SWEDISH: &[Row] = &[
("ec.stylize.threshold", "Threshold", "Tröskel"),
("ec.text.numbers", "Numbers", "Siffror"),
("ec.text.timecode", "Timecode", "Tidskod"),
- ("ec.time.ccforcemotionblur", "CC Force Motion Blur", "CC Tvinga rörelseoskärpa"),
- ("ec.time.ccwidetime", "CC Wide Time", "CC Bred tid"),
+ ("ec.time.ccforcemotionblur", "Temporal Motion Blur", "Tidsbaserad rörelseoskärpa"),
+ ("ec.time.ccwidetime", "Temporal Blend", "Tidsblandning"),
("ec.time.echo", "Echo", "Eko"),
("ec.time.pixelmotionblur", "Pixel Motion Blur", "Pixelrörelseoskärpa"),
("ec.time.posterizetime", "Posterize Time", "Posterisera tid"),
@@ -2156,23 +2163,23 @@ const SWEDISH: &[Row] = &[
("ec.time.timewarp", "Timewarp", "Tidsförvrängning"),
("ec.transition.blockdissolve", "Block Dissolve", "Blockövertoning"),
("ec.transition.cardwipe", "Card Wipe", "Kortridå"),
- ("ec.transition.ccglasswipe", "CC Glass Wipe", "CC Glasridå"),
- ("ec.transition.ccgridwipe", "CC Grid Wipe", "CC Rutnätsridå"),
- ("ec.transition.ccimagewipe", "CC Image Wipe", "CC Bildridå"),
- ("ec.transition.ccjaws", "CC Jaws", "CC Käftar"),
- ("ec.transition.cclightwipe", "CC Light Wipe", "CC Ljusridå"),
- ("ec.transition.cclinesweep", "CC Line Sweep", "CC Linjesvep"),
- ("ec.transition.ccradialscalewipe", "CC Radial ScaleWipe", "CC Radiell skalridå"),
- ("ec.transition.ccscalewipe", "CC Scale Wipe", "CC Skalridå"),
- ("ec.transition.cctwister", "CC Twister", "CC Virvel"),
- ("ec.transition.ccwarpomatic", "CC WarpoMatic", "CC WarpoMatic"),
+ ("ec.transition.ccglasswipe", "Glass Wipe", "Glasövergång"),
+ ("ec.transition.ccgridwipe", "Grid Wipe", "Rutnätsövergång"),
+ ("ec.transition.ccimagewipe", "Luminance Image Wipe", "Luminansbildsövergång"),
+ ("ec.transition.ccjaws", "Serrated Wipe", "Tandad övergång"),
+ ("ec.transition.cclightwipe", "Light Wipe", "Ljusövergång"),
+ ("ec.transition.cclinesweep", "Line Sweep", "Linjesvep"),
+ ("ec.transition.ccradialscalewipe", "Radial Scale Wipe", "Radiell skalövergång"),
+ ("ec.transition.ccscalewipe", "Scale Wipe", "Skalövergång"),
+ ("ec.transition.cctwister", "Twist Wipe", "Vridövergång"),
+ ("ec.transition.ccwarpomatic", "Warp Dissolve", "Förvrängningsupplösning"),
("ec.transition.gradientwipe", "Gradient Wipe", "Gradientridå"),
("ec.transition.iriswipe", "Iris Wipe", "Irisridå"),
("ec.transition.linearwipe", "Linear Wipe", "Linjär ridå"),
("ec.transition.radialwipe", "Radial Wipe", "Radiell ridå"),
("ec.transition.venetian", "Venetian Blinds", "Persienner"),
("ec.utility.applylut", "Apply Color LUT", "Använd färg-LUT"),
- ("ec.utility.ccoverbrights", "CC Overbrights", "CC Överljust"),
+ ("ec.utility.ccoverbrights", "Out-of-Range Display", "Visa utanför intervallet"),
("ec.utility.cineon", "Cineon Converter", "Cineon-konverterare"),
("ec.utility.colorprofileconverter", "Color Profile Converter", "Färgprofilkonverterare"),
("ec.utility.facemeasurements", "Face Measurements", "Ansiktsmått"),
@@ -2226,6 +2233,38 @@ mod tests {
use crate::i18n::set_current;
use effectcraft_engine::effects;
+ #[test]
+ fn legacy_effect_names_draw_current_labels_without_changing_custom_names() {
+ for language in ["en", "ja", "zh-hans", "zh-hant", "fr", "sv", "ka", "cs", "de", "es", "pl", "pt-br", "ru", "uk"] {
+ set_current(language);
+ for spec in effects::registry() {
+ let translated = name(spec.id, spec.name);
+ for alias in effects::aliases(spec.id) {
+ assert_eq!(group(spec.id, alias), translated, "{language}: {alias}");
+ assert!(matches(spec.id, alias, &spec.name.to_lowercase()), "{language}: search current name of {alias}");
+ assert!(matches(spec.id, spec.name, &alias.to_lowercase()), "{language}: search legacy name {alias}");
+ assert_eq!(group(spec.id, &format!("{alias} 2")), format!("{translated} 2"));
+ let custom = format!("{alias} custom");
+ assert_eq!(group(spec.id, &custom), custom);
+ }
+ }
+ }
+ set_current("en");
+ }
+
+ #[test]
+ fn localized_effect_names_do_not_reintroduce_legacy_branding() {
+ for (language, rows) in COMPLETE.iter().chain(PARTIAL) {
+ for (_, _, translated) in *rows {
+ let label = translated.to_lowercase();
+ assert!(!label.starts_with("cc "), "{language}: {translated}");
+ for mark in ["lumetri", "mercury", "mocha", "keylight"] {
+ assert!(!label.contains(mark), "{language}: {translated}");
+ }
+ }
+ }
+ }
+
/// Every row names an effect in the registry and still carries its English name, so a rename
/// or a removal fails here rather than attaching a translation to a different effect.
#[test]
@@ -2242,6 +2281,20 @@ mod tests {
}
}
+ /// Two effects that draw one name cannot be told apart in the Effect menu, Effect Controls or
+ /// Effects & Presets, so every catalog names each effect it covers distinctly.
+ #[test]
+ fn display_names_are_unique_in_every_catalog() {
+ for (language, rows) in COMPLETE.iter().chain(PARTIAL) {
+ let mut seen: std::collections::HashMap<&str, &str> = std::collections::HashMap::new();
+ for (id, _, translated) in *rows {
+ if let Some(other) = seen.insert(translated, id) {
+ assert_ne!(other, *id, "{language}: {id} and {other} are both {translated:?}");
+ }
+ }
+ }
+ }
+
/// Rows are keyed by id, so a repeated id would shadow a translation.
#[test]
fn ids_are_unique() {
diff --git a/crates/ui-egui/src/i18n/ui.rs b/crates/ui-egui/src/i18n/ui.rs
index 72ba2a719..259fe2d60 100644
--- a/crates/ui-egui/src/i18n/ui.rs
+++ b/crates/ui-egui/src/i18n/ui.rs
@@ -708,8 +708,8 @@ const JAPANESE: &[(&str, &str)] = &[
("Import Photoshop File", "Photoshopファイルを読み込み"),
("Interpret Unlabeled Alpha As", "ラベルのないアルファの解釈"),
("Join the ArtCraft Discord", "ArtCraftのDiscordに参加"),
- ("Mercury GPU Acceleration ({})", "Mercury GPUアクセラレーション({})"),
- ("Mercury Software Only", "Mercuryソフトウェアのみ"),
+ ("GPU Acceleration ({})", "GPUアクセラレーション({})"),
+ ("Software Rendering", "ソフトウェアレンダリング"),
("OCIO (built-in ACES config)", "OCIO(組み込みACES設定)"),
("Off (Final Quality)", "オフ(最終品質)"),
("OpenGL (compatibility)", "OpenGL(互換)"),
@@ -1119,7 +1119,7 @@ const JAPANESE: &[(&str, &str)] = &[
("Script Console", "スクリプトコンソール"),
("Essential Graphics", "エッセンシャルグラフィックス"),
("ScriptUI Panel", "ScriptUIパネル"),
- ("Lumetri Scopes", "Lumetriスコープ"),
+ ("Video Scopes", "ビデオスコープ"),
("Media Browser", "メディアブラウザー"),
("Content-Aware Fill", "コンテンツに応じた塗りつぶし"),
("Create Nulls From Paths", "パスからヌルを作成"),
@@ -1319,6 +1319,7 @@ const JAPANESE: &[(&str, &str)] = &[
("per second", "毎秒"),
("Waveform", "波形"),
("steps", "ステップ"),
+ ("GPU Acceleration (no GPU: software)", "GPUアクセラレーション(GPUなし:ソフトウェア)"),
];
const SIMPLIFIED_CHINESE: &[(&str, &str)] = &[
@@ -1838,8 +1839,8 @@ const SIMPLIFIED_CHINESE: &[(&str, &str)] = &[
("Import Photoshop File", "导入 Photoshop 文件"),
("Interpret Unlabeled Alpha As", "将未标记的 Alpha 解释为"),
("Join the ArtCraft Discord", "加入 ArtCraft Discord"),
- ("Mercury GPU Acceleration ({})", "Mercury GPU 加速({})"),
- ("Mercury Software Only", "仅 Mercury 软件"),
+ ("GPU Acceleration ({})", "GPU 加速({})"),
+ ("Software Rendering", "软件渲染"),
("OCIO (built-in ACES config)", "OCIO(内置 ACES 配置)"),
("Off (Final Quality)", "关闭(最终质量)"),
("OpenGL (compatibility)", "OpenGL(兼容)"),
@@ -2282,7 +2283,7 @@ const SIMPLIFIED_CHINESE: &[(&str, &str)] = &[
("Script Console", "脚本控制台"),
("Essential Graphics", "基本图形"),
("ScriptUI Panel", "ScriptUI 面板"),
- ("Lumetri Scopes", "Lumetri 示波器"),
+ ("Video Scopes", "视频示波器"),
("Media Browser", "媒体浏览器"),
("Content-Aware Fill", "内容识别填充"),
("Create Nulls From Paths", "从路径创建空对象"),
@@ -2435,6 +2436,7 @@ const SIMPLIFIED_CHINESE: &[(&str, &str)] = &[
("Blend Mode", "混合模式"),
("Show mesh", "显示网格"),
("Record Options...", "记录选项..."),
+ ("GPU Acceleration (no GPU: software)", "GPU 加速(无 GPU:软件)"),
];
/// Swedish (`sv`), written from the English source.
@@ -2952,8 +2954,8 @@ const SWEDISH: &[(&str, &str)] = &[
("Import Photoshop File", "Importera Photoshop-fil"),
("Interpret Unlabeled Alpha As", "Tolka omärkt alfa som"),
("Join the ArtCraft Discord", "Gå med i ArtCraft på Discord"),
- ("Mercury GPU Acceleration ({})", "Mercury GPU-acceleration ({})"),
- ("Mercury Software Only", "Endast Mercury-programvara"),
+ ("GPU Acceleration ({})", "GPU-acceleration ({})"),
+ ("Software Rendering", "Programvarurendering"),
("OCIO (built-in ACES config)", "OCIO (inbyggd ACES-konfiguration)"),
("Off (Final Quality)", "Av (slutlig kvalitet)"),
("OpenGL (compatibility)", "OpenGL (kompatibilitet)"),
@@ -3194,7 +3196,7 @@ const SWEDISH: &[(&str, &str)] = &[
("Drop {} files to import", "Släpp {} filer för att importera"),
("Effects", "Effekter"),
("Label of {}: {}", "Etikett för {}: {}"),
- ("Mercury GPU Acceleration (no GPU: software)", "Mercury GPU-acceleration (ingen GPU: programvara)"),
+ ("GPU Acceleration (no GPU: software)", "GPU-acceleration (ingen GPU: programvara)"),
("Only one project can be opened per drop; skipped {} more", "Bara ett projekt kan öppnas per släpp; hoppade över {} till"),
("Open in Essential Graphics", "Öppna i Grundläggande grafik"),
("Original color: click to go back to it", "Originalfärg: klicka för att återgå till den"),
@@ -3443,7 +3445,7 @@ const SWEDISH: &[(&str, &str)] = &[
("Script Console", "Skriptkonsol"),
("Essential Graphics", "Grundläggande grafik"),
("ScriptUI Panel", "ScriptUI-panel"),
- ("Lumetri Scopes", "Lumetri-scope"),
+ ("Video Scopes", "Videoskop"),
("Media Browser", "Mediebläddrare"),
("Content-Aware Fill", "Innehållsmedveten fyllning"),
("Create Nulls From Paths", "Skapa nullobjekt från banor"),
@@ -4612,7 +4614,7 @@ const TRADITIONAL_CHINESE: &[(&str, &str)] = &[
("Script Console", "指令碼主控台"),
("Essential Graphics", "基本圖形"),
("ScriptUI Panel", "ScriptUI 面板"),
- ("Lumetri Scopes", "Lumetri 示波器"),
+ ("Video Scopes", "視訊示波器"),
("Media Browser", "媒體瀏覽器"),
("Content-Aware Fill", "內容感知填色"),
("Create Nulls From Paths", "從路徑建立空物件"),
@@ -4765,6 +4767,9 @@ const TRADITIONAL_CHINESE: &[(&str, &str)] = &[
("Blend Mode", "混合模式"),
("Show mesh", "顯示網格"),
("Record Options...", "記錄選項..."),
+ ("Software Rendering", "軟體算繪"),
+ ("GPU Acceleration ({})", "GPU 加速({})"),
+ ("GPU Acceleration (no GPU: software)", "GPU 加速(無 GPU:軟體)"),
];
/// Ukrainian (uk): original translations of the same interface rows as the Chinese catalogs.
@@ -5305,8 +5310,8 @@ const UKRAINIAN: &[(&str, &str)] = &[
("Import Photoshop File", "Імпорт файлу Photoshop"),
("Interpret Unlabeled Alpha As", "Інтерпретувати непозначену альфу як"),
("Join the ArtCraft Discord", "Приєднатися до Discord ArtCraft"),
- ("Mercury GPU Acceleration ({})", "Прискорення Mercury GPU ({})"),
- ("Mercury Software Only", "Лише програмний Mercury"),
+ ("GPU Acceleration ({})", "Прискорення GPU ({})"),
+ ("Software Rendering", "Програмне відтворення"),
("OCIO (built-in ACES config)", "OCIO (вбудована конфігурація ACES)"),
("Off (Final Quality)", "Вимкнено (остаточна якість)"),
("OpenGL (compatibility)", "OpenGL (сумісність)"),
@@ -5352,6 +5357,8 @@ const UKRAINIAN: &[(&str, &str)] = &[
("Project", "Проєкт"),
("Total Offset", "Загальний зсув"),
("Per Layer", "На шар"),
+ ("Video Scopes", "Відеоскопи"),
+ ("GPU Acceleration (no GPU: software)", "Прискорення GPU (без GPU: програмне)"),
];
// Brazilian Portuguese.
@@ -5984,7 +5991,7 @@ const PORTUGUESE: &[(&str, &str)] = &[
("Guess", "Adivinhar"),
("Import Image Sequence", "Importar sequência de imagens"),
("Import PDF / Illustrator File", "Importar arquivo PDF / Illustrator"),
- ("Mercury Software Only", "Apenas software Mercury"),
+ ("Software Rendering", "Renderização por software"),
("OCIO (built-in ACES config)", "OCIO (config do ACES integrado)"),
("Still Duration", "Duração da imagem fixa"),
("Straight", "Direto"),
@@ -6091,7 +6098,7 @@ const PORTUGUESE: &[(&str, &str)] = &[
("Light", "Claro"),
("Lines", "Linhas"),
("Memory & CPU", "Memória e CPU"),
- ("Mercury GPU Acceleration ({})", "Aceleração de GPU Mercury ({})"),
+ ("GPU Acceleration ({})", "Aceleração de GPU ({})"),
("Off", "Desativado"),
("Options", "Opções"),
("Overlay", "Sobrepor"),
@@ -6116,6 +6123,8 @@ const PORTUGUESE: &[(&str, &str)] = &[
("Video", "Vídeo"),
("channel", "canal"),
("files", "arquivos"),
+ ("Video Scopes", "Escopos de vídeo"),
+ ("GPU Acceleration (no GPU: software)", "Aceleração de GPU (sem GPU: software)"),
];
/// Polish (pl): original translations covering every row in the Chinese panel catalogs.
@@ -6634,8 +6643,8 @@ const POLISH: &[(&str, &str)] = &[
("Import Photoshop File", "Importuj plik Photoshopa"),
("Interpret Unlabeled Alpha As", "Interpretuj nieoznaczoną alfę jako"),
("Join the ArtCraft Discord", "Dołącz do Discorda ArtCraft"),
- ("Mercury GPU Acceleration ({})", "Akceleracja Mercury GPU ({})"),
- ("Mercury Software Only", "Tylko programowy Mercury"),
+ ("GPU Acceleration ({})", "Akceleracja GPU ({})"),
+ ("Software Rendering", "Renderowanie programowe"),
("OCIO (built-in ACES config)", "OCIO (wbudowana konfiguracja ACES)"),
("Off (Final Quality)", "Wył. (jakość końcowa)"),
("OpenGL (compatibility)", "OpenGL (zgodność)"),
@@ -6873,6 +6882,8 @@ const POLISH: &[(&str, &str)] = &[
("Resolution:", "Rozdzielczość:"),
("Guide Layer", "Warstwa pomocnicza"),
("Layer Styles", "Style warstwy"),
+ ("Video Scopes", "Wskaźniki wideo"),
+ ("GPU Acceleration (no GPU: software)", "Akceleracja GPU (bez GPU: programowa)"),
];
/// Czech (cs): original translations covering every row in the Chinese panel catalogs.
@@ -7385,8 +7396,8 @@ const CZECH: &[(&str, &str)] = &[
("Import Photoshop File", "Importovat soubor Photoshop"),
("Interpret Unlabeled Alpha As", "Interpretovat neoznačenou alfu jako"),
("Join the ArtCraft Discord", "Připojit se na Discord ArtCraft"),
- ("Mercury GPU Acceleration ({})", "GPU akcelerace Mercury ({})"),
- ("Mercury Software Only", "Pouze softwarové zpracování Mercury"),
+ ("GPU Acceleration ({})", "Akcelerace GPU ({})"),
+ ("Software Rendering", "Softwarové vykreslování"),
("OCIO (built-in ACES config)", "OCIO (vestavěná konfigurace ACES)"),
("Off (Final Quality)", "Vypnuto (finální kvalita)"),
("OpenGL (compatibility)", "OpenGL (kompatibilita)"),
@@ -7437,6 +7448,8 @@ const CZECH: &[(&str, &str)] = &[
("Variable fonts only", "Jen proměnná písma"),
("Total Offset", "Celkový posun"),
("Per Layer", "Na vrstvu"),
+ ("Video Scopes", "Videoskopy"),
+ ("GPU Acceleration (no GPU: software)", "Akcelerace GPU (bez GPU: software)"),
];
/// Spanish: neutral, tú, sentence case; the same source strings as the Chinese catalogs, in the same
@@ -7965,8 +7978,8 @@ const SPANISH: &[(&str, &str)] = &[
("Import Photoshop File", "Importar archivo de Photoshop"),
("Interpret Unlabeled Alpha As", "Interpretar alfa sin etiquetar como"),
("Join the ArtCraft Discord", "Únete al Discord de ArtCraft"),
- ("Mercury GPU Acceleration ({})", "Aceleración por GPU Mercury ({})"),
- ("Mercury Software Only", "Solo software Mercury"),
+ ("GPU Acceleration ({})", "Aceleración por GPU ({})"),
+ ("Software Rendering", "Renderizado por software"),
("OCIO (built-in ACES config)", "OCIO (configuración ACES integrada)"),
("Off (Final Quality)", "Desactivado (calidad final)"),
("OpenGL (compatibility)", "OpenGL (compatibilidad)"),
@@ -8007,6 +8020,8 @@ const SPANISH: &[(&str, &str)] = &[
("After Effects project", "Proyecto de After Effects"),
("Lottie animation", "Animación de Lottie"),
("Project", "Proyecto"),
+ ("Video Scopes", "Monitores de vídeo"),
+ ("GPU Acceleration (no GPU: software)", "Aceleración por GPU (sin GPU: software)"),
];
/// Georgian (ka): every row of the Chinese catalogs, in the same order (the tests keep them in step).
@@ -8533,8 +8548,8 @@ const GEORGIAN: &[(&str, &str)] = &[
("Import Photoshop File", "Photoshop ფაილის იმპორტი"),
("Interpret Unlabeled Alpha As", "უცნობი ალფას ინტერპრეტაცია"),
("Join the ArtCraft Discord", "შემოგვიერთდით Discord-ზე"),
- ("Mercury GPU Acceleration ({})", "GPU აჩქარება ({})"),
- ("Mercury Software Only", "მხოლოდ Mercury Software"),
+ ("GPU Acceleration ({})", "GPU აჩქარება ({})"),
+ ("Software Rendering", "პროგრამული რენდერი"),
("OCIO (built-in ACES config)", "OCIO (ჩაშენებული ACES კონფიგურაცია)"),
("Off (Final Quality)", "გამორთული (საბოლოო ხარისხი)"),
("OpenGL (compatibility)", "OpenGL (თავსებადობა)"),
@@ -8766,6 +8781,7 @@ const GEORGIAN: &[(&str, &str)] = &[
("Total Offset", "ჯამური წანაცვლება"),
("Per Layer", "შრიდან შრემდე"),
("Track", "ტრეკინგი"),
+ ("Video Scopes", "ვიდეოსკოპები"),
];
/// Georgian rows for interface text no other catalog has yet: strings the panels already send
@@ -8956,7 +8972,7 @@ const GEORGIAN_PANELS: &[(&str, &str)] = &[
("Solid Settings", "სოლიდის პარამეტრები"),
("Save as Template", "შაბლონად შენახვა"),
("My Custom RGB", "ჩემი მორგებული RGB"),
- ("Mercury GPU Acceleration (no GPU: software)", "Mercury GPU აჩქარება (GPU არ არის: პროგრამული)"),
+ ("GPU Acceleration (no GPU: software)", "GPU აჩქარება (GPU არ არის: პროგრამული)"),
("Sort by {}, {}", "დალაგება: {}, {}"),
("Sort by {}", "დალაგება: {}"),
("Label of {}: {}", "{}-ის იარლიყი: {}"),
@@ -9515,8 +9531,8 @@ const FRENCH: &[(&str, &str)] = &[
("Import Photoshop File", "Importer un fichier Photoshop"),
("Interpret Unlabeled Alpha As", "Interpréter l’alpha non étiqueté comme"),
("Join the ArtCraft Discord", "Rejoindre le Discord ArtCraft"),
- ("Mercury GPU Acceleration ({})", "Accélération GPU Mercury ({})"),
- ("Mercury Software Only", "Mercury, logiciel uniquement"),
+ ("GPU Acceleration ({})", "Accélération GPU ({})"),
+ ("Software Rendering", "Rendu logiciel"),
("OCIO (built-in ACES config)", "OCIO (configuration ACES intégrée)"),
("Off (Final Quality)", "Désactivé (qualité finale)"),
("OpenGL (compatibility)", "OpenGL (compatibilité)"),
@@ -9931,7 +9947,7 @@ const FRENCH: &[(&str, &str)] = &[
("Solid Settings", "Paramètres du solide"),
("Save as Template", "Enregistrer en tant que modèle"),
("My Custom RGB", "Mon RVB personnalisé"),
- ("Mercury GPU Acceleration (no GPU: software)", "Accélération GPU Mercury (aucun GPU : logiciel)"),
+ ("GPU Acceleration (no GPU: software)", "Accélération GPU (aucun GPU : logiciel)"),
("Sort by {}, {}", "Trier par {}, {}"),
("Sort by {}", "Trier par {}"),
("Label of {}: {}", "Étiquette de {} : {}"),
@@ -10052,7 +10068,7 @@ const FRENCH: &[(&str, &str)] = &[
("Script Console", "Console de scripts"),
("Essential Graphics", "Graphiques essentiels"),
("ScriptUI Panel", "Panneau ScriptUI"),
- ("Lumetri Scopes", "Scopes Lumetri"),
+ ("Video Scopes", "Oscilloscopes vidéo"),
("Media Browser", "Explorateur de médias"),
("Content-Aware Fill", "Remplissage adapté au contenu"),
("Create Nulls From Paths", "Créer des objets nuls à partir de tracés"),
@@ -10271,6 +10287,26 @@ const FRENCH: &[(&str, &str)] = &[
mod tests {
use super::*;
+ /// Check rendered feature labels only. Format names, compatibility tokens and user text
+ /// are not subject to this guard, and a missing translation keeps its English fallback.
+ #[test]
+ fn renamed_panel_labels_do_not_reintroduce_vendor_names() {
+ for language in ["en", "ja", "zh-hans", "zh-hant", "fr", "sv", "ka", "cs", "de", "es", "pl", "pt-br", "ru", "uk"] {
+ set_current(language);
+ for source in ["GPU Acceleration ({})", "GPU Acceleration (no GPU: software)", "Software Rendering", "Video Scopes"] {
+ let rendered = tr(source);
+ assert!(!rendered.is_empty(), "{language}: {source}");
+ let label = rendered.to_lowercase();
+ for mark in ["lumetri", "mercury", "mocha", "keylight"] {
+ assert!(!label.contains(mark), "{language}: {source} -> {rendered}");
+ }
+ }
+ // A real interchange label remains factual, not rewritten or rejected.
+ assert!(!tr("Export Adobe Premiere Pro Project").is_empty());
+ }
+ set_current("en");
+ }
+
/// The interface text that has moved into this catalog. Add a panel here when you convert it;
/// `every_row_is_used_by_a_converted_panel` then looks for its rows' English sources in it.
pub(super) const CONVERTED: &[(&str, &str)] = &[
diff --git a/crates/ui-egui/src/panels/forms.rs b/crates/ui-egui/src/panels/forms.rs
index 635ef9a43..e83530fa4 100644
--- a/crates/ui-egui/src/panels/forms.rs
+++ b/crates/ui-egui/src/panels/forms.rs
@@ -338,11 +338,11 @@ fn interpret_footage_form(s: &effectcraft_engine::Session, proxy: bool, base: &m
/// The Project Settings dialog's title and fields.
fn project_settings_form(s: &effectcraft_engine::Session) -> (String, Vec) {
let st = &s.project.settings;
- // The catalogue row is `Mercury GPU Acceleration ({})`, so the value goes through
+ // The catalogue row is `GPU Acceleration ({})`, so the value goes through
// tr_args: wrapping the assembled string in tr() would look up the backend's name.
let gpu_label = match &s.accel {
- Some(a) => tr_args("Mercury GPU Acceleration ({})", &[&a.name()]),
- None => tr("Mercury GPU Acceleration (no GPU: software)").to_string(),
+ Some(a) => tr_args("GPU Acceleration ({})", &[&a.name()]),
+ None => tr("GPU Acceleration (no GPU: software)").to_string(),
};
let depth = match st.bit_depth.label() {
l if l.starts_with("16") => 1,
@@ -436,7 +436,7 @@ fn project_settings_form(s: &effectcraft_engine::Session) -> (String, Vec
Field::choice(
"renderer",
"Video rendering and effects",
- &[(gpu_label.as_str(), json!("gpu")), ("Mercury Software Only", json!("software"))],
+ &[(gpu_label.as_str(), json!("gpu")), ("Software Rendering", json!("software"))],
usize::from(!st.gpu_acceleration),
),
],
@@ -1050,6 +1050,18 @@ pub fn show_view_options(app: &mut EffectcraftApp, ctx: &egui::Context, t: &Toke
mod tests {
use super::*;
+ #[test]
+ fn renderer_form_keeps_descriptive_labels_and_stable_option_values() {
+ crate::i18n::set_current("en");
+ let (_, fields) = project_settings_form(&effectcraft_engine::Session::default());
+ let renderer = fields.iter().find(|field| field.key == "renderer").unwrap();
+ let FieldKind::Choice { options, .. } = &renderer.kind else { panic!("renderer must be a choice") };
+ assert_eq!(
+ options.as_slice(),
+ &[("GPU Acceleration (no GPU: software)".to_string(), json!("gpu")), ("Software Rendering".to_string(), json!("software"))]
+ );
+ }
+
#[test]
fn form_params_build_arrays_and_choices() {
let f = Form {
diff --git a/crates/ui-egui/src/state.rs b/crates/ui-egui/src/state.rs
index 60a30e97e..612aa0a10 100644
--- a/crates/ui-egui/src/state.rs
+++ b/crates/ui-egui/src/state.rs
@@ -756,7 +756,7 @@ pub struct UiState {
/// Flowchart panel options (layers, effects, solids, direction, root comp).
#[serde(default)]
pub flowchart: crate::panels::flowchart::FlowOptions,
- /// Lumetri Scopes panel options.
+ /// Video Scopes panel options.
#[serde(default)]
pub scopes: crate::panels::scopes_panel::ScopesState,
}
diff --git a/crates/ui-egui/src/updates_ui.rs b/crates/ui-egui/src/updates_ui.rs
index bb8187f56..316e34ac4 100644
--- a/crates/ui-egui/src/updates_ui.rs
+++ b/crates/ui-egui/src/updates_ui.rs
@@ -91,6 +91,7 @@ pub(crate) fn show(app: &mut EffectcraftApp, ctx: &egui::Context) {
rt.updater.dismiss_status();
}
CheckResultResponse::CheckAgain => rt.updater.check_now(ctx),
+ CheckResultResponse::RestartToUpdate => rt.updater.restart_to_update(),
}
// A check that found a release leaves the status idle and the startup prompt takes over.
if matches!(rt.updater.status(), Status::Idle) && !rt.check_requested {
diff --git a/crates/ui-egui/tests/it/ui_angles.rs b/crates/ui-egui/tests/it/ui_angles.rs
index 007e11286..40ad17bc1 100644
--- a/crates/ui-egui/tests/it/ui_angles.rs
+++ b/crates/ui-egui/tests/it/ui_angles.rs
@@ -38,7 +38,7 @@ fn harness(panel: Panel, angle: f64) -> (Harness<'static, EffectcraftApp>, u64,
s.execute("comp.new", json!({"name": "Angles", "width": 320, "height": 180, "duration": 4})).unwrap();
let layer = s.execute("layer.newSolid", json!({"name": "Plate", "color": "#40b080"})).unwrap()["layer"].as_u64().unwrap();
let uid = if matches!(panel, Panel::EffectControls) {
- let fx = s.execute("effect.apply", json!({"layer": layer, "effect": "CC Bend It"})).unwrap()["effects"][0].as_u64().unwrap();
+ let fx = s.execute("effect.apply", json!({"layer": layer, "effect": "Two-Point Bend"})).unwrap()["effects"][0].as_u64().unwrap();
s.active_comp().unwrap().layer(LayerId(layer)).unwrap().props.find_group(fx).unwrap().get("bend").unwrap().uid
} else {
s.active_comp().unwrap().layer(LayerId(layer)).unwrap().props.prop("transform/rotation").unwrap().uid
diff --git a/crates/ui-egui/tests/it/ui_color_hex.rs b/crates/ui-egui/tests/it/ui_color_hex.rs
index 4f8a8ab14..8a5a39b8e 100644
--- a/crates/ui-egui/tests/it/ui_color_hex.rs
+++ b/crates/ui-egui/tests/it/ui_color_hex.rs
@@ -1,4 +1,4 @@
-//! The colour picker every colour input opens: its hex field sets an effect's colour (CC Toner),
+//! The colour picker every colour input opens: its hex field sets an effect's colour (Multi-Tone Tint),
//! the dialogs' colour button stores sRGB (egui's own `color_edit_button_rgba` read the stored
//! sRGB values as linear, so mid-grey `#808080` was stored as `#373737`), the square, slider and
//! HSB / RGB fields set the colour, and Cancel / Escape / the original swatch restore it.
@@ -45,7 +45,7 @@ fn hex_code_sets_an_effect_colour() {
let mut s = Session::default();
s.execute("comp.new", json!({"name": "Hex", "width": 320, "height": 180, "duration": 4})).unwrap();
let layer = s.execute("layer.newSolid", json!({"name": "Plate", "color": "#40b080"})).unwrap()["layer"].as_u64().unwrap();
- let fx = s.execute("effect.apply", json!({"layer": layer, "effect": "CC Toner"})).unwrap()["effects"][0].as_u64().unwrap();
+ let fx = s.execute("effect.apply", json!({"layer": layer, "effect": "Multi-Tone Tint"})).unwrap()["effects"][0].as_u64().unwrap();
let uid = s.active_comp().unwrap().layer(LayerId(layer)).unwrap().props.find_group(fx).unwrap().get("midtones").unwrap().uid;
s.state.selected_layers = vec![LayerId(layer)];
let mut app = EffectcraftApp::new(s);
diff --git a/crates/ui-egui/tests/it/ui_effect_controls.rs b/crates/ui-egui/tests/it/ui_effect_controls.rs
index 1db059220..15802d889 100644
--- a/crates/ui-egui/tests/it/ui_effect_controls.rs
+++ b/crates/ui-egui/tests/it/ui_effect_controls.rs
@@ -260,14 +260,14 @@ fn the_eyedropper_stays_armed_until_the_viewer_has_a_frame() {
}
}
-/// Key Light's Screen Colour eyedropper picks from the effect's input: the shown frame is
+/// Screen Color Key's Screen Colour eyedropper picks from the effect's input: the shown frame is
/// already keyed (the default screen colour takes most of a green), so sampling it would miss.
#[test]
fn keyer_eyedropper_picks_the_screen_from_the_effect_input() {
let mut s = Session::default();
s.execute("comp.new", json!({"name": "Key", "width": 320, "height": 180, "frameRate": 30, "duration": 1})).unwrap();
let screen = s.execute("layer.newSolid", json!({"name": "Screen", "color": "#30b050"})).unwrap()["layer"].as_u64().unwrap();
- let fx = s.execute("effect.apply", json!({"layers": [screen], "effect": "Key Light"})).unwrap()["effects"][0].as_u64().unwrap();
+ let fx = s.execute("effect.apply", json!({"layers": [screen], "effect": "Screen Color Key"})).unwrap()["effects"][0].as_u64().unwrap();
let prop = layer(&s, screen).effects().unwrap().groups().find(|g| g.uid == fx).and_then(|g| g.get("screenColour")).map(|p| p.uid).unwrap();
s.state.selected_layers = vec![LayerId(screen)];
let mut app = EffectcraftApp::new(s);
@@ -295,7 +295,7 @@ fn keyer_eyedropper_picks_the_screen_from_the_effect_input() {
fn command_clicking_an_effect_twirl_closes_and_opens_its_groups() {
let (app, x) = app();
let mut h = Harness::builder().with_size(egui::vec2(1600.0, 1000.0)).build_eframe(|_| app);
- let fx = h.state_mut().session.execute("effect.apply", json!({"layers": [x.small], "effect": "Lumetri Color"})).unwrap()["effects"][0].as_u64().unwrap();
+ let fx = h.state_mut().session.execute("effect.apply", json!({"layers": [x.small], "effect": "Color Grading"})).unwrap()["effects"][0].as_u64().unwrap();
// Only this effect open, so its header is on screen.
let l = layer(&h.state().session, x.small);
let others: Vec = l.effects().unwrap().groups().map(|g| g.uid).filter(|u| *u != fx).collect();
diff --git a/crates/ui-egui/tests/it/ui_effect_drop_highlight.rs b/crates/ui-egui/tests/it/ui_effect_drop_highlight.rs
index 6c0ede47a..ddef6c94b 100644
--- a/crates/ui-egui/tests/it/ui_effect_drop_highlight.rs
+++ b/crates/ui-egui/tests/it/ui_effect_drop_highlight.rs
@@ -13,7 +13,7 @@ fn rect(h: &Harness<'_, EffectcraftApp>, id: &str) -> Rect {
fn drag_to(h: &mut Harness<'_, EffectcraftApp>, p: Pos2) {
h.input_mut().events.push(Event::PointerMoved(p));
h.input_mut().events.push(Event::PointerButton { pos: p, button: PointerButton::Primary, pressed: true, modifiers: Modifiers::NONE });
- egui::DragAndDrop::set_payload(&h.ctx, DragPayload::Effect("CC Bend It".into()));
+ egui::DragAndDrop::set_payload(&h.ctx, DragPayload::Effect("Two-Point Bend".into()));
h.run_steps(2);
}
diff --git a/crates/ui-egui/tests/it/ui_fx_editors.rs b/crates/ui-egui/tests/it/ui_fx_editors.rs
index b9530fdf4..b4d999311 100644
--- a/crates/ui-egui/tests/it/ui_fx_editors.rs
+++ b/crates/ui-egui/tests/it/ui_fx_editors.rs
@@ -130,7 +130,7 @@ fn undo(h: &mut Harness<'_, EffectcraftApp>) {
#[test]
fn lumetri_rgb_and_hue_saturation_curve_editors() {
- let (s0, l, fx) = with_effect("Lumetri Color");
+ let (s0, l, fx) = with_effect("Color Grading");
let mut h = harness(s0);
only_groups(&mut h, l, fx, &["curves", "rgbCurves", "hueSaturationCurves"]);
let pre = format!("effectControls.effect.{fx}.lumetri.rgbCurves");
diff --git a/crates/ui-egui/tests/it/ui_live_preview.rs b/crates/ui-egui/tests/it/ui_live_preview.rs
index e72856bfc..abe3cc427 100644
--- a/crates/ui-egui/tests/it/ui_live_preview.rs
+++ b/crates/ui-egui/tests/it/ui_live_preview.rs
@@ -77,12 +77,12 @@ fn position_anchor_and_effect_edits_present_intermediate_pixels() {
(None, "transform/position", json!([22, 18, 0]), json!([18, 18, 0])),
(None, "transform/anchor", json!([9, 8, 0]), json!([6, 8, 0])),
(Some("Gaussian Blur"), "blurriness", json!(3), json!(6)),
- (Some("CC Radial Fast Blur"), "center", json!([4, 4]), json!([18, 12])),
+ (Some("Fast Radial Blur"), "center", json!([4, 4]), json!([18, 12])),
] {
let mut session = Session::default();
session.execute("comp.new", json!({"width":64,"height":36,"duration":1})).unwrap();
let layer = session.execute("layer.newSolid", json!({"color":"#ffffff","width":24,"height":16})).unwrap()["layer"].as_u64().unwrap();
- if effect == Some("CC Radial Fast Blur") {
+ if effect == Some("Fast Radial Blur") {
// A uniform solid is invariant under a radial blur; give the point edit visible detail.
session.execute("effect.apply", json!({"layers":[layer],"effect":"Gradient Ramp"})).unwrap();
}
diff --git a/crates/ui-egui/tests/it/ui_parameter_spacing.rs b/crates/ui-egui/tests/it/ui_parameter_spacing.rs
index 71b70a14e..167029f7c 100644
--- a/crates/ui-egui/tests/it/ui_parameter_spacing.rs
+++ b/crates/ui-egui/tests/it/ui_parameter_spacing.rs
@@ -54,7 +54,7 @@ fn nested_groups_keep_indentation_value_alignment_and_effect_gaps_at_fixed_compa
let mut s = Session::default();
s.execute("comp.new", json!({"width":64,"height":36,"duration":1})).unwrap();
s.execute("layer.newSolid", json!({"name":"Plate","color":"#406080"})).unwrap();
- let fx = s.execute("effect.apply", json!({"effect":"Lumetri Color"})).unwrap()["effects"][0].as_u64().unwrap();
+ let fx = s.execute("effect.apply", json!({"effect":"Color Grading"})).unwrap()["effects"][0].as_u64().unwrap();
let next = s.execute("effect.apply", json!({"effect":"Checkbox Control"})).unwrap()["effects"][0].as_u64().unwrap();
let g = s.active_comp().unwrap().layers[0].props.find_group(fx).unwrap();
let basic = g.sub("basicCorrection").unwrap();
diff --git a/crates/ui-egui/tests/it/ui_viewer.rs b/crates/ui-egui/tests/it/ui_viewer.rs
index 7b32fa2ec..e01608e16 100644
--- a/crates/ui-egui/tests/it/ui_viewer.rs
+++ b/crates/ui-egui/tests/it/ui_viewer.rs
@@ -2370,7 +2370,7 @@ fn command_clicking_a_group_twirl_opens_its_whole_tree() {
// twirls open with it, and closed again with it.
let mut h = harness();
let id = layer_id(&h, "Box");
- h.state_mut().session.execute("effect.apply", json!({"effect": "Lumetri Color", "layers": [id]})).unwrap();
+ h.state_mut().session.execute("effect.apply", json!({"effect": "Color Grading", "layers": [id]})).unwrap();
fn walk(g: &effectcraft_engine::project::PropGroup, out: &mut Vec) {
for sg in g.groups() {
out.push(sg.uid);
diff --git a/docs/aep-import.md b/docs/aep-import.md
index 8a83de81f..f41ba3081 100644
--- a/docs/aep-import.md
+++ b/docs/aep-import.md
@@ -135,7 +135,15 @@ Units, the "absent = default" rule and the keyframe templates are the reader's
text does not have; the runs are cut to the text. A range style splits `Hello` into runs of 1,
2 and 2 characters (248, 340).
- **Null objects.** The hidden placeholder solid of a null object is not an item (null layers
- have no source item here).
+ have no source item here). A null's Anchor Point that is not stored is its top-left corner
+ `[0, 0]`, not the centre, as After Effects 2026 reads it back (#3099).
+- **Placed Illustrator and PDF files** (`.ai`, `.pdf`; `Footage::placed_page`): the page is
+ framed as After Effects places it (the ArtBox clipped to the crop box, `/Rotate` ignored) and
+ drawn to fill the stored footage size, which masks and anchors are measured against (#3099).
+ Create Shapes from Vector Layer on such a layer adds a hidden ` Frame` shape layer, the
+ Alpha track matte of every layer it makes, so they show only the frame, as the footage does.
+ EPS files keep their bounding box at their own size: how After Effects sizes them is not
+ measured.
- **Track mattes.** The mode and the matte layer's id are in the target layer's header
(aep-format.md 3.1). The matte layer can be any layer of the composition (407: below its
target); it keeps its stored video switch (After Effects switches it off when the matte is set,
diff --git a/docs/architecture.md b/docs/architecture.md
index 83c03f14f..1e91da215 100644
--- a/docs/architecture.md
+++ b/docs/architecture.md
@@ -43,7 +43,7 @@ cpal or muda. Everything in L0 to L4, the egui UI and the web app also build for
| L3 | `interchange` | Premiere Pro interop through timeline interchange (FCP7 XML, FCPXML, OTIO, EDL, AAF, OMF via FilmCraft's `filmcraft-interchange`): sequences ↔ compositions (§6a) |
| L3 | `aep` | After Effects projects in one crate (like `lottie`): `container` reads and writes the `.aep` container (RIFX `Egg!`) as a lossless chunk tree with a byte-identical round trip, bounded for hostile input, reads the `.aepx` XML form into the same tree, and has a typed view of items, layers, properties, effects, masks, shapes, text, markers, footage, cameras, lights and layer styles, from our own observations of generated files ([aep-format.md](aep-format.md)); `import` maps the typed view into a project (items, settings, compositions, every layer kind, Transform, keyframes, expressions, masks, text, shapes, cameras, lights, mattes, markers, time remapping, layer styles, the effects of a shared table, footage) with a report of everything not imported ([aep-import.md](aep-import.md)); `export` builds every chunk in code (prototypes in the layout After Effects writes, cloned and edited only at verified fields) for the same scope, with a report of everything not exported, verified by opening the output in After Effects ([aep-export.md](aep-export.md)) |
| L3 | `lottie` | Lottie JSON / dotLottie import and export (layers, precomps, eased and spatial keyframes, shapes, masks, mattes) with a warnings list for what Lottie cannot express |
-| L3 | `plugin` | Effect plug-ins: loads sandboxed WebAssembly effect modules (plug-in API v1; the wasmi interpreter behind the `wasm` feature, on for native hosts) into the effect registry ([plugins.md](plugins.md)) |
+| L3 | `plugin` | Effect plug-ins: loads sandboxed WebAssembly effect modules (WebAssembly ABI v1 and v2, the latter with neighbouring frames; the wasmi interpreter behind the `wasm` feature, on for native hosts) into the effect registry ([plugins.md](plugins.md)) |
| L3 | `helper-host` | External effect helpers: finds helper programs, runs each as a child process and registers its effects (plug-in API 2) over a versioned pipe + shared-file protocol; a crashing helper is an error on the effect, never a crash ([external-helpers.md](external-helpers.md), [ADR 0001](adr/0001-external-effect-helpers.md)). Native only |
| L4 | `engine` | `Session`: project, branching undo history, editor state, the command registry and menus, the ScriptUI window model (`scriptui`) |
| L4 | `script` | Scripting: JavaScript (boa) with an After Effects-style object model (`app.project`, comps, layers, properties, render queue) and ScriptUI (dialogs, palettes, dockable panels; script-host threads so dialogs block `show()`), whose edits run engine commands; AE match names |
@@ -121,7 +121,7 @@ are not rewritten, so an expression that computes an effect point on a shape or
other values may need `+ [thisComp.width / 2, thisComp.height / 2]`. Effects that use the layer
bounds (edge pinning, wipes, Offset, generators) now cover the whole comp-sized bounds instead of
their bottom-right quarter. Tracking data of effects that analyse footage (Warp Stabilizer, 3D
-Camera Tracker, Mocha shape) is left as it is: footage has a source rectangle, whose effect space
+Camera Tracker, Tracked Shape Matte) is left as it is: footage has a source rectangle, whose effect space
did not change.
## 4. Rendering
@@ -331,7 +331,7 @@ before conversion (a quarter of the conversions; the result differs from convert
in blocks where colours clip) and resampled from there, as other frames are from full size.
**GPU compositor** (`crates/gpu`; Project Settings ▸ Video Rendering and Effects ▸ Mercury GPU
-Acceleration, the default, or Mercury Software Only; `render.backend`). The CPU renderer is the
+Acceleration, the default, or Software Rendering; `render.backend`). The CPU renderer is the
reference and keeps rendering layer content (sources, masks, CPU effects, layer styles) into the
layer cache. The render crate defines an `Accelerator` trait; `effectcraft_gpu::Gpu` implements it
on wgpu compute shaders. `RenderOpts::backend` picks `Cpu`, `Gpu` or `Auto` (an accelerator
@@ -341,7 +341,7 @@ per comp, output scale and path (readback or viewer display) it averages CPU and
(warm-up on both sides, the fastest warm-up frame starting the average, single stalls capped),
picks the GPU unless the CPU is clearly faster, and re-measures the other side every 48 frames.
Render Queue jobs don't use Auto: every frame of a job renders on the project's renderer (the
-GPU compositor with Mercury GPU Acceleration), so runs of a render don't differ by timing.
+GPU compositor with GPU Acceleration), so runs of a render don't differ by timing.
Light comps (a few small layers, which the CPU composites only within their bounds) then stay on
the CPU instead of paying for full-frame passes and a readback. A GPU frame walks the comp like
`draw_comp`: cached layer buffers are uploaded once per buffer, then transformed with the CPU's
@@ -370,16 +370,16 @@ Preserve Transparency / blend kernels (a 3D track matte renders solo through the
Environment Light Background layers draw their sky in a kernel (`adv_sky`, from
`Renderer::sky_draw`) before the rest of the run, in Classic and Advanced 3D comps. Wireframe
outlines draw on the GPU from the CPU's pixel list (`Renderer::wireframe_pixels`). GPU effects
-(`effects::GPU_EFFECTS`, 280 of them: blurs, colour correction, keying incl. Key Light, mattes,
-channel, stylize, distortion and warps (Warp, Bezier Warp, Smear, Reshape, CC Bend It, CC Page
-Turn, CC Bender, CC Blobbylize), Cartoon, bevels, shapes, the transitions (CC light family, CC
-transitions, Block Dissolve), perspective (Radial Shadow, CC Cylinder / Sphere / Spotlight /
+(`effects::GPU_EFFECTS`, 280 of them: blurs, colour correction, keying incl. Screen Color Key, mattes,
+channel, stylize, distortion and warps (Warp, Bezier Warp, Smear, Reshape, Two-Point Bend, CC Page
+Turn, Flexible Bend, Organic Displacement), Cartoon, bevels, shapes, the transitions (CC light family, CC
+transitions, Block Dissolve), perspective (Radial Shadow, Cylinder Wrap / Sphere / Spotlight /
Environment, 3D Glasses), generators, noise, grain, text (Numbers, Timecode), time, 3D Channel (aux channels as an
extra texture), Immersive Video, colour management (colour programs from
`effects::color_program`, LUTs in a storage buffer) and the simulations' render passes (the
simulation stays on the CPU and hands its plan — sprites, pieces, blobs, grids — to a tiled
-rasteriser; the particle effects too, `gpu::fx_particles`: CC Particle World / Systems II,
-Particle Playground with its Layer Map frames in one atlas, CC Ball Action, CC Pixel Polly, CC
+rasteriser; the particle effects too, `gpu::fx_particles`: Particle Emitter 3D / Systems II,
+Particle Playground with its Layer Map frames in one atlas, Ball Grid, Pixel Shatter, CC
Scatterize; plans too large for one item table draw in several passes over the previous one),
and the geometry generators (Lightning, Advanced Lightning, Radio Waves, Stroke, Scribble,
Vegas, Write-on, Audio Spectrum / Waveform, Basic / Path Text: bolts, strokes, waves, audio
@@ -390,7 +390,7 @@ as kernels, in one module per family (`gpu::fx_*` with `shaders/fx_*.wgsl`); con
effects run as one chain with one upload and one readback. Statistics that need the whole frame
(Auto Levels / Contrast / Color, Equalize, Shadow/Highlight, Color Stabilizer, Remove Grain's
noise level) are measured on the CPU from one readback and applied on the GPU; effects reading
-other frames (Echo, Posterize Time, Time Difference, Time Displacement, CC Force Motion Blur, CC
+other frames (Echo, Posterize Time, Time Difference, Time Displacement, Temporal Motion Blur, CC
Wide Time, Pixel Motion Blur, Timewarp) upload the frames the host renders (`time_frames`) and
combine them on the GPU; Time Displacement's per-pixel times and Timewarp's motion vectors
(`time_fx::timewarp_plan`) are computed on the CPU. Numbers and Timecode rasterise their glyph
@@ -433,12 +433,12 @@ sentinel is implemented here. Browser scope futures are not synchronously awaite
forwards shared-device errors, while owned worker devices install their own handlers. On the web
(WebGPU) the GPU composites viewer frames; steps that need a readback fall back to the CPU (the
Info panel's pixel readout reads GPU frames back asynchronously). **GPU particles**
-(`effects::psim`, `gpu::particles`): CC Particle World, CC Particle Systems II and Particle
+(`effects::psim`, `gpu::particles`): Particle Emitter 3D, Particle Emitter 2D and Particle
Playground cannons without interacting forces evolve every particle independently, so the GPU
backend (reached through `EffectHost::particles` when the GPU compositor is active) simulates one
particle per invocation from the CPU's birth schedule and keeps per-key state checkpoints on the
GPU, like `SimCache`; the CPU simulation stays the oracle (tests compare ids and positions).
-CC Particle World, CC Particle Systems II and CC Mr. Mercury sample their Birth Rate at every
+Particle Emitter 3D, Particle Emitter 2D and Liquid Particles sample their Birth Rate at every
step (`EffectHost::param_at`, #1373), so a keyed rate only decides the births of its own time;
the rate is left out of the simulation key, and a checkpoint is resumed only with the same rate history (the CPU state's `hist`, the GPU
checkpoint's births). The rate's keyframes are read at the step's exact layer time
@@ -629,7 +629,7 @@ Unix milliseconds. The layer's Start Time becomes `dataStart + videoStart − fi
(`videoStart` given, or the file's creation date on the desktop; reduced to a time of day when
the data has no dates).
-**Lumetri Scopes** (`raster::scopes`) are density plots of the viewer frame (rendered over the
+**Video Scopes** (`raster::scopes`) are density plots of the viewer frame (rendered over the
comp background) with BT.601 / BT.709 / BT.2020 luma and colour-difference coefficients.
## 5. Expressions
diff --git a/docs/effects.md b/docs/effects.md
index d9f726481..723edd0d0 100644
--- a/docs/effects.md
+++ b/docs/effects.md
@@ -48,21 +48,21 @@ Effects are addressed by id (`ec..`) or display name in commands
| Effect | Id | Params | GPU | 32 | Status |
|---|---|---:|:-:|:-:|---|
| Bilateral Blur | `ec.blur.bilateral` | 3 | GPU | 32 | Implemented |
-| CC Cross Blur | `ec.blur.cccross` | 3 | GPU | 32 | Implemented |
-| CC Radial Blur | `ec.blur.ccradial` | 4 | GPU | 32 | Implemented |
-| CC Radial Fast Blur | `ec.blur.ccradialfast` | 3 | GPU | 32 | Implemented |
-| CC Vector Blur | `ec.blur.ccvector` | 4 | GPU | 32 | Implemented |
| Camera Lens Blur | `ec.blur.cameralens` | 16 | GPU | 32 | Implemented |
| Camera-Shake Deblur | `ec.blur.camerashakedeblur` | 8 | | 32 | Implemented |
| Channel Blur | `ec.blur.channel` | 6 | GPU | 32 | Implemented |
| Compound Blur | `ec.blur.compound` | 4 | GPU | 32 | Implemented |
+| Cross Blur | `ec.blur.cccross` | 3 | GPU | 32 | Implemented |
| Directional Blur | `ec.blur.directional` | 2 | GPU | 32 | Implemented |
| Fast Box Blur | `ec.blur.fastbox` | 4 | GPU | 32 | Implemented |
+| Fast Radial Blur | `ec.blur.ccradialfast` | 3 | GPU | 32 | Implemented |
| Gaussian Blur | `ec.blur.gaussian` | 3 | GPU | 32 | Implemented |
| Radial Blur | `ec.blur.radial` | 4 | GPU | 32 | Implemented |
| Sharpen | `ec.blur.sharpen` | 1 | GPU | 32 | Implemented |
| Smart Blur | `ec.blur.smart` | 3 | GPU | 32 | Implemented |
| Unsharp Mask | `ec.blur.unsharp` | 3 | GPU | 32 | Implemented |
+| Variable Radial Blur | `ec.blur.ccradial` | 4 | GPU | 32 | Implemented |
+| Vector Blur | `ec.blur.ccvector` | 4 | GPU | 32 | Implemented |
## Channel
@@ -70,7 +70,6 @@ Effects are addressed by id (`ec..`) or display name in commands
|---|---|---:|:-:|:-:|---|
| Arithmetic | `ec.channel.arithmetic` | 5 | GPU | 32 | Implemented |
| Blend | `ec.channel.blend` | 4 | GPU | 32 | Implemented |
-| CC Composite | `ec.channel.cccomposite` | 3 | GPU | 32 | Implemented |
| Calculations | `ec.channel.calculations` | 9 | GPU | 32 | Implemented |
| Channel Combiner | `ec.channel.combiner` | 6 | GPU | 32 | Implemented |
| Compound Arithmetic | `ec.channel.compoundarithmetic` | 6 | GPU | 32 | Implemented |
@@ -81,6 +80,7 @@ Effects are addressed by id (`ec..`) or display name in commands
| Set Matte | `ec.channel.setmatte` | 6 | GPU | 32 | Implemented |
| Shift Channels | `ec.channel.shiftchannels` | 4 | GPU | 32 | Implemented |
| Solid Composite | `ec.channel.solidcomposite` | 4 | GPU | 32 | Implemented |
+| Source Composite | `ec.channel.cccomposite` | 3 | GPU | 32 | Implemented |
## Color Correction
@@ -92,18 +92,18 @@ Effects are addressed by id (`ec..`) or display name in commands
| Black & White | `ec.color.blackwhite` | 8 | GPU | 32 | Implemented |
| Brightness & Contrast | `ec.color.brightnesscontrast` | 3 | GPU | 32 | Implemented |
| Broadcast Colors | `ec.color.broadcast` | 3 | GPU | 32 | Implemented |
-| CC Color Neutralizer | `ec.color.cccolorneutralizer` | 11 | GPU | 32 | Implemented |
-| CC Color Offset | `ec.color.cccoloroffset` | 4 | GPU | 32 | Implemented |
-| CC Kernel | `ec.color.cckernel` | 12 | GPU | 32 | Implemented |
-| CC Toner | `ec.color.cctoner` | 7 | GPU | 32 | Implemented |
| Change Color | `ec.color.changecolor` | 9 | GPU | 32 | Implemented |
| Change to Color | `ec.color.changetocolor` | 9 | GPU | 32 | Implemented |
| Channel Mixer | `ec.color.channelmixer` | 13 | GPU | 32 | Implemented |
+| Channel Offset | `ec.color.cccoloroffset` | 4 | GPU | 32 | Implemented |
| Color Balance | `ec.color.colorbalance` | 10 | GPU | 32 | Implemented |
| Color Balance (HLS) | `ec.color.colorbalancehls` | 3 | GPU | 32 | Implemented |
+| Color Grading | `ec.color.lumetri` | 66 | GPU | 32 | Implemented |
| Color Link | `ec.color.colorlink` | 6 | GPU | 32 | Implemented |
+| Color Neutralizer | `ec.color.cccolorneutralizer` | 11 | GPU | 32 | Implemented |
| Color Stabilizer | `ec.color.colorstabilizer` | 6 | GPU | 32 | Implemented |
| Colorama | `ec.color.colorama` | 20 | GPU | 32 | Implemented |
+| Convolution Kernel | `ec.color.cckernel` | 12 | GPU | 32 | Implemented |
| Curves | `ec.color.curves` | 0 | GPU | 32 | Implemented |
| Equalize | `ec.color.equalize` | 2 | GPU | 32 | Implemented |
| Exposure | `ec.color.exposure` | 14 | GPU | 32 | Implemented |
@@ -112,7 +112,7 @@ Effects are addressed by id (`ec..`) or display name in commands
| Leave Color | `ec.color.leavecolor` | 5 | GPU | 32 | Implemented |
| Levels | `ec.color.levels` | 36 | GPU | 32 | Implemented |
| Levels (Individual Controls) | `ec.color.levelsic` | 27 | GPU | 32 | Implemented |
-| Lumetri Color | `ec.color.lumetri` | 66 | GPU | 32 | Implemented |
+| Multi-Tone Tint | `ec.color.cctoner` | 7 | GPU | 32 | Implemented |
| OCIO CDL Transform | `ec.color.ociocdl` | 12 | GPU | 32 | Implemented |
| OCIO Color Space Transform | `ec.color.ociocolorspace` | 7 | GPU | 32 | Implemented |
| OCIO Display Transform | `ec.color.ociodisplay` | 9 | GPU | 32 | Implemented |
@@ -133,40 +133,40 @@ Effects are addressed by id (`ec..`) or display name in commands
|---|---|---:|:-:|:-:|---|
| Bezier Warp | `ec.distort.bezierwarp` | 13 | GPU | 32 | Implemented |
| Bulge | `ec.distort.bulge` | 6 | GPU | 32 | Implemented |
-| CC Bend It | `ec.distort.ccbendit` | 4 | GPU | 32 | Implemented |
-| CC Bender | `ec.distort.ccbender` | 5 | GPU | 32 | Implemented |
-| CC Blobbylize | `ec.distort.ccblobbylize` | 15 | GPU | 32 | Implemented |
-| CC Flo Motion | `ec.distort.ccflomotion` | 7 | GPU | 32 | Implemented |
-| CC Griddler | `ec.distort.ccgriddler` | 5 | GPU | 32 | Implemented |
-| CC Lens | `ec.distort.cclens` | 3 | GPU | 32 | Implemented |
-| CC Page Turn | `ec.distort.ccpageturn` | 7 | GPU | 32 | Implemented |
-| CC Power Pin | `ec.distort.ccpowerpin` | 10 | GPU | 32 | Implemented |
-| CC Ripple Pulse | `ec.distort.ccripplepulse` | 5 | GPU | 32 | Implemented |
-| CC Slant | `ec.distort.ccslant` | 4 | GPU | 32 | Implemented |
-| CC Smear | `ec.distort.ccsmear` | 4 | GPU | 32 | Implemented |
-| CC Split | `ec.distort.ccsplit` | 3 | GPU | 32 | Implemented |
-| CC Split 2 | `ec.distort.ccsplit2` | 4 | GPU | 32 | Implemented |
-| CC Tiler | `ec.distort.cctiler` | 3 | GPU | 32 | Implemented |
| Corner Pin | `ec.distort.cornerpin` | 4 | GPU | 32 | Implemented |
| Detail-preserving Upscale | `ec.distort.upscale` | 4 | | 32 | Implemented |
+| Directional Smear | `ec.distort.ccsmear` | 4 | GPU | 32 | Implemented |
| Displacement Map | `ec.distort.displacementmap` | 8 | GPU | 32 | Implemented |
+| Dual Lens Warp | `ec.distort.ccflomotion` | 7 | GPU | 32 | Implemented |
+| Dual Split Warp | `ec.distort.ccsplit2` | 4 | GPU | 32 | Implemented |
+| Flexible Bend | `ec.distort.ccbender` | 5 | GPU | 32 | Implemented |
+| Lens Distortion | `ec.distort.cclens` | 3 | GPU | 32 | Implemented |
| Liquify | `ec.distort.liquify` | 13 | GPU | 32 | Implemented |
| Magnify | `ec.distort.magnify` | 10 | GPU | 32 | Implemented |
| Mesh Warp | `ec.distort.meshwarp` | 3 | GPU | 32 | Implemented |
| Mirror | `ec.distort.mirror` | 2 | GPU | 32 | Implemented |
| Offset | `ec.distort.offset` | 2 | GPU | 32 | Implemented |
| Optics Compensation | `ec.distort.opticscompensation` | 6 | GPU | 32 | Implemented |
+| Organic Displacement | `ec.distort.ccblobbylize` | 15 | GPU | 32 | Implemented |
+| Page Curl | `ec.distort.ccpageturn` | 7 | GPU | 32 | Implemented |
+| Perspective Pin | `ec.distort.ccpowerpin` | 10 | GPU | 32 | Implemented |
| Polar Coordinates | `ec.distort.polar` | 2 | GPU | 32 | Implemented |
+| Pulsed Ripple | `ec.distort.ccripplepulse` | 5 | GPU | 32 | Implemented |
| Puppet | `ec.distort.puppet` | 1 | | 32 | Implemented |
| Reshape | `ec.distort.reshape` | 6 | GPU | 32 | Implemented |
| Ripple | `ec.distort.ripple` | 7 | GPU | 32 | Implemented |
| Rolling Shutter Repair | `ec.distort.rollingshutterrepair` | 5 | | 32 | Implemented |
+| Scaled Tiles | `ec.distort.cctiler` | 3 | GPU | 32 | Implemented |
+| Slant | `ec.distort.ccslant` | 4 | GPU | 32 | Implemented |
| Smear | `ec.distort.smear` | 8 | GPU | 32 | Implemented |
| Spherize | `ec.distort.spherize` | 2 | GPU | 32 | Implemented |
+| Split Warp | `ec.distort.ccsplit` | 3 | GPU | 32 | Implemented |
+| Tile Grid | `ec.distort.ccgriddler` | 5 | GPU | 32 | Implemented |
| Transform | `ec.distort.transform` | 12 | GPU | 32 | Implemented |
| Turbulent Displace | `ec.distort.turbulentdisplace` | 11 | GPU | 32 | Implemented |
| Twirl | `ec.distort.twirl` | 3 | GPU | 32 | Implemented |
| Twirl (Legacy) | `ec.distort.twirllegacy` | 3 | GPU | 32 | Implemented |
+| Two-Point Bend | `ec.distort.ccbendit` | 4 | GPU | 32 | Implemented |
| Warp | `ec.distort.warp` | 5 | GPU | 32 | Implemented |
| Warp Stabilizer | `ec.distort.warpstabilizer` | 20 | | 32 | Implemented |
| Wave Warp | `ec.distort.wavewarp` | 7 | GPU | 32 | Implemented |
@@ -194,11 +194,6 @@ Effects are addressed by id (`ec..`) or display name in commands
| Audio Spectrum | `ec.generate.audiospectrum` | 23 | GPU | 32 | Implemented |
| Audio Waveform | `ec.generate.audiowaveform` | 17 | GPU | 32 | Implemented |
| Beam | `ec.generate.beam` | 11 | GPU | 32 | Implemented |
-| CC Glue Gun | `ec.generate.ccgluegun` | 7 | GPU | 32 | Implemented |
-| CC Light Burst 2.5 | `ec.generate.cclightburst` | 6 | GPU | 32 | Implemented |
-| CC Light Rays | `ec.generate.cclightrays` | 8 | GPU | 32 | Implemented |
-| CC Light Sweep | `ec.generate.cclightsweep` | 9 | GPU | 32 | Implemented |
-| CC Threads | `ec.generate.ccthreads` | 8 | GPU | 32 | Implemented |
| Cell Pattern | `ec.generate.cellpattern` | 14 | GPU | 32 | Implemented |
| Checkerboard | `ec.generate.checkerboard` | 10 | GPU | 32 | Implemented |
| Circle | `ec.generate.circle` | 11 | GPU | 32 | Implemented |
@@ -209,11 +204,16 @@ Effects are addressed by id (`ec..`) or display name in commands
| Gradient Ramp | `ec.generate.gradientramp` | 7 | GPU | 32 | Implemented |
| Grid | `ec.generate.grid` | 12 | GPU | 32 | Implemented |
| Lens Flare | `ec.generate.lensflare` | 4 | GPU | 32 | Implemented |
+| Light Rays | `ec.generate.cclightrays` | 8 | GPU | 32 | Implemented |
+| Light Sweep | `ec.generate.cclightsweep` | 9 | GPU | 32 | Implemented |
+| Paint Beads | `ec.generate.ccgluegun` | 7 | GPU | 32 | Implemented |
| Paint Bucket | `ec.generate.paintbucket` | 11 | GPU | 32 | Implemented |
+| Radial Light Burst | `ec.generate.cclightburst` | 6 | GPU | 32 | Implemented |
| Radio Waves | `ec.generate.radiowaves` | 31 | GPU | 32 | Implemented |
| Scribble | `ec.generate.scribble` | 25 | GPU | 32 | Implemented |
| Stroke | `ec.generate.stroke` | 11 | GPU | 32 | Implemented |
| Vegas | `ec.generate.vegas` | 26 | GPU | 32 | Implemented |
+| Woven Threads | `ec.generate.ccthreads` | 8 | GPU | 32 | Implemented |
| Write-on | `ec.generate.writeon` | 10 | GPU | 32 | Implemented |
## Immersive Video
@@ -238,15 +238,15 @@ Effects are addressed by id (`ec..`) or display name in commands
| Effect | Id | Params | GPU | 32 | Status |
|---|---|---:|:-:|:-:|---|
| Advanced Spill Suppressor | `ec.key.advancedspill` | 8 | GPU | 32 | Implemented |
-| CC Simple Wire Removal | `ec.key.ccsimplewireremoval` | 7 | GPU | 32 | Implemented |
| Color Difference Key | `ec.key.colordifference` | 16 | GPU | 32 | Implemented |
| Color Range | `ec.key.colorrange` | 8 | GPU | 32 | Implemented |
| Difference Matte | `ec.key.differencematte` | 6 | GPU | 32 | Implemented |
| Extract | `ec.key.extract` | 6 | GPU | 32 | Implemented |
| Inner/Outer Key | `ec.key.innerouter` | 88 | GPU | 32 | Implemented |
| Key Cleaner | `ec.key.keycleaner` | 4 | GPU | 32 | Implemented |
-| Key Light | `ec.keying.keylight` | 56 | GPU | 32 | Implemented |
+| Line Removal | `ec.key.ccsimplewireremoval` | 7 | GPU | 32 | Implemented |
| Linear Color Key | `ec.key.linearcolor` | 6 | GPU | 32 | Implemented |
+| Screen Color Key | `ec.keying.keylight` | 56 | GPU | 32 | Implemented |
| Screen Key | `ec.key.screen` | 11 | GPU | 32 | Implemented |
| Unmult | `ec.key.unmult` | 6 | GPU | 32 | Implemented |
@@ -255,12 +255,12 @@ Effects are addressed by id (`ec..`) or display name in commands
| Effect | Id | Params | GPU | 32 | Status |
|---|---|---:|:-:|:-:|---|
| Matte Choker | `ec.matte.mattechoker` | 7 | GPU | 32 | Implemented |
-| Mocha shape | `ec.obsolete.mochashape` | 6 | | 32 | Implemented |
| Object Matte | `ec.matte.objectmatte` | 13 | | 32 | Implemented |
| Refine Hard Matte | `ec.matte.refinehard` | 16 | GPU | 32 | Implemented |
| Refine Soft Matte | `ec.matte.refinesoft` | 18 | GPU | 32 | Implemented |
| Roto Brush & Refine Edge | `ec.matte.rotobrush` | 25 | | 32 | Implemented |
| Simple Choker | `ec.matte.simplechoker` | 2 | GPU | 32 | Implemented |
+| Tracked Shape Matte | `ec.obsolete.mochashape` | 6 | | 32 | Implemented |
## Noise & Grain
@@ -308,65 +308,65 @@ Effects are addressed by id (`ec..`) or display name in commands
| 3D Glasses | `ec.perspective.3dglasses` | 8 | GPU | 32 | Implemented |
| Bevel Alpha | `ec.perspective.bevelalpha` | 4 | GPU | 32 | Implemented |
| Bevel Edges | `ec.perspective.beveledges` | 4 | GPU | 32 | Implemented |
-| CC Cylinder | `ec.perspective.cccylinder` | 15 | GPU | 32 | Implemented |
-| CC Environment | `ec.perspective.ccenvironment` | 4 | GPU | 32 | Implemented |
-| CC Sphere | `ec.perspective.ccsphere` | 14 | GPU | 32 | Implemented |
-| CC Spotlight | `ec.perspective.ccspotlight` | 8 | GPU | 32 | Implemented |
+| Cylinder Wrap | `ec.perspective.cccylinder` | 15 | GPU | 32 | Implemented |
| Drop Shadow | `ec.perspective.dropshadow` | 6 | GPU | 32 | Implemented |
+| Environment Map | `ec.perspective.ccenvironment` | 4 | GPU | 32 | Implemented |
| Radial Shadow | `ec.perspective.radialshadow` | 9 | GPU | 32 | Implemented |
+| Sphere Wrap | `ec.perspective.ccsphere` | 14 | GPU | 32 | Implemented |
+| Surface Spotlight | `ec.perspective.ccspotlight` | 8 | GPU | 32 | Implemented |
## Simulation
| Effect | Id | Params | GPU | 32 | Status |
|---|---|---:|:-:|:-:|---|
-| CC Ball Action | `ec.sim.ccballaction` | 8 | GPU | 32 | Implemented |
-| CC Bubbles | `ec.sim.ccbubbles` | 7 | GPU | 32 | Implemented |
-| CC Drizzle | `ec.sim.ccdrizzle` | 14 | GPU | 32 | Implemented |
-| CC Hair | `ec.sim.cchair` | 20 | GPU | 32 | Implemented |
-| CC Mr. Mercury | `ec.sim.ccmrmercury` | 23 | GPU | 32 | Implemented |
-| CC Particle Systems II | `ec.sim.ccparticlesystems2` | 21 | GPU | 32 | Implemented |
-| CC Particle World | `ec.sim.ccparticleworld` | 36 | GPU | 32 | Implemented |
-| CC Pixel Polly | `ec.sim.ccpixelpolly` | 10 | GPU | 32 | Implemented |
-| CC Rainfall | `ec.sim.ccrainfall` | 14 | GPU | 32 | Implemented |
-| CC Scatterize | `ec.sim.ccscatterize` | 4 | GPU | 32 | Implemented |
-| CC Snowfall | `ec.sim.ccsnowfall` | 19 | GPU | 32 | Implemented |
-| CC Star Burst | `ec.sim.ccstarburst` | 6 | GPU | 32 | Implemented |
+| Ball Grid | `ec.sim.ccballaction` | 8 | GPU | 32 | Implemented |
+| Bubbles | `ec.sim.ccbubbles` | 7 | GPU | 32 | Implemented |
| Card Dance | `ec.sim.carddance` | 53 | GPU | 32 | Implemented |
| Caustics | `ec.sim.caustics` | 28 | GPU | 32 | Implemented |
| Foam | `ec.sim.foam` | 36 | GPU | 32 | Implemented |
+| Liquid Particles | `ec.sim.ccmrmercury` | 23 | GPU | 32 | Implemented |
+| Particle Emitter 2D | `ec.sim.ccparticlesystems2` | 21 | GPU | 32 | Implemented |
+| Particle Emitter 3D | `ec.sim.ccparticleworld` | 36 | GPU | 32 | Implemented |
| Particle Playground | `ec.sim.particleplayground` | 92 | GPU | 32 | Implemented |
+| Pixel Scatter | `ec.sim.ccscatterize` | 4 | GPU | 32 | Implemented |
+| Pixel Shatter | `ec.sim.ccpixelpolly` | 10 | GPU | 32 | Implemented |
+| Rainfall | `ec.sim.ccrainfall` | 14 | GPU | 32 | Implemented |
| Shatter | `ec.sim.shatter` | 60 | GPU | 32 | Implemented |
+| Snowfall | `ec.sim.ccsnowfall` | 19 | GPU | 32 | Implemented |
+| Starfield | `ec.sim.ccstarburst` | 6 | GPU | 32 | Implemented |
+| Surface Fibers | `ec.sim.cchair` | 20 | GPU | 32 | Implemented |
+| Water Ripples | `ec.sim.ccdrizzle` | 14 | GPU | 32 | Implemented |
| Wave World | `ec.sim.waveworld` | 35 | GPU | 32 | Implemented |
## Stylize
| Effect | Id | Params | GPU | 32 | Status |
|---|---|---:|:-:|:-:|---|
+| Block Reveal | `ec.stylize.ccblockload` | 5 | GPU | 32 | Implemented |
| Brush Strokes | `ec.stylize.brushstrokes` | 7 | GPU | 32 | Implemented |
-| CC Block Load | `ec.stylize.ccblockload` | 5 | GPU | 32 | Implemented |
-| CC Burn Film | `ec.stylize.ccburnfilm` | 3 | GPU | 32 | Implemented |
-| CC Glass | `ec.stylize.ccglass` | 17 | GPU | 32 | Implemented |
-| CC HexTile | `ec.stylize.cchextile` | 5 | GPU | 32 | Implemented |
-| CC Kaleida | `ec.stylize.cckaleida` | 4 | GPU | 32 | Implemented |
-| CC Mr. Smoothie | `ec.stylize.ccmrsmoothie` | 7 | GPU | 32 | Implemented |
-| CC Plastic | `ec.stylize.ccplastic` | 18 | GPU | 32 | Implemented |
-| CC RepeTile | `ec.stylize.ccrepetile` | 5 | GPU | 32 | Implemented |
-| CC Threshold | `ec.stylize.ccthreshold` | 4 | GPU | 32 | Implemented |
-| CC Threshold RGB | `ec.stylize.ccthresholdrgb` | 7 | GPU | 32 | Implemented |
-| CC Vignette | `ec.stylize.ccvignette` | 4 | GPU | 32 | Implemented |
| Cartoon | `ec.stylize.cartoon` | 12 | GPU | 32 | Implemented |
+| Channel Threshold | `ec.stylize.ccthreshold` | 4 | GPU | 32 | Implemented |
| Color Emboss | `ec.stylize.coloremboss` | 4 | GPU | 32 | Implemented |
+| Edge Tile Repeat | `ec.stylize.ccrepetile` | 5 | GPU | 32 | Implemented |
| Emboss | `ec.stylize.emboss` | 4 | GPU | 32 | Implemented |
+| Film Burn | `ec.stylize.ccburnfilm` | 3 | GPU | 32 | Implemented |
| Find Edges | `ec.stylize.findedges` | 2 | GPU | 32 | Implemented |
+| Glass Relief | `ec.stylize.ccglass` | 17 | GPU | 32 | Implemented |
| Glow | `ec.stylize.glow` | 14 | GPU | 32 | Implemented |
+| Hexagonal Tiles | `ec.stylize.cchextile` | 5 | GPU | 32 | Implemented |
+| Kaleidoscope | `ec.stylize.cckaleida` | 4 | GPU | 32 | Implemented |
| Mosaic | `ec.stylize.mosaic` | 3 | GPU | 32 | Implemented |
| Motion Tile | `ec.stylize.motiontile` | 8 | GPU | 32 | Implemented |
+| Palette Map | `ec.stylize.ccmrsmoothie` | 7 | GPU | 32 | Implemented |
+| Plastic Shading | `ec.stylize.ccplastic` | 18 | GPU | 32 | Implemented |
| Posterize | `ec.stylize.posterize` | 1 | GPU | 32 | Implemented |
+| RGB Threshold | `ec.stylize.ccthresholdrgb` | 7 | GPU | 32 | Implemented |
| Roughen Edges | `ec.stylize.roughenedges` | 13 | GPU | 32 | Implemented |
| Scatter | `ec.stylize.scatter` | 3 | GPU | 32 | Implemented |
| Strobe Light | `ec.stylize.strobe` | 7 | GPU | 32 | Implemented |
| Texturize | `ec.stylize.texturize` | 4 | GPU | 32 | Implemented |
| Threshold | `ec.stylize.threshold` | 1 | GPU | 32 | Implemented |
+| Vignette | `ec.stylize.ccvignette` | 4 | GPU | 32 | Implemented |
## Text
@@ -379,11 +379,11 @@ Effects are addressed by id (`ec..`) or display name in commands
| Effect | Id | Params | GPU | 32 | Status |
|---|---|---:|:-:|:-:|---|
-| CC Force Motion Blur | `ec.time.ccforcemotionblur` | 4 | GPU | 32 | Implemented |
-| CC Wide Time | `ec.time.ccwidetime` | 3 | GPU | 32 | Implemented |
| Echo | `ec.time.echo` | 5 | GPU | 32 | Implemented |
| Pixel Motion Blur | `ec.time.pixelmotionblur` | 4 | GPU | 32 | Implemented |
| Posterize Time | `ec.time.posterizetime` | 1 | GPU | 32 | Implemented |
+| Temporal Blend | `ec.time.ccwidetime` | 3 | GPU | 32 | Implemented |
+| Temporal Motion Blur | `ec.time.ccforcemotionblur` | 4 | GPU | 32 | Implemented |
| Time Difference | `ec.time.timedifference` | 5 | GPU | 32 | Implemented |
| Time Displacement | `ec.time.timedisplacement` | 4 | GPU | 32 | Implemented |
| Timewarp | `ec.time.timewarp` | 28 | GPU | 32 | Implemented |
@@ -393,29 +393,28 @@ Effects are addressed by id (`ec..`) or display name in commands
| Effect | Id | Params | GPU | 32 | Status |
|---|---|---:|:-:|:-:|---|
| Block Dissolve | `ec.transition.blockdissolve` | 5 | GPU | 32 | Implemented |
-| CC Glass Wipe | `ec.transition.ccglasswipe` | 5 | GPU | 32 | Implemented |
-| CC Grid Wipe | `ec.transition.ccgridwipe` | 7 | GPU | 32 | Implemented |
-| CC Image Wipe | `ec.transition.ccimagewipe` | 7 | GPU | 32 | Implemented |
-| CC Jaws | `ec.transition.ccjaws` | 6 | GPU | 32 | Implemented |
-| CC Light Wipe | `ec.transition.cclightwipe` | 8 | GPU | 32 | Implemented |
-| CC Line Sweep | `ec.transition.cclinesweep` | 5 | GPU | 32 | Implemented |
-| CC Radial ScaleWipe | `ec.transition.ccradialscalewipe` | 3 | GPU | 32 | Implemented |
-| CC Scale Wipe | `ec.transition.ccscalewipe` | 3 | GPU | 32 | Implemented |
-| CC Twister | `ec.transition.cctwister` | 5 | GPU | 32 | Implemented |
-| CC WarpoMatic | `ec.transition.ccwarpomatic` | 8 | GPU | 32 | Implemented |
| Card Wipe | `ec.transition.cardwipe` | 44 | GPU | 32 | Implemented |
+| Glass Wipe | `ec.transition.ccglasswipe` | 5 | GPU | 32 | Implemented |
| Gradient Wipe | `ec.transition.gradientwipe` | 5 | GPU | 32 | Implemented |
+| Grid Wipe | `ec.transition.ccgridwipe` | 7 | GPU | 32 | Implemented |
| Iris Wipe | `ec.transition.iriswipe` | 7 | GPU | 32 | Implemented |
+| Light Wipe | `ec.transition.cclightwipe` | 8 | GPU | 32 | Implemented |
+| Line Sweep | `ec.transition.cclinesweep` | 5 | GPU | 32 | Implemented |
| Linear Wipe | `ec.transition.linearwipe` | 3 | GPU | 32 | Implemented |
+| Luminance Image Wipe | `ec.transition.ccimagewipe` | 7 | GPU | 32 | Implemented |
+| Radial Scale Wipe | `ec.transition.ccradialscalewipe` | 3 | GPU | 32 | Implemented |
| Radial Wipe | `ec.transition.radialwipe` | 5 | GPU | 32 | Implemented |
+| Scale Wipe | `ec.transition.ccscalewipe` | 3 | GPU | 32 | Implemented |
+| Serrated Wipe | `ec.transition.ccjaws` | 6 | GPU | 32 | Implemented |
+| Twist Wipe | `ec.transition.cctwister` | 5 | GPU | 32 | Implemented |
| Venetian Blinds | `ec.transition.venetian` | 4 | GPU | 32 | Implemented |
+| Warp Dissolve | `ec.transition.ccwarpomatic` | 8 | GPU | 32 | Implemented |
## Utility
| Effect | Id | Params | GPU | 32 | Status |
|---|---|---:|:-:|:-:|---|
| Apply Color LUT | `ec.utility.applylut` | 1 | GPU | 32 | Implemented |
-| CC Overbrights | `ec.utility.ccoverbrights` | 2 | GPU | 32 | Implemented |
| Cineon Converter | `ec.utility.cineon` | 7 | GPU | 32 | Implemented |
| Color Profile Converter | `ec.utility.colorprofileconverter` | 7 | GPU | 32 | Implemented |
| Face Measurements | `ec.utility.facemeasurements` | 14 | | 32 | Implemented |
@@ -423,4 +422,5 @@ Effects are addressed by id (`ec..`) or display name in commands
| Grow Bounds | `ec.utility.growbounds` | 1 | GPU | 32 | Implemented |
| HDR Compander | `ec.utility.hdrcompander` | 3 | GPU | 32 | Implemented |
| HDR Highlight Compression | `ec.utility.hdrcompression` | 1 | GPU | 32 | Implemented |
+| Out-of-Range Display | `ec.utility.ccoverbrights` | 2 | GPU | 32 | Implemented |
diff --git a/docs/feature-naming.md b/docs/feature-naming.md
new file mode 100644
index 000000000..a69bc713f
--- /dev/null
+++ b/docs/feature-naming.md
@@ -0,0 +1,108 @@
+# Descriptive feature names
+
+Related to #1365. This is a naming cleanup, not a trademark clearance or a product rename.
+
+## Naming policy
+
+Use short, descriptive labels for EffectCraft implementations. Do not reuse a vendor prefix or
+coined feature name as our branding. Qualify similar effects by what distinguishes them; each
+English display name remains unique across the registry.
+
+- Renderer: **GPU Acceleration** / **Software Rendering**.
+- Panel: **Video Scopes**.
+- The table below covers the 69 former CC effects plus color grading, the shape matte and keying.
+
+## Compatibility contract
+
+Only presentation names change. Effect IDs, command IDs, parameter IDs, enum values, panel IDs,
+serialized types and AEP import/export match names stay unchanged. Old effect display names
+remain case-insensitive lookup and search aliases. Existing project instance names, custom names,
+expressions, animation and values are not rewritten. The UI displays a current label for an exact
+legacy default name, optionally followed by its numeric instance suffix; all other names stay
+verbatim. A user-entered name identical to a legacy default cannot be distinguished from it, but
+its saved value is still retained.
+
+External format specifications, comparison documents, attribution records and compatibility
+fixtures may still name the external product or effect they actually describe.
+
+## Display mapping
+
+| Stable ID | Previous display name | Current display name |
+|---|---|---|
+| `ec.sim.ccballaction` | CC Ball Action | Ball Grid |
+| `ec.distort.ccbendit` | CC Bend It | Two-Point Bend |
+| `ec.distort.ccbender` | CC Bender | Flexible Bend |
+| `ec.distort.ccblobbylize` | CC Blobbylize | Organic Displacement |
+| `ec.stylize.ccblockload` | CC Block Load | Block Reveal |
+| `ec.sim.ccbubbles` | CC Bubbles | Bubbles |
+| `ec.stylize.ccburnfilm` | CC Burn Film | Film Burn |
+| `ec.color.cccolorneutralizer` | CC Color Neutralizer | Color Neutralizer |
+| `ec.color.cccoloroffset` | CC Color Offset | Channel Offset |
+| `ec.channel.cccomposite` | CC Composite | Source Composite |
+| `ec.blur.cccross` | CC Cross Blur | Cross Blur |
+| `ec.perspective.cccylinder` | CC Cylinder | Cylinder Wrap |
+| `ec.sim.ccdrizzle` | CC Drizzle | Water Ripples |
+| `ec.perspective.ccenvironment` | CC Environment | Environment Map |
+| `ec.distort.ccflomotion` | CC Flo Motion | Dual Lens Warp |
+| `ec.time.ccforcemotionblur` | CC Force Motion Blur | Temporal Motion Blur |
+| `ec.stylize.ccglass` | CC Glass | Glass Relief |
+| `ec.transition.ccglasswipe` | CC Glass Wipe | Glass Wipe |
+| `ec.generate.ccgluegun` | CC Glue Gun | Paint Beads |
+| `ec.transition.ccgridwipe` | CC Grid Wipe | Grid Wipe |
+| `ec.distort.ccgriddler` | CC Griddler | Tile Grid |
+| `ec.sim.cchair` | CC Hair | Surface Fibers |
+| `ec.stylize.cchextile` | CC HexTile | Hexagonal Tiles |
+| `ec.transition.ccimagewipe` | CC Image Wipe | Luminance Image Wipe |
+| `ec.transition.ccjaws` | CC Jaws | Serrated Wipe |
+| `ec.stylize.cckaleida` | CC Kaleida | Kaleidoscope |
+| `ec.color.cckernel` | CC Kernel | Convolution Kernel |
+| `ec.distort.cclens` | CC Lens | Lens Distortion |
+| `ec.generate.cclightburst` | CC Light Burst 2.5 | Radial Light Burst |
+| `ec.generate.cclightrays` | CC Light Rays | Light Rays |
+| `ec.generate.cclightsweep` | CC Light Sweep | Light Sweep |
+| `ec.transition.cclightwipe` | CC Light Wipe | Light Wipe |
+| `ec.transition.cclinesweep` | CC Line Sweep | Line Sweep |
+| `ec.sim.ccmrmercury` | CC Mr. Mercury | Liquid Particles |
+| `ec.stylize.ccmrsmoothie` | CC Mr. Smoothie | Palette Map |
+| `ec.utility.ccoverbrights` | CC Overbrights | Out-of-Range Display |
+| `ec.distort.ccpageturn` | CC Page Turn | Page Curl |
+| `ec.sim.ccparticlesystems2` | CC Particle Systems II | Particle Emitter 2D |
+| `ec.sim.ccparticleworld` | CC Particle World | Particle Emitter 3D |
+| `ec.sim.ccpixelpolly` | CC Pixel Polly | Pixel Shatter |
+| `ec.stylize.ccplastic` | CC Plastic | Plastic Shading |
+| `ec.distort.ccpowerpin` | CC Power Pin | Perspective Pin |
+| `ec.blur.ccradial` | CC Radial Blur | Variable Radial Blur |
+| `ec.blur.ccradialfast` | CC Radial Fast Blur | Fast Radial Blur |
+| `ec.transition.ccradialscalewipe` | CC Radial ScaleWipe | Radial Scale Wipe |
+| `ec.sim.ccrainfall` | CC Rainfall | Rainfall |
+| `ec.stylize.ccrepetile` | CC RepeTile | Edge Tile Repeat |
+| `ec.distort.ccripplepulse` | CC Ripple Pulse | Pulsed Ripple |
+| `ec.transition.ccscalewipe` | CC Scale Wipe | Scale Wipe |
+| `ec.sim.ccscatterize` | CC Scatterize | Pixel Scatter |
+| `ec.key.ccsimplewireremoval` | CC Simple Wire Removal | Line Removal |
+| `ec.distort.ccslant` | CC Slant | Slant |
+| `ec.distort.ccsmear` | CC Smear | Directional Smear |
+| `ec.sim.ccsnowfall` | CC Snowfall | Snowfall |
+| `ec.perspective.ccsphere` | CC Sphere | Sphere Wrap |
+| `ec.distort.ccsplit` | CC Split | Split Warp |
+| `ec.distort.ccsplit2` | CC Split 2 | Dual Split Warp |
+| `ec.perspective.ccspotlight` | CC Spotlight | Surface Spotlight |
+| `ec.sim.ccstarburst` | CC Star Burst | Starfield |
+| `ec.generate.ccthreads` | CC Threads | Woven Threads |
+| `ec.stylize.ccthreshold` | CC Threshold | Channel Threshold |
+| `ec.stylize.ccthresholdrgb` | CC Threshold RGB | RGB Threshold |
+| `ec.distort.cctiler` | CC Tiler | Scaled Tiles |
+| `ec.color.cctoner` | CC Toner | Multi-Tone Tint |
+| `ec.transition.cctwister` | CC Twister | Twist Wipe |
+| `ec.blur.ccvector` | CC Vector Blur | Vector Blur |
+| `ec.stylize.ccvignette` | CC Vignette | Vignette |
+| `ec.transition.ccwarpomatic` | CC WarpoMatic | Warp Dissolve |
+| `ec.time.ccwidetime` | CC Wide Time | Temporal Blend |
+| `ec.color.lumetri` | Lumetri Color | Color Grading |
+| `ec.obsolete.mochashape` | Mocha shape | Tracked Shape Matte |
+| `ec.keying.keylight` | Key Light | Screen Color Key |
+
+`Roto Brush & Refine Edge` and `Warp Stabilizer` keep their current names; renaming them is
+deferred.
+
+No effect algorithms or formats are changed.
diff --git a/docs/gaps.md b/docs/gaps.md
index d481f9810..d9de84675 100644
--- a/docs/gaps.md
+++ b/docs/gaps.md
@@ -266,6 +266,12 @@ Issues #41–#47 (all from the Linux AppImage 0.1.1, 5 October): panning the vie
The second means reading another implementation of the format, which AGENTS.md rules out
unless the clean-room scope allows it.
- Also in this area: relative footage paths and relinking when a project moves (gap 18).
+- Placed PDF / Illustrator footage of an `.aep` is framed as After Effects places it (the ArtBox
+ clipped to the crop box, `/Rotate` ignored) and drawn to fill the size After Effects stored
+ (#3099), measured with hand-written PDFs named `.ai`. Not yet measured: files saved by
+ Illustrator itself (artboards, bleed, art past the artboard, private data), a CropBox without
+ an ArtBox, `.pdf` names, and EPS files (they keep their bounding box at their own size, not
+ the placed framing).
- Done when: the decision is recorded and, if approved, a corpus of real-world-shaped projects
opens with its comps, layers, keyframes, effects and expressions intact.
diff --git a/docs/plugins.md b/docs/plugins.md
index 3fd8cf944..290ed033c 100644
--- a/docs/plugins.md
+++ b/docs/plugins.md
@@ -11,7 +11,7 @@ Guide):
| After Effects | EffectCraft | |
|---|---|---|
-| Effect plug-ins (C/C++ SDK, `.aex` / `.plugin`) | [Effect plug-ins](#effect-plug-ins): WebAssembly modules (plug-in API v1) or Rust; the `Plug-ins` folder next to the settings loads at start-up | Different ABI: After Effects SDK plug-ins can't run (G8) |
+| Effect plug-ins (C/C++ SDK, `.aex` / `.plugin`) | [Effect plug-ins](#effect-plug-ins): WebAssembly modules (WebAssembly ABI 1 and 2) or Rust; the `Plug-ins` folder next to the settings loads at start-up | Different ABI: After Effects SDK plug-ins can't run (G8) |
| Scripts folder: its scripts are listed in File ▸ Scripts | `Scripts/` in the settings folder (File ▸ Scripts ▸ Install Script File… copies a script there), listed in File ▸ Scripts with the bundled samples; a subfolder (one level) is a submenu named after it | Same |
| File ▸ Scripts ▸ Run Script File… (`.jsx`, `.jsxbin`) | `.jsx` / `.js` | Gap: `.jsxbin` (an undocumented binary encoding) |
| File ▸ Scripts ▸ Recent Script Files: the 10 most recently run scripts; Cmd+Option+Shift+D (Ctrl+Alt+Shift+D on Windows) reruns one | File ▸ Scripts ▸ Recent Script Files lists the 10 scripts run last (script files and File ▸ Scripts entries, newest first, kept in the settings); Cmd+Alt+Shift+D runs the most recent one again (`file.runScript {"recent": 0}`, a key that can be changed in Edit ▸ Keyboard Shortcuts) | Same |
@@ -152,7 +152,7 @@ example of a keyframe tool.
## Effect plug-ins
-EffectCraft loads third-party effects through a small, versioned plug-in API (**API version 2**; WebAssembly ABI 1).
+EffectCraft loads third-party effects through a small, versioned plug-in API (**API version 2**; WebAssembly ABI 1 and 2).
A plug-in effect behaves exactly like a built-in one: it is listed in Effects & Presets (and the
Effect menu) under its category, applied by id (`effect.apply {"effect": "org.example.posterize"}`)
or display name, its parameters are ordinary properties (keyframes, expressions, Effect Controls,
@@ -178,7 +178,8 @@ author, source, params}]}`.
* **Parameters** arrive flattened to `f64`s in the order they are declared: slider, angle,
checkbox (0 / 1) and popup (0-based index) take one value, point two (already in **buffer
pixels**), colour four (RGBA 0–1).
-* **Time** is layer time in seconds.
+* **Time** is layer time in seconds. A WebAssembly module written for ABI 2 also gets the
+ layer's neighbouring frames at other times (see [WebAssembly ABI](#webassembly-abi)).
* Rendering must be **deterministic** and may run on several threads at once (a WebAssembly
plug-in gets one instance per thread).
* A failed render (an error code, a trap, running out of fuel) leaves the frame unchanged.
@@ -216,22 +217,36 @@ Every plug-in describes itself with a JSON manifest:
parameters; a slider needs `min ≤ default ≤ max` (and `sliderMin ≤ sliderMax`); the manifest
is at most 1 MiB.
-### WebAssembly ABI (v1)
+### WebAssembly ABI
-A module with **no imports** that exports:
+A module with **no imports** exports:
| export | signature | |
|---|---|---|
| `memory` | memory | linear memory shared with the host |
-| `ec_api_version` | `() -> i32` | must return `1` |
+| `ec_api_version` | `() -> i32` | `1` for ABI 1, `2` for ABI 2 (neighbouring frames) |
| `ec_manifest_ptr`, `ec_manifest_len` | `() -> i32` | the UTF-8 JSON manifest in memory |
| `ec_alloc` | `(bytes: i32) -> i32` | a buffer of at least `bytes` bytes, 8-byte aligned; it may reuse the previous one |
-| `ec_render` | `(pixels: i32, width: i32, height: i32, params: i32, nparams: i32, time: f64, scale: f64) -> i32` | process the pixels in place; return 0 on success |
+| `ec_render` (ABI 1) | `(pixels: i32, width: i32, height: i32, params: i32, nparams: i32, time: f64, scale: f64) -> i32` | process the pixels in place; return 0 on success |
+| `ec_render2` (ABI 2) | `ec_render`'s arguments, then `prev: i32, prev_time: f64, next: i32, next_time: f64, flags: i32` | the same, with the neighbouring frames; return 0 on success |
For each frame the host calls `ec_alloc` once for a buffer holding the parameters (`nparams`
-little-endian `f64`s) followed by the pixels (`width × height × 4` little-endian `f32`s), fills it,
-calls `ec_render`, and reads the pixels back. Each call gets a fuel budget proportional to the
-frame size; a module that loops forever stops with an error instead of hanging the app.
+little-endian `f64`s) followed by the pixels (`width × height × 4` little-endian `f32`s,
+premultiplied RGBA, row-major), fills it, calls the module's render export, and reads the pixels
+back. An ABI 2 module gets two more pixel buffers after the current frame: the previous and next
+frames, resampled onto the current buffer's grid. At a frame boundary they are the frames before
+and after it (`time ± 1/fps`); between frames they are the two frames that bracket `time`.
+
+The neighbour buffers are always allocated (zeroed when the layer has no pixels there, so a
+module can read both without a null check). `flags` bit 0 is set when `prev` holds a real frame,
+bit 1 when `next` does; `prev_time` / `next_time` are those frames' layer times in seconds (0
+when absent). The ABI version is the module's `ec_api_version` and is independent of the
+manifest's `api` (the native plug-in API): a module can use ABI 2 while its manifest says
+`"api": 1`. Because an ABI 2 module reads other times, its layer is keyed on the layer time in
+the render cache; ABI 1 modules keep the time-independent key.
+
+Each call gets a fuel budget proportional to the frame size; a module that loops forever stops
+with an error instead of hanging the app.
#### Example
@@ -324,8 +339,10 @@ register_plugin(Arc::new(Swap(manifest)))?; // before the UI builds its menus
## Plug-in API 2 (native plug-ins)
API 2 is for Rust plug-ins and for hosts that bring effects from elsewhere (such as
-[external effect helpers](external-helpers.md)); the WebAssembly ABI stays at 1. Manifests with `"api": 1` or `2` are accepted,
-`effect.plugins.list` reports `api: 2`, and up to 1024 plug-in effects can be registered.
+[external effect helpers](external-helpers.md)); the WebAssembly ABI is versioned separately
+(ABI 2 adds the neighbouring frames, see [WebAssembly ABI](#webassembly-abi)). Manifests with
+`"api": 1` or `2` are accepted, `effect.plugins.list` reports `api: 2`, and up to 1024 plug-in
+effects can be registered.
* **New parameter types**: `point3` (`default` `[x, y, z]`; x, y arrive in buffer pixels, z as is),
`layer` (another layer of the composition; flattens to its id, -1 for none, read with
@@ -354,9 +371,11 @@ API 2 is for Rust plug-ins and for hosts that bring effects from elsewhere (such
### Compatibility
-The API version is checked when a plug-in loads: a manifest or module for another version is
-refused with a message. Within a version the contract above does not change; additions (new
-parameter types, new optional exports) bump the version.
+The API version is checked when a plug-in loads: this build implements plug-in API 1 and 2 and
+WebAssembly ABI 1 and 2; a manifest or module for another version is refused with a message.
+ABI 1 modules load and render unchanged; ABI 2 modules add `ec_render2` and the neighbouring
+frames. Within a version the contract above does not change; additions (new parameter types,
+new optional exports) bump the version.
## Plug-in Library
diff --git a/docs/web.md b/docs/web.md
index 666ffe37b..f94a687be 100644
--- a/docs/web.md
+++ b/docs/web.md
@@ -174,7 +174,7 @@ the same futures with `passes::block_on`; they never wait there).
- **Render Queue**: `effectcraft_export::export_async` renders each frame in passes (frames
with deferred readbacks render one by one instead of in parallel batches) and encodes as
before (`Exporter::export_async`). As on the desktop, a job renders every frame on the
- project's renderer (the worker's GPU with Mercury GPU Acceleration), not on whichever
+ project's renderer (the worker's GPU with GPU Acceleration), not on whichever
compositor measured faster, so runs don't differ by timing.
- **Analyses** (Warp Stabilizer, 3D Camera Tracker, Track Motion, mask and face tracking, Roto
Brush freeze and propagation): their work functions are `async`; started with `wait` inside
diff --git a/examples/plugins/posterize-bands/Cargo.toml b/examples/plugins/posterize-bands/Cargo.toml
index 825d704aa..65bbbaaaf 100644
--- a/examples/plugins/posterize-bands/Cargo.toml
+++ b/examples/plugins/posterize-bands/Cargo.toml
@@ -1,6 +1,6 @@
[package]
name = "posterize-bands"
-description = "Example EffectCraft effect plug-in (WebAssembly, plug-in API v1): posterizes luminance into tinted bands"
+description = "Example EffectCraft effect plug-in (WebAssembly ABI 1): posterizes luminance into tinted bands"
version = "1.0.0"
edition = "2024"
license = "MIT OR Apache-2.0"
diff --git a/examples/plugins/posterize-bands/src/lib.rs b/examples/plugins/posterize-bands/src/lib.rs
index 9af709433..77026a16f 100644
--- a/examples/plugins/posterize-bands/src/lib.rs
+++ b/examples/plugins/posterize-bands/src/lib.rs
@@ -1,4 +1,4 @@
-//! Posterize Bands: an example EffectCraft effect plug-in (plug-in API v1, see
+//! Posterize Bands: an example EffectCraft effect plug-in (WebAssembly ABI 1, see
//! `docs/plugins.md`). It quantizes each pixel's luminance into `levels` bands and mixes a tint
//! colour in by `mix` percent, optionally only above a `threshold`.
//!