Commit Graph
3466 Commits
Author SHA1 Message Date
Nigel Ihza FirdausyandClaude Opus 5.5 a82408e3e2 Actions: Play runs the first action when none is selected (#1990)
The Actions panel's Play button falls back to the first action when no row (or a stale row) is selected, as Photoshop does, and a failed playback request now shows in the status bar instead of being dropped (#1951).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 15:53:33 -04:00
Nigel Ihza FirdausyandClaude Opus 5.5 25e349b048 Dialogs: the whole title band drags the window (#1945)
A dialog's drag handle spans the full title row plus a few pixels of padding around the title, so grabs slightly beside, above or below the title text move the window (#1921). The title keeps its height.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 15:50:27 -04:00
Nigel Ihza FirdausyandClaude Opus 5.5 765495e53b Free Transform: rotation cursor and live angle readout (#1948)
Just outside a corner the pointer becomes a curved rotate arrow, and while rotating the angle is shown
next to it. Distort and Warp keep their cursors.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 15:50:07 -04:00
Nigel Ihza FirdausyandClaude Opus 5.5 c02ffa9755 Spot Healing: Proximity Match samples the original pixels (#1968)
Proximity Match copied its translated patch within the buffer it was writing, so overlapping offsets
re-copied fresh output and left streaks. It now reads from the pre-heal pixels, with checked bounds.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 15:46:58 -04:00
Reynold HuandClaude Opus 5.5 60bce1894b File Handling: wire Lowercase Extension through Save As (#1941)
Preferences > File Handling > Lowercase Extension is live: with it on (the default) a save path's extension is lowercased (CAT.PSD saves as CAT.psd); off keeps the user's spelling. Settings that do nothing: 51 of 141 (#204).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 15:45:20 -04:00
LloydNicholsonandClaude Opus 5.5 be446f89d3 Transparent PNG, TIFF and other flat images open as Layer 0, not Background (#1913)
A flat image with transparency (alpha channel or tRNS) opens as a normal, unlocked Layer 0, as in
Photoshop; opaque images still open as the locked Background. A lone Layer 0 saves back to PNG natively.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 15:43:14 -04:00
Reynold HuandClaude Opus 5.5 429b9fc6a5 Type: wire the Use Escape to Commit preference (#1927)
Preferences > Type > Use Escape to Commit is live: on (the default) Escape commits the type session as before; off, Escape cancels it like the Cancel button, as in Photoshop. Settings that do nothing: 52 of 141 (#204).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 15:42:05 -04:00
Reynold HuandClaude Opus 5.5 23c56c659e Type: wire Fill New Type Layers with Placeholder Text (#1935)
Preferences > Type > Fill new type layers with placeholder text is live: with it off, a Type tool click starts an empty layer (removed again if committed without typing). Settings that do nothing: 53 of 141 (#204).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 15:38:38 -04:00
Nigel Ihza FirdausyandClaude Opus 5.5 3eef2c6bb4 Type: imported PSD tabs render as whitespace, not a box (#1942)
A literal tab in PSD text shaped as .notdef. Layout now shapes it as a space, keeping byte, style
and caret offsets intact. Tab stops are still to come. Part of #1881.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 15:34:38 -04:00
Nigel Ihza FirdausyandClaude Opus 5.5 cc4a13b58d Paint: keep stylus pressure on quick taps (#1967)
A release that egui reports as both a drag stop and a click no longer replays the click over a live
stroke (which painted a second full-pressure dab), and the click fallback now uses the pen's pressure.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 15:34:21 -04:00
MarekSpodBiedryandClaude Opus 5.5 f885991184 Menus: a submenu with every item disabled is disabled too (#1984)
A submenu header is enabled only while some item under it can run, so File > Export, Automate, Scripts and Import grey out while a crop is pending, as in Photoshop (#1976).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 15:33:39 -04:00
Nigel Ihza FirdausyandClaude Opus 5.5 54d7b07acf Convert to Smart Object keeps a pattern fill's pattern (#1937)
The embedded document built by layer_to_smart now carries the document's patterns, so pattern fills
and pattern effects keep rendering inside the smart object and after Edit Contents. Fixes #1867.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 15:33:20 -04:00
Brandon ThomasandClaude Opus 5.5 ee3ebfa748 Smart contents test: match the refused path by file name (Windows CI red since #1882) (#2042)
The refusal message Debug-quotes the path, which doubles backslashes on Windows, so
contains(path) never matched there. Matching the unique file name keeps the check.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 15:32:39 -04:00
kayrockscreenprintingandClaude Opus 5.5 8b29d6c2cd PSD import: warn when an adjustment layer can't be read (#1925)
An adjustment layer kept verbatim as Unsupported rendered as nothing without telling anyone. Import
now warns, naming the layer, the adjustment and (for Color Lookup) the reason. Part of #1763.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 15:29:29 -04:00
Reynold HuandClaude Opus 5.5 b9f469546f Print Size honors the Screen Resolution preference (#1923)
View > Print Size divides the document's ppi into Preferences > Units & Rulers > Screen Resolution (72 ppi by default) instead of a hard-coded 72, and the setting is no longer hidden. Settings that do nothing: 54 of 141 (#204).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 15:29:25 -04:00
Nigel Ihza FirdausyandClaude Opus 5.5 d6802c62c0 Proximity Match: bound search radii to the image (#1969)
best_offset clamps the search radius and ring to the image extent and rejects zero or negative radii,
so hostile values no longer overflow i32 loops or search for billions of iterations.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 15:29:16 -04:00
Nigel Ihza FirdausyandClaude Opus 5.5 3cae29abfa Grid: percentage spacing and snapping use each canvas axis (#1914)
A percentage grid now spaces vertical lines by the document width and horizontal lines by its height,
so rectangular canvases get proportional cells, and grid snapping uses the same per-axis steps.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 15:27:30 -04:00
kayrockscreenprintingandClaude Opus 5.5 2819f37033 PSD export: pattern fill layers keep their pattern in CMYK and Lab (#1917)
The PSD (and layered TIFF) exporter rendered fill layers with no patterns, so pattern fills were
written as transparent pixels; in CMYK and Lab those tiles survive and the reopened layer drew empty.
Pattern fills now render from the document's patterns. Round-trip test over 4 modes x 3 depths.
Fixes #1907.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 15:26:56 -04:00
kayrockscreenprintingandClaude Opus 5.5 19256a29f5 Fill layers keep their colours in the document's mode (#1915)
New Fill Layer (Solid Color, Gradient), the Gradient tool's live fill layers, gradient fill edits and Gradients panel presets store their colours in the document's mode (Color::in_mode / Fill::in_mode), so a fill layer in a Grayscale, CMYK or Lab document composites like the same colour painted with Edit › Fill, as Image › Mode already converted them. Fixes #1905; tests at 8, 16 and 32 bits.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 15:23:07 -04:00
khhjoeandClaude Opus 5.5 01bdf39f1b gpu: write F32_MAX exactly so the compositor shader builds on WebGPU (#1982)
The decimal 3.40282347e38 is just above f32::MAX; naga rounds it but browsers' Tint rejects it, so
the web app had no GPU compositor. Now a hex literal, with a test that every decimal float literal in
the shader fits f32.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 15:22:30 -04:00
3c5dc002d2 macOS: unsaved-changes prompt shows plain button labels (#1936)
On macOS the save prompt reads Save / Don't Save / Cancel without printed key letters, like the native alert; D, C, S, Return and Escape still answer it. Windows and Linux keep their mnemonics. Shortcut test from #1963 (arthurdeka).

Co-Authored-By: arthurdeka <arthurdeka@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 15:22:26 -04:00
jason4shortandClaude Opus 5.5 b808780666 Paste: drop a stale image once the OS clipboard has moved on (#1912)
When the OS clipboard no longer holds the image we mirrored or imported (text or a file was copied
since), the session clipboard drops it, so Paste reports nothing to paste instead of a stale image.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 15:20:38 -04:00
shmuelbiller1andClaude Opus 5.5 3e9359071c Native format: deflated ZIP entries read with an unbounded budget, no huge preallocation (#1956)
Reading a deflated .pcraft entry with max = usize::MAX no longer overflows the take() limit, and a
forged size in the ZIP header no longer reserves gigabytes up front (preallocation is now capped).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 15:19:43 -04:00
DmytroandClaude Opus 5.5 74eacf9860 i18n(uk): refine eyedropper and colour picker wording (#1974)
Ukrainian: clearer sampling terms (Sample, Sample Size), N × N averages, Color to Alpha and the web/print gamut warnings, plus the missing Transparency/Opacity Threshold rows.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 15:18:16 -04:00
ROSSA AIandClaude Opus 5.5 483712655f codecs: PNG export gives the same bytes on any core count (#1932)
The parallel PNG encoder now cuts deflate bands by a fixed byte budget instead of by thread count,
so the same image and options give identical files on any machine. Test covers 1, 2, 7 and 32 threads.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 15:17:06 -04:00
shmuelbiller1andClaude Opus 5.5 decc7715b9 PSD: Optical kerning survives a round trip (#1517)
PSD export regenerates the document Txt2 block with one text object per TextIndex carrying each run's auto-kern mode (manual, metrics, optical), which EngineData's AutoKerning can't distinguish, so Optical no longer reopens as Metrics (#1348). A kept object with unchanged text keeps the file's extras (glyph pen positions); duplicate or out-of-range TextIndex values are renumbered and capped, so a crafted file can't size the save. io corpus tests stay at their floors.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 15:09:10 -04:00
optimalbyteeandClaude Opus 5.5 6ae2a8498c Optimize Radial Blur sampling without changing output (#1499)
Radial Blur prepares its sample transforms once per filter (blur::radial::Plan) and shares them across output tiles, reading each bilinear tap once with channels kept together. Output is identical to the previous sampler at Draft, Good and Best, across colour models and depths (tests compare against the unchanged reference path); a failed table allocation falls back to that sampler. Measured on 24 MP RGBA8, Good, amount 1: Spin 66.1 -> 16.4 s, Zoom 19.2 -> 5.4 s (bench_radial example, docs/radial-blur-performance.md).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 14:41:52 -04:00
Nigel Ihza FirdausyandClaude Opus 5.5 d402631411 File > Export > Color Lookup Tables: export selected adjustment layers (#1493)
file.export.colorLookupTables takes scope all|selected or an explicit layers list and bakes only those top-level, visible adjustment layers, always in document stacking order; the dialog defaults to the selection when it is all exportable adjustments. Invalid selections and sizes are errors rather than silent fallbacks; LUT sizes outside 2-129 (the reader's limit) are now refused instead of clamped.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 14:36:51 -04:00
optimalbyteeandClaude Opus 5.5 d651be1393 Speed up Mosaic with portable row reads (#1524)
Mosaic sums each four-channel cell by reading whole rows once with channel sums kept in registers, in the original addition order, so the output is bit-identical (including HDR values, -0.0, zero alpha and partial source bounds); 24-38% faster on three of the four measured cell sizes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 14:26:13 -04:00
Harrison O'Connor-HooverandClaude Opus 5.5 9e36825d2d Allow automation to edit embedded Smart Object contents (#1882)
Fixes #1833. Control and MCP may run Edit Contents, Convert to Layers and Save Contents on smart objects whose source is in memory (embedded, or a Photoshop UUID backed by embedded liFD data). Before any disk read the engine re-checks the source's stored path through the session's authorize gate, including nested sources re-rendered while unpacking, so external linked files stay refused; explicit layer targets work with another layer selected, and interactive linked-file access is unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 14:24:58 -04:00
Minseo LeeandClaude Opus 5.5 9f23d65262 Type tool: list fonts' real style names, including numeric subfamilies (#1844)
The style menu now shows each face's actual OpenType subfamily (name 17, else 2) instead of a name guessed from its weight, so fonts whose faces share one weight (Yoon's numeric 20/30/40/50) list and render distinct faces: FontDb::select_named_face registers a runtime-only alias for the exact face, while the document keeps its public family and PostScript name. Variable faces still list the standard weights their wght axis covers.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 14:12:49 -04:00
Harrison O'Connor-HooverandClaude Opus 5.5 cd559b387a Fix browser Save for Web downloads and stale export dimensions (#1857)
Save for Web gets a platform-writer entry point (web_cmds::save_for_web_with_writer) so the browser build downloads every image, spacer and HTML file side by side; the export is authorized before any picker opens, a failed write stops it, and only a complete export remembers its settings. Each document now opens the dialog at its own size instead of the last export's width, height and percent.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 14:03:58 -04:00
Kostis PapadakisandClaude Opus 5.5 c0541baf6a Raw: decode uncompressed Fujifilm RAF, Bayer and X-Trans (#1872)
RAF's header, metadata records and Fuji IFD give size, packing (16-bit, 12-bit LSB-first,
14-bit in 32-bit words), layout, black, WB, crop and exposure bias; X-Trans and other
periodic non-Bayer CFAs go through a new edge-directed demosaic. Compressed and early
SuperCCD RAF stay unsupported (preview fallback). Tests use synthetic files only.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 13:59:07 -04:00
kayrockscreenprintingandClaude Opus 5.5 82148e77f5 Filter previews compute off the UI thread; a stale one is cancelled once the slider settles (#1899)
In the desktop app every filter's live preview now runs on the preview worker (not just Indexed Color), so a slow one like Gaussian Blur at 1000 px no longer freezes the window. The worker hands the filter a JobCtx (Session::set_inline_job_ctx) and cancels a preview for older values once the dialog's values have been unchanged for 150 ms; during a drag the running preview is left to finish.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 13:52:24 -04:00
Gotya-OFFCIALandClaude Opus 5.5 4716d33372 Raw: cRAW black level without a tag; measured image areas (D800E, ILCE-7) (#1902)
Sony cRAW files with no BlackLevel tag take the 512 their tone curve gives the black
code instead of 0 (the ILCE-7 no longer develops washed out; the RX0 corpus oracle moves
to 512 too). cameras.rs gains measured image areas without a full profile: the Nikon
D800E and Sony ILCE-7 crop like the camera's JPEG.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 13:51:43 -04:00
sunyd168andClaude Opus 5.5 0af072e82c SVG import: refuse deeply nested markup instead of overflowing the stack (#1901)
A pre-scan rejects element nesting past 512 levels before the XML parser recurses
(a 70 KB file of <g> aborted the process). .svgz is inflated by the importer with a
128 MB cap, so it can be scanned too and gzip bombs are refused; flate2 moves from a
dev-dependency to a dependency (already in the tree through usvg).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 13:47:17 -04:00
Shayan HorbankandClaude Opus 5.5 a342ab8820 Add centered and transformable painting symmetry axes (#1821)
Photoshop's Vertical, Horizontal, Dual Axis and Diagonal paint symmetry presets beside the
path-based symmetry: axes start at the document centre, Transform Symmetry moves and rotates
them (Shift snaps to 15°, Enter applies, Esc cancels), and all copies merge into one coverage
pass so overlaps don't build opacity. New paint.setSymmetry command and preset icons. Fixes #1648.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 13:44:24 -04:00
Reynold HuandClaude Opus 5.5 3ae44e3911 Document tabs: Reveal in Finder and drag to reorder (#1906)
The document tab's context menu gains Reveal in Finder (a new file.revealInFinder command that reuses the smart-object reveal helper and targets the clicked tab's document), and dragging a tab sideways reorders the open documents through document.move, with a drop line, in both tab strips. Flips UI-217-6 to done.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 13:38:40 -04:00
kayrockscreenprintingandClaude Opus 5.5 0299162db2 MCP: tool schemas without $ref, $defs or boolean schemas (#1845)
Every tool's input schema is rewritten once at startup: $refs inlined (use-site
descriptions win), $defs dropped, boolean schemas turned into {}, with a depth cap
for recursive definitions. ui_pointer events get a concrete schema. Strict providers
no longer reject the whole tool list. Fixes #1782.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 13:29:50 -04:00
kayrockscreenprintingandClaude Opus 5.5 63f9ca9d74 Control: shell dialogs are listed and driven as "shell" (#1811)
ui.inspect lists the open shell dialog (Workspace, Pixel Aspect Ratio, Show Extras,
32-bit Preview) with the id "shell", and ui.dialog.set/confirm/cancel accept it;
confirm goes through the automation authorizer and the dialog's shared OK. Fixes #1004.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 13:27:46 -04:00
David MannandClaude Opus 5.5 147ee7efa0 Crop tool: rotate the crop frame by dragging outside it (#1879)
Outside the crop frame the pointer is Photoshop's curved turn cursor and a drag turns the frame
about its centre (Shift: 15 degree steps) with an angle readout; handles resize along the turned
axes and a double-click inside commits. image.crop takes an optional angle: Image Rotation >
Arbitrary so the frame is upright, then the crop, in one undo step. Fixes #1792.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 13:27:27 -04:00
Nigel Ihza FirdausyandClaude Opus 5.5 0f2900da34 Edit > Stroke: a full options dialog with Fill's blending controls (#1477)
Edit > Stroke… from the menus opens a Photoshop-style dialog (Width, Color, Location, Blending:
Mode, Opacity, Preserve Transparency) remembering its last values; called with params it runs
directly. edit.stroke gains mode and preserveTransparency, blending through Fill's compositing
(blend_color_mask), and validates them. The Blending section is shared with Fill
(dialog_blend_ui.rs). Fixes #1463.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 13:21:21 -04:00
Reynold HuandClaude Opus 5.5 4ed4faee51 Command palette: recently run commands on an empty query (#1824)
menus::invoke records each successfully run command (deduplicated, newest first, last 8) and the palette lists them when its query is empty, falling back to the full list in a fresh session. Flips UI-217-7 to done.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 13:21:17 -04:00
Jason XiangandClaude Opus 5.5 5aaf0e4aae file.new rejects invalid parameters instead of falling back (#1878)
Unknown keys, wrong types, out-of-range sizes or resolution and unsupported
mode/depth/background now fail naming the parameter, before a floating selection is
committed or a document added; omitted fields keep their defaults. The renderer tests
now pass numeric depths (strings had silently fallen back to 8-bit). Part of #507.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 13:20:34 -04:00
Nigel Ihza FirdausyandClaude Opus 5.5 ffb62ec975 Pen: Ctrl/Cmd+Z undoes in-progress points (#1478)
While a Pen path is being drawn, Undo (its customisable shortcut or Edit > Undo) and Backspace/
Delete remove the last uncommitted anchor instead of undoing an earlier document step, as in
Photoshop; once the draft is empty, Undo works on the document again. Fixes #1466.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 13:18:00 -04:00
kayrockscreenprintingandClaude Opus 5.5 fdfa57f456 New Document starts from the last document's settings (#1869)
Fixes #1810. File > New remembers the size, resolution, mode, depth, background and display units its OK used (in the preferences' dialogs map, so they survive a restart) and starts from them next time, as Photoshop does; a clipboard image still sets the size, and corrupt remembered values are ignored.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 13:15:35 -04:00
AntonandClaude Opus 5.5 66b022cddd Web: fonts served next to the app, loaded on demand (#1875)
A host lists fonts in fonts/manifest.txt beside index.html (craft-fonts' manifest format, paths
kept inside the site); the web shell lists those families in the font menus and fetches a family
when it is picked or a layout needs it, then re-renders the affected type layers without a history
step. No manifest changes nothing; package.sh copies one in with PHOTOCRAFT_WEB_FONTS_DIR. The
style menu also lists the weights of a variable font's wght axis.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 13:14:47 -04:00
kayrockscreenprintingandClaude Opus 5.5 54ff207004 Image › Adjustments: apply per tile in parallel (#1800)
adjust_surface now takes the layer's tiles and adjusts each one on its own rayon task, so a large layer needs one tile's buffers per thread instead of four full-layer copies. The result is bit-identical to the single pass for every adjustment kind, colour model and depth, with and without a soft selection (tiled_adjustment_matches_one_pass_over_the_content). Adds an invert scenario to large_image_bench.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 13:06:46 -04:00
JeremyandClaude Opus 5.5 7a5b0b5d45 Canvas: the CPU canvas pixel grid skips empty pixels, like the GPU canvas (#1891)
The CPU path drew the pixel grid over the whole view, including transparent areas, while the
GPU shader only lightens or darkens pixels with content. pixel_grid.rs applies the shader's
rule to the composite of the area in view, as merged segments cached per revision and padded
region (capped at 60k segments), sharing the zoom and strength constants with the shader.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 13:04:27 -04:00
David MannandClaude Opus 5.5 45c5001dfd GPU canvas: convert changed layer tiles once each, in parallel (#1847)
Changed tiles are grouped by shared Arc and converted once each in parallel batches; a tile
shared by several coordinates (a solid fill, a cleared area, a non-zero default) is uploaded
once to a scratch tile and copied on the GPU, and new pages take the same path. 16-bit RGB and
gray tiles convert to RGBA16F through a lookup table. Select All + Fill on a 50 MP 16-bit page
refreshes in 15-19 ms instead of about 1.4 s. Fixes #1774.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 13:04:21 -04:00