What's Changed
- Save the flattened document at full size into .pcraft files as an option by @dotCooCoo in #9913
- Add guarded scratch storage and owned memory supervision by @vistaero in #5330
- Save: stop doubling the encoded file in memory (#6607) by @VishnuByrraju in #8115
- Stream native PSD/PSB and EXR imports through bounded bands by @vistaero in #5331
- Size PSD import memory limits from available RAM by @wanikhawar in #10897
- Portable mode: create the write probe exclusively, never through an existing entry by @dylanmtaylor in #10963
- codecs: refuse EXR preview attributes larger than their value by @dylanmtaylor in #10982
- security(affinity): charge allocation records, empty subpaths, paint lists, tile indexes and shape lookups by @dylanmtaylor in #10966
- Stream GPU viewport pages with bounded staging and cancellation by @vistaero in #5332
- fix(ui): Save for Web Matte takes only whole colours while typed (#8830) by @hnoerenberg in #8890
- test(ui): pin the options-bar swatch's rounded checker clip (#8741) by @hnoerenberg in #8898
- fix(ui): the Stroke Path dialog remembers Simulate Pressure (#10527) by @hnoerenberg in #10583
- fix(plugins): the install error names the format the file actually is (#10362) by @hnoerenberg in #10633
- fix(ui): Ctrl+Alt + wheel zooms the canvas like Alt + wheel (#10488) by @hnoerenberg in #10517
- TIFF Options: compression, image pyramid and Save Transparency (#8827) by @Yuki-init in #10932
- fix(ui): Minimum and Maximum preview at the scale they apply (#10474) by @hnoerenberg in #10524
- Type: add OpenType Numerals submenu (figure styles) by @tareq-halaby in #11051
- fix(ui): Roundness previews its radius within 1 px, and a held frame survives a factor change (#10474) by @FredApps in #11081
- fix(ui): Overscroll off keeps an image smaller than the window centred (#10488) by @FredApps in #11085
- Don't auto-select off-canvas layers from the pasteboard (#10665) by @RickiNano in #10731
- Integrate streamed PSB saves with the shared save service by @vistaero in #5333
- Integration batch 13: 13 parity epic PRs on main by @davidmann4 in #10952
- Record actions in a document-independent form (#219) [depends on #4496] by @FabioLissi in #4514
- Batch: subfolders, open documents, file naming, stop on error, error log, progress and cancel (#219) by @FabioLissi in #4579
- Layers panel: the filter row lists linked, missing or embedded smart objects by @dotCooCoo in #9211
- Layers panel: filter by Color, as in Photoshop (#5898) by @hectorviov in #10439
- Layers panel: show the filter row in every theme by @Psychotoxical in #10752
- Support newer recorded Action events by @yoriswind in #10755
- Actions: support direct Gradient Map and Lab-range Replace Color by @yoriswind in #10765
- ATN: keep encoding fallbacks among the top-scoring candidates by @neversaynv3r in #10832
- Crop with Delete Cropped Pixels off turns the Background into Layer 0 (#10867) by @ljkx in #10905
- Actions: a recorded Save As or Save for Web with the suggested name saves each document under its own (#5305) by @Daktyl198 in #5430
- Actions: Check Spelling records and saves as the spellCheck event by @dotCooCoo in #8726
- Crop: ⇧-corner drag follows the frame's diagonal (#10871) by @ljkx in #10941
- CMYK: adjustment layers in the special eight keep the Fill rule on the ink path (#10386) by @davidmann4 in #10387
- text: find paragraphs and trailing blanks without rescanning by @dylanmtaylor in #11045
- Integration batch 14: 9 PRs planned by @davidmann4 in #11157
- fix(ui): Free Transform keeps plain layers over the moving one under a blend or adjustment layer (#9387) by @x-labb in #9573
- Fix Crop Clear retaining custom proportions by @vanvo in #9842
- Crop: the Info panel shows the crop frame's W and H (#3145) by @indy2kro in #10453
- Free Transform: lift a pixel's coverage up to all of it, as Move does by @hectorviov in #10565
- Crop: no frame around the cropped image until the next press by @D-monized in #10642
- fix(algo): Filter Gallery reach no longer overflows on out-of-range stored effect values by @jayzed80 in #10850
- Crop: a Ctrl-held Straighten line keeps the frame size (#10870) by @ljkx in #10950
- Actions: map recorded Shear curves by @yoriswind in #10955
- Actions: map recorded Scale Effects and Create Layers by @yoriswind in #10998
- Crop: give each overlay its own glyph in the menus and on the options-bar button (#10889) by @Raghav2012Code in #11019
- Layers panel: filter by layer effect (#10880) by @Psychotoxical in #11067
- Crop: turning the image keeps the frame inside it (#10869) by @ljkx in #11109
- Crop: H and P pick the Hand and Pen tools over the default frame (#9731) by @Luis-0508 in #9855
- text: group glyphs by colour once instead of rescanning per colour by @dylanmtaylor in #11069
- text: merge a run of union components once when fitting area type by @dylanmtaylor in #11065
- fix(gpu): saturate effect band edges at the coordinate ceiling by @dylanmtaylor in #11057
- ipp: resume the reply's header search where the last read stopped by @dylanmtaylor in #11049
- raw: check retone's pixel count with checked multiplication by @dylanmtaylor in #11043
- raw: refuse lossy DNG tiles that carry Extended XMP by @dylanmtaylor in #11042
- raw: decode a tile range once when several tiles share it by @dylanmtaylor in #11041
- raw: refuse JPEG XL tiles with compressed metadata boxes or splines by @dylanmtaylor in #11039
- raw: keep at most 64 GainMap opcodes from one list by @dylanmtaylor in #11023
- codecs: leave Extended XMP fragments out of zune-jpeg's header parse by @dylanmtaylor in #10981
- codecs: charge dropped PNG text against the metadata budget by @dylanmtaylor in #10980
- codecs: admit animated GIF screens, sparse RLE BMPs and icon PNG profiles by @dylanmtaylor in #10979
- format: bound blob inflation by the remaining load budget; browser budgets by @dylanmtaylor in #10984
- Toolbar: Alt/Option-click cycles the flyout tool slot by @tareq-halaby in #10301
- Properties: W/H/X/Y take a typed percentage (#10784) by @RickiNano in #10802
- Preferences: show Effect Cache, which the engine reads (#204) by @RickiNano in #10921
- perf(bench): split command and refresh time; refresh like the app; stop rows timing setup by @RickiNano in #10750
- PSD: keep stylistic sets in Txt2 for PhotoCraft-native documents by @tareq-halaby in #10313
- fix(layers): refuse to ungroup the sole empty layer group (#11118) by @hnoerenberg in #11163
- fix(atomic): report where the original survives when the Windows restore fails by @hnoerenberg in #11189
- fix(assets): bind post-save generation to the saved document's identity by @hnoerenberg in #11244
- feat(filters): Lens Flare looks like Photoshop's (SSIM 0.97–0.995 per lens) by @the-unknown in #8705
- Integration batch 15: Crop, Free Transform and Actions epic PRs by @davidmann4 in #11203
- fix(gpu): build compositor pipelines without sharing FXC shader blobs across threads (#9173) by @FinnNk in #9182
- feat(ui): live preview in Color Pickers for dialog colour fields and the Crop shield (#9886) by @ljkx in #9979
- fix(ui): open export dialog for Data Sets as Files and gate on data sets by @kk376 in #10203
- Edit › Transform › Distort: side handles move their edge, Perspective's side handles skew (#10085) by @ljkx in #10814
- Load Actions: Mac Roman step names with accented letters or a degree sign read as Mac Roman (#10774) by @TrevorBrown-dev in #10837
- Free Transform: Shift-rotate snaps the turn made by the drag (#11099) by @vangel76 in #11162
- contributors: set names for vangel76 by @vangel76 in #11207
- Crop: centred 48-point grid while turning by @yoriswind in #11220
- fix(ui): a save that failed some Image Assets reports which outputs (#11117) by @hnoerenberg in #11168
- Integration batch 16: 9 epic PRs on main by @davidmann4 in #11278
- feat(zoom): refine zoom field input handling, focus rules, and animation by @sn-o-w in #6647
- Crop: Esc hides the crop frame until the next press (#10370) by @qvest-ssels in #10396
- Group action playback into one history state by @yoriswind in #10965
- Actions: map recorded Content-Aware Fill settings by @yoriswind in #10986
- Layers filter: fill layers match no Kind button, and the Mode list has no Pass Through (#10878) by @Hamza0101 in #11017
- Layers panel: filter by layer attribute (#10881) by @Psychotoxical in #11077
- Actions: support recorded Type Create Work Path by @yoriswind in #11222
- Actions: map supported classic Gradient recordings by @yoriswind in #11223
- Layers panel: applying a filter deselects the layers it hides (#10879) by @NaufalDzz in #11235
- Free Transform: linked layers transform together (#11217) by @chamber074 in #11243
- Pass the Linux signing key to the release workflow by @dylanmtaylor in #11344
- PDF export: keep the top text and shape layers as vectors, with selectable text by @wanikhawar in #10355
- perf(paint): create a large dab's new coverage tiles on the workers by @wanikhawar in #11349
- perf(ui): cache Adaptive Wide Angle preview mesh for constraint overlays by @wanikhawar in #9872
- Add a headless GPU backend for composition and flat export by @wanikhawar in #10842
- Use native Pen cursors to avoid canvas-frame delay by @wanikhawar in #10860
- Paste into another artboard keeps the place on the board (#8788) by @Probler-Yt in #10538
- bs: Add Bosnian (bs) to the interface languages by @nine-codes in #10290
- feat(paint): add History Brush opacity/flow controls, source selection, and custom icon by @davidvhk in #4446
- Expose optional GPU composition and export in photocraft-cli by @wanikhawar in #10912
- Fix imported gradient presets sharing selection names by @wanikhawar in #10521
- Type: add OpenType Stylistic Sets submenu (Set 1–20) by @wanikhawar in #10304
- Move tool: auto-nest layers into the artboard they're dropped on (#10218) by @Probler-Yt in #10512
- Bound Photomerge memory and safely reject out-of-budget jobs (#7851) by @wanikhawar in #10463
- Art History Brush: Opacity on the options bar (#10263) by @wanikhawar in #10278
- UI: 2-column Home screen with recent file cards and centered workspace by @coqui-software in #7231
- perf(io): build JPEG/PNG tiles straight from the decoded rows, in parallel (#10259) by @wanikhawar in #10281
- fix(compose): align CMYK adjustment Fill and Posterize with split rendering by @wanikhawar in #11001
- Home screen: hide the tools, options bar, status bar and docks while Home is up by @wanikhawar in #11253
- PSD: flat files keep their spot and alpha channels by @wanikhawar in #10260
- Selection: Grow and Similar match only selected colours, Grow starts from the frontier by @wanikhawar in #9673
- perf(paint): cache sampled-tip mipmaps between strokes by @wanikhawar in #9617
- MCP headless: waited commands run as jobs, with progress and cancel (#8129) by @wanikhawar in #8132
- feat(frame): rework the Frame tool's selection, handles and placement by @wanikhawar in #8920
- test(engine): cover File Info exposure 1/n formatting by @mroxso in #6983
- Select sky beneath an obstructed top border by @wanikhawar in #9693
- fix(compose): keep CMYK backdrop inks exact at zero Fill by @wanikhawar in #10985
- MCP bridge: waited commands poll the app's job, with progress and cancel (#8130) by @wanikhawar in #8134
- perf: JPEG/PNG open bench with per-phase timings and peak memory (#10259) by @wanikhawar in #10271
- Make Select and Mask refinement and previews tile-sparse by @wanikhawar in #10732
- Guides: integrate edit-session previews and interaction-check scenarios by @PerchAnton in #9190
- Artboards: clipping groups move between boards together; pastes off the boards and into masks land right by @FredApps in #11441
- perf(io): stream large PNGs row by row into the layer's tiles (#10259) by @wanikhawar in #10305
- Canvas: a right-click that moved a few pixels still opens its menu (#10183) by @ZIDAN44 in #10351
- Add recipe-driven checks for PSD exports by @wanikhawar in #10307
- fix(ui): About credits table columns can be dragged wider or narrower by @FredApps in #11182
- Release: refresh contributor credits for each release (#8737) by @Luis-0508 in #11426
- Type: a duplicated type layer is renamed after its new text (#9023) by @ZIDAN44 in #10352
- Integration batch 17: 14 epic PRs by @davidmann4 in #11320
- Free Transform: hide the reference point behind a Toggle Reference Point check box (#11098) by @NaufalDzz in #11247
- Color Lookup: apply a .3dl's shaper before the table (#8982) by @hectorviov in #9170
- Layers panel: the filter row lists the artboards that hold the selected layers by @dotCooCoo in #9315
- feat(ui): add a Reset button to the Crop tool's options bar (#9730) by @x-labb in #9739
- fix(ui): a click during a background Free Transform commit runs when it lands (#9974) by @DuBearte in #10360
- Free Transform takes soft edges whole after a move, leaving no outline behind (#10461) by @Lcoding15 in #10505
- Run the selected action in Batch and Create Droplet by @yoriswind in #10612
- Support recorded dialog filters, Calculations and Batch naming by @yoriswind in #10788
- Crop: Fill labels follow Delete Cropped Pixels, and the Selection preset entry (#10872) by @Raghav2012Code in #11011
- Free Transform: a click outside the box on the image no longer commits (#11100) by @vangel76 in #11165
- Expose Move transform controls through the control channel by @yoriswind in #11210
- feat(atn): map Batch steps inside actions to file.automate.batch (#7104) by @HirthikBalaji in #7170
- Fix Paint Bucket target with Gradient-style crosshair by @envy-ai in #7994
- Grow and Similar: budget the colour index and report allocation failures by @wanikhawar in #9825
- perf(algo): build Remove Tool target masks with a bounded separable dilation (#10179) by @wanikhawar in #10194
- Select Subject: keep parts that run off the image edge and detached parts near the subject by @wanikhawar in #10160
- Web build: big operations that won't fit fail with an error instead of trapping, and a trap says so by @wanikhawar in #10129
- perf(paint): sampled, textured and wet-edge dabs rasterize on all cores by @wanikhawar in #11369
- Build the GPU compositor off the UI thread by @wanikhawar in #9969
- Place decodes and fits in the background: dropping a large file no longer freezes the window by @wanikhawar in #10147
- Preview spot inks over the RGB/CMYK composite as an overprint by @wanikhawar in #10276
- GPU plan: cache adjustment LUT rows between plans (#11498) by @RickiNano in #11539
- SVG: refuse filters too costly to render (#9409) by @davidmann4 in #9410
- SVG: a drawing the renderer panics on is an error, not a crash (#9404) by @davidmann4 in #9405
- Crop: the options-bar swap button turns the frame instead of shrinking it (#7738) by @davidmann4 in #7739
- History snapshots: follow-ups to #3567 (#6087) by @davidmann4 in #6088
- Export to files: a Custom JPEG quality in Artboards, Layers and Layer Comps to Files (#11481) by @ZIDAN44 in #11558
- Channels: the panel menu has the channel commands, New Spot Channel among them (#11451) by @ZIDAN44 in #11557
- SVG: the fallback font search reads each font's character map once (#9671) by @davidmann4 in #9672
- Crop / Perspective Crop: a drag held past the canvas edge scrolls the view (#9307) by @davidmann4 in #9310
- Layers: separators between the Blend Mode groups (#5532) by @davidmann4 in #5533
- Crop: Esc in full screen cancels a drag on the default frame (#9275) by @davidmann4 in #9276
- Crop: a tool switch during a frame drag ends the drag (#9223) by @davidmann4 in #9224
- Crop W x H budgets the hidden pixels it resamples (#9212) by @davidmann4 in #9213
- SVG: a DTD entity can't hide nesting from the depth check (#9669) by @davidmann4 in #9670
- Image Size: refuse a resolution outside 1..30000 ppi instead of clamping it (#9260) by @davidmann4 in #9261
- Crop: a click on the frame or a handle never snaps it (#9283) by @davidmann4 in #9284
- Crop: a Straighten line inside the frame no longer snaps like a frame move (#9277) by @davidmann4 in #9278
- Crop: History jumps wait for a pending crop (#9285) by @davidmann4 in #9286
- Crop: switching documents leaves the old document's view turned (#9202) by @davidmann4 in #9204
- History Options: Automatically Create First Snapshot, New Snapshot When Saving, Show New Snapshot Dialog by Default (#2966) by @davidmann4 in #3634
- Single Row / Column Marquee: a drag from inside the selection moves it (#11392) by @RickiNano in #11534
- Integration batch 18: 23 epic PRs (toolbar, move, selection, artboard, menus) by @davidmann4 in #11563
- Selection tools: dragging the outline records Move Selection, as the reference does (#11390) by @TrevorBrown-dev in #11444
- Polygonal Lasso: History step "Polygonal Lasso" and Shift diagonals snap to the shorter offset (#11393) by @Hamza0101 in #11453
- Shortcuts: Ctrl+Alt+0 also zooms to 100% and F9 also opens Actions, the reference's second keys (#11396) by @TrevorBrown-dev in #11456
- Elliptical Marquee: the anti-aliased edge ramps across the pixel, matching the reference within 1 level (#11391) by @Hamza0101 in #11461
- Menus: Edit › Preferences says Plugins… and Camera Raw… and has the reference's separators (#11398) by @TrevorBrown-dev in #11494
- Artboard tool: the first board drawn in a document takes the Background in as "Layer 0" (#11387) by @TrevorBrown-dev in #11496
- Menus: View › Guides submenu in the reference's order, with Edit Selected Guides and Clear Selected Guides (#11400) by @TrevorBrown-dev in #11497
- Layers panel: a right-click on the empty area opens the reference's menu (#11404) by @TrevorBrown-dev in #11500
- The document tab's right-click menu lists the reference's eight entries in order, with its two separators (#11403) by @TrevorBrown-dev in #11502
- Layer > Smart Objects says Reveal in Explorer, Embed Linked and Embed All Linked, in the reference order, without the Warp rows (#11401) by @TrevorBrown-dev in #11503
- Select and Mask: E switches the tool mode between add and subtract (#11402) by @TrevorBrown-dev in #11511
- Shift+letter cycles a tool group in toolbar order and the anchor point tools no longer take the letter P (#11376) by @TrevorBrown-dev in #11521
- The Artboard tool's Add New Artboard button switches on a placing mode where a click puts a bar-sized board at the click (#11386) by @TrevorBrown-dev in #11532
- The healing slot starts on Spot Healing Brush and the brush slot lists Color Replacement before Mixer Brush (#11375) by @TrevorBrown-dev in #11535
- Actions: replay recorded Perspective Warp steps by @yoriswind in #11553
- feat(ui): bounding box with eight handles for several selected shape layers (#11107) by @x-labb in #11295
- Move tool: Shift+drag of a layer locks to the eight directions, as the reference does (#11382) by @TrevorBrown-dev in #11436
- Shortcuts: Ctrl+/ opens Layer › Lock Layers…, shown in the Layer menu and the Layers panel menu (#11397) by @TrevorBrown-dev in #11437
- Move tool: History names its steps Move, Nudge and Duplicate as the reference does (#11383) by @TrevorBrown-dev in #11443
- Marquee: with no selection, Shift and Alt held from the press constrain the shape (#11389) by @Hamza0101 in #11449
- Menus: Combine Shapes, Open Recent, Arrange and Proof Setup items carry the reference's names (#11399) by @TrevorBrown-dev in #11455
- Crop: fill the active layer and Background with Content-Aware Fill by @yoriswind in #11458
- Actions: play recorded Stack Modes and Video Frame events by @yoriswind in #11495
- Copy the shared house rules into AGENTS.md by @FredApps in #11632
- Image: Trim (Transparent Pixels) ignores alpha that rounds to 0 at the document's depth (#9299) by @davidmann4 in #9300
- PSD write recipes: keep every exported candidate and pin the base file by @wanikhawar in #11607
- Match Rotation leaves a pending crop's turn out (#9308) by @davidmann4 in #9309
- ui.click / ui.move reject coordinates beyond the screen range (#9137) by @davidmann4 in #9138
- Review follow-up to #10328: Liquify saved twirl, copied type brings its styles, restored tests (#10500) by @davidmann4 in #10501
- Interface: remove the Enable animations preference (#9479) by @davidmann4 in #9480
- Image Rotation: a flip reverses an Angle gradient fill's sweep (#9243) by @davidmann4 in #9244
- Windows: count scratch room when opening large files; refusal names the build's limit by @wanikhawar in #11513
- Keep each colour's values in the Selective Color dialog by @wanikhawar in #11474
- Windows: run explorer.exe and reg.exe by full path (#9666) by @davidmann4 in #9667
- Content-Aware Scale works on the Background with a selection (#7717) by @davidmann4 in #7719
- Rotated view: Type box and Move marquee previews follow the document axes (#7063) by @davidmann4 in #7064
- Stop stale settings overriding edits to adjustment smart filters by @wanikhawar in #11609
- Stop an adjustment smart filter losing settings when its dialog is confirmed by @wanikhawar in #11613
- Web build: Place runs a slice per frame, so a large PNG no longer freezes the page by @wanikhawar in #10164
- Network scratch folders report their own free space, or say they can't by @wanikhawar in #11628
- A scratch folder that stops answering no longer freezes the app by @wanikhawar in #11652
- A little free memory no longer refuses every PSD; the refusal says what to do by @wanikhawar in #11641
- Add an opt-in WinTab backend for pen pressure on Windows by @Triwarr in #11331
- CI: run the GPU tests on lavapipe on Linux and fail if they skip by @FredApps in #7975
- fix(export): preserve high-quality JPEG colour detail in Export As by @fokas-hoa in #7985
- Integration batch 19: epic PRs (WIP) by @davidmann4 in #11643
- fix(transform): a click on another layer's pixels commits the box; the next click picks it (#11100, #8208) by @Higgs32584 in #9862
- Move tool: an arrow nudge is one screen pixel, as in Photoshop (#9511) by @hectorviov in #10438
- Pen: Make Shape turns the path into a shape layer (#10934) by @DingusMcRinkyDinky in #11005
- Actions: load and save Blend If and Gradient Fill layers (#10771) by @NaufalDzz in #11249
- Right-click on the toolbar's "…" button opens a flyout with one row, Edit Toolbar… (#11378) by @TrevorBrown-dev in #11541
- i18n and Layers empty-area menu follow-ups to integration batch 18 (#11494, #11503, #11455, #11500) by @TrevorBrown-dev in #11648
- feat(ui): Path mode for the Shape tools (part of #9453) by @hectorviov in #9456
- Select and Mask: resize the brush with Alt+right-drag by @hectorviov in #10559
- Add Group filter to Layers panel (#10883) by @Nurana100 in #11092
- Crop: Contextual Task Bar under the crop frame, as a reusable task-bar widget (#10890) by @davidmann4 in #11669
- Integration batch 20: 7 i18n PRs (Thai, Hebrew, Urdu, Tamil, Azerbaijani, Romanian, Korean) by @davidmann4 in #11671
- Add Korean support by @arksky1 in #8185
- i18n: add Thai UI catalog by @Thanawatttt in #10241
- i18n(ui-egui): add Tamil (ta) translation by @newsbaba24x7 in #10359
- i18n: add Urdu (ur) UI translation by @tronicum in #10361
- i18n: add Hebrew (he) UI translation by @tronicum in #10365
- i18n: add Romanian (ro) UI translation by @tronicum in #10547
- i18n: add Azerbaijani UI language by @Taxperia in #10555
- perf(paint): Smudge start-up and selection sampling without per-pixel work by @vangel76 in #11146
- perf(paint): cache procedural brush textures between strokes by @vangel76 in #11148
- i18n: translate Contextual Task Bar in the Azerbaijani catalog (#11737) by @davidmann4 in #11738
- Crop: Always Show Overlay by default, Fill resets on another open document, and an untouched frame shows only itself (#10894, #10930) by @Hamza0101 in #11022
- fix(transform): refuse the Background among several layers and apply the box on a selection change by @NaufalDzz in #11252
- Marquee and Lasso: a drag after moving pixels moves only the outline (#11368) by @RickiNano in #11672
- i18n: no test fails on a missing translation (#11778) by @davidmann4 in #11780
- Toolbar slots and tool keys keep their last tool across launches (#3569) by @Saloouu in #11322
- Magnetic Lasso: a right-click while drawing opens no menu (#11689) by @RickiNano in #11692
- feat(move): options bar gets Distribute buttons, the ... icon panel and the gear menu (#11381) by @TrevorBrown-dev in #11540
- fix(ui): Delete with a note selected asks to delete the note, not the layer (#11788) by @DuBearte in #11841
- fix(paint): Pressure for Size starts off, as the reference does by @hnoerenberg in #11847
- fix(engine): deleting the current count group makes the first group current (#11771) by @DuBearte in #11851
- Show notes after creating one with the Note tool by @yoriswind in #11865
- Sample the targeted layer mask with the Eyedropper by @yoriswind in #11862
- Actions: typed text records as one step; Batch says which files failed (#10113, #10682) by @Lcoding15 in #10730
- Raw: decode Canon sRAW / mRAW CR2 files by @texjer in #7122
- Liquify: Preview checkbox and P show the image unwarped by @hectorviov in #10566
- Levels: Alt-drag clipping display (#3328) by @funkvay-star in #3693
- Context menus: an overflowing menu shows ▲/▼ scroll arrows (#2091) by @Higgs32584 in #6417
- docs: regenerate the scorecard so main is green again (#11983) by @davidmann4 in #11984
- Preferences: Skip Transform when Placing (#8492) by @indy2kro in #9075
- Print: Japanese paper sizes (はがき・往復はがき・JIS B5/B4・L判) by @midasdf in #8307
- feat(psd): parse legacy frame-animation metadata by @cloutier in #8633
- Drag a layer mask onto another layer or group to move it, ⌥ to copy it (#10485) by @hectorviov in #10549
- Save for Web: show slices in the preview and export selected slices by @hectorviov in #10557
- Replace Color: Add to Sample and Subtract from Sample (#6280) by @hectorviov in #10443
- Saves take maximizeCompatibility for a PSD/PSB's merged image (#8064) by @indy2kro in #10001
- chore(docs): regenerate docs/scorecard.md (prefs 193 -> 194) by @hnoerenberg in #12012
- fix(ui): Properties panel value fields: sliders keep a drag, a wheeled Transform field is one edit by @FinnNk in #10403
- Polygonal Lasso: the last corner of a small shape no longer closes it (#6578) by @vangel76 in #6734
- Affinity reader: table-based raster conversion and parallel tile decoding by @vangel76 in #9414
- raw: DNG saturation histogram per CFA row in parallel bands by @vangel76 in #9447
- raw: orientations 5-8 copy the frame in tiles (stacked on #9455) by @vangel76 in #9459
- raw: MHC and bilinear demosaic written out per row kind (stacked on #9455) by @vangel76 in #9464
- perf(psd): single-pass 16/32-bit ZIP prediction encode and decode by @vangel76 in #9745
- perf(cms): block the 8/16-bit matrix/TRC conversion over 64 pixels by @vangel76 in #9746
- perf(cms): tabulate the first-stage curves for 8-bit exact pipelines by @vangel76 in #9747
- Render Video: cap the total an animated GIF keeps staged (#6103) by @vangel76 in #10947
- fix(ui): Patch tool hides the selection it replaces and shows +/− badges (#11024) by @RickiNano in #11115
- Brush: Texture at a scale other than 100% samples about 1.6x faster, same pixels by @vangel76 in #11142
- perf(paint): Mixer Sample All Layers reads only the dab rectangle by @vangel76 in #11147
- Paint: stream the dab generator's steps, keep NaN brush values and points out (#11137) by @vangel76 in #11155
- Text fields: test that their text is centred in the box (#2084) by @RickiNano in #11608
- Windows: the pen's eraser end selects the Eraser (#2285) by @RickiNano in #11684
- Saving: the temporary file is no longer a dot file (#11624) by @ZIDAN44 in #11691
- Shapes: a selected shape's box resizes from anywhere along a side (#11473) by @ZIDAN44 in #11698
- Labels: match Photoshop's menu, tooltip and spelling conventions by @nikolainyegaard in #8239
- JPEG Options: remember the last quality and format (#9631) by @SofiaAFigueredo in #9661
- Curves: Option/Alt+2..6 select the dialog's channel (#7325) by @qvest-ssels in #10475
- Layers panel: Convert to Shape and Create Work Path on type layers by @rus152 in #9821
- raw: decode Nikon "lossy after split" NEFs by @luben93 in #10529
- Gradient Map: drag a stop off the strip to remove it by @DingusMcRinkyDinky in #10797
- Layer Style: a drag on the image moves a Gradient Overlay (#10763) by @TrevorBrown-dev in #10840
- fix(ui): Escape in the Brush Preset picker reverts what was typed (#11816) by @DuBearte in #11850
- raw: LinearRaw fill works out the black level once per row and phase (stacked on #9455) by @vangel76 in #9460
- Guide dialogs: add Position Tab navigation and preserve exact positions by @SvenCarstensen in #9876
- memory: a sandbox without a cgroup mount no longer reads as 0 bytes free by @diegochagas in #11538
- feat: Layer > Smart Objects > Reset Transform (#11662) by @hnoerenberg in #11675
- The Artboard tool's options bar gets the iPhone 8/7/6 default size, a background control, the Align panel and the gear menu (#11385) by @TrevorBrown-dev in #11545
- Magnetic Lasso: the edge comes from the visible composite, not the active layer (#11686) by @TrevorBrown-dev in #11710
- Magnetic Lasso: Shift+[ and Shift+] jump to the width limits (#11688) by @TrevorBrown-dev in #11701
- fix(ui): the Brush options bar gets the reference tooltips and Smoothing Options title (#11813) by @DuBearte in #11857
- Equalize: with a selection, choose the selected area only or the entire image based on it by @dotCooCoo in #9604
- Window > Arrange: drag the borders between arranged documents (#10101) by @Lcoding15 in #10695
- Curvature Pen: carry an open path on from its selected endpoint (#10726) by @Lcoding15 in #10744
- i18n: Georgian (ka) interface language by @devius in #5845
- fix(ui): remember foreground and background colors between launches (Photoshop parity) by @david419kr in #8485
- New Guide takes arithmetic in its position, as in Photoshop (#10440) by @hectorviov in #10445
- Paths: ⇧⌥⌘↩ intersects the path with the selection (#7726) by @hectorviov in #10429
- Brush Settings: align Angle and Roundness left of the tip widget by @augrclk in #5269
- fix(ui): live preview in the Fade dialog (#8230) by @Korg1ch in #8261
- Render live painting and canvas navigation in the input frame by @bommerts in #5238
- PSD: Photoshop's Puppet Warp smart filter, drawn with the mesh the file stores by @Tungtono in #8140
- Reset Tool gives the Brush a 13 px soft tip (#11810) by @RickiNano in #11856
- fix(type-tool): start the type tool at 50 pt by @hnoerenberg in #12110
- Move tool: Auto-Select target defaults to Layer; dropdown lists Group, Layer (#11380) by @hectorviov in #12166
- Select Behind with Shift+Alt+Q for Brush and Pencil by @yoriswind in #12092
- Free Transform: relative positioning toggle between X and Y (#11679) by @hectorviov in #12139
- Background Eraser: Alt+click picks the foreground colour (#11906) by @davidmann4 in #12190
- Add five Classic Actions panel commands by @yoriswind in #10766
- Actions: map Create Droplet and cover the Gradient tool's recorded steps (#10710) by @hectorviov in #12134
- Magnetic Lasso: fastening points are spaced as the reference measures (#11687) by @TrevorBrown-dev in #11700
- Smooth live preview for Work Path dragging by @FartmanAndBurps in #9306
- Select › Find Layers opens the Layers panel's Name filter (#10884) by @NaufalDzz in https://github.com/storytold/photocraft/pull/11238
- Preserve Count groups in PSD resource 1080 by @yoriswind in https://github.com/storytold/photocraft/pull/12093
- raw: decode Hasselblad 3FR/FFF (X2D II 100C, uncompressed) by @Gotya-OFFCIAL in https://github.com/storytold/photocraft/pull/9058
- Color Sampler: a new point lands where the drag ends, markers follow the pointer, a click on a point moves it, Escape cancels (#11729) by @hectorviov in https://github.com/storytold/photocraft/pull/12173
- Camera Raw: Done saves the raws' settings to their sidecars without opening them by @texjer in https://github.com/storytold/photocraft/pull/7121
- Camera Raw: raws opened together share the dialog in a filmstrip by @texjer in https://github.com/storytold/photocraft/pull/7120
- Patch tool: start Content-Aware Sample All Layers on (#12125) by @ElNeMeR70 in https://github.com/storytold/photocraft/pull/12164
- Photo Filter opens at its last settings (#9879) by @ljkx in https://github.com/storytold/photocraft/pull/9970
- Use whole-edge Free Transform handles and consistent rotate cursors by @yoriswind in https://github.com/storytold/photocraft/pull/11221
- xtask: check that every panel button routes through a command id (#3495) by @davidmann4 in https://github.com/storytold/photocraft/pull/3498
- Crop: Shift+H, Shift+P and Shift+I switch tools again (#9232) by @davidmann4 in https://github.com/storytold/photocraft/pull/9233
- Scale Effects and Image Size scale Bevel & Emboss Texture's scale (#9254) by @davidmann4 in https://github.com/storytold/photocraft/pull/9256
- Crop: refuse an invalid explicit rectangle instead of cropping to the selection (#9279) by @davidmann4 in https://github.com/storytold/photocraft/pull/9280
- CMYK: the test reference keeps the source ink over nothing (#12079) by @davidmann4 in https://github.com/storytold/photocraft/pull/12080
- CLI: --metadata none|all leaves document XMP out of convert, run --out and batch exports (#9466) by @ljkx in https://github.com/storytold/photocraft/pull/9975
- Brush: opacity minimum 1 % and "00" sets 100 % (#11812) by @davidmann4 in https://github.com/storytold/photocraft/pull/11823
- Background Eraser: number keys set the Tolerance (#11907) by @davidmann4 in https://github.com/storytold/photocraft/pull/11920
- Color Sampler: right-click menu on the canvas (#11733) by @davidmann4 in https://github.com/storytold/photocraft/pull/11921
- Background Eraser: Tolerance takes whole numbers 1-100 with an alert, bar tooltips (#11909) by @davidmann4 in https://github.com/storytold/photocraft/pull/12188
- Toolbar: Star Tool in the shape slot between Polygon and Line (#11377) by @hectorviov in https://github.com/storytold/photocraft/pull/12142
- ui-egui: support native file drag and drop on Wayland by @aethelisdev in https://github.com/storytold/photocraft/pull/10222
- Export dialogs start in the last exported folder (#10192) by @qvest-ssels in https://github.com/storytold/photocraft/pull/10448
- PDF: import pages as artboards, export a page per artboard (+ recursive group export) by @Triwarr in https://github.com/storytold/photocraft/pull/11647
- Gradient stops dragged off the bar are removed in every stop editor (#10742) by @ljkx in https://github.com/storytold/photocraft/pull/10823
- Brush Settings: place Both Axes on the Scatter header by @augrclk in https://github.com/storytold/photocraft/pull/5250
- feat: add Indexed Color Matte options by @Firstbober in https://github.com/storytold/photocraft/pull/9887
- Use toolbar order for fresh tool shortcuts by @yoriswind in https://github.com/storytold/photocraft/pull/11852
- Blend mode keys leave Behind when they pick another mode by @hectorviov in https://github.com/storytold/photocraft/pull/12248
- Rasterize prompt: the smart object wording as in the reference by @hectorviov in https://github.com/storytold/photocraft/pull/12252
- Color Replacement: Alt+click picks the foreground like the Eyedropper by @hectorviov in https://github.com/storytold/photocraft/pull/12256
- Background Eraser: the compact brush popup from the picker and a right-click by @hectorviov in https://github.com/storytold/photocraft/pull/12257
- Color Replacement: History names each edit "Color Replacement Tool" by @hectorviov in https://github.com/storytold/photocraft/pull/12263
- Eraser: in Block mode a right-click opens the Brush / Pencil / Block menu by @hectorviov in https://github.com/storytold/photocraft/pull/12269
- Background Eraser: a 13 px hard tip at 25 % spacing after Reset Tool by @hectorviov in https://github.com/storytold/photocraft/pull/12253
- Patch: Shift during the drag keeps the patch horizontal or vertical (#12129) by @TrevorBrown-dev in https://github.com/storytold/photocraft/pull/12274
- Color Replacement: in Lab, Color keeps L and takes the foreground's a and b by @hectorviov in https://github.com/storytold/photocraft/pull/12260
- Color Replacement: refuse RGB/32, Grayscale, Bitmap and Indexed documents by @hectorviov in https://github.com/storytold/photocraft/pull/12265
- Brush: the reference's alert when it can't paint by @hectorviov in https://github.com/storytold/photocraft/pull/12254
- Mixer Brush: Useful mixer brush combinations dropdown (#11946) by @hectorviov in https://github.com/storytold/photocraft/pull/12293
- Zoom tool bar: 100%, Fit Screen and Fill Screen with the reference tooltips, no hint text by @DuBearte in https://github.com/storytold/photocraft/pull/12286
- Hand tool: the canvas right-click menu lists only Fit on Screen, 100%, 200% and Print Size by @DuBearte in https://github.com/storytold/photocraft/pull/12291
- Smoothing Options: greyed out at Smoothing 0 % (#11939) by @hectorviov in https://github.com/storytold/photocraft/pull/12279
- Ruler: Shift snaps to 45 degree steps without making the ruler longer (#11985) by @hectorviov in https://github.com/storytold/photocraft/pull/12307
- Mixer Brush: refuse Indexed Color and Bitmap documents with the alert (#11958) by @hectorviov in https://github.com/storytold/photocraft/pull/12306
- Patch: History names as the tool's (fixes #12117) by @SBaksa in https://github.com/storytold/photocraft/pull/12255
- Zoom tool menu: keep the view centre for Zoom In and Out by @Bobderto in https://github.com/storytold/photocraft/pull/12102
- fix(ui): the Type options bar gets the reference tooltips (#12057) by @rmsff in https://github.com/storytold/photocraft/pull/12328
- fix(ui): Escape commits a Type Mask session as Command+Return does (#12070) by @rmsff in https://github.com/storytold/photocraft/pull/12333
- fix(ui): a Type Mask always replaces the selection when committed (#12073) by @rmsff in https://github.com/storytold/photocraft/pull/12338
- Camera Raw sidecars: apply the crop, stop reporting RawFileName (#9985) by @ljkx in https://github.com/storytold/photocraft/pull/9991
- fix(engine): the Type tool leaves a selection in Indexed Color by @hnoerenberg in https://github.com/storytold/photocraft/pull/12144
- fix(engine): Straighten Layer greys out and refuses the states the reference does by @hnoerenberg in https://github.com/storytold/photocraft/pull/12148
- Pencil: the Auto Erase checkbox shows its tooltip by @DuBearte in https://github.com/storytold/photocraft/pull/12205
- Perspective Crop: the options bar's Cancel and Commit show only during a session (#11978) by @hectorviov in https://github.com/storytold/photocraft/pull/12221
- Notes: new notes store the reference application's colour, popup rectangle and local-time date by @hectorviov in https://github.com/storytold/photocraft/pull/12231
- Count tool: History names Add/Drag/Delete Count Object, Add Count Group and one name per group setting (#11763) by @hectorviov in https://github.com/storytold/photocraft/pull/12203
- Brush Preset picker: the tip's angle/roundness widget at its top left by @hectorviov in https://github.com/storytold/photocraft/pull/12238
- File: Open as Smart Object... opens a file as a new document holding one embedded smart object (#11678) by @TrevorBrown-dev in https://github.com/storytold/photocraft/pull/12212
- Patch: an arrow badge over the selection shows that a drag moves the patch (#12130) by @TrevorBrown-dev in https://github.com/storytold/photocraft/pull/12299
- fix(ui): vertical text gets Top / Center / Bottom alignment buttons (#12059) by @rmsff in https://github.com/storytold/photocraft/pull/12341
- Background Eraser: Find Edges erases soft edges graded instead of cutting them hard (#11904) by @davidmann4 in https://github.com/storytold/photocraft/pull/12152
- Background Eraser: alpha falls off over the whole Tolerance (#11901) by @davidmann4 in https://github.com/storytold/photocraft/pull/12150
- PDF: opt-in editable import (paths and text) by @Triwarr in https://github.com/storytold/photocraft/pull/12275
- test(ui): align Hand menu anchor checks with fixed zoom rows by @FredApps in https://github.com/storytold/photocraft/pull/12375
- Brush Settings: combine the Spacing checkbox and percentage header by @augrclk in https://github.com/storytold/photocraft/pull/5224
- Pen: carry on a shape's or vector mask's open path, and show the cont… by @kavishkashehan726-sudo in https://github.com/storytold/photocraft/pull/9396
- paint: 12 more painting tools wrap across the canvas edges in Pattern Preview (#8883) by @VoiceLessQ in https://github.com/storytold/photocraft/pull/9348
- fix(engine): Magic Wand Subtract and Intersect grow from the seed through the selection (#11779) by @DuBearte in https://github.com/storytold/photocraft/pull/11848
- Background Eraser: partly erased pixels lose the sampled colour's tint (#11902) by @davidmann4 in https://github.com/storytold/photocraft/pull/12154
- Count tool: adding a marker turns View > Show > Count back on (#11770) by @mzuniga37 in https://github.com/storytold/photocraft/pull/11845
- Magic Wand: Anti-alias keeps the region whole and softens only near-matching neighbours (#11776) by @hectorviov in https://github.com/storytold/photocraft/pull/12146
- Patch: in Destination mode the selection moves with the patch (#12119) by @TrevorBrown-dev in https://github.com/storytold/photocraft/pull/12298
- Menus: Layer Via Copy and Layer Via Cut with a capital V, as in the reference (#12357) by @TrevorBrown-dev in https://github.com/storytold/photocraft/pull/12382
- Brush: Clear on the Background paints as Normal and the Mode reads Normal by @DuBearte in https://github.com/storytold/photocraft/pull/12049
- Magic Wand seed-outside tests expect the measured Anti-alias fringe, main green again (#12397) by @davidmann4 in https://github.com/storytold/photocraft/pull/12399
- Filter dialogs: a click on the image centres the preview window (#9648) by @ljkx in https://github.com/storytold/photocraft/pull/9981
- Hand tool: Scroll All Windows, or Shift while dragging, scrolls every shown document by @dotCooCoo in https://github.com/storytold/photocraft/pull/9144
- Free Transform: redraw only what the box changes; prepare large layers as a job by @tjbbjt in https://github.com/storytold/photocraft/pull/12312
- fix(ui): a Type tool click on a Lock All text layer shows the locked alert (#12040) by @rmsff in https://github.com/storytold/photocraft/pull/12329
- Use standard macOS Settings, Hide and Minimize shortcuts by @andeecollard in https://github.com/storytold/photocraft/pull/7809
- fix(ui): Reset Tool gives the Healing Brush a 19 px hard tip at 25 % spacing (#12099) by @rmsff in https://github.com/storytold/photocraft/pull/12383
- Eraser: Opacity, Flow and Smoothing out of range show the Closest value inserted alert (#11938) by @hectorviov in https://github.com/storytold/photocraft/pull/12277
- Content-Aware Move: warn "No pixels are selected." for a drag with no area (#12192) by @RickiNano in https://github.com/storytold/photocraft/pull/12354
- Background Eraser: erase transparency-locked layers (#11905) by @davidmann4 in https://github.com/storytold/photocraft/pull/12191
- Background Eraser: Protect Foreground Color fades with the distance (#11903) by @davidmann4 in https://github.com/storytold/photocraft/pull/12153
- Layer › Copy CSS by @hectorviov in https://github.com/storytold/photocraft/pull/10569
- Turn Content-Aware Move's Transform On Drop on by default by @hsmith-dev in https://github.com/storytold/photocraft/pull/12389
- Background Eraser: Angle and Pressure for Size on the options bar (#11908) by @davidmann4 in https://github.com/storytold/photocraft/pull/12186
- Show Content-Aware Move's slider popups, tooltips, and transform actions by @hsmith-dev in https://github.com/storytold/photocraft/pull/12395
- feat(ui): drag the zones of a Hue/Saturation colour range (#9252) by @hectorviov in https://github.com/storytold/photocraft/pull/9272
- fix(engine): Record Measurements labels a Count tool row "Count N" (#11775) by @DuBearte in https://github.com/storytold/photocraft/pull/11853
- Updates: the updater reports installing, ready, installed and failed, and installs at exit by @dotCooCoo in https://github.com/storytold/photocraft/pull/12384
- Updates: take craft-update from craft-libs main at 1b34eba41 by @dotCooCoo in https://github.com/storytold/photocraft/pull/12435
- Naming: use RAW Develop for PhotoCraft's raw-processing feature by @FredApps in https://github.com/storytold/photocraft/pull/12403
- fix: dismiss context menu without triggering tool action on outside click by @Kaedo17 in https://github.com/storytold/photocraft/pull/9841
- Perspective Crop: dim the image outside the quad with a shield by @hectorviov in https://github.com/storytold/photocraft/pull/12227
- fix(text): size faux bold by Photoshop's size/72 ring instead of a flat 3.6% (#9008) by @ebosido444-ai in https://github.com/storytold/photocraft/pull/10344
- fix(ui-egui): the rasterize prompt no longer replays the click that opened it (#8806) by @Higgs32584 in https://github.com/storytold/photocraft/pull/9864
New Contributors
- @vistaero made their first contribution in #5330
- @tareq-halaby made their first contribution in #11051
- @Psychotoxical made their first contribution in #10752
- @x-labb made their first contribution in #9573
- @indy2kro made their first contribution in #10453
- @jayzed80 made their first contribution in #10850
- @Raghav2012Code made their first contribution in #11019
- @Luis-0508 made their first contribution in #9855
- @kk376 made their first contribution in #10203
- @TrevorBrown-dev made their first contribution in #10837
- @qvest-ssels made their first contribution in #10396
- @chamber074 made their first contribution in #11243
- @nine-codes made their first contribution in #10290
- @davidvhk made their first contribution in #4446
- @coqui-software made their first contribution in #7231
- @ZIDAN44 made their first contribution in #10351
- @Lcoding15 made their first contribution in #10505
- @HirthikBalaji made their first contribution in #7170
- @Triwarr made their first contribution in #11331
- @fokas-hoa made their first contribution in #7985
- @DingusMcRinkyDinky made their first contribution in #11005
- @Nurana100 made their first contribution in #11092
- @arksky1 made their first contribution in #8185
- @Thanawatttt made their first contribution in #10241
- @newsbaba24x7 made their first contribution in #10359
- @tronicum made their first contribution in #10361
- @Taxperia made their first contribution in #10555
- @Saloouu made their first contribution in #11322
- @funkvay-star made their first contribution in #3693
- @cloutier made their first contribution in #8633
- @SofiaAFigueredo made their first contribution in #9661
- @rus152 made their first contribution in #9821
- @luben93 made their first contribution in #10529
- @SvenCarstensen made their first contribution in #9876
- @devius made their first contribution in #5845
- @ElNeMeR70 made their first contribution in https://github.com/storytold/photocraft/pull/12164
- @aethelisdev made their first contribution in https://github.com/storytold/photocraft/pull/10222
- @Firstbober made their first contribution in https://github.com/storytold/photocraft/pull/9887
- @Bobderto made their first contribution in https://github.com/storytold/photocraft/pull/12102
- @rmsff made their first contribution in https://github.com/storytold/photocraft/pull/12328
- @mzuniga37 made their first contribution in https://github.com/storytold/photocraft/pull/11845
- @tjbbjt made their first contribution in https://github.com/storytold/photocraft/pull/12312
- @hsmith-dev made their first contribution in https://github.com/storytold/photocraft/pull/12389
- @Kaedo17 made their first contribution in https://github.com/storytold/photocraft/pull/9841
Full Changelog: v0.20.1...v0.22.0