Commit Graph
9 Commits
Author SHA1 Message Date
.CooCoo 890c27ccb2 Native format: take the .vectorcraft envelope from craft-vectorcraft-format (#5146)
* Native format: the .vectorcraft envelope comes from craft-vectorcraft-format

vectorcraft-format reads and writes the file's envelope through the
craft-vectorcraft-format crate in craft-libs: Head and Image, the version
and size constants, the format and version check, Tail for the data after
the JSON, split_tail and entry, and base64. The constants, is_compressed,
json_part, base64_encode and base64_decode are re-exported from
vectorcraft_format, so callers do not change. load_file reads the members
it uses with Image entries and skips the preview and PDF data. The
document, its migrations, the version 1 writer, gzip writing, sniff and
the limits on decompression stay here.

A preview or pdf member of the wrong shape now reads as missing on its
own, so pdf_content still returns a file's PDF when its preview is
damaged.

A new test saves a document in every version, compressed and pretty,
with a preview, profiles and a PDF, reads it back, saves it again and
compares the bytes; it also reads each uncompressed file as the crate's
File. Another reads the PDF of a file whose preview is damaged.

* Native format: sniff from craft-vectorcraft-format, pinned at #408's head

- craft-vectorcraft-format moves to craft-libs 0fd7e75fe6, the head of
  storytold/craft-libs#408.
- `sniff` is the crate's: a file is native when its top-level `format`
  member, within the first 256 bytes after decompression, is
  `vectorcraft` or `drawcraft`, read with JSON escapes decoded. The word
  elsewhere in the head no longer counts. All 192 corpus files and
  their resaved copies get the same answer as before.
- Envelope errors other than the format and the version keep the
  crate's message instead of reading as a compressed file that unpacks
  to too much.
- A test checks that a repeated `generator`, `preview` or `pdf` opens
  and any other repeated member is refused, by `load_file` and by the
  crate's `Contents` alike.

* Native format: read through the crate's Contents and Entries

Pins craft-vectorcraft-format at 420a27f18f, the current head of
craft-libs#408, and replaces VectorCraft's own copies with the crate's:

- load_file reads the JSON through Contents::read, which also refuses
  another format or a newer version. Opened is removed. Messages are
  those of main: serde names the struct File, as main's reader did.
- In-memory data after the JSON (uncompressed files, and compressed
  files unpacked whole) is read through the crate's Entries.
  entries_within keeps its streaming reader for compressed files, whose
  data is unpacked entry by entry and is never one slice in memory.
- The streaming reader finds the marker through the crate's marker_at.
- MAX_BLOB is the crate's MAX_ENTRY (1 GiB).

save_to still writes the envelope member by member: it streams the
document into the output and looks for the images it uses as it
writes, and File would need the images before the document. A new test
checks that its output, compact, pretty and compressed, for versions 1
to 4, equals serde_json::to_vec or to_vec_pretty of the crate's File
holding the same members followed by the crate's Tail, so a change to
either side fails.

* Native format: pin craft-vectorcraft-format at craft-libs main

craft-libs#408 merged as 14d5dbb50c; the crate is unchanged from
420a27f18f. A test checks that the crate's sniff takes every layout
VectorCraft has written: the version 1 and 2 files from before the
rename, compact and pretty, and each version save_with writes.
2026-11-01 23:30:54 -05:00
Dylan M. TaylorandClaude Opus 5.5 03d2f0e83c Security: file authority for stored paths, linked files, placed documents, font folders, recovery areas and atomic saves
CodeRabbit findings #7, #72, #92, #94, #95, #99, #100, #140, #158, #174:

- Link search hashes at most the size it looked at (a growing file no longer matches).
- Resolving links reads, decodes and previews each linked file once, shared by every key.
- Placed documents read inside one another resolve links at most 8 deep, never one already
  being read.
- A data set's image path and the placed-document rereader follow stored paths through
  `document_path` (no other computer's share).
- The Links panel looks at a linked file within the roots of the automation caller that
  opened the document.
- A fonts folder set by a confined caller is scanned without following links out of it.
- Recovery refuses an area folder that is a link or another account's.
- Atomic saves keep the replaced file's group and Linux access ACL, or make the replacement
  owner-only.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-24 17:19:59 +07:00
Marco Arnulfo 544b17ec33 Workspace: rustix is declared once in the workspace dependencies 2026-10-13 12:58:04 +07:00
Marco Arnulfo 5e8581e42f Save: a network drive on macOS that refuses the full flush gets a plain fsync (fixes #1620) 2026-10-13 12:58:04 +07:00
bflatasticandClaude Opus 5.5 65cdc45ed9 M4.35: native files compress, save atomically, drop unused images, keep newer keys and save down to v1
- Format v3: optional gzip (Preferences > File Handling > Use Compression, or
  document.save {compress}); compressed files open by their magic bytes, legacy
  ones too.
- Every file write goes to a temporary file renamed over the target (engine
  writes and the desktop app's writer), so a failed save keeps the old file.
- Only the images the document uses are written.
- Document keys from newer versions are kept (Document.extra, flattened).
- Assigned colour profiles are a real field (Document.color_profiles),
  migrated from unknown.colorProfiles on load.
- document.save {version: 1|2} writes files older versions open; {preview}
  embeds a PNG of the first artboard of at most 256 px.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-05 12:27:02 +07: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 <noreply@anthropic.com>
2026-10-01 14:30:09 -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 <noreply@anthropic.com>
2026-09-30 09:32:20 -04:00
Brandon ThomasandClaude Opus 5.5 bea0c16636 M0.7/M0.8: egui UI (Illustrator layout), control channel, desktop app
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 06:16:46 -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 <noreply@anthropic.com>
2026-09-30 05:53:29 -04:00