Commit Graph
77 Commits
Author SHA1 Message Date
FinnNkandClaude Opus 5.5 159fe710a2 feat(guides): New Guide Layout takes lengths with units (#8719)
* feat(guides): New Guide Layout takes lengths with units

view.newGuideLayout took pixels only. Its widths, gutters and margins now
also take text with a unit as typed in Photoshop's dialog ("1 cm",
"0.25in", "12 pt", "3pc", "10%"), at the document's resolution; percent
is of the target's width for columns, gutters and left/right margins and
of its height for rows and top/bottom margins, per artboard. The dialog's
Width and Height fields already pass such text through, so they accept
units now too.

Part of #4984

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

* test(guides): New Guide Layout percent resolves per selected artboard

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

* test(guides): assert the full guide lists after a selected-artboard layout

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

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-23 17:40:06 -04:00
ZFzuofeng 13e4d8ceed fix(engine): select files correctly in Windows Explorer (#8518) 2026-10-23 17:39:08 -04:00
81925d7769 Integration: Raw Defaults resolution on Revert, Batch, Stack, headless open and CLI convert (#7811)
The resolution preference reached File › Open, but the other ways a raw
becomes a document of its own still opened it at 72 ppi: File › Revert
(a raw opened at 240 dropped to 72), Batch / Image Processor / Lens
Correction batch (a raw saved as PSD came out at 72 while Open + Save
gave 240), Load Files into Stack, the headless MCP `doc.open`, and the
CLI (`convert` at 72 while `run`/`info`, which open headless, now take
the default 300). They now apply the same `raw_defaults` rule; Batch
passes the user's value into its scratch sessions.

Tests that fail without this change (72 vs 240/300):
revert_batch_and_stack_open_a_raw_at_the_raw_defaults_resolution
(engine, one assertion per path), doc_open_gives_a_raw_the_raw_defaults_resolution
(automation), convert_opens_a_raw_at_the_raw_defaults_resolution (CLI).

Co-authored-by: Korg1ch <57859048+Korg1ch@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-22 15:42:42 +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 1dc684a2b6 Integration: track t09
# Conflicts:
#	contributors/people.toml
#	crates/engine/src/atn_cmds/tests.rs
#	crates/engine/src/file_cmds.rs
#	crates/engine/src/jobs.rs
#	docs/gaps.md
#	docs/target-app-parity.md
2026-10-22 15:38:26 +00:00
aiongg 4d1b922ddf Integration: track t02
# Conflicts:
#	contributors/people.toml
#	crates/engine/src/file_cmds/tests.rs
#	crates/engine/src/print_cmds/tests.rs
#	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
2026-10-22 15:38:14 +00:00
aiongg 0e80156397 Integration: track t16
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.
2026-10-22 15:38:13 +00: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 8df0e70e3e Merge PR #8168: File names: keep Windows device names (nul, con, com1...) off the disk
crates/engine/src/file_cmds/tests.rs: tests appended by both sides; kept both whole.
2026-10-22 02:23:46 +00:00
aiongg f443de8cc4 Merge PR #6841: fix(file): treat zero or negative width/height as unconstrained in fitImage 2026-10-22 02:23:13 +00:00
aiongg 5b08c0ce79 Merge PR #7811: Preferences › Raw Defaults › Resolution: a developed raw opens at it (#7789)
docs/scorecard.md: ours (regenerated at combine).
2026-10-22 02:22:53 +00:00
aiongg 2121cfecd0 Integration: #7665 the near-one-second exposure test expects three significant digits
Main's test expected 0.996 s to print as "1 s" (two decimals); the PR prints three significant digits, so it reads "0.996 s". Still never "1/1 s".
2026-10-22 02:22:26 +00:00
aiongg e1492a75f4 Merge PR #7665: File Info: print a slow shutter speed as the fraction a camera writes
crates/engine/src/file_cmds.rs: exposure_text kept the PR's fraction rule and main's guard against "1/1 s" (n > 1.0 for exposures from 0.1 s to 1 s); the main test for it still holds.
2026-10-22 02:22:19 +00:00
aiongg 2bf3e4e0be Merge PR #5470: feat(tiff): a tiffCompression option for scripted TIFF saves
crates/engine/src/file_cmds/tests.rs: both sides' appended tests kept whole.
docs/file-format-parity.md: header line keeps ours plus the PR's change item, date 2026-10-18; TIFF row has both notes; change-log rows kept both, newest first.
2026-10-22 02:22:15 +00:00
jonathanwxh-cell e7bf017502 Merge main into batch save-point fix, retaining both regression suites 2026-10-22 07:47:27 +08:00
aiongg f32f882f3a Merge main into integration-10
# Conflicts:
#	apps/photocraft-web/src/web.rs
#	apps/photocraft/src/services.rs
#	crates/engine/src/file_cmds/tests.rs
#	crates/engine/src/float_cmds.rs
#	crates/engine/src/float_cmds/tests.rs
#	xtask/src/corpus.rs
#	xtask/src/corpus_pins.rs
#	xtask/src/main.rs
2026-10-21 21:56:26 +00:00
aiongg f0137c6ace Merge PR #7963: Fix File Info showing 1/1 s for exposures just under one second 2026-10-21 21:55:49 +00:00
skylar taylor-barrick 6d8cbac7dc Merge pull request #2945 from diegochagas/feat/xcf-read
Open GIMP XCF files: layers, groups, masks, blend modes, channels and selection
2026-10-21 14:35:32 -06:00
Diego Chagas ca18689304 Open GIMP XCF files: layers, groups, masks, modes, channels and selection (#1076)
PhotoCraft reads GIMP's .xcf (and .xcf.gz) files, read only, through a new
reader in photocraft-io written from the public XCF specification: versions
0 to 26, uncompressed, RLE and zlib tiles, 8/16/32-bit integer and
16/32/64-bit float precisions (linear precisions get a linear profile),
pixel layers at any position, groups by item path with pass-through,
layer masks applied or disabled, opacity, visibility, locks, colour tags,
the 2.10 and legacy blend modes mapped to Photoshop's (modes without an
equivalent open as Normal with a note), the ICC profile, resolution,
guides, the comment, extra channels and the saved selection; indexed
images open as RGB. Text, vector and link layers open as their pixels;
layer effects, paths and floating selections are reported.

Fixtures are written by GIMP 3.2 itself (scripts/xcf_fixtures.py), each
with GIMP's merged rendering as a PNG. In gamma-encoded blend and
composite spaces our composite matches GIMP within 0.5/255; GIMP's
linear-light default, its Clip to backdrop and its clamp-after-alpha
for unbounded modes are documented and measured in docs/xcf.md.
2026-10-21 16:57:22 -03: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
Korg1ch 01784f104f test(raw): a developed raw takes the Raw Defaults resolution on every open path; other files keep theirs (#7789) 2026-10-21 18:28:11 +03:00
jonathanwxh-cellandClaude Opus 5.5 171f612337 Keep Batch results when the action saves and then closes the document
Batch dropped recorded Save / Save As / Save a Copy steps and saved the
active document after the whole action, so "..., Save As, Close" failed on
every file, and a Close that left another document active saved that one
instead. Treat a recorded save as marking the result (Photoshop's "Override
Action 'Save As' Commands"): write the document as the save found it when it
is closed or another document is active at the end, else save it after the
action as before (#3058). Droplets keep the save steps too.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-21 20:38:27 +08:00
Eddi Andree Salazar MatosandClaude Opus 5.5 196238fe95 File names: superscript COM/LPT ports, and _ before the dot in web exports
Review follow-ups:

- Windows also reserves COM¹–COM³ and LPT¹–LPT³ (the ISO 8859-1
  superscript digits), with any extension. `is_windows_device_name`
  takes them too; `sanitize` keeps those characters, so `COM¹` became a
  device file name before.
- Save for Web's `portable_generated_stem` added `_` at the end, so
  `path: nul.v2.png` gave `nul.v2_.html`, still the NUL device, and the
  export failed as an unsafe component. Both it and `sanitize` now share
  `portable_device_name`, which puts `_` before the first dot.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-21 01:29:31 -05:00
Eddi Andree Salazar MatosandClaude Opus 5.5 7c0d307293 File names: keep Windows device names (nul, con, com1…) off the disk
File › Package named its folder and document after the document with
`file_cmds::sanitize`, which let Windows device names through. On
Windows 11 a document named `nul` failed to package with "path not
found (os error 3)"; on Windows 10 `con`, `prn`, `aux`, `comN` and
`lptN` are devices too.

`sanitize` now adds `_` before the first dot of a device name
(`nul` -> `nul_`, `com1.v2` -> `com1_.v2`) on every platform, so a
package written anywhere can be copied to Windows. The device check
moves from web_cmds.rs to `file_cmds::is_windows_device_name`, and
web_cmds uses it unchanged.

The new package test fails on Windows without the fix.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-21 01:02:05 -05:00
aiongg cb8bea1636 Merge PR #7044: Conditional Mode Change: "gray" as a single source mode matches Grayscale (#7042)
# Conflicts:
#	crates/engine/src/file_cmds/tests.rs
2026-10-21 05:04:04 +00:00
aiongg dd8770f96d Merge PR #6767: Fit Image: a width or height of 0 leaves that side unconstrained (#6766) 2026-10-21 01:06:15 +00:00
Higgs32584andClaude Opus 5.5 5eac93bf23 Merge upstream/main into revive/4330-jpeg-options
Main moved on (integration batch #8095 and others). Two conflicts:
- docs/gaps.md revision history: both rows kept, newest first.
- docs/scorecard.md (generated): main's version taken. It needs
  `cargo xtask scorecard` again: with FILE-215-19 done, File
  compatibility reads 8 done / 5 missing rather than main's 7 / 6.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-20 20:47:00 -04:00
Higgs32584andClaude Opus 5.5 92d1ff42f9 Merge upstream/main into revive/4330-jpeg-options
Main added DDS saving (#5993): DDS Options, and FormatChoices carrying the
Targa and DDS answers through every save path (this branch's SaveChoices
carried Targa and JPEG). Resolved by keeping main's name and making it
the one struct for all three answers.

- lib.rs: FormatChoices { tga_bits, dds, jpeg } with from_params (strict),
  from_step (lenient JPEG read of a recorded step), apply and record;
  main's separate block is folded in. Both prompts (dds_options and
  jpeg_options) are kept everywhere: save_to asks Targa, then DDS, then
  JPEG Options; save_options_open covers all four. save_in_place takes
  main's (path, choices) signature and records the plain-Save step with
  plain_save_step for JPEG plus the Targa/DDS answers (save_in_place_with
  folded into it). journal_as_plain_save relabels a parked Targa, DDS or
  JPEG prompt and keeps tgaBits/dds*/quality/jpegFormat when dropping the
  path. replay_save reads choices with from_step.
- SAVE_OPTIONS_OPEN names all four prompts; DDS Options uses it too.
- targa_options_ui: main's plain-Save step (no path) through this
  branch's write_answered_save. JPEG Options gets main's Enter-on-a-
  focused-Cancel fix.
- view_cmds Save a Copy asks Targa, DDS, then JPEG Options; write_copy
  takes FormatChoices.
- control.rs: both app.save tests (JPEG and DDS) kept.
- engine file_cmds: SaveOpts keeps jpeg_format and dds; param docs list
  both jpegFormat and ddsCompression/ddsMipmaps. CLI: both --jpeg-format
  and --dds-compression/--dds-mipmaps. codecs re-exports JpegFormat and
  DdsCompression/DdsOptions.
- docs/book: both entries kept (control-protocol app.save lists both).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-20 20:43:26 -04:00
aiongg 6265d67de9 Integration: naming templates and more read-only formats use same_format, for #5857
With a naming template, Format Same still took the raw extension (IMG_0001_001.dng: unknown file format). HEIC, SVG, Cineon, PCX and XPM open but have no writer, so they save as PSD too; DDS has a writer and keeps its format.
2026-10-20 22:07:10 +00:00
aiongg f5c2f2091e Merge PR #5857: Batch: Format "Same" saves camera raws as PSD instead of failing (#5799) 2026-10-20 22:07:10 +00:00
Finn Newick 15029dfcee Merge remote-tracking branch 'origin/main' into fix/tiff-alpha-compression
# Conflicts:
#	apps/photocraft-cli/src/lib.rs
#	crates/engine/src/file_cmds.rs
#	docs/file-format-parity.md
2026-10-20 18:20:08 +01:00
Guillem Hermida 872748fb5b Codecs: save DDS textures, uncompressed or BC1–BC3, with optional mipmaps (#1327) (#5993)
DDS textures can now be saved, not just opened: uncompressed (BGRA, BGRX, L8, A8L8; lossless) or BC1/BC2/BC3 (DXT1/3/5) from a clean-room block encoder, with an optional box-filtered mip chain, in the legacy header. Save As and Save a Copy ask with DDS Options; scripts pass `ddsCompression`/`ddsMipmaps` (file commands, control `app.save`, RPC `doc.save`, MCP `doc_save`/`doc_export`), and the CLI takes `--dds-compression`/`--dds-mipmaps`. Targa and DDS answers travel together as `FormatChoices` through the Save As flow.

Review follow-ups:
- File › Save behind DDS or Targa Options records a plain Save with its answer, and replaying `file.save` applies it (#3531).
- The block encoder finds the principal axis from every channel, so a channel that varies on its own can't hide the others' variation.
- DDS joins the shared round-trip suite; the header is built before the output buffer is allocated.
- Enter on a focused Cancel in DDS, Targa or TIFF Options cancels instead of saving.
2026-10-20 11:02:39 -06:00
NetterSilverandClaude Haiku 5.5 ff2db1b83b Fix File Info showing 1/1 s for exposures just under one second
Found while testing crates/engine/src/file_cmds.rs:768

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-20 14:21:14 +02:00
e647e102f3 Save As JPEG: JPEG Options dialog (quality 0–12, Baseline / Optimized / Progressive) (FILE-215-19)
Save As and Save a Copy to a JPEG now ask for JPEG Options before writing,
as Photoshop does. Re-creates #4330 on current main and folds in the
unique parts of #5580 (#5563).

- codecs: `JpegFormat` (Baseline, Optimized, Progressive) on
  `EncodeOptions`. Progressive writes SOF2. Baseline Optimized fits the
  Huffman tables only at 4:4:4 (Gray, CMYK) or with Progressive: fitted
  tables make the baseline scans non-interleaved, which zune-jpeg 0.5.15
  decodes wrongly with 4:2:0 chroma (zune-image#419), as Save for Web
  already works around.
- engine: a `jpegFormat` save param (file.saveACopy, Batch, Image
  Processor, Layers to Files and every SaveOpts user; anything but the
  three names is BadParams before writing) and a shared 0–12 -> 1–100
  `jpeg_quality()` that maps NaN/inf to 100.
- ui-egui: `jpeg_options_ui` (Quality 0–12 with Low/Medium/High/Maximum
  presets, Format Options), parked like Targa Options. It starts at the
  opened JPEG's own quality (`file_encoding`, #4032), else the Export
  preference; left there, OK writes that quality exactly and the step
  records no `quality`. `SaveChoices` (Targa bits + JPEG) replaces the
  bare `tga_bits` through file.save / file.saveAs / app.save, replay and
  Save a Copy; automation never prompts. `write_answered_save` is shared
  with Targa Options. `park_at` + `Start` let any save seed the prompt.
  A File › Save that confirms the document's own flat JPEG is still
  journalled as a plain `file.save` (#3531).
- CLI: `--jpeg-format`.
- i18n: five new strings in all 20 catalogs (#4330's duplicate de/es/zh
  `Low`/`High` rows dropped: main has them since #4008).
- Docs: book raster-formats JPEG bullet, control protocol, file-format
  parity, gaps G10, target-app parity; scorecard FILE-215-19 done.

Co-authored-by: SckraT <70698629+SckraT@users.noreply.github.com>
Co-authored-by: PierrunoYT <95778421+PierrunoYT@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 20:28:38 -04:00
Michael Higgins b05b641122 Merge branch 'storytold:main' into fix/5799-batch-same-format-raw 2026-10-19 19:34:48 -04:00
Finn Newick 9d95f13a9d Merge remote-tracking branch 'origin/main' into fix/tiff-alpha-compression
# Conflicts:
#	docs/file-format-parity.md
2026-10-19 18:14:36 +01:00
David MannandClaude Opus 5.5 bc4f2a783d Scripts: Flatten All Layer Effects bakes with the document's Global Light and patterns (#5719) (#5720)
`bake` rendered each layer through `render_layer`, which has no document context (default Global
Light, no patterns, the render rect as canvas). It now uses the new doc-aware `render_layer_in`.

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-19 13:04:46 -04:00
Ashsajal be9f0c250a File Info: print a slow shutter speed as the fraction a camera writes (#6958)
The `1/n s` test in `exposure_text` was relative to the reciprocal, so the
tolerance shrank as the exposure slowed. Under 1/50 s the reciprocal drops
below 50, which makes 1 % of it smaller than half a rounding step, and nearly
every fraction fell through to the decimal form: a stored 0.031714 s printed
as "0.03 s" (5.4 % off) and 0.0215 s as "0.02 s" (7 % off).

Below 1/10 s the reciprocal is above 10, so its nearest whole number puts the
shown time within 5 % of the stored one and is the form a photographer
expects. At or above 1/10 s the existing near-whole rule is kept, so 0.5 s is
still "1/2 s" and 0.4 s still "0.4 s". The decimal fallback moves from two
decimals to three significant digits ("0.105 s", not "0.11 s").

The two fixtures from the report now read "1/32 s" and "1/47 s" through
`photocraft-cli run ... --cmd file.fileInfo`.
2026-10-19 12:35:45 +06:00
Finn NewickandClaude Opus 5.5 9a167b2e88 test(engine): a refused tiffCompression leaves the document as it was
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-18 22:19:29 +01:00
Khawar Zamman WaniandClaude Opus 5.5 502d055c6c file.saveACopy refuses the document's own file without "overwrite" (#7437) (#7456)
* file.saveACopy refuses the document's own file without "overwrite" (#7437)

Save a Copy through the engine (control channel, MCP, serve, headless
action playback) silently replaced the open document's own file when
given its path, so a lossy re-encode could not be undone. It now returns
BadParams when `path` is the active document's file (same text, ./ or ..
spelling, hard link, case on Windows via same_file) unless the params
pass "overwrite": true, and nothing is written. The desktop dialog writes
through the shell after the OS confirms a replace, so it is unchanged.

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

* same_file: compare file identity on Windows, so a hard link is the same file

On Windows `same_file` compared canonical path strings, so a hard link to
the input (another name for the same file) passed the new convert guard
without --in-place. It now compares the volume serial number and file index
(the `same-file` crate, already in the dependency tree; std's file_index is
unstable), as unix compares dev and inode, falling back to the
case-insensitive canonical path when a file won't open. The engine's
same_file test now checks hard links on every platform. (Review on #7454.)

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

* saveACopy own-file test: hard link on every platform, doc state unchanged after a refusal

Each refused copy (same path, ./ spelling, hard link) now also checks the
document keeps its path, revision and unsaved state. The hard link is no
longer unix-only: same_file compares file identity on Windows too. (Review
on #7456.)

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

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-18 16:56:21 -04:00
Finn Newick 5c665ca96f Merge remote-tracking branch 'origin/main' into fix/tiff-alpha-compression
# Conflicts:
#	crates/engine/src/file_cmds.rs
2026-10-18 21:23:58 +01:00
Michael Higgins cd3ef1444f Merge branch 'main' into fix/5799-batch-same-format-raw 2026-10-18 10:16:37 -04:00
David MannandClaude Opus 5.5 cb185320ed Conditional Mode Change: "gray" as a single source mode matches Grayscale (#7042)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-17 15:44:56 +02:00
rudrakshagarwal4200-ai d24d25f5e7 Enhance fitImage tests for dimension constraints
Added tests for handling zero or negative dimensions in fitImage.
2026-10-17 04:01:18 +05:30
David MannandClaude Opus 5.5 ab81052308 Fit Image: a width or height of 0 leaves that side unconstrained (#6766)
fit_image read width/height with f64_param and clamped to 1, so a 0 or
negative side (dialogs send 0 for an empty field) became a 1 px box and
shrank the document to 1x1. It now uses size_param like the rest of
file_cmds.rs, so such a side falls back to the document's own size.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-16 22:49:38 +02:00
aionggandDavid Mann 87918a6c85 Linked smart objects: follow stored paths only to local files or the document's share
A linked smart object's path comes from the document. Every place that
follows it now goes through one resolver (photocraft_io::doc_path, built on
craft-docpath): a relative path is taken from the document's folder, and
only local files or files on the share the document itself is on are
opened. Paths to other computers, device paths and URLs are treated like a
missing file: the layer keeps its last rendering.

- Link watch: such links are not stamped, and no background look starts
  when no link of the document is followed.
- Update Modified Content and other re-renders read only followed files;
  the error names why a link is not followed.
- Package lists such links as missing instead of copying them.
- Reveal in Finder for a linked layer shows only a followed file; the
  document's own Reveal is unchanged. The macOS invocation ends options
  with `--`, and Explorer is not asked to select a path containing a comma
  or a quotation mark.
- Place Linked stores a relative path as an absolute one.

The document path travels to smart-object renders in a thread-local scope
entered by Session::edit, command dispatch and background jobs.

Co-authored-by: David Mann <daaavid.mann@gmail.com>
2026-10-16 16:53:13 +00:00
Higgs32584andClaude Opus 5.5 2750809257 Batch: Format "Same" saves camera raws as PSD instead of failing (#5799)
With Format "Same" every output took its input's extension, so a folder of
ARW/CR2/NEF/DNG files tried to write raws, which PhotoCraft can't, and every
file failed. Raws and other import-only inputs (PDN, Krita, Affinity) are now
saved as PSD; other inputs keep their format.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 18:56:28 -04:00
Finn NewickandClaude Opus 5.5 bb8fc93908 Merge remote-tracking branch 'origin/main' into fix/tiff-alpha-compression
Batch and Image Processor params keep main's includeSubfolders and this branch's tiffCompression.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 19:12:44 +01:00
aad56285ad Batch: Include All Subfolders (AUTO-219-5, #3753) (#3758)
* Batch: Include All Subfolders (AUTO-219-5, #3753)

File > Automate > Batch and File > Scripts > Image Processor take an
optional "includeSubfolders" (default false): a folder input also yields
the images in its subfolders, walked depth first in name order, bounded at
32 levels and 100000 files, with a seen-set of canonical folders against
symlink loops and the output folder left out. Each result keeps its
relative subfolder under the output folder, so same-named files in
different subfolders no longer collide. A non-boolean value is BadParams.

Both dialogs gain an "Include All Subfolders" checkbox (translated in
every complete catalog). Scorecard AUTO-219-5 stays partial (naming
template, progress/cancel, error log file); gaps.md G11 updated.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* Batch: translate Include All Subfolders for Hungarian and Turkish

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-authored-by: Brandon Thomas <echelon@gmail.com>
2026-10-14 14:08:20 -04:00
Finn NewickandClaude Opus 5.5 7fae49548d Merge remote-tracking branch 'origin/main' into fix/tiff-alpha-compression
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 09:34:37 +01:00