Commit Graph

1242 Commits

Author SHA1 Message Date
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
skylar taylor-barrick 18e2d45420 Merge pull request #6318 from robertoffmoura/fix/floating-selection-move-lag
Fix lag when dragging a floating selection with the Move tool
2026-10-21 14:25:55 -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
Roberto Moura 8352b26c1a Fix lag when dragging a floating selection with the Move tool
- Replace whole-region Vec<f32> read_region/write_region in CutParts::new
  with tile-parallel cut_piece + try_fill_surface/try_clear_surface,
  sharing interior Arc<Tile> allocations in O(1) and activating the
  solid_tile hole-fill fast path on Background and mask targets.
- Cache piece_bounds on CutParts so CutParts::place avoids scanning tile
  content bounds on every drag frame.
- Parallelize composite_over across top tiles with Rayon and share fully
  opaque top tiles by Arc<Tile> clone in O(1), preserving COW tile
  identity for GPU canvas uploads.
- Parallelize Surface::translated across target tiles with Rayon and
  prune cleared tiles in-place inside edit_tiles.
- Skip zero-offset floating preview generation on pointer-down in
  move_ui::floating_doc.
- Exclude SnapKind::Selection when moving selected pixels with the Move
  tool so small initial drags do not snap back to (0, 0).
- Keep navigator_plain active during Move/Brush/Patch drags on a GPU
  canvas so navigator_gpu is not evicted into a synchronous full-document
  CPU thumbnail composite on the first drag frame.
- Parallelize row normalization in compose::render_reduced_in_bands and
  add a direct read_rgba_into fast path for unmasked Normal layers over
  an empty backdrop.
2026-10-21 13:21:10 +00:00
aiongg c5176efd93 Integration: a scale beyond f32 range is refused, not clamped, for #7048
Main's 3f216a0cd1 rejects numeric overflow before document edits; #7048's test predates it and expected 1e39 to clamp to 150 %.
2026-10-21 05:04:04 +00: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 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 1d567a115f Merge PR #7015: Actions: deleting an action removes its function key (#7014)
# Conflicts:
#	crates/engine/src/actions_cmds.rs
2026-10-21 05:04:04 +00:00
aiongg 2a1ac6a6fb Merge PR #6208: Preferences: Save in Background off saves in the foreground (#6207)
# Conflicts:
#	docs/gaps.md
#	docs/scorecard.md
2026-10-21 05:04:04 +00:00
aiongg 050caf9ecd Merge PR #6681: Content-Aware Move: live preview for large selections (TOOL-213-4, #6680)
# Conflicts:
#	docs/gaps.md
#	docs/scorecard.md
#	docs/target-app-parity.md
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
aiongg f163e3ce0b Merge PR #6211: Zoom tool: hold to zoom continuously with Animated Zoom on (#6210)
# Conflicts:
#	docs/gaps.md
#	docs/scorecard.md
#	docs/ui-parity.md
2026-10-21 05:04:03 +00:00
aiongg fc371711e6 Merge PR #5847: Shapes: Density and Feather on shape layers (#5846)
# Conflicts:
#	docs/scorecard.md
#	docs/target-app-parity.md
#	docs/ui-parity.md
2026-10-21 05:04:03 +00:00
aiongg cd710ca898 Merge PR #5622: Filters: Lens Correction, Adaptive Wide Angle and Camera Raw Filter respect locks on smart objects (#5621)
# Conflicts:
#	crates/engine/src/lens_cmds.rs
2026-10-21 05:04:02 +00:00
aiongg 34c5e7d49e Merge PR #3536: History: set the History Brush source from the panel (history.setSource) (#2966)
# Conflicts:
#	crates/engine/src/commands.rs
#	crates/ops/src/lib.rs
2026-10-21 05:04:02 +00:00
aiongg c23a6c9b90 Merge PR #6206: Performance: a cancelled Gaussian Blur job stops within budget (#6205)
# Conflicts:
#	docs/gaps.md
2026-10-21 05:04:02 +00:00
aiongg 375c5e1517 Merge PR #7085: Actions: an imported Crop step in a unit other than pixels is not applied as pixels (#7084) 2026-10-21 05:04:02 +00:00
aiongg 3d233afd31 Merge PR #7028: Transform Selection: an unknown reference point is an error (#7027) 2026-10-21 05:04:02 +00:00
aiongg 26844944b9 Merge PR #7005: Keyboard Shortcuts: switching sets keeps action function keys (#7004) 2026-10-21 05:04:01 +00:00
aiongg 1637ae25e1 Merge PR #6805: Droplets: carry the actions that Conditional steps call (#6804) 2026-10-21 05:04:01 +00:00
aiongg 9d5bf2a82c Merge PR #6773: Actions: renaming an action updates the Conditional steps that call it (#6772) 2026-10-21 05:04:01 +00:00
aiongg dc8b8834e0 Merge PR #5889: Image: Bitmap dialog with Output resolution and per-method settings (#5559) 2026-10-21 05:04:01 +00:00
aiongg 40895532aa Merge PR #5840: Export As: Resample menu, incl. Nearest Neighbor (#5838)
# Conflicts:
#	docs/scorecard.md
2026-10-21 05:04:01 +00:00
aiongg 5ec2b90f1b Merge PR #7771: Save for Web: later slices cover earlier ones, covered slices split into pieces (#7770) 2026-10-21 05:03:49 +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 831afd2408 Merge PR #7008: Timeline: a longer duration moves a work area that reached the old end (#7006) 2026-10-21 01:06:18 +00:00
aiongg b5f48b3d7b Merge PR #6213: Tools: each painting tool's brush persists across launches; restored tool options are clamped (#6212)
# Conflicts:
#	docs/scorecard.md
2026-10-21 01:06:17 +00:00
aiongg 8c33acf7cc Merge PR #7733: Painting symmetry: canvas edits move the axis with the pixels (#7732) 2026-10-21 01:06:17 +00:00
aiongg 6c2bcd52e8 Merge PR #7079: Merge to HDR Pro and merged duplicates: the Background layer is a real Background (#7078) 2026-10-21 01:06:16 +00:00
aiongg c15c1e214e Merge PR #7766: Layer Style: a new Stroke is 1 px inside black, as in Photoshop (#7765) 2026-10-21 01:06:16 +00:00
aiongg ac11edc9ec Merge PR #7048: Layer Style: gradient overlay and stroke scale stay within 10-150 % (#7047) 2026-10-21 01:06:16 +00:00
aiongg 69954138f9 Merge PR #7001: Stamp Down keeps the lower layer's clipping, label and link (#6999) 2026-10-21 01:06:16 +00:00
aiongg 9b889e1a58 Merge PR #6640: Layers: toggling a clipped adjustment damages only its base (#6535) 2026-10-21 01:06:16 +00:00
aiongg 6172d967ae Merge PR #5784: Paint: Lock Transparency blends source-atop on semi-transparent pixels (#5783) 2026-10-21 01:06:16 +00:00
aiongg 56102a11fc Merge PR #5753: Fill layers: reject non-finite gradient angles and pattern angle/phase (#5752) 2026-10-21 01:06:16 +00:00
aiongg acdf17f858 Merge PR #5680: Layer masks: From Transparency and Mask All Objects convert the Background and match the document depth (#5679) 2026-10-21 01:06:16 +00:00
aiongg 8c942e481d Merge PR #7224: Image: Trim and merged Duplicate report an error on documents over 2^30 px (#7223) 2026-10-21 01:06:16 +00:00
aiongg 73a6dc7215 Merge PR #7125: Image Size: type keeps its pixel size when the resolution changes (#7124) 2026-10-21 01:06:15 +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
aiongg a91466ae3a Merge PR #7762: Perspective Crop: Color Sampler points move with the image (#7760) 2026-10-21 01:06:15 +00:00
aiongg 41819a01e2 Merge PR #7087: Crop / Canvas Size: extending keeps the Background's hidden pixels (#7086) 2026-10-21 01:06:14 +00:00
aiongg c92fa0a1c7 Merge PR #7723: Crop: a W x H crop on an Indexed Color document resamples with Nearest Neighbor (#7722) 2026-10-21 01:06:14 +00:00
aiongg 3807454782 Merge PR #7013: Crop: Color Samplers scale with a W x H crop (#7012) 2026-10-21 01:06:14 +00:00
aiongg ea1c6fce1f Merge PR #6781: Apply Image: write into the targeted layer mask (#6780) 2026-10-21 01:06:14 +00:00
aiongg 81c030f217 Merge PR #7003: Channels: Multichannel conversion keeps the targeted channel (#7002) 2026-10-21 01:06:14 +00:00
aiongg ab88a0e4bb Merge PR #6777: Auto-Align: warp layer masks as masks, keeping what lies outside revealed (#6776) 2026-10-21 01:06:14 +00:00
aiongg 954a7560ef Merge PR #7030: Lens Correction: smart filters keep the exact focal length (#7029) 2026-10-21 01:06:14 +00:00
aiongg b9404a6eda Merge PR #3534: History: panel menu, Step Forward/Backward and Clear History (#2966) 2026-10-21 01:06:12 +00:00
aiongg b097800e78 Merge pull request #8095 from aiongg/integration-7
Integration batch: 9 PRs on main
2026-10-20 20:44:51 -04:00