Commit Graph
31 Commits
Author SHA1 Message Date
FredApps 8abafb2980 Merge approved PhotoCraft PR #7743: packaging: the portable zip holds the files, not a folder with the files in it 2026-10-29 03:29:33 +01:00
FredApps cd3a054cf0 Merge approved PhotoCraft PR #6383: Windows releases ship a symbols zip: the release build's PDBs for profilers (#688) 2026-10-29 03:29:22 +01:00
Jeremy 40310f10ea test(installer): cover the compiled folder searches, resolver chains and wizard folder replay
The policy check now reads the compiled AppSearch and RegLocator rows for the
remembered-folder properties (registry root, key, value name and type for both
scopes) and runs the DIR, FOLDER, PATH and legacy exe actions in sequence order
against seeded values, so their precedence and the preset-folder guard cannot
regress. It also replays the wizard folder actions in sequence order (a
remembered folder beats the new-install default, a typed folder beats both) and
requires the machine restore action between the scope page and costing.
2026-10-27 21:13:29 +00:00
Jeremy f82028c00d fix(installer): check the exact architecture-specific machine folder
The pre-signing check matched any folder named Program Files, so it rejected
a valid MSI when Windows resolves Program Files elsewhere, accepted the 64-bit
root for an x86 package and accepted a different app name. Build the expected
folder from the package architecture's resolved root and the policy name.
2026-10-27 19:13:14 +00:00
Jeremy 8f3265c747 fix(installer): resolve the wizard scope and folder correctly
Real msiexec runs (per-user and all-users, silent and wizard) found two defects
that the metadata fixtures cannot see:

- "Only for me" published ALLUSERS=2, so FindRelatedProducts treated the run as
  per-machine and skipped the existing per-user copy. An interactive upgrade
  left two registered products and uninstall left files behind. The page now
  leaves ALLUSERS unset for a per-user choice.
- Windows Installer resolves Program Files once, for the context it started in,
  so choosing "Everyone" in the wizard installed into the user profile with a
  machine-wide registration. The wizard now sets the new-install folder itself
  after the choice (Program Files, Program Files (x86) for 32-bit, or the
  per-user Programs folder). Silent installs are unchanged.

check-install-policy.ps1 now fails if either regresses.
2026-10-27 15:32:31 +00:00
Jeremy bf4e8214fc fix(installer): correct the wizard and shortcut description in the release docs; harden install-policy checks 2026-10-27 12:01:33 +00:00
Jeremy f35b356f87 fix(installer): address scope and ARM64 review feedback 2026-10-27 12:01:33 +00:00
Jeremy c19d201748 feat(installer): default to a per-user ArtCraft folder 2026-10-27 12:01:33 +00:00
Jeremy 9956352be0 packaging(windows): dual-scope MSI, per-user by default, under the ArtCraft suite folder
Microsoft "Single Package Authoring": Package/Scope="perUserOrMachine"
writes ALLUSERS=2 and MSIINSTALLPERUSER=1, so the package installs
per-user by default (no UAC prompt) into %LOCALAPPDATA%\Programs\ArtCraftPhotoCraft (Windows Installer redirects the ProgramFiles folder in a
per-user install), and per-machine into Program Files\ArtCraft\PhotoCraft
through the setup wizard's "Install for all users" box or msiexec
ALLUSERS=1. Registry follows the context automatically: HKMU writes HKCU
per-user and HKLM per-machine, HKCR classes land in HKCU\Software\Classes
per-user, and components are keyed on registry values (ICE38).

Upgrades update the copy registered in the same context: the remembered
InstallDir is read from HKLM and HKCU separately, and installing in the
other context while a copy already exists is stopped with a message naming
the fix rather than creating a silent duplicate. The existing UpgradeCode,
ProductCode behaviour and per-machine upgrades are unchanged.

The Start Menu shortcut becomes non-advertised in its own component (an
advertised shortcut must target its component keypath, which is now a
registry value), as the ArtCraft Launcher's MSI already does.

Built and checked with WiX 5.0.2: full ICE validation and ICE50 pass, and
the built package's Property table, launch conditions, directory chain and
registry roots were read back from the MSI.
2026-10-27 12:01:33 +00:00
5c9192bbe2 Migrate PhotoCraft to egui 0.37 (#9363)
* egui037: name each control for what it sets, and order the eager fonts for the UI

CodeRabbit review follow-ups on the migration: the Artboard X/Y fields, the CAF
dropdowns, the channel Solidity field, the GPU backend/adapter dropdowns, the
corner radius fields and the canvas extension colour all had an accessible name
that named another control (or was shared by four). The eager craft-fonts
registration now puts the UI Japanese face first, as the lazy loader does, so
Japanese UI is not drawn in the manifest's Mincho face and shared Han characters
do not take Japanese forms.

Generated with Codebuff
Co-Authored-By: Codebuff <noreply@codebuff.com>

* egui037: rustfmt the eager craft-font order

---------

Co-authored-by: Dylan M. Taylor <dylan@dylanmtaylor.com>
Co-authored-by: Codebuff <noreply@codebuff.com>
2026-10-25 15:04:35 -04:00
Erica Franco 938542c78b Security: pin and verify the Windows signing client (#2936) (#3938)
sign.ps1 downloaded Microsoft.Trusted.Signing.Client from the unversioned
NuGet URL and loaded its dlib into signtool, next to the Azure signing
secrets, with no version or integrity check.

Download a pinned version (1.0.95, which the unversioned URL serves today)
and refuse it unless its SHA-256 matches, so upgrading the client is a
deliberate change in the repository. The release docs say where the pin
lives.
2026-10-25 12:32:10 -04:00
Hamza fd6fc92015 packaging: the portable zip holds the files, not a folder with the files in it
`Compress-Archive -Path $Portable` archives the staging *folder*, so the zip
contained

  photocraft-<version>-windows-<arch>-portable\photocraft.exe

rather than `photocraft.exe` at its root -- which is what this script's own
synopsis promises, what portable mode needs (portable.txt sits beside the exe,
and extracting to a folder of the user's choosing now nests one more), and what
the launcher looks for when it installs a portable build
(storytold/craft-launcher#627). `<folder>\*` archives the contents, which is
what VectorCraft's windows7.ps1 already does for its portable zip.

Nothing read the layout back, which is how it drifted, so the three files are
checked in the archive after it is written.

Fixes #7699.
2026-10-19 16:56:22 +05:00
Michael Higgins f45d15d211 Merge branch 'main' into fix/688-windows-symbols 2026-10-18 10:15:51 -04:00
Korg1ch 4c881326ea fix(windows): keep crash-recovery autosaves out of the roaming profile (#5648) (#6412)
* fix(windows): keep crash-recovery autosaves out of the roaming profile (#5648)

* test(windows): cover the local recovery folder and moving old autosaves (#5648)
2026-10-16 20:19:06 -06:00
Higgs32584andClaude Opus 5.5 7cf4f27cf6 Windows releases ship a symbols zip: the release build's PDBs for profilers (#688)
package.ps1 now also writes photocraft-<v>-windows-<arch>-symbols.zip with photocraft.pdb and
photocraft_cli.pdb from the same optimized build as the signed exes, plus symbols.txt on loading
them in WPA, Superluminal or Visual Studio. It's a separate optional asset, so the MSI and
portable zip keep their size; the shared release workflow uploads everything in dist/release.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 19:42:38 -04:00
0a32b3593d Add Krita (.kra) import (#4388)
Open .kra and .krz with paint layers (8/16-bit RGBA and gray, any offset), nested
and pass-through groups, names, visibility, opacity, locks, blend modes and
transparency masks, plus the image's ICC profile and resolution. Vector, filter,
fill, file and clone layers and the other mask kinds are left out with a warning;
float, CMYK and Lab documents open as Krita's merged image (preview). Import only:
Save suggests .ora. Checked against 35 Krita 5.2.9-authored files.

Co-authored-by: Scott Campbell <251750033+scottcampbelldata@users.noreply.github.com>
Co-authored-by: Brandon Thomas <echelon@gmail.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 22:41:38 -04:00
Brandon ThomasandClaude Opus 5.5 0d6e658e73 PSD: rasterized fill and smart layers stay rasterized after save and reopen (#4034)
* fix(psd): rasterized fill and smart layers stay rasterized after save and reopen

Layer > Rasterize > Fill Content / Smart Object swapped the layer's content
to pixels but kept the fill (SoCo/GdFl/PtFl) or placed-layer (SoLd/PlLd/SoLE)
blocks read from the PSD. Written back, they made the reopened file a fill
layer or smart object again and discarded the pixels. Photoshop writes none
of them for a pixel layer.

- Rasterize drops those blocks from the layer.
- The PSD exporter never writes fill, placed, type (TySh), shape-content
  (vscg/vstk), adjustment or CgEd blocks for a raster layer, whichever
  command made it one; a vector mask (vmsk/vsms with its vogk) stays.

Tests: synthetic fill + smart object rasterize/save/reopen, the exporter
backstop with stale blocks, and Photoshop-authored corpus files.

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

* fix(psd): keep a pixel layer's vstk when it has no vector mask, as Photoshop does

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

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 06:11:33 -04:00
Dan HiornsandClaude Opus 5.5 20cb95bc27 Windows installer: refuse Windows 7 and 8 with a clear message (#2310) (#3261)
The Rust standard library has needed Windows 10 since 1.78, so on
Windows 7 and 8 PhotoCraft fails at launch with "The procedure entry
point ProcessPrng could not be located in the dynamic link library
bcryptprimitives.dll" (#2310). The MSI installed anyway.

It now has a launch condition: a registry search sets WINDOWS10ORLATER
from HKLM\...\Windows NT\CurrentVersion\CurrentMajorVersionNumber,
which exists only from Windows 10 on (in the 32- and 64-bit views), and
without it the installer stops with "PhotoCraft needs Windows 10 or
later." Repair and uninstall still run (Installed). MSI's VersionNT
isn't used: it has reported both 603 and 1000 on Windows 10.

The README's Windows downloads now say Windows 10 or later is required;
the portable zip can't check, as Windows rejects the exe before any of
its code runs.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 02:26:36 -04:00
7722172585 Add OpenRaster (.ora) import and export (#2257)
Open and save .ora with pixel layers (any offset), nested groups, pass-through
groups, names, visibility, opacity, edit/alpha locks and blend modes (svg:* plus
Krita's krita:* names), at 8 and 16 bit. Save applies pixel masks, renders
text/shape/fill/smart layers to pixels and reports what OpenRaster can't hold.
Wired into File > Open/Save, the CLI, automation/MCP, the web picker and the
desktop file associations. Checked against 34 Krita 5.2.9-authored files
(opt-in krita_corpus test) and Krita re-opening our exports.

Co-authored-by: Scott Campbell <251750033+scottcampbelldata@users.noreply.github.com>
Co-authored-by: Brandon Thomas <echelon@gmail.com>
2026-10-10 08:40:35 -04:00
SilentYetiandClaude Opus 5.5 db0fb07862 Add native layered Paint.NET (.pdn) import (#1998)
Squashed onto main, with the maintainer's asks applied:
- Photoshop's blend menus (layers, brush, pencil, gradient, layer style) stay as they are;
  the Layers panel and Blending Options list a Paint.NET mode only for a layer that uses one.
- The six Paint.NET mode labels are translated in every catalog, and the blend-mode i18n test
  iterates layer_modes().
- pdn::pixels rejects truncated uncompressed (version 1) data before allocating its buffer.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 21:05:00 -04:00
Roaldo Sulejmani 424a5d492f fix: remove Photoshop from user-facing strings (#1985) (#2008)
The app still showed the Adobe Photoshop name in several user-visible
strings. Per the product rule (user-facing text says PhotoCraft only),
none of these mention Photoshop now.

UI labels, tooltips and status messages:
- New Document preset "Default Photoshop Size" -> "Default PhotoCraft Size"
- "All shortcuts reset to Photoshop defaults." -> "All shortcuts reset to
  PhotoCraft defaults."
- "Import Photoshop brushes (.abr)" -> "Import brushes (.abr)"
- smart-filter fallback name "Photoshop filter" -> "Smart filter"
- File > Save As .psd/.psb filter "Photoshop" -> "PSD Document"

Errors and warnings:
- "this Photoshop filter isn't implemented in PhotoCraft" -> "this smart
  filter isn't implemented in PhotoCraft"
- smart_map: "has no PSD equivalent", "not a recognized filter", "its
  filter data is missing/unreadable", "this filter has no PSD equivalent"
- tiff_layers: "the PSD layer data...", "the PSD image resources..."
- multichannel: "32-bit Multichannel isn't supported"
- abr: "not a readable brush file (.abr)"
- gradient import: "not a readable gradient file (.grd)"

Translations: updated the changed tl! sources in all 16 catalogs and
dropped the stale "Load Photoshop brushes (.abr)" entries.

Installer / OS metadata: de-branded the nfpm description, the PSB MIME
comment, the AppStream summary/description, the macOS UTType
descriptions, the Windows ProgId Description and the desktop launcher's
Keywords. The Photocraft.PhotoshopDocument ProgId and the
image/vnd.adobe.photoshop MIME/UTType stay: machine identifiers,
changing them hurts file fidelity and Open-with registration.

Command params docs (agent-facing): dropped Photoshop from the
type_cmds kernPair text, the layer_menu_cmds Advanced Blending defaults
and the mask_view_cmds backslash-key text. The "photoshopManages" wire
value stays. Comments, format identifiers and the "photoshop" theme
alias are out of scope and unchanged.

The macOS native-menu shortcut resolution messages no longer say "as in
Photoshop" (Hide/Minimize).
2026-10-09 13:59:07 -07:00
BFlatandClaude e39cacd895 Packaging: Windows MSI setup wizard (folder choice, progress, version, launch on finish) (#1864)
Double-clicking the MSI now opens WixUI_InstallDir without the licence page:
Welcome, install folder (remembered for upgrades in
HKLM\Software\PhotoCraft\InstallDir), Ready, progress, and a Finish page with
a ticked "Launch PhotoCraft" box (WixShellExec, unelevated). The pages name
the full version, pre-release tag included (photocraft.en-us.wxl).
package.ps1 draws the banner and side bitmaps from the app icon, so no WiX
stock art ships. msiexec /qn still installs silently. The release and ARM64
workflows install the WiX UI and Util extensions; packaging-lint checks the
.wxl. Ported from VectorCraft (storytold/vectorcraft@aa548d2).


Claude-Session: https://claude.ai/code/session_01AP7ThRN3kpNmjsuJUerJui

Co-authored-by: Claude <noreply@anthropic.com>
2026-10-09 21:33:38 +07:00
47f9306fd0 Open HEIC/HEIF photos (#355) (#372)
* Open HEIC/HEIF photos (#355)

iPhones save HEIC by default and Photoshop opens it; PhotoCraft had no
HEIF code, so .heic was missing from File > Open and failed to decode.

Add Format::Heif to photocraft-codecs, decoded by heic-rs (pure Rust,
forbid(unsafe), MIT OR Apache-2.0, wasm-ready): single pictures and
grid-tiled photos, 8-bit to U8 and 10/12-bit to U16, auxiliary alpha,
ICC, EXIF and XMP. The container's irot/imir/clap are applied and EXIF
Orientation is rewritten to 1, so photos are never turned twice. Limits
are checked against the declared size before decoding. Read-only (no
pure-Rust HEVC encoder), listed in ASYMMETRIC_EXCEPTIONS.

File > Open (desktop, web) and the batch list accept heic/heif/hif.
Tests compare against Apple's own decode and a 16-bit source, cover
orientation, metadata, limits and every truncation; fixtures from
heic-rs and pillow-heif are attributed in ATTRIBUTION.md.

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

* HEIF: pin heic-rs exactly and add a decode_heif fuzz target

Review follow-up: heic-rs is young and parses untrusted files, so pin it
(=0.1.1) and fuzz the HEIF path. The target covers both orientation
paths and is meant to run with -timeout so a hang is reported, not
only a panic. It is added to the CI fuzz matrix.

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

* HEIF: a heic-rs panic is a malformed-file error, not a crash

Fuzzing decode_heif found two out-of-range slices in heic-rs 0.1.1 on
malformed files:
- in its box parser (boxes.rs:130), reachable from a 72-byte file, even
  through the metadata-only probe;
- during HEVC reconstruction (hevc/decode/recon.rs:70).

The background job path catches panics, but the synchronous ones (jobs
off, the CLI) did not. The HEIF codec now runs the decoder under
catch_unwind and reports a panic as CodecError::Malformed, as
gpu/health.rs already does around wgpu.

The fuzz target also calls heic-rs directly, so its panics still reach
the fuzzer. The 72-byte input is a regression test, which fails
without the guard.

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

* HEIF: move the decoder into an optional photocraft-heif crate

The heic-rs decoding from #372 now lives in `crates/heif` (photocraft-heif, standalone, depends
only on heic-rs =0.1.1): probe, decode with a pixel limit, container transforms, alpha, 8/10-bit,
ICC/EXIF/XMP and the catch_unwind guard, behind a small API of its own (Info, Options, Decoded,
Error). photocraft-codecs uses it behind a new non-default `heif` feature; the apps and
photocraft-io forward it. HEIF detection, extensions and mime stay compiled in, so without the
feature a HEIC file is still recognised and opening it is a clear "HEIC/HEIF support isn't
included in this build of PhotoCraft" error. `cargo xtask layers` allows exactly codecs -> heif
between standalone crates.

The fixtures are no longer committed: `cargo xtask corpus --heif` fetches them from heic-rs
(tests/fixtures, v0.1.1) and pillow-heif (tests/images) at pinned commits, verified against
xtask/heif-corpus.sha256 (same bytes as the PR's copies). The fixture tests run with
`--features corpus,heif` (`cargo xtask test-corpus` enables both).

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

* Build CI and official binaries with HEIC support (--features heif)

CI test and clippy, the FreeBSD job, and the macOS, Linux (and Flatpak), FreeBSD, Windows and
web packaging all build with the `heif` feature; CI also tests codecs/io without it on Linux so
the "not in this build" path stays covered. `cargo xtask wasm` also checks photocraft-codecs with
`--features heif`.

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

* Docs: HEIC open is an optional build feature, on in official builds

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

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Brandon Thomas <echelon@gmail.com>
2026-10-07 10:20:40 -04:00
Brandon Thomas c161eaec73 Fonts: use craft-fonts as an optional build input; move the Japanese fonts out (#353) (#353) 2026-10-06 18:21:46 -04:00
Brandon Thomas e8677ff851 Windows on ARM64: release builds, PE header check, install test on ARM64 hardware (#333) (#333) 2026-10-06 10:09:55 -04:00
Brandon Thomas 315be69dd5 Portable mode: keep settings beside the exe in the Windows portable zip (#228) (#267) (#267) 2026-10-05 18:15:29 -04:00
才倾梦华V 2172d085c6 Fix Windows MSI advertised shortcut icons (#238) (#238) 2026-10-05 18:13:51 -04:00
Brandon ThomasandClaude Opus 5.5 5969c8d58a Windows packaging: don't publish .wixpdb debug symbols
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 14:34:39 -04:00
Brandon ThomasandClaude Opus 5.5 08c6c08e2e Discord, website and GitHub links; fix AppStream validation on 22.04
- Help menu: Join the ArtCraft Discord, PhotoCraft Website
  (getartcraft.com/apps/photocraft), ArtCraft Website, PhotoCraft on
  GitHub, Report an Issue; separator before About. All also in the ⌘K
  palette and drivable via the control channel (returns {"url"}).
- "Join us on Discord" button + website/GitHub/ArtCraft links on the
  start screen and in About; a Discord button in the title bar.
- Linux metainfo: drop url type vcs-browser (unknown to appstream 0.15 on
  ubuntu-22.04, which failed both Linux release jobs); homepage is the app
  page, contact is Discord. nfpm homepage and Windows ARP links updated.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 14:04:04 -04:00
Brandon ThomasandClaude Opus 5.5 1f1ddb2a47 Release pipeline id renames and PhotoCraft branding
- Lowercase reverse-DNS id ai.storyteller.photocraft across icons, Linux
  desktop/metainfo/mime/flatpak, Windows WiX, macOS Info.plist and workflows.
- PhotoCraft display name in the title bar, start screen, web loader,
  Windows exe metadata, README and docs.
- .gitignore target/, roadmap refresh.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 13:25:17 -04:00
Brandon Thomas d98bee4c94 progress, release workflows 2026-10-01 10:49:51 -04:00