Commit Graph
5557 Commits
Author SHA1 Message Date
David Mann 159728aaa0 Merge PR #8118: GPU compositor: build its pipelines in parallel; DX12 startup 13.2 s -> 7.3 s (part of #6419) 2026-10-22 23:40:19 +02:00
David Mann a79d8cb9f6 Merge PR #5937: fix(compose): prevent outside stroke from bleeding into opaque character interior (#5861) 2026-10-22 23:40:19 +02:00
David Mann 7c9d6ac344 Merge PR #8150: fix(automation): doc.replaceSmartObject replaces Smart Object contents from the read root (#8061) 2026-10-22 23:40:19 +02:00
David Mann 18124238f7 Merge PR #8502: fix(actions): accept Photoshop stringID blend modes (#8454) 2026-10-22 23:40:19 +02:00
David Mann 8d23a06eae Merge PR #6094: Fix legacy PSD point-text placement after font resolution 2026-10-22 23:40:19 +02:00
David Mann 09eef59e90 Integration: #5878 second fix-up (two instances keep each other's Shift tool switch choice) 2026-10-22 23:40:18 +02:00
David Mann c436f61d53 Merge PR #7202: fix(atn): import a recorded Save As with its destination (#7102) 2026-10-22 23:40:18 +02:00
David Mann ee85da2ffd Merge PR #8527: fix(atn): export Black & White adjustment layers with Photoshop's BanW class (#8481) 2026-10-22 23:40:17 +02:00
David Mann 9ee6c407b6 Merge PR #8254: Image Assets: optionally keep a transparent artboard's full size 2026-10-22 23:40:16 +02:00
David Mann a23c29b53a Merge PR #5878: Preferences: old settings files take Shift-to-switch-tools on (#5647) 2026-10-22 23:40:16 +02:00
David Mann 79ab013961 Merge PR #8496: fix(ui-egui): expand layer visibility eye hitbox and render sunken well (#8467) 2026-10-22 23:40:16 +02:00
David Mann b1e4c9b1f9 Merge PR #6041: Raw: charge the retained tile intermediates together (#4959) 2026-10-22 23:40:15 +02:00
David Mann 24051914fd Merge PR #6352: fix(engine): honor lock all on layer mask commands 2026-10-22 23:40:15 +02:00
David Mann 3fdcabded4 Merge PR #5248: Keep adjustment clipping visible in compact Properties panels 2026-10-22 23:40:15 +02:00
David Mann 49a98690ad Merge PR #8354: Keep the CPU canvas sharp at 100% zoom 2026-10-22 23:40:14 +02:00
David Mann 5301a128b8 Merge PR #8509: fix(atn): preserve unsupported event kinds 2026-10-22 23:40:13 +02:00
David Mann 14d68f972b Merge PR #8035: CLI: reject ignored or conflicting mcp/serve launch options 2026-10-22 23:40:13 +02:00
David Mann 7f68d4e06a Merge PR #5370: fix(gpu): catch validation errors in watched compositor work 2026-10-22 23:40:13 +02:00
David Mann 83b1850539 Merge PR #7455: photocraft-cli run: refuse an --out that is the input file unless --in-place (#7437) 2026-10-22 23:40:13 +02:00
David Mann 7be48940b3 Merge PR #8518: fix(engine): select files correctly in Windows Explorer 2026-10-22 23:40:13 +02:00
David Mann 0fcdd660cb Merge PR #7849: Menu bar: a held Alt's auto-repeat doesn't re-arm the Alt tap 2026-10-22 23:40:12 +02:00
David Mann 837242536b Merge PR #7840: gpu, docs: fix timing test skip guard and document Windows ARM64 build on RTX Spark 2026-10-22 23:40:12 +02:00
David Mann 6e4d89d13d Merge PR #8473: test(panic_hunt): give the panic-counting self-test its own deadline 2026-10-22 23:40:12 +02:00
David MannandClaude Opus 5.5 106776f598 Integration: fix the batch's merge seams (#5815, #6658)
- io tests/it/psd_structure.rs: main's Duotone test compares the raw
  block as a slice now that #5815 shares it as Arc<[u8]>.
- ru and fr catalogs: main and #6658 both added "Continue" with the same
  translation; the second copy goes (bundled_catalogs_are_consistent).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-22 23:40:12 +02:00
David MannandClaude Opus 5.5 494cdb236a Integration: batch tests join the io test binary, regenerate the scorecard
Main's #8644 builds each crate's integration tests as one binary; #3356's
cmyk_export.rs and #5769's cylinder_warp.rs move into crates/io/tests/it.
docs/scorecard.md regenerated for the batch (#5485 DIST-220-1, #6055
UI-217-17, preferences).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-22 23:40:12 +02:00
8a2d35fcd2 Integration: an unchanged dialog keeps a baked overlay's exact ends (#7335)
After merging main, the Layer Style dialog always sends From/To as 8-bit
hex (#7072). On a baked Gradient Overlay without a source record (PSD or
.asl import) the custom and no-record paths wrote those hex ends back,
so OK without a change rounded the curve's ends (a Smooth bake's white
end 0.99999994 became 1.0, Lab ends became RGB). Like edit_endpoint for
the recorded source, a hex end that only repeats the current end is now
left out. baked_overlay_is_unchanged_until_method_selection_then_edits_
the_whole_curve fails without this.

Co-authored-by: oRE-o <42003350+oRE-o@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-22 23:40:12 +02:00
f895f844e7 Integration: a hidden Work Path is no area type target (#6230)
After merging main, the Type tool's path target fell back to the Work
Path over its whole inside, while main's #6551 only draws an unselected
Work Path for path tools. Ctrl-click Load as Selection (or deselecting
the Work Path) and a Type tool click inside it started area type in a
path nobody could see. Now the Work Path's inside counts only while it
is selected in Paths (drawn), its outline still takes type on a path
with main's 6 px band, and a missed shape path falls back to the Work
Path as on main. an_unselected_work_path_is_not_an_area_target fails
without this.

Co-authored-by: SillySilk <31193727+SillySilk@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-22 23:40:12 +02:00
David Mann a7b833caf6 Integration: stack #8529 (its merge onto main, conflicts resolved) 2026-10-22 23:40:11 +02:00
David Mann fff01d8918 Integration: stack #7335 (its merge onto main, conflicts resolved) 2026-10-22 23:40:11 +02:00
David Mann 6cb8673e8f Integration: stack #6658 (its merge onto main, conflicts resolved) 2026-10-22 23:40:11 +02:00
David Mann 9e7b35b716 Integration: stack #6055 (its merge onto main, conflicts resolved) 2026-10-22 23:40:11 +02:00
David Mann c6e628afad Integration: stack #5815 (its merge onto main, conflicts resolved) 2026-10-22 23:40:10 +02:00
David Mann 8748dcbf16 Integration: stack #5598 (its merge onto main, conflicts resolved) 2026-10-22 23:40:09 +02:00
David Mann ddf1bba02f Integration: stack #5485 (its merge onto main, conflicts resolved) 2026-10-22 23:40:09 +02:00
David Mann 7546c9d60d Integration: stack #4221 (its merge onto main, conflicts resolved) 2026-10-22 23:40:09 +02:00
David MannandClaude Opus 5.5 e0fed98f23 Merge PR #8529: perf(bench): run bench_filters2 from cargo xtask perf, four heavy filters now tracked (P64-P67)
docs/scorecard.md: conflict in generated file, kept ours (b7-base); regenerated later.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-22 23:39:17 +02:00
David MannandClaude Opus 5.5 6c7e920d5a Merge PR #7335: Gradient Overlay: add Method selector and retain editable source stops
- crates/ui-egui/src/layer_style.rs: values_of keeps the PR's method/smoothness keys and source-stop ends, and main's (#7072) unconditional From/To and geometry fields.
- crates/compose/src/cmyk_tests.rs (no textual conflict): add the PR's new `interpolation: None` field to main's CMYK test GradientOverlay literal.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-22 23:39:14 +02:00
David MannandClaude Opus 5.5 6aa27edb06 Merge PR #6658: fix(ui): confirm opening damaged PSD/PSB documents
crates/io/src/lib.rs: kept main's ImportOptions; import_for_open/_with and import_stages now take &ImportOptions (plus the PR's damaged flag); import_with_options_and_interrupt delegates to import_for_open_with.
crates/engine/src/jobs.rs: open job decodes via import_for_open_with(&opts) so the damage flag reaches the held-open path; main's raw_defaults and docId kept.
crates/ui-egui/src/lib.rs: open_bytes_from uses main's import_options + raw_defaults and the PR's PSD damage check via import_for_open(&opts).
Also: moved crates/io/tests/psd_recovery_generated.rs to tests/it/ (mod added, support path fixed) and adapted PR tests to ImportOptions.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-22 23:39:09 +02:00
David MannandClaude Opus 5.5 945a10dc7c Merge PR #6055: Color panel: Photoshop's panel-menu modes, the same in every theme (#6000)
Conflicts:
- crates/ui-egui/src/i18n/{cs,de,el,es,fr,hu,id,it,ja,ko,nl,pl,pt-br,ru,sr,tr,uk,vi,zh-hans,zh-hant}.tsv: kept every key of both sides (main's block, then the PR's Color panel block); no duplicate keys.
- crates/ui-egui/src/panels.rs: took the PR's removal of color_picker/hsb_sliders/rgb_sliders (moved to color_panel_ui.rs); kept main's color_field_height doc comment; main's #5842 slider recolour tests ported to color_panel_tests.rs for the new HSB/RGB slider modes; main's black-HSB test dropped as the PR's hsb_sliders_take_values_on_black covers it.
- crates/ui-egui/src/color_panel_ui.rs (no textual conflict, adapted): set_color now goes through apply_color::foreground_changed with the gesture (was type_tool::foreground_changed), so every mode (sliders, ramp, alerts, wheel) recolours selected type/shapes tool-gated in one undo step per gesture; panel() calls apply_color::track_focus.
- crates/ui-egui/src/color_panel_tests.rs (adapted): new every_slider_mode_recolours_the_selected_shape test.
- docs/gaps.md, docs/ui-parity.md: union of both sides' status lines, rows and revision history; the PR's done row replaces the old "missing" Color panel row.
- docs/scorecard.md: generated, took b7-base's version.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-22 23:39:04 +02:00
David MannandClaude Opus 5.5 cab3ef6191 Merge PR #5815: perf(doc): share the XMP packet, Duotone PSD data and unsupported adjustment bytes between snapshots
- crates/engine/src/tests.rs: kept both tests (main's restore_layer_selection test and the PR's history_states_share_large_document_payloads).
- crates/io/src/psd_import.rs: kept main's parsed Duotone inks (duotone_map) with the PR's Arc<[u8]> psd_raw; also main's unknown-adjustment-key import (#6575) now builds Arc<[u8]> raw.
- crates/io/tests/adjust_warnings.rs: moved to tests/it/adjust_warnings.rs on main; PR's .into() edits applied there, plus #6322's Color Lookup test (raw.as_slice().into()).
- docs/architecture.md: union; status line names both changes, both revision-history rows kept.
- Adapted main-new sites to the PR's types: psd_export.rs (Duotone write-back via as_deref/to_vec, Unsupported block compare by slice), inspect.rs and ui-egui unsupported_marker_tests.rs (raw .into()), io tests/it/psd_unknown_adjustment.rs (slice compare).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-22 23:38:56 +02:00
David MannandClaude Opus 5.5 ced9aa6947 Merge PR #5598: Plug-ins: wire Enable Generator (Image Assets needs it)
docs/scorecard.md: conflict in generated file, kept ours (b7-base); regenerated later.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-22 23:38:50 +02:00
David MannandClaude Opus 5.5 f56147655d Merge PR #5485: Add opt-out startup release checks and manual update status
Conflicts resolved:
- crates/ui-egui/src/i18n/hu.tsv: kept base's Bevel & Emboss keys, then the PR's update-check keys
- crates/ui-egui/src/i18n/ru.tsv: kept base's Bevel & Emboss keys, then the PR's update-check keys
- crates/ui-egui/src/i18n/sr.tsv: kept base's added sections, then the PR's update-check keys
- crates/ui-egui/src/i18n/tr.tsv: kept base's Bevel & Emboss keys, then the PR's update-check keys
- crates/ui-egui/src/menus.rs: kept base's saved-workspace entries, then the PR's Help › Check for Updates reordering
- docs/gaps.md: base status line with the PR's G17 clause prepended; PR revision row above base's rows
- docs/target-app-parity.md: base status line (updated 2026-10-22) with the PR's clause prepended; PR revision row above base's rows
- docs/scorecard.md: generated, took b7-base's version

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-22 23:38:46 +02:00
David Mann e7c53231a5 Merge PR #8547: perf(gpu): layer pages that just miss the budget borrow the effect-map share, P60/P61 10× faster on integrated GPUs 2026-10-22 23:38:40 +02:00
David MannandClaude Opus 5.5 08f951b909 Merge PR #4221: Options bar: the same tool options in every theme (#4178)
Conflicts:
- crates/ui-egui/src/panels.rs: took b7-base's file (keeps align_bar in the Move bar and all other main changes) and re-applied the PR's change: dropped the six `if t.pro` guards (Marquee, Lasso, Paint Bucket, Perspective Crop, Crop, Move) and deleted the eight non-Pro hint/fallback arms (incl. the Studio Move arm, now covered by the Pro arm which already has Auto-Select, Show Transform Controls and align_bar); rustfmt reindent.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-22 23:38:40 +02:00
David Mann 4d6e2b08c5 Merge PR #8465: perf(camera-raw): exposure with all scopes under its 10 ms budget (P36), same output 2026-10-22 23:38:39 +02:00
3175a3c4cb Integration: keep failed compositor pipelines in the map (#8118)
The parallel build skipped a non-map pipeline whose creation raised an
error, so with new_with_format (errors logged, compositor still returned)
its key was missing from kit.pipelines and the first draw panicked on the
`self.kit.pipelines[&(kernel, acc)]` index. As before the PR, a failed
non-map pipeline now keeps its invalid handle (draws report GPU errors);
only a failed effect-map pipeline is skipped (all maps go to the CPU).

Test: a_compositor_with_failed_pipelines_draws_without_panicking builds
new_with_format(Rgb9e5Ufloat) on a device with an uncaptured-error
handler and renders: it panicked at the index without the fix. The PR's
test moves into tests/it (one test binary) and takes GPU_LOCK.

Co-authored-by: 00xJS <56056764+00xJS@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-22 21:42:40 +02:00
2e29033b50 Integration: no Outside stroke share under opaque pixels on the GPU too (#5937)
The PR gives an Outside stroke no share beneath fully covered pixels on the
CPU, but no test failed without it: under a Normal layer the opaque pixel hides
the stroke anyway. It shows with Blend Interior Effects as Group on a Multiply
layer: main multiplied the red interior with the blue stroke beneath it (black).
New test outside_stroke_under_multiply_layer_leaves_interior_to_backdrop
(raster and filled shape) fails on main's effects.rs, passes with the PR.

The GPU compositor mirrored the old math (outline_share 1 at full coverage, and
1 under an opaque pixel layer); compose.wgsl now matches the CPU. Blend Interior
Effects as Group itself renders on the CPU, so on the GPU this is consistency;
a parity case pins non-Normal layers with an Outside stroke.

Co-authored-by: seotarek <30214297+seotarek@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-22 21:41:01 +02:00
1bfae77c16 Integration: test stringID blend modes through .atn import (#8502)
The PR's test only called blend_label/blend_ps. This adds one through the
import entry point: a Set Lyr step with Md enm("BlnM","softLight") and a
Make layer step with Usng Md "luminosity", written with atn::write and
imported, must give layer.setProps blend "Soft Light" and layer.new.layer
mode "Luminosity" with no unsupported steps. Without the PR's table rows
the Set step is unsupported (and the Make falls back to Normal).

Co-authored-by: justinjohn0306 <34035011+justinjohn0306@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-22 21:39:28 +02:00
6bb15d2278 Integration: keep another instance's shift tool switch choice (#5878)
Two instances migrate the same version 1 file (useShiftKeyForToolSwitch
false -> true), so both save bases hold false. When B turns the switch off
and saves version 2, A's next unrelated save wrote its migrated true over
that choice. write_prefs now drops the migration delta from the base when
the file on disk is already version 2 or later.

Test: another_instances_shift_tool_switch_choice_beats_this_ones_migration
(fails without the fix: true written over false).

Co-authored-by: Higgs32584 <55243596+Higgs32584@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-22 21:39:04 +02:00
95c3af68c3 Integration: prove doc.replaceSmartObject replaces and undoes (#8150)
The rpc test only checked the returned layer id, so a no-op that echoed
{"layer": id} passed, its undo check passed on doc.place's own step, and
the bad-layer case asserted on an empty reason. It now checks the smart
object's file name and rendered centre pixel (42 -> 200 after the
replace, back to 42 on undo, 200 on redo), that every refusal changes
nothing, and that layer 999999 fails with "no such layer".

The bridge row in docs/control-protocol.md claimed doc_replace_smart_object
maps onto layer.smartObjects.replaceContents; the desktop refuses that
command (ambient path), like doc_place's file.placeEmbedded. The row now
says so and points to the headless / workspace server method.

Co-authored-by: VishnuByrraju <112673081+VishnuByrraju@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-22 21:36:42 +02:00