Commit Graph
10857 Commits
Author SHA1 Message Date
Martin BallandClaude Opus 5.5 dd39514ef0 Merge origin/main into craft-i18n-cutover
Keeps the deletion of the in-repo catalogs; #12357's Layer Via Copy/Cut
rows are in craft-i18n.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-08 22:28:32 +00:00
David Mann 70c0911d4e Merge pull request #12399 from davidmann4/fix/12397-wand-seed-tests-antialias
Magic Wand seed-outside tests expect the measured Anti-alias fringe, main green again (#12397)
2026-11-08 21:57:33 +01:00
David Mann dff5d29584 Merge remote-tracking branch 'origin/main' into fix/12397-wand-seed-tests-antialias 2026-11-08 21:03:43 +01:00
David MannandClaude Opus 5.5 bfe5d2a671 Magic Wand seed-outside tests: keep Anti-alias on, expect the measured fringe (#12397)
Instead of turning Anti-alias off, the tests keep the default setup and
expect the reference application's measured results (#11776, #11779):
the selection ends at 381, Subtract at 219, Intersect runs 219-381.
Suggested by hectorviov on #12399.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-08 21:03:37 +01:00
David MannandClaude Opus 5.5 4e43c23e43 Magic Wand seed-outside tests: Anti-alias off, so they test the modes with hard edges (#12397)
#12146 gives near-matching neighbours a soft fringe when Anti-alias is on.
The #11848 tests left Anti-alias at its default and expected exact column
bounds, so main's engine tests failed (381 instead of 380).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-08 20:31:42 +01:00
David Mann a17acfa7a7 Merge pull request #12049 from DuBearte/fix/11897-clear-on-background
Brush: Clear on the Background paints as Normal and the Mode reads Normal
2026-11-08 20:16:11 +01:00
David Mann 3ef886c2e0 Merge pull request #12382 from TrevorBrown-dev/fix/layer-via-copy-capital-12357
Menus: Layer Via Copy and Layer Via Cut with a capital V, as in the reference (#12357)
2026-11-08 20:10:52 +01:00
David Mann 8acd45bfa9 Merge pull request #12298 from TrevorBrown-dev/fix/patch-destination-selection-12119
Patch: in Destination mode the selection moves with the patch (#12119)
2026-11-08 19:56:56 +01:00
David Mann 4e5f150eb4 Merge pull request #12146 from hectorviov/fix/wand-antialias-fringe
Magic Wand: Anti-alias keeps the region whole and softens only near-matching neighbours (#11776)
2026-11-08 19:49:41 +01:00
David Mann 5b0c31fc47 Merge pull request #11845 from mzuniga37/fix/11770-count-click-shows-count
Count tool: adding a marker turns View > Show > Count back on (#11770)
2026-11-08 19:49:27 +01:00
David Mann f235e9f30c Merge pull request #12154 from davidmann4/fix/11902-bg-eraser-decontamination
Background Eraser: partly erased pixels lose the sampled colour's tint (#11902)
2026-11-08 19:34:28 +01:00
David Mann 83e2172336 Merge pull request #11848 from DuBearte/fix/11779-wand-seed-outside
fix(engine): Magic Wand Subtract and Intersect grow from the seed through the selection (#11779)
2026-11-08 19:33:29 +01:00
David Mann fa41efebc5 Merge pull request #9348 from VoiceLessQ/pattern-preview-wrap-tools
paint: 12 more painting tools wrap across the canvas edges in Pattern Preview (#8883)
2026-11-08 19:22:34 +01:00
David Mann 9eb2abcf33 Merge pull request #9396 from kavishkashehan726-sudo/fix/9356-pen-continue-path
Pen: carry on a shape's or vector mask's open path, and show the cont…
2026-11-08 19:22:19 +01:00
David Mann 40c310dfa3 Merge pull request #5224 from augrclk/fix/brush-spacing-row
Brush Settings: combine the Spacing checkbox and percentage header
2026-11-08 19:22:06 +01:00
David Mann 6f6db07478 Merge remote-tracking branch 'origin/main' into pr-12154 2026-11-08 18:50:05 +01:00
Trevor BrownandClaude Sonnet 5.5 76ad52bf47 Patch Destination: the rectangle check is capped and scans in bands (#12119)
Cause: is_hard_rect read selection coverage over the selection's own content bounds in one buffer. After a transform those bounds can reach far past the canvas, while the patch-size guard only measures the on-canvas part, so a huge mostly-off-canvas selection could stall or exhaust memory.

Fix: is_hard_rect now calls is_hard_rect_within with MAX_PIXELS (the patch's own cap); bounds over the cap are not a hard rectangle and the selection stays in place. Otherwise coverage is scanned in 64-row bands, stopping at the first pixel below 1.0.

Verified: new test covers a limit below and at the pixel count and a hole in the third band; patch (25) and retouch (126) lib tests pass, clippy -D warnings and fmt clean.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Model-Effort: Opus 5.5 drove and briefed; Sonnet 5.5 wrote at medium
2026-11-08 12:38:04 -05:00
David Mann f439a33ce5 Merge remote-tracking branch 'origin/main' into pr-12049 2026-11-08 18:20:55 +01:00
b5501b9bd1 PR #12049: keep a held ~ erasing on the Background, keep Clear on a locked one
The engine turned every "mode": "clear" stroke on the Background into
Normal, so a held ~ painted the foreground there instead of erasing to
the background colour as on main. The options bar already turns a chosen
Clear off at the press, so the engine conversion was not needed: drop it
and keep the one check in clear_off_on_background.

A Background with locked pixels refuses the stroke, so a chosen Clear now
stays chosen there. The "Tool state machine" doc line is back on
tool_event.

Co-Authored-By: DuBearte <DuBearte@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-08 18:20:55 +01:00
FredApps e564137b23 Merge pull request #12275 from Triwarr/pdf-editable
PDF: opt-in editable import (paths and text)
2026-11-08 18:13:39 +01:00
David Mann bb7a1289b0 Merge remote-tracking branch 'origin/main' into pr-12049 2026-11-08 18:05:36 +01:00
FredApps 79f1da3a93 Merge main and Hand menu test compatibility fix 2026-11-08 17:30:30 +01:00
FredApps dd6e77309f test(ui): align Hand menu anchor checks with fixed zoom rows 2026-11-08 17:28:55 +01:00
Martin BallandClaude Opus 5.5 d82297759f build: pin craft-i18n 7f93d10 (sync branch head)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-08 16:25:38 +00:00
Martin BallandClaude Opus 5.5 d11912b49b build: pin craft-i18n cc833c5 (sync branch head)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-08 16:24:09 +00:00
Martin BallandClaude Opus 5.5 ddb2725e16 test(i18n): skip catalog tests in a build without craft-i18n
Tests that read a translation call needs_catalogs() first, so a build
without CRAFT_I18N_DIR stays green and English-only; CI embeds the
catalogs and runs them.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-08 16:16:46 +00:00
Martin BallandClaude Opus 5.5 acc88b3203 chore(i18n): delete the in-repo catalogs and their packer
The 34 crates/ui-egui/src/i18n/*.tsv, LICENSE-translations.txt and
catalog.rs now live in craft-i18n, as does the credit for each catalog;
ATTRIBUTION has one row pointing there. build.rs stops deflating catalogs
and the Dockerfile stops copying the deleted licence.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-08 16:16:46 +00:00
Martin BallandClaude Opus 5.5 9dd39df78d feat(i18n): look up translations through the craft-i18n crate
The i18n module becomes a thin Lang wrapper over craft_i18n::I18n and the
catalogs embedded from craft-i18n. Plurals use trn_plain and PhotoCraft
keeps its own fmt; @id rows come only from PhotoCraft's own rows that keep
the label's shape. Detection, PHOTOCRAFT_LOCALE, tag bounds and the 35
offered languages are unchanged.

Serbian: sr, sr-RS, sr-Cyrl-RS and sr-ME reach sr-latn, the only Serbian
catalog, and a saved interface.language "sr" migrates to "sr-latn".

The menu completeness test becomes a report that never fails, and
`cargo xtask i18n-coverage` is replaced by `cargo xtask i18n-report`, which
reads CRAFT_I18N_DIR through the crate. Docs describe the new system.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-08 16:16:46 +00:00
Martin BallandClaude Opus 5.5 0c628208b5 build(i18n): embed the craft-i18n catalogs pinned in craft-i18n.rev
- `craft-i18n` crate (craft-libs c5a1cbfb, PhotoCraft's existing pin; already in the tree through
  craft-ui) as a ui-egui dependency.
- build.rs writes `CRAFT_I18N` from `CRAFT_I18N_DIR`: one (locale, common.tsv, photocraft.tsv)
  entry per locale with a PhotoCraft catalog, paths written with `{:?}` and never canonicalized.
  Unset: empty, English only; `CRAFT_I18N_REQUIRED=1` makes a missing checkout an error.
- `craft-i18n.rev` pins storytold/craft-i18n 4bafe3ed (the cutover sync of photocraft@848fa30),
  LF through `.gitattributes`.
- Both flatpak manifests fetch craft-i18n at that commit; the source build sets `CRAFT_I18N_DIR`
  and `CRAFT_I18N_REQUIRED=1`. A test keeps both manifests equal to the pin.
- ci.yml: the Windows, without-heif and web jobs check out craft-i18n at the pin, as the shared
  gate and release workflows do; a pin bump selects the web and Windows jobs.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-08 16:16:46 +00:00
David Mann 535ea2d15c Merge pull request #12152 from davidmann4/fix/11904-bg-eraser-find-edges-graded
Background Eraser: Find Edges erases soft edges graded instead of cutting them hard (#11904)
2026-11-08 17:00:18 +01:00
David Mann 1c9448e87f Merge pull request #12341 from rmsff/fix/vertical-type-align-buttons-12059
fix(ui): vertical text gets Top / Center / Bottom alignment buttons (#12059)
2026-11-08 17:00:04 +01:00
David Mann 718b06645e Merge pull request #12299 from TrevorBrown-dev/fix/patch-cursor-arrow-12130
Patch: an arrow badge over the selection shows that a drag moves the patch (#12130)
2026-11-08 16:59:48 +01:00
David Mann 532421aa2a Merge pull request #12212 from TrevorBrown-dev/feat/open-as-smart-object-11678
File: Open as Smart Object... opens a file as a new document holding one embedded smart object (#11678)
2026-11-08 16:59:25 +01:00
David Mann 6b73593478 Merge pull request #12238 from hectorviov/fix/brush-picker-angle-widget
Brush Preset picker: the tip's angle/roundness widget at its top left
2026-11-08 16:59:09 +01:00
David Mann 8c94ba8a15 Merge pull request #12203 from hectorviov/fix/count-history-names
Count tool: History names Add/Drag/Delete Count Object, Add Count Group and one name per group setting (#11763)
2026-11-08 16:58:51 +01:00
FredApps 5ae31d3de2 fix(pdf): preserve editable import fidelity and bound caches 2026-11-08 16:58:06 +01:00
David Mann 89660c82fe Merge pull request #12231 from hectorviov/fix/note-stored-values
Notes: new notes store the reference application's colour, popup rectangle and local-time date
2026-11-08 16:57:08 +01:00
David Mann 90e362e7a6 Merge pull request #12221 from hectorviov/fix/perspective-crop-bar-buttons
Perspective Crop: the options bar's Cancel and Commit show only during a session (#11978)
2026-11-08 16:56:52 +01:00
David Mann be4f54df4c Merge pull request #12205 from DuBearte/fix/11968-pencil-auto-erase-tooltip
Pencil: the Auto Erase checkbox shows its tooltip
2026-11-08 16:56:35 +01:00
David Mann b0953546ca Merge pull request #12148 from hnoerenberg/fix/straighten-layer-states-12033
fix(engine): Straighten Layer greys out and refuses the states the reference does
2026-11-08 16:56:18 +01:00
David Mann 45c76d5c5c Merge pull request #12144 from hnoerenberg/fix/indexed-type-selection-12041
fix(engine): the Type tool leaves a selection in Indexed Color
2026-11-08 16:56:00 +01:00
David Mann 32ce08364b Merge pull request #9991 from ljkx/feat/raw-xmp-crop
Camera Raw sidecars: apply the crop, stop reporting RawFileName (#9985)
2026-11-08 16:55:43 +01:00
David Mann 8f94ff568f Merge pull request #12338 from rmsff/fix/type-mask-replaces-selection-12073
fix(ui): a Type Mask always replaces the selection when committed (#12073)
2026-11-08 16:54:03 +01:00
David Mann 2a2b381297 Merge pull request #12333 from rmsff/fix/type-mask-escape-commits-12070
fix(ui): Escape commits a Type Mask session as Command+Return does (#12070)
2026-11-08 16:53:46 +01:00
David Mann 5a288de0e8 Merge pull request #12328 from rmsff/fix/type-options-bar-tooltips-12057
fix(ui): the Type options bar gets the reference tooltips (#12057)
2026-11-08 16:51:41 +01:00
David Mann 2ffe5d1008 Merge pull request #12102 from Bobderto/fix/12085-zoom-menu-centre
Zoom tool menu: keep the view centre for Zoom In and Out
2026-11-08 16:51:19 +01:00
Trevor BrownandClaude Sonnet 5.5 66d5ebed89 Menus: Layer Via Copy and Layer Via Cut with a capital V, as in the reference (#12357)
Cause: the menu bar, the command labels and the selection tools' canvas menu spelled the two commands "Layer via Copy" and "Layer via Cut", while the reference application (and PhotoCraft's own History names and ATN event table) use a capital V.

Fix: renamed the labels in crates/ui-egui/src/menu_catalog.rs, the two spec! labels in crates/engine/src/cmd/edit_cmds.rs, and the rows in crates/ui-egui/src/canvas/canvas_tool_menu.rs with its test assertions. In the 33 locale files crates/ui-egui/src/i18n/*.tsv that carry the keys, only the key column of those two rows changed (66 rows), so every translation is kept and no language falls back to English. New tests are in crates/ui-egui/src/layer_via_label_tests.rs, registered with one mod line in lib.rs like the other *_tests.rs files.

Verified: the 5 new tests pass; canvas_tool_menu 51 passed; engine edit_cmds 112 passed; i18n 66 passed and 8 live_tests failed with the known local font panic in epaint fonts.rs (font-dependent, green on CI); cargo xtask parity left docs/parity-checklist.md unchanged; clippy -D warnings and fmt are clean. TSV check against HEAD: 34 files, same row count in each, exactly 66 rows differ (2 per file in 33 files, Hindi has none), only the key column of those rows differs, the translation column is byte-identical, no old key remains, and no CR bytes in any touched file.

Not changed: the translations' text, the History names and the ATN event table (already the capital V), docs/ui-parity.md and the other parity docs.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Model-Effort: Opus 5.5 drove and briefed; Sonnet 5.5 wrote at medium
2026-11-08 10:14:55 -05:00
Trevor BrownandClaude Opus 5.5 1483d5193d Merge upstream/main into fix/patch-destination-selection-12119
Conflict in retouch_cmds/patch.rs with #12255 (one History name, "Patch Selection", for every mode): kept the Destination branch that moves a hard rectangular selection with the patch and gave it HISTORY_NAME, and restored Plan's destination flag, which #12255 had removed as unused. patch tests 24 passed (including #12255's history-name test), clippy and fmt clean.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Model-Effort: Opus 5.5 drove and resolved
2026-11-08 09:51:27 -05:00
Trevor BrownandClaude Sonnet 5.5 f3de619549 Patch Destination: a hard rectangle partly off the canvas moves with the patch (#12119)
Cause: is_hard_rect required the selection's bounds to equal plan.area, which is clipped to the canvas. A hard rectangle reaching past the canvas (e.g. moved there with select.transformSelection, which keeps the off-canvas pixels) has bounds larger than the area, so the pixels were patched but the selection was left behind.

Fix: treat the selection as a hard rectangle when nothing is selected outside its own bounds and every pixel inside those bounds is fully selected, then translate the whole selection by the drag offset. Feathered, non-rectangular and holed selections still stay in place.

Verified: new test destination_moves_a_hard_rectangle_that_extends_past_the_canvas failed before the change (selection stayed at -20,100..40,140 while the pixels changed) and passes after, including one-undo restore of pixels and selection. cargo test -p photocraft-engine --lib patch (19 passed) and retouch (120 passed), clippy -D warnings and fmt clean.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Model-Effort: Opus 5.5 drove and briefed; Sonnet 5.5 wrote at medium
2026-11-08 09:47:11 -05:00
David Mann 848fa306f5 Merge pull request #12255 from SBaksa/patch-history-names
Patch: History names as the tool's (fixes #12117)
2026-11-08 15:25:52 +01:00