The engine built the PDF options without a creation date, so the
writer dated every PDF and PDF-compatible .ai file with the time it
was written. A document created on 2020-01-01 (File › File Info
shows the date) exported as a PDF with today's date in /CreationDate
and xmp:CreateDate. SVG export with the metadata option already
writes the document's own date.
The options now carry the document's File Info created date and the
time of writing as the modification date. A document without a
creation date is dated with the time of writing, as before, so PDF/X
files still get their required date. The PDF writer writes one date
for both, so the export then sets /ModDate, xmp:ModifyDate and the
PDF/A history dates to the time of writing; /CreationDate and
xmp:CreateDate keep the document's date. The page information mark
and the embedded editing data's modification date keep the time of
writing.
Docs: docs/mcp.md (File Info), docs/target-app-parity.md.
Print and Print Preview name the area type and type on a path that
prints without the text past the end of its frame (#2308). The exports
that draw type gave no such warning: a PDF, EPS, SVG, EMF, WMF or
raster export of a frame too small for its text answered with no
warning about it.
These exports now add the same warning, with "isn't drawn in the
export" in place of "doesn't print". Each export counts the visible
objects that it draws. Those are the objects on the pages or artboards
it writes, or all of them in an EPS of the visible art and in an SVG
without chosen artboards. A PDF leaves out layers that don't print
unless includeNonPrinting or createLayers is set. The objects are found
with the walk that fonts::printed_type runs for Print, and typecmd.rs
builds the message with the code that builds Print's. A .ai file keeps
the whole text in its editing data and gives no warning.
Docs: docs/mcp.md (Fitting area type), docs/target-app-parity.md.
The MCP server read one line, ran it and answered it before reading the next,
so notifications/cancelled was never seen during a call and every request
(even ping) waited behind a running export.
- vectorcraft_doc::cancel: a thread-local cancel token and progress sink that
long work polls. Checkpoints: PDF pages, PDF flattening, geometry bake,
raster-effect flattening, drawing objects, raster artboards, and before any
file is written. A cancelled command returns EngineError::Cancelled and
changes nothing.
- Server::serve reads on its own thread: notifications/cancelled drops a
queued request or stops the running one (no reply, as the MCP spec says),
engine-free requests (ping, the list methods, prompts/get) are answered at
once, a request that would wait behind a call running for 2 s is refused
with -32003 naming that call, and _meta.progressToken gets
notifications/progress (page n of m). Queue and output are bounded.
- The remote backend stops waiting for the app when the call is cancelled.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The PDF writer defaulted to Convert Text to Outlines, so every glyph of
every page became a path: a text-heavy PDF grew several times larger on
export (a 7-page document went from 27 KB to 226 KB) and its text could
no longer be selected or searched. Illustrator's PDF presets embed font
subsets and keep live text; that is now the default too
(advanced.outlineText: false). Outlining stays available as an option,
fonts that can't be embedded still become outlines with a warning, and
printer's marks (page information) are drawn as shapes as before.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- a story is read once however many text objects name it; the text objects, their pairs with the
page's type, the pieces of a line and a story's size are capped, and over a cap the layers aren't used
- the ASCII85 of the text document is bounded before it is decoded
- joining the pieces of lines that interleave no longer removes the wrong pieces
- a run length too large for the text saturates instead of overflowing
- a dictionary left open at the end of a layer, and layers nested deeper than are read, make the
file one that comes in as its page (they were silently dropped)
- a file whose editing data can't be decoded says so, and the notes about art that was too much or
too far away count as losses, so writing over the source asks first
- the private data of a .ai is inflated under a cap of its own (the PDF reader's decoder has none)
- the other writers (PDF, selection, office, print) ask before replacing a source that lost things,
and a recovered copy remembers that
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
A `.ai` file's PDF part is what apps that don't read VectorCraft's native
document open. It had no PDF layers: hidden layers and sublayers were left
out of it and everything else was flat page content.
- `.ai` files (Save As, exports, the CLI) write PDF layers unless
`createLayers` is false (a PDF standard still decides for itself).
- createLayers writes sublayers too, as optional content groups listed
under their layer's in `/Order`, hidden ones off with their art.
- A layer's form gets a box round the whole page instead of its art's
bounds, which readers made a clipping group of, gathering a layer's art
and its sublayers' in one group.
- PDF import: art inside a group, clip or form that dissolves into its
parent keeps the layer it was drawn in, so sublayers nested in their
layer's content import as sublayers.
- Save PDF: "Create PDF layers from layers and sublayers" (ja, es, it,
pt-br, ru, zh-hans, zh-hant).
Hidden objects (not layers) still aren't in the PDF part.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Opening a PDF whose fonts aren't installed keeps the text live in the fallback font (as
Illustrator substitutes and highlights missing fonts), and opening said so, but every export
then wrote the fallback font silently ("warnings": []), so a headless convert re-set the type
without a word.
- Exports that draw type now say so in their warnings, naming the missing families and the
fallback font: PDF (outlined or real text, also .ai and Save As), EPS, EMF/WMF, raster images
and SVG with outlined or embedded fonts. Live SVG text, DXF, text and native files name the
font itself and don't warn. Replacing the font (Find Font) clears it.
- The fonts a document uses (text.fonts' scope, Package's font list) come from one helper.
- textAs: outlines already keeps the glyphs the PDF draws (its embedded font program, installed
or not): now covered by a test with an embedded serif font that isn't installed, checked
against the installed font's and the fallback's outlines.
- docs/mcp.md and ROADMAP describe the warning.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
compatibility "1.3" writes a %PDF-1.3 file (its XMP metadata says 1.3
too) without transparency: a copy of the document is flattened first
with flattenerPreset (stored with PDF presets; empty is High Resolution)
and the flattener options over it, see-through image pixels counting as
transparency and rasterized areas clipped to their regions so no soft
mask is needed. Page groups are left out and the writer refuses a file
that would still have transparency. PDF/X-1a and PDF/X-3 share this
path (their version is now PDF 1.3; 1.4 is still accepted and written
as 1.3), and with it the preset, the header and metadata code and the
transparency check. Passwords at PDF 1.3 encrypt with 40-bit RC4
(revision 2). The Save PDF dialog lists PDF 1.3 and picks the flattener
preset under Advanced.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Embed Page Thumbnails gives every page a /Thumb image: the page drawn on
white, 106 px on its long side, without the layers the page leaves out
(the engine draws them; vectorcraft_pdf::page_areas says what each page
shows; PDF/X files get grey ones). Optimize for Fast Web View writes a
linearised file: the objects are put in linearised order and numbering,
encrypted when a password asks (the encryption dictionary goes with the
catalog, PDF layers' groups too), then laid out with the linearization
dictionary, both cross-reference tables and the page offset and shared
object hint tables (the hint stream encrypted like any other). Their
"not applied yet" warnings are gone. Reading the objects back uses the
lexer of encrypt.rs (syntax.rs adds what rewriting needs).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Advanced > Overprint: Preserve (the default; document.exportPdf
advanced.overprint) writes each overprinting fill and stroke (an object's
own, a character's, a type object's) with a graphics state of /OP true
/op true /OPM 1 (/OPM 0 in PDF/A); Discard writes none. White ones knock out
when Document Setup's Discard White Overprint is on, as in print. Mask art
never overprints. File > Print's composite PDF honours Print > Advanced >
Overprints: Preserve the same way (separations keep multiplying plates).
Each overprinting fill or stroke is drawn as a form marked to overprint
(crates/pdf/src/forms.rs); after writing, its content starts by setting the
overprinting graphics state, and the PDF/X self-check runs on the result.
The engine's "overprint is not written to PDF yet" warning and print's
"overprints print as knockouts in composite output" warning are gone.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Create PDF layers from top-level layers (document.exportPdf createLayers, the
Save PDF dialog's General option) now writes an optional content group per
top-level layer (template layers are left out): named as the layer, off when
the layer is hidden, /PrintState /OFF when its Print option is off, locked
when it is locked, listed top first, with a print auto-state (not under a
standard). The file reopens with those layers.
The PDF writer has no optional content, so each layer is drawn as a form of
its own (no transparency group, so it draws as in place) starting with a mark;
after writing, the uses of the layers' forms are wrapped in /OC ... BDC/EMC
and the catalog gets /OCProperties (crates/pdf/src/forms.rs, through the
shared patch writer and the PDF syntax reader of encrypt.rs). PDF 1.4 and a
knockout page group write plain page content with a warning; the dialog greys
the option at 1.4. The "not written yet" warning is gone.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
document.exportPdf {standard: pdfX1a|pdfX3|pdfX4} and the PDF/X presets now
write conforming files instead of being refused:
- every PDF/X file gets a /GTS_PDFX output intent (by default the CMYK
profile in effect, embedded), TrimBox, Trapped, GTS_PDFXVersion (and
GTS_PDFXConformance for X-1a), a title and dates; editing data,
passwords and, in X-1a/X-3, PDF layers are refused
- PDF/X-1a converts every colour and image to a CMYK destination,
untagged, with CMYK spot alternates; X-3 and X-4 tag colours with ICC
profiles
- X-1a and X-3 are written as PDF 1.3 and their transparency is flattened
first (High Resolution preset; images with see-through pixels count,
rasters stay opaque); X-4 keeps transparency, is PDF 1.6 at most and
names the standard in its XMP metadata
- the written file is checked against its standard (soft masks,
transparency groups, opacity, blend modes, RGB in X-1a, fonts not
embedded) and refused rather than mislabelled
- choosing a standard sets the latest compatibility it allows and turns
off what it forbids (engine and Save PDF dialog)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The Print dialog (Ctrl/Cmd+P) edits the document's print settings in the
sections General, Marks and Bleed, Output, Graphics, Color Management,
Advanced and Summary, with a preview of each printed page under the section
list (drag the art to move its placement). It drives print.setup,
print.preview and file.print; the preview pages now carry their transform,
printed area and trim box. Print sends the job's PDF to the chosen printer
through the new PrintService (lp on macOS/Linux, the shell print verb on
Windows, a hidden frame and the browser's print dialog on the web); without
one, or with PDF File, it saves the PDF. Done only keeps the settings.
UI commands file.print, print.printers and print.printerSetup.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
With Convert Text to Outlines off (advanced.outlineText: false), type is
written as selectable, searchable text: each glyph in its font, embedded
as a subset with a ToUnicode map, where its outline would be (rotated,
scaled, skewed and on-path type too; gradients keep their place). Fonts
whose licence forbids embedding, or allows only whole fonts, fall back to
outlines with a warning; a subset threshold below 100% is accepted with a
warning. Laid-out glyphs now carry their glyph id and transform.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Save PDF > Output now applies: colours convert to a destination profile
(destination, or preserveNumbers keeping the numbers of colours already in
its model; grey stays grey; images and freeform gradient images convert
too; printer's marks don't). Profile inclusion writes ICC-based colour
spaces (CMYK with the destination's or the document's profile, RGB as sRGB,
grey), and transparency in CMYK output blends in the CMYK profile's space.
The output intent profile is embedded as the catalog's /GTS_PDFX output
intent with its condition, identifier and registry, and Trapped goes in
the document information (PDF/A keeps its own). A shared patch module
edits written PDFs (Lab spot alternates use it too).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- document.save / Save As / Save a Copy to a native or .ai file take
separateArtboards + range (also write <name>-<artboard>.<ext> per artboard
beside the master file, holding that artboard and the art touching it; the
result lists every file), includeLinked (linked images keep their files' own
pixels), embedProfiles (ICC profiles loaded from files that the document is
tagged with; opening installs them where missing) and pdfCompatible (native:
also carry a PDF of every artboard; .ai: false writes blank pages around the
native document). .ai files also take compress (compression.compressText).
- File > Save As to a native or .ai file shows the options dialog (VectorCraft
Options) after the save panel: Save each artboard to a separate file (All or a
range), Include Linked Files, Embed ICC Profiles, Create PDF-Compatible File,
Use Compression, Preview; the web's Save As dialog shows them too. Save, Save a
Copy and Save as Template reuse the options as last saved.
- Format: optional "profiles" and "pdf" members (load_file, pdf_content),
SaveOptions.include_linked/profiles/pdf; files without them are unchanged.
- Changed test: tests_aisave::save_as_ai_writes_a_pdf_that_reopens_editable now
confirms the options dialog Save As .ai shows before writing.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- pdf/src/encrypt.rs encrypts a written PDF with the standard security handler: 128-bit RC4
(PDF 1.4, revision 3; PDF 1.5, revision 4), 128-bit AES (1.6) or 256-bit AES (1.7/2.0,
revision 6), every string and stream, plaintext XMP metadata when asked, the permission bits
(printing none/low/high, five change levels, copy, screen readers). Crypto from RustCrypto
(aes, md-5, sha2: MIT OR Apache-2.0, pure Rust, wasm).
- PDF/A and PDF/X refuse passwords; equal passwords and passwords the algorithm can't take are
refused.
- Opening: the permissions password opens RC4/AES-128 files too; editing data comes back from
an encrypted PDF opened with its password.
- Save PDF › Security: the passwords, permissions and plaintext metadata, the encryption level.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
file.print {settings?, path?} lays the document out on paper and writes one PDF page per sheet:
copies (collated, reversed), artboards (all, a range, ignored), blank artboards skipped, paper
size and orientation (or turned per artboard), transverse, Print Layers (template layers never
print), placement on the imageable area, no scale / fit / custom / tiles of the paper or of the
imageable area with overlap and a tile range; printer's marks and bleed as PDF export draws
them; composite or separations (one grey plate per ink that prints, overprints honoured, spots
as process), emulsion down, negative; rendering intent and preserve numbers. print.preview lists
the pages, tiles, inks and warnings; print.setup saves the settings with the document
(Document.print_setup, one undo step).
PDF export and print share one page writer; the ink separation helpers move from the renderer to
vectorcraft_doc::inks and the range parser to vectorcraft_doc::range so print can use them.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
document.exportPdf {marks} now draws trim marks (Roman or Japanese, at the
trim mark weight and offset, outside the bleed), a registration target at the
middle of each side, colour bars (process inks, their overprints, the
document's spot inks and black tints) and the page information (title,
artboard, export date in UTC). Marks print in [Registration] (/Separation
/All), the MediaBox grows to hold them and the art is clipped to the
BleedBox. The geometry is the shared vectorcraft_doc::marks::PrinterMarks
(built on TrimMarks) so print can draw the same marks. The "not drawn yet"
warning is gone.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
document.exportPdf applies the bleed (the document's with bleed.useDocument,
else the custom values): each page's TrimBox is its artboard and its BleedBox
and MediaBox the artboard grown by the bleed, so art in the bleed is kept.
Layers whose Print option is off are left out unless includeNonPrinting (new
setting, Save PDF › General) or createLayers is on. The bleed warning is gone;
the Marks and Bleeds section shows the document's bleed when it is used.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Colour, greyscale and monochrome (black-and-white) images placed above the
threshold resolution are resampled to the target (average, subsample or
bicubic) and compressed with ZIP, JPEG at the chosen quality, or
automatically (JPEGs stay JPEG, the others lossless); images already as
asked are embedded unchanged. JPEG 2000, CCITT, Run Length and no
compression are written as ZIP with a warning when an image needs them;
images with transparency stay lossless. Images no longer ask viewers to
smooth them in PDF/A files.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Pattern strokes are written as the pattern's tiles clipped to the stroke's
outline (dashes, caps, profile, arrowheads and alignment included) instead
of mid-grey; freeform gradients on fills, strokes and type as an image of
their colour field at the document raster effects resolution, clipped to
what they paint, instead of their average colour. Both read back within
2% of the canvas at 150 ppi with no warning. Text strokes are covered for
cap, miter limit, dash array and alignment; knockout groups keep their
soft-masked form with a warning. The freeform box and grid sampling are
shared with the renderer.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Save As offers VectorCraft, VectorCraft Template, PDF, SVG and SVGZ and asks
for the chosen format's options before writing: SVG Options for SVG/SVGZ, the
Save PDF dialog for PDF (its OK finishes the save); on the web a Save As
dialog first names the file and picks the format. A document opened from or
saved as SVG/PDF remembers its format and options in one place
(DocState.format, save_options: the SVG options, or every Save PDF setting),
so Save writes it again; the result's warnings name what the format loses,
then the encoder's notes. Save a Copy writes "<name> copy.<ext>" and leaves
the path, title and modified state alone. Save is off for a clean saved
document, and Save as PDF... is in the File menu.
Engine: document.save, file.saveAs and file.saveCopy take {path?, format?,
options?, svg?} (SVG options also flat) and write linked images beside an
SVG; file.formatOptions reads a format's options. save_plan/save_with are the
one save path of every frontend, on the shared SVG encoder (one SVGZ path).
The template format is writable. Save panels get per-format filters, a folder
and a suggested name.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Built-in presets are generated in code (VectorCraft Default, High
Quality Print, Press Quality, Smallest File Size and PDF/X-1a, X-3,
X-4, the latter listed as not supported yet) and read-only. Saved
presets live with the preferences (Prefs.pdf_presets) and work as
`preset` wherever PDF options are taken: document.exportPdf,
pdfSettings, export/serialize as PDF and .ai saves.
pdf.preset.list / save / delete / export / import manage them
(.vcpdfpresets files; opening one imports it). The Save PDF dialog's
Save Preset… saves its settings under a name; Edit > PDF Presets…
(ui.pdfPresetsDialog) lists the presets with each one's description and
differences from the default, with New…, Edit… (the Save PDF dialog as
a preset editor, ui.pdfPresetDialog), Delete, Import… and Export….
document.pdfSettings now lists what differs from the chosen preset.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Preserve Editing (on in the VectorCraft Default preset) embeds the
native document in the PDF as an embedded file with a hash of the pages
it was written with. document.open of a PDF, .ai or .ait restores it
exactly (restored: true) and falls back to importing the artwork, with a
first warning saying why, when the pages were changed elsewhere or the
data can't be read; SVG and PDF share that fallback and its warnings.
The legacy drawcraft payload name is read too. vectorcraft_pdf gains
editing(), ImportReport.native and PdfOptions.native.
document.save / file.saveAs / Save a Copy write .ai (format "ai" or an
.ai path): every artboard as a PDF that always carries the document and
takes the PDF options; a restored .ai keeps its path so Save writes .ai
again, and .ait templates open their document untitled. The desktop
save dialog lists the formats Save writes. Choosing a standard turns
Preserve Editing off (PDF/A refuses it), Export for Screens and PDFs of
some artboards leave it out with a warning.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
File > Export > Export As... (file.exportAs) picks any writable format and Use Artboards: All
or a range writes one file per artboard, <file>-<artboard>.<ext> (a PDF keeps them as pages);
off, the export covers the bounds of the visible art (an artless document is refused before the
save dialog). The format's options dialog follows: PNG/JPEG/WebP Options, SVG Options, or Save
PDF for artboards as pages. document.export takes useArtboards for raster formats (true: one
file per chosen artboard, default all) and PDF (false: the art's bounds), and the app's exports
return every file written and the encoder's warnings.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
document.export and document.serialize return the encoder's warnings (PDF:
options not applied yet, features approximated or left out, overprint).
document.pdfSettings lists the options that differ from the defaults and
the warnings (includeDocument adds the active document's own from an
in-memory export); the dialog's Summary section shows both. View PDF after
Saving opens the written file as a file:// URL through Services.open_url;
the status line reports the notes. The PDF writer's raster-effects warning
now names what it leaves out (objects of a kind, fills, strokes) instead of
claiming raster effects are never exported.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
PdfSettings (serde, camelCase) is the Save PDF model: Standard, Compatibility
PDF 1.4-2.0, General (Preserve editing, Thumbnails, Fast web view, View after
saving, Create layers), Compression, Marks and Bleeds, Output, Advanced and
Security. PdfOptions = settings + pages, title and date.
document.exportPdf {path?, preset?, artboard?|artboards?|range?, standard?,
compatibility?, ...sections} -> {path|dataBase64, bytes, warnings} applies the
options over the preset (null keeps the preset's value); PDF/X, passwords,
PDF/A-2b at 2.0 and out-of-range values are refused; options accepted but not
applied yet come back as warnings. document.export {format: pdf} and
document.formats take and list the same options.
The Save PDF dialog (file.export.pdf, ui.savePdfDialog) has Preset,
Standard and Compatibility on top and a section list; it runs the export
before asking for a path, so bad options never open a save dialog.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>