Commit Graph
2585 Commits
Author SHA1 Message Date
dedandClaude Opus 5.5 a330110476 G5: a styled layer rendered by two workers at once shares its body and passes (#1812)
Review: styled() kept the buffers it rendered instead of the ones LayerCache::insert returned, so
without a blending-space conversion concurrent misses still returned separate body and pass
buffers (and the GPU uploaded each).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-20 16:12:22 +03:00
Camille Moine 14453386ac Viewer: keep hidden AV layers' controls visible (#1769) 2026-10-20 14:46:05 +02:00
Camille Moine c7eb48dc3a Layer: reveal layer sources in the Project panel (#1809) 2026-10-20 13:59:01 +02:00
Camille Moine 8d887fd6da Layer: replace a layer's source with Alt-drag and Ctrl+Alt+/ (#991, #813)
Alt/Option-drag a Project item onto a Timeline layer, or press Ctrl+Alt+/ (Cmd+Opt+/) with layers and an item selected, to swap the layer's source. The layer keeps its name, timing, transforms, keyframes, expressions, effects, masks, switches, parenting and track matte; a source with audio adds Audio properties when missing. Precompositions can't be nested inside themselves.

AVLayer.replaceSource now runs the same engine command and closes the replaceSource part of #813.
2026-10-20 12:18:46 +02:00
dedandClaude Opus 5.5 9c5494fd29 G5: a layer rendered by two workers at once is shared from the cache (#1812)
Preview workers that start together miss the layer cache together, and each kept its own copy
of every layer; on the GPU each copy was uploaded and packed into its own Classic 3D atlas, which
ran the device out of memory on a cold start. LayerCache::insert now keeps the first buffer of a
key and returns it, and the renderer goes on with the returned buffer, so the workers share one.
Renders don't wait for each other: on the shared frame pool a blocking wait could end up beneath
the work it waits for (tried, it stalled playback for the wait's timeout).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-20 12:31:25 +03:00
dedandClaude Opus 5.5 ac5799bd26 G5: the playing prefetch window starts at the first uncached frame, ahead × 3 wide
Looking up to the whole RAM preview for uncached frames let the workers spread over the preview
while the playhead waited. On the GPU each worker then built a Classic 3D atlas for its own set
of layers, and on a cold start of the #1812 project the device ran out of memory far more often
(first pass 1-56 % of real time instead of 63-81 %). The window now keeps its old width but
starts at the first frame ahead that isn't cached, so a loop or a restart still renders on at
once.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-20 11:43:30 +03:00
dedandClaude Opus 5.5 4cf6580b19 G5: a reduced still's cache key includes its nominal size (#1812)
Review: two footage items of one file with different nominal sizes could share a sized entry,
though one is resampled and the other kept as decoded.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-20 10:42:22 +03:00
Brandon ThomasandClaude Opus 5.5 de3fec28ed Release 0.13.0
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
v0.13.0
2026-10-19 22:18:54 -04:00
dedandClaude Opus 5.5 e14cdd6009 Layer cache: animated masks with mask motion blur key the layer time
Review: mask motion blur draws an animated mask at the shutter's other times, but the layer key
hashed its value at this time only. Two frames with the same mask value (a hold before a move)
shared a cached layer, with the wrong blur. This applied to solids, text and shapes already, and
to stills since this PR.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-20 04:21:53 +03:00
dedandClaude Opus 5.5 ea1f2fe984 G5: a still decoded larger than its nominal size is resampled like the renderer does (#1812)
Review: still_at_size returned a smart object's pixels unresampled when they differed from the
footage's nominal size. It now follows footage_buf: pixels larger than nominal are resampled to
the requested size, smaller ones are left for the renderer to scale up.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-20 04:21:14 +03:00
SBaksa f41aa134a8 Text Range Selector test: change Units through the Timeline popup (#1814)
The Index-units test now opens the Units popup in the Timeline and picks
Index, asserts the stored Units value, then reads the painted Start, End
and Offset, so it also fails when the Units control doesn't update the
session.
2026-10-20 12:09:33 +11:00
dedandClaude Opus 5.5 c33d5c20df G5: a still asked for at its own size is the unsized frame (#1812)
Review: frame_at_size at a still's native size made a second cache key, so the pool decoded
and kept a second full-size copy of a frame thumbnail() or frame() already had.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-20 04:01:07 +03:00
dedandClaude Opus 5.5 ff20f8ec41 G5: a playing preview prefetches past the frames it already cached
The playback prefetch only looked ahead*3 frames (96 with 16 workers) for uncached frames.
After a loop or a restart from the start those were all cached, so the workers stood idle until
the playhead came within that window of the end of the cached run, then the preview stalled.
A playing preview now looks as far ahead as the RAM preview holds (and the range spans) for
the next uncached frames, still queuing at most ahead at a time; eviction already spares the
frames the playhead reaches first (#595).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-20 03:43:35 +03:00
dedandClaude Opus 5.5 fd1250d224 G5: still footage layers are kept in the layer cache across times (#1812)
Footage layers had no layer cache key, so a still made a new layer buffer every frame on every
preview worker, and the GPU compositor uploaded it again each time (its upload cache is keyed
by buffer). Stills (without a proxy) are now keyed like text and shape layers, without the
source time; movies and sequences are unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-20 03:43:33 +03:00
dedandClaude Opus 5.5 57326dc6a7 G5: stills at a reduced render size are resampled once and kept at that size (#1812)
The media pool honoured the requested size only for movies; stills came back
at full size and the renderer resampled them on every frame. A 21120 px wide
plate at Quarter was re-filtered each frame, and four of them (1.85 GB as f32)
did not fit the 1 GiB pool, so they were also decoded again and again.

Stills are now resampled once with effectcraft_raster::resample (the same
call the renderer made, so pixels are unchanged) and the pool keeps the
reduced copy under the sized key.

#1812 project at Quarter, CLI bench: 410 ms -> 33 ms a frame (26 ms with the
layer cache); desktop playback 2% -> 60-99% of real time.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-20 03:43:33 +03:00
TimotheusG f667b6e11e fix(script): retire streams after failed mode transitions 2026-10-19 19:19:20 -04:00
TimotheusG c4505d34de test(render): document automatic backend fixtures 2026-10-19 18:47:51 -04:00
TimotheusG 4a84b4da08 docs(script): explain socket dispatch and regression cases 2026-10-19 18:26:34 -04:00
TimotheusG e551cbe2ca test(render): use controlled costs for Auto backend checks 2026-10-19 18:26:34 -04:00
Egon 5000 ce928a66da Merge remote-tracking branch 'origin/main' into ui/shape-group-elided-contents
# Conflicts:
#	docs/ui-parity.md
2026-10-19 23:00:22 +02:00
Egon 5000 89eaac0489 Merge remote-tracking branch 'origin/main' into menu-bar-native-behaviour
# Conflicts:
#	crates/ui-egui/src/panels/timeline.rs
2026-10-19 22:59:07 +02:00
Wes CampbellandClaude Opus 5.5 a3d5e55bc7 EPS: Illustrator EPS files draw their artwork (#955)
Illustrator EPS imported as an empty layer. Three gaps in the PostScript
interpreter, each against the PostScript Language Reference:

- An operator stored under another name (`/mo /moveto load def`, as
  Illustrator's prolog does for every path and paint operator) pushed the
  operator's name instead of running it, so nothing was drawn.
- Device queries that return values (currentpagedevice, currentscreen,
  currentflat, currenthalftone, status, dictstack, ...) pushed nothing,
  shifting the stack under the procset's guards. They now push a plain
  device's defaults; setscreen pops its three operands.
- `currentfile 0 (eod) /SubFileDecode filter` now skips to the end-of-data
  string, so an embedded XMP packet isn't run as PostScript.

The regression test uses synthetic PostScript only.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 14:33:59 -05:00
TimotheusG d6afa87641 fix(text): isolate CJK fallback language and cache entries (#1141) 2026-10-19 15:30:35 -04:00
NetterSilverandClaude Haiku 5.5 eca2c32793 Fix hsv_to_rgb returning magenta for tiny negative hues
Found while testing crates/color/src/lib.rs:143-158

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-19 20:31:18 +02:00
dedandClaude Opus 5.5 35691f8d19 G5: bench builds scenarios from an args file on Windows
xtask bench passed the whole layers scenario on one command line, longer
than Windows' 32 767-character limit (os error 206), so no scenario past
demo ran. effectcraft-cli run takes --args-file F (one argument per line)
and bench writes its commands there.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 21:29:59 +03:00
NetterSilverandClaude Haiku 5.5 81548edff9 Resolve SVG font-size percentages against the parent font size
Found while testing crates/svg/src/lib.rs:624

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-19 20:22:36 +02:00
Davit MatchakhelidzeandClaude Opus 5.5 c628dc7d96 docs: the Georgian panel count is at this revision; the other counts stay upstream's dated recount
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YMTAbGNRxnMEzRvYnQGphF
2026-10-19 21:42:50 +04:00
TimotheusG 0a78eb2870 fix(script): bound and cancel socket writes (#1248) 2026-10-19 12:56:33 -04:00
vangel76andClaude Opus 5.5 e559a7ce9a Review: tie the colour kernels' literals to the CPU constants; visible GPU skip; B&C wording
WGSL cannot read Rust constants, so the Rec. 601 luma (Tint, Tritone, Luma Key /
Extract), Black & White's tint weights and Exposure's 2.2 power stay literals in the
kernels; they now name their Rust source (effects::LUMA_601, BW_TINT_LUMA,
EXPOSURE_LINEAR_GAMMA, newly exported) and the test shader_constants_match_the_cpu
(no GPU needed) fails if a literal drifts. gpu_tint_defaults_match_after_effects_greys
says "skipped: no GPU adapter" when it skips (EFFECTCRAFT_REQUIRE_GPU=1 still makes it
fail). docs/effects-parity.md: Brightness & Contrast is close to, not the same as,
After Effects (up to 6.2/255), and the summary row lists what is measured.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 18:38:41 +02:00
NetterSilverandClaude Haiku 5.5 e244d64235 Reject non-finite numbers in CSS colour parsing
Found while testing crates/svg/src/color.rs:182-185

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-19 18:25:20 +02:00
vangel76andClaude Opus 5.5 d9205fa5f4 Curves: a natural cubic spline through the points, as After Effects
After Effects' Curves effect interpolates its points with a natural cubic
spline (zero curvature at the ends), clamped to 0..1: AE 2026 renders of an
RGB curve (0,0) (125,199) (255,255) and a Red curve (0,0) (128,44)
(255,255) (cases 962 / 963, ROUND4) give exactly the natural spline's values
on every grey step (0, 30, 59, 115, 164, 202, 227, 242, 250, 255 and 0, 0, 1,
6, 19, 44, 83, 135, 194, 255). EffectCraft used a monotone (Fritsch-Carlson)
spline: 34 / 67 / 125 / 171 ... on the RGB curve, up to 10/255 off (ROUND4
measured up to 6 levels on real projects); now within 1/255, CPU and GPU (the
same Hermite tables carry the spline's knot slopes). Lumetri's curves and
Glow's Arbitrary Map keep the monotone spline (not measured).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 16:54:31 +02:00
Davit MatchakhelidzeandClaude Opus 5.5 2447b54856 docs: Georgian catalog counts at this head
Menus 628 rows (every menu catalog), panels 886 (695 shared with the Chinese
catalogs plus 191 Georgian-only), effect names 307 + 21 categories; gaps.md
and localization-parity.md now agree.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YMTAbGNRxnMEzRvYnQGphF
2026-10-19 18:16:21 +04:00
Davit MatchakhelidzeandClaude Opus 5.5 dd29665939 text: the Georgian fallback test goes through fallback_for
system_fallback is the scan-order search; fallback_for is where the Georgian
families are preferred, so the test asks it for Mkhedruli in Inter.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YMTAbGNRxnMEzRvYnQGphF
2026-10-19 18:16:21 +04:00
vangel76andClaude Opus 5.5 84ffc8453e Fill: Opacity is the filled layer's opacity, as After Effects
Without a Fill Mask, After Effects turns the layer into the fill colour and
applies Opacity to its alpha; nothing of the original shows through. AE 2026
renders Fill (0, 0.5, 1) at Opacity 50 % on a Gradient Ramp over a red solid
as premultiplied (0, 0.251, 0.502) at alpha 0.502 at every pixel; EffectCraft
mixed the fill with the ramp (mean difference 95.5/255), now within 1/255,
CPU and GPU. Invert fills the transparent part the same way. With a Fill
Mask the mix with the original is unchanged (not measured). Lottie's fill
effect (colour, alpha x opacity) now plays the same in EffectCraft.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 16:16:12 +02:00
vangel76andClaude Opus 5.5 d7854b84a3 4-Color Gradient: weights 1 / (d² + Blend²), as After Effects
After Effects weighs each of the four points by its inverse squared
distance softened by Blend squared, 1 / (d^2 + Blend^2) in pixels: fitted to
AE 2026 renders of the default gradient at Blend 10, 100 and 300 and case
904 E16 at Blend 50 (power 2.00 at every Blend, softening 0 / 2367 / 9817 /
90127 = about Blend^2; mean error 0.27/255, max 0.9). EffectCraft used
1 / (d^2 / (100 Blend))^1.5, in which Blend cancels out: E16 was 34/255 off
on 99 % of the grid, now 0 grid points off, max 1/255, CPU and GPU.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 16:16:02 +02:00
vangel76andClaude Opus 5.5 75271bfe6c Luma Key and Extract: Rec. 601 luminance, as After Effects
After Effects 2026 keys Luma Key and Extract (Channel Luminance) on Rec. 601
weights of the working-space values: Key Out Darker / Extract Black Point at
65, 166 and 24 on pure red, green and blue keep red (601: 76, 709: 54) and
blue (29 / 18) and key out green (150 / 182) - Rec. 709, which EffectCraft
used, decides all three the other way. Case 904 E18 (Extract 30 / 220 /
softness 10 on grey and colour steps): 513 of 5184 grid points off (pure blue
kept at 231 in AE, keyed out in EC), now 0, max 0. CPU and GPU.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 16:16:01 +02:00
Davit MatchakhelidzeandClaude Opus 5.5 4d62e21e90 Merge i18n-improvements (CodeRabbit fixes)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YMTAbGNRxnMEzRvYnQGphF
2026-10-19 18:15:46 +04:00
Davit MatchakhelidzeandClaude Opus 5.5 ad8db289cf i18n: Settings page titles read the menu bar's Settings rows
The panel catalog's \"Type\" is the kind (Camera Settings, the Project column), so
the Type page drew as \"kind\" in Chinese; its title now comes from the
app.settings menu row (文字), as the Settings submenu draws it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YMTAbGNRxnMEzRvYnQGphF
2026-10-19 18:15:35 +04:00
Davit MatchakhelidzeandClaude Opus 5.5 60dab98e9b i18n: saved workspace names stay verbatim in the workspace menu
Only the built-in workspaces read the Window ▸ Workspace rows; a name the user
saved (\"Composition\", say) no longer falls through to the panel catalog.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YMTAbGNRxnMEzRvYnQGphF
2026-10-19 18:15:35 +04:00
vangel76andClaude Opus 5.5 39bd0efac2 Luma Key: Key Out Brighter and Darker cut hard at Threshold, as After Effects
After Effects' Luma Key removes everything darker (or brighter) than Threshold
and ignores Tolerance for those two key types; Tolerance only sets the band of
Key Out Similar / Dissimilar. EffectCraft ramped the matte over Tolerance, so
case 719 (a 50 % grey, Key Out Darker, Threshold 140, Tolerance 20) kept about
80 % of the layer where AE keys it out completely.

Measured in AE 2026 on a vertical grey ramp (cases 812-814): Darker keys up to
level 139.9 and keeps 140.1 (EffectCraft now the same row); Similar keys levels
120.3-160.0; with Edge Thin 1 / Edge Feather 2.5 the matte rises over rows
591-596 (EffectCraft within 0.2 of AE's alpha there). CPU and GPU.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 16:15:02 +02:00
vangel76andClaude Opus 5.5 dc9f15ada1 Brightness & Contrast: negative settings invert the positive curves, as After Effects
In After Effects 2026 the non-legacy curve of Brightness -40 is the inverse
of Brightness +40 (within 2.6/255 on a full black-to-white ramp) and Contrast
-50 the inverse of Contrast +50. EffectCraft fitted the negative brightness
with its own power (2^(1.32 |b|) on v), 20/255 off AE at -40; the negatives
now use the reciprocal exponents of the positive curves: Brightness -40 max
6.2/255 (was 19.8), Contrast -50 4.1 (was 7.0); positives unchanged (40:
5.5, 80: 7.8, Contrast 50: 2.7, 90: 5.0; B20 C30: 6.6, which confirms
brightness before contrast). The #681 oracle samples still pass. CPU and GPU.
The positive curves' remaining 5-8/255 needs a better curve family (a
two-point spline fits each capture within 1.6/255), left open.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 16:15:02 +02:00
vangel76andClaude Opus 5.5 515cc3d5f7 Levels: channel controls before RGB, "Off for 32 bpc Color" unclipped in 32 bpc, as After Effects
After Effects 2026 in a 32 bpc project, Levels (Individual Controls) with RGB
(0.1, 0.9, gamma 1.5, 0.05, 0.95), Red Gamma 0.8, Green Input White 0.8 and
Blue Output Black 0.2 on grey steps 0..255 (case 904 E07): every step matches
"each channel's controls, then the RGB controls" with nothing clipped
(values below Input Black end below Output Black, above Input White above
Output White). EffectCraft ran RGB first and clipped "Off for 32 bpc Color"
(it could not see the bit depth): up to 27/255 off on 95 % of the grid; now
0 grid points off, max 1/255, CPU and GPU.

EffectEnv gains float_depth (the renderer sets it for 32 bpc projects), so
"Off for 32 bpc Color" clips in 8 / 16 bpc projects as before. Unclipped
values below 0 take the gamma mirrored through 0. Plain Levels keeps its
order (its channel controls were not measured); its clipping follows the same
rule. EffectCraft's own projects default to 8 bpc and are unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 16:14:42 +02:00
vangel76andClaude Opus 5.5 617b0a578d Exposure: After Effects parameter ranges
All twelve sliders (Master, Red, Green, Blue) take After Effects'
ranges: Exposure valid -100..100, slider -4..4, 2 decimals (was -20..20,
slider -5..5); Offset -2..2, slider -0.5..0.5, 4 decimals (unchanged);
Gamma Correction valid and slider 0.1..10, 2 decimals (was 0.01..9.99,
slider 0.1..3).

Every value inside the old Exposure and Offset ranges stays valid. Saved
values are not clamped on load, so a gamma below 0.1 from an older
project or a Photoshop import (0.01..9.99) is kept and still renders
(the renderer's 0.01 floor is unchanged); only new edits clamp to 0.1.
Test of the ranges and of an old gamma surviving the load refresh.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 16:14:26 +02:00
vangel76andClaude Opus 5.5 c7060e2d75 Exposure: gamma 2.2 linear-light conversion, as After Effects
With Bypass Linear Light Conversion off, Exposure decoded and re-encoded
with the piecewise sRGB curve. After Effects 2026 renders (sRGB working
space, 32 bpc) of Offset 0.0005 / 0.002 / 0.02 / 0.1 on black measure
8 / 15 / 43 / 90, which a pure 2.2 power predicts (8.06 / 15.13 / 43.08 /
89.54) and the sRGB curve does not (1.65 / 6.59 / 38.68 / 89.04).

The effect now uses its own 2.2 power curve on the CPU and in the GPU
kernel; the shared colour functions and other effects are unchanged. As
before, the conversion applies whatever the working space, also a
linearised one. Negative values go through both curves mirrored (input
was clamped at 0 before), so defaults are an identity for 32-bpc values
and a negative Offset darkens past black without NaN.

New test against the AE values; existing Exposure tests still hold.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 16:14:26 +02:00
vangel76andClaude Opus 5.5 70c1349cbc Black & White: Tint keeps the gray's luminosity, as After Effects
After Effects tints Black & White's gray like a Color blend: the tint colour's
hue and saturation at the gray's luminosity (weights 0.3 / 0.59 / 0.11, channels
outside 0..1 pulled back toward the gray). EffectCraft used the gray as HSL
lightness. Measured in AE 2026, Tint Color [1, 0.5, 0]: a red solid at Reds 10
(case 717) AE (43, 21, 0), EffectCraft was (51, 26, 0), now (43, 21, 0); a
yellow solid at the default sliders (gray 0.6, case 825) AE (255, 129, 2), now
(255, 129, 3); white stays white. The six sliders already matched AE on eight
colours (cases 816, 817). CPU and GPU.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 16:14:21 +02:00
vangel76andClaude Opus 5.5 960f41d50b Tritone: Rec. 601 luminance, as After Effects
After Effects' Tritone weighs the working-space values with Rec. 601 (0.299,
0.587, 0.114), as its Tint does; EffectCraft used Rec. 709. Case 718 (red solid,
Highlights [1,1,0.8], Midtones [0.6,0.2,0.2], Shadows [0,0,0.3], Blend 25):
AE (132, 23, 46), EffectCraft was (113, 16, 49), now (132, 23, 46). On a grey
ramp (case 815) the shadows / midtones / highlights mapping already matched and
still does within 1/255. CPU and GPU (fx_color op 4).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 16:13:41 +02:00
vangel76andClaude Opus 5.5 fb16d5573e Tint: Rec. 601 luminance weights, as After Effects
After Effects 2026 (sRGB working space, not linearised) maps red, green,
blue and 50% grey solids at Tint's defaults to 76, 150, 29 and 128/255:
Rec. 601 weights on the working-space values, not Rec. 709. CPU and GPU
kernel changed; tests pin the four greys within 1/255.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 16:12:50 +02:00
SBaksa 71aafd6307 Text Range Selector: test the Timeline shows Index-unit values without % (#1814)
Start, End and Offset are read as painted in the Timeline: with % under
Units = Percentage, without it under Units = Index. Fails on the old
suffix rule ("0.0%").
2026-10-20 01:05:15 +11:00
dorfee 80158bb69b ScriptUI: install scheduled task runner in host sessions 2026-10-19 16:45:39 +03:00
SBaksa c17f9eb959 Text Range Selector: Start, End and Offset show as counts with Units = Index (#1814)
With Units set to Index the selector already counts characters (words,
lines), but the timeline kept showing Start, End and Offset as
percentages ("3.0%"), so switching looked like it did nothing. They are
now shown without the % sign while Units is Index
(render::text::in_index_units).
2026-10-19 21:08:16 +11:00