31 Commits
Author SHA1 Message Date
ef8610adeb Fix radial blur sampling density (#515) (#658)
* Fix radial blur sampling density (#515)

Co-authored-by: Copilot <[email protected]>

Copilot-Session: e77cd34a-ce3e-4981-996f-4d37d49df90d

* Bound radial blur quality and parallelize sampling

Add Draft, Good, and Best radial sampling tiers, defaulting to Good, and process sampled blur rows in parallel. Preserve compatibility with serialized filters that omit quality.

Co-authored-by: Copilot <[email protected]>

Copilot-Session: e85c024b-ace5-4415-9208-b8d4e4684505

* i18n(ko): Radial Blur quality choices Good and Best

Co-Authored-By: Claude Opus 5.5 <[email protected]>

---------

Co-authored-by: Brandon Thomas <[email protected]>
Co-authored-by: Claude Opus 5.5 <[email protected]>
Copilot-Session: e77cd34a-ce3e-4981-996f-4d37d49df90d
Copilot-Session: e85c024b-ace5-4415-9208-b8d4e4684505
2026-10-08 18:28:01 -04:00
9ef9992878 fix(automation): close ambient filesystem authorization gaps (#763)
* fix(automation): block ambient filesystem bypasses

Co-authored-by: Copilot <[email protected]>

Copilot-Session: e77cd34a-ce3e-4981-996f-4d37d49df90d

* test(automation): cover ambient path denial

Co-authored-by: Copilot <[email protected]>

Copilot-Session: e77cd34a-ce3e-4981-996f-4d37d49df90d

* fix(automation): guard filesystem path authorization

Co-authored-by: Copilot <[email protected]>

Copilot-Session: e85c024b-ace5-4415-9208-b8d4e4684505

* automation: judge the first non-empty prefs segment; refuse any path without data

prefs.set skips empty path segments, so `.scriptEvents.enabled` reached
script events past the section check. Preset import / plugin.install
with a whitespace path also read the filesystem.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

---------

Co-authored-by: Brandon Thomas <[email protected]>
Co-authored-by: Claude Opus 5.5 <[email protected]>
Copilot-Session: e77cd34a-ce3e-4981-996f-4d37d49df90d
Copilot-Session: e85c024b-ace5-4415-9208-b8d4e4684505
2026-10-07 17:14:03 -04:00
Alex GorevskiandCopilot 1b24b5212b Repair corrupt directory-save objects (#752)
* Fix directory save reuse of corrupt objects

Co-authored-by: Copilot <[email protected]>

Copilot-Session: e77cd34a-ce3e-4981-996f-4d37d49df90d

* Avoid revalidating unchanged directory-save objects

Co-authored-by: Copilot <[email protected]>

Copilot-Session: e85c024b-ace5-4415-9208-b8d4e4684505

---------

Copilot-Session: e77cd34a-ce3e-4981-996f-4d37d49df90d
Copilot-Session: e85c024b-ace5-4415-9208-b8d4e4684505
2026-10-07 17:13:09 -04:00
Alex GorevskiandCopilot e9142754a4 Fix text ink bounds overflow (#750)
* Fix text ink bounds overflow

Co-authored-by: Copilot <[email protected]>

Copilot-Session: e77cd34a-ce3e-4981-996f-4d37d49df90d

* Validate type size and tracking parameters

Reject out-of-range text metrics at type command boundaries to avoid silently empty renders.

Co-authored-by: Copilot <[email protected]>

Copilot-Session: e85c024b-ace5-4415-9208-b8d4e4684505

---------

Copilot-Session: e77cd34a-ce3e-4981-996f-4d37d49df90d
Copilot-Session: e85c024b-ace5-4415-9208-b8d4e4684505
2026-10-07 17:12:55 -04:00
Alex GorevskiandCopilot 51a0816f99 Bound paint stroke work (#678, #679) (#751)
* Bound paint stroke work

Cap airbrush catch-up for long timestamp gaps and enforce safe brush dimensions before rendering, with a lower-level renderer guard and regression coverage.

Fixes #678

Fixes #679

Co-authored-by: Copilot <[email protected]>

Copilot-Session: e77cd34a-ce3e-4981-996f-4d37d49df90d

* fix: align paint brush limits and airbrush catch-up

Co-authored-by: Copilot <[email protected]>

Copilot-Session: e85c024b-ace5-4415-9208-b8d4e4684505

---------

Copilot-Session: e77cd34a-ce3e-4981-996f-4d37d49df90d
Copilot-Session: e85c024b-ace5-4415-9208-b8d4e4684505
2026-10-07 17:12:49 -04:00
Alex GorevskiandCopilot 165e11ad6a Fix hostile PSD pattern geometry (#743)
* Fix hostile PSD pattern geometry

Use checked rectangle extents and reject channel rectangles that differ from their parent tile, preventing panic-prone subtraction and huge zero-filled plane allocations. Bound aggregate decoded pattern data and PackBits expansion using parser limits and payload size. Add regression coverage for .pat, PSD global pattern blocks, and .abr embedded patterns.

Fixes #682
Fixes #683

Co-authored-by: Copilot <[email protected]>
Copilot-Session: e77cd34a-ce3e-4981-996f-4d37d49df90d

* Preserve bounded PSD pattern channel placement

Co-authored-by: Copilot <[email protected]>

Copilot-Session: e85c024b-ace5-4415-9208-b8d4e4684505

---------

Co-authored-by: Copilot <[email protected]>
Copilot-Session: e77cd34a-ce3e-4981-996f-4d37d49df90d
Copilot-Session: e85c024b-ace5-4415-9208-b8d4e4684505
2026-10-07 17:12:44 -04:00
Alex GorevskiandCopilot 8302f57190 Fix vector pixel bounds overflow (#747)
* Fix vector pixel bounds overflow

Saturate exclusive pixel bounds at i32::MAX and cover extreme and ordinary paths with regression tests.

Co-authored-by: Copilot <[email protected]>

Copilot-Session: e77cd34a-ce3e-4981-996f-4d37d49df90d

* Cover extreme vector path fill commands

Co-authored-by: Copilot <[email protected]>

Copilot-Session: e85c024b-ace5-4415-9208-b8d4e4684505

---------

Copilot-Session: e77cd34a-ce3e-4981-996f-4d37d49df90d
Copilot-Session: e85c024b-ace5-4415-9208-b8d4e4684505
2026-10-07 17:10:21 -04:00
Alex GorevskiandCopilot d9a0f38280 fix(raw): validate DNG default crop bounds (#745)
* fix(raw): validate DNG default crop bounds

Fixes #692

Co-authored-by: Copilot <[email protected]>

Copilot-Session: e77cd34a-ce3e-4981-996f-4d37d49df90d

* fix(raw): fall back for invalid DNG default crops

---------

Copilot-Session: e77cd34a-ce3e-4981-996f-4d37d49df90d
2026-10-07 17:10:03 -04:00
a1f4387e63 fix(codecs): correct TIFF polarity and BigTIFF orientation (#746)
Use the TIFF decoder's normalized WhiteIsZero samples without a second inversion, and parse BigTIFF IFD0 Orientation so decode applies the recorded rotation.

Fixes #691

Fixes #693

Co-authored-by: Copilot <[email protected]>

Co-authored-by: Tanish Manku <[email protected]>
Copilot-Session: e77cd34a-ce3e-4981-996f-4d37d49df90d
2026-10-07 13:50:04 -07:00
702b4aa6b0 Fix ui.set brush size command journaling (#744)
Co-authored-by: Copilot <[email protected]>

Co-authored-by: Tanish Manku <[email protected]>
Copilot-Session: e77cd34a-ce3e-4981-996f-4d37d49df90d
2026-10-07 13:49:59 -07:00
151afe47b6 fix(automation): downscale bridge screenshots before PNG budget (#753)
Co-authored-by: Copilot <[email protected]>
Co-authored-by: Tanish Manku <[email protected]>
Copilot-Session: e77cd34a-ce3e-4981-996f-4d37d49df90d
2026-10-07 13:49:50 -07:00
3ad26e3b51 Fix document run and ID overflow (#684, #685) (#749)
Co-authored-by: Copilot <[email protected]>

Co-authored-by: Tanish Manku <[email protected]>
Copilot-Session: e77cd34a-ce3e-4981-996f-4d37d49df90d
2026-10-07 13:49:46 -07:00
35ceaefce2 Fix #695: validate Layer Style effect fields (#729)
* Fix #695: validate Layer Style effect fields

Reject non-object effect parameter fields before preview or confirmation, render a visible validation message, and keep the canvas on the original document when preview input is invalid.

Co-authored-by: Copilot <[email protected]>

Copilot-Session: e77cd34a-ce3e-4981-996f-4d37d49df90d

* fix(ui): keep global light preview fields compatible

Co-authored-by: Copilot <[email protected]>

Copilot-Session: e77cd34a-ce3e-4981-996f-4d37d49df90d

* Layer Style: show an invalid-parameters error once

Co-Authored-By: Claude Opus 5.5 <[email protected]>

---------

Co-authored-by: Brandon Thomas <[email protected]>
Co-authored-by: Claude Opus 5.5 <[email protected]>
Copilot-Session: e77cd34a-ce3e-4981-996f-4d37d49df90d
2026-10-07 16:33:11 -04:00
Alex GorevskiandCopilot 7a45adc913 Fix Hue/Saturation range drag bounds (#727)
Canonicalize imported bounds before rendering or moving range handles. Keep drag constraints ordered and cover both non-canonical and ordinary ranges.

Fixes #696

Co-authored-by: Copilot <[email protected]>

Copilot-Session: e77cd34a-ce3e-4981-996f-4d37d49df90d
2026-10-07 16:32:22 -04:00
12460d0345 Fix multi-file open dialog (#595) (#657)
* Fix multi-file open dialog (#595)

Co-authored-by: Copilot <[email protected]>

Copilot-Session: e77cd34a-ce3e-4981-996f-4d37d49df90d

* Multi-file open test: write its fixtures under the temp dir

Co-Authored-By: Claude Opus 5.5 <[email protected]>

---------

Co-authored-by: Brandon Thomas <[email protected]>
Co-authored-by: Claude Opus 5.5 <[email protected]>
Copilot-Session: e77cd34a-ce3e-4981-996f-4d37d49df90d
2026-10-07 16:31:57 -04:00
Alex GorevskiandCopilot 2050ca083e Fix #570: connect brush strokes on Shift-click (#654)
Co-authored-by: Copilot <[email protected]>

Copilot-Session: e77cd34a-ce3e-4981-996f-4d37d49df90d
2026-10-07 16:31:15 -04:00
Alex GorevskiandCopilot 681dee8c8f Fix type edit undo grouping (#652)
Co-authored-by: Copilot <[email protected]>

Copilot-Session: e77cd34a-ce3e-4981-996f-4d37d49df90d
2026-10-07 16:21:49 -04:00
Alex GorevskiandCopilot 0c40ec17c6 fix(color): match Photoshop blend corner values (#699)
Co-authored-by: Copilot <[email protected]>

Copilot-Session: e77cd34a-ce3e-4981-996f-4d37d49df90d
2026-10-07 16:00:27 -04:00
Alex GorevskiandCopilot e70deecbe5 fix(cms): check LUT declared sizes before arithmetic (#725)
Fixes #689

Co-authored-by: Copilot <[email protected]>

Copilot-Session: e77cd34a-ce3e-4981-996f-4d37d49df90d
2026-10-07 15:41:09 -04:00
90df9cfc15 Report per-language UI translation coverage (#220) (#427)
* feat(xtask): report UI translation coverage

Add a deterministic per-language coverage report backed by a checked English key inventory. Reject malformed, duplicate, and unknown catalog keys, and document the invocation.

Co-authored-by: Copilot <[email protected]>

Copilot-Session: f77709e9-6475-4953-ab57-b78347b4499d

* fix(xtask): derive i18n coverage keys from source

Co-authored-by: Copilot <[email protected]>

Copilot-Session: e5e4c3e6-e406-4010-b05d-5042f9f4e4fc

* fix(xtask): handle Windows line endings in i18n scan

Co-authored-by: Copilot <[email protected]>
Copilot-Session: e5e4c3e6-e406-4010-b05d-5042f9f4e4fc

* Scorecard: DIST-220-4 is partial now that xtask reports translation coverage

Co-Authored-By: Claude Opus 5.5 <[email protected]>

---------

Co-authored-by: Copilot <[email protected]>
Co-authored-by: Brandon Thomas <[email protected]>
Co-authored-by: Claude Opus 5.5 <[email protected]>
Copilot-Session: f77709e9-6475-4953-ab57-b78347b4499d
Copilot-Session: e5e4c3e6-e406-4010-b05d-5042f9f4e4fc
2026-10-07 07:54:05 -04:00
Alex GorevskiandCopilot bf545e0e81 Hide unconfigured layer effects from panel (#559)
Co-authored-by: Copilot <[email protected]>

Copilot-Session: 8fbf5558-5421-4e91-8c33-89a347bb27da
2026-10-07 07:14:04 -04:00
047aeb747a Wayland: explain native file drag-and-drop limitation (#386) (#430)
* Wayland: add persistent file drop guidance (#386)

Co-authored-by: Copilot <[email protected]>
Copilot-Session: f77709e9-6475-4953-ab57-b78347b4499d

* Fix Wayland file-drop guidance review

Co-authored-by: Copilot <[email protected]>

Copilot-Session: e5e4c3e6-e406-4010-b05d-5042f9f4e4fc

* fix(app): pass no dismissal preference for portable notice

Co-authored-by: Copilot <[email protected]>
Copilot-Session: e5e4c3e6-e406-4010-b05d-5042f9f4e4fc

* Pass no dismissal preference for the prefs save-failure notice

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* notices::post takes the dismiss preference: pass None for the GPU retry notice (#434)

Co-Authored-By: Claude Opus 5.5 <[email protected]>

---------

Co-authored-by: Copilot <[email protected]>
Co-authored-by: Brandon Thomas <[email protected]>
Co-authored-by: Claude Opus 5.5 <[email protected]>
Copilot-Session: f77709e9-6475-4953-ab57-b78347b4499d
Copilot-Session: e5e4c3e6-e406-4010-b05d-5042f9f4e4fc
2026-10-07 07:12:25 -04:00
50d52a0848 Clarify integer and float bit-depth labels (#324) (#428)
* Clarify integer and float bit-depth labels

Add type-specific labels to New Document and Image Mode with translations and focused UI/catalog tests.

Co-authored-by: Copilot <[email protected]>

Copilot-Session: f77709e9-6475-4953-ab57-b78347b4499d

* Fix bit-depth labels and tooltips

Co-authored-by: Copilot <[email protected]>

Copilot-Session: e5e4c3e6-e406-4010-b05d-5042f9f4e4fc

* Keep the reference menu names for the depth commands and preference

The Image > Mode items keep their menu-catalogue labels, so the engine
labels (command palette, MCP, Keyboard Shortcuts) and the preference
choice stay "8/16/32 Bits/Channel" to match; the integer / floating point
hint comes from the new tooltips.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

---------

Co-authored-by: Brandon Thomas <[email protected]>
Co-authored-by: Claude Opus 5.5 <[email protected]>
Copilot-Session: f77709e9-6475-4953-ab57-b78347b4499d
Copilot-Session: e5e4c3e6-e406-4010-b05d-5042f9f4e4fc
2026-10-07 07:09:51 -04:00
Alex GorevskiandCopilot 2c02d41eaf Show active ICC profile in the status bar (#321) (#432)
* Show active ICC profile in status bar (#321)

Co-authored-by: Copilot <[email protected]>

Copilot-Session: f77709e9-6475-4953-ab57-b78347b4499d

* Fix active profile status review feedback

Co-authored-by: Copilot <[email protected]>
Copilot-Session: e5e4c3e6-e406-4010-b05d-5042f9f4e4fc

---------

Co-authored-by: Copilot <[email protected]>
Copilot-Session: f77709e9-6475-4953-ab57-b78347b4499d
Copilot-Session: e5e4c3e6-e406-4010-b05d-5042f9f4e4fc
2026-10-07 07:08:51 -04:00
d07eecf66f PSD: read/write the artboard lock at Photoshop's lspf bit 3 (#395) (#406)
* PSD: read/write the artboard lock at Photoshop's lspf bit 3 (#395)

Photoshop writes layer locks with the artboard bit at 0x08 (a Background
layer carries 0x0D). PhotoCraft read it at 0x10, so 0x0D came back as
0x05 and the lock bytes drifted on every re-save. Map artboard to bit 3
on both read and write; still accept 0x10 on read so older PhotoCraft
files keep their lock, rewriting it at 0x08.

Co-Authored-By: Qwen 3.8 Flash <[email protected]>

* style(io): fix PSD artboard lock review comments

Co-authored-by: Copilot <[email protected]>

Copilot-Session: e5e4c3e6-e406-4010-b05d-5042f9f4e4fc

---------

Co-authored-by: Qwen 3.8 Flash <[email protected]>
Copilot-Session: e5e4c3e6-e406-4010-b05d-5042f9f4e4fc
2026-10-07 07:08:00 -04:00
d91ab25772 Expose the Mixer Brush as a UI tool (#213) (#433)
* feat(ui): expose Mixer Brush tool (#213)

Wire the existing Mixer Brush command into the selectable UI tool model, options bar, and control-driven painting path. Cover shortcut cycling, options persistence, and selection clipping.

Co-authored-by: Copilot <[email protected]>

Copilot-Session: f77709e9-6475-4953-ab57-b78347b4499d

* docs(scorecard): mark Mixer Brush slice complete (#213)

Reflect the new Mixer Brush toolbar, options, control dispatch, and selection tests in TOOL-213-2 and regenerate the scorecard.

Co-authored-by: Copilot <[email protected]>

Copilot-Session: f77709e9-6475-4953-ab57-b78347b4499d

* fix(i18n): translate Mixer Brush labels in zh-Hans

Add Simplified Chinese entries for the Mixer Brush tool, its options, and the brush-settings heading. Test all Mixer Brush UI strings against every registered language catalog.

Co-authored-by: Copilot <[email protected]>

Copilot-Session: f77709e9-6475-4953-ab57-b78347b4499d

* Polish Mixer Brush UI controls

Co-authored-by: Copilot <[email protected]>

Copilot-Session: e5e4c3e6-e406-4010-b05d-5042f9f4e4fc

* Regenerate docs/scorecard.md

Co-Authored-By: Claude Opus 5.5 <[email protected]>

---------

Co-authored-by: Brandon Thomas <[email protected]>
Co-authored-by: Claude Opus 5.5 <[email protected]>
Copilot-Session: f77709e9-6475-4953-ab57-b78347b4499d
Copilot-Session: e5e4c3e6-e406-4010-b05d-5042f9f4e4fc
2026-10-07 07:04:31 -04:00
48bd08150e feat(ui): add bounded Liquify redo history (#435)
* feat(ui): add bounded Liquify redo history

Co-authored-by: Copilot <[email protected]>

Copilot-Session: f77709e9-6475-4953-ab57-b78347b4499d

* Regenerate docs/scorecard.md

Co-Authored-By: Claude Opus 5.5 <[email protected]>

---------

Co-authored-by: Brandon Thomas <[email protected]>
Co-authored-by: Claude Opus 5.5 <[email protected]>
Copilot-Session: f77709e9-6475-4953-ab57-b78347b4499d
2026-10-07 06:59:03 -04:00
6237f6e46e Layer Style: the shadow/bevel Angle slider now moves the light (#350) (#411)
* Layer Style: the shadow/bevel Angle slider now moves the light (#350)

The Drop Shadow, Inner Shadow and Bevel & Emboss dialogs exposed an Angle
slider but no "Use Global Light" checkbox. The engine defaults
use_global_light to true, so the compositor used the document's fixed
global light angle and ignored the per-effect angle — dragging Angle did
nothing.

Add Photoshop's "Use Global Light" checkbox to those three effects,
round-trip useGlobalLight through the dialog fields, show the effective
(global light) angle when it is on, and — when it is on — drive the
document's shared light angle from the slider so the shadow follows it,
exactly as in Photoshop.

Co-Authored-By: Claude Haiku 4.5 <[email protected]>

* fix(ui): preserve edited layer-style global light

Apply a layer-style global-light angle only when it differs from the dialog's initial angle, so later unchanged effects cannot override a Bevel & Emboss edit. Use the current light angle for new global-light effects and add translations for Use Global Light.

Co-authored-by: Copilot <[email protected]>

Copilot-Session: e5e4c3e6-e406-4010-b05d-5042f9f4e4fc

---------

Co-authored-by: Claude Haiku 4.5 <[email protected]>
Copilot-Session: e5e4c3e6-e406-4010-b05d-5042f9f4e4fc
2026-10-07 06:12:23 -04:00
Alex GorevskiandCopilot a312c3d0c7 PSD export: select PSB from size estimate (#431)
Estimate encoded raster and retained-data size with checked arithmetic, and select PSB when the PSD limit is exceeded. Keep forced PSB choices and document the completed scorecard slice.

Co-authored-by: Copilot <[email protected]>

Copilot-Session: f77709e9-6475-4953-ab57-b78347b4499d
2026-10-07 11:41:08 +07:00
Alex GorevskiandCopilot 7b3d131bc8 docs: correct VectorCraft sibling name (#429)
Replace the stale DrawCraft name in the contributor sibling list.

Co-authored-by: Copilot <[email protected]>

Copilot-Session: f77709e9-6475-4953-ab57-b78347b4499d
2026-10-07 10:43:46 +07:00
Alex GorevskiandCopilot 1cb5af9218 Build desktop app by default (#425)
Include apps/photocraft in workspace default-members so a plain cargo build also builds the native UI.

Co-authored-by: Copilot <[email protected]>
Copilot-Session: f77709e9-6475-4953-ab57-b78347b4499d
2026-10-07 10:34:59 +07:00