Commit Graph
48 Commits
Author SHA1 Message Date
skylar taylor-barrick 2ecba1fb9c PDF.R1: reconcile shared reader with current writer 2026-10-14 03:59:03 -06:00
skylar taylor-barrick 52960faf63 PDF.W1: reconcile shared writer with current main 2026-10-14 01:23:19 -06:00
skylar taylor-barrick e01a65d8a9 PDF.R1: integrate shared reader with bounded nesting checks 2026-10-13 21:58:01 -06:00
bflatastic f1fd8e85e8 PDF: krilla without its text shaping, so rustybuzz and ttf-parser don't ship (#1730)
krilla's default `simple-text` feature is the only thing that brings in rustybuzz and
ttf-parser, which RustSec lists as unmaintained. The PDF writer places glyphs itself, so the
workspace takes krilla with `raster-images` only; the one test that writes files with
`draw_text` turns `simple-text` on as a dev-dependency feature.
2026-10-14 10:13:45 +07:00
skylar taylor-barrick a699a26221 refactor(pdf): use shared writer for export and print (PDF.W1) 2026-10-13 20:41:14 -06:00
Ayberk A. 0d28ee0872 Fix #1710: ruzstd 0.9.1 (RUSTSEC-2026-0344)
0.9.1 enforces the decompressed size of each block, which 0.9.0 didn't
(memory exhaustion on crafted .ai / Affinity zstd data). The manifests now ask
for at least 0.9.1.
2026-10-13 21:14:00 +03:00
dotCooCoo 3374d0778d Scripts: Check Script… reports what a .jsx script needs and does, without running it
VectorCraft does not run scripts written for the reference app, and
File › Scripts held only the disabled Other Script…. File › Scripts ›
Check Script… picks a .jsx, .jsxinc or .jsxbin file, reads it without
running any of it, and shows a report: what the script needs (the
script language's own objects, the document model, files, menu
commands, dialogs, or features only the reference app has), what it
would do outside the document, the menu-command strings it passes, the
document-model member chains and type names it uses, its directives,
the files it includes, and the problems that would stop it loading.
Copy Report copies the report as JSON. File › Open and drag-and-drop
show the report for those files too.

- vectorcraft-scriptcheck, a new Standalone crate with no
  dependencies, holds the checker: a lexer for ECMAScript 3 with E4X
  literals and the #name and //@name directive lines, and an analysis
  of the tokens that follows variables, function scopes and the files
  a script includes. It never recurses: open brackets, the levels of
  an XML literal and the function bodies being read are kept on stacks
  capped at 4,096. It reads at most 8 MiB of a file and 32 MiB with the
  included files, follows 64 included files 16 deep, looks up at most
  1,024 paths for them, keeps 1,000 entries in a list, tracks 1,000
  variables holding member chains and 1,000 holding File objects, and
  cuts echoed text to 120 characters. A compiled script is reported as
  compiled and isn't read.
- script.check (engine, a query) takes path, data or dataBase64. With a
  path and includes: true, it reads the files the #include lines name
  from inside the script's folder, through the automation read root,
  and when the script or one of those files assigns a member chain or a
  File object to a variable, the check treats the variable as holding
  it in every file. It doesn't follow absolute names, names, folders or
  links that lead out of the folder, names or folders longer than 4,096
  bytes, or JSINCLUDE, and it reads only regular files.
- ui.checkScript shows the report (dialog scriptCheck). File › Open
  lists Scripts (.jsx, .jsxinc, .jsxbin) and sends a script's path to
  script.check, which reads at most 8 MiB of it.

The language rules come from ECMA-262 3rd edition and ECMA-357 2nd
edition. The directive, platform and document-model root names come
from the public JavaScript Tools Guide and scripting guide pages that
catalog.rs cites by URL, and executeMenuCommand, doScript, loadAction,
unloadAction and selectTool come from the public forum posts cited
there; only names are used. Every script in the tests is written from
scratch with invented names.

Docs: docs/mcp.md, docs/target-app-parity.md.
2026-10-13 13:36:41 +07:00
Marco Arnulfo 544b17ec33 Workspace: rustix is declared once in the workspace dependencies 2026-10-13 12:58:04 +07:00
Brandon ThomasandClaude Opus 5.5 71174477cc Release prep: 0.10.0
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-12 05:44:41 -04:00
skylar taylor-barrick e74c2f113c Print: adopt craft-print while retaining Windows 7 support 2026-10-12 14:20:48 +07:00
skylar taylor-barrick 0c57b1d5d2 UI.6: reconcile shared docking with native panel sets 2026-10-10 19:28:31 -06:00
Brandon ThomasandClaude Opus 5.5 10f1c56a86 Release prep: 0.9.0 and a Linux riscv64 release build (#1071)
- Version 0.8.0 -> 0.9.0 (cargo xtask version set; Cargo.lock refreshed).
- release.yml: new linux-riscv64 job, ported from GridCraft. Cross-compiles
  riscv64gc-unknown-linux-gnu on ubuntu-24.04 against riscv64 -dev packages
  from ports.ubuntu.com (the same set the linux job installs), packages a
  tar.gz, and runs vectorcraft-cli --version under qemu-riscv64. The draft
  release job now needs it, so its tarball is uploaded and in SHA256SUMS.
- packaging/linux/package.sh: CROSS_ARCH / CROSS_TARGET / CROSS_COMPILE /
  EMULATOR support, as in GridCraft.
- docs/releasing.md: list the riscv64 artifact.

Checked locally: cargo check -p vectorcraft -p vectorcraft-cli --target
riscv64gc-unknown-linux-gnu, cargo fmt --check, actionlint, shellcheck.

Co-authored-by: Claude Opus 5.5 <[email protected]>
2026-10-10 19:47:38 -04:00
lloydandClaude Opus 5.5 1622a70f85 #1028: Offset Path finishes where the sweep looped forever
The sweep under Offset Path (linesweeper 0.4) never finished on some
miter offsets: on the reported glyph and on a synthetic outline it kept
allocating until the app ran out of memory. linesweeper 0.5 fixes that
infinite loop ("Fixed an infinite loop", 0.5.0 changelog), and builds
without changes.

0.5 can hand back a curve piece that doesn't follow the input curve it
was cut from. In the Shape Builder rosette test, a contour runs out along
one petal and back by such a piece, which became a 59 x 4 pt hole in the
merged shape. Tidy::repair rebuilds a piece that strays from the one input
curve through both its ends as that curve's exact sub-curve (input curves
are indexed by their bounds' left edge, so it stays cheap). The there-and-
back then encloses nothing and is dropped as a sliver. Pieces on their
curve, and pieces whose ends two input curves pass through (a real lens),
are left alone.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-11 05:30:41 +07:00
skylar taylor-barrick ed14640756 UI.9: integrate shared docking and preserve panel workflows 2026-10-10 14:49:35 -06:00
alpha-rock c36b6976e3 M9: add live Revolve with artboard rotation and lighting controls 2026-10-10 23:44:46 +07:00
bflatasticandClaude Opus 5.5 4099ebf3c9 Fix #787: raster exports keep translucent edges over opaque art opaque
The renderer composited in 8-bit integers, so where a partly transparent
anti-aliased edge crossed opaque art (or a background colour) the result
came out at alpha 254 on some pixels, and PNG, TIFF and WebP files were
written with an alpha channel. Raster exports (and Save for Web) now
composite in floating point (vello_cpu's f32 pipeline, enabled as a
feature), offscreen groups, masks and patterns included; the canvas keeps
the faster 8-bit path.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-10 11:12:13 +07:00
Brandon ThomasandClaude Opus 5.5 537fbece16 Bump version to 0.8.0 (from 0.7.0) for release; refresh contributors
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-09 21:02:29 -04:00
Matthew FarrowandClaude Sonnet 5.5 ec43ac5a1e Read Illustrator EPS and .ai layers from their editing data
An Illustrator EPS is a flattened page plus, after %%EOF, an editing copy of
the document; a PDF-compatible .ai carries the same in its private data.
Importing only the page lost layer names, order, visibility, hidden layers
and hidden objects and hidden text.

- eps: read the editing copy (Zstandard %AI24_DataStream, older zlib
  %AI9_DataStream) into layers, sublayers, groups, compound paths, clip
  groups and hidden objects, run by the existing PostScript interpreter.
  Falls back to the page, with a warning, when a shown layer uses an
  operator that isn't read or the art differs from the page by over 5%.
- eps: read the text document (ate.rs) to place type on hidden layers and
  objects; the page's type is matched to the file's text objects by
  position (pieces of a line included) and kept with the nearest one when
  none claims it. Area type and type on a path are left out with a note.
- pdf/engine: .ai files go through the same reader.
- engine/cli: a file whose import left things out isn't overwritten unless
  asked (acknowledgeLoss, --replace-lossy).
- eps: font names re-encoded with a *<n> suffix resolve to their family.
- i18n: es/it/ru for the new import messages; ROADMAP updated.

Container and text-document formats were inferred from user-owned files; the
Adobe file format specification was not read.

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
2026-10-09 03:49:49 -04:00
callmeBalloch 2b4d8f4074 Merge remote-tracking branch 'upstream/main' into claude/kind-darwin-btjse2
# Conflicts:
#	README.md
#	ROADMAP.md
#	apps/vectorcraft/src/open_documents.rs
2026-10-08 18:45:39 +00:00
bflatasticandClaude Opus 5.5 c3279f1bcf Release: VectorCraft v0.7.0
For users, since 0.6.0:
- Linux: no more startup crash on desktops whose compositor runs on another
  GPU (#502, #551); the window renders on the desktop's GPU and retries
  the next one instead of crashing.
- Windows: rendering through DirectX 12 first, fixing the black flicker on
  Intel GPUs (#545).
- Italian interface (#514).
- macOS: the menus live in the system menu bar.
- Panels, panel groups and the Tools panel undock into floating panels (#495).
- Live Corners on any path's corners: stars, polygons, pen paths (#511).
- Drawing tools snap to Smart Guides as the Selection tool does (#506).
- Pen: Cmd/Ctrl edits the path being drawn, Alt reshapes segments, drags
  out of the first anchor always close (#494, #501); Convert buttons for
  whole paths (#504).
- Right-click a ruler to change the document's units; the Control bar's
  Transform link opens the Transform panel.
- Object > Image Trace > Make traces with the Default preset (#543).
- Edit menu Select All, Cut, Copy and Paste act on a focused field (#516).
- Japanese UI: new type starts top-to-top with em box centre alignment (#432).
- PDF/.ai import keeps type strokes, wrapped lines and layer order (#508);
  EPS import fixes (#498, #505).
- macOS 27: only file URLs are opened (#433); Linux: the Paste menu no
  longer freezes on an unresponsive clipboard owner (#510).

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-09 01:16:08 +07:00
callmeBalloch 3e782b22a9 Merge remote-tracking branch 'upstream/main' into claude/kind-darwin-btjse2
# Conflicts:
#	ROADMAP.md
2026-10-08 16:08:36 +00:00
callmeBalloch 3c7bdfe6a3 AF.1: import bounded Affinity previews with explicit fidelity warnings
Read only the indexed PNG thumbnail observed in version-12 Affinity containers. Bound and validate the PNG before decoding, warn about omitted native content, clear the source save target, and reject auxiliary imports that cannot display that warning. Add malformed-input, lifecycle, property and optional native-oracle tests plus a fuzz target. Editable native layers and Affinity export remain unsupported.
2026-10-08 17:19:18 +02:00
Brandon ThomasandClaude Opus 5.5 f12188ad15 Bump version to 0.6.0 (from 0.5.0) for release
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-08 10:01:57 -04:00
Brandon ThomasandClaude Opus 5.5 d9fc3b6505 Bump version to 0.5.0 (from 0.4.0) for release
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-08 08:13:01 -04:00
bflatasticandClaude Opus 5.5 ab62b5f8e8 Fix #320: CMYK images stay CMYK from PDF import to PDF export
A PDF's DeviceCMYK image opened as RGB (the interpreter's pixels as a PNG),
so every export wrote it as DeviceRGB or ICC RGB, silently. Images now keep
their CMYK samples, as CMYK colours already did:

- Model: CMYK images are blobs holding CMYK samples, a four-component JPEG
  (Adobe's inverted samples) or a Deflate CMYK TIFF. vectorcraft-doc's cmyk
  module reads their ink amounts (ImageBlob::is_cmyk, ::cmyk, capped at 64
  megapixels) and writes the TIFF (ImageBlob::cmyk_tiff).
- PDF import: DeviceCMYK, CalCMYK and four-component ICC images keep their
  samples. A JPEG with Decode [1 0 1 0 1 0 1 0] is kept byte for byte; any
  other is decoded (8 or 16 bits, its Decode array applied) and stored as a
  CMYK TIFF. Masked CMYK images and 1/2/4-bit ones open in RGB with a warning.
  Placing a CMYK TIFF keeps it CMYK too.
- PDF export: CMYK images are written in CMYK (DeviceCMYK, or ICC-based with
  the CMYK profile when colours are tagged: PDF/X-3, PDF/X-4, PDF/A). A CMYK
  JPEG neither resampled nor recompressed passes through unchanged; others are
  resampled in CMYK and compressed as ZIP or as a CMYK JPEG (jpeg-encoder,
  which also replaces the ZIP fallback and its warning for images converted to
  CMYK). Output conversion treats them like CMYK colours: Preserve Numbers and
  PDF/X-1a keep their numbers, Convert to Destination converts them to another
  CMYK profile or to RGB through a 17^4 lookup table (cms::CmykLut, now also
  behind the renderer's ink table). A CMYK image that can't be decoded is
  reported in the warnings.
- Canvas: CMYK images show through the working CMYK profile, as CMYK fills
  do, and paint their own inks in ink planes (CMYK raster exports, CMYK
  blending). SVG export writes TIFF images as PNG.

Illustrator's Output › No Conversion keeps colour data as it is
(https://helpx.adobe.com/illustrator/using/pdf-options.html).

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-08 06:04:07 +07:00
bflatasticandClaude Opus 5.5 7be80776f2 Release: VectorCraft v0.4.0
Bump the workspace version 0.3.1 -> 0.4.0 (cargo xtask version set 0.4.0).
Minor release: 50 pull requests since v0.3.1 (#128-#289).

What changes for users:
- Interface languages: VectorCraft > Language picks Automatic or a
  language; Traditional Chinese covers the whole interface, Czech and
  Japanese every menu.
- Vertical type: kinsoku, tate-chu-yoko and upright CJK glyphs, each
  character in its own cell down the column.
- Area type resizes its frame with the Selection tool's handles and is
  reshaped with Direct Selection; the text reflows at its size.
- Canvas and tools: right-click context menu, guides dragged out of the
  rulers, Cmd+Space / Cmd+Alt+Space zoom, Cmd drags with the selection
  tool used last, double-clicking type places the caret, tool
  double-clicks (Hand, Zoom, Rotate, Scale, Reflect, Shear), Free
  Transform distort and shear by the keys held during a drag, the status
  bar's artboard navigator, Symbols panel drag and drop, Shift+punctuation
  shortcuts.
- Live Paint treats every path as an edge; Effect > Pathfinder works on
  several objects.
- Files: EPS files from other apps open; PDF/.ai import finds fonts by
  PostScript name, brings type on a path back as type on a path and keeps
  each artboard's art on its own page; DXF Fit/Aligned text.
- MCP: prompts, resource templates, completions and logging; tool
  descriptions and replies match the engine.
- Platforms: FreeBSD and Windows on ARM64 release packages; Japanese
  fonts come from craft-fonts at build time.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-07 15:33:13 +07:00
Brandon ThomasandClaude Opus 5.5 15ab25426e Release: VectorCraft v0.3.1
Fixes the Windows installer: the Start Menu shortcut and Add/Remove Programs icon were blank. Release builds no longer open a console window behind the app.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-06 08:03:13 -04:00
bflatasticandClaude Opus 5.5 811ad1efd8 Fix #121: sandboxed WebAssembly plug-ins: object filters and live effects
VectorCraft had an Additional Plug-ins Folder preference but nothing loaded from it. Port
PhotoCraft's wasmi plug-in host (same sandbox, manifest and parameter schema) as the new
vectorcraft-plugins crate (L2), extended for vector documents:

- Object filters read the selected paths and compound paths as JSON (native PathData and
  Paint forms: geometry, fills, strokes, gradients, opacity) and return the objects to keep,
  change, add or delete; the output is validated in full and applied as one undo step
  (plugin.run). A failing plug-in leaves the document untouched.
- Live-effect plug-ins are geometry effects in the appearance stack (effect id
  plugin.<id>), re-evaluated (and cached) when the object or parameters change, editable,
  exported and baked by Expand Appearance; a missing plug-in leaves the geometry as is.
- plugin.list / info / run / install / remove / reload; the preference folder installs
  every *.wasm at startup and when it changes; File > Open of a .wasm installs it (web).
- Object > Plug-ins and Effect > Plug-ins menus with dialogs generated from the parameter
  schema (live preview), the Appearance panel's fx menu, docs/plugins.md, an original
  example plug-in (Desaturate, a Rust crate outside the workspace) and fuzzing of the
  plug-in boundary (engine/tests/plugin_fuzz.rs).

Tool plug-ins and paint-changing live effects are left for later (docs/plugins.md).

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-06 00:19:41 +07:00
bflatasticandClaude Opus 5.5 885b7acac1 Fix #87: rust-version is 1.95, and clippy 1.95 passes
egui 0.36 needs rustc 1.95 (hayro and krilla 1.92), so the declared 1.90 let
cargo fail on dependency versions instead of naming the toolchain. Clippy 1.95
also flagged four collapsible matches that newer clippy no longer does; each is
rewritten without changing behaviour.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-05 23:05:32 +07:00
bflatasticandClaude Opus 5.5 a1deca3d13 Release: VectorCraft v0.3.0
Bump the workspace version 0.2.0 -> 0.3.0 (cargo xtask version set 0.3.0).

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-05 19:23:19 +07:00
bflatasticandClaude Opus 5.5 ab1c6b0516 M4.94: EMF and WMF export from Export As and document.export
New crates/metafile (L3, pure Rust): hand-written EMF and WMF writers over
one shared document walk. EMF keeps Bezier paths, solid brushes, geometric
pens (width, caps, joins, miter limit, user-style dashes), clipping masks as
path clips, images (StretchDIBits, or AlphaBlend with transparency) placed by
a world transform, type as outlines; gradients become images clipped to their
shape and pattern fills their tiles clipped to it. The header's frame is the
artboard in 0.01 mm on a 100 px/mm reference device. WMF flattens curves into
polygons in 16-bit units behind a placeable header (with its checksum),
numbers objects as players do, and reports what it leaves out (clipping,
transparency, gradients, rotated images).

document.export {format: emf|wmf} (and serialize, export) writes one artboard,
or one file per artboard with useArtboards (false: the art's bounds); raster
effects are rendered to images first, as for PDF. Export As lists EMF and WMF.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-05 15:24:24 +07:00
bflatasticandClaude Opus 5.5 4c4850e745 M4.76: EPS export (PostScript Level 2 and 3) with EPS Options, TIFF previews and the document embedded
New crates/eps (L3): a hand-written EPS writer. A DSC header with
%%BoundingBox and %%HiResBoundingBox (y up from the origin), %%LanguageLevel
and spot colours; paths filled and stroked with caps, joins, miter limits
and dashes (strokes a plain line can't draw as filled outlines, brushes as
their art), clipping groups, linear and radial gradients as smooth
shadings at Level 3 and stepped fills at Level 2 or with compatible
gradient printing, patterns as tiles, freeform gradients and placed images
as images (Flate with masked transparent pixels at Level 3, run-length at
Level 2), type as glyph outlines, spot colours as Separation spaces and
overprints when preserved; RGB written as CMYK on request. A TIFF preview
(1-bit or colour, transparent or opaque) behind the binary header, a PNG
thumbnail and the native document in comments (eps::native and
eps::thumbnail read them back for a later import).

document.export {format: eps} and document.exportEps: transparency is
flattened first with a flattener preset (built-in or saved) and options;
the visible art's bounds, or with useArtboards one file per artboard named
{stem}_{artboard}.eps. Export As lists EPS, then EPS Options
(ui.epsOptionsDialog for agents, remembered between exports).

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-05 13:50:50 +07:00
Brandon ThomasandClaude Opus 5.5 8b50a2604d Release: VectorCraft v0.2.0
Bump the workspace version 0.1.1 -> 0.2.0 (cargo xtask version set 0.2.0).

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-05 02:41:32 -04:00
bflatasticandClaude Opus 5.5 a17cc428d1 M4.77: DXF export (R12 to 2018) with DXF Options; DWG and PICT say what to use instead
New crates/cad (L3): a hand-written ASCII DXF writer. Layers become DXF
layers (hidden: off, locked, non-printing: not plotted), straight paths
LWPOLYLINE (POLYLINE before R14), curves cubic SPLINEs through every
anchor, fills solid HATCHes (outlines in R12), strokes lines with a
lineweight and a linetype per dash pattern, type TEXT or glyph outlines,
placed images IMAGE entities linked to PNG or JPEG files. Units and
scale ($INSUNITS), scaled lineweights, 8/16/256 indexed or true colour
(420), transparency (440), Preserve Appearance / Maximize Editability,
Alter Paths for Appearance, Outline Text.

document.export {format: dxf} and document.exportDxf; useArtboards
writes one drawing per artboard; selectedOnly (any export) writes the
selection in its layers. Export As lists DXF (then DXF Options,
ui.dxfOptionsDialog for agents, remembered between exports) and DWG
greyed out; document.formats lists DWG and PICT as unsupported with a
hint, and exporting or opening them answers with it.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-05 12:00:17 +07:00
bflatasticandClaude Opus 5.5 7b30dd787b M1.9: the MCP connect-failure test holds its own closed port
remote_connect_fails_fast bound a port and dropped it, so another test or
process could take the port before the connect and make it succeed. It now
holds a socket bound without listening (socket2, a test-only dependency):
connections to it are refused and nothing else can bind it meanwhile. It
also checks the failure comes within 5 s.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-05 11:41:26 +07:00
bflatasticandClaude Opus 5.5 ac77b52ad3 M4.49: PNG-8 and GIF export with a palette quantizer and dithering
document.export {format: "png8" | "gif"} reduces the art to a palette of at most `colors`
(2–256) entries: median cut over a 15-bit histogram refined by k-means (perceptual,
selective or adaptive weighting), or the web-safe, black-and-white or grey palettes; art
with that many colours or fewer keeps them exactly. Dithering is Floyd–Steinberg diffusion,
an 8×8 ordered pattern or noise, with an amount. Pixels under half opacity become one
transparent entry; partly transparent edges blend over the matte. PNG-8 is an indexed PNG
(PLTE, tRNS, 1–8 bits per pixel, Adam7); GIF is a GIF89a (optionally interlaced). Both are in
document.formats, Export As (PNG-8 / GIF Options dialogs) and Export for Screens.
document.formats' writable list and the MCP export tool's format enum gain gif and png8
(their tests list them).

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-05 11:26:15 +07:00
bflatasticandClaude Opus 5.5 ba4ed2ff93 M4.48: JPEG Options — RGB/CMYK/gray, baseline/optimized/progressive, embedded ICC profiles and image maps
document.export {format: "jpg"} takes colorModel (rgb|cmyk|gray), quality 0–100, method
(baseline|optimized|progressive), scans (3–5), embedIcc and imageMap (none|client|server).
JPEGs are written with jpeg-encoder. CMYK files hold ink amounts drawn as the renderer's ink
planes, so CMYK colours keep their inks (black type stays black ink alone). Profiles are made
in code from the CMS (cms::icc_bytes): the RGB spaces from their primaries, the CMYK spaces as
Lab lookup tables sampled from their model, a grey with sRGB's tone curve, and loaded
profiles as loaded. Image maps write <stem>.html or <stem>.map beside the image for objects
with a URL and an Image Map shape. The JPEG Options dialog gains Color Model, Quality 0–10,
Method and Scans, Image Map and Embed ICC Profile; CMYK documents default to CMYK.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-05 11:25:09 +07:00
bflatasticandClaude Opus 5.5 0968e34e7e M4.57: PNG, PDF and text clipboard flavours in and out
Copy and Cut also offer other apps a PNG of the copied objects, a PDF
with On Copy: PDF, and plain text when every copied object is type
(clipboard.flavours; clipboard.exportPng {scale?}, exportPdf,
exportText). Paste outside text editing takes what another app copied:
SVG, then PDF (clipboard.importPdf), then plain text as point text
(clipboard.importText), then a bitmap embedded at the view centre
(clipboard.importImage {dataBase64, mime?, center?}); pasting our own
copy keeps the lossless internal clipboard, and Cmd+V pastes a bitmap
that comes with no text. Services gains system_clipboard
(SystemClipboard: write, holds_ours, read, has): on Windows every
format at once, on macOS and Linux one (the text, else the PNG); the
web keeps SVG text only. With When pasting text: Keep Plain Text, text
the Type tool copied pastes without its formatting.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-05 10:52:01 +07:00
Brandon ThomasandClaude Opus 5.5 3e323bfa2a Robustness: VectorCraft never crashes — no panics in shipped code
Shipped code no longer unwraps, expects or panics: every one of the 124
unwrap()/expect()/panic!/unreachable! sites outside tests now handles the
failure (Result/Option, ?, let-else, defaults) and reports errors to the user.

- Lints: workspace clippy denies unwrap_used, expect_used, panic, todo,
  unimplemented and unreachable; clippy.toml allows them in tests, and
  integration tests, examples and testkit opt out explicitly.
- Safety net (vectorcraft_engine::guard): a panic in a top-level command rolls
  the document back and returns EngineError::Internal; a panicking tool is
  reset; the MCP server answers with an internal error and keeps serving; the
  UI frame and each control request are guarded.
- APIs that hid failures now return them: Rendered::to_png/to_jpeg/to_webp
  return Result (JPEG/WebP errors used to write empty files),
  FontDb::face returns Option, Region::top returns Option.
- Fuzzing: engine/tests/import_fuzz.rs feeds garbage, hostile and mutated SVG
  and PDF through import → render → export (30k cases locally, no panics).
- Docs: AGENTS.md/CLAUDE.md rule, docs/development.md "Robustness" section,
  README pointer and a PR template checklist.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-05 06:28:59 +07:00
bflatasticandClaude Opus 5.5 4d503c0327 M4.12: one loader and encoder for every frontend — engine fileio (load/encode/export/save, append-only FORMATS table, OPEN_EXTS, document.formats query, typed per-format options, parse_range); document.open reads native/legacy, SVG/SVGZ, PDF/.ai, .ait (opens untitled like native templates) and PNG/JPEG/GIF/WebP/TIFF/BMP; desktop, web, control channel, headless MCP and the CLI open and encode through it; open dialogs list "All readable files" plus one filter per format
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-04 11:36:51 +07:00
Brandon ThomasandClaude Opus 5.5 4ddc422e51 Release 0.1.1
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-03 09:55:30 -04:00
Brandon ThomasandClaude Opus 5.5 7d393add4a Community links: Help menu (Discord, ArtCraft website, app page, GitHub), Discord button in the header, links on the About and Home screens; engine help.* commands return the URLs (menu clicks open them via the host's browser service)
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-01 14:37:29 -04:00
Brandon ThomasandClaude Opus 5.5 4878f1c5dd Rename DrawCraft → VectorCraft: crates (vectorcraft-*), apps, binaries, types, env vars, docs, examples (.vectorcraft); old .drawcraft files and preferences still load. Fix: text bounds exact after opening a file; selection no longer marks a document modified (dirty = content differs from the saved document). Screenshots and renders regenerated.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-01 14:30:09 -04:00
Brandon ThomasandClaude Opus 5.5 318a55350a M4.8: system clipboard — copy/cut publish SVG markup, paste adopts SVG from other apps (centred in view); Copy/Cut/Paste events handled off macOS; Place bypasses the clipboard hook
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-01 08:27:54 -04:00
Brandon ThomasandClaude Opus 5.5 f8136f1e35 Live Blends/Envelopes/Gradient Mesh, Shape Builder, Live Paint, Image Trace (drawcraft-trace), Recolor Artwork, Export for Screens, Actions panel, prefs persistence, real layer thumbnails; menus bound
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-09-30 11:02:16 -04:00
Brandon Thomas a7e49bfa72 continued work 2026-09-30 09:43:24 -04:00
Brandon ThomasandClaude Opus 5.5 42df20ca7f Panels to Illustrator parity (19 panels), ~70 menu commands, generic param dialogs, view rotation, property/model-based tests + MCP e2e; fix arrange overflow, compound grouping, double journaling, float round-trip, coordinate sanity, simplify growth, batch rollback of session state
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-09-30 09:32:20 -04:00
Brandon ThomasandClaude Opus 5.5 bfee80a22c M0: workspace skeleton — geom, color, doc, render, text, pathops, svg, tools, engine
Engine-first Cargo workspace for DrawCraft (clean-room Illustrator):
- geom: anchor-based path model, shapes, hit testing, snapping
- color: colours, paints, gradients, swatches, blend modes, harmonies
- doc: persistent Arc document tree, appearance stacks, text model, selection
- render: vello_cpu renderer (appearance, gradients, clip groups, blend modes)
- text: font DB, harfrust shaping, point/area/path layout
- pathops: curve booleans (linesweeper), Pathfinder, offset, simplify
- svg: import (usvg) and export
- tools: selection/direct/pen/shape tools emitting commands
- engine: Session, history with interactions, ~110 commands

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-09-30 05:53:29 -04:00