Commit Graph
397 Commits
Author SHA1 Message Date
FredApps a62b9ee217 Merge approved PhotoCraft PR #8347: Type: Roman Hanging Punctuation (trailing marks hang, don't steer the alignment)
Port behavior and regression coverage into current modules; preserve current upstream behavior.
Ported hanging punctuation into current line placement and kerning modules, preserving forced breaks, bounded edge-tip row merging, justified-last-line behavior, area exclusions and independent Roman orientation shaping; kept PSD/engine/UI regression coverage.
2026-10-29 05:22:57 +01:00
FredApps 959b41dca4 Merge approved PhotoCraft PR #9606: fix(ui): the Color panel remembers its options across restarts
Port behavior and regression coverage into current modules; preserve current upstream behavior.
Persist and restore Color panel options through the current dock/startup modules and regenerate the scorecard from current source.
2026-10-29 04:46:40 +01:00
FredApps 663c0204dd Merge approved PhotoCraft PR #8896: Select and Mask: Photoshop's full-window workspace (#7069, #8148)
Resolve moved test modules and independent catalog/workflow additions without changing behavior.
2026-10-29 03:32:04 +01:00
David MannandClaude Opus 5.5 f66f749f96 Merge main
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 22:18:30 +01:00
aiongg e2f9ae6bfb Merge main into perf/9328-slow-frames
Conflicts in perf/budgets.toml and docs/scorecard.md: both sides added perf rows (P80 here, P81 and P82 from #9942). Kept all three; scorecard regenerated with cargo xtask scorecard.
2026-10-28 20:30:50 +00:00
bd9590d060 Arabic interface language, combined from the community catalogs
Adds Arabic (ar, العربية) as an interface language. The catalog combines
the open Arabic catalogs of #2505, #4520, #4569, #5593, #5915, #6092 and
#6287: each row takes the best of their translations, with one Arabic
term per concept across the UI, and the strings added since are filled
in. Modern Standard Arabic, Western digits, the six CLDR plural forms
(zero|one|two|few|many|other).

The two tests that used ar-SA as an unsupported locale now use sw-KE, and
the direction test expects Arabic to be the one right-to-left catalog.

Co-authored-by: azizr12 <163084230+azizr12@users.noreply.github.com>
Co-authored-by: hicbest <213873494+hicbest@users.noreply.github.com>
Co-authored-by: hasan-sdaif <306196098+hasan-sdaif@users.noreply.github.com>
Co-authored-by: NibrasAz7 <34162952+NibrasAz7@users.noreply.github.com>
Co-authored-by: vfggf95565 <74471233+vfggf95565@users.noreply.github.com>
Co-authored-by: syrrevshin4202-prog <243624842+syrrevshin4202-prog@users.noreply.github.com>
Co-authored-by: test-bit-sys <336050374+test-bit-sys@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 21:22:26 +01:00
Brennan StehlingandClaude Opus 5.5 a9c26551f1 perf: add P81/P82 redraw-area rows on full-canvas layers (#9329)
Track-only rows that check they hit the whole-document-redraw path and
print the refreshed pixel count: undo of a brush dab on a 16-bit
15000x10000 full-canvas layer (reps capped at 5) and a fill of a 2 %
selection on a 24 MP full-canvas layer.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-27 23:08:30 -07:00
Brennan Stehling 00522c852e Perf: P80, app frame time for a full CPU refresh of a 24 MP document (#9328)
Track-only row, the slow-frame recorder's worst case. A 24 MP photo plus
three full-canvas blended copies (Multiply, Screen, Overlay); each sample
toggles the top copy and times one harness.step(), so every frame
recomposites all 24 MP on the CPU (the photo's tiles are never uniform,
which keeps the reduced render's one-colour shortcut out of the way).
The row errors unless each frame recorded a CPU refresh covering at least
95 % of the canvas, so it can't silently take a fast path. 10 samples.
2026-10-27 23:06:56 -07:00
Khawar Zamman Wani 4e22d214dc Merge origin/main into select-mask-workspace 2026-10-28 09:22:54 +05:30
aiongg a9e6f73ac5 Merge remote-tracking branch 'upstream/main' into HEAD 2026-10-28 02:31:52 +00:00
Brennan StehlingandClaude Opus 5.5 e43762ac0d Perf: rename P79 to the reduced composite it times (#7494)
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-27 14:38:45 -07:00
Brennan Stehling 5b057e2247 Scorecard: regenerate for the cliff rows (#7494) 2026-10-27 14:38:45 -07:00
David MannandClaude Opus 5.5 5ccb6fb723 Merge main
Conflicts with main's batch #9880:
- psd file.rs / layer.rs: #5287 (PSB by encoded size, RLE tables widened on
  promotion) against #6583's lazy reader. Main's new widening and length code
  read `.data`, which #6583 leaves empty while the bytes stay in the source;
  it now goes through `encoded()` / `encoded_len()` (also the auto-merged
  lines in `rle_widening`, `encoded_len` and `LayerRecord::write`), and the
  lazy reader sets `write_as_psb: false`. New test
  `a_lazy_psd_promotes_to_the_same_psb_as_an_eager_one`: a lazily read PSD
  writes the same PSB bytes as an eager one; it fails with a `.data` read.
- direct_select.rs / vector_ui.rs: #9321's Type Path and #6353's hidden
  Work Path both kept.
- io tests main.rs: both modules. scorecard.md regenerated (12 of 181);
  ui-parity.md and gaps.md follow it.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-27 19:49:42 +01:00
e3b2854838 Integration: font menu fix-ups after merging main (#6526)
- Character section: a style picked under a family's ">" with type layers
  selected set the layers but not the style for new type (the options bar
  did both). Pick "Inter > Thin" in Properties > Character: new type stayed
  Regular.
- Faux bold: a pointed tip moved r/sin(half its angle) along its bisector,
  uncapped (3.9 r at 30 degrees, an A apex grew a spike), and tips sharper
  than about 20 degrees did not move at all. Every tip now moves at most
  2r, continuously; inner corners (the crotch of a V) keep their exact
  miter.
- Faux bold: each point searched past runs of coincident points for its
  neighbours, O(n^2); a contour of 50 000 copies of one point took ~8 s per
  glyph. Neighbours now come from one O(n) pass over the runs.
- prefs.reset {"path":"type"} and Preferences > Type > Reset Section wiped
  the favourite fonts; they are kept now (type.favoriteFonts by name, or
  Reset All, still clear them).
- An expanded family whose own row scrolled out of view lost its style
  rows, so the list below jumped up.
- Show Similar Fonts re-sorted around each font an arrow step applied, so
  Down went back and forth between two fonts; the list now compares with
  the font current when the filter was turned on (or the menu opened).
- Docs: an uninstalled favourite is kept but not listed; FAUX_BOLD_RADIUS
  and the raster budget describe the thickened outline; the unused
  "Recent font list" rows are gone; docs/scorecard.md regenerated (the
  favourite fonts are one more setting).

Co-authored-by: D-monized <341904702+D-monized@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-27 14:52:20 +01:00
David Mann 9ca53a162a Merge remote-tracking branch 'origin/main' into HEAD
# Conflicts:
#	crates/ui-egui/src/panels.rs
#	docs/scorecard.md
2026-10-26 15:01:52 +01:00
Khawar Zamman Wani 56008a682d Merge origin/main into select-mask-workspace 2026-10-26 10:20:37 +05:30
Hector VillarrealandClaude Opus 5.5 a7b412d422 docs: regenerate the scorecard
The gate's scorecard check failed on #9606: the new remembered Color
panel option is one more preference (179). Regenerated with
`cargo xtask scorecard`.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-25 22:03:16 -06:00
Brennan Stehling 43581abc5f perf budgets: judge P25 on p95, keep P16 unenforced (#7494)
P25 broke at 299 ms once on the contended runner (2026-10-18). It now uses
the p95 metric with the same 200 ms budget; with n <= 20 the p95 rank equals
the max, so on the runner (n = 8) this has no effect until reps >= 21.
P16 stays unenforced: the new --from enforce report over the 2026-10-18..25
nightlies lists it as flaky (p95 103.7 ms on 2026-10-18).
2026-10-25 16:04:30 -07:00
Brennan Stehling 6caa8056ce scorecard: label a contended baseline and say where the regression check runs (#7494)
The 2026-10-05 baseline was recorded at load 224.9 on 14 cores; the scorecard now
says so without changing a number, shows the baseline's run count, and replaces
the claim that the nightly checks regressions with the machine class it actually
runs on.
2026-10-25 16:04:30 -07:00
VladimirPozdnyakov 516580ee07 The merge-back takes the edge tip only: two clusters, once per row, and leaves a justified paragraph's last line alone
davidmann4's round-3 review of #8347: a marks row the box had to split
out of a run folded row after row into one line running past the edge by
almost the whole run, and a row merged into a justified paragraph's last
line kept the row above's spread instead of the last-line align.

- A marks-only row steps back only while it is at most two clusters (the
  tip that hangs at the edge); a row above that already ends in a
  hangable mark takes no more.
- A justified paragraph's last row keeps its own align (centered, right
  or left): the placed clusters already carry the spread, and the merge
  only moves x1/range.end.
- hanging_marks_of_a_split_run_keep_their_breaks pins that a run keeps
  its rows and no line outgrows the box by more than two marks;
  hanging_marks_stay_off_a_justified_paragraphs_last_line pins the
  JustifyCenter/Right/All last lines. The old merged-row test now pins
  the tip (a_stepped_mark_row_keeps_its_clusters_and_glyphs_in_step).
2026-10-25 19:10:26 +03:00
David MannandClaude Opus 5.5 ac7de75007 Integration: scorecard regenerated without #4573
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-25 16:36:23 +01:00
David Mann ff479a2c01 Merge PR #9139: Rebuild the Histogram panel
# Conflicts:
#	crates/ui-egui/src/control.rs
#	docs/scorecard.md
#	docs/ui-parity.md
2026-10-25 16:11:31 +01:00
David Mann ef98aa507a Merge PR #3281: Vanishing Point: tear off planes and clone in perspective (#3280) 2026-10-25 15:57:43 +01:00
David MannandClaude Opus 5.5 53e118bec5 Integration: scorecard summary counts File compatibility rows again (#3297)
The summary row still said 9/13/5 after an earlier batch PR moved FILE-215-11 to partial,
and #3297 moves FILE-215-3 to done: scorecard/file_compat.toml now counts 10 done,
14 partial, 3 missing.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-25 15:46:30 +01:00
David Mann 7b79f70787 Merge PR #3297: Smart Filters: paint the filter mask directly, with undo (#3290)
Merged with our fix-up pr-3297-fixup (1de1e9eb58) on top of the author's head 053e1e0d03.
Conflicts resolved: channel_cmds.rs routed() keeps the PR's PAINT_IDS list plus the batch's
paint.artHistoryBrush; paint_cmds.rs Paint Bucket params keep the batch's "mode" and the PR's
"filterMask" target; docs/scorecard.md takes the batch's numbers with FILE-215-3 done.
2026-10-25 15:42:51 +01:00
David Mann d2f9aeb88d Merge PR #7203: feature: gradient paint to the shape tools, any shape can have a gradient stroke. 2026-10-25 14:29:48 +01:00
David Mann d576113233 Merge PR #3627: Mixer Brush: render mixed paint during the stroke and commit the live result
# Conflicts:
#	crates/engine/src/float_cmds.rs
2026-10-25 14:29:47 +01:00
David Mann b28073389c Merge PR #3316: Add intermediate UI scale presets between 100% and 125%
# Conflicts:
#	contributors/people.toml
#	docs/gaps.md
#	docs/scorecard.md
#	docs/ui-parity.md
2026-10-25 14:27:10 +01:00
096ad5b194 Integration: merge main, resolve conflicts (#7203)
Main moved the shape options bar and paint swatch out of vector_ui.rs into
shape_options.rs and shape_paint_ui.rs (#5452). Carry the PR's gradient paint
over: PaintChange::Gradient, paint_param and the swatch's Gradient tab live in
shape_paint_ui.rs, the tool gradients and set_tool_paint in shape_options.rs,
and shape_gradient_ui.rs is its own module. Both sides' new tests are kept.

Co-authored-by: Denis <179751626+deniskhud@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-25 13:26:26 +01:00
a222c2aee4 Integration: Calibration keeps the Camera Raw preview on the CPU develop (#5128, #6923)
#6923 develops the Camera Raw dialog's preview on the GPU whenever no spatial stage is set,
from `per_pixel`'s stages. #5128 adds Calibration (primaries and Shadows tint) to the CPU
develop between white balance and Dehaze, which those stages don't run, so with both merged
a Calibration-only change previewed unchanged on the GPU while Open applied it. `per_pixel`
now returns None when Calibration is set, so the dialog develops on the CPU then. The
white and black points stay as they were, so the dialog's points cache is still right once
Calibration goes back to neutral. The hardware parity doc and BUG-204-3's note now say so.

Co-authored-by: Fabio Lissi <3223836+FabioLissi@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-25 13:12:57 +01:00
David Mann 7eec69f8f5 Merge PR #5128: Camera Raw: Calibration panel, Auto, raw sidecars and live Camera Raw Defaults (FILE-215-11)
# Conflicts:
#	crates/engine/src/prefs.rs
#	docs/gaps.md
#	docs/scorecard.md
2026-10-25 13:07:14 +01:00
fab7d9739e Integration: keep foreign raw sidecars, develop before the workflow conversion (#5128)
Open wrote PhotoCraft's crs: subset over any existing sidecar, on by
default: a Lightroom or Bridge IMG_0001.xmp lost its crop, masks, rating
and keywords, even when the raw was only opened with Open in Camera Raw
off (FredApps' review). Now a sidecar is only written when the settings
changed, never over one whose x:xmptk isn't PhotoCraft's (a notice says
it was kept, camera_raw_xmp::is_photocraft_xmp), and never for a control
or MCP request, which has no authority to write beside the user's files.
A write error goes to a notice instead of a status line the develop
overwrote at once.

The Camera Raw Defaults' colour space, 8-bit and smart-object steps ran
before the Camera Raw step, so with the default Adobe RGB every raw opened
with the dialog's settings applied to other pixels than it previewed. They
now follow the step (also when a background re-develop lands), as
Camera Raw converts to the workflow space last. Main already sets the raw
resolution at import (#7811), so the PR's Image Size step is dropped.

Two raws opened back to back with raw-stage edits: the second one's
background re-develop replaced the first one's pending entry, so the first
never got its Camera Raw step, conversions or unmodified mark. Pending
re-develops are now a list keyed by job. Sidecars are read only from
regular files of at most MAX_XMP_BYTES (a pipe or a huge file named
IMG.xmp no longer blocks or fills memory), and a conversion that fails
after the Camera Raw step is reported instead of leaving the dialog open
for a second Open that would apply the step twice.

Tests: a_foreign_sidecar_is_never_overwritten,
a_rating_only_sidecar_is_left_alone,
opening_without_the_dialog_does_not_rewrite_the_sidecar,
a_control_request_never_writes_the_sidecar,
a_sidecar_write_error_stays_reported,
the_camera_raw_step_runs_before_the_workflow_conversion (inline and
background), two_raws_opened_back_to_back_both_finish_their_open,
sidecars_are_read_from_small_regular_files_only,
is_photocraft_xmp_reads_the_toolkit_marker; the existing
sidecar round trip now uses a PhotoCraft-written fixture.

Co-authored-by: Fabio Lissi <3223836+FabioLissi@users.noreply.github.com>
Co-authored-by: FredApps <153173854+FredApps@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-25 13:03:14 +01:00
David MannandClaude Opus 5.5 2415c6979f Integration: merge main, resolve conflicts (#3627)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-25 13:00:08 +01:00
David Mann aee5dac19f Merge PR #8658: fix(xtask): derive scorecard corpus counts from pinned manifests
# Conflicts:
#	docs/scorecard.md
2026-10-25 12:49:14 +01:00
David MannandClaude Opus 5.5 a60b72483e Integration: merge main, resolve conflicts (#8658)
docs/file-format-parity.md: main's PSD row with the round-trip count
258/258. docs/scorecard.md: regenerated with `cargo xtask scorecard`.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-25 12:46:18 +01:00
David Mann 75e2ce844c Merge PR #8175: PSD: type on a path opens on its path and saves back into the file's Txt2 (#7962) 2026-10-25 12:40:11 +01:00
David MannandClaude Opus 5.5 cfb5812fb9 Integration: merge main (#8175)
Resolves the conflicts with main's area type (TextShape::Area): EngineData keeps main's area arm beside the path comment, and a Txt2 frame of an area layer becomes a text box over the path's bounds, as its EngineData describes it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-25 12:14:17 +01:00
David Mann 6d0ab91536 Merge PR #4097: Integrations: wire Allow Agent Control and Control Port (#204)
# Conflicts:
#	docs/scorecard.md
2026-10-25 12:10:21 +01:00
David Mann f85ff03a26 Merge PR #1610: Art History Brush in the Y-group flyout
# Conflicts:
#	crates/ui-egui/src/retouch_ui.rs
#	docs/brush-parity.md
2026-10-25 12:03:30 +01:00
David Mann 8fd157afef Integration: merge main, resolve conflicts (#4097)
docs/scorecard.md regenerated with cargo xtask scorecard.
2026-10-25 11:15:07 +01:00
David MannMatt Van HornFredAppscoderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>Claude Opus 5.5
ce6b831c03 Integration: Art History Brush tolerance, source window, History source (#1610)
- Tolerance defaulted to 50 and averaged alpha into the difference, so an
  ordinary edit (e.g. #c03030 -> #d04848) was never painted back, and a stroke
  that wrote nothing still left an empty History step. Photoshop's default is
  0; the difference is now the larger of the mean colour change and the
  alpha change (the Eraser keeps colour and lowers alpha), and a stroke that
  writes nothing is an error instead of an empty step.
- Each tile copied a source window of tile +- halo per dab: a leftward stroke
  or a curl across x = 64 read empty pixels there (seam), and a size-1000 click
  copied ~5e9 floats (11.9 s). The rotated read stays inside the dab, so it now
  samples the source directly; bilinear reads at pixel centres, so an
  unrotated dab copies the history pixel instead of a 2x2 blend.
- The brush used its own history lookup (state 0 by default): it now takes
  the History Brush's source (history.setSource, snapshots, refusal after a
  canvas size change).
- TOOL-213-20 is partial (8 of 10 styles, Area scales spacing); docs follow.

Co-authored-by: Matt Van Horn <455140+mvanhorn@users.noreply.github.com>
Co-authored-by: FredApps <153173854+FredApps@users.noreply.github.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-25 11:11:50 +01:00
David Mann acd7e07252 Merge PR #4573: Interface: Animation Effects follows the system setting, or is on or off
Conflicts with #5547 (Animated Zoom) resolved in wheel_nav.rs, canvas.rs and
panels.rs: the Navigator and canvas pass both Animated Zoom and
!animations_off; with Animation Effects off, the sideways part of an
animated wheel zoom pans by the frame's own events folded by their
modifiers (#4573's unsmoothed scroll) instead of the plain-event raw.x,
so Ctrl + wheel still pans sideways there. #4573's modifier test runs
with Animated Zoom off and on.
2026-10-25 10:30:00 +01:00
David MannandClaude Opus 5.5 d73c91133b Integration: merge main, resolve conflicts (#1610)
Translation catalogs keep main's strings plus the Art History Brush ones
(fr: main already has Area; hi: added the brush strings). docs/scorecard.md
regenerated.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-25 10:19:42 +01:00
David Mann ed401d5321 Merge PR #5478: Blend mode keys: Shift+Alt+letter picks a mode, as in Photoshop
# Conflicts:
#	docs/ui-parity.md
2026-10-25 10:15:19 +01:00
David Mann e6cf04cf42 Merge PR #7873: perf(photomerge): track multiband timing and peak memory
# Conflicts:
#	docs/scorecard.md
#	perf/budgets.toml
2026-10-25 10:15:10 +01:00
VladimirPozdnyakov 352a633611 Address the follow-up review; merge upstream/main
- Photoshop's documented hang list carries weights: period, comma, quote,
  apostrophe and hyphen hang 100%, colon, semicolon, ellipsis and dash hang
  50%; ! and ? are not in the list (davidmann4). The drawn positions never
  change: the weights only come out of the composed width.
- A marks-only row after a forced break keeps its row: the merge-back must
  not cross the author's break (CodeRabbit).
- The merge-back reads its pair style from the mapped byte; the box slack
  and the justify-all path take the shaped advance scaled once and the
  (already scaled) trim on top, so horizontal scale no longer scales the
  trim twice; area type keeps its planned rows (hanging applies to point
  and box lines only).
- The Styles editor row label goes through tl!, the dock comment loses its
  (#...), space-before keeps upstream's arrow order, tests get abs() and
  exact centering assertions; hi.tsv carries the label.
2026-10-24 22:30:30 +03:00
squirrelnoobandClaude Opus 5.5 3eebdec501 Merge upstream/main into feat/histogram-panel-parity
Conflicts resolved by keeping both sides:
- ui-egui control.rs: UI_SET_FIELDS has main's updatesOpen and the
  histogramPanel, histogramRange and histogramRefresh fields (42).
- automation server.rs: the ui_set description names all of them.
- docs/ui-parity.md: main's header, with the Histogram panel entry
  added to its change list.
- docs/scorecard.md: regenerated with `cargo xtask scorecard`.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-24 16:41:46 +03:00
squirrelnoobandClaude Opus 5.5 049abb7d42 Histogram panel: views, channels, statistics, source, Uncached Refresh and live preview
- Compact, Expanded and All Channels views; the channel is kept across views.
- Channels per colour mode, plus Luminosity and Colors (overlaid, mixed where
  channels overlap); Show Channels in Color and Show Statistics in the panel menu.
- Statistics for the level under the pointer or a dragged range: Mean, Std Dev,
  Median, Pixels, Level, Count, Percentile, Cache Level.
- Source (Entire Image, Selected Layer, Adjustment Composite) for multilayer
  documents.
- Adjustment previews counted live, with the original outlined over them.
- Cached-data warning and Uncached Refresh; Preferences > Performance > Cache
  Levels (1-8) caps the cache level.
- ui.set histogramPanel / histogramRange / histogramRefresh, ui.inspect histogram.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-24 16:41:46 +03:00
vangel76andClaude Sonnet 5.5 47fa9fa3a5 Keep TOOL-214-14 partial and regenerate docs/scorecard.md
The row's own note says the window's Marquee tool and the Stamp's Heal modes
are still missing, so it stays partial; the scorecard is regenerated to match.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-24 14:32:41 +02:00
vangel76 053e1e0d03 Merge upstream/main into fix/3290-filter-mask-paint 2026-10-24 14:24:45 +02:00