arboard 3.6 asks the clipboard for image/png only, so a screenshot tool or
clipboard manager that offers just image/jpeg, image/bmp or image/webp pasted
nothing ("the clipboard holds no image"). When arboard finds no image, read
the other image/* types through wl-clipboard-rs (already in Cargo.lock via
arboard's wayland-data-control) and decode them with photocraft-codecs.
Reads are capped at 1 GiB; TGA is trusted only when its type says so.
Claude-Session: https://claude.ai/code/session_01AbyXia7KGdFgbNjBeggY8J
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* perf(camera-raw): convert the refined preview in parallel bands, not per row (#4682)
#3427 colour-managed the refined (zoomed-in) Camera Raw preview by calling
the display transform once per row. A row is below photocraft-cms's 16K-pixel
parallel threshold, so every edit ran the whole conversion on one core of
the UI thread, plus two allocations per row. Read and convert 64K-pixel bands
instead, in parallel off wasm (as channel_view does); output is identical.
2560x1600 visible crop, median of 15 runs (22-thread laptop, dev profile):
- sRGB document: 31.5 ms -> 3.9 ms
- Adobe RGB document: 125.0 ms -> 12.5 ms
- ProPhoto document: 117.5 ms -> 12.7 ms
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AbyXia7KGdFgbNjBeggY8J
* perf(camera-raw): the main preview converts in parallel bands too, without a full copy
CameraRawDialog::image copied the whole proxy into a Buffer and colour-converted
it on one thread on every edit. It now goes through the same banded, parallel
display_image as the refined preview, reading bands straight from the slice.
Median of 21 runs (22-thread laptop, dev profile):
- 858x572 sRGB: 4.72 ms -> 1.00 ms
- 858x572 Adobe RGB: 7.39 ms -> 2.06 ms
- 1716x1144 sRGB: 18.58 ms -> 2.48 ms
- 1716x1144 Adobe RGB: 28.78 ms -> 6.88 ms
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AbyXia7KGdFgbNjBeggY8J
---------
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Brandon Thomas <echelon@gmail.com>
When drawing faux-bold glyphs, the offset dilation was composed as
`Xform(ox * r, oy * r).mul(&glyph)`. Because `Xform::mul(o)` applies `o`
first (`self ∘ o`), the translation offset was added after the glyph's
scaling transform, leaving faux bold dilation unscaled by horizontal
and vertical font scaling.
Applying the glyph transform to the offset transform (`glyph.mul(&offset)`)
ensures dilation is performed in font-local coordinates and scaled
proportionally with anisotropic glyph scaling, matching Photoshop.