Commit Graph
9794 Commits
Author SHA1 Message Date
Vlad Grankovsky d9400a7cb8 Merge upstream main 048ae7977 into curves follow-up 2026-11-07 01:41:38 +01:00
Vlad Grankovsky 283de2c506 Merge upstream main 8df2b7a2e into curves follow-up 2026-11-07 01:27:10 +01:00
David Mann 048ae79779 Merge pull request #11672 from RickiNano/fix/11368-marquee-moves-outline-after-move
Marquee and Lasso: a drag after moving pixels moves only the outline (#11368)
2026-11-07 01:12:58 +01:00
David Mann 0f286b57a9 Merge pull request #11252 from NaufalDzz/fix-transform-several-selection-rules
fix(transform): refuse the Background among several layers and apply the box on a selection change
2026-11-07 01:12:41 +01:00
David Mann 927c63d394 Merge pull request #11022 from Hamza0101/fix/crop-overlay-and-fill-defaults
Crop: Always Show Overlay by default, Fill resets on another open document, and an untouched frame shows only itself (#10894, #10930)
2026-11-07 01:11:21 +01:00
David Mann 8df2b7a2e2 Merge pull request #11738 from davidmann4/fix/az-contextual-task-bar
i18n: translate Contextual Task Bar in the Azerbaijani catalog (#11737)
2026-11-07 00:20:21 +01:00
David MannandClaude Opus 5.5 ee8a4caa03 i18n: translate Contextual Task Bar in the Azerbaijani catalog (#11737)
The Window menu item from #11669 and the Azerbaijani catalog landed
together, so azerbaijani_covers_every_menu_label_and_path fails on main.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-06 23:32:50 +01:00
David Mann 9922871a4e Merge pull request #11148 from vangel76/perf/paint-procedural-texture-cache
perf(paint): cache procedural brush textures between strokes
2026-11-06 23:20:44 +01:00
David Mann ad55badcb8 Merge pull request #11146 from vangel76/perf/paint-retouch-smudge-selection
perf(paint): Smudge start-up and selection sampling without per-pixel work
2026-11-06 23:20:17 +01:00
David Mann 6b0f7762e1 Merge pull request #11671 from davidmann4/integration-batch-20
Integration batch 20: 7 i18n PRs (Thai, Hebrew, Urdu, Tamil, Azerbaijani, Romanian, Korean)
2026-11-06 22:49:42 +01:00
David Mann fd890eaca4 Merge pull request #11669 from davidmann4/feat/crop-task-bar-10890
Crop: Contextual Task Bar under the crop frame, as a reusable task-bar widget (#10890)
2026-11-06 22:49:21 +01:00
David Mann 7ecfccbd64 Merge pull request #11643 from davidmann4/integration-batch-19
Integration batch 19: epic PRs (WIP)
2026-11-06 22:48:55 +01:00
David Mann bd84401dcf Merge remote-tracking branch 'origin/main' into integration-batch-20 2026-11-06 21:46:47 +01:00
David MannandClaude Opus 5.5 e339ecead2 Batch fix-up: keep one path.toShape entry after merging #11005's 0b66e8f00c
#11005's new head adds path.toShape to the vector-path list next to
path.stroke; the batch's 95c7a5d17e had added it next to path.set. Both
merged cleanly into a duplicate or-pattern; keep the contributor's.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-06 21:44:32 +01:00
David Mann 47f4f1ce23 Merge PR #11005's new head 0b66e8f00c (path.toShape vector-path fix) 2026-11-06 21:44:23 +01:00
David MannandClaude Opus 5.5 46d6307cba Crop task bar: Done fits the cropped document
The bar draws inside the canvas pass, whose write-back of its own camera
dropped the fit that commit_crop asks for, so Done kept the old zoom. The
stored view now wins when the bar changed it, as a view menu row's does.
done_fits_the_cropped_document starts at 50 % and fails without the fix.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-06 21:17:51 +01:00
David Mann ce88165362 Merge remote-tracking branch 'origin/main' into fix/crop-task-bar-fit-11669 2026-11-06 21:00:22 +01:00
tasosf b49c6c97c5 fix(export): preserve high-quality JPEG colour detail in Export As (#7985)
* fix(export): preserve full JPEG chroma in Export As

* style(ui): simplify blend preview condition for Clippy

* test(export): verify full JPEG chroma at every quality

Exercise real JPEG export and decode at five qualities across U8, U16 and F32. Read all sampling factors from the main frame while skipping metadata segments and embedded thumbnails. Keep the colour-error limit at quality 100 and verify that the layered source is unchanged.

* Keep JPEG regression compatible with current Clippy

Restore the upstream blend-preview and IME predicates, removing unrelated lint-only changes. Use array chunks in the JPEG colour-error assertion for current stable Clippy.

* Use quality-dependent JPEG sampling in Export As

Keep 4:2:0 through quality 50 and full 4:4:4 above it, using the existing percentage-scale cutoff from Save for Web. Photoshop 27.11 modern Export As measurements show 4:2:0 at levels 1-4 and 4:4:4 at 5-7; no exact numerical mapping of the two scales is claimed.

Exercise both sampling regimes through 15 real JPEG exports across U8/U16/F32, check all percentage qualities in settings, and retain the Save As default. Boundary mutations fail at 50 and 51 as expected.
2026-11-06 20:59:25 +01:00
DingusMcRinkyDinkyandClaude Opus 5.5 0b66e8f00c path.toShape: its path is a vector path, not a host file
The automation registry check takes a `path` parameter for a host file
unless the command is listed as taking a document vector path, as the
other path commands are. path.toShape's `path` is the inline path being
drawn, so it belongs in that list; integration batch #11643 failed on it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EZbgszHyuEuWAzxaamteuU
2026-11-06 20:55:12 +01:00
David MannandClaude Opus 5.5 0b3b3e470b direction tests: ignore the env override, check glyphs only with craft-fonts
Unit tests no longer read PHOTOCRAFT_UI_DIRECTION (cached per process, so a
developer's shell could flip the Hebrew/Urdu and shell assertions). The
Hebrew/Urdu test checks glyphs only when craft-fonts carries a face for the
script (the eager provider draws it in the first frame, as in CI with
CRAFT_FONTS_REQUIRED); without it the harness allows tofu and only the
mirroring is checked, instead of panicking on a host without the fonts.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-06 20:52:58 +01:00
David MannandClaude Opus 5.5 e078c560ec Address CodeRabbit review: task bar tile, inspect and ui.set merge
- Draw the Crop task bar only on the active document's tile: a click into
  another tile activates its document mid-pass, and the tile drawn after it
  put the new frame's bar on itself for that frame.
- ui.inspect reports the bar hidden (and no rect) as soon as it can't show,
  not only after the next draw.
- ui.set merges panels.task_bar field by field: {"at": [x, y]} keeps a pin,
  {"pinned": true} keeps a dragged place; unknown nested fields are refused.
- Tests for each (each fails with its fix reverted), plus the task bar's
  preset dropdown picking 1 : 1 in sync with the options bar.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-06 19:41:21 +01:00
David MannandClaude Opus 5.5 5d5519dcac Regenerate docs/scorecard.md after merging main
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-06 19:41:20 +01:00
95c7a5d17e Batch fix-up: path.toShape (#11005) takes a document vector path, not a file
The automation registry check reads a `path` param as a host filesystem
path unless the command is listed as taking a document vector path, as
path.set is. #11005's new path.toShape takes an inline vector path, so it
joins that list; CI failed registry_filesystem_path_params_are_classified.

Co-Authored-By: DingusMcRinkyDinky <DingusMcRinkyDinky@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-06 19:39:16 +01:00
David MannandClaude Opus 5.5 d7e66606ad Address CodeRabbit review: Turkic I text, type-ahead language change, RTL coverage
- zoom field: a menu's I key drops İ/ı text whatever the UI language (the keyboard layout is
  not the interface language).
- dropdown type-ahead: one entry per list tagged with its language, cleared on any frame in
  another language, so a prefix never carries over a quick switch and back.
- Hebrew and Urdu: live shell test selects each catalog, checks mirroring and glyphs.
- Azerbaijani restart test resets the drawing language before the restarted shell loads.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-06 19:27:11 +01:00
David MannandClaude Opus 5.5 da7690e937 Camera Raw localization test: allow tofu only for Tamil until craft-fonts ships it
The pinned central font manifest has no Tamil face (storytold/craft-fonts#63 adds one) and the
Linux runner has none installed, so the strict missing-glyph policy panicked on the Tamil
labels. Tamil keeps every label and state check; a guard fails once the manifest ships Taml.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-06 19:27:10 +01:00
David Mann d1d913e7e6 Merge remote-tracking branch 'origin/main' into feat/crop-task-bar-10890 2026-11-06 19:24:17 +01:00
David Mann 670fa8b5f1 Merge remote-tracking branch 'origin/main' into integration-batch-20
# Conflicts:
#	crates/ui-egui/src/prefs/prefs_ui/fields.rs
2026-11-06 19:01:38 +01:00
David MannandClaude Opus 5.5 af0ae88bad Batch: drop #9876 (New Guide unit dropdown) from the batch
The reference application's New Guide dialog has Orientation, Position
(a text field that takes typed units such as "2 cm") and Color, but no
unit dropdown; measured on 2026-11-06. Typed units already work on main,
so the PR only adds something the reference lacks.

This reverts merge 22e03d0bcb.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-06 18:54:34 +01:00
2ff8f419cb ci: run the GPU tests on lavapipe on Linux and fail if they skip (#7975)
The Linux runner has no GPU, so the GPU tests ran on Mesa llvmpipe over
GL, which can't render Rgba32Float: 57 GPU checks (50 GPU parity, 3
canvas, 2 adjustment preview parity, 2 effect-map recovery) returned
early and passed without comparing anything. A new step after Test
installs mesa-vulkan-drivers and runs the nextest `gpu` group on
lavapipe (Vulkan), reusing Test's build, and fails unless the parity
tests report the Vulkan backend and no test printed a skip.

No code change: photocraft's tests take whatever adapter wgpu returns,
software adapters included. Follows the CI half of lightcraft#1148.

Co-authored-by: FredApps <FredApps@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-06 18:44:13 +01:00
f23d173933 Add an opt-in WinTab backend for pen pressure on Windows (#11331)
* Add an opt-in WinTab backend for pen pressure on Windows

Windows Ink stays the default. Preferences > Tools > Pen Tablet has a Tablet
input dropdown (Windows Ink (default) / WinTab). WinTab opens a WinTab 1.4
system context on PhotoCraft's window and polls pressure and the eraser end
(tilt on devices that report orientation axes; rotation only with a pen and
driver that report twist) into the stylus feed. The row says to turn Windows
Ink off in the tablet's software utility; the choice applies at next launch.

- crates/tablet: Windows-only wintab/wintab-sys backend. Devices with
  orientation axes use the orientation packet; pressure-only devices open a
  packet without it and report neutral tilt. Leaving is the driver's hardware
  proximity message (WT_PROXIMITY) and the packet's out-of-context status, with
  a long fallback for drivers that never report either. Overlap priority
  follows window focus, and the message hook requests a frame for each WinTab
  message so pressure-only strokes update without cursor movement.
- apps/photocraft: install the backend when the preference is on; poll it at
  the start of each frame; the installed wake repaints the UI.
- ui-egui: TabletPollFn service; the Windows-only Pen Tablet row with the
  Tablet input dropdown and the note.
- engine: tools.tabletInput (windowsInk/winTab), default windowsInk.
- docs: hardware-parity WinTab gap entry, qualifying tilt to orientation axes
  and rotation to twist-reporting pens.

Tested locally on a Wacom tablet with Windows Ink off: pressure, tilt and the
eraser end reach the brush (rotation where the pen reports twist); the default
path is unchanged.

* WinTab: a message that finds the state borrowed is skipped, not a panic in the hook

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* WinTab: rustfmt

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Scorecard: count the Tablet input setting

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: FredApps <153173854+FredApps@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-06 18:39:40 +01:00
FredApps d2ce418bb3 Merge pull request #11641 from wanikhawar/claude/agitated-jones-8e1a8e
A little free memory no longer refuses every PSD; the refusal says what to do
2026-11-06 18:36:17 +01:00
812b25fa10 Batch fix-up: CodeRabbit findings on #11249, #11541 and #9862
- #11249: a recorded Blend If Set that also carries real layer effects (a
  Lefx with more than the scale) stays the recorded step instead of playing
  and saving back without the effects.
- #11541: the toolbar "..." flyout owns Escape, so Escape with it open no
  longer deselects or leaves full screen; a failed Edit Toolbar from a left
  click on "..." reports its error in the status bar like the flyout row.
- #9862: the click-on-another-layer check uses the commit's targets (the
  link group as it is now), so a layer linked after the box opened is not
  "another layer".

Each has a test that fails without the fix.

Co-Authored-By: NaufalDzz <NaufalDzz@users.noreply.github.com>
Co-Authored-By: TrevorBrown-dev <TrevorBrown-dev@users.noreply.github.com>
Co-Authored-By: Higgs32584 <Higgs32584@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-06 18:35:38 +01:00
FredApps 91a2fd1d85 Merge pull request #11652 from wanikhawar/claude/stoic-yalow-d695ab
A scratch folder that stops answering no longer freezes the app
2026-11-06 18:28:41 +01:00
FredApps ce97bde34b Merge pull request #11628 from wanikhawar/claude/brave-wu-261567
Network scratch folders report their own free space, or say they can't
2026-11-06 18:15:40 +01:00
FredApps 71aa3eef9a Merge pull request #10164 from wanikhawar/fix/10031-web-place-steps
Web build: Place runs a slice per frame, so a large PNG no longer freezes the page
2026-11-06 18:12:11 +01:00
FredApps 1659ceb2b7 Merge pull request #11613 from wanikhawar/fix/smart-filter-dialog-seed-shadows-alias
Stop an adjustment smart filter losing settings when its dialog is confirmed
2026-11-06 18:09:40 +01:00
FredApps a81d9f9220 Merge pull request #11609 from wanikhawar/fix/smart-filter-stale-adjust-params
Stop stale settings overriding edits to adjustment smart filters
2026-11-06 18:09:27 +01:00
156cab0d6f Integration: translate the strings main added since the Thai, Tamil and Azerbaijani catalogs (#10241, #10359, #10555)
Main gained the Crop tool's "Background (default)" / "Transparent (default)"
Fill labels and the Pen tool's refused-draft messages after these catalogs were
written, and two tests require them in every catalog:
the_fill_labels_are_translated_where_the_old_label_was (az, th, ta) and
esc_ends_a_refused_draft_and_return_keeps_it (th, ta). Built from each
catalog's own terms for Background, Transparent, Default and Work Path.

Co-authored-by: Thanawatttt <89511939+Thanawatttt@users.noreply.github.com>
Co-authored-by: NewsBaba <346041388+newsbaba24x7@users.noreply.github.com>
Co-authored-by: Tamer Albayrak <56173603+Taxperia@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-06 17:52:08 +01:00
FredApps c49c1fd6fc Describe scratch settings without promising memory admission
Present the live scratch state as current configuration rather than the cause of a file's refusal. Explain that configured scratch capacity cannot override caller/build limits or replace non-spillable memory. Keep the typed error and admission policy unchanged, and add wording regressions.

Formatting and whitespace checks passed. No local build or test execution; validation awaits hosted CI.
2026-11-06 17:51:45 +01:00
FredApps d41e29a24f fix(ui): identify the active scratch directory in warnings 2026-11-06 17:51:33 +01:00
FredApps 1eba8f6c72 Bound scratch capacity test query waits 2026-11-06 17:51:32 +01:00
FredApps 96cb31b8d2 Merge commit '0a2365e925567d0b4144bd9acef673081965889d' into fix/11641-final 2026-11-06 17:51:32 +01:00
FredApps 0a2365e925 Keep rejected scratch growth queries due for retry 2026-11-06 17:50:54 +01:00
David Mann 7919429708 Merge remote-tracking branch 'origin/main' into feat/crop-task-bar-10890 2026-11-06 17:50:28 +01:00
David MannandClaude Opus 5.5 c7b5373ba8 Crop: Contextual Task Bar under the crop frame, as a reusable task-bar widget (#10890)
The Crop tool gets the reference application's contextual task bar: a small floating
bar centred 11 pt under the crop frame with a grip, the preset dropdown (the options
bar's own, so both stay in sync), Straighten, a ⋯ menu (Hide bar, Reset bar position,
Pin bar position) and, while a crop is pending, Cancel and Done. It follows the frame,
stays inside the canvas, and stays put once dragged or pinned. Window › Contextual Task
Bar (after Tools, as in the reference) shows and hides it.

The bar itself is a reusable widget (widgets/task_bar.rs): position rule, grip, ⋯ menu
and the hide/pin/place state in Panels (kept with the panel layout across restarts,
read by ui.inspect › taskBar, set by ui.set {panels}). A context supplies only its
controls and where ⋯ goes; the Crop contents are tools/crop_task_bar.rs. Generative
Expand stays out until #41.

Also: Lucide pin and rotate-ccw icons, six new strings in all 27 catalogues, parity
661/661 (FLOOR raised), control-protocol docs. Three tests about the options bar's
Ratio dropdown now hide the task bar, which shows the same dropdown.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-06 17:50:20 +01:00
RickiNano 6ddfe56705 Canvas: filter_event_before_tool's doc names the axis lock too 2026-11-06 17:49:51 +01:00
RickiNano 33afe59583 Canvas: document filter_event_before_tool 2026-11-06 17:49:37 +01:00
RickiNano 8967dbe5f3 Single-line marquee tests: the dropped piece keeps its pixels (#11368)
The two no-op drag tests now drop an unmoved floating piece at the press;
check that its pixels are still where they were, not only the selection.
2026-11-06 17:42:37 +01:00
0b775dab11 Integration: keep the Korean rows, drop the session notes (#8185)
docs/korean-translation-validation.md records one agent session's checks
against a base from October (a "root task", a correction ZIP, other apps'
string tables); it says nothing a reader of docs/ can use. The 344 rows #8185
adds on top of main's ko.tsv stay (the merge kept main's wording for the 14
keys where both differ and dropped the 3368 rows main already has).

Co-authored-by: AKY <85772856+arksky1@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-06 17:33:07 +01:00
f236f0f6a4 Integration: Thai test compiles; Tamil catalog rows, plurals and attribution (#10241, #10359)
#10241: `th.0.plural(5)` calls a function-pointer field with method syntax
(E0599), so the ui-egui test target did not build; call it as `(th.0.plural)(5)`
(CodeRabbit). Add the ATTRIBUTION.md row for th.tsv and Thai to the licence
header (review ask).

#10359, from the review asks on the PR: two rows used spaces instead of a TAB
(Layer Mask Display Options..., Proportional Lining) and two had an empty
fourth column; "Scratch: {size}" translated the placeholder, so it rendered
literally; "Zoom In (hold, drag to scrub)" was split into a second "Zoom In"
key; "Print Settings..." lost its trailing ellipsis to a space. Tamil counts
take one|other, so the 28 two-form @plural rows now use plural_one_other; the
entry moves to the end of the registry. Adds the ATTRIBUTION.md, licence and
docs/localization.md rows, and tamil_tags_plurals_and_placeholders, which fails
on the old plural rule and placeholder.

Co-authored-by: Thanawatttt <89511939+Thanawatttt@users.noreply.github.com>
Co-authored-by: NewsBaba <346041388+newsbaba24x7@users.noreply.github.com>
Co-authored-by: Tanish Manku <13985398+tanish2k09@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-06 17:32:39 +01:00