.ai import: a file whose PDF part can't be read opens from its editing data

Squashed from #5051 onto main.
This commit is contained in:
dotCooCoo
2026-11-02 12:04:04 +07:00
committed by bflatastic
parent 54436b0aa2
commit 100730d4d3
43 changed files with 476 additions and 42 deletions
+3
View File
@@ -51,6 +51,9 @@ private editing data. VectorCraft:
A PDF saved with its editing data (`AIPDFPrivateData`) opens the same way.
The swatches of a version 7 `.ai` palette, which carry no names, come in named by their spot color, gradient or
values.
When the PDF part of either can't be read (a stream the import refuses), the file opens from its editing
data alone, with the PDF part's error as its first warning, and without the bleed and File Info the PDF
part would give (part of #4366).
- **Writes** a PDF-compatible `.ai` (Save As › `ai`): Illustrator opens it as plain art. It never writes
Illustrator's private editing data, which is undocumented.
- **Writes** a legacy `.ai` of version 7 (Save As › `ai` › Version: Legacy (version 7), `aiVersion: "7"`): the
+1
View File
@@ -1085,6 +1085,7 @@ Moved from the ROADMAP's "Shipped so far" on 2026-10-10. Update it when a featur
`.ai` and EPS editing-data import keeps template layers, and opens canvas and artboard ruler guides as ruler guides on their layers; guide objects stay editable guide paths (#779; `crates/eps/src/import/ai/tests.rs`, `crates/eps/src/import/tests_native.rs`).
`.ai` and EPS editing-data import keeps each path's Attributes panel note (`%AI3_Note:`, `%%Note:`, more lines in `%AI5_NoteMore:`, up to 1,024 characters) and Show Center (`1 Ap`); a note or Show Center applies to every path after it until the next one, and a note before a group or compound path is not theirs (`crates/eps/src/import/ai/tests.rs`, `crates/eps/src/import/tests_illustrator.rs`).
A `.ai` saved without PDF compatibility (its PDF part only a placeholder page) is placed and pasted from its editing data, as it opens: File › Place places the art of the layers that show on the first artboard (`file.place`'s `page` places another one), and Paste of it as PDF data (`clipboard.importPdf`) takes every object. `document.open` with `pages` naming every page of such a file opens it the same way (`crates/engine/src/cmd/fileio/tests_aiimport.rs`).
A `.ai`, or a PDF saved with Illustrator's editing data, whose PDF part can't be read (a stream the import refuses) opens from its editing data, with the PDF part's error as its first warning; File › Place places its first artboard the same way, and Paste of it as PDF data with `editingData: true` takes every object (part of #4366; `crates/engine/src/cmd/fileio/tests_aiimport.rs`).
- EPS and DXF in and out, EMF/WMF in and out; PNG (with PNG-8), JPEG, WebP, GIF, TIFF, BMP, Targa and layered PSD export; grayscale TIFFs with an alpha channel or other extra channels place, relink and open, the alpha as the image's transparency (#1466 in part; CCITT Group 3 and planar files with extra channels are not read); PSD and PSB files open and place, linked or embedded, as their merged image in every colour mode and depth (#918). EPS import runs a PostScript Level 3 interpreter written from the PostScript Language Reference: resource categories and `resourceforall`, local and global VM (`currentglobal`/`setglobal`/`gcheck`), `clipsave`/`cliprestore`, subarrays and substrings that share storage, the standard dictionaries in `systemdict`, `dictstack`, `internaldict`, executable filters and strings, `load` by any key, `//name` immediate names, `token`, `execform`, user paths, `cshow`, `rootfont`, `cachestatus`, colour rendering and halftone queries, file `status` and data read with `flushfile`, and `pdfmark` marks dropped (Discord feedback, #466, #469, #474). Masked images (`ImageType 3` in its three interleavings) and reusable streams are read, and an image's several data sources are read in turn, as the reference defines (procedures that read one file get their own rows: such images came in banded, #498). `restore` puts dictionaries back as they were at the `save`, so programs that count their saves in a dictionary read to their end (part of #505). Tiling patterns come in as pattern swatches, uncoloured ones too; Type 3 fonts' glyphs as their outlines, spaced by `ashow`/`widthshow`/`xshow`/`kshow`; mesh and function-based shadings (types 1, 4–7) as gradient meshes; sampled functions (type 0) and Flate/LZW predictors are read. It is tested with programs written from the specification in the ways common generators use these features; Inkscape/cairo EPS files open as vectors. When a file's PostScript still can't be read, it opens as its TIFF preview, its Windows metafile preview (as vectors) or its EPSI preview, and the warning (in the status bar, `document.open`/`app.open`/MCP `open_file` replies and `vectorcraft-cli info`) names the error, the operator that raised it and the procedures it ran in. Legacy PostScript `.ai` files (Illustrator 3–8, written with the prolog that defines their operators) keep their groups and nested groups (`u` … `U`), between and inside clipping groups; EPS and EMF/WMF import nest clips (and groups) at most 128 deep, so a hostile file can't exhaust the stack. DXF TEXT justified Fit or Aligned spans its two points (stretched, or scaled as a whole). PDF export writes type as real, searchable text in embedded subset fonts by default, as Illustrator's PDF presets do (Convert Text to Outlines is an option; printer's marks stay shapes), so text-heavy PDFs stay small (#733). DXF export writes each fill as its outlines followed by its hatch, so laser and cutter software, which skips hatches, gets filled art and type too (#546).
- The Open and Place dialogs list PostScript `.ps` files and `.epsf` files. A `.ps` file opens and places through the EPS reader (its first page), also when its header is only `%!`, as the `ps` format, which exports don't write (Print to PostScript does); an `.epsf` file opens and places as EPS. Copied in a file manager, these files paste as EPS, and `clipboard.importEps` also reads PostScript whose header is only `%!` (`crates/engine/src/cmd/fileio/tests_epsimport.rs`).
`document.pdfInfo` reads an EPS, a `.ps` file or a `.ai` in PostScript form as one page the size of its bounding box (a US Letter page without one), and its `thumbnail: 1` is a PNG of what that page prints (`crates/engine/src/cmd/fileio/tests_pdfimport.rs`).