Commit Graph
307 Commits
Author SHA1 Message Date
aiongg 7aaa59712a Merge main into integration-batch-7 2026-10-23 20:37:05 +00:00
Khawar Zamman WaniandClaude Opus 5.5 4970534e05 feat(engine): Select and Mask tool edits as select.refineEdge params
select.refineEdge takes `edits`: the Select and Mask workspace's Quick
Selection, Brush, Lasso, Object Selection, Select Subject, Clear Selection
and Invert, applied in order to the starting selection (or layer mask)
before the edge is refined. Cancel discards them, OK is one history step,
and agents drive them over MCP and the control channel.

- engine/select_mask_edits.rs: parse (bounded, every bad field an Err)
  and a pure apply/apply_one the workspace preview can share
- algo matting::brush_region: soft round brush coverage (hardness)
- ATN export reports steps with edits instead of dropping them
- "Edits" label in the 21 catalogs

Part of #7069 and #8148 (the workspace UI follows in a second PR).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-23 10:30:46 +05:30
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
David Mann 9487065314 Integration: merge main (one test binary per crate, #8644)
# Conflicts:
#	docs/file-format-parity.md
#	docs/gaps.md
#	docs/scorecard.md
#	scorecard/file_compat.toml
2026-10-22 19:55:06 +02:00
David MannandClaude Opus 5.5 f5533e5d82 Integration: merge main into batch 6
Main merged #5940, #6472, #7838 and #7922 directly. Kept from the batch:
the snapshot/History-follow identity at the history limit (#5940,
c7ef3676a; main still had the 3-tuple HistorySpot) and the strokeless
shape at a 0 px width step (#6472, 962539607; main still added the
stroke). Main already carries the other two fix-ups (34c9d0ea4, dff8bfd0e).

Overlaps with main resolved:
- #5842 vs main's #5568: one path, apply_color, tool-gated as #5842
  has it, with #5568's float fill, kept fill opacity and lock skip;
  shape_fill_ui's duplicate foreground_changed/gesture dropped; #5568's
  tests run with a shape tool.
- #6230 vs main's #5180: one Type tool path click (path_target), no
  second type.attachToPath; vertical type does not start type on a path,
  as main has it; main's path_at/path_cursor and canvas arm dropped.
- #5452 moved the shape swatch to shape_paint_ui.rs: main's hex field
  (#6201) ported there.
- type_extra_cmds::with_text takes main's dpi form, pub(crate) for
  type_area_cmds.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-22 19:20:26 +02:00
aiongg ffa400c754 Keep tests correct and docs current with one test binary per crate
- gpu: the test modules share one GPU_LOCK, and timing and vector_mask
  take it too, so one process drives one wgpu device at a time.
- ui-egui: the wgpu tests in pattern_preview_canvas, adjust_preview_gpu,
  marquee_autoscroll and layout_perf take gpu_lock().
- affinity compound_limits: the child process selects its test by the
  module path (compound_limits::<name>); with --exact, the bare name
  matches no test and the child passes without running the check.
- xtask scorecard reads crates/io/tests/it/corpus.rs.
- Docs and comments name the new test paths and the --test it filters.
2026-10-22 16:55:34 +00:00
aiongg fa010ff7c3 Integration: regenerate docs/scorecard.md 2026-10-22 16:03:31 +00:00
6d3092f243 Integration: merge main, resolve conflicts, JPEG Options docs and encoder test (#7883)
Merges main (8f09d122d). Conflicts: the replay_save doc comment (main added
file.export.exportAs replay) and the status lines and history rows of
docs/file-format-parity.md and docs/gaps.md; both sides kept.

The docs called FILE-215-19 done and said only Save As and Save a Copy ask.
Photoshop's JPEG Options also has Matte, the progressive scan count
(Scans 3-5) and the size preview, none of which is offered, and Baseline
Optimized writes the same file as Baseline for RGB (4:2:0). The row is now
partial with those gaps named, and the docs say File > Save asks too.
docs/scorecard.md is regenerated.

Adds jpeg_options_ui::tests::the_answer_reaches_the_encoder. Every UI test
used a fake exporter, so dropping `opts.encode.jpeg_format` from
ExportSettings::io_options (the desktop and web save path) left them all
green; this test writes a real JPEG through io_options and fails without it.

Co-authored-by: Michael Higgins <55243596+Higgs32584@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-22 15:45:30 +00:00
a74b9a72a1 Integration: merge main, resolve conflicts (#6793)
The 20 i18n catalogs: main and the PR both appended a block at the end;
both kept, main's first. docs/gaps.md: main's text with the PR's
TYPE-218-2 change applied (G8 Missing, Evidence 5 done / 4 partial /
0 missing, revision row), dated 2026-10-22. docs/scorecard.md
regenerated with cargo xtask scorecard.

The TYPE-218-2 note now also says PSD doesn't store the paragraph
direction (crates/text psd.rs maps only the vertical WritingDirection),
so a direction set with the new buttons reopens from a PSD as Auto.

docs/localization-parity.md: the Arabic row said paragraph direction has
no UI (TYPE-218-2); it now has the buttons, the RTL caret is still missing.

Co-authored-by: tareqziad1998 <83318513+tareqziad1998@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-22 15:44:17 +00:00
b526378de4 Integration: 32-bit Hue/Saturation with Photoshop's saturation factor, finite at lightness 1 (#5781)
The 32-bit branch cut the slider to floor(|s| * 255) / 255, which only matches
Photoshop near 25 and 50 %: measured at every whole percent from -100 to +100
on a 32-bit document, Photoshop lowers by 1 - floor(|s| * 256) / 256 and raises
by 255 / (255 - floor(s * 254)) taken to 1/256 and capped at 32767/256 (201 of
201 exact). +100 gave 512x where Photoshop gives 128x, +90 9.8x for 9.44x.

It also kept the HSL saturation unclipped, which is inf at HSL lightness 1 and
0 and negative above 1: (2, 0, 0), red at +1 stop, turned NaN with any edit,
Hue +40 alone included, where Photoshop gives (2, 1.333, 0). The 32-bit branch
now scales the chroma around the lightness instead (same result in gamut),
on the CPU and in the shader, in whole numbers on both. Colorize clamps its
saturation before the 32-bit scaling, so a PSD's out-of-range value renders
the same on the GPU.

Tests (fail without this): thirty_two_bit_saturation_steps_match_photoshop,
thirty_two_bit_hue_saturation_keeps_bright_colours, the GPU parity
hdr_hue_saturation_bright_colours. Photoshop-oracle floor 188 -> 190 of 258,
measured after merging main.

Co-authored-by: Timothy Daly <100327160+timothydaly1@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-22 15:42:03 +00:00
aiongg fe220983a7 Integration: regenerate docs/scorecard.md 2026-10-22 15:38:46 +00:00
aiongg 5857afd121 Integration: track t11
# Conflicts:
#	apps/photocraft-cli/src/lib.rs
#	crates/ui-egui/src/i18n/cs.tsv
#	crates/ui-egui/src/i18n/el.tsv
#	crates/ui-egui/src/i18n/es.tsv
#	crates/ui-egui/src/i18n/fr.tsv
#	crates/ui-egui/src/i18n/hu.tsv
#	crates/ui-egui/src/i18n/id.tsv
#	crates/ui-egui/src/i18n/ja.tsv
#	crates/ui-egui/src/i18n/ko.tsv
#	crates/ui-egui/src/i18n/nl.tsv
#	crates/ui-egui/src/i18n/pl.tsv
#	crates/ui-egui/src/i18n/pt-br.tsv
#	crates/ui-egui/src/i18n/ru.tsv
#	crates/ui-egui/src/i18n/sr.tsv
#	crates/ui-egui/src/i18n/tr.tsv
#	crates/ui-egui/src/i18n/uk.tsv
#	crates/ui-egui/src/i18n/vi.tsv
#	crates/ui-egui/src/i18n/zh-hans.tsv
#	crates/ui-egui/src/i18n/zh-hant.tsv
#	docs/gaps.md
2026-10-22 15:38:31 +00:00
aiongg 446b74a8de Integration: track t07
# Conflicts:
#	crates/ui-egui/src/i18n/cs.tsv
#	crates/ui-egui/src/i18n/de.tsv
#	crates/ui-egui/src/i18n/el.tsv
#	crates/ui-egui/src/i18n/es.tsv
#	crates/ui-egui/src/i18n/fr.tsv
#	crates/ui-egui/src/i18n/hu.tsv
#	crates/ui-egui/src/i18n/id.tsv
#	crates/ui-egui/src/i18n/it.tsv
#	crates/ui-egui/src/i18n/ja.tsv
#	crates/ui-egui/src/i18n/ko.tsv
#	crates/ui-egui/src/i18n/nl.tsv
#	crates/ui-egui/src/i18n/pl.tsv
#	crates/ui-egui/src/i18n/pt-br.tsv
#	crates/ui-egui/src/i18n/ru.tsv
#	crates/ui-egui/src/i18n/sr.tsv
#	crates/ui-egui/src/i18n/tr.tsv
#	crates/ui-egui/src/i18n/uk.tsv
#	crates/ui-egui/src/i18n/vi.tsv
#	crates/ui-egui/src/i18n/zh-hans.tsv
#	crates/ui-egui/src/i18n/zh-hant.tsv
#	crates/ui-egui/src/layer_shortcut_tests.rs
2026-10-22 15:38:21 +00:00
aiongg 1f0177f23c Integration: track t04
# Conflicts:
#	ATTRIBUTION.md
#	contributors/people.toml
#	crates/ui-egui/src/i18n/cs.tsv
#	crates/ui-egui/src/i18n/de.tsv
#	crates/ui-egui/src/i18n/el.tsv
#	crates/ui-egui/src/i18n/es.tsv
#	crates/ui-egui/src/i18n/fr.tsv
#	crates/ui-egui/src/i18n/hu.tsv
#	crates/ui-egui/src/i18n/id.tsv
#	crates/ui-egui/src/i18n/it.tsv
#	crates/ui-egui/src/i18n/ja.tsv
#	crates/ui-egui/src/i18n/ko.tsv
#	crates/ui-egui/src/i18n/nl.tsv
#	crates/ui-egui/src/i18n/pl.tsv
#	crates/ui-egui/src/i18n/pt-br.tsv
#	crates/ui-egui/src/i18n/ru.tsv
#	crates/ui-egui/src/i18n/sr.tsv
#	crates/ui-egui/src/i18n/tr.tsv
#	crates/ui-egui/src/i18n/uk.tsv
#	crates/ui-egui/src/i18n/vi.tsv
#	crates/ui-egui/src/i18n/zh-hans.tsv
#	crates/ui-egui/src/i18n/zh-hant.tsv
#	docs/gaps.md
2026-10-22 15:38:17 +00:00
David MannandClaude Opus 5.5 7a54fa9c77 Integration: merge main into batch 6
Conflicts, both sides kept: main's .act swatches next to the batch's .asl
styles (Open filters, preset extensions), main's Render smart filters next
to the batch's Distort ones (53 mapped), parity doc status lines.
docs/scorecard.md regenerated.

Follow-ups the merge needed: the Distort smart filter readers pass their
enum type to main's stricter enum_name (the type their writers use), and
the CMYK effect tests set main's new StrokeFx overprint and Bevel
gloss_anti_alias.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-22 12:09:25 +02:00
aiongg dfde38919e Merge PR #7883: Save As JPEG: JPEG Options dialog (quality 0–12, Baseline / Optimized / Progressive) (FILE-215-19)
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).
2026-10-22 02:27:46 +00:00
aiongg 51606201ac Merge PR #3698: feat: animate zoom
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.
2026-10-22 02:24:09 +00:00
aiongg 11c3f1ec92 Merge PR #5180: Type tool: click a path to start type on it (TYPE-218-1, #218)
contributors/people.toml: union of both sides' entries.
crates/ui-egui/src/canvas.rs: main's Move cursor (arrow) plus the PR's Type path-cursor arm.
crates/ui-egui/src/type_tool.rs: main's has_transform in draw_overlay; the PR's earlier `shape` binding kept, the duplicate binding dropped.
crates/ui-egui/src/vector_ui.rs: main's draw_overlay (paths already show with any tool), the PR's vector_tool line dropped.
docs/gaps.md: header line from main, G8 text from main with the click-on-path clause, change-log lines of both.
2026-10-22 02:22:58 +00:00
aiongg db6fc62d58 Merge PR #3565: M11: ten more acceptance tasks (21-30) in a second file for FILE-216-6 2026-10-22 02:21:46 +00:00
aiongg 200206f56b Merge PR #4392: Layer Style: user contour library with New…, Load/Replace/Save Contours (#4391) 2026-10-22 02:21:46 +00:00
David MannandClaude Opus 5.5 8905fdccca Integration: .asl gets its own Open filter, type.fillPath is a vector path (#4049, #6230)
- main's every_open_format_has_its_own_filter needs a named File › Open filter for every format:
  .asl (#4049) gets "Styles", as in Photoshop.
- main's registry_filesystem_path_params_are_classified read type.fillPath's "path" (#6230) as a
  host file; it is a document vector path, like type.attachToPath.
- docs: Type scorecard 5 / 4 / 1 in target-app-parity.md, 49 mapped smart filters in the scorecard.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-22 00:22:00 +02:00
aiongg c71322043c Merge PR #7941: Light themes outline the slider knob (UI-217-11, #7927) 2026-10-21 21:56:21 +00:00
David Mann a8f91f54ad Merge PR #6230: feat(type): area type, text that wraps inside a closed path or shape
Integration: resolve with main for area type (#6230)

- Image Size with a new resolution (#7124, canvas_geom::set_resolution) now scales an area type's
  path with the text space like a box or a type path, so the same words wrap onto the same lines;
  test a_resolution_change_keeps_area_type_wrapping_where_it_was fails without it.
- The Paragraph panel's justify buttons (#7713) stay available on area type, which is paragraph
  text in Photoshop; test justify_buttons_work_on_area_type.
- Test files: main's tests plus #6230's; layout.rs imports joined; docs and scorecard regenerated.
2026-10-21 23:46:05 +02:00
vangel76 d614b67ad5 Regenerate contour-library scorecard after merging main 2026-10-21 20:34:12 +02:00
Higgs32584andClaude Opus 5.5 f916c98536 Merge upstream/main into revive/4330-jpeg-options
Conflicts only in the parity docs: status lines take main's text with the
JPEG Options entry (FILE-215-19) on top; scorecard takes main's rows with
FILE-215-19 done and File compatibility 10 / 12 / 5.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-21 12:56:32 -04:00
Gustavo Ziger 89f8eed896 Merge main into feat/zoom-animation-566 2026-10-21 13:48:26 -03:00
aiongg a7825b9e0f Integration: regenerate docs/scorecard.md for the batch 2026-10-21 15:47:34 +00:00
Korg1ch 76e4e81e33 fix(ui-egui): outline the slider knob in the light themes (#7927) 2026-10-21 18:28:10 +03:00
aiongg b1e408d28f Merge the smart-filter track (#7066 #6398 #6397 #6297 #6299 #6301 #6303 #6315 #6305 #6317)
# Conflicts:
#	docs/file-format-parity.md
2026-10-21 05:04:04 +00:00
aiongg 8e04e6f21e Integration: regenerate docs/scorecard.md for the batch 2026-10-21 05:04:04 +00:00
aiongg 4804148ff9 Merge PR #3759: Pattern Stamp and Background Eraser draw live; Spot Healing shows its heal area (TOOL-213-7, #3754)
# Conflicts:
#	docs/gaps.md
#	docs/target-app-parity.md
2026-10-21 05:04:04 +00:00
Gustavo Ziger e41df200b4 Merge main into feat/zoom-animation-566 2026-10-20 23:29:13 -03:00
aiongg c633674b6d Integration: one smart-filter count (41 plus Hue/Saturation, Perspective Warp, Filter Gallery and Camera Raw) in the parity doc and FILE-215-2, for #6317 2026-10-21 01:21:19 +00:00
aiongg 3a3796af05 Merge PR #6397: PSD: Perspective Warp smart filters open and save like Photoshop (#6268)
# Conflicts:
#	crates/io/src/smart_map.rs
#	docs/file-format-parity.md
#	docs/scorecard.md
#	scorecard/file_compat.toml
2026-10-21 01:07:59 +00:00
aiongg 61ef780550 Merge PR #6398: PSD: Hue/Saturation smart filters open and save like Photoshop (#6267) 2026-10-21 01:07:14 +00:00
aiongg d1bed2f98d Merge PR #6644: Hue/Saturation: the Lightness track runs black, grey, white (#6539) 2026-10-21 01:06:14 +00:00
Higgs32584andClaude Opus 5.5 50a745bfce docs: scorecard rows for FILE-215-19 on top of main's regenerated file
The merge with main took main's generated docs/scorecard.md. It is
brought back in line with scorecard/file_compat.toml (FILE-215-19 done):
File compatibility 8 done / 14 partial / 5 missing, and the FILE-215-19
row with its status and note. Edited by hand to the generator's row
format, since `cargo xtask scorecard` isn't run locally; CI's
`cargo xtask scorecard --check` verifies it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-20 20:59:59 -04:00
aiongg 9ac1d5adc6 Integration: regenerate docs/scorecard.md for the batch
#7813's performance.gpu_adapter is read from the prefs file before the window opens (gpu_startup::read_gpu_adapter), which the prefs audit's heuristic doesn't see, so it counts as unread.
2026-10-20 22:07:10 +00:00
13733ba3a9 Integration: hide area type that reaches the shape's narrow bottom (#6230)
When area type overflowed a closed shape, a word too wide for the narrow
bottom rows of an ellipse stayed in its span and was drawn past the outline
(a 260x160 bubble at 12 pt drew "misunderstanding" from x 110 to 212 over a
110..149 span). The shape's wider rows would hold such a word, so the shape
has just run out of room: that line and the rest are now hidden as overflow.
The check looks at every row of the shape, not just the paragraph's own (a
later paragraph starts below the wide top of a funnel), and also runs when
the line-breaking pass budget is spent. Only a word no span in the shape
holds still overflows its span.

The TYPE-218-10 note said such a word overflows "the way box text does";
since #6694 box text breaks it at the edge. Corrected, and the other known
gaps (first line about 0.24 em lower than box text, PSD area type opening as
box text, no handles for the area path) are listed.

Co-authored-by: Silly Silk <31193727+SillySilk@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-20 23:23:54 +02:00
f44e8e4be8 Integration: merge main, resolve conflicts (#6230)
docs/scorecard.md was the only conflict: regenerated with `cargo xtask scorecard`
on the merged tree.

Co-authored-by: Silly Silk <31193727+SillySilk@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-20 23:08:25 +02:00
aiongg ea7553f031 Merge PR #5111: Large documents: a gigapixel New Document draws without freezing (#4017) 2026-10-20 18:39:28 +00:00
aiongg 0ae688b59a Merge PR #6939: Mixer Brush: Clean Brush empties the brush, and the automatic Load and Clean can be switched off 2026-10-20 18:39:27 +00:00
David Mann 38605ceac5 Merge main into feat/tool-213-7-live-retouch
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

# Conflicts:
#	crates/ui-egui/src/canvas.rs
#	docs/gaps.md
#	docs/target-app-parity.md
2026-10-20 19:05:39 +02:00
David Mann 1b0b3e218c Merge main into fix/6267-psd-hue-sat-sf 2026-10-20 17:13:41 +02:00
David Mann a3196466a3 Merge main into fix/6268-psd-perspective-warp-sf 2026-10-20 17:09:56 +02:00
Gustavo Ziger 41682288b2 docs: regenerate scorecard after main merge 2026-10-19 16:06:34 -03:00
Gustavo Ziger bd6723e0bf Merge branch 'main' into feat/zoom-animation-566 2026-10-19 15:34:36 -03:00
Brandon ThomasandClaude Opus 5.5 3a896a5efc docs: regenerate the scorecard (Show File Name In Title adds a preference) (#7829)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 14:23:47 -04:00
PanPDX 54b6b0dbc0 Merge remote-tracking branch 'upstream/main' into area-type
# Conflicts:
#	crates/ui-egui/src/type_tool.rs
#	docs/gaps.md
#	docs/scorecard.md
#	docs/target-app-parity.md
2026-10-18 22:41:59 -07:00
Gustavo Ziger e14dda9dc8 Merge main into feat/zoom-animation-566 2026-10-18 22:52:16 -03:00