Merges main through #3283 (Smart Filters: distinct editors, shared
disclosure and stable alpha).
filter_dialog.rs: main's split of the preview into is_smart_edit,
smart_preview_factor and scale_preview_params is kept. The plug-in branch
from #7524 (plugin_cmds::scale_for_preview scales only declared pixel
lengths) moved into scale_preview_params, so it applies to a plug-in run
on its own and to a plug-in recorded as a smart filter.
smart_ui.rs open_editor: main's smart_filter_dialog::target flow and the
shared adjust/filter dialog opening are kept; the Liquify re-open with
recorded strokes (r4) stays ahead of it. The old per-adjustment
edit_filter call is dropped with main's rewrite.
Resolutions: CLI usage, flag lists and flag parsing carry both --tiff-compression (t15) and
--jpeg-format (t16); file.saveACopy, batch, imageProcessor and layersToFiles param specs carry
both tiffCompression and jpegFormat; file_cmds keeps tiff_compression_param and
jpeg_format_param; atn_cmds keeps flag_set/applies_at_canvas_bounds (t15) and UNHOLDABLE (t16),
edit.transform uses the pixel_target guard (t15) with layer_ref(p)? (t16); ui-egui open paths
build ImportOptions (t16) and apply raw_defaults (t15); docs headers/rows unioned; atn tests keep
both sides; tr.tsv "Keep Using CPU" kept once.
crates/io/tests/corpus.rs: kept main's pass_floor 188 (the PR's 187 would lower it; not re-measured here)
docs/file-format-parity.md: kept main's header and PSD/PSB rows; added the PR's change-log row without its floor figure
docs/gaps.md: kept main's header and evidence line; added the PR's change-log row without its floor figure
docs/scorecard.md: ours
crates/io/tests/corpus.rs: kept main's pass_floor 188 (TAKE-FIX: drop the PR's 186 hunk)
docs/file-format-parity.md: kept main's header and PSD/PSB rows; added the PR's change-log row without its floor figure
docs/gaps.md: kept main's header and evidence line; added the PR's change-log row without its floor figure
docs/scorecard.md: ours
docs/gaps.md: header and change-log row once each (the PR's row on top).
docs/ui-parity.md: header and change-log row once each; the Selection row keeps main's #6549 sentence and adds the PR's #6548 sentence.
The Hand tool's held Zoom goes through `zoom_tool::drag`, so with Scrubby
Zoom off a ⌘-drag draws a zoom rectangle rather than scrubbing. Say so in
the parity row, and test that case.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
crates/format/src/store.rs: the Windows tiles/blobs directory flush goes before main's manifest write (main publishes the manifest before removing stale previews), and that write takes the PR's fs argument; the PR's second manifest write is dropped.
crates/ui-egui/src/lib.rs: replay_save doc comment names both Export As and JPEG; replay_save uses the PR's FormatChoices::from_step, after main's export_dialog::replay branch.
docs/file-format-parity.md: header keeps main's text plus the JPEG Options item (last updated 2026-10-19); TIFF row is main's, JPEG row is the PR's; change-log rows once each, newest first.
docs/gaps.md: header keeps main's text plus the G10 item (last updated 2026-10-19).
Conflicts:
docs/gaps.md: header line is ours plus the PR's missing change item (later Last updated date); change-log rows kept both, newest first
docs/file-format-parity.md: same
crates/engine/src/float_cmds.rs: kept main's cut_piece (parallel, shares full tiles) and try_lift_coverage, and the PR's CutParts::outline; the outline is read from the piece's alpha, which holds min(alpha, selection) as the PR's own lift loop computed, instead of replacing cut_piece with that loop.
crates/engine/src/float_cmds/tests.rs: git interleaved the two sides' new tests; took main's file and appended the PR's added tests whole.
docs/ui-parity.md: header line keeps main's text plus the PR's #7538 item.
Conflicts:
docs/gaps.md: header line is ours plus the PR's missing change item (later Last updated date); change-log rows kept both, newest first
docs/file-format-parity.md: same
crates/ui-egui/src/i18n/*.tsv (20 catalogs): both sides appended rows at the same place; union, no duplicate keys.
crates/ui-egui/src/state.rs: both new ToolOptions fields (type_style_defaults, type_direction) and defaults.
crates/ui-egui/src/tool_reset.rs: Type tools reset both type_direction and type_style_defaults.
crates/ui-egui/src/type_tool.rs: new type is created from default_style_params (main); direction added to it, and apply_defaults stores a direction edit in type_direction.
docs/gaps.md: header and G8 evidence from main, G8 missing text reworded for direction buttons, change-log lines of both.
docs/scorecard.md: ours (regenerated at combine).
crates/ui-egui/src/lib.rs: union in the PhotocraftApp fields, the initialiser and set_wgpu (main's window_device/window_lost/window_recovery_retry and set_available, the PR's gpu_render_state/gpu_fault).
docs/control-protocol.md: ui.gpu.simulateLoss line takes the PR's text and keeps main's destroy: true sentences.
crates/ui-egui/src/i18n/ru.tsv: both sides added rows at two places; kept both (union).
docs/gaps.md: header from main, change-log lines of both.
docs/localization-parity.md: change-log lines of both.
crates/format/src/store.rs: kept both field sets in PcraftWriter::default (main's blob_hash_cache/compressed_budget and the PR's lock_wait) and both setters (set_compressed_cache_budget, set_lock_wait).
crates/ui-egui/src/canvas.rs: crop-camera block and paint_canvas call take the PR's display_view easing; the overlay-while-panning guard (`panning`, `if primary`) is main's, replacing the PR's hand_pan && dragged condition.
apps/photocraft/src/services.rs: SAVE_FILTERS keeps the DDS entry from main and the PR's Cineon entry.
crates/codecs/README.md: Cineon table row from the PR (read and write), then main's DICOM and Amiga IFF rows.
crates/codecs/src/format.rs: caps keep the PR's Cineon (read and write) and main's Dicom and Iff rows.
crates/codecs/src/lib.rs: encode keeps the PR's Cineon arm and main's Dicom and Iff arms.
docs/file-format-parity.md: header kept from main with the Cineon write item added; Cineon / DPX row from the PR, DICOM row from main; the PR's change-log line added once at the top.
docs/gaps.md: header kept from main with the Cineon write item added; Missing list without 'Cineon write'; the PR's Cineon progress line replaces main's read-only one; the PR's change-log line added once at the top.