- Smart-object contents (Replace Contents, Convert to Layers, Stack Mode,
internal Edit Contents) refused any SVG whose canvas area times its
node count passed 24 MP, e.g. a 1920x1080 layout with 12 shapes.
decode_source now uses the bounded image parse with File > Open's
layered import (import_svg_bounded_images). Convert to Layers' shape
cache cap is 1 GiB in the document's format, the import's own budget,
not 24 MP (four full-canvas shapes in a 4K document failed).
- The bounded resolver failed the whole drawing on an embedded image it
can't read (an unknown MIME type, a corrupt PNG); it now leaves it out
as usvg does, so such SVGs place and render again. Byte and decode
overruns stay errors.
- resvg gives each embedded SVG image a scratch pixmap the size of its
target and frees it after, so the scratch budget counts the deepest
chain of nested SVG images, not every sibling: 12 SVG icons on a 2 MP
canvas, or one at a 12 MP render, no longer fail.
- Main's shared nesting budget (#9397) now covers the bounded path too:
511 + 511 levels across a drawing and its embedded SVG overflowed a
1 MB stack.
- An AI working copy is regenerated through VectorCraft only when
VectorCraft is the editor; Illustrator or another program gets the
original bytes. VectorCraft is recognised by bundle id, a known
install, or its name (vectorcraft[.exe], vectorcraft-<version> AppImage,
ai.storyteller.vectorcraft).
- updateSvg refuses an AI/PDF/EPS source (updateVectorSource saves it
back in its own format); the doc no longer calls updateSvg "existing".
- Edit Contents on contents already open in the internal editor switches
to that document, as main does, instead of an error.
- Stack Mode on an SVG refuses up front when one float frame per layer
would pass 1 GiB (the layered import no longer refuses for it).
- A stored display preview still fails on an embedded image it can't
read (strict budget, its own import_svg_preview_with_work; external-
editor saves and conversions leave the image out as placement does); skipped embedded SVGs still use up the XML byte
budget; an image under an unknown MIME type or with no pixels is left
out uncharged.
- Merge: the PSD import reads a preview's native source from the
document's global blocks; main's owned open moves them out of the
file, so every stored preview was dropped.
- Main's strict Clippy rules on the PR's app code (explicit import, a
Unix-only test helper, one long opt-in test).
Co-authored-by: Mocky Digital <282319807+mockydevs@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
When the working file changed between settling and reading, the watcher
sent "The SVG is still being saved" to the UI as an error. Treat that
result as a retry: clear the pending stamp so the new save settles again,
and send nothing. Other read errors are still reported once.
Tests cover the retry, single reporting of other errors, queue
backpressure and receiver drop, and a stress run of atomic replacements
that must deliver only complete saves ending with the final one.
Resolve conflicts with the engine's cmd/ module move and the per-crate
integration test binaries. Run a selected VectorCraft.app bundle directly
(identified by bundle id) and reject nested gzip in bounded SVG parsing.
- External vector editing on macOS: discover VectorCraft.app in /Applications and
~/Applications, offer Illustrator when an Adobe Illustrator*.app is found, and accept a
chosen .app under Other application. CFBundleExecutable is read from a bounded Info.plist
(XML or binary, streamed with a nesting cap) and must resolve inside Contents/MacOS;
chosen bundles open with /usr/bin/open -a. vectorcraft-cli is looked for in the same
bundle, then in known installs. Logic is compiled and unit-tested on every Unix.
- Windows "not found" errors name the dialog's "Other application" option.
- Native preview hash verification is remembered per source allocation in a 32-entry
Weak-keyed LRU (no strong references, no reusable stale addresses, lock not held
while hashing), so refreshes and warp frames hash a shared source once.
- source_box uses the new io::svg::bounded_canvas_bounds for SVG without Stack Mode, so
warp setup gets a frame for drawings whose editable layer caches exceed the budget.
Stack Mode and Edit Contents stay strict. Exact 24,000,000-pixel boundary tested.
- Document every non-test function this PR adds; describe macOS behaviour in
docs/embedded-vector-editing.md.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Offer explicit external editing for embedded SVG, PDF-compatible AI, PDF and
EPS smart objects, with bounded conversion/rendering and transactional save-back
that retains placement, shared instances, masks, filters and undo history.
On Linux, export the checked writable working file through the desktop portal
so the regular VectorCraft instance handles it. Keep Flatpak working copies in
the app-private cache and release completed editor sessions after cancellation.
Do not execute another Flatpak's interactive payload inside PhotoCraft.
Adapt the credited SVG editor foundation from Skyfuller1303's 897f2007 without
its clipboard or unrelated Shape Tools changes. Add current-main compatibility,
embedded native-vector support, regression tests and authored screenshots.
Co-authored-by: Skyfuller1303 <skyfullerdesign@gmail.com>