Review of #2158: a buffer-backed accessor is checked against its buffer, but
each primitive that references it reads it again and keeps its own copy, so a
3 MB file listing 50,000 references to one 100,000-vertex accessor asked for
about 80 GB. Every accessor read, with or without a bufferView, is now
charged to one budget for the whole file, as is what a primitive keeps
besides its reads: generated indices when `indices` is missing, the triangle
list (3(k-2) for a strip or fan of k), flat-normal vertices and computed
tangents. Going over it is the usual malformed-file error.
The cap is a fixed 2^28 components (about 1 GiB as f32/u32), not a multiple
of the buffer size: real assets share one vertex buffer across many
primitives, and a 10M-triangle scan reads about 90M components. Buffer-less
accessors keep their tighter 16M sub-budget.
The WGSL grammar test scanner indexed token characters directly, so a malformed shader could panic the test instead of failing it. Checked access turns that into a reported violation.
Conflict in crates/text/src/layout.rs (paragraph direction at the top of
paragraph()), against the closure-to-method-path cleanup (4e9fa51f): kept this
branch's direction resolved once from BidiInfo.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Review (CodeRabbit on #1875): with the direction unset, Hebrew text resolved to
right-to-left took its start indent on the left. The paragraph direction is now
resolved once from BidiInfo before the margin and alignment helpers, so both use
it. Regression test.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Review (CodeRabbit on #1875): with the paragraph direction unset, a right-to-left
paragraph resolved by BidiInfo was still aligned as left-to-right justified point
text, so it stayed left instead of flush right. eff_align now takes the resolved
direction. The box-text first baseline used the font ascent whenever any run of
the text was vertical; it now looks only at the runs of the first line.
Two regression tests.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
After Effects lists Targa among its still-image output formats; EffectCraft
imported Targa (#745) but could not render to it.
- OutputFormat::TargaSequence ("Targa Sequence", `.tga`, numbered like the
other sequences; `tga` / `targa` as a format name or output extension).
- Written by the `image` crate's Targa encoder (its `tga` feature, already
enabled in effectcraft-media; no new crates, Cargo.lock unchanged), with
run-length compression off: an 18-byte header, top-left origin, 24-bit BGR
for RGB, 32-bit BGRA with 8 alpha bits in the image descriptor for
RGB + Alpha (straight or premultiplied), 8-bit grey for Alpha.
- The render queue's size estimate counts the uncompressed bytes.
- CLI usage, the renderQueue command specs, README, architecture.md and
file-format-parity.md name the new format.
Tests: each Targa frame holds exactly the pixels of the PNG sequence of the
same job, with the expected header, numbering and size; the frames read back
through the Targa importer as the same picture (straight, and premultiplied
when interpreted so); the image-sequence round trip, the format parser and
the renderQueue commands cover it too.
Found while testing crates/time/src/lib.rs:390 (format_time, TimeDisplay::Seconds)
Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Found while testing crates/color/src/lib.rs:100 (rgb_to_hsl)
Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Found while testing crates/model/src/gltf.rs:83-96 (uri_decode)
Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
upgrade_shape_contents now visits nested groups with a work list, so a
project with very deeply nested shape groups does not run out of stack
while Wiggle Paths gains Spatial Phase. The new test nests a Wiggle
Paths 100,000 groups deep and upgrades it on a 2 MiB stack.
Pin craft-libs crates to 3723e32a, which adds the group extra-tabs hook.
The comp tabs follow the panel tabs directly, with no drag bar between
them, and the group header holds only the lock and the panel menu.
The macOS menu bar takes Cmd+C, Cmd+X, Cmd+V, Cmd+A, Cmd+Z and Shift+Cmd+Z
before any window sees them. The menu only checked the main window's
keyboard focus, so with a text field focused in a floating panel's own OS
window those keys ran Copy, Paste or Undo on the project. The menu now asks
craft-ui which window is typing and sends the field its keys there (the
window fetches the clipboard text for Paste), and keeps the Edit items a
field takes enabled while one has the keyboard: Paste followed the project
clipboard and was greyed out with nothing copied there.
The comp tabs follow the panel tabs and are drawn like them (craft-ui's
tab widget and the dock style's font and colours). The panel tabs keep
their full width; comps without room are listed in a » menu at the end
of the row, and picking one shows it. The shown comp's tab always stays
in the row, and the comp tabs stay while another panel of the group is
shown.
craft-libs crates move to one rev, 37c907d2 (contains main's craft-update and craft-docpath pins).
Docs: native floating windows are Windows, macOS and X11 only; the UI estimate drops the
multi-monitor panel work that is done.
With Show Font Names in English off (the default), the Character and
Properties font menus draw each family's own-language name in the
interface font. On Windows, Microsoft YaHei's Simplified Chinese family
name is 微软雅黑, and the Han face of an English interface can lack 软.
The app drew a missing-glyph box in its place, and the font search
tests in the effectcraft-ui-egui it binary panicked with "No glyph for
"软"".
A row now draws its own-language name when the interface fonts have a
glyph for each character, and its English family name otherwise. The
row's hover text follows the same rule. Search still matches both names.
- delta_for no longer searches 0..255 for every probability: a 256x256 table is
built once.
- BoolEncoder remembers where the trailing run of 0xFF bytes starts, so a carry
no longer rescans the output (the cost was quadratic over long runs).
- Vp9Encoder::new clamps width and height to 65536; larger sizes used to wrap
in the 16-bit frame size fields and write a corrupt stream.
The output is byte-identical for all sizes up to 65536.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
The 8x8 and 16x16 SAD uses per-column 16-bit sums, and the cost of a motion
vector (a pure function of the vector) is remembered for the vectors the
search tests again. The output is byte-identical.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
The 16 outputs of the 4x4 forward transform are accumulated together in the
same order as before (no serial add chain per output) and the quantiser
truncates instead of calling floor on a non-negative value. The output is
byte-identical.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
The encoder's loop filter runs three trial passes per frame with a scalar
filter. Filter the eight positions along an edge together with 16-bit lanes
(ported from the decoder's loop filter); the scalar filter stays as the test
oracle and a new test compares both on 20000 random cases. The output is
byte-identical.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
The 16 quarter-sample phase planes are built with 16-bit lane filters (the same
narrowing trick as the decoder), edge replication copies rows instead of
clamping every sample, and mc::predict reads straight from the reference for
blocks away from the edges. The output is byte-identical.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Wiggle Paths had Size, Detail, Points, Wiggles/Second, Correlation,
Temporal Phase and Random Seed, but no Spatial Phase, which After
Effects lists among its properties (ADBE Vector Spatial Phase). Spatial
Phase now moves each point's own displacement along its subpath: 360
degrees is once around, and a fraction of a point is interpolated
between neighbors. At 0 degrees a path draws as before.
A project saved without the property gets it at 0 degrees, after
Temporal Phase, when it opens. Scripts can read and set every Wiggle
Paths property by its match name.