M6: SVG import fidelity (#90)

SVG import comes in editable and looking right: groups named from their
ids with transforms baked into the layers (rotated, scaled and skewed
groups, viewBox scaling and <use> offsets used to be lost); rectangles,
ellipses and lines recognised and kept as those shapes; gradients with
exact handles, reflect/repeat and focal points; patterns as image fills;
clip paths and masks as vector, luminance and alpha masks; shadow and
blur filter chains as drop shadows, inner shadows and layer blurs; blend
modes; text as text layers (it used to vanish); images and nested SVG
images. What can't be represented is reported as import warnings
(file.import / file.open warnings, figcraft-cli info notes). Linked
files are never read, and documents nested too deep for the parser are
refused instead of crashing.

Pasted SVG is recognised after XML declarations, comments and doctypes
and lands centred in the view (file.import center). SVG export writes
vector masks as clip paths and alpha/luminance masks as the mask layer
drawn, so masks survive a round trip.

Tests: a corpus of 21 synthetic SVG files with hand-worked expected
pixels (158 probes), structure checks and export round trips; unit tests
for shape recognition, paints, filters, structure, mask export; hostile
input and byte-mangled corpus fuzzing; engine file command tests.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
BFlat
2026-10-10 20:36:55 +07:00
committed by GitHub
co-authored by Claude Opus 5.5
parent 4904303fc2
commit e27f2751d4
45 changed files with 3391 additions and 267 deletions
+2 -1
View File
@@ -47,7 +47,8 @@ figcraft-cli export app.figcraft -o screens.pdf --page "Screens"
### `convert <in> <out>`
By extension. Inputs: `.figcraft`, `.json` (FigCraft or REST API file JSON), `.svg` (becomes vectors), `.png/.jpg/.webp/.gif/.bmp`
By extension. Inputs: `.figcraft`, `.json` (FigCraft or REST API file JSON), `.svg` (an editable frame: groups,
shapes, text, gradients, masks and effects; `info` lists what it left out as `note:` lines), `.png/.jpg/.webp/.gif/.bmp`
(an image layer). Outputs: `.figcraft`, `.json` (FigCraft JSON, pretty-printed), `.svg`,
`.png/.jpg/.webp` (the current page rendered at 1x with its background), `.pdf` (the current page's
frames, one page each).