The base run comes from the file and is cloned once per character run, so
it now has to fit the template node budget, and each font is looked up
once per name. Also names the reopened-layer tuple in psd_kerning for
clippy::type_complexity.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The reader takes a `quiltWarp` of at most 64 patches along a side, but the
writer wrote any split warp and framed `Trnf` by its control box. A Warp
Grid of 64 plus one more split (65 patches) was refused on reopen while its
corners still framed the warped box, so the layer came back stretched and
shifted ([2,0,0,2,120,210] -> [2.4,0,0,2.4,100,200]). Such a warp is now
written as no warp, with a message, framed by the source rect, as before
#6913, and a stale imported `quiltWarp` is dropped.
Co-authored-by: Thang Nguyen <13392060+thangnm93@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Photoshop reads the character style from Txt2 and quit on the bare run
(`/0 0 /11 mode`) that new objects got. New and edited objects now get one
style run per character run, built on one of the object's own runs with
every key kept, and font, size, faux styles, leading, scales, tracking,
fill colour, OpenType keys and auto-kern mode set from the layer. A font
the block's font list lacks is appended to it. Edited objects therefore no
longer keep the old text's features by position.
build_tysh no longer writes TextIndex 0 for a layer without one: the
export took it as a kept number, so a Type tool layer landed on object 0
(a deleted layer's, or the one of a layer above it). set_text_index puts a
missing TextIndex right before EngineData, where Photoshop writes it.
pad_frames pads to at most MAX_TEXT_INDEX + 1 frames.
edited_text_keeps_the_files_txt2_object (#7220) now expects style runs
that follow the layer's runs and size.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
`batch_runs` cut a run at the pass where the render captured its prefix checkpoint, so a cached
render grouped plain layers differently from an uncached one. On D3D12 with FXC a layer's bits
batched and drawn alone differ by about 1 ULP, so reuse stopped being exact there (#5286):
prefix_follows_an_edit_up_the_stack_and_stays_exact and
chunks_keep_their_own_checkpoint_after_a_partial_refresh failed on an RTX 5070 Ti.
The runs now depend on the plan alone and are computed once per render. `run_starts` marks the
passes a run starts at, and the prefix cache captures and resumes only at checkpoints there, so a
resumed render draws the passes above in the same runs as an uncached one. It may resume up to
three layers lower than before, one more batched pass.
The cache tests give their layers a reveal-all mask so each draws alone and keeps a checkpoint;
prefix_follows also runs on batched layers and checks that a capturing render batches like an
uncached one, which fails on the old executor on any backend.
Claude-Session: https://claude.ai/code/session_01Aab8aPCQgoN1sYrWPk8Kr6
wgpu's Instance::default() ignores WGPU_BACKEND and WGPU_DX12_COMPILER, so the parity tests
always took the default adapter: Vulkan on a Windows machine that has a driver for it, which hid a
D3D12-only difference. They now read both, and a backend asked for that has no adapter or can't
render Rgba32Float fails the tests instead of skipping them.
Claude-Session: https://claude.ai/code/session_01Aab8aPCQgoN1sYrWPk8Kr6
DDS textures can now be saved, not just opened: uncompressed (BGRA, BGRX, L8, A8L8; lossless) or BC1/BC2/BC3 (DXT1/3/5) from a clean-room block encoder, with an optional box-filtered mip chain, in the legacy header. Save As and Save a Copy ask with DDS Options; scripts pass `ddsCompression`/`ddsMipmaps` (file commands, control `app.save`, RPC `doc.save`, MCP `doc_save`/`doc_export`), and the CLI takes `--dds-compression`/`--dds-mipmaps`. Targa and DDS answers travel together as `FormatChoices` through the Save As flow.
Review follow-ups:
- File › Save behind DDS or Targa Options records a plain Save with its answer, and replaying `file.save` applies it (#3531).
- The block encoder finds the principal axis from every channel, so a channel that varies on its own can't hide the others' variation.
- DDS joins the shared round-trip suite; the header is built before the output buffer is allocated.
- Enter on a focused Cancel in DDS, Targa or TIFF Options cancels instead of saving.
Main made the Properties Feather slider's track cubic (#6727), so a
1% drag no longer reaches 10 px; drag a fifth of the way (8 px) as
main's own mask test does.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Adds .coderabbit.yaml so CodeRabbit no longer reviews or comments on PRs opened by dependabot[bot].
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>