PhotoCraft changelog
Back to PhotoCraft16 releases since October 2026 · GitHub releases, checked Oct 27, 2026
0.16.0LatestBig update
- Reuse filled-shape effect maps while moving styled groups
- fix(ui-egui): a click on the bottom layer's Smart Filters selects them again
- security(paint): cap spaced steps and procedural primitives
- i18n(zh-hans): translate status messages and preview labels
- perf(liquify): reuse interpolation taps and bound render buffers
- perf(mcp): move command list rows instead of cloning
- Codecs: warn when DPX or Cineon saves drop bits
- fix(type): type.edit with new text keeps the styles of unchanged text
- perf(text): rasterise each text colour only over its own glyphs
- fix(engine): refuse partial Color Balance and Hue/Saturation ATN exports
- fix(geom): reject non-finite affine inverses
- Crop default mode: moving the image under the box snaps
- fix(engine): select files correctly in Windows Explorer
- Fix EngineData format_real emitting a bare trailing dot
- fix(app): no unused screen picker code on FreeBSD
- fix(ui): restore extras when showing the grid
- fix(text): lay out a variable font's named instance from its PostScri…
- Fix XCF import with short linked-layer property lengths
- Soft Light: dark backdrops follow Photoshop's W3C curve
- fix(actions): a recorded Layers-panel drag keeps its drop target by name
- fix(gpu): rebuild the GPU canvas after an out-of-memory error
- Layers: show effect row names through tl!
- Black & White: keep 32-bit superwhites
- feat(guides): New Guide Layout takes lengths with units
- Write the Levels and Curves composite channel as Chnl.Cmps in .atn export
- fix(cms): reject malformed hex data in .look LUTs
- Accept all-caps possessives in spell check
- Reject non-hex characters in engine hex color parser
- test(panic_hunt): give the panic-counting self-test its own deadline
- Puppet Warp pins go where they are dragged, without snapping
- test(liquify): expand freeze-boundary regression coverage
- fix(layers): keep blend mode, Opacity, locks and Fill visible but greyed with no layer selected
- fix(curves): 32-bit Curves continue past 0..1 like Photoshop
- fix(codecs): WebP export keeps the resolution
- PSD: write pattern transparency where Photoshop keeps it
- fix(ui): cap text fields and oversized text events
- fix(export): report skipped layers in doc_export_layers
- Slice tool: Style offers Fixed Ratio and Fixed Size
- Lost window device: quitting goes through while recovery can't be saved
- Fix pasted shape group bounds and effects across documents
- fix(io): preserve custom-domain Color Lookup LUTs
- i18n(tr): fix mistranslations, inconsistencies and untranslated rows
- IPP: preserve printer metadata across attribute groups
- Levels, Curves and the other adjustments: ⌥ plus the shortcut opens the dialog at its last settings
- fix(atn): keep Photoshop's other transform interpolation modes on import
- fix(contributors): drop a duplicate people.toml table
- Curves: the graph grows with the Properties panel and a resizable dialog
- Perspective Crop: the swap button swaps W and H
- Keep shape fill and stroke alpha through PSD round-trip
- Color pickers: pick on press and follow small drags
- fix(actions): match Selective Color ATN export to command parsing
- Auto-Align: a locked layer becomes the reference instead of being moved
- Paste: keep the pasted image on the canvas
- PSD smart filters: Sharpen, Dust & Scratches and Hue/Saturation stay editable
- Isolate live distortion tools per document
- fix(format): report a failed directory flush after a save instead of ignoring it
- fix(automation): release idle headless TCP server ports
- Crop: Delete Cropped Pixels keeps type and smart objects whole
- PSD: keep Photoshop 2026 Light adjustment layers verbatim and warn
- perf: skip redundant smart object resamples and per-pixel reads
- New Document: category tabs and preset cards show a pointer, not a text cursor
- Make magnetic lasso edge direction polarity-independent
- Integration batch: 44 PRs on main
- perf(camera-raw): exposure with all scopes under its 10 ms budget (P36), same output
- fix(atn): export Black & White adjustment layers with Photoshop's BanW class
- perf(gpu): layer pages that just miss the budget borrow the effect-map share, P60/P61 10× faster on integrated GPUs
- feat(styles): import and export .asl layer style libraries
- Options bar: the same tool options in every theme
- Keep adjustment clipping visible in compact Properties panels
- PSD: Distort smart filters and Invert open and save like Photoshop
- fix(gpu): catch validation errors in watched compositor work
- UI: split shape options and gradient stop helpers into reusable pieces (no behaviour change)
- Add opt-out startup release checks and manual update status
- Plug-ins: wire Enable Generator (Image Assets needs it)
- PSD smart objects: keep Photoshop's Cylinder warp when re-rendered
- perf(doc): share the XMP packet, Duotone PSD data and unsupported adjustment bytes between snapshots
- Color: a picked colour recolours the selected type and shapes
- Preferences: old settings files take Shift-to-switch-tools on
- fix(compose): prevent outside stroke from bleeding into opaque character interior
- Raw: charge the retained tile intermediates together
- Color panel: Photoshop's panel-menu modes, the same in every theme
- Fix legacy PSD point-text placement after font resolution
- feat(type): area type, text that wraps inside a closed path or shape
- Selection: ⇧ mid-drag locks a selection-tool move to the axis
- fix(engine): honor lock all on layer mask commands
- fix(ui): confirm opening damaged PSD/PSB documents
- perf(canvas): skip occluded checker on CPU textures
- Eyedropper: a large sampling ring that reads on any colour
- fix(atn): import a recorded Save As with its destination
- Gradient Overlay: add Method selector and retain editable source stops
- photocraft-cli run: refuse an --out that is the input file unless --in-place
- gpu, docs: fix timing test skip guard and document Windows ARM64 build on RTX Spark
- Menu bar: a held Alt's auto-repeat doesn't re-arm the Alt tap
- CLI: reject ignored or conflicting mcp/serve launch options
- GPU compositor: build its pipelines in parallel; DX12 startup 13.2 s -> 7.3 s (part of #6419)
- fix(automation): doc.replaceSmartObject replaces Smart Object contents from the read root
- fix(actions): strict .atn export keeps Apply Image's flat source fields
- Image Assets: optionally keep a transparent artboard's full size
- Keep the CPU canvas sharp at 100% zoom
- fix(ui-egui): expand layer visibility eye hitbox and render sunken well
- fix(actions): accept Photoshop stringID blend modes
- security(io): charge sparse layers, shape caches and shared decodes
- CMYK: Dissolve and post-adjustment rounding match the RGB compositor
- security(engine): bound script, batch, adjustment, import and export work
- Make Crystallize 4x and Pointillize 3x faster on 24 MP layers
- perf(retouch): releasing a Blur/Smudge/Dodge stroke takes its live pixels
- perf(seam): the shrink proxy drops its original-column map, same pixels (−15 % at 24 MP)
- PSD export: embed a linked file only when it is an image PhotoCraft can open
- CLI integration batch: clap for photocraft-cli and the desktop app
- refactor(cli): split photocraft-cli into modules, no behaviour change
- refactor(cli): typed errors with thiserror instead of String
- Segmentation: anti-aliasing the full-resolution mask skips runs far from its edge
- fix(cli): help after a mistake, and mcp/serve option notes in --help
- fix(ui): keep repeated Tab presses in text editing
- ui: highlight menu rows while dragging with the button held
- fix(ui): centre size-changing filter previews on the CPU canvas
- fix(ui): show a filter dialog's preview on the CPU canvas
- raster: translated surfaces share one rebuilt tile however many threads build it
- JPEG: open 12-bit and arithmetic-coded files through craft-jpeg
- security(affinity): charge archive names, failed reads, corner arrays, attachments, pages and font names
- fix(ui): Liquify, Content-Aware Fill, Filter Gallery and Adaptive Wide Angle are modal, like Camera Raw
- Autosave: a recovery listing judges each key once, so an autosave in progress isn't listed twice
- @drunkeninja42 made their first contribution in
- @IgnatAi401 made their first contribution in
- @ZFzuofeng made their first contribution in
- @hai5656a made their first contribution in
- @paulou-jpg made their first contribution in
- @MatRanc made their first contribution in
- @ronibalthazar made their first contribution in
- @batuhangozegu made their first contribution in
- @marmitoTH made their first contribution in
- @SiFuMax09 made their first contribution in
- @Arian100 made their first contribution in
- @geduful made their first contribution in
- @ZhuanTou33212 made their first contribution in
- @alvarohn made their first contribution in
- @bogusyogi made their first contribution in
- @SillySilk made their first contribution in
- @DavidBonnier made their first contribution in
- @hogawish made their first contribution in
- @ijasonwhite made their first contribution in
- @oRE-o made their first contribution in
- @mweinbach made their first contribution in
- @IbrahimOezhan made their first contribution in
- @kobaltgit made their first contribution in
- @justinjohn0306 made their first contribution in
0.15.1Big update
- fix(psd): keep pattern budget charges on parse failure
- fix(algo): avoid repeated copies of duplicate EXIF text
- fix(paint): validate gray tile dimensions safely
- fix(text): bound untrusted font and PSD text processing
- Select and Mask: tool edits as select.refineEdge params (engine, part 1 of 2)
- fix(cms): confirm ICC profile identity by bytes, not the 64-bit hash …
- fix(vector): bound hostile geometry and raster work
- fix: restrict droplet shim permissions, explain test range (SonarCloud)
- Linked files: resolve stored paths with craft-docpath's resolve_absolute
- CI: no debug info for dependencies, nextest in xtask ci, long sweeps spread over days
- security(affinity): bound shared-object expansion work and metadata
- release: the git-sources gate moves into craft-common-actions (storytold/craft-common-actions#78)
- packaging: use [[ for bash conditional tests (SonarCloud S7688)
- CI: the Linux gate runs through the suite's shared gate workflow
- security(raster,doc): tile counts, shared rebuilt tiles, slice merge index
- security(ipp): total reply deadline, resumable chunk walk
- security: bisect table/stop lookups; charge ICC curves; bound PSD/RAW buffers
- security(algo): bound working sets sized by caller-controlled extents
- security(compose): bound dense working sets and nested Blend If evaluation
- Tests: missing translations don't fail; xtask ci lists them
- security(codecs): bound truncated JPEG recovery; count WebP frame ICC copies
- security(plugins): host keys, band count, start fuel, FIFO open
- security(gpu,ui-egui): bound clipped group planning; pattern swatch sampling
- CI: cargo xtask ci is the gate, and the workflow runs it
- xtask: the panic hunt without nextest builds with the HEIF decoder
- ci(sonar): stop cancelling main-branch runs so coverage is published
- deps: roxmltree 0.21 in photocraft-io and photocraft-engine
- packaging(macos): retry stapling when Apple's ticket lookup drops
0.14.0Big update
> [!NOTE] > FreeBSD aarch64 is dropped from this release. We had to cut releases, and we cannot build this target within the 5-hour CI limit for any of the Craft apps, so we are dropping it for now. This is a known blocker, flagged for a future fix in storytold/craft-common-actions#39. FreeBSD x86_64 and every other platform are included.
- Automation: tighten workspace checks for export, linked files and dialogs
- View › Extras (Cmd+H) hides the Move tool's transform controls
- fix(raster): prevent overflow in strided row sampling
- security: index slice IDs in PSD slices parser
- security: preflight PCX and XPM allocations
- security: harden native temporary and recovery files
- security: admit embedded SVG raster images by header size
- security: stop double decompression of gzip-compressed SVG
- @mercuryVM made their first contribution in
0.13.0Big update
> [!NOTE] > FreeBSD aarch64 is dropped from this release. We had to cut releases, and we cannot build this target within the 5-hour CI limit for any of the Craft apps, so we are dropping it for now. This is a known blocker, flagged for a future fix in storytold/craft-common-actions#39. FreeBSD x86_64 and every other platform are included.
- Fix lag when dragging a floating selection with the Move tool
- Open GIMP XCF files: layers, groups, masks, blend modes, channels and selection
- Layers Panel: flyout, options and thumbnail sizes (part 1/3)
- Layers Panel: Smart Filters mask follows thumbnail size, sub-rows stay compact (part 2/3)
- Fill layers: match masks in creation and Pattern Fill preview (part 3/3)
- Integration batch: #8229, David's follow-ups and 85 FredApps-approved PRs on main
- Vanishing Point: perspective clone samples without allocating per pixel
- Actions: a background filter's step is recorded only by the recording it started in
- Camera raw: a developed raw keeps its EXIF (RW2 included), so File Info shows its Camera Data
- Displace on a Smart Object: the map is embedded in the smart filter, so it displaces
- feat(ui): search font input field sticky on scroll
- Free Transform: a result over the pixel limit says so, not "not enough memory"
- Free Transform: a result may take what Memory Usage allows, not 2^30 px
- Scale layer-effect noise by coverage so it follows the glow
- Shortcuts: Ctrl+F4 closes the document beside Ctrl+W (Windows/Linux)
- Lock Slices: Slice Select can't select a locked slice, and both slice tools say why
- Slice Select: the selected slice's handles resize it
- Filter Gallery › Halftone Pattern: a tone-keeping screen at 45°
- Smart Blur: 3.5× faster at radius 12 with identical output
- Fixed Size marquee: Width and Height in any length unit
- Light themes outline the slider knob (UI-217-11, #7927)
- Note tool: a selected note shows its author and colour in the options bar
- Actions: Emboss saves to and loads from .atn as Photoshop's Embs step
- Fix File Info showing 1/1 s for exposures just under one second
- Slice Select gets its own icon: the Slice knife with a pointer
- perf(raster): tile content bounds compare rows in blocks (P32, #211)
- Windows on ARM: auto picks DirectX 12 for Qualcomm graphics
- Open: a file without type never waits for the font scan
- automation: edit.installedProfiles is no host-path command
- fix(liquify): keep frozen pixels stable near mask boundaries
- Codecs: Fix corrupted CMYK JPEG exports
- Pencil: align 1 px click snapping with the line walker
- fix(psd): pad Gradient Map blocks
- CodeRabbit follow-ups for the #8095 batch
- PSD layer comps: an entry without enab inherits the previous visibility, as in Photoshop
- Integration batch: 8 PRs on main
- Content-Aware Move: live preview for large selections (TOOL-213-4, #6680)
- Actions that start with Deselect play on when nothing is selected
- A layer that doesn't fit in GPU memory no longer breaks GPU drawing: older pages are freed and the layer is retried
- HEIF: honour the nclx colour description; HLG/PQ HEICs open as linear BT.2020 32-bit
- test(ui): a toolbar click with no prior hover picks the tool (part of #2603)
- Background redraw: keep the last finished composites, so a solo's restore uploads instead of recompositing (part of #6528)
- Web: one press per tap, so menus open again on touch
- Shortcuts: custom bindings on PageUp/PageDown (and other multi-word keys) fire again
- Selections don't mark a document modified
- Actions: record File › Export › Export As and replay it with its settings
- Brushes: folders with search matches can be collapsed while searching
- macOS: keep the bundle's Dock icon after the window opens
- Keyboard Shortcuts: Shift is recorded when capturing a shortcut
- Freeform Pen: ⇧ constrains freehand strokes to straight 45° lines
- Color panel: RGB slider mode
- test(engine): make the define-brush mask allocation fail on its own (fail-after-one)
- Content-Aware Fill workspace: an erased sampling area previews as an error, and a failed OK keeps it open
- fix(atn): a preset-only Photo Filter step exports its resolved colour
- Auto-Blend Layers: turn the Background into a layer before masking it
- Menu bar: Alt held through a shortcut no longer takes the keyboard, so Enter reaches the dialog
- Presets: an Export As preset survives a damaged sibling set (test for #6906)
- Preserve saved PCraft previews when manifest replacement fails
- Actions: stop when a Save step's document is closed by a Save Document script
- Toolbar: colour chips stay centred when the tools scroll
- Studio: the floating Properties card has the Adjustments tab
- Flatpak: a second launch hands its files to the running PhotoCraft over a Unix socket
- Actions: Minimum / Maximum with Preserve: Roundness is no longer exported as Squareness
- Show Technique and Range in the glow Layer Style pages
- Open the selection menu on a Quick Selection right-click
- Carry on an open path from its end with the Pen
- Move typed text with a drag from just outside it
- Move tool: a selection lifts up to a pixel's own coverage
- perf(format): reuse .pcraft writers between document saves
- fix(actions): preserve effective Stroke width in ATN export
- fix(actions): refuse lossy fractional Ripple ATN export
- Painting symmetry: canvas edits move the axis with the pixels
- Actions: a Selective Color step keeps the values of its scalar form
- Perspective Crop: Color Sampler points move with the image
- Lasso: a short straight segment places a vertex instead of closing the outline
- Save for Web: later slices cover earlier ones, covered slices split into pieces
- Copy: text selected in an error notice is copied, not the layer
- feat(toolbar): select grouped tools using press-drag-release
- scorecard: five rows catch up with work already on main
- .atn: a pinned corpus of real action sets, with byte-exact and load/save/reload tests
- fix(screen-picker): cancel queued requests without stale replies
- Fix mixed-order layered TIFF type geometry and unsafe text fallback
- PSD Duotone: read and write the ink block (names, colours, curves)
- Support .act color tables end to end (swatches + Color Table dialog)
- IO: open .psd through the PSD reader, not codecs
- Layers: Group Layers creates the group collapsed
- Warp: apply a large layer's warp in the background, with progress and Esc to cancel
- Move tool: ΔX/ΔY readout beside the pointer while dragging
- Export As: Resample menu, incl. Nearest Neighbor
- Shapes: Density and Feather on shape layers
- Displace: OK asks for the displacement map, as in Photoshop
- Image: Bitmap dialog with Output resolution and per-method settings
- Text: apply anti-alias mode shaping when rasterizing type
- BMP export: Indexed Color documents save as palette BMPs
- Bevel & Emboss: keep the Gloss Contour's Anti-aliased (antialiasGloss)
- Stroke: keep Overprint (overprint)
- Zoom tool menu: Zoom In and Zoom Out last, as in Photoshop
- refactor: share hsb conversions between photocraft-color and the color picker
- feat(psd): editable Render smart filters (Clouds, Difference Clouds, Fibers, Lens Flare)
- Performance: a cancelled Gaussian Blur job stops within budget
- Preferences: Save in Background off saves in the foreground
- Zoom tool: hold to zoom continuously with Animated Zoom on
- Tools: each painting tool's brush persists across launches; restored tool options are clamped
- GPU: pin the keep-overlap ordering with a tile-growth regression test
- PSD: parameterless smart filters (Blur, Sharpen, Find Edges, Solarize…) open and save like Photoshop
- PSD: Surface Blur, Smart Blur and Radial Blur smart filters open and save like Photoshop
- PSD: Offset and Custom smart filters open and save like Photoshop
- PSD: Mezzotint and Color Halftone smart filters open and save like Photoshop
- New Document: Color Profile, the working space or another profile of the mode
- PSD: Perspective Warp smart filters open and save like Photoshop
- Artboards: layers outside the boards stay visible over the pasteboard
- Survive a lost window GPU device: draw nothing, save unsaved work for recovery, close
- fix(ui): preserve shape stroke settings at zero width
- Type: commit the edit when another layer or document becomes active
- Canvas overlays stay visible while panning
- Tab in Full Screen Mode shows the menu bar and panels; leaving Full Screen restores them as before
- Actions: .atn Select Subject, Select and Mask, Color Range, clipping and layer masks, colours map to commands (part of #6745)
- Tests: generated large-file fixtures and a P20 number
- security: prevent script injection in fuzz workflow (SonarCloud S7630)
- test: non-blocking sleep in async test loop (SonarCloud rust:S7488)
- security: enforce HTTPS on curl downloads (SonarCloud S6506)
- ci: pin GitHub Actions to full commit SHA (SonarCloud S7637)
- refactor(atn): build the clipping-mask and three adjustment events with macros (SonarCloud duplication gate)
- Smart Filters: distinct editors, shared disclosure and stable alpha
- README: the app icon above the title
- security: cap uncached pattern conversion
- security: bound dense mask working set
- security: bound XCF copied layer metadata
- security: bound PDN layer-name copies
- security: bound cumulative retained RAW tile memory
- security: cap lossless-JPEG Huffman table builds
- security: apply caller limits to RAW preview decoding
- security: interpolate RAW gain maps per pixel, not per full row
- security: position RW2 bit cursor in constant time
- security: reject tiled Sony cRAW and cap row references
- security: bound TIFF structure-dump output
- security: admit HEIF coded image size, not just transformed
- security: admit deep-EXR output size and validate chunks before indexing
- security: budget Cryptomatte per-pixel pair capacity
- security: bound inverse-curve and CLUT interpolation work
- security: compute auto-slice coverage per band, not per cell
- security: check filter-effects padding length before scanning
- security: bound Affinity raw child-slot traversal work
- security: index Affinity live-corner radii by record
- security: index Affinity object fields for O(1) lookup
- security: validate corpus paths and bound symlink traversal in xtask
- security: count GIF frame delays with a map
- security: convert spelling offsets in a single pass
- security: stop quadratic rescans in XMP value scanning
- security: dedup Cryptomatte keys and cache stream lists
- security: deduplicate ATN action names in near-linear time
- security: index FITS header keywords for O(1) lookup
- security: index XCF parasite names for duplicate replacement
- security: index comp IDs in PSD layer-comp import
- security: bound RAW metadata array reads
- security: bound nested automation playback
- security: encode printer names in IPP requests
- ci(freebsd): run the photocraft-gpu tests one at a time
- Fixes #8519 quick export honours extension
- Format the quick export test
- Backlog batch: 271 reviewed contributor PRs
- Fix Fixed Size marquee drag positioning, building on #6026
- fix(ui): pin the document tabs' » button to the strip's right end (part of #8290)
- fix(actions): Hue/Saturation uses Photoshop's hue key H in .atn files
- New Document: labels show the arrow, not a text cursor
- Compose: effect maps that don't fit in the effect cache are built over the render rect, not rebuilt whole on every render
- i18n(pt-br): translate 131 runtime labels that still showed in English
- Save: a tab whose file another save writes over is detached and marked unsaved
- Open/Save: refuse file names that aren't valid Unicode instead of rewriting them
- Alt held during a drag is no menu-bar tap, so Enter commits Free Transform
- Liquify: keep short strokes whole so undo removes only the last
- Compose: tone and hue-range lookups truncate instead of calling floor
- Fix tooltip text in scrub_label function
- Panels: the dock can be dragged as wide as the window allows, not only 520 points
- Quick Export: preserve floating-point EXR output
- Compose: adjustment layers blend back and round without per-sample calls
- fix(psd): an edited type layer updates the Photoshop-era Txt2 objects too
- fix(ui): grey out Select and Mask in the options bar without a selection
- fix(ui): Browse… buttons for dialog folder and plug-in path fields
- fix(info): Info panel CMYK uses the Color Picker's colour-managed conversion
- fix(swatches): a CMYK swatch keeps its inks as the foreground
- fix(ui): menu titles switch on hover at the very top screen edge
- feat(ui): Brushes tab preview-size slider for grid cells and list rows
- Layers panel: mark adjustment layers kept as imported but not rendered
- fix(actions): .atn export of Image Size with resample none no longer adds a pixel resize
- fix(paths): the Work Path is drawn only while selected or a path tool is active
- fix(ui): a unit after a range bound in a params doc no longer resets the dialog range (part of #7598)
- docs(parity): Crop rows in ui-parity.md match the code and the scorecard
- Preferences: the theme swatch star no longer grows the row on hover
- Warp: a surface drag commits exactly as previewed, now under test
- Preferences: list the languages alphabetically by their own name
- Color Lookup lists the LUTs in a Preferences folder
- UI: Control-click opens the right-click menus on macOS
- Alt + wheel zooms while Alt is held, even when the modifier state misses it
- Plug-ins: a reduced live preview scales the settings a manifest marks "unit": "px"
- Add interactive drag positioning to print preview
- Clipboard: a panic while reading the clipboard is reported, not a crash (refs #7582)
- CPU canvas: a large document shows its own pixels at 100%
- Keep Batch results when the action saves and then closes the document
- Pen: ⌥/Alt-drag grabs the last anchor's incoming handle too
- Object Selection: preserve Shift/Alt from mouse-down
- fix(engine): Remove Background looks for the subject in the layer, not the canvas
- docs(architecture): drop references to the removed rust-framework-options.md
- test(codecs): cover exact TGA packet and encoder input boundaries
- test(io): cover PSD palette boundaries and bitmap row packing
- test(algo): cover deinterlace choices and NTSC signal limits
- test(algo): cover Custom convolution bounds, padding and depth semantics
- Dialogs: Preferences' title no longer sits against an inner outline
- contributors: add adi-1108
- docs(support): Canvas Size added a white border around my photo
- test(ui): cover tool memory persistence
- Keyboard Shortcuts: the dialog switches sets through the engine too
- fix(ui): Free Transform corners show the diagonal resize arrow on wide or tall boxes
- MCP stdio: a line that is not UTF-8 gets a parse error instead of ending the session
- Layers: per-layer XMP metadata (layer.xmpMetadata), stored as Photoshop stores it
- fix(atn): reject non-replace select.rect modes in .atn export
- Fix: add missing Chinese translations for "Up" and "To"
- Auto-Blend Layers: mask and blend the whole layers, past the canvas too
- Camera Raw: choose the demosaic method when a raw opens
- Camera Raw: the full-resolution preview of a raw open shows the raw-stage sliders
- CLI convert: refuse to write over the input file unless --in-place
- Refuse strict .atn export of Apply Image with a blending mask
- Move tool: moving selected pixels shrinks the selection, transform controls and snapping to them
- Refuse strict .atn export of a mask/channel-targeted Free Transform
- fix(atn): keep a Transform Selection's interpolation; refuse what the transform descriptor can't carry
- fix(atn): refuse strict export of canvas-bound selection modifies and placed pattern buckets
- Refuse .atn export of crops with output size or resolution
- Lasso tools: the outline is solid until the selection is made
- Refuse strict ATN export of Select and Mask with brush strokes
- Previous / Next / First / Last Brush commands (, . ⇧, ⇧.)
- Fade the alpha channel or Quick Mask an edit changed
- Record one action call when playback pauses for a step dialog
- Map the bevel's shading through its gloss contour, not its light
- Refuse .atn export of resolution-only Image Size without keepPrintSize
- Preferences: Zoom Resizes Windows resizes floating document windows, and the Zoom tool shows it as Resize Windows to Fit
- File Info: print a slow shutter speed as the fraction a camera writes…
- Export As: show the size the file will have
- fix(actions): refuse lossy fractional Crystallize ATN export
- Actions: a setting Photoshop's event cannot hold refuses the step
- fix(ui): guides draw over the Puppet Warp, Perspective Warp and Vanishing Point previews
- Guides: show the X or Y position beside the pointer while dragging
- Refuse strict .atn export of an in-place layer duplicate
- Add a draggable center diagram for Radial Blur Zoom
- Preferences › Raw Defaults › Resolution: a developed raw opens at it
- PNG: correct sTER eye-order names without changing stored bytes
- Don't paint from the sampled point when Alt is released mid-press
- Print: an IPv6 print server is parsed as a host, not split on its last colon
- Print: the no-listener test takes a port the OS says is free, not port 1
- Brush: with airbrush build-up on, number keys set Flow and Shift+number sets Opacity
- fix(touch) double tap jitter
- Save As JPEG: JPEG Options dialog (quality 0–12, Baseline / Optimized / Progressive) (FILE-215-19)
- Slice Select: Delete deletes the selected slice, not the layer
- Liquify: Alt-drag brush resize keeps the brush in place and no longer paints a dab
- Create Rectangle and the other shape dialogs: right-click Width or Height to pick their unit
- perf(liquify): parallel dab nodes and source read, P30 −13–15 %, same pixels
- Layers: the pointer over a thumbnail shows what ⌘-click loads, with the +/−/× badge
- fix(transform): keep artboard paper below child previews
- Type: hovering a served font fetches it after a short rest, not as the pointer passes
- Align: a lone layer in an artboard aligns to that artboard
- Fix dropdown menus opening behind modal dialogs on macOS trackpad tap
- Decode numeric character references in File Info XMP text
- Preferences: say Rendering Mode applies at next launch, next to it
- fix(geom): reject extreme warp split indices without overflow
- perf(raster): read 16- and 32-bit rows into RGBA with the colour model resolved per row
- Keep previous crop length when normalizing rounds to zero
- Keep '#' inside quoted .cube TITLE when parsing
- Snapping: artboard edges and centres are snap targets
- Layers panel: a group's layers indent past the group
- fix(format): make Windows native-save publication durable
- Page Up/Down, Home and End scroll the canvas, as in Photoshop
- Write DOMAIN_MIN/DOMAIN_MAX in the .cube writer
- Preferences › File Handling: Do not append "copy" to filename when saving a copy
- fix(liquify): include cubic overshoot in source reads
- fix(type): resolve exact PostScript names in type.create
- Reject '+' signs in color picker hex field
- Compose: Color Balance works out each channel's curve once, not per pixel
- Layers panel: a click on the empty space below the layers deselects them
- Find small objects in large documents with the Object Finder
- macOS: Beep When Done plays the system alert sound (NSBeep) instead of a terminal bell
- Puppet warp: Delete and Backspace remove the selected pin
- Puppet warp: Fix discrepancy between preview and the final state
- Intel Iris Xe on DX12: no more red blocks in brush previews and tool icons
- Type: paragraph direction buttons in the Paragraph panel and options …
- feat(ui): System Info shows the graphics card's own memory
- docs(contributors): add Gotix-eg to people.toml
- Actions: Shift-click layer select in .atn imports as range select and exports back
- Title bar: only the primary button starts a window drag
- Object Finder: hovering with an empty active layer shows the status-bar hint
-…
0.12.0Big update
From docs/scorecard.md (done / partial / missing):
| Area | v0.11.1 | v0.12.0 | |---|---|---| | Tools | 33 / 11 / 0 | 36 / 8 / 0 | | File compatibility | 7 / 14 / 6 | 9 / 12 / 6 | | Type | 4 / 3 / 2 | 5 / 3 / 1 | | Workspace and UI | 13 / 6 / 4 | 13 / 7 / 3 | | Open bugs | 29 / 2 / 1 | 31 / 1 / 0 |
- Now done: Content-Aware Move with a coarse-then-exact preview for large selections; shape Density/Feather and mask Density/Feather in Properties; Export As Nearest Neighbor resample; large-file fixtures (20 MP, 150 layers, 2 GB PSD, 4 GB PSB); Warp Text opens with the layer's warp and previews live; retouch-tool mask/channel targeting tests; selection modifiers pressed before the drag.
- Moved up: Alt+wheel zoom (missing → partial); live stroke preview now covers Pattern Stamp, Background Eraser and Color Replacement; Smart Filters map 41 filters to PSD (was 14); tool options and per-tool brushes persist across restarts.
- Settings that do nothing: 24 of 171 (was 25 of 169).
- Performance: no change to the 2026-10-05 baseline (3 within budget, 22 over). Added scenarios P20, P62 and P63 (2 GB PSD, 4–5 GB PSB, 3.1 GP New Document), not run yet.
- Corpus floors: unchanged.
FreeBSD aarch64 is not in this release: the shared release pipeline dropped it for every Craft app until it builds in time (storytold/craft-common-actions#40). FreeBSD x86_64 is included.
- docs: add SonarCloud and CodeRabbit badges to README
- Skip CodeRabbit reviews on Dependabot PRs
- Codecs: save DDS textures, uncompressed or BC1–BC3, with optional mipmaps
- Integration batch: 26 PRs from the known-issues list on main
- Group all selected layers from the Layers panel footer
- Web: start when the server already inflated the app's gzip part (Apache mod_mime_magic)
- Give a new type layer a full Txt2 object and its own frame
- Choose the graphics adapter on multi-GPU Linux machines
- Print: Portrait and Landscape in the Print dialog on Windows
- Indexed GIF opens in Indexed Color with its colour table, as in Photoshop
- Preserve near-black ICC colors on the GPU canvas
- fix(ui): wire video menu pickers/dialogs and fix Timeline Stop playback
- Large documents: a gigapixel New Document draws without freezing
- perf(retouch): row-parallel Blur/Sharpen dabs, 2.6-3.3x faster strokes
- Preserve editable clipboard contents when native reads fail
- Snap: View › Snap off also disables smart-guide snapping
- Batch: Format "Same" saves camera raws as PSD instead of failing
- fix(tablet): support stylus barrel button and brush resize on Windows
- Reveal newly created selections after hiding Extras
- Windows: PhotoCraft starts without Windows.Data.Pdf.dll
- macOS: list fonts activated outside the font folders
- fix(ui): disable Batch without a recorded action
- Windows: maximized window lets an auto-hidden taskbar show
- Pen: a finished path keeps its anchor squares on screen
- Mixer Brush: Clean Brush empties the brush, and the automatic Load and Clean can be switched off
- Brushes: accept .abr files up to 1 GiB
- GPU startup: Auto on Windows leaves Vulkan out when an Intel adapter is present
- fix(psd): an edited type layer keeps its Txt2 object instead of a bare stub
- Paragraph panel: grey the justify buttons on point text
- Integration batch: 9 PRs on main
- PSD: save Indexed Color, Bitmap and Duotone documents in their own mode
- PSD: render constant RGB noise gradient fills
- perf(compose, gpu): many-layer composites, P60/P61 on the GPU 111 -> 28 ms
- perf(compose): Reuse bounded scratch and tone tables
- PSB save: 8-byte-length global blocks use the 8B64 signature, so Photoshop opens the file
- Type: keep superscript and subscript when a text layer is re-rendered
- PSD: read split ("quilt") warps of placed layers, so Replace Contents keeps their curvature
- ci: switch to shared nix workflow from craft-common-actions
- Integration batch: 86 PRs on main
- PSD: read colours stored as HSB
- Apply Image: write into the targeted layer mask
- Droplets: carry the actions that Conditional steps call
- Guides: ruler guide snapping rebuilds its targets when snap options change
- CLI batch: skip shell-only Save and view steps inside played action sets
- Image Size: Resolution with Resample on keeps the print size in physical units
- Control: ui.set rejects zoom, rotation, center and dockWidth beyond f32 range
- Channels: Multichannel conversion keeps the targeted channel
- Keyboard Shortcuts: switching sets keeps action function keys
- Timeline: a longer duration moves a work area that reached the old end
- Crop: Color Samplers scale with a W x H crop
- Actions: deleting an action removes its function key
- Automation: doc.save rejects a bad quality instead of ignoring or clamping it
- Automation: place and layer/data-set export by index keep the active document
- Transform Selection: an unknown reference point is an error
- Lens Correction: smart filters keep the exact focal length
- Match Zoom: matched views stay within each document's zoom range
- Crop: the turn readout never shows -0.0° or -180.0°
- Conditional Mode Change: "gray" as a single source mode matches Grayscale
- Layer Style: gradient overlay and stroke scale stay within 10-150 %
- Perspective Crop: a drag without area leaves no crop box
- PSD: Hue/Saturation export writes each triplet in its own slot
- Merge to HDR Pro and merged duplicates: the Background layer is a real Background
- Actions: an imported Crop step in a unit other than pixels is not applied as pixels
- Crop / Canvas Size: extending keeps the Background's hidden pixels
- Crop: in default mode, box Undo/Redo keeps the box in place
- Image Size: type keeps its pixel size when the resolution changes
- Perspective Crop: switching documents drops the pending box
- Crop: a refused crop keeps the frame for fixing
- Perspective Crop: W and H follow the Point/Pica Size preference
- Image: Trim and merged Duplicate report an error on documents over 2^30 px
- Crop: a W x H crop on an Indexed Color document resamples with Nearest Neighbor
- Crop: Undo/Redo grey out when the frame has no step left
- Crop: a lost Straighten release no longer hijacks the next drag
- Brush smoothing: catch-up compares the pose too, not only the position
- Crop: a typed ratio fits from the frame the edit started with
- Layer Style: a new Stroke is 1 px inside black, as in Photoshop
- History: panel menu, Step Forward/Backward and Clear History
- History: set the History Brush source from the panel (history.setSource)
- Pattern Stamp and Background Eraser draw live; Spot Healing shows its heal area (TOOL-213-7, #3754)
- Performance: brush dab on a CMYK document within budget
- Filters: Lens Correction, Adaptive Wide Angle and Camera Raw Filter respect locks on smart objects
- Layer masks: From Transparency and Mask All Objects convert the Background and match the document depth
- Fill layers: reject non-finite gradient angles and pattern angle/phase
- Paint: Lock Transparency blends source-atop on semi-transparent pixels
- PSD Multichannel: alpha channels are stored as-is, not as ink
- Effects: Gradient Overlay transparency follows Smoothness, midpoints and method
- PSD: Smart Sharpen and Dust & Scratches smart filters open and save like Photoshop
- PSD: Wind, Extrude and Tiles smart filters open and save like Photoshop
- Move tool: Ctrl-hover shows the distance to another layer
- PSD: Hue/Saturation smart filters open and save like Photoshop
- Layers: toggling a clipped adjustment damages only its base
- Hue/Saturation: the Lightness track runs black, grey, white
- Shortcuts: a command shortcut leaves the focused menu bar and runs
- Paths: Delete Path on a shape layer's path row deletes the layer
- Paths: drag a path row onto the Trash to delete it
- PSD: open an adjustment layer of an unknown type as an unsupported adjustment
- PSD: layered TIFF byte-order conversion reads the class of Idnt/indx references
- Fit Image: a width or height of 0 leaves that side unconstrained
- Actions: renaming an action updates the Conditional steps that call it
- Auto-Align: warp layer masks as masks, keeping what lies outside revealed
- PSD: layered TIFF byte-order conversion swaps every smart filter section
- Type: paragraph box handles are picked at the unsnapped press
- Stamp Down keeps the lower layer's clipping, label and link
- Crop: W x H x Resolution follows the Point/Pica Size preference
- Crop: Straighten is one box Undo step
- @guillehr2 made their first contribution in
- @readtedium made their first contribution in
- @ToastyStoemp made their first contribution in
- @Anim86 made their first contribution in
- @Elements2720 made their first contribution in
- @ArintonAkos made their first contribution in
- @thangnm93 made their first contribution in
0.11.1Big update
- perf(canvas): a Properties-panel adjustment drag refreshes only the view, 4.2× faster
- Linux: Reveal never hands xdg-open a file
- Stack Mode: Kurtosis and Skewness give the same bits on Windows and Linux
- Content-Aware Fill workspace, as Photoshop's
- perf(stack): one loop per statistic, up to 2.2× faster, bit for bit the same
- Trap: refuse locked layers
- Lens Flare: don't darken 32-bit pixels above 1.0
- Duotone: view and flat export clamp ink density like the Multichannel conversion
- Custom filter: in CMYK a positive offset brightens
- Measurement Scale: large pixel lengths print their real value
- Clamp filter.cameraRaw exposure to its documented -5..5 range
- fix(engine): check the define-brush tip size multiply before reserving (wasm32)
- Ignore a leading UTF-8 BOM in variable data set CSV import
- fix(engine): flip and rotate presets turn about the selection's bounds, as Free Transform does
- Actions: a Paint Bucket step keeps its explicit colour through .atn
- EXR: the ACEScg preference applies to every way of opening a file
- Type: Paste Lorem Ipsum inserts into the type layer named by "layer"
- Place Scale Marker: lay out the label in points, not pixels
- Fix generator spaced size keeping size text in asset file name
- Stamp Visible fills an empty active pixel layer instead of adding another
- test(type): PostScript names guessed apart from their installed family resolve exactly
- GPU: a group's effect cache follows its vector mask and children's Blend If
- Pencil: a 1 px line paints the same pixels whichever end it starts from, at any Smoothing
- Twirl, Pinch and Spherize fill the inscribed ellipse
- Reject out-of-range leading, baseline shift and scales in type styles
- Snapping: layer targets ignore the selection, so a moved selection snaps to guides and the document
- Krita: uncompressed tiles are read as interleaved pixels
- Fix GPU startup requests exceeding adapter limits
- Paste: an image pastes with Ctrl+V whichever key is let go first
- fix(linux): file dialog probe sees a portal with no FileChooser backend
- Reject notes.set moves that make the popup non-finite
- Document tab says "Quick Mask" in Quick Mask mode, as in Photoshop
- Preset Manager: renaming or deleting a brush keeps the current preset and names consistent
- PSD: layer_tree_max_depth hoists layers under unclosed dividers past the cap
- Swatches: the .ase reader refuses files with more than 10,000 groups
- fix(io): exclude transparent palette entries for opaque PNG pixels
- perf(psd): 8-bit merged composite unmattes through a table, not a division per sample
- Menus: rows scrolled out of view no longer open their submenus
- Check unclamped transform dimensions against the pixel budget
- Remove tool: every queued stroke is tinted in full
- Keep Color Sampler points on their pixel after flips and turns
- Upload 16-bit layer masks as R16Float instead of R32Float
- fix(ui): distinct Elliptical Marquee and Quick Selection icons
- OpenRaster: layer locks no longer change silently on save
- fix(ui): Ctrl/Cmd-drag in the Navigator zooms to the drawn rectangle, as in Photoshop
- Menus: one checkmark column keeps every label aligned
- fix(codecs): keep EXR color channels within one layer
- Focus font search when opening the picker
- Assign Profile and Convert to Profile: Preview, as in Photoshop; "Black Point Compensation" spelled out
- Korean: consistent terms in the Gradient Editor, Object Selection messages and shortcut hints
- docs: write product name as PhotoCraft in engine docs, LUT export header and image sources
- Saving onto a dangling symlink writes through to its target
- Document tabs: keep whole names, hide what doesn't fit, list every document in the » menu
- Translate the brush size and hardness shortcut rows in every language
- i18n(uk): translate color picker titles and rasterization warnings
- Tests: fix the flaky file-lock tests and the occasional portal_save hang
- Fix nested Free Transform preview isolation
- Open Photoshop guides stored in a JPEG's APP13 resources
- Centre stacked ruler digits and the Properties W/H/X/Y labels
- Esc leaves full screen with the Crop tool showing its default frame
- Crop and Straighten Photos keeps Duotone inks and is disabled for Indexed Color
- Tool Presets: + saves only the current tool's options
- Canvas Size: growing the canvas re-renders PSD fill layers
- Rotate Canvas Arbitrary: keep the angle at full precision, so rotated crops land on the pixel
- Image Rotation: Arbitrary keeps Color Sampler points on their pixel
- Spot Healing Brush trail is Photoshop's dark half-opaque tint
- Crop: Esc and Enter go to an open options bar popup first
- Refuse strict ATN export of Close with an explicit document target
- Save Actions ATN files atomically so a failed write keeps the old file
- Raw tone curve: no NaN between a knot at black and the next one
- Camera Raw histogram: spikes run off the top, as in Photoshop's Camera Raw
- Keep fractional translation-only Free Transform on .atn import
- Integration batch: 19 PRs on main
- fix(svg): budget rasterised fallback layers across imports
- Retouch: bound every stroke command before its dense buffers
- Help › Search: typed letters go to the field, not to menu mnemonics (fixes #5996)
- Image Size: Indexed Color resamples with Nearest Neighbor only (fixes #6019)
- Type: Korean paragraph text wraps between words, not syllables (fixes #5959)
- Window › Arrange: tiles keep their documents, and every tile has rulers (fixes #6017)
- Replace Color: the sample eyedropper is armed when the dialog opens (fixes #6279)
- Smart filters: an edited filter's dialog previews again (fixes #6324)
- Replace Color: a Result swatch whose Color Picker sets the sliders (fixes #6278)
- File › Open: a file type filter per format (fixes #6337)
- Type: the text caret shows on a white background (part of #6085)
- Brush: the Dual Brush tip keeps its proportion at tiny main sizes
- Automation: a control token authenticates in either letter case
- Desktop: a control/automation flag without its value is a usage error
- Engine: reject numeric overflow before document edits
- Character and Paragraph panels: size, leading, baseline shift and indents follow the Type units preference
- Refuse Affinity spot colours nested more than 4 levels deep
- Integration batch: 11 PRs on main
- Native format: refuse a .pcraft with out-of-range numbers when it is opened
- Render Video: GIF frame delay follows timelines under 1 fps
- Perspective Crop and Rotate Arbitrary keep the Background opaque
- perf(camera-raw): Shadows/Highlights 1.5× faster, bit for bit the same
- Count tool: deleting an earlier count group keeps the active group
- Count: reject unknown groups instead of adding markers to the wrong group
- fix(path): validate Make Selection options and guard selection state
- Plug-ins: running a filter plug-in respects layer locks
- Object Selection: enclosed background gaps stay unselected, only object-like holes fill
- perf(canvas): report how long the GPU spends on a composite
- Color panel field fills its group in a custom workspace too
- ci: configure Dependabot for Cargo and GitHub Actions
- Preferences: the settings fill the resized dialog, buttons at the bottom
- Tests: the slow-job frame loop test waits for the worker's progress message
- Tests: the authentication deadline test writes its first line before the deadline starts
- Font menu: hovering a font no longer grows its row and makes the list jump
- Font field: ↑/↓ step through the fonts after a pick, as in Photoshop
- Fix clipped ancestors in nested transform previews
- file.saveACopy refuses the document's own file without "overwrite"
- Replacing selected type keeps its size
- Fade: restore uniformly inverted layer masks
- Remove: cancel queued strokes when the paint target changes
- Fix/7381 action worker failure 20261018t2254jkt
- Make .pcraft reload f64 coordinates bit-exact
- perf(canvas): composite and upload an inline filter preview once
- fix(shortcuts): plain , and ; bindings follow the typed character on AZERTY
- image.crop: accept whole-number float targetWidth/targetHeight
- Filters: normalize nonpositive explicit tile sizes
- Perspective Crop: draw the crop quad's side of the horizon
- Refuse strict .atn export of plain events whose target is not the layer pixels
- Print: the last print's settings survive a relaunch, as in Photoshop
- Type: right-click on committed text opens the type layer menu
- Save for Web and Quick Export: "All" keeps the photo's EXIF
- Curves: Cmd/Ctrl-click on the image adds a point at the pixel's tone
- Preferences: Enable Gestures off ignores touch-screen pinch and twist
- Edit: Copy with no selection keeps fill and adjustment layers
- Lens Blur: an alpha channel as the depth map source, as in Photoshop
- docs: add user docs in docs/user
- Save: keep the replaced file's metadata
- Integration batch: 12 PRs on main
- Smart Filters: deleting the last filter removes its filter mask
- Image > Adjustments: locked smart objects refuse new smart filters
- Brush smoothing: the lagging brush keeps the pressure of where it is
- Menu bar: zooming with Alt+scroll, then holding Space to pan, no longer opens New Document
- fix(engine): refuse a Content-Aware Fill with nothing to sample instead of filling black
- Presets: refuse renaming a group to a name another group has
- Image Size: a gradient fill's centre offset stays a fraction of the frame
- Mesh warp: about twice as fast, same pixels (tiles encoded in parallel, direct in-bounds reads)
- Transform: drop a fill layer's cached render when its frame changes
- Artboards to Files: paths, notes, slices and marks move with the board
- Video: Interpret Footage and New Video Layer from File reject an invalid frame rate
- PNG: keep a stereo file's sTER pairing on save
- fix(actions): flush pending recorded steps on save
- Show File Name In Title: hide the file name from the title bar
- Actions: Photoshop Shadows/Highlights steps play
- Free Transform: show a flip as -100 % on the flipped axis
- Type: formatting commands respect Lock All
- Docs: install the CLI and register it with MCP clients
- refactor: use photocraft-color's srgb transfer functions in algo and proof simulation
- Layers: ⌘-click on the Background thumbnail is a plain click, as in Photoshop
- Minimum / Maximum: CMYK spreads paper white with Maximum, ink with Minimum
- Export and import saved tool presets
- Fix live gradient fill scale limits to match OG program
- Histogram: count the document's pixels, not a blurred thumbnail
- Affinity: bound compound geometry expansion and reject cycles
- Color Settings: the working-space menus list the installed profiles of their space
- Scripts: Flatten All Layer Effects bakes with the document's Global Light and patterns
- Gradient Overlay: repaint the whole layer when a stroke moves its frame
- Add Liquify's Show Backdrop Use and Mode
- Actions: Smart Blur quality uses Photoshop's SBQL/SBQM/SBQH codes
- Color Lookup: warn when it opens without its usable table (part of #1763)
- Crop: a preset picked in Tool Presets fits the frame to its ratio
- Actions: a function key can take Shift and Command
- perf(photomerge): build multi-band bands in bounded batches
- Guides: colours follow Crop, Canvas Size and rotations
- Keep arbitrary canvas rotation interpolation in ATN export
- Type: a click inside the paragraph box off the glyphs moves the caret
- Presets: Migrate Presets reads tool presets like the launch loader
- fix(linux): keep crash-recovery autosaves in $XDG_STATE_HOME, out of the config folder
- Hide the Hyphenate checkbox until layout hyphenates
- Disable Save for Web while a Free Transform is pending
- Layer Mask Properties: the Feather slider has fine steps near 0 px, as in Photoshop
- GPU canvas: redraw mip levels of 128 px or less whole; fixes AMD Vulkan corruption after partial updates
- Free Transform: W and H take a typed length in percent view
- fix(engine): keep layer-based slices when duplicating a document
- refactor(engine): drop the second damage pass after single-edit duplicates and pastes
- Tools: Sample All Layers is each tool's own, as in Photoshop
- Actions: Apply Layer Comp is recorded by the comp's name, so it plays in any document
- Reject exporting a partial Play Action call to .atn
- refactor(algo): route the splitmix64 copies through one function
- Explain the Memory Usage budget and GPU caps
- Actions: export Box Blur, Surface Blur, Flatten Image and Black & White under ids Photoshop runs
- Home screen: fit the card and stack the buttons in a narrow window
- perf(codecs): Avoid redundant PNG filter passes
- Crop: a ui.pointer click on the frame leaves it alone
- Apply background jobs to the layers they started on
- Print: Save as PDF gets a Browse… button
- Reveal All: one History step named "Reveal All"
- Crop: Enter during a drag ends the drag
- fix(psd): make packbits::decode_into crate-private and overflow-safe
- Content-Aware Fill: preview at full resolution so it matches the result
- Actions: loading a set renames each Play target once
- Preferences: a wrongly typed value resets only that field
- Guides: Ctrl/Cmd drags a guide with every tool that moves guides, and the cursor shows it
- PSD save: check the Background's opacity without copying the canvas
- Flatpak on Wayland: say why a paste finds nothing, and how to paste anyway
- fix(engine): apply document-wide image and colour conversions to stored video frames
- Crop: a turned crop rotates only what the frame keeps
- Toolbar: Edit Toolbar, Quick Mask and Screen Mode in every theme
- Layered TIFF: Photoshop opened only the composite of a many-layer file (PSB-style layer data)
- docs: regenerate the scorecard after today's landings
- Integration batch: 8 PRs on main
- Limit blend-mode hover refreshes to the visible canvas region
- perf: chisel bevel size changes, CPU passes on threads and GPU fields share their sharp edges (results unchanged)
- PSD: keep guide resources 1092/1097 only while they match the guides
- Brushes: importing an .abr file numbers repeated brush names in linear time
- fix(perf): validate regression minimum threshold
- perf(io): Interleave PSD pixels in the final buffer
- perf(raster): Avoid redundant default pixel work
- perf(text): rasterize a type layer's pixels on all cores, bit for bit the same
- @Silvertree2010 made their first contribution in
- @Bortlesboat made their first contribution in
- @arnav-hiwarkar made their first contribution in
- @denstu473 made their first contribution in
- @ingling made their first contribution in
- @junhyun-dev made their first contribution in
- @driftee made their first contribution in
- @aiongg made their first contribution in
- @saad-mughal435 made their first contribution in
- @chrisgleissner made their first contribution in
- @hodd1444 made their first contribution in
- @Byxis made their first contribution in
- @jlange91 made their first contribution in
- @KLBMinhLong made their first contribution in
- @odgrim made their first contribution in
- @artman67 made their first contribution in
- @osaidahmed made their first contribution in
- @nanopink made their first contribution in
- @hectorviov made their first contribution in
- @zrsix1 made their first contribution in
- @TaylorBurke made their first contribution in
- @bramheerink made their first contribution in
- @ersoynarin-code made their first contribution in
- @ebosido444-ai made their first contribution in
0.10.0Big update
From docs/scorecard.md (done / partial / missing):
- Tools: 29 / 13 / 1 → 33 / 11 / 0. Done: per-control pressure curves, image files as brush tips, Pen Shift 45° constraints, arrow-key nudges bundled into one History state.
- File compatibility: 7 / 13 / 7 → 7 / 14 / 6; PDF save went from missing to partial (one flattened page with ICC).
- Corpus floors raised: Photoshop oracles 145 → 188 / 256, psd-tools 236 → 249 / 309, io corpus 146 → 148 / 170 (round-trip floors unchanged).
- Reliability: never-crash lints on 30 of 30 crates (was 28 of 28).
- Workspace and UI: unchanged at 13 / 6 / 4; settings that do nothing 26 of 168 (157 before, after new settings landed).
- Performance: two new scenarios tracked (P60/P61, layer opacity and visibility among 150 layers), not run yet; budgets met unchanged at 3 (baseline 2026-10-05).
- Keep channel pastes transactional when memory allocation fails
- Bound selection sampling and report layer-buffer allocation failures
- Gradient Map is driven by the W3C luminosity, as in Photoshop
- fix(layers): merging layers keeps pixels that lie outside the canvas
- Map .atn duplicate-into-new-document (Mk) to layer.duplicate
- Text: non-finite numbers and negative indices from PSD files are sanitized
- feat(commands): find the Elliptical Marquee by 'ellipse' or 'marquee'
- Linux: a virtual keyboard claiming BTN_TOOL_PEN no longer sends the window through Xwayland
- Fix/scale marker rollback layer state 4975
- affinity: decoded layers are admitted against an aggregate pixel budget
- ICC parser: checked arithmetic on offsets and counts from the file
- GPU compositor: pattern textures are freed on close, when idle and over a budget
- Performance: the lower-stack cache follows an edit up the stack (P9 / P11, #5286)
- Expose shared Smart Object instances in inspection and replacement results
- Free Transform: solid pixel stretch (edge-repeat sampling, selected-pixel bounds)
- feat(engine): layer.list, a read-only listing of the layer tree
- PSD import: flat fallback respects the decode budget; checked sizes
- Actions: record layer selections by name and display the target
- Color Balance: fold the tones into one Levels per channel
- IO: smart-object source sizes from WebP/GIF/BMP/EXR headers, not a full decode
- Compose: build effect-map layer identity once per render, not per tile
- fix(brush): preserve Dual Brush tip spacing and scale its size with the primary brush
- Font preview test: skip installed fonts whose Arabic glyphs are blank
- ui: remove the title-bar Discord button
- fix(windows): prefer WARP over GL to avoid black window
- fix(ui): make Preferences modal resizable on desktop
- Color Range: sample colours outside the active selection
- fix(transform): keep masked objects visible during transform
- Canvas: themes without a dot pattern draw no dots texture
- fix(ui): remove empty right column from Curves dialog
- Frame tool: take type, shape and smart object layers into the frame
- perf(gpu): keep the DX12 mip scratch textures for Intel adapters only
- Display profile notice: one card for all displays without a usable profile
- Type: hovering a font previews it with the Character section shown too
- Number fields: centre the number in its box
- fix(ui): Color Picker hex field accepts repeated pastes
- Edit › Menus: Menus, Keyboard Shortcuts, Preferences, Save and Exit can't be hidden
- perf(ui): the Info panel composites its Color Sampler readouts once per revision
- Show feathering in layer mask views
- fix(ui): give the Quick Selection tool its own icon
- fix(puppet-warp): drop open Puppet Warp and other distort sessions when the active document changes
- fix(ui): swatches touch with no padding, as in Photoshop
- fix(ui): show brush tip thumbnails while dragging presets
- Interface: hide the Home screen's recent files
- Large document: large damage over the GPU budget redraws in the background; open warms layer bounds
- Layer styles: editing effects no longer re-enables a disabled effect list
- Actions: a recorded File › Save of a flat file saves the file it is played on
- fix(ui): guides draw over the Free Transform preview, under its box
- Undo and redo Camera Raw adjustments from the keyboard.
- Fix custom-frame maximization with a top taskbar
- Start Free Transform after placing an image from the file picker
- raster: a shifted surface copies in one pass per row without pre-filled tiles
- i18n(it): translate the 103 labels other catalogs added since #3742
- History panel: the trash deletes the selected snapshot
- ACEScg: File Handling option opens colour-less EXR renders in the ACES working space
- Layer Style: Bevel & Emboss Technique dropdown
- feat(ui): Darken and Lighten Interface (Ctrl/Cmd+Shift+F1, F2)
- Actions: Button Mode
- Embedded Profile Mismatch: profile names on the choices, and Remember this choice
- Posterize: 16-bit documents bin the 16-bit sample, as Photoshop does (two oracles pass)
- Groups: a pass-through clipping base with an adjustment renders isolated (passthrough_clipping_mask_adjustment passes)
- Threshold: split on Photoshop's luminosity of whole samples (threshold_rgb, threshold_16bits_rgb pass)
- Masks: feathers blur with exactly the feather's variance (mask-parameters-no-real-channel passes)
- 32-bit: legacy Brightness/Contrast, Channel Mixer, Photo Filter and B&W tint unclipped, as in Photoshop
- Free Transform: the box is the selection, and the marching ants follow it
- Layers panel: filter-type dropdown with Kind, Name and Mode
- Batch: Include All Subfolders (AUTO-219-5, #3753)
- fix(ui): remember the selected tool between launches (Photoshop parity)
- Brushes: import an image file as a brush tip
- Brush Settings: a response curve per dynamic control
- Pen tool: Shift constrains segments and handles to 45° (TOOL-214-10, #3751)
- Levels: whole levels at every step and Photoshop's shadow toe (levels_rgb + stack oracle pass)
- Layers panel: Clip Thumbnails to Layer Bounds
- Lab: adjustment layers composite on the stored L, a and b (seven Lab oracles pass)
- feature(ui): added brushes panel dockable with floating option
- Modern Brightness/Contrast: Photoshop's brightness curve (six oracles pass)
- Resize cursors turn with the box and with a rotated or flipped view
- CMYK: Brightness/Contrast curves each ink, as Photoshop does
- CMYK: adjustment layers composite on the document's own inks (14 oracles pass)
- CMYK: Hue/Saturation and Color Balance keep the black ink
- fix(ui): snap distorted corners to visible guides
- feat(psd): editable Filter Gallery smart filters (Chrome)
- Curvature Pen: edit finished paths (drag, add, smooth/corner) with an adaptive cursor
- Blur Gallery: Iris Blur's pins and handles on the image
- Posterize and Threshold commands use the 16-bit rules on 16-bit layers (fixes main)
- Shapes: on-canvas corner radius widgets for live rectangles (TOOL-214-12)
- Crop tool: Content-Aware fill of the area a rotated or extended crop uncovers
- Add Shift+scroll snap zoom to Photoshop zoom ladder levels
- Menu bar from the keyboard: Alt / F10 focus, Alt+letter, underlined mnemonics
- Shortcuts: a command can answer a second key (F2/F3/F4, Shift+F7, Cmd++)
- feat(ui): select guides, the guide context menu and Edit Selected Guides
- Export As: exact pixel size, named presets, and profile options
- Arrow-key nudges: a run of nudges is one History state, with Tools preferences
- Blur Gallery: Tilt-Shift and Spin Blur on the image
- i18n(es): complete dynamic UI translations
- Vector: bound flattening memory, keep over-budget dashes, cheaper edge build
- fix: limit Render Video timeline and GIF staging allocations
- fix(export): prompt for a Render Video output directory
- fix(ui): avoid overflow when allocating layer style instance IDs
- fix(doc): variable definitions follow layer id remapping on copy and load
- fix(raw): reject truncated or oversized Deflate tiles in DNG import
- fix(history): count fill caches and smart filter masks in undo memory
- fix(ui): keep the close prompt up when a Save Document script edits the document after saving
- fix(geom): clamp huge sizes in Rect::from_xywh instead of wrapping, and saturate TileCoord::rect
- Fix integer overflow in clipped warp bounds
- fix(linux): install the AppImage menu entry when AppImageLauncher skips it
- FITS: clamp 32-bit saves to 0..1 and warn, so they reopen as saved
- Properties / New Document: tiny sizes in physical units no longer resize the document
- fix(psd): write the layer block after a kept merged-transparency marker
- Options bar: Brush and Eraser size go to 5000 px in every theme
- Smart Objects: Curves preview no longer zooms in on a reduced proxy
- Fix Nikon NEF lossy levels, packed decoding and metadata crops
- Curves: apply to masks, alpha, and Quick Mask
- perf(ui): bound transform outlines and stabilize perspective clipping
- fix(heif): a grid's ICC profile is inherited from its tiles
- fix(ui): expose toolbar column toggle in all themes
- Double-clicking the empty workspace shows File › Open
- fix(ui): a held arrow key keeps stepping the focused value field
- fix(ui): ⇧ marquee square keeps equal sides on the pixel grid
- fix(engine): validate bounded extended filter parameters
- Guide Layout: the disabled Rows field no longer turns Rows on
- Fix filter preview live during drag
- Fix #5414: Keep created paths visible and editable
- fix(ui): widen tool-options drag targets
- fix(cms): write the product name as PhotoCraft in built-in profile descriptions
- Format five files on main (fmt break from #5448, #5670, #5135)
- Document layerFilter in the ui_set MCP schema
- i18n(hu): align six rows with the catalog conventions
- UI: centre text vertically in shared text fields
- fix(ui): the Move tool keeps Photoshop's arrow pointer
- fix(pen): keep unfinished paths in their original document
- Drag and drop: PhotoCraft comes to the front after a drop
- Options bar: Show Transform Controls in every theme
- Preserve Layers scroll per document
- Rulers: Alt-drag makes a guide of the other orientation
- Adjustment layers: a live preview is never coarser than the screen
- UI: unsaved-changes buttons show every key in one style
- macOS: a bundled app keeps its own Dock icon
- Title bar: dialogs no longer stop the window dragging on macOS
- fix(path): Shift locks a Direct Selection anchor drag to 45°
- Type: keep text selection highlight visible while Command/Ctrl is held
- Filter dialogs: a Random button for seeds
- Brushes: dragging a preset to the list's edge scrolls the list
- fix(ui): smart filter adjustments open their own editor on double-click
- Canvas: no scroll glide with Enable Animations off
- Scaling around reference point no longer snaps center of image to ref…
- Type: a scaled type layer keeps its size when the Character fields show it
- fix(ui): restore previous tool when committing or canceling text edit
- File › Scripts › Browse: reject Photoshop ExtendScript
- Channels: load the targeted layer mask as selection
- Type: Swap and Default Colors recolour the selected text
- Image Size, Canvas Size: points and picas follow the Point/Pica Size preference
- Pen and Path Selection: Delete deletes the finished work path
- Layer Style: drag on the image to move a drop or inner shadow
- Free Transform: shapes and paths stay on whole pixels
- Snapping: snap edges of Marquees / Object Selection box / shapes while repositioning with Spacebar
- Move: Show Transform Controls frames every selected layer
- Warp: a thin layer stretched and bent keeps its curve on commit
- Dialogs: a close box in the title bar cancels like Cancel
- Commit text editing when selecting a Layers-panel row
- Info panel: show guide coordinates while dragging outside the canvas
- fix(ui): brush outline matches the stroke on Wayland at fractional scales
- Raw: measure the Nikon D90 image area (4288x2848 at (10, 10))
- Codecs: open Cineon (.cin) film frames read-only
- PSD: write tiff blocks without copies, inflate merged ZIP once
- Content-Aware Fill: no ghost edges or object colour around thin removed objects
- Select Subject: keep subject parts coloured like the backdrop, leave enclosed gaps open
- perf: keep effect-cache pins and History snapshots inside the memory budgets
- TIFF: read and write CIE L*a*b* (CIELab, ICCLab); Lab documents stay Lab
- PSD: cap pattern memory across a parse, reject mixed-depth pattern channels
- DNG: decode lossy (JPEG-compressed) DNG tiles (FILE-215-11)
- PSD: a smart object's filter mask shows when the file opens
- File > Save As / Save a Copy / CLI can write PDF
- CI: fix the tests that keep main red, and ship the wasm as compressed parts
- fix(compose): serialize effect identity cache misses
- psd: write PSB foreign-order long-key blocks with the correct big-endian length
- ci: add comfortable runtime limits to unbounded jobs
- CI: run clippy, layers and scorecard checks before the tests
- Quick Mask: ⌘I inverts the whole mask, unstored black included
- Pen: Auto Add/Delete on the path being drawn
- Dependencies: require ruzstd 0.9.1 for RUSTSEC-2026-0344
- Control channel: connections must authenticate within 10 s, however active
- Check deep EXR tile count tables against max_alloc
- Clip groups: Release Clipping Mask takes the layers above; merges keep clipping; Delete Hidden settles
- Paste Layer Style carries Blend If and channels; align to an active selection with several layers
- Paste Layer Style: a group's Pass Through lands on other layers as Normal
- Keyboard Shortcuts: Accept and Go to Conflict / Undo Changes, and reserved keys (K4a)
- Layers panel: blend mode, Opacity, Fill and locks change every selected layer; Photoshop's History names
- CI: run the tests with cargo nextest
- CI: run only the font tests in the craft-fonts pass
- Low-Latency Drawing preference (vsync off, opt-in), plus present-mode overrides for testers
- Shortcuts without the UI: shell commands and tools in the engine, reserved keys, set files
- Free Transform: New Layer applies the transform first; tests for switching tool, layer or New Layer
- Follow-ups to #5801 and #5859: precheck docs and tests, translated refusals, stranded-backup test
- Security: enforce the automation read boundary on stored smart-filter params
- PSD: recover available layers when merged image data is damaged
- ci: delegate FreeBSD workflow to craft-common-actions and add nix check
- CI: cut wall time, starting with the Windows test job
- Canvas textures fit the device's texture limit; GPU tests use the app's device and the GPU lock
- perf(gpu): cap the GPU memory budgets by a discrete GPU's own memory
- GPU memory: discrete cards aren't charged for the document; GPU Memory preference; GPU Memory Full status
- GPU memory follow-ups: indicator after device loss and document switches, notice wording
- Save As on Linux: the file type picked sets the extension
- Tests: canvas_16f and rotation preview run on the app's wgpu device
- Windows/Linux: open files in the running PhotoCraft instead of a second instance
- perf(camera-raw): Shadows/Highlights 1.9× faster, bit for bit the same
- Histogram: scale bar heights to the tallest bin instead of the 251st smallest
- fix(linux): avoid duplicate AppImage desktop launcher when managed by AM / AppMan
- Paragraph text: a word wider than the box breaks at the box edge
- Pen: the path in progress stays visible while panning with Space
- Crop tool: custom ratios keep three decimals, 1.414 : 1 no longer becomes 1.4 : 1
- fix(codecs): respect PAM ENDHDR line boundaries
- docs(cli): write product name as PhotoCraft in USAGE and description
- fix(engine): prevent colliding artboard export filenames
- docs: write product name as PhotoCraft in crate module docs
- docs: write product name as PhotoCraft in package descriptions and comments
- perf(testkit): RSS sampler reads /proc/self/statm, not smaps, on Linux
- test(io): cover mixed-region CMYK TIFF composites
- fix(io): preserve linear grayscale profiles for selected EXR parts
- fix(io): honor version-aware OpenRaster group isolation
- fix(io): color-manage grayscale WebP exports
- Unsaved-changes prompt: the default answer takes keyboard focus, so arrows and Enter work
- fix: open new solid fill picker
- Color Picker: Only Web Colors snaps every edit
- fix(ui): reset caret blink phase on navigation and typing
- fix(engine): reserve the define-brush tip buffer fallibly
- Bound shared numeric input before text layout
- README: install on Gentoo from the ::snakebyte overlay
- Face detection: libfacedetection's CNN in pure Rust, and image.detectFaces
- fix(engine): list the document's layers when a layer id or name is unknown
- Layers panel and title: Arabic and Hebrew names read right to left
- fix(web): enable Place Embedded with browser file picker
- chore: fix workspace Clippy warnings
- README: put Community packages after the Get started status note (follow-up to #1149)
- Filters: the live preview is never coarser than the screen (fixes #6326)
- fix(io): keep transforms on imported SVG text
- GPU composite: lower-stack cache chunks have no texture view
- Text: break paragraph lines at the horizontally scaled width
- Engine: load each persisted preset set independently
- Targa: RLE packets end with their scanline (fixes #6382)
- perf(stack): Stack Mode 8–17× faster, deterministic Entropy
- PSD type: clamp warp bend and distortion before the f32 cast
- Linked smart objects: don't refresh a document while a background job runs on it
- Close All, Close Others and Quit ask again about documents dirtied during the prompt
- fix(windows): keep crash-recovery autosaves out of the roaming profile
- Save: ask before overwriting a file another app changed
- fix(automation): refuse a group/world-readable control-token file
- perf(panorama): Photomerge 4× faster, bit for bit the same
- Fix the build: restore export_presets in load_presets_json (#5344 x #5616)
- algo: gate the recorded-hash test's helpers with the test
- Quick Export: Same Folder asks before replacing the document's own file
- Opening a file that is already open shows its tab instead of a second copy
- Duotone: ink curve points must be finite
- Save: refuse to replace a read-only file
- Image Assets: two layers naming the same file no longer overwrite each other
- Desktop app: photocraft --help prints usage; unknown options are usage errors
- Logging: a second launch leaves the running instance's log alone
- Follow linked paths only on this computer or the document's share
- CI: run panic_hunt in the Linux test job
- Web: Place Embedded and canvas drops place images
- Print through CUPS over IPP and the print portal: File › Print works in the Flatpak
- Package: report its paths with / on Windows too
- Release 0.10.0
- @dutraroberto made their first contribution in
- @lu123bing made their first contribution in
- @zkm made their first contribution in
- @Pharbi made their first contribution in
- @sabbirshawon made their first contribution in
- @notdezzi made their first contribution in
- @david419kr made their first contribution in
- @badaaif made their first contribution in
- @the-unknown made their first contribution in
- @cwshields made their first contribution in
- @gorevyoneticisi made their first contribution in
- @saadkhantareen made their first contribution in
- @nrq6993-a11y made their first contribution in
- @LabDennis made their first contribution in
- @sidney made their first contribution in
- @Daktyl198 made their first contribution in
- @JuanAntonioRC made their first contribution in
- @Ahmeddouhm made their first contribution in
- @midasmatterhorn made their first contribution in
- @envy-ai made their first contribution in
- @WendelVolm made their first contribution in
- @wanikhawar made their first contribution in
- @PerchAnton made their first contribution in
- @1Git2Clone made their first contribution in
- @ahmed0magdy made their first con…
0.9.0Big update
- Use craft-print for system printing
- Tests: allow-list language-invariant bit-depth labels, add missing tr/hu 'Enable animations'
- feat(automation): allow Crop and Straighten Photos through automation
- Pencil: no 8-bit dither on aliased strokes, one flat colour at partial opacity
- Preserve grayscale appearance in profileless exports
- Save As: a saved .pcraft manifest reports the file it was saved under
- Selection: lasso polygons scan only the edges that cross each row
- Fix group transform bounds with active pixel selections
- fix(color): validate RGB working profiles atomically
- Load and save Photoshop Actions (.atn)
- feat(engine): recolor vector shape layer fill with Alt+Backspace and Cmd+Backspace
- fix(ui): default the Move tool Auto-Select target to Group
- fix(gpu): preflight compositor uniform buffer limits
- Properties: a new adjustment or fill layer brings Properties to the front
- Actions panel: set folders, dialog toggle, Insert Stop
- Delete with several layers selected deletes them, not the active layer's targeted mask
- Fix multi-layer Delete and Move drags on a locked Background
- File Handling: wire Maximize PSD and PSB File Compatibility
- View: Esc leaves full screen modes (part of #4116)
- .atn: map the remaining frequent Photoshop events
- Windows: keep full screen and maximized apart; never restore full screen
- Make channel filter previews match the committed edit
- .atn: Place, Open, Image Size in percent, Paint Bucket and Insert Conditional
- Quantize the colour field when Only Web Colors is on.
- fix(ui): cancel unfinished Polygonal Lasso when switching tools
- fix(ui): reject rotation angles outside f32 range
- fix(move): no trail when dragging a shape past the canvas edge
- Resolve every pattern name before a batch delete removes any of them.
- Brush cursor: the tip's centre mark follows Show Crosshair in Brush Tip
- Brush Settings: toggle switch rows without losing smoothing settings
- Color Table: keep the transparent index inside the palette
- Stylus: a light Windows pen tap is pressure 0, not a full-pressure click
- Filters on a type layer: ask to rasterize or convert to a Smart Object instead of greying out
- i18n(hu): informal address in the rows added on merge
- Italian: native-speaker review of the UI catalog
- Color Picker: CMYK foreground fills a CMYK document with the picked inks
- Codecs: open and save DPX frames
- Brush: CMYK foreground paints the picked inks into a CMYK document
- Paint Bucket and Edit > Stroke: a CMYK foreground writes the picked inks
- perf(raster): moved fills keep sharing one copy-on-write tile
- perf(compose): stop sweeping the bounds cache on every call once it i…
- perf(engine): move layers without a second document clone
- perf(compose): read PHOTOCRAFT_FX_NOCACHE once
- perf(engine): read selection coverage per row when mixing edits back
- Layer Style: OK keeps an Inner Glow's Center source
- Layers panel: double-clicking an effect row opens that layer's Layer Style
- Keep Liquify undo and redo working while a numeric field is focused.
- Draw the Free Transform rotate arrow instead of hiding the pointer.
- Snap 1 px pencil clicks to the pixel the aliased tip paints.
- Image Size and Canvas Size: no silent resize of large documents in physical units
- Exposure: the slider keeps fractional stops
- Shape tools: the click-to-open-dialog tolerance is the same on HiDPI displays
- Rotate View: the image follows the pointer in a flipped view
- Brush resize HUD: horizontal is size and vertical is hardness in a rotated view
- feat(codecs): support full X11 rgb.txt color names in XPM
- feat(codecs): add XPM2 plain-text image import support
- Docs: refresh gaps.md against main
- Docs: refresh target-app-parity and file-format-parity against main
- Clone Stamp and History Brush: releasing a stroke commits the live pixels
- Stylus: a pen held still is not a press-and-hold right click
- Refresh Liquify's zoomed preview when a stroke is undone.
- fix(selection): avoid panics when sampling incomplete region masks
- Type: Space inserts a space while editing type
- fix(algo): reject oversized Magic Eraser masks without overflow
- fix(selection): validate Magic Wand pixel buffers before indexing
- feat(ui): the shaped brush cursor turns and flips with the view
- Affinity import: pie shapes with huge angles no longer hang the reader
- Affinity: rectangles keep per-corner radii and straight corners
- feat(ui): spring-loaded tool letters
- Quick Selection: cut window sizes in parallel, cancel the larger ones once one is kept (-37% on 24 MP strokes, identical masks)
- PSD: a zero-length annotation entry no longer hangs the import
- Swatches: reject colour values beyond f32 range so presets survive a restart
- Compose: the effect cache follows Transparency Shapes Layer and Blend If
- Auto-Select: honour layer mask density when picking layers
- Find and Replace Text: backward Change/Find moves past the replaced text
- Liquify, Puppet Warp and Perspective Warp: refuse locked smart objects
- Count tool: Marker Size and Label Size fields take effect
- Layers panel: show the lock icon for every lock
- Automation: reject an invalid document index instead of using the active document
- Paint Bucket and Gradient: validate opacity like the Magic Eraser
- Video layers: edits keep the timeline work area
- Warp: move only the selected part of a linked mask
- Contours (.shc): keep long names valid and readable
- Global Light: reject angles beyond f32 range instead of storing NaN
- Tests: set the Move tool's Auto-Select target to Layer in the layout_perf clicks
- feat: resize Save for Web previews and custom palette editing for Gif export
- Tests: GPU startup marker tests wait while another test's child process holds the lock
- Control: a transport that gives up knows whether the command was dispatched
- Canvas: a tool drag past the edge auto-scrolls the view
- fix(linux): respect GNOME's default light appearance
- Brush Settings: Brush Tip Shape lines up with the other section names
- Properties: the Studio-layout themes show it for every layer
- Give numeric type controls translated accessible names
- Free Transform: unlinking W and H frees the handles too
- fix(ui): make clickable tab, checkbox, and radio labels non-selectable
- fix(ui): use a linear gradient ramp glyph for the Gradient tool icon
- fix(ui): add Brushes button at top of Brush Settings control list
- fix(ui): keep brush settings section lock icons permanently visible
- Layers: Fill and the Paint Bucket edit an adjustment layer's mask when its icon is targeted
- Object Selection: hover preview of the object it would select (Object Finder)
- feat(ui): add GRD import option to gradient map preset picker
- Type: every text edit respects Lock All
- Color Sampler: keep the CMYK readout in range on 32-bit documents
- Layer Comps: the warning icon clears only its own comp
- fix(type): key font menu caches on the shared engine's fonts (flaky font menu tests)
- Vector masks: validate feather like pixel masks
- Shapes: a rectangle with a negative size extends from its origin like the other shapes
- Cryptomatte: decode the .blue/.alpha rank of every channel set
- EXR: an unnamed part can be opened by the name the part list gives it
- Bitmap mode: validate the halftone screen angle
- Find Edges and Solarize: treat CMYK values as ink
- fix(compose): paint interior effects over the layer's blend mode
- feat(ui): add hamburger menu to the Brush Settings panel
- Simplify the raster stale-block filter for clippy's nonminimal_bool
- Save for Web and Export As remember their settings across restarts (FILE-215-18)
- fix(layer-picker): include text bounds in right-click layer selection
- Gradients: Photoshop's interpolation method for Gradient Overlay, gradient Stroke and the Gradient tool
- fix(type): the Type tool's canvas pick skips text in hidden groups
- Smart Objects Warp: mesh knots span the contents on a skewed placement
- Type: faux bold keeps antialiased edges at small sizes
- Free Transform: refuse outputs over a pixel budget instead of building them
- feat(ui): developer tile grid overlay (ui.set {"tileGrid": true})
- Camera Raw Filter: save and load settings as .xmp
- feat(ui): Photoshop's type formatting keys while editing text
- fix(io): read CS2 placed layers that carry only a PlLd block
- Pen: show a close cue when hovering the first anchor
- Type tool: spelling suggestions in the edit menu
- Menus keep clear of a panel that covers a maximized window (X11)
- feat(codecs): open DDS textures, uncompressed and BC1-BC3
- Color panel: the spectrum field in every theme
- macOS: big brushes keep a native outline too, and big cursor bitmaps rasterise 7x faster
- Save As: offer ICO, GIF and BMP in the file type list
- Recent files: a saved document is listed, as an opened one is
- Paths: curves stay smooth when zoomed in
- Toolbar: click and hold on Change Screen Mode opens its modes
- Puppet Warp: ⌘Z / ⌘⇧Z undo and redo pin edits
- Crop tool: the drawing crosshair, not the move cursor, inside the untouched default frame
- Clone Source: clip the overlay to a shaped brush tip
- The wheel steps the options bar's Mode dropdown for Brush, Pencil and Gradient
- Pen: Auto Add/Delete anchors on the active path
- Save As: on Windows, picking another file type changes the extension
- Toolbar: no tooltips over an open tool flyout
- Free Transform: apply a large layer's warp in the background, with progress and Esc to cancel
- Toolbar: a press outside a tool flyout closes it
- Replace Color: a canvas eyedropper picks the From colour
- Allow toolbar tool shortcuts to be remapped
- Fix macOS system dialog localization
- Engine: reject unknown params for layer.hideLayers/showLayers, opt-in registry check
- Preserve HDR and signed colors in 32-bit text rasterization
- Type: fall back to installed Indic fonts for document text
- Raw: treat DNG samples piled up below the stated white level as clipped
- Content-Aware Move: live preview of the result
- Swatches: an RGB group with the exact primaries and secondaries
- SVG: a group clipped by one path opens as editable shapes with a vector mask
- Compose: key the vector-mask cache by content, not a temporary's address
- Actions: record File › Save a Copy and play it back as a copy
- Compose: no overflow or unbounded allocation on hostile coordinates
- Smart Filters: select a filter, drag or ⌥-drag it onto another smart object
- Add Krita (.kra) import with layers
- i18n(sr): add a Serbian (Latin, Ekavian) UI catalog
- feat(ui): Linux caption buttons follow the desktop layout, style and icon theme
- Themes: Soft Dark and Soft Light
- Type: type on a path, glyphs follow the curve
- panic_hunt: don't fuzz the print commands into a real printer
- Fix main: gate rayon in the tile grid overlay so the web build compiles
- Align tighter camera JPEGs for RAW colour fitting
- Check peak RAW development memory and bound AHD scratch
- Content-Aware Fill: no tinted blotch in a smooth gradient
- Composited CMYK documents now export as CMYK TIFF and JPEG with their profile
- Open Canon CR3 as labelled camera JPEG previews
- Sample every visible layer in Content-Aware Fill by default.
- Resize the Liquify brush with Alt+right-drag
- Free Transform: the live preview feathers a linked layer mask
- perf: reuse sampled composite across channel visibility toggles
- Fix main: Serbian translations for the Soft themes
- Save for Web: no matte by default, as Photoshop's scripted export
- Load Files into Stack: Photoshop's dialog with a Source Files list and the align option
- Edit › Transform › Rotate and Skew no longer scale
- Open: warn about type in fonts that aren't installed
- Status bar: wrap fullscreen zoom scrubbing at horizontal edges
- Screen color picker: no DX12 crash, and the overlay can be left on Windows
- Add timeline playback to Save for Web previews
- Free Transform: H and V skew fields in the options bar
- Channels: drag a channel onto New, Delete or Load Selection
- Fit Image: the dialog is as narrow as its few fields
- Move tool: the curved rotate arrow just outside its transform controls
- perf(select): reuse run-table buffer in Feather horizontal pass
- Reject negative PSD style-sheet indexes
- Keep the scrollbar thumb visible
- Translate Turkish Amount as Miktar
- Use a half-filled circle for adjustment thumbnails
- Indent layer effects under their layer
- Remove the dead gap between popup menu rows
- Show (C)ancel on the unsaved-changes prompt
- Apply Image: source layer, Scale and Offset in the dialog
- feat(vector): add shape from selection with simplify tolerance
- Channels: clicking RGB hides the alpha channel overlay
- Fix: Preview pixelation in Sharpen filters
- Brushes: a New Brush Preset dialog for every way of making a preset
- fix(ui): expose custom paper dimensions in Print Settings
- Play real Photoshop action sets: TrueGrit .atn mappings and fixes
- New Document: blank presets follow the picked orientation and physical unit
- Checkboxes: a pressed box shows it, as in Photoshop
- fix(clipboard): prompt to save new documents containing pasted pixels
- perf(text): applying preferences no longer waits for the system font scan
- perf(ui): Channels thumbnails skip selection-only steps and reuse their textures
- perf(engine): Fill, Stroke and Clear keep tiles the selection doesn't reach
- Screen color picker: Esc, right-click and any click always end it
- PSD save: keep the Lr16/Lr32 padding outside the block length
- Filter dialogs: the preview keeps square pixels
- Update Japanese translations in ja.tsv
- Cursors: the pen tools show their icon, and Caps Lock swaps it for the crosshair
- Hue/Saturation: colour ranges apply in full to dull colours
- Free Transform / Warp: Photoshop's Bicubic (Keys −0.75) and a reduction prefilter
- Codecs: FITS keeps long CONTINUE strings intact on open and save
- Layers panel: shape layers show a shape badge on their thumbnail
- Brushes: Photoshop's measured round tip (hardness falloff and reach)
- Gradient options bar: the swatch covers its checkerboard at half-pixel offsets
- Layers panel menus: highlight the item a press-drag is over
- Fill keys: Alt/Cmd+Backspace recolour the text of a type layer
- Layers: right-clicking a layer-mask thumbnail opens the mask menu
- Background Eraser: one pass clears the whole stroke
- fix(engine): a pasted smart object keeps its PSD-embedded linked source
- CMYK: Invert, Posterize and Threshold on the inks; 16-bit Lab Invert keeps greys neutral
- fix(ui): click and hold on a toolbar button selects its tool
- OpenRaster: never overwrite an .ora with less than the document has
- fix(ui): floating panel groups get an opaque title strip in Studio themes
- Fix main: duplicate Japanese rows and missing Serbian mask strings
- fix(text): preserve hyphenated PSD font identity on reopen
- feat(gpu): composite Blend If on the GPU
- Pen: a close-path pointer over the first anchor
- Color: Dot Gain 20%-compatible default working gray, as in Photoshop
- perf(engine): Edit › Copy shares whole tiles instead of rebuilding them
- Select › Sky: a white or grey backdrop that reaches the bottom is not sky
- Properties: Align and Distribute with the Background in a multiple selection
- Layers: Add vector mask makes the mask from the selected path and targets it
- Handle signed coordinate limits in the Offset filter
- perf(ui): Duotone and live-adjust display documents are built once per snapshot
- Layers panel: clicking a row's lock icon unlocks the layer
- perf(raster): mode and depth conversion keep shared tiles shared
- feat(ui): bidirectional hover highlighting between Layers panel and canvas
- Filters: ⌘Z steps the open dialog's settings instead of the document
- Keep close gradient stops on the CPU
- perf(camera-raw): convert both previews in parallel bands
- perf(algo): filters read the selection once per tile when mixing it back
- fix(batch): skip recorded Quick Export steps when writing batch output
- fix(type): preserve keyboard focus when searching for fonts
- feat(export): offer ICO in Export As with dimension validation
- Fix print fuzzing and Windows crop GPU test fixtures
- feat(print): Printer menu lists the system's printers (file.printers)
- i18n(pt-br): fix 12 Brazilian Portuguese strings
- feat(new-document): add ISO B3 and B4 print presets
- i18n(ru): fix counted status agreement and font weight labels
- fix(input): support precision trackpad pinch zoom on Linux
- Brush Settings: disable minimum inputs when Control is Off
- Brush: the Mode dropdown shows in every theme, not only Pro
- Channels: Channel Options dialog to make alpha channels spot colours
- fix(macos): default generated droplets to a user directory
- fix(clipboard): paste JPEG, BMP and other non-PNG images on Wayland
- fix(format): contain directory-bundle symlinks without slow autosaves
- Scorecard: Smart Object corner skew and perspective is done (FILE-215-6, #426)
- docs: credit Ufuk Efe in people.toml
- Save for Web: JPEG chroma is full (4:4:4) above quality 50, as in Photoshop
- Flat export: a Lab document with one layer isn't reported as flattened
- TIFF: save uncompressed by default, like Photoshop
- fix(segment): stop push/relabel looping forever on unreachable nodes
- PSD: a version 3 Photo Filter colour is XYZ relative to the D50 white
- Validate merged PSD channel indices before decoding
- fix(psd): reserve imported layer IDs when allocating section dividers
- fix(canvas): open small images at 100%, not at the display scale
- Brush Settings: no section title above the options pane
- Save: a name without an extension gets the suggested one
- A file dropped on the canvas applies the open Free Transform and is placed at once
- fix(ui): an open Free Transform box takes Zoom tool drags and clicks
- Shapes: test that the options bar Fill swatch recolours the shape just drawn
- Alerts: Enter is OK, but not the Enter that raised the alert
- Toolbar: clicking a tool's button again closes its open flyout
- Themes: default light theme to Pro Light to preserve the Pro layout
- i18n(ru): translate dynamic selection, theme and measurement labels
- Smart Filters: Delete removes the selected filter, not its smart object
- Canvas: the CPU canvas shows crisp pixels when zoomed in
- Layer Style applies an open Free Transform first, so its preview shows
- fix(gradient): options-bar Opacity updates the live gradient layer
- Fix: native gesture fallback dedupe
- Keep applied guide layouts visible after preview closes
- Type options: the wheel over the font menu steps through the families
- Navigator: one zoom row as in Photoshop: the percentage, Zoom Out, the slider and Zoom In
- fix(ui): display uppercase hex values in the color picker
- Pen: a new path joins the selected path instead of replacing the Work Path
- Brush import: Dual Brush spacing comes from its tip
- Fix Color Balance Preserve Luminosity with multiple midtone sliders
- PNG: a whole-ppi pHYs reads back whole (300 ppi stays 300)
- io: a tagged CMYK file's merged image reads through its own profile
- perf(raster): moving a layer no longer stores tiles of only the default pixel
- perf(gpu): closing a document frees what the compositor holds for it
- Direct Selection: arrow keys nudge the selected anchors
- Brushes: preset card size numbers stay clear of the tips
- Shortcuts: ⌥⇧⌘N makes a new layer without the dialog
- Brush Settings: use an amount slider for Hue Jitter
- Keep custom title bar draggable while dialogs are open
- Assign Profile: list only profiles of the document's colour mode
- Symmetry: Transform Symmetry gets commit/cancel buttons and its own cursors
- Layers: Ctrl+Alt+G releases the clipping mask when pressed again, as in Photoshop
- UI fonts: draw a variable CJK fallback at Regular, not Thin
- Smart Filters: drag a filter up or down its stack to reorder it
- New Document: a custom background colour, from Custom… or the swatch beside the menu
- Polygonal Lasso: drop the polygon on a…
0.8.2Big update
- Adopt shared docking while preserving panel controls and workspaces
- GPU composite: reuse unchanged lower-stack chunks for property edits
- Design: bounded GPU stack prefix reuse for property edits
- feat(ui): allow disabling Studio canvas background dots
- File Info shows Camera Data from EXIF/XMP
- fix(canvas): update Move transform-control cursors on first hover
- Releasing a brush stroke no longer freezes: the commit takes the pixels the live stroke already drew (P32: 136 ms → 0.8 ms)
- fix(brush): interpolate pen pressure across Shift-click connecting strokes
- fix(transform): commit Free Transform on an outside click
- app.save: encode on the save worker, not the UI thread
- fix(shortcuts): reject malformed bindings and correctly display Plus
- Favorite themes from the appearance button's right-click menu
- Render Video: animated GIFs keep their transparency
- fix(type): exclude text inside hidden groups from automatic hit testing
- Enhanced Controls: wire Zoom with Trackpad Pinch
- Units & Rulers: wire the Type units preference
- fix(type): use the correct line at soft-wrap caret boundaries
- fix(masks): preserve off-canvas alpha in From Transparency
- Rulers: keep tick marks and labels out of the origin corner
- fix(psd): Improve interoperability and decoding
- fix(layers): remap linked-layer groups when copying between documents
- Brush HUD: wire Vary Round Brush Hardness and Brush Preview Color
- fix(history): preserve an empty layer selection across undo and redo
- Auto-Align Layers: register focus and exposure brackets by intensity when there is nothing to match
- Double-clicking a mask thumbnail in the Layers panel now opens that mask's settings
- fix(layers): select Shift ranges in visible panel row order
- Auto-Blend Stack Images: fuse the merged layer per pyramid level by region energy, with halo control
- fix(io): preserve group fill opacity in OpenRaster exports
- Control channel: input methods reject bad params instead of using defaults
- fix(vector): pivot explicit path transforms on target layer
- General: wire Beep When Done for finished background jobs
- fix(vector): preserve scaled live-line thickness during endpoint edits
- fix(actions): avoid replaying Browse script edits twice
- i18n test: scan past small test modules; translate what it was missing
- fix(masks): bake feathered coverage when applying a layer mask
- Type: wire Font Preview Size for the font menu samples
- fix(video): retain original footage for Restore Frame and Show Altered Video
- Improve zoomed Liquify preview detail
- fix(compose): preserve Dissolve coverage for adjustments, styles and clipping
- Color Replacement tool on the toolbar
- fix(shapes): preserve transformed outline on unchanged live geometry edits
- Crop tool: New / Delete Crop Preset saves and removes user presets
- Test Move layer edges across bit depths and view modes
- fix(type): preserve formatting for trailing empty paragraphs
- Keep custom crop ratio fields editable
- raw: fit non-DNG colour to the camera's embedded JPEG
- Add Anchor Point and Delete Anchor Point tools
- fix(crop): stabilize resizing and apply ratio changes immediately
- Layers panel: load a fallback font for layer names in other scripts
- Type: ⇧⌘> / ⇧⌘< change the type size (and work on Nordic/German layouts)
- CLI: batch plays an action from an Actions set with the whole set loaded
- Droplets: carry the actions their Play Action steps call
- Spot Healing: Content-Aware dab no longer scans every patch in full
- Layers: double-click a shape layer's thumbnail to pick its fill colour
- TGA: targa options asks for 24 or 32 bits/pixel, same as in Photoshop
- Tools: remember tool options between launches
- Options bar: Reset Tool and Reset All Tools
- Free Transform: right-click menu with the transform modes, rotate and flip
- Channels: Edit › Transform works on a targeted alpha channel
- Free Transform: themed rotate cursor and live angle/size/offset readout
- Move tool: drag a marquee from an empty spot to select the layers it touches
- View: Pattern Preview tiles the document around the canvas
- Tools: Freeform Pen and Curvature Pen
- Tools: Horizontal and Vertical Type Mask
- Speed up large feathered mask refreshes
- Tools: Artboard tool
- Tools: Perspective Crop
- Actions: toggle, reorder and delete single steps
- Text fields: drag-selecting in a single-line field follows the pointer's x
- perf: repeated Select Subject answers from the last mask
- Dropdowns: press, drag onto an option and release to choose it
- perf: Select › Modify › Feather/Smooth on 24 MP within budget
- Refine gradient stop controls in Properties and Gradient Editor
- perf: duplicating a layer recomposites only where the copy draws
- Status bar: buttons sit inside the bar with centred labels
- perf: keep resident GPU tiles and convert 32-bit tiles directly for brush dabs on large documents
- Themes: Photoshop's light-gray and light Pro brightness levels
- scorecard: twenty rows describe work that is already in the tree
- perf: marquee selections on large documents are built row by row
- Tools: Frame tool
- Add Photoshop-style guide layout dialog and live preview
- perf: pasting a layer recomposites only where it draws
- Image Size: Photoshop's resampling, measured
- Toolbar: Pro themes draw tool glyphs at two thirds of the button
- MCP bridge: reconnect before idle sockets die, retry reads, actionable timeouts
- Dropdowns: type a letter to jump to an item, Enter to choose
- Layers: right-click an effect row for the layer style menu
- Smart Objects: linked smart objects follow their files while open
- Place: wire Always Create Smart Objects When Placing
- Preferences: wire Tools › Show Transformation Values
- Channels: keep RGB off while an alpha or mask is shown, and select from that channel.
- Tools: wire Enable Flick Panning for the Hand tool
- app.open: open directory .pcraft through the automation read root
- Layers: Pattern Fill dialog for new and edited pattern fill layers
- Layer Style: contour picker and Contour Editor
- Type: wire Show Font Names in English
- Text fields: right-click edit menu
- control: allow requests that operate an open Camera Raw dialog
- Pixel grid: fade the line colour across mid-tones instead of flipping at one luma
- Tests: the marquee ellipse check walks several dash periods of the curve
- Fix Shape Stroke controls, popup interactions and paint colours
- Fix canvas context menus closing immediately on trackpad taps
- 8-bit documents: soft, low-flow brush strokes are dithered instead of banded
- fix(ui): reduced suffix spacing width in the value field to prevent overflow
- Rulers: remember View › Rulers for new documents; guides as f64
- Mirror the shell for right-to-left UI languages (DIST-220-4)
- Type: Edit › Paste, Copy and Select › All work on the text being typed
- New Document: presets follow Units & Rulers › Preset Resolutions
- Dialogs: the live dialog stays in front of older ones (stuck stacked profile prompts)
- Window menu: list the open documents, the active one checked
- fix(ui): respect explicit dropdown defaults in schema dialogs
- PSD: don't inflate an over-budget ZIP merged image at parse time
- i18n(es): native-style review of the Spanish catalog (Dodge/Burn swap, Photoshop terminology, formal register)
- Type tool: right-click menu while editing text
- Preserve HDR range in float adjustments and stack statistics
- Speed up large Content-Aware Scale operations
- fix(zoom): Alt-click with the Zoom tool on desktops that take Alt+cli…
- Select and Mask: live preview in Photoshop's view modes
- Five exact-output speedups: dense Extrude 160s to 0.39s
- fix(ui): respect native desktop scale under Auto UI scaling
- fix: macOS Monterey crash on Intel Iris Pro (disable wgpu indirect validation)
- fix(engine): allow targeting layer mask and vector mask via channel.target
- Tools: Convert Point tool in the Pen flyout
- fix(ui): unchanged Custom Proof Setup replaces active document proof profile
- PSD: cap the layer tree in psd_to_document; layered TIFF checks group depth
- Type menu: Anti-Alias › None first and checked; checks follow the edited layer
- fix(ui): Global Light opens with stale values and overwrites document setting
- Color Sampler tool
- Clip the checker under rounded colour swatches to their corners
- ci: refactor workflows to use storytold/craft-common-actions
- Speed up Tilt-Shift with existing per-level halo trimming
- Select and Mask: Refine Edge Brush
- Layers: Combine Shapes merges the selected shape layers
- Move dock tabs between groups individually
- Add built-in rainbow gradient presets
- Native brush outline and crosshair cursors on macOS, X11 and Wayland
- Menus: a submenu stays open while the pointer heads for it
- i18n(pt-br): complete Brazilian Portuguese catalog (+782 missing UI, filter, and tool strings)
- Zoom and Hand tools: right-click the canvas for the view menu
- Quick Mask: an empty start and Select All stay apart
- raw: charge the lossless-JPEG intermediate and segment-sized buffers against max_alloc
- Prevent white flash when opening the screen color picker
- Add FITS read/write (astronomy images)
- ui: keep the Color panel knob in the corner it was dragged to
- Rulers: stay level and fully ticked on a rotated view; guides turn with the image
- ui: Dust & Scratches previews at full resolution, as it applies
- Open several files in name order, keeping it for background opens
- GPU canvas: price the display textures before building them
- Move tool: double-click type on the canvas to edit it
- Free Transform: right-click W or H to pick their unit
- Type: variable font axis sliders; optical size follows the type size
- Tests: panic_hunt reruns a timed-out command before calling it hung
- Cycle Color Lookup LUTs with keyboard and wheel
- Fix/3144 taskbar maximized
- File Handling: wire Image Previews to embed a PSD thumbnail
- Select and Mask: Output To New Document, with or without a layer mask
- Inspect: report each layer's vector mask
- Pen: Alt breaks a handle while drawing, and close-drag pulls out the first anchor's handles
- Type: Warp on live type takes the warp styles and stays editable, no prompt
- feat(ui): Motion Blur and other filter angles get the angle dial
- Free Transform: ⌘-drag of a corner scales editable type instead of distorting it
- Color panel: HSB on sRGB values, like Photoshop
- fix(shapes): options bar Fill/Stroke edit the selected shape
- Installed ICC profiles in the profile menus, and Mirror in Print
- Window: a window saved while minimized reopens at the minimum size, not 160 × 64
- i18n: translate the Select and Mask dialog labels
- Color: honour the EXIF sRGB tag on open; wire Ignore EXIF Profile Tag
- Linux: say so when no file dialog can open; read ldconfig on non-English systems
- fix(paint): respect Lock All on layer masks
- Transform: Distort, Perspective and Warp keep shape layers live
- fix(gradient): respect Lock All on Gradient Fills
- fix(ui): focus and select hex field when color picker opens
- Type: scan system fonts off the UI thread
- fix(type): respect Lock All on text edits
- fix(type): return caret after normalized CRLF insertion
- Toolbox: make the colour swap arrow clearer
- fix(type): navigate adjacent line with large leading
- fix(ui): drop doubled options-bar borders reintroduced in UI.9
- Transform Path: Distort, Perspective and Warp apply to paths
- fix(crop): unlock Background when extending canvas
- Fix Camera Raw preview color management
- fix(mode): restore indexed pixels after clearing transparency
- Marquee: Single Row/Column Marquee History step names
- fix(cli): skip recorded view and save steps in batch
- Properties: a new adjustment or fill layer shows its settings, not its mask
- fix(filters): process untouched Reveal All masks
- Keep the Color panel selected when switching themes
- fix(history): read locked history sources
- automation: refuse edit.installedProfiles, it scans the OS profile folders
- Keep transform controls with moved selected pixels
- SVG: warn when text has no font to use (fixes the FreeBSD svg test)
- Crop tool: switching to another tool commits the pending crop
- fix(warp): Perspective Warp moves only the selected part of a linked …
- Paths: Stroke Path with any brush-based tool and Simulate Pressure
- fix(image): arbitrary canvas rotation moves position-locked children in groups
- i18n(cs): translate the dynamic labels the Czech catalog was missing
- Artboard tool: '+' buttons add a board beside the selected one; ⇧ keeps proportions
- fix(transform): identity transform makes feathered selection edges translucent
- Let the Actions step list grow with its panel
- Layers: clip groups follow New Layer, Arrange, Reorder and Delete
- Type Mask: Shift/Alt at commit add to or subtract from the selection; no Layers row for the working text
- Quick-export each selected layer as a separate PNG
- scorecard: FILE-216-5 save-path tests are in the tree
- Actions: a command that runs other commands is recorded once
- Type: triple-click selects a line, quadruple a paragraph, five clicks all text
- Layers: the New Layer dialog (Layer › New › Layer…, ⇧⌘N)
- Color Picker: no bigger than Photoshop's (532 × 376 points, was 682 × 437), buttons sized to their labels
- Artboards: a board moved past the canvas origin grows the canvas left/up
- Optimise computed brush coverage and native raster row writes
- fix(crop): the crop box's own Undo/Redo
- Freeform Pen: Alt-clicks draw straight segments; Cmd/Ctrl is Direct Selection with the new pens
- test(gradient): guard the on-canvas midpoint diamond drag
- Actions: Last Filter is recorded as the filter it repeated
- Content-Aware Move: Transform On Drop
- Numeric fields: typed units, scrubby labels, double-click reset
- Keep fitted Camera Raw colour during tuning and crop Nikon D5100 borders
- Preserve surrounding whitespace in OpenRaster layer names
- Tests: one GPU harness at a time in every GPU test binary (WARP crash)
- Content-Aware Scale: transform box with live preview
- automation: doc.place reads a file through the read root
- Layers panel: Shift+Plus/Minus cycle blend modes; effects dropped on the Trash are deleted
- Moving type keeps its rendering: Artboards to Files no longer drops PSD text
- Shortcuts: layout-independent brush keys, Photoshop's German keys plus a fallback for all layouts
- Liquify: the brush fades to nothing at its edge at every Density
- test(paint): pin the retouch dab footprint to the Full Size ring
- Layers panel: a mask dragged onto the Trash asks to apply or delete it
- PNG export: Indexed Color keeps the document resolution
- Layers panel: dragging the vector mask to the Trash asks to delete just the mask
- Interface: an Enable Animations preference
- Edit > Copy takes a targeted layer mask, so masks travel between layers and documents
- automation: export layers, data sets and CSVs through the granted roots
- Type: fall back to installed Khmer, Lao and Burmese fonts
- Curves: pencil mode, Smooth and Edit points
- fix(io): smooth PSD gradients no longer overshoot their stops
- Codecs: decode PNM straight into the budgeted output buffer
- Properties: Curves adjustment layers get the black/gray/white eyedroppers
- Format: admit the declared .pcraft canvas before loading it
- fix(format): persist the Save As filename in .pcraft manifests
- Levels: black, gray and white point eyedroppers
- Puppet Warp: the mesh follows the object outline
- Clone Source: W/H link and overlay blend modes
- Vanishing Point: on-canvas plane editor with Create/Edit Plane, grid and paste
- Let [ shrink the brush to 1 px
- MCP: command_batch says it is not atomic, and the docs explain recovery
- New Document: a real Recent category of recently created documents
- Group effects follow their children's effects, not just their pixels
- Format: reopening a .pcraft shares deduplicated tiles again
- fix(presets): never overwrite preset or actions files that failed to load
- fix(engine): create new layer masks at the document depth
- feat(api): add file path to document.inspect
- Ctrl-click shape and path thumbnails to load selections
- fix(selection): scope Color Range to the active selection
- Layer › Duplicate Layer… asks for the copy's name and destination document
- Copy takes every selected layer, Paste recreates them
- Fix GIMP hole heading name and location
- Commands check an explicit "layer" instead of whichever layer is active
- Brush cursor: shaped tips trace their outline (split from #2516)
- perf: Edit > Clear works tile by tile on large selections
- Autosave: best-effort cleanup after commit; sweep orphaned recovery bundles
- Raw: open monochrome LinearRaw DNGs (1 sample per pixel)
- PSD gradients: read the interpolation method Photoshop writes; add Smooth
- CI: restore tests, catalogs, and web size gate
- Color Balance: Photoshop's per-channel levels and gamma curves
- Save: show save progress as Saving NN% in the status bar and tab title
- Warp presets: Photoshop's Bezier control grids instead of approximations
- Brush and Pencil: hold ~ to erase, and Clear mode
- Content-Aware tools: faster, cancellable at once, same pixels (P21, P22, P49)
- fix(io): a fresh Metrics type layer writes no empty Txt2 stub
- Brush: show the smoothing string from brush to pointer
- Security: verify AppImage build inputs
- History panel: snapshots (camera button, snapshot rows, history.*Snapshot)
- feat(ui): Photoshop's New Guide: units and colour
- Tools: Shift key switches tools by default, as in Photoshop
- Use Fontconfig for Linux font discovery
- Use each XRandR output's ICC profile in the screen picker
- Support automatic monitor ICC profiles on Linux X11
- Security: harden document exports and automation inputs
- Animated GIF: every frame loads into video layers
- GPU memory budget: read installed RAM on Windows
- fix(ui): correct the clipping-mask indicator orientation
- Windows installer: refuse Windows 7 and 8 with a clear message
- Format: index ZIP entries by name and use crc32fast
- psd: harden the standalone binary parsers (fuzz + property tests, gradient/swatch correctness)
- Add Vietnamese localization
- Linux: StartupWMClass is the window's app id
- M11: ten more MCP acceptance tasks (11-20) for FILE-216-6
- fix(ui): don't reopen floating Brush Settings on restart
- M11: six rounding-out acceptance tasks (31-36)
- Options bar: the Gradient tool's controls show in every theme
- fix(ui): one eliding label for fixed-width chrome, so translations can't overrun
- test(ui): marquee shift+alt before the drag intersects the selection
- Crop tool: a resized frame snaps its handle, not the pointer
- fix(transform): keep nearest-neighbor previews on original texels
- fix(engine): image.canvasSize rejects unlisted anchors instead of landing between two
- Edit › Transform › Skew: corners and sides move along one axis, like Photoshop
- PSD: alpha channel resources count the merged transparency; 13-byte DisplayInfo
- Glows: Photoshop's precise ramp; centre-source glows inverted after the contour
- Canvas: wheel/pinch zoom over the pasteboard keeps the image in view
- Select: open the Save Selection and Load Selection dialogs
- Toolbar: the colour chips sit right under the tools again
- Fix: video frames to layers working using folder dialog request
- Menus: keep clear of the taskbar when Wayland hides the window position
- i18n(it): translate the dynamic labels the Italian catalog was missing
- Chisel bevels: Photoshop's facet slope and ramp ends
- Character panel: OpenType feature buttons (TYPE-218-5, #3752)
- Brush: symmetric live strokes update only what changed
- Move: an unlinked layer mask moves alone when targeted
- fix(ui): drag a document tab off the strip to float it in its own window
- fix(web): keep the canvas steady during preset saves
- UI: drag to reorder swatch groups and preset folders
- Keep transform preview visible while panning
- perf: draw marching ants as one mesh instead of a line shape per dash
-…
0.7.0Big update
- docs: register the MCP server from an installed release
- docs(adjust): align Levels and Curves comments with evaluation order
- Preserve unchanged XMP translations in File Info
- Smudge: use the Brush Settings spacing for retouch strokes
- Fix layer mask toggle action labels
- Fix hyperlink in credits panel
- Layers: mask thumbnails update after Invert and other whole-mask edits
- Keep the selection when smart selection finds nothing
- fix(layer style): wrap Make/Reset Default buttons
- i18n(ru): translate layer style effects
- Layers panel: Opacity and Fill share one right-aligned column
- Ignore hidden RGB when Magic Wand selects transparency
- Canvas: clip the Free Transform preview to the canvas
- fix(ui): avoid drawing panel borders twice
- Layers panel: press-drag-release picks a fill or adjustment layer
- fix(engine): select neighbouring layer after deletion
- Preferences: the dialog grows with the window
- scorecard: Marquee modifiers and brush resize drag are done (TOOL-214-2, TOOL-213-10)
- Confirm layer deletion only from the Layers trash button
- Soft brushes paint soft strokes and thin lines stay even: a Gaussian-like tip and area coverage for tiny tips
- TGA: save the document's alpha channel as 32-bit alpha
- Preserve quoted multiline variable CSV records
- Workspace: wire open_documents_as_tabs preference
- Expose Clone Stamp opacity and flow and apply them to strokes
- Masks: target a new layer mask and keep separate colour pairs for mask and pixels
- Default layered edits of flat images to PSD on Save
- Selection cursors: badges for cutting, copying and dragging the selected pixels
- Tools: double-clicking a layer mask launches Select and Mask with preference
- Add pixel mask density and feather controls to Properties
- Cmd held is the Move tool with the painting tools (Cmd+Alt duplicates)
- Hand tool: an open hand and a fist as the pointer on Windows, and the fist while panning everywhere
- Move tool on a locked layer: Photoshop's message
- fix(ui): remove the gap beneath Spectrum document tabs
- Web: leave the JPEG XL DNG decoder out of the wasm (25.1 MB -> 24.3 MB)
- fix(ui): mode buttons respect two-column toolbar
- Layer › Rasterize acts on every selected layer; the Layers menu offers "Rasterize Layers"
- Fix SVG selection and import detection
- Pen pressure curve: Preferences › Tools shapes how pen pressure reaches every brush
- feat(ui): allow toolbar to scroll
- GPU startup: CPU mode on Linux falls back to Vulkan to present the window
- Layers menu and layer commands follow the selection, not the active layer
- Window edges: easier to grab, theme-safe cursors, and no lost hover after a resize
- fix(engine): reject invalid core-filter parameters
- Keep duplicated Smart Objects linked to shared contents
- fix(ui): complete system appearance selection and styling
- Add the Remove tool with non-local patch completion
- Regenerate docs/scorecard.md after #2193
- fix(engine): Image › Adjustments on a smart object records a smart filter (FILE-215-4); strokes honour the document CMYK profile
- Expand arithmetic expressions across numeric inputs
- automation: accept absolute paths beneath the automation roots
- Filters: preview at the scale OK applies
- Load Thai fallback fonts for native UI text
- Content-Aware tools: Photoshop's behaviour, measured
- Apply Type formatting to selected text layers
- Distance fields on threads: bevel size changes 2-3x cheaper
- EXR: Cryptomatte layers list, decode and hash to the specification
- Expose native shape stroke controls with staged previews
- Select and Mask: 4x faster CPU refinement with exact octagonal morphology
- Addition : Brush popup better UI
- kys import: first launch asks before importing; edit.keyboardShortcuts importKys (#1987 review)
- OpenRaster (.ora) open and save
- automation: test root look-alike siblings and sub/../.. climbs (#2216 follow-up)
- Canvas: UI Scale must not magnify the image
- Free Transform: the Hand tool no longer steals a resize drag
- Clip warp tiles at the inverse horizon so steep Distort commits keep every pixel
- GPU canvas: re-upload a layer or mask texture when its default pixel changes
- fix(selection): constrain Polygonal Lasso segments with Shift
- fix(properties): expose equal-gap horizontal and vertical distribution
- Fix snapping when drawing a new crop inside the default frame
- Capture marquee selection modifiers at mouse press
- Marquee: keep one-pixel rows and columns on release
- Move tool: outline follows the moved layer
- Move tool: Ctrl/Cmd+arrow nudges the layer from any tool
- Move tool: Auto-Select picks a type layer inside its text bounds
- Tools: a tool key brings back its group's last-used tool
- Zoom tool: double-click zooms to 100%
- Canvas: right-click outside the image opens the pasteboard colour menu
- Spot Healing: the drag trail shows the dabs the heal covers
- Preserve the Zoom drag anchor in rotated views
- Selection feather: the radius is the Gaussian's sigma, as in Photoshop
- Select › Modify › Smooth: a hard threshold, as in Photoshop, not soft edges
- Select › Modify › Border: Photoshop's soft band, 2r wide, not a hard r-pixel ring
- Keep surrounding spaces when renaming a layer
- Layer commands accept an explicit layer with none selected; Deselect Layers is a no-op when nothing is selected
- fix(engine): list running jobs before ended ones in jobs.list
- fix(psd): an unedited save writes Photoshop's Txt2 back unchanged
- Remove tool: an empty layer is a no-op instead of running the fill
- fix(vector): Stroke Path refuses pixel-locked and fully locked layers
- fix: Preserve CMYK solid and gradient fills through PSD round trips
- fix(codecs): exports drop the source's EXIF thumbnail
- fix(vector): Fill Path stays inside the active selection
- Let Edit > Fill and the fill keys fill an adjustment layer's mask
- fix(document): restore layer comps when duplicating documents
- Float the layer mask, not the layer, when the mask is targeted
- Quit and Close All: answering No closes that document
- Save As to a flat format keeps the layered original
- OpenEXR/HDR export: linearize grayscale documents too
- TGA: a 32-bit Targa opens with its alpha as "Alpha 1", as in Photoshop
- Keep Duotone ink colours when converting to RGB, CMYK or Lab
- Reject colliding data-set export filenames before writing
- Save and export dialogs remember where each document was last saved
- Open file pickers for Replace Contents, Export Contents and Convert to Linked
- Fix current .af artboard recognition and preserve editable boards
- fix(blend): keep 32-bit Hue/Saturation/Color/Luminosity above 1
- Render: Tree and Picture Frame accept whole numbers sent as floats
- Extended filters: an unknown option is a bad-params error (#2228 follow-up)
- Legacy Brightness/Contrast: brightness first, then contrast around 128, as in Photoshop
- Bevel contour: drop the glow-style Range stretch
- Blend modes: Fill below 100% works inside the blend for Photoshop's special eight
- Issue #2326: Hue/Saturation Colorize at 0% saturation gives grey, not a 25% tint
- cms: accept ICC DeviceLinks whose output isn't a 3-channel PCS
- fix(ui): keep menus responsive on documents with thousands of layers
- Shift-click New Group groups the selected layers
- Fix/2361 scrub layer labels s20261010 t083444 z og3kyw
- Filters: full-resolution preview for Add Noise, Wind, Extrude, Tree, the Filter Gallery and more
- Handle allocation failures in large pixel operations
- fix(layers): preserve Background behavior across merge, duplication and canvas resize
- Fixed a bug where if you select a mask and hit the delete key, it deletes the image
- fix(ui-egui): ui.key with ctrl does not trigger shortcuts off the Mac
- Warp Text: the dialog opens with the layer's warp and previews it live
- Text fields: copy, cut and paste through the Mac menu's key equivalents
- Filter Gallery: preview at the scale OK applies
- Paste: a web Ctrl/Cmd+V key press and its paste event are one paste
- Opening card: a long file name no longer pushes Cancel out of the card
- Windows: keep the custom title bar's window borderless
- Image Size and Canvas Size open on Width, selected
- Close a document tab with a middle click
- Dock splitters push the neighbouring groups instead of stopping
- Dropdowns: open lists start at their widest option's width
- DNG: lossy compression 34892 (baseline JPEG tiles)
- Command palette: don't list menu separators
- fix(ui): restore muted text color for disabled Layer Style effects
- Number fields: centre digits vertically
- Menus: Reveal in Finder names the platform file manager off macOS
- Enable menu Cut for selected type text
- Create new documents by double-clicking presets
- Re-render shapes when an artboard move grows the canvas
- Curved shapes no longer report bounds 1 px too wide
- Crop tool: W x H x Resolution mode resamples the crop to a size and resolution
- EXR parts: import parts, channel groups and an AOV precomp as layers
- fix(ui): toggle color swatches when selecting or deselecting a layer mask
- Skip distant TSL-off stroke layers during composition
- Ctrl+Tab and Ctrl+Shift+Tab switch to the next and previous document
- Keep plug-in menu rows under Filter › Plug-ins in every language
- Color panel: the field and hue strip fill the panel height
- Speed up Iris Blur without changing output
- fix(ui): unify Spectrum menu spacing and hover contrast
- Colour swatches open PhotoCraft's Color Picker: filter dialogs, Preferences, Note, Count, artboard (part of #2144)
- Dialogs: Tab walks the text fields only; New Document opens with its name selected
- Search: an exact name match ranks first
- Channels: tint single colour channel views on the canvas with Show Channels in Color
- Pixelate: CMYK Facet 13.7x faster, Lab halftone 5.0x faster
- Tests: line-tables-only dev debuginfo, nextest GPU group, faster loop docs
- Free Transform: refuse a locked layer up front, with Photoshop's message
- Crop tool: Photoshop's default mode turns the image behind an upright box; Use Classic Mode (P), Auto Center Preview
- Free Transform: keep the layer's place in the stack
- Quick Selection: 3.5x faster CPU strokes with hybrid graph cuts
- Image warp: grab anywhere on the grid, Ctrl-click to cut, Warp in the transform menu
- Layers panel: a dragged layer copies onto its own row and into the empty space below the stack
- Properties ▸ Layer Mask: add Photoshop's Refine row
- Ruler units keep their own decimal places
- fix(docs): Linux build prerequisites only name Debian packages
- i18n(es): translate the Add Noise and Reduce Noise dialog controls
- Type: wire Use Smart Quotes for typed text
- Progress docs standard: ROADMAP, target-app parity, gaps, per-dimension parity docs
- Keep As Is when reusing variable definitions
- File > Scripts > Browse: filter the picker to script files
- PSD export: pad regenerated fill blocks to 4 bytes, as Photoshop does
- PSD: warn on an unreadable Lr16/Lr32 layer block and save one layer list
- Channels: Delete with one channel targeted clears only that channel
- Fix Windows-only path expectation in save dialog test
- Channels: Delete with an alpha channel targeted fills that channel
- Lasso: Free Transform drags work with the Lasso tool selected
- Copy and paste a single channel from the Channels panel
- Move tool: the drag's box and snapping follow the Auto-Selected layer
- Channels: Cut with one channel targeted clears only that channel
- Move tool: ⌘-drag temporary Move gets the drag box and snapping
- Smart Objects: converting several layers keeps them at the contents top level
- feat(prefs): add intermediate UI scale options from 80% to 95%
- Smart Objects: stacked layers sit at the contents top level
- Selection: moving a selection outline snaps its bounds, not the pointer
- Batch: a failed step inside a called action fails the file and the script
- fix(ui): make painting symmetry available across all themes
- Guides: ⌘-drag over a guide moves it with the selection tools too
- Keep the blend-mode preview between list rows
- Lasso: ⌘-drag outside the selection moves the layer
- Esc deselects when no active operation needs cancelling
- Actions: record File › Save and Save As steps and replay them
- Batch: skip recorded view steps in batch and droplets
- fix(navigator): zoom the document with the mouse wheel over the preview
- Home screen: remove individual Recent entries
- Move tool: ⌘-drag with a painting tool floats the selected pixels from the control channel too
- Actions: double-click an action to rename it
- Brush cursor: Normal Brush Tip ring on the tip's real 50% contour
- fix(ui): prevent Layers opacity controls from overflowing narrow docks
- Image Size: Resample off keeps the pixel readouts honest
- Paint a pen tap at its own pressure, not full or zero
- i18n: wrap remaining hardcoded UI strings for translation
- fix(compose, gpu): round dithered gradient fills to the document dept…
- Pencil/Eraser: round Pencil cursor and Eraser Pencil mode
- Linux: no false missing-library warning when the linker cache can't be read
- Speed up large group merges
- Interface: wire Dynamic Color Sliders for the colour tracks
- Eraser: Block mode
- Smart filter edits: re-render from cached stages, in a background job
- Brush: Wet Edges acts on the whole stroke, not each dab
- Spot Healing: Create Texture keeps the film grain
- wasm: gate native-only constants so wasm32 builds without dead-code warnings
- Marquee hinting follows a rotated view like the release does
- Place: wire Resize Image During Place into the implicit fit
- Free Transform frames the whole type layer; Distort/Perspective greyed for type
- Tests: save-dialog expectations build their paths with Path::join, so they pass on Windows
- docs: correct Photomerge roadmap status
- Crop/marquee readout and Properties W/H/X/Y in the ruler unit (cm, mm, in…)
- Warp Text: Style and orientation come before Bend and the distortions
- Layers: Layer via Copy duplicates every selected layer
- Fix brush picker closing immediately on trackpad taps
- Web: File › Open opens every selected file
- Status bar: show document dimensions in the ruler unit
- Workspaces: preserve the embedding host menu and rail flags
- Canvas honours Pixel Aspect Ratio Correction
- Control: timeout errors name the likely causes
- Variables: applied text keeps the type layer's style
- feat(prefs): add search across preference sections and settings
- ui-egui tests: drop the shadowing joined closure (fixes clippy on main)
- Filter Gallery: an unknown option is a bad-params error (#2548 follow-up)
- Type: tabs advance to tab stops; Tab key types a tab
- Smart Objects: Copy/Paste with no selection keeps the smart object
- Pencil: 1 px lines step pixel by pixel, no doubled corners
- ui-egui tests: restore the joined helper (fixes main)
- Dock: drag a tab to reorder it within its group
- Edit: Copy/Paste with no selection keeps type, shape and group layers
- feat(ui): hold Alt+Space to zoom out, as in Photoshop
- Themes: add Breeze Light and Breeze Dark
- Move tool: highlight the layer Auto-Select would pick on rollover
- Font menus: show an Arabic sample for families that cover Arabic
- Layer > New > Background from Layer; the Background stays at the bottom
- Tools: Single Row Marquee and Single Column Marquee
- feat(ui): live font preview on hover
- Fix Linux appearance changes lost during startup
- Linux: a late first appearance reply repaints the idle window
- Layer > Rasterize > Layer Style bakes effects; Rasterize Layer converts vector masks
- Navigator preview fills its group; no scroll fade over dock panels
- Release prep 0.7.0: Linux riscv64 tarball + version bump
- @sawizzle made their first contribution in
- @Benziza made their first contribution in
- @crqch made their first contribution in
- @vbasky made their first contribution in
- @kmnkv1 made their first contribution in
- @tropicaaal made their first contribution in
- @kotulsky made their first contribution in
- @MrCloudy2 made their first contribution in
- @JohnnYoru made their first contribution in
- @scottcampbelldata made their first contribution in
- @vangel76 made their first contribution in
- @KausBoss made their first contribution in
- @vivekprojects-GIT made their first contribution in
- @reneleonhardt made their first contribution in
- @itrycodinganditsbad made their first contribution in
- @itsF4LCON made their first contribution in
- @bitshiftza made their first contribution in
- @fabianghe made their first contribution in
- @callmeBalloch made their first contribution in
- @juswus2000 made their first contribution in
- @kavishkashehan726-sudo made their first contribution in
- @m6502 made their first contribution in
- @Lyraedan made their first contribution in
- @Erica4fr made their first contribution in
- @Trade-Mottoes made their first contribution in
- @Geljic made their first contribution in
- @seldoms made their first contribution in
- @twentymls made their first contribution in
- @zi-ger made their first contribution in
- @arthurdeka made their first contribution in
- @ahmedhosnypro made their first contribution in
- @FinnNk made their first contribution in
- @diax7 made their first contribution in
- @TssHack made their first contribution in
0.6.0Big update
- Motion Blur: 6x to 70x faster (one merged kernel applied over whole rows)
- Applying a text data set re-renders the type layer instead of blanking it
- PSD: a spec-order mask record is not misread as Photoshop's order when that reading is implausible
- ui.window.open: an invalid document index is an error, not a side effect
- fix(ui): remember previously applied New Guide Layout values
- fix(ui): allow removing the last polygonal lasso point
- PSD export: write empty layer and mask channels as raw
- Fix #1286: Delete and Fill Selection on the selection tools' right-click menu
- Part of #1275: the Studio themes show the Move tool's Auto-Select toggle
- Fix #1323: a Distort corner stops before the box folds over
- chore: remove accidentally committed fb-*.log files and ignore *.log
- Filter › Last Filter applies to the active layer, not the layer the filter first ran on
- Gradient tool: a handle dragged past the 10% scale floor stops; the other handle stays put
- fix(ui): prevent hidden guides from intercepting canvas input
- fix(ui): display configured Quick Export format in File menu
- fix(export): add WebP quality controls to Export Preferences
- PSD text fill: keep FillFlag so Photopea-edited text keeps its fill, carrying #1240
- Free Transform: W/H and X/Y fields reach large documents, carrying #1295
- Select › Modify: Apply effect at canvas bounds, carrying #1296
- Layers panel: hovering a blend mode previews it live on the canvas
- docs: craftrules is not public — say so instead of linking it
- i18n: fix pt-br label collisions (Feather/Diffuse, Liquify/Dissolve)
- Never crash on hostile numbers: LUT sizes, Quick Selection points, link group ids
- A PSD layer with bounds but no channel data no longer aborts on a 360 GB allocation
- New Document: a Clipboard preset with the clipboard image's size
- Layer copies are numbered: "Layer 1 copy 2", not "Layer 1 copy copy"
- file.new at 300000x300000 no longer fills ~360 GB of tiles before returning
- Divide wide slice rectangles without integer overflow
- Saturate layer-slice margins at coordinate limits
- image.crop rejects an origin or far edge that can't be moved within i32 instead of panicking
- Place Scale Marker: a document under 8 px tall returns an error instead of panicking
- Timeline: out-of-range duration and fps are rejected, and stepping never panics
- Slices test: as_chunks for the fixed 3-wide rows (follow-up to #991)
- gradient.fill.stop rejects an out-of-range index with BadParams instead of overflowing
- Link Layers allocates a group id that can't overflow
- Median, Dust & Scratches: run time grows linearly with the radius, identical output at 8, 16 and 32-bit
- docs: refresh implemented tool status in the roadmap
- Options bar: the airbrush, smoothing options and symmetry buttons work
- Startup: preserve the GPU backend after windowing errors
- Brush Scatter: out-of-range amounts are rejected and dab rects can't overflow
- Space untimed stroke segments by distance when Spacing is off
- Variables: preserve Unicode when importing data-set CSV
- image.analysis.recordMeasurements: refuse an area too large to measure instead of overflowing
- Edit Contents switches to the already-open contents document
- Paste into a targeted layer mask (or channel) instead of making a new layer
- Absolute colorimetric refuses a zero or non-finite media white
- Clone Stamp / Healing Brush: a far source is a bad-params error, not an out-of-bounds slice
- Keep the Background position lock after Flatten Image
- Shape gradients: honour midpoints, opacity stops, offset, dither and align
- Holding a number key sets one digit's opacity, not a two-digit value
- Layers panel: Alt-click the line between two layers creates or releases a clipping mask
- ⌘/Ctrl-scroll pans the canvas sideways; scroll bars always shown
- Nearest Neighbor: sample single source pixels on reductions without averaging
- Fix: Resolve issue where various file formats save incorectly as a .psd
- New adjustment and fill layers take the active selection as their mask
- Tools leave hidden layers alone: painting or moving a hidden layer is refused
- CI: ~1.6x faster runs (2.2x on Linux-only PRs), no more out-of-disk failures
- feat(ui): edit the Color panel's hex and RGB readouts
- Deep EXR: write the flattened pixel by layout, not a fixed RGBA quadruple
- Eyedropper cursor: a pipette instead of the crosshair when sampling
- Option flips Dodge/Burn and Blur/Sharpen for a stroke
- CPU effect maps: key fill layers by their cached pixels, drop opacity/visible
- fix(cli): report missing font fallbacks in run, info and convert
- Corpus: pin the deep OpenEXR test images and check them in CI (FILE-216-3, part of #216)
- Selection tools: ⌘ moves like the Move tool; ⌘⌥ copies (pixels inside the selection, the layer outside)
- Layer comps: offsets that don't fit i32 are dropped with a warning instead of overflowing
- MCP doc_save: bridge mode refuses headless-only options instead of saving with defaults
- Move tool: layers with effects that overhang the canvas drag ~2x faster
- Artboards: coordinates past the 32-bit range are rejected instead of overflowing
- Autosave: a thread that fails to start is reported, not a silent no-op
- Desktop: write log records to standard error and a rotating log file
- fix: resolve edge-case crashes, unbounded allocations, and UI sync defects
- UI Scale Auto keeps the system's fractional scale on 4K
- raw: decode Nikon compressed NEF (lossless + lossy)
- Fix Drop Shadow angle synchronization and add a radial dial
- PSD notes: an icon position near i32::MAX saturates on save instead of overflowing
- Improve Color Picker layout and spacing
- Toolbar: the header chevron switches between one and two columns
- Find host CJK fonts inside Flatpak
- Select › Color Range: Photoshop's Sampled Colors model, Subtract from Sample and the eyedropper on the image
- PSD: preflight pattern allocations and reuse decoded buffers
- Fix #1271, fix #1316: Preferences › Interface › System Title Bar
- A non-Unicode command-line argument is a usage error, not a startup panic
- Fix transform cancellation undoing the wrong document
- Fit Artboard on Screen: no i32 overflow for a board with large coordinates
- filter.cameraRaw: refuse an area too large to develop instead of overflowing
- PSD plane shuffles in bands; the document histogram computes off the UI thread
- Add Polish translation
- Layer style: an Outside stroke at Fill below 100 % leaves the interior clear
- Fix(text): keep tiny EngineData reals parseable
- Delete with nothing selected deletes the selected layers, of any kind
- Keep empty selections empty for subtract and intersect
- Filters respect layer locks; render filters and Fill Path refuse a pixel-locked layer
- Relight: halo covers the blur reach, no silent no-op above 8 MP, box-Gaussian blur (follow-up to #735)
- Help › Search: clicking the search field keeps the menu open
- Preferences: reset a single shortcut or menu colour override
- Hand tool: 100%, Fit Screen and Fill Screen buttons, carrying #1314
- SVG opens as shape layers and places as a vector smart object (FILE-215-9, part of #215)
- Show Clone Stamp source preview inside the brush cursor
- Clear, Cut and Image › Adjustments refuse a pixel-locked layer
- PSD export parallel layer channels; shared proxy cache; banded CMYK export
- Optimize Mosaic by averaging each cell once per tile (45-117x speedup)
- Open camera raws in Camera Raw first (Open / Cancel)
- ORF: a file cut short inside IFD0 is malformed, not the compressed variant
- Refuse to save a .pcraft holding a NaN or infinite float, instead of writing one that never opens again
- channel.merge: reject a repeated source index instead of closing an unrelated document
- layer.delete keeps a document's last layer
- Paint Bucket and Gradient keep alpha on a transparency-locked layer
- Document tabs: elide and overflow into a » menu when they are too many
- Embed PhotoCraft CLI Windows icon and version metadata
- Fix corrupted reduced canvas previews with separate mip render targets
- Fix Classic Gradient transparency and open the Gradient Editor
- i18n(pl): translate the strings that landed alongside the Polish catalog
- Regenerate docs/scorecard.md (139 preferences after #1016)
- Fix #1272: a reassigned shortcut runs its new command
- Pen tablets: the pen works on Wayland (through Xwayland), macOS pressure fixes
- Content-Aware Fill: size error instead of a panic for a huge selection, carrying #1024
- Fix radial blur sampling density
- Right-click Brush Preset picker picks presets like Photoshop
- Brush tests: seams, hard edge, zero scatter and ABR tip colour
- Feature: Add incrementation with up/down arrow keys on numeric fields
- codecs README: lossy WebP is written by the built-in VP8 encoder
- Perspective Warp: replacing the planes mid corner drag ends the drag
- Puppet Warp: an expansion that empties the mesh is refused, not a panic
- Vibrance: Photoshop's Saturation and Vibrance, measured (linear light, 0.288 R + 0.712 G grey)
- Select › Modify refuses a negative radius instead of clamping it
- Rulers: right-click to switch the ruler unit
- Fix/1350 preserve active on save
- Zoom: the Zoom tool's click honours Zoom Clicked Point to Center
- Preferences: show Zoom Clicked Point to Center now that the Zoom tool reads it (follow-up to #1241)
- feat(ui): auto-scroll Layers panel during layer drag and drop
- Preferences › Performance › Low Resolution Previews: live previews at full resolution when it's off
- Eyedropper: the comparison ring while sampling
- Type Tool: Ctrl/Cmd temporary transform handles while editing
- i18n: translate the Fill dialog, layer style contours and Image Size "(was …)"
- Pipette cursor test: Windows draws the precise crosshair itself (main is red on Windows)
- Keep the active document when closing another tab
- Cancel transforms in their originating document, carrying #1170
- Move several selected layers into a group in one step, carrying #1297
- Regenerate generated docs after the latest community merges
- undo/redo report the step's damage instead of recompositing the whole canvas
- Color Lookup: keep the .cube input domain and reject the ones we cannot apply
- ui.set validates every field before applying the first one
- Red Eye tool in the J-group flyout
- Layered TIFF: the review changes of #672 (keep unknown blocks with their byte order, io behind the engine, fixture attribution)
- Advanced Blending: knockout, blend as group, transparency shapes, masks hide effects (FILE-215-16, part of #215)
- I18N: Localize startup notices and welcome text
- Lasso: Alt clicks add straight segments, releasing Alt closes the outline
- Layers panel: Alt-drag a row to copy the layer there, as in Photoshop
- fix(ui): wrap New Document preset titles inside their cards
- PSD type layers without pixels are rendered on import; PostScript font names resolve to the installed family
- Curves: add black, gray, and white point eyedroppers
- GPU startup: windowing errors keep the backend; a failed CPU start doesn't pin CPU, carrying #1228 by @liowald and #1145
- Add layer and group color labels
- Color Balance: Photoshop's slider double-click reset, wheel and arrow steps, Alt+Cancel Reset, Properties Reset and history
- Fix #1248: Create and Release Clipping Mask act on every selected layer
- Fix #1288: keep edits to a video frame when the playhead moves
- Dropdowns take the arrow keys once open, carrying #1324
- Move tool moves the selected pixels when there is a selection
- Fix #1371: read large macOS display ids, keep ICC bytes out of the error
- Fix #1354: the macOS menu bar is modal under dialogs, like shortcuts
- Fix #1387: the Type tool's font, style and size controls show in every theme
- Selection tools: ⌥ with nothing selected draws a new selection (follow-up to #1190)
- Fix #1380: the web build asks before leaving the page with unsaved work
- Camera Raw opens in a window of its own
- Export As: a scale that changes only the height is applied
- New Document: a size typed in millimetres or another physical unit keeps its digits
- PNM: the file, not the header, bounds what a decode reserves
- Select › Modify refuses a radius below the dialog's minimum, carrying #1391
- Edit › Toolbar: hidden tools leave the toolbar, carrying #1376
- Paint Bucket: All Layers samples the visible image, carrying #1386
- Swatches: user swatch model with .aco/.ase import and export (FILE-215-14, part of #215)
- Regenerate generated docs after the latest community merges
- Toolbar test: qualify egui::Vec2 (ui-egui tests don't compile on main)
- Large document: a notice explains a slow CPU fallback redraw
- i18n: split "Light" — font weights get their own context, Camera Raw keeps the panel term
- Pattern Stamp tool in the S-group flyout
- Fix #1229: the Polygonal Lasso tool removes its last vertex on Backspace (follow-up to #1262)
- Document tabs: elide and overflow into a » menu, carrying #1293
- Fix #1381: selecting type on Wayland no longer deletes it
- File dialogs no longer freeze or crash the app
- Fix #1357: every Layer Style effect row shows its checkbox
- Swatches import/export and the Export As test use the async file dialog (main doesn't compile)
- Color Range: improve previews, sampling and eyedropper responsiveness
- Surface Blur: 4x to 20x faster on 16-bit and 32-bit layers, carrying #1095
- Regenerate generated docs after the latest community merges
- type.create: an unknown or out-of-range kerning is a bad-params error, as in type.edit
- Control server: a bad JSON reply carries "id": null like every other unknown-id error
- Show Extras Options: checkboxes read and set the Show flags they name
- Numeric fields: arrow-key steps never clamp with a reversed or NaN range (follow-up to #1326)
- New Document: preset titles wrap inside their cards, carrying #1401
- Fix startup panic when UI Font Size is not Small
- Clone Stamp: live stroke, strokes start on the press, source preview under the brush
- Wayland: drop notice offers paste and the XWayland command for this install
- Live strokes for the History Brush, Healing Brush and the dab tools
- Non-Unicode arguments: translate the desktop notice (follow-up to #1168)
- Fix #1313: Tab hides all panels, Shift+Tab the panel dock, as in Photoshop
- Selection tools: arrow keys nudge the selection outline
- Mesh warp of a gray surface writes the old and warped regions separately
- Apply the transform when another layer is selected
- Preserve document depth when splitting stroked vector shapes
- Puppet Warp: pins that stretch the content too far are refused
- Canvas: checker moves with the image; pixel grid from 500%, over pixels only
- Liquify: Alt reverses Twirl and swaps Pucker/Bloat, as in Photoshop
- .pcraft: a tile index outside the i32 pixel range is a corrupt file
- Camera RAW: a measured Nikon D4 profile (image area, white level, colour matrix, tone curve)
- fix(psd): write Photoshop-compatible Photo Filter adjustment blocks
- Speed up wide Motion Blur with adaptive FFT convolution
- Crop: an explicit rectangle past 300000 px per side is refused
- [P1] Enforce PNG text metadata decode limits
- Keep Arbitrary Rotation previews visible on the GPU canvas
- Fix #1543: oversized Satin and Bevel & Emboss sizes render instead of panicking
- Fix #1544: Image Size refuses a resample past the raster budget; resampling writes bands as it goes
- Docker web deployment
- macOS DMG: branded window background and icon layout
- Fill and adjustment layers take the active path as their vector mask, carrying #1539
- docs: MCP tool names and job tools, codec README JPEG metadata and deep EXR
- Fix #1531: duplicate artboards beside the original, drag boards with the Move tool
- Free Transform: the reference point moves with the box when scaling
- MCP bridge: do not replay edits after a lost reply
- Control: reject queued requests after their reply deadline
- Undo: a paint stroke's undo keeps the painted layer active
- PSD: warn that Color Lookup tetrahedral interpolation is saved as trilinear
- TIFF: alpha after an unspecified extra sample opens transparent
- Crop tool: show the pixels past the canvas while a frame is edited, as Photoshop does
- Help › Search: keep the field focused after a click opens Help
- Font menu keeps its height and focuses its search field
- Divide Slice: one division makes at most 10000 parts
- Canvas: a huge view centre draws the selection outline without overflow
- Plug-ins: a missing parameter's default is clamped to the declared min..max
- Plug-in names reject bidi controls, zero-width spaces and other invisible format characters
- Opening a file with different horizontal and vertical resolutions says the vertical one is not kept
- Control channel: ui.click rejects a count above 256 instead of queueing unbounded input
- Fix Transform Again action playback applying the transform twice
- MCP previews: reject unsupported document indices, carrying #1533
- Pen: reshape the final anchor's outgoing handle; independent rounded-rect corner radii, carrying #1538 and #1541
- Faster blur and resize accumulators; release closed-document textures, carrying #1511 and #1509
- fix(ui): allow Delete and Backspace shortcuts to delete layer when a widget is focused
- Windows: use native bitmap cursors for brush tips
- Add full Type Color Picker and screen eyedropper with magnification
- i18n: fix pt-br collisions (View/Preview, Flip/Invert, Light/Thin, Warp/Distort)
- Greek localization
- Dodge and Burn tone each pixel once per stroke
- full_res_preview test: wait again when WARP outlasts egui_kittest's 10 s render wait (Windows CI)
- i18n(el): translate the screen color picker strings (main red since #1232 + #1562)
- History: count retained tiles incrementally below the byte budget
- feat: add saved New Document presets
- i18n(el): translate the saved New Document preset strings (main red since #1516 + #1562)
- Improve Actions editing, nested playback, and function-key shortcuts
- PSD save: stream Lr16/Lr32 layer blocks into the output
- Speed up exact Shape Blur convolution
- Command lookup: index registered and shell command IDs
- i18n(el): translate "Pick a screen pixel or press Esc to cancel" (main's xtask i18n test)
- Pipette cursor test: Windows reports the precise crosshair with its bitmap (Windows CI red since #1160)
- Rotate View tool (#1611 by @mvanhorn) and ui_set describes every field (#1599 by @kubuntugamer), carried
- Rotate View tool in the Hand flyout
- Grammatical articles in layer diagnostics and invalid document index errors, carrying #1571 and #1586
- A pathless PSD or PSB save leaves the document clean, carrying #1589
- fix(io): layered TIFF export warns that retained EXIF will be dropped
- Open Apply Image and Calculations dialogs
- fix(raw): a DNG with only DefaultCropSize is cropped from the active area's origin
- Layers panel: pop-up sliders for Opacity and Fill
- Snap the Marquee drag outline to whole pixels
- fix(autosave): report background write failures and retry unchanged revisions
- fix(engine): finish background job bookkeeping on its document
- [P2] Invalidate combined masks after pixel edits
- Layers panel: ⌥-click on the line between layers, measured against Photoshop (follow-up to #1066)
- macOS: quit with terminate:, not by closing the window
- Keep legacy PSD text origins visible when editing
- Keep a brush per painting tool, as in Photoshop, carrying #1629
- Linux: display server preference (X11 / XWayland) so file drops work, carrying #1319
- fix(scorecard): mark the #204 preference rows done; their readers, allowlist and test exist
- fix(control): ui.inspect reports the documented view preferences
- fix(engine): Layer via Copy and Cut deselect, as Photoshop does
- fix(engine): layer bounds drop the area a selection transform moved pixels out of
- fix(ui): the Photoshop-style status bar shows messages with no document open
- fix(ui): the Navigator keeps its image during a live paint stroke
- fix(engine)…
0.5.0Big update
- Add rendering modes and CPU fallback recovery
- Type layers keep their name in step with their text
- Unsaved-changes prompt: (D)on't Save / (C)ancel / (S)ave keys, Tab order
- Layer Style: the shadow/bevel Angle slider now moves the light
- Color Picker: sample colours from the image with a pipette
- Polygonal Lasso: double-click closes the polygon; a new polygon replaces the selection in one step
- Type: the Color panel, Swatches and Color Picker recolor selected text
- Free Transform: Undo steps through the transform; handles are easier to grab
- 32-bit documents: Levels don't clip the input and output ranges
- rustfmt discard_ui.rs (CI Format step red since #533)
- Smart objects keep their four-corner (Distort / Perspective) placement
- feat(ui): add bounded Liquify redo history
- Lasso inside liquify mode , with hotkeys L, alt , ctrl+i, ctrl+h for …
- Expose the Mixer Brush as a UI tool
- Control protocol docs: file.open/file.save are refused over --control
- docs: sync scorecard with implemented behavior
- Focus PhotoCraft for unsaved close prompt
- PSD: read/write the artboard lock at Photoshop's lspf bit 3
- Show active ICC profile in the status bar
- Clarify integer and float bit-depth labels
- Wayland: explain native file drag-and-drop limitation
- Preferences › Interface: Show bounding box when dragging layer
- Hide unconfigured layer effects from Layers panel
- Paste: a copied image file pastes its pixels (part of #338)
- Content-Aware Scale: 13x faster seam removal, bit-identical output (part of #211)
- PSD: read smart-filter masks (FEid) with one section per smart object
- Open documents in bounded reads, with a clear out-of-memory error
- Camera Raw: interactive histogram, clipping warnings and scopes (part of #215)
- Add the Patch tool with a live preview
- Add blend modes to the Gradient tool
- Start context-menu parity across canvas, paths, and document tabs
- i18n: complete Simplified Chinese catalog and localize brush sections
- i18n: add French (fr) UI translation
- i18n: "id" indonesian translation
- Report per-language UI translation coverage
- Add style warp splits and grid presets
- Add Edit Contents to the Smart Object context menu
- Edit type layers by double-clicking their thumbnails
- Monitor profile auto follows each window's display; what is applied is visible
- feat(i18n): add Korean and live language switching
- Add fixed UI scale steps from 75% to 300%
- algo: fix flaky cancel/progress test - tile workers report out of order
- Apply Image onto a transparent layer no longer turns it black
- Remember desktop window and panel sizes across restarts
- monitor_profile test: Unix only (fixes Windows CI after #591)
- README: remove a stray "ArtCraft" line before Star history
- Open HEIC/HEIF photos
- Rename PrintCraft to PdfCraft
- Persist migrated presets with preferences
- Select Linked Layers excludes an unrelated active layer
- fix(cms): check LUT declared sizes before arithmetic
- i18n: add German (de) UI translation
- fix(ui): search palette: the Enter that opens a dialog no longer closes it
- scorecard: BUG-203 (atomic saves) is done - flip the stale rows
- layer.showOnly: ⌥-click a layer's eye to show only that layer
- Text fields stop resetting the input method every frame, so keys no longer repeat endlessly on Wayland
- fix(color): match Photoshop blend corner values
- Box Blur: up to 26x faster at large radii (same running-sum boxes as Gaussian Blur)
- Layers panel: drag down the eyes to show or hide layers; empty eye when hidden
- Minimum / Maximum (Squareness): up to 37x faster at large radii, bit-identical output
- Surface Blur: 13x to 40x+ faster on 8-bit layers (sliding histogram)
- Free Transform: picking another tool applies the transform
- Layer › Remove Background: one-step subject cutout (layer.removeBackground)
- Brazilian Portuguese UI translation (pt-br)
- fix(linux): AppImage registers its desktop entry and icon on launch
- macOS: menus open on press; only the title bar's free gap drags the window
- Color panel: click a chip to edit that color, double-click to open the Color Picker
- Fix #497: group type edits and renames in undo
- Numeric fields evaluate typed arithmetic
- Transform modes: Skew / Distort / Perspective as real modes; legacy corners as a preference
- document.pixel: no panic at x or y = i32::MAX, and no wrap-around past it
- Fix #570: Shift-click connects brush strokes
- Type: a forced line break (U+0003) breaks the line instead of drawing a box
- Fix multi-file open dialog
- Fix Hue/Saturation range editor drag panic
- JPEG export no longer fails when the document's XMP is over 64 KB
- Improve Korean terminology and dynamic UI translation coverage
- Image Size keeps the canvas border opaque instead of fading it
- Fix #695: validate Layer Style effect fields
- type.edit: a reversed runs range is a bad-params error, not a panic
- Arbitrary rotation starts at the ruler line's straightening angle
- Prevent "Export As" from saving webp files as "*.webp.psd"
- rustfmt xtask/src/i18n_coverage.rs (Format red on main since #663 + #700)
- Find and Replace Text: no panic searching a non-type active layer
- Apply the Interface UI Font Size preference
- codecs: decode deep OpenEXR (deepscanline/deeptile), composited flat or structured
- Selections: drag to move the outline; ⌘-drag floats the selected pixels (engine commands)
- Filter › Render › Relight: redirect a photo's lighting
- rustfmt crates/codecs/tests/deep_exr.rs (Format red on main since #642)
- Fix document run and ID overflow
- Fix bridge preview PNG budgeting
- Clamp Variables data-set indices from control input
- Fix ui.set brush size command journaling
- Fix TIFF WhiteIsZero and BigTIFF orientation
- Shapes: a hairline vector stroke no longer darkens the shape's edge pixels
- Spot Healing: Sample All Layers heals onto an empty layer
- fix(i18n): follow native UI languages on first launch
- Support Alt-held polygon segments in the freehand lasso
- Type: hitTest, caret and navigate commands so agents can edit text by position (part of #219)
- Korean labels for Relight's Ambient and Warmth options
- fix(raw): validate DNG default crop bounds
- Fix vector pixel bounds overflow
- Layered TIFF: open and save Photoshop layer data in TIFF files, in either byte order (part of #215)
- Reject overflowing slice rectangles
- Fix hostile PSD pattern geometry
- Bound paint stroke work
- Actions: actions.record/stop/play/list commands for agents and the CLI (part of #219)
- Fix text ink bounds overflow
- Repair corrupt directory-save objects
- fix(automation): close ambient filesystem authorization gaps
- rustfmt crates/ui-egui/src/canvas.rs (Format red on main since #711)
- Flat exports embed no document XMP by default; Export As gains a Metadata choice
- pcraft directory saves: re-verify a rolling share of cached objects; stronger file signature
- rustfmt crates/ui-egui/src/export_dialog.rs (Format red on main since #672 + #733)
- Follow-ups to #665, #666, #734: Photoshop's mask-only Remove Background, one-step eye sweep, no-clone Show Only
- Headless saves write a flat TIFF unless they ask for layers
- Dialog buttons follow the OS order; Windows/Linux unsaved-changes prompt asks Yes / No / Cancel
- Layers panel: a double-click just above or below a layer name renames it
- Open .psdt templates as new untitled documents
- fix(algo): blur small sigmas instead of silently no-oping
- fix(algo): gallery colour injection covers Colored Pencil and Neon Glow
- fix(algo): HDR Toning gamma follows its documented direction
- fix(engine): keyboard shortcut bulk set reports in-call clashes
- Auto-Align Layers: the dialog no longer sends reference 0
- fix(engine): view.newGuideLayout rejects absurd column/row counts
- Windows DX12: never load a foreign dxcompiler.dll from PATH
- Cancel stale Warp drags when the mesh changes
- Handle Stack Mode sources with no visible layers
- Camera Raw: read and write settings as a live PSD Smart Filter (part of #215)
- fix(engine): clone source_rect clamps huge mapped coordinates
- Geom: Rect::width and height no longer overflow on i32-extreme rects
- New Document: changing Resolution keeps the physical size when a physical unit is shown
- Reject geometry params that would silently wrap through i64->i32 narrowing
- ⌘⌥⌃-click on the canvas selects the topmost layer under the pointer
- Help › Search: find any menu command by name
- i18n(ko): drop the duplicate Ambient and Warmth rows (main red since #811 + #824)
- rustfmt crates/engine/tests/hdr_gamma_direction.rs (Format red on main since #801)
- Copy works on smart object, type and shape layers
- Add the Content-Aware Move tool
- Rework Camera Raw filter preview and navigation
- Bound layer-group nesting at import and Group Layers (stack-overflow guard)
- fix(photocraft): reject an unparseable --control port instead of silently dropping it
- M9: create vertical type from the Type tool flyout
- Drag-and-drop: place onto the canvas in Free Transform, open at a tab slot
- Large PSBs open with their pixels: decode planes past 2 GiB, plus 4-5 GB PSB fixtures
- Layer Style: complete multi-instance effects and dialog parity
- Italian UI translation (it)
- Add the Magnetic Lasso tool
- CI: never cancel main's runs; trim per-PR runner time
- tiff_corpus: ask for layers explicitly (corpus job red since #825)
- agent_tasks: wait for the MCP server task before removing the test folder (Windows os error 32)
- Preset store: a store directory that doesn't exist yet reads as empty on Windows too
- Locking a group locks the layers inside it
- fix(engine): Camera Raw clamps the noise amounts to their range
- Test: press-drag-release across menu titles and into submenus
- Filter previews stay inside the selection on large documents
- fix(test): find sleep on PATH in monitor profile test
- ui-egui tests: GPU adapter catch_unwind stops swallowing setup-command failures
- Warp: reject extreme rect params with BadParams instead of running a giant warp (#808 follow-up)
- fix(algo): Path Blur clamps per-path speeds
- fix(io): artboard guide indices follow resource 1032 order
- fix(codecs): large PNG exports no longer lose bytes at a band's sync flush
- PSD: decode the merged composite only when something consumes it
- Lossy WebP: a pure-Rust VP8 encoder with quality and lossless controls
- Gaussian Blur: large radii are fast, live preview included
- Resampling reads a bounded window, however small the target
- About: contributor and model credits compiled in (grab bag + table, self-submitted names)
- Automation: Apply Data Set works for text and visibility data sets
- Document tab × sits after the title on Windows and Linux, as in Photoshop
- Brush size and hardness keys are remappable in Keyboard Shortcuts
- Menu rows touch, as in native menus: long menus are a fifth shorter
- actionlint: declare the org macos-release runner label
- Slice Options and Divide Slice are one undo step; a rejected one changes nothing
- Selection tools: Photoshop's full right-click menu
- CI: craft-fonts run uses the Test step's exact build again (Linux runner out of disk since #800)
- TIFF: BigTIFF, every IFD and SubIFD, banded parallel decode (FILE-215-8, part of #215)
- Direct Selection tool: reshape pen and shape paths after they're drawn
- Windows and Linux: one title bar with the app icon (no stacked OS bar); long context menus scroll
- Filter Gallery: Angled Strokes paints strokes, not a smear; Rough Pastels' texture shows in dark areas
- Save for Web: slices never overwrite each other; overlapping slices keep their HTML cells
- Out-of-range slice, layer comp and type style ids are rejected, not wrapped
- Invert (⌘I) inverts the targeted layer mask
- Drag layers onto another document's tab to copy them there
- Layer › Smart Objects › Convert to Layers
- Photo Filter and gradient glows render like Photoshop
- Fix main: classify the Direct Selection path commands; Czech for "{n} layer"
- Automation: an allowed command can't run a denied one on its behalf
- Variables dialog: malformed entries can't crash an edit
- Layers panel: drop layers on the footer's New Layer, New Group and Delete buttons
- Crop tool starts with a frame around the canvas (or the selection), as in Photoshop (#668 item 7)
- Type: ⌘/Ctrl+T while typing shows or hides the Character panel (#668 item 15)
- Shape tools: Shift and Alt pressed during the drag constrain it, as in Photoshop (#668 item 12)
- Layer via Copy, Copy and Cut read only the selected area: 33× faster on 24 MP (#668 item 18)
- Windows: selection and other crosshair tools stay visible over grey
- Clone Stamp / Healing Brush: the source crosshair shows only while painting (#668 item 10)
- Preferences: colour settings take a typed #rrggbb value (#668 item 2)
- macOS: use the native menu bar instead of the in-window menus
- README: Downloads section listing every release build
- README Downloads: where to get it, then builds (Windows first)
- Release workflow: only signing and draft-release jobs use the release environment
- @TheSeanLavery made their first contribution in
- @mnmlyw made their first contribution in
- @rosematcha made their first contribution in
- @jason4short made their first contribution in
- @siraxe made their first contribution in
- @arpitkjaiswal made their first contribution in
- @EthanSuquet made their first contribution in
- @alexanderalber made their first contribution in
- @flyyangX made their first contribution in
- @leblanc-simon made their first contribution in
- @trokute made their first contribution in
- @ha1des made their first contribution in
- @neko233-com made their first contribution in
- @Sirsyorrz made their first contribution in
- @Elvis33LE made their first contribution in
- @cristianmoroaica made their first contribution in
- @Webificio made their first contribution in
- @mvanhorn made their first contribution in
- @gangldiego made their first contribution in
- @kijoong-kim made their first contribution in
- @Cyanoxide made their first contribution in
- @tanish2k09 made their first contribution in
- @jerrykimo made their first contribution in
- @bfenty made their first contribution in
- @Luna161 made their first contribution in
- @abc2cb made their first contribution in
- @remidesbois1 made their first contribution in
- @giallorosso84 made their first contribution in
- @louwers made their first contribution in
- @simonwjackson made their first contribution in
- @ajsongpilot made their first contribution in
- @brennanMKE made their first contribution in
0.3.0Big update
182 commits from 183 merged pull requests, including work from 31 community contributors (thank you!), and 146 issues closed.
- Your work is safer:
- Recovered unsaved documents survive a second crash.
- Deeply nested .pcraft files reopen.
- photocraft-cli batch refuses to overwrite its input folder.
- Preferences no longer get lost when two windows or tabs save, or when a save fails.
- Languages: the interface is available in 日本語, 简体中文, 繁體中文, Español, Русский and Čeština (Edit › Preferences › Interface › Language), with CJK fonts and IME input in the Type tool.
- Files:
- JPEG and other no-alpha exports composite transparency over white.
- Formats without colour profiles get sRGB.
- Truncated JPEGs and multi-frame files open with a warning instead of silently.
- TGA is offered in Save As and Export As.
- Editing:
- Free Transform a Copy and Transform Again on a Copy.
- Keyboard layer navigation, number keys for opacity, Alt-click colour sampling.
- New from Clipboard.
- Undo and redo restore the targeted layer.
- Shortcuts pressed in quick succession all run, in order.
- Automation (CLI, MCP, control channel):
- Stricter, clearer parameter and flag errors, and <subcommand> --help.
- Background jobs that agents can wait for or poll.
- Recorded actions run in batch.
This is the first release with docs/scorecard.md, so these numbers are its baseline. 0.2.0 had no scorecard to compare against. Area counts are done / partial / missing.
| Area | Done | Partial | Missing | Measured | |---|---|---|---|---| | Performance | 3 | 22 | 12 | 46 scenarios: 3 within budget, 22 over budget or failing, 13 tracked only, 4 not run, 8 not yet measurable (baseline 2026-10-05) | | File compatibility | 1 | 8 | 18 | io corpus oracle ≥ 146/170, round trip ≥ 169/170; psd-tools oracle ≥ 229/309, round trip ≥ 307/309; Photoshop-authored oracles ≥ 130/256, round trip 258/258 | | Tools | 3 | 14 | 13 | | | Workspace and UI | 0 | 4 | 19 | settings that do nothing: 60 of 133 (target 0) | | Type | 0 | 3 | 6 | | | Automation | 1 | 3 | 7 | 626 of 626 menu items live | | Reliability | 3 | 1 | 3 | never-crash lints on 26 of 26 crates; panic_hunt fuzzes every command | | Distribution | 4 | 3 | 4 | | | Open bugs | 0 | 3 | 29 | |
- perf(compose): avoid unnecessary backdrop snapshots
- perf(compose): prepare gradient stops outside pixel loops
- Fix stale effect maps after default-only mask changes
- Preserve HDR samples when importing white-matted PSD composites
- Mix pass-through group coverage in premultiplied space
- perf(compose): avoid redundant effect-halo rendering
- Preserve merged PSD alpha at the exported sample precision
- perf(compose): reuse compiled vector masks within each render
- perf(compose): reuse bounded pattern preparation across render tiles
- fix(ui): pasting an image copied in another app never ran
- fix(ui): make Move transform controls interactive
- Menu overlap and overflow #92
- PR #96 — Liquify undo
- fix(ui): shape tools show the shape while dragging
- security: bound automation previews and reply resources
- Japanese support: IME input in the Type tool and CJK glyphs in the UI
- Community batch follow-ups: on-demand OS clipboard paste; fmt + egui 0.36 test port
- perf(ui): borrow the active layer from its document snapshot
- perf(ui): reuse exact cached content bounds
- perf(ui): skip offscreen layer thumbnail generation
- perf(ui): retain channel thumbnails across view-only revisions
- fix(ui): prune thumbnails for removed layers and documents
- fix(ui): prune closed-document display and preview resources
- Disambiguate colliding document identities at session admission
- Warn when the PSD channel limit drops a Quick Mask
- Preserve compositing properties in single-layer flat export
- Preserve selected real masks during PSD import
- Scale artboard bounds in proxy documents
- Crop tool: move and resize the crop frame, Space repositions while drawing
- Fix flaky canvas_geom undo test (process-wide text gamma raced by another test)
- Dock: fixed-height panel groups, splitters, collapse, reorder; panels never vanish
- Brush Settings panel: Photoshop structure and depth, edits through tools.setBrush
- Selecting current bit depth must preserve redo
- Detect PhotoCraft archives independent of ZIP entry order
- Type tool: caret/selection land on the glyph under the pointer; font size is live, one undo step, ~60x faster
- Layers groups expand/collapse; every displayed shortcut fires
- Layers rows: names never run under the indicators; fx triangle; Collapse All Groups; designer PSD for QA
- fix(geom): saturate Rect::translate and inflate on i32 overflow
- fix(ui): make tall menus scrollable on short displays
- PSD type layers: bounds regression tests; #148 is the layer's vector mask, not text bounds
- Flatpak single-file bundles as release artifacts
- Roadmap: honest parity assessment (2026-10-05)
- AGENTS.md: no Tauri, Electron or webview shells
- Menus scroll and navigate by keyboard on small displays; Color Range dialog on the no-GPU path
- Docs: where we stand and where we're going (roadmap, README, AGENTS.md)
- Brushes: Tilt Scale, Brush Projection, Spacing checkbox, section locks, Mixer Wetness/Mix; Brushes grid + drag and drop; options bar through tools.setBrush
- fix(ui): refresh Liquify preview after undo
- fix(ui): sample eyedropper colours while dragging
- fix(ui): keep Curves endpoint handles inside the graph area
- fix(ui): avoid duplicate sliders for wide filter ranges
- Dock polish: Layers gets the height, Character/Paragraph group, eliding tab strips, reveal the active layer
- Move/Free Transform modifier keys; sharp full-resolution transform preview
- CJK UI font fallback: Simplified/Traditional Chinese and Korean, lazily loaded in locale order
- Layers mask thumbnails + chains; Channels/Paths temporary rows and footers
- GPU compositor: paged residents and effect maps, so 20k+ documents refresh on the GPU
- Properties: uniform sections, per-kind Quick Actions, full-width controls
- PSD corpus: psd-tools set (pinned, verified), an oracle for every file, and the fixes it found
- Tool feedback: selection-mode cursor badges, scrubby zoom, contrasting outlines, Shift lines
- PSD fidelity: 16/32-bit colour modes, Lab, Levels, Exposure, Dissolve oracle (corpus 133 → 140, psd-tools 212 → 222)
- Fix tests on FreeBSD with RADV
- fix(clipboard): use the wayland clipboard for images
- FreeBSD: build and test the workspace in a FreeBSD VM
- Fix automatic UI scaling on 4K monitors
- FreeBSD: serialise canvas GPU tests, CI template, RAM detection, CJK font paths
- Title bar: never draw the window title over the menus or controls
- Packaging: Linux runtime deps + start-up library check; wasm 26.3 -> 18.8 MiB
- Fix live brush preview drawing a polygon
- PSD effects fidelity: spread metric, emboss, gradient geometry, text gamma (113 -> 118 oracle passes)
- Scorecard: cargo xtask perf + scorecard, budgets, checklists, nightly perf
- Layout documents: fix GPU device loss, live Move tool, local damage, no per-frame work
- PSD export: write tagged blocks other readers can parse
- CR2: measure the colour filter row phase instead of assuming RGGB
- Atomic saves: one crash-safe atomic_write for every document write
- Preferences: wire tooltips, Home screen, recent files; hide what nothing reads
- Eraser on locked layers: no lock-out from the simple lock button; Stroke Path erases to the background colour
- Retouch tools paint the mask/channel target; Sample All Layers for Blur/Sharpen/Smudge; premultiplied Smudge
- Free Transform: selection moves only its part of a linked mask; masked preview; target masks and channels
- Vertical type (tategaki): lay out, render, edit and round-trip
- PSD stroke effects: outlines of filled shapes, vector stroke above interior effects, joined subpaths
- Live gradients: Gradient tool makes editable Gradient Fill layers (on-canvas handles, stops, midpoints) + Classic mode
- Marquee: Shift squares, Alt draws from the centre, live W × H readout
- GPU: crash-safe startup and device-loss fallback
- Text: deterministic font family order; hide private system families (fixes a flaky test)
- Photoshop oracles via storytold/photocraft-corpus: pinned corpora, corpus feature, test-corpus, CI job
- Masks: Alt-click to view mask, Cmd-click vector mask to select, vector-mask target brackets
- Stylus pressure, tilt, rotation and eraser on macOS and X11
- Fix Windows MSI advertised shortcut icons
- Windows taskbar icon: .exe icon id for the MSI shortcut + icon regression tests
- Colours: handle non-hex Unicode values without an internal error
- Align the CJK fallback font's baseline with Latin text
- UI: platform shortcut notation in every label and tooltip
- New Document: a typed Width/Height reaches Create
- Menus are as tall as their items; scroll only when the window is too short
- Portable mode: keep settings beside the exe in the Windows portable zip
- Brush Settings for every brush: options-bar toggle and real preset picker
- Ctrl+Alt-drag resizes the brush on the canvas
- Shift rubber band: preview the straight line before the click
- Selection drag previews: regression tests for #253 (visible mid-drag, 1x and 2x)
- Shortcuts: rebindable fill keys, D/X and held temporary tools
- PSD manual and optical kerning: import, export, render, edit
- Localise the UI: i18n foundation and a Japanese catalog (menus, dialogs, panels)
- Pencil tool, Edit › Fill… dialog and "Rasterize?" prompt
- Fast Select › Modify › Smooth and Feather (part of #211)
- Compositor: effect maps never block inside parallel tiles (fixes #276 deadlock)
- FreeBSD release tarball and README platform lines
- fix: forward document index in bridge inspection
- Marquee: stop the selection at the canvas edge
- Background layer: double-click, masks and cut behave like Photoshop
- i18n: add Simplified Chinese localization
- Enable dictionary segmentation for Japanese type
- Smart Objects and Smart Filters survive PSD save and open
- Apply EXIF orientation on open, write Orientation = 1 on export
- PSD export: 32-bit files open in Photoshop (HDR toning Color Mode Data, #291)
- Windows on ARM64: release builds, PE header check, install test on ARM64 hardware
- Fix preference usage scanning on CRLF checkouts
- Windows: Alt-click clone hint and Ctrl+N channel errors (#251 follow-up)
- Move tool: Auto-Select on by default; a click picks and drags the layer under the pointer
- Cmd+Enter (Ctrl+Enter) loads the path as a selection
- Layers panel: rename commits on click elsewhere, Enter or Tab; one at a time
- Keyboard Shortcuts: Ctrl+F records as Ctrl+F, not Ctrl+ControlLeft
- macOS CLI: verify the shipped CLI is Developer ID signed and notarized in the release workflow
- fix(ui): feed every pointer move per frame so fast strokes stay smooth
- Fix logic Show the clone crosshair only while Option is held
- i18n: add Traditional Chinese (zh-hant) UI catalog
- Add a Spanish catalog (menus, dialogs, panels)
- Localise the UI into Russian: a complete catalog and the missed tl! call sites
- Preferences: add an Apply button
- i18n: add Czech (cs) UI translation
- Menus: no menu or submenu covers the menu bar
- Menus stay above the taskbar; oversized windows open maximized
- Background jobs: engine job API, progress and cancel (part of #210)
- Background jobs in the app: progress, Cancel, open-as-job (part of #210)
- Harden EXIF orientation: limits after rotation, fallible allocation, strict IFD parsing
- Fonts: use craft-fonts as an optional build input; move the Japanese fonts out
- Stamp Visible (Cmd+Alt+Shift+E) and Stamp Down; Alt+Merge keeps the originals
- Right-click on the canvas lists the layers under the pointer
- Canvas scrollbars, and Preferences > Tools > Overscroll works
- Alt+right-drag resizes the brush and changes its hardness
- Alt+scroll zooms the canvas in 5% steps around the pointer
- ui.set: reject unknown fields; the theme error names all five themes
- serve: methods lists jobs.list and jobs.cancel
- MCP command_batch and serve batch honour each step's wait
- Headless saves without path never flatten over the opened file
- Alt-click with the Brush, Pencil, Gradient or Paint Bucket samples a colour
- Layers panel: double-click beside a layer's name opens Layer Style
- Batch runs report inputs that share an output name instead of overwriting
- New from Clipboard, and Paste with nothing open makes a document
- CLI: unknown flags are usage errors, <subcommand> --help prints usage, usage lists --quality
- Liquify remembers its brush settings between uses and launches
- The main window opens centred on the screen
- Keyboard layer navigation: Alt+[ / Alt+] / Alt+, / Alt+. and Shift to add (part of #352)
- Transform Again on a Copy (Cmd+Alt+Shift+T): step and repeat (part of #352)
- Number keys set opacity, Shift+[ / Shift+] step hardness, Shift+Cmd+A opens Camera Raw (part of #352)
- Export: TGA in Save As and Export As
- Docs and MCP schema: use the real Gaussian Blur id
- Image Size shows the one-pixel minimum it applies
- prefs.reset resets a single colorSettings key
- Content-Aware Scale: enlarging a 1 px wide or tall layer no longer panics
- Build desktop app by default
- fix(engine): use wasm-safe timing for Liquify
- Profile mismatch: compare profiles by colour, not bytes (sRGB vs sRGB prompt)
- Type: dragging a paragraph box handle resizes the box
- docs: correct VectorCraft sibling name
- Free Transform a Copy (Cmd+Alt+T); Esc takes the copy back (part of #352)
- Raise rust-version to 1.95, the minimum egui 0.36 needs
- docs: add star history chart to README
- Move drag reveals a larger-than-canvas layer's off-canvas pixels
- Spanish: add missing tool, filter and path translations
- Dialogs keep their top-left when their content resizes
- PSD export selects PSB above size limit
- 32-bit documents: Exposure works on the stored linear values
- Ctrl+Insert copies and Shift+Insert pastes on Linux; Shift+Insert pastes images on Windows
- Docs: roadmap, scorecard and README after the 2026-10-07 fixes
- CLI batch: recorded-action steps, --format .ext, strict --quality, refuse --out = --in
- Gradients honour explicit transparency stops; smart filter commands accept an explicit layer target
- Recovered documents keep their recovery data until saved or closed
- History: tool and preset names, Frame from Layers as one step, undo/redo restore the targeted layers
- Shortcuts run in the order pressed; Shift+Delete fills on Windows; colour pickers stay put while dragging
- Control channel: menu/dialog requests wait for their job; right-click menus at the point; MCP ui_pointer button
- Automation: non-object params rejected; headless sees finished jobs; serve stdio survives a bad line; MCP batch keeps results
- Formats: deep .pcraft groups reopen; zero-size PSD rejected; JPEG mattes over white; no-ICC formats get sRGB
- Preferences merge with other tabs/windows and retry failed saves; web startup shows a Reload hint
- FreeBSD CI: run the GPU integration tests one at a time
- Import warns when it keeps only the first frame or page, or a JPEG ends early
- Linux: AppImage update information and a .zsync beside it
- Color Picker and Color panel fields accept typed values
- Release 0.3.0
- @MikeeI made their first contribution in
- @tiredIsa made their first contribution in
- @Ni-zav made their first contribution in
- @kntrttm made their first contribution in
- @kevin9327 made their first contribution in
- @mekanix made their first contribution in
- @nuIIpointerexception made their first contribution in
- @john8675309 made their first contribution in
- @CQMHV made their first contribution in
- @kuishou68 made their first contribution in
- @midasdf made their first contribution in
- @bommerts made their first contribution in
- @leonaci made their first contribution in
- @juansebsol made their first contribution in
- @WildfootW made their first contribution in
- @Mawfyy made their first contribution in
- @petrleocompel made their first contribution in
- @bflatastic made their first contribution in
- @Pedroj-64 made their first contribution in
- @floflo777 made their first contribution in
- @HEOJUNFO made their first contribution in
- @Ar-maan05 made their first contribution in
- @naumanAhmed3 made their first contribution in
- @ljkx made their first contribution in
- @carterwsmith made their first contribution in
- @coygeek made their first contribution in
- @neversaynv3r made their first contribution in
- @ianswope made their first contribution in
0.2.0Big update
- Automation (MCP / control channel) now needs explicit file roots. File access from automation clients is limited to folders you grant with --automation-read-root <dir> / --automation-write-root <dir> (or PHOTOCRAFT_AUTOMATION_READ_ROOT / PHOTOCRAFT_AUTOMATION_WRITE_ROOT), and paths must be relative to them. Without roots, automation file operations fail closed. The desktop control channel also requires the per-launch token printed at startup. Interactive file dialogs and one-shot CLI commands are unaffected.
- Camera RAW: DNG, Canon CR2, Sony ARW (lossless and compressed), Panasonic RW2 and uncompressed Olympus ORF now decode. Nikon's compressed NEF and other formats still open their embedded full-size preview for now.
- Indexed Color: no panic when forced colours fill the palette
- MCP: a panicking command no longer wedges the headless session
- Layers: Add Layer Mask uses the active selection
- feat(ui): add Exit to the File menu
- fix(ui): give menu bar labels more breathing room
- Eraser on Background layer paints the background colour (fixes #15)
- Open links in the system browser via a platform service (fixes #14)
- Test: Image Rotation rotates every layer (re #1)
- GPU: Rgba16Float fallback when Rgba32Float isn't renderable (fixes #7)
- Add File > Open Recent (fixes #5)
- Licensing: MIT OR Apache-2.0 files, NOTICE, ArtCraft brand terms, attribution
- cms tests: system_profiles skips malformed named-colour profiles
- Codecs: camera raw files fail with a clear "not supported" error
- Filter › Other › Minimum / Maximum: Preserve Roundness
- Layer Style › Blending Options › Blend If (render, PSD round trip, command)
- Dialogs can be moved by dragging the title bar
- Layer Style dialog previews effects live on the canvas
- Never crash: steering rules, clippy.toml, forbid unsafe
- CI: green on all platforms (rustfmt config, clippy 1.99, FXC-safe adjust shader)
- feat(ui): confirm before discarding unsaved changes
- docs: add mdBook and security documentation foundation
- Never crash: psd, codecs, format, io are panic-free
- Never crash: cms is panic-free
- Never crash: text, color, doc, paint, geom, raster, compose, vector
- Never crash: automation (MCP/RPC) and photocraft-cli are panic-free
- Never crash: algo pyramids and ui-egui parity without expect
- Never crash: the engine is panic-free
- Never crash: the GPU compositor is panic-free
- Never crash: algo is panic-free
- Never crash: ui-egui is panic-free
- Never crash: last-resort guard for commands and file import/export
- Never crash: ops denies panicking shortcuts
- security: authenticate control channels and bound transport resources
- PSD round trip: read/write Vibrance, Color Balance, B&W, Photo Filter, Channel Mixer; corpus floors
- UI input: Ctrl+'+' zooms the canvas, dialogs don't cancel on outside click, menu hover-switch
- macOS: open files from Finder/Open With/Dock; file path, recent, warnings and .pcraft fixes
- Camera raw: clean-room pure-Rust decoder (DNG, CR2, TIFF/EP raws) with develop pipeline
- Colour-managed canvas: document profile -> monitor (P3/Adobe RGB/ProPhoto/Gray/CMYK), linear EXR, embedded CMYK
- Sandboxed WebAssembly plug-ins: photocraft-plugins (wasmi), plugin.* commands, Filter › Plug-ins
- Image › Adjustments overhaul: full params, one editor per kind, live-preview dialogs, Curves point deletion
- Magic Eraser and Background Eraser tools; canvas rotation/flip/size move vector geometry
- Photoshop brushes: .abr import, stylus pressure/tilt, 36 grouped presets, .grd import
- security: constrain automation file access to granted roots
- Large images: adapter texture limits, banded compositing/export, proxy thumbnails, history byte budget
- fix(ui): brush and eraser show the real stroke while drawing
- Select › Color Range: the dialog, Select presets, eyedroppers, Localized Color Clusters, Invert
- Persist brush presets (user + imported .abr) in a size-aware preset store
- raw: Sony cRAW, Panasonic RW2 (RawFormat 5), uncompressed ORF + ORF previews; NEF blocked (clean-room)
- GPU canvas: Rgba16Float display texture for 16/32-bit documents
- Adjustment dialogs: GPU live preview through a clipped adjustment layer
- Painting: right-click opens the brush picker (or erases), real Smoothing, eraser-on-Background tests
- Release 0.2.0
- @storybored379 made their first contribution in
- @Multipad-cyber made their first contribution in
- @torstfugl made their first contribution in
- @echelon made their first contribution in
- @sommerper made their first contribution in
- @Gh0stlyKn1ght made their first contribution in
0.1.1
0.1.0