Gradient Objects now leaves out fills and strokes at an opacity of 0,
so the test expects no gradient count once every fill and stroke of
the spot gradient object is clear.
Find Font and Replace Missing Fonts looked only at the type on the layers
and in symbols, and the font list behind the export warning, Package and
the Missing Fonts dialog skipped opacity masks and pattern swatches.
- text.fonts lists the type in opacity masks (on objects and layers,
disabled masks and masks inside other art included) and in pattern
swatches, a swatch that nothing paints with included. A pattern's type
counts once however many objects it paints. With selectionOnly, the
masks of the selected objects and the symbols and patterns they show.
- select.font also selects the objects whose mask holds the font and the
objects painted with a pattern whose art uses it (visible fills and
strokes wider than 0). A layer's mask and an unused swatch select
nothing.
- text.replaceFont changes that type in one undo step. Type in the mask
of a hidden or locked object, and the type of a pattern that only
hidden or locked selected objects paint with, keeps its font and is
counted in skipped.
- addon.cleanup.replaceFonts replaces missing fonts in masks and
patterns, hidden or locked type included.
- text.missingFonts, File > Package and the export warning read masks
and patterns too.
- document.info's fonts for the whole document (the Fonts and Font
Details categories and the text report) include the same type. With
selectionOnly the list stays the selected type's fonts.
While a mask or pattern is edited, its type is taken from the editing
layer only.
The Brushes rows name each type as the New Brush dialog does (Art Brush,
Scatter Brush) and say "missing from the Brushes panel" for a brush the
panel does not hold. The panel now shows these values through the
catalogs, so a localized interface no longer shows them in English.
document.info and the saved report keep them in English. Every catalog
gets a row for "missing from the Brushes panel"; the type names already
had rows.
A spot-colored fill or stroke whose opacity is 0 prints no ink, but
Spot Color Objects still listed its object and objects.spots counted
it. Such fills and strokes are now left out; an object stays listed
while another of its fills or strokes prints the spot color. Pattern
Objects and Gradient Objects are unchanged.
A stroke at an opacity of 0 draws nothing, so its brush is no longer
listed in the Brushes category, brushNames or brushes. Pattern Objects,
Gradient Objects and Spot Color Objects likewise leave out fills and
strokes at an opacity of 0, and Objects no longer counts objects whose
only such paint is at opacity 0.
Document Info's Brushes category now lists the brushes the artwork's
strokes draw with, each once with its type (Calligraphic, Scatter, Art,
Pattern or Bristle), as the Document Info panel help page describes:
https://helpx.adobe.com/illustrator/desktop/get-started/learn-the-basics/document-info-panel.html
Without Selection Only the category used to list every brush in the
Brushes panel, used or not; it now lists only the brushes art uses.
document.info adds `brushes` ([{name, type}]) and `panelBrushNames`
(the Brushes panel's brushes), and `brushNames` holds the used brushes.
Hidden strokes, strokes with no paint or width, guides, paths with no
segment, type that draws no characters, groups' and layers' own strokes,
compound path members' own strokes and image strokes without a shape
are left out. A brush the panel does not hold is listed as missing,
with a null type, and a name two panel brushes share takes the type of
the brush the renderer draws with.
A grayscale or 1-bit image colorized with a spot color now counts as a
Spot Color Object. A gradient whose stops are all at an opacity of 0
draws nothing, so its spot stops no longer list the object.
The spotColors category is now titled Spot Color Objects and lists each
object filled or stroked with a spot color, by name with the spot colors
it uses, instead of the spot swatch names. A solid color or a gradient
stop linked to a spot swatch at a tint above 0 counts; process colors
that look the same and Registration do not. Paint that draws nothing is
left out by the rules Pattern Objects and Gradient Objects follow, and
type whose characters use a spot color is listed. Objects counts the
listed objects as Spot Color Objects.
document.info returns spotObjects, spotColorNames and objects.spots;
spotColors now holds the spot colors those objects use. The report that
Document Info > Save... and Package write lists the same rows.
The Spot Color Objects, Pattern Objects and Gradient Objects titles have
a row in each of the 27 complete catalogs, and a test checks that every
complete catalog has the three.
Docs: docs/mcp.md, docs/target-app-parity.md.
A client confined with --automation-read-root could learn paths it was
not given and may not read from the replies of several commands. Each
one now names such a path only when no read roots are in force or the
path is inside them:
- document.save and file.save, file.saveAs, file.saveCopy and
file.saveAsTemplate (app.save and engine.execute) without a path:
the document's own file, the files of separate artboards and linked
files are left out or named by file name, and the folder a save
suggests is left out.
- document.exportForScreens with the folder of an exportPreset: the
ZIP path is left out and files are relative to that folder.
- document.exportSettings, document.exportPresets.list and
document.exportPresets.export: a kept folder outside the read roots
is left out of the reply and of the presets file the export writes.
- file.package: warnings, missingLinks and the report name a file
outside the read roots by its file name. A link's stored path, read
from the document's folder when it is relative, decides, also when
its file was found under another path.
- document.info: an image linked to a file outside the read roots has
link null, and its Linked Images row names the file alone.
docs/mcp.md and the params text describe the rule.
The gradients category was titled Gradient Swatches and listed every
gradient swatch, used or not. It is now Gradient Objects: one row per
object filled or stroked with a gradient, named as the object is, with
the gradients it uses (a linked swatch by name, else Linear gradient,
Radial gradient or Freeform gradient). document.info adds
gradientObjects and gradientNames, and Selection Only, Save and the
Package report use the same rows.
Gradient objects follow the rules Pattern Objects uses for paint that
draws: hidden fills and strokes, strokes with no width, guides, compound
path members' own paint, image paint without a shape and type that draws
nothing are left out, and type whose characters carry a gradient is
included. objects.gradients now counts the listed objects, so it no
longer counts hidden or zero-width gradient paint and no longer misses
type whose characters use a gradient.
The duplicate Document Info Save line in docs/target-app-parity.md is
removed.
Ruler guides were a list kept beside the layers. Each guide is now an
object of its layer or sublayer, always directly in it and above the
layer's art. These behave as on main:
- Guides draw on screen only. Exports (SVG, PDF, PNG, PSD), Fit All,
Select All, the art bounds, clicks and marquees, and a layer's
Pathfinder and Transform effects leave them out. The Layers panel
lists them as guide rows of their layer, the highest guide.list
index first.
- Deleting a layer deletes its guides, and merging layers keeps their
guides in the merged layer.
- The guide commands number guides as guide.list does, in the order
they were made.
New: each guide takes an id from the document's object ids. An object
command given a guide's id fails with an error, and node.move cannot
put a guide into a group or out of its layers. A guide made while an
opacity mask, a symbol or a pattern is edited moves to the top
visible, unlocked layer when editing ends.
File format: native files still save the guides in the document's
guides list, in every file version, so older builds read them. Each
entry may now also carry the guide's id, name, locked and hidden
flags; older builds ignore those fields. Opening a file puts each
saved guide on its layer (on the top visible, unlocked layer when the
file names none or a layer it does not have), and each saved guide
counts against the object limit for opening a file. A ruler guide node
that a file holds below a layer's art moves up to the layer's guides,
and one anywhere else (in a group or another object, beside the
layers, or in a symbol) is removed. Ruler guides read from an .ai file
become guide objects on the layer they were on, numbered in the order
the file lists them.
Object > Expand of gradient and pattern fills now expands the pieces a
painted live effect draws one by one, so a piece keeps its own paints.
A later painted effect on a fill replaces only the first fill of a piece
and leaves the piece's other fills in place.
Document Info passes the document when it reads an image's painted fills.
The walk that skips objects it has already visited keys them by address
instead of id, so two objects that share an id in a damaged file are
both counted. An object reached through a selected group and again on
its own still counts once.
An object with a gradient or a pattern on both its fill and its stroke
counted twice in Objects. It now counts once for each paint kind it uses.
With Selection Only, a selection that holds a group and an object inside
it walked that object twice, so the object counts, the paths' total
length and Repeat Objects counted it twice. The walk now visits each
object once.
Document Info had no Repeat Objects category, and document.info
refused category "repeats". The reference app's Document Info panel
menu lists Repeat Objects after Font Details.
Document Info now has a Repeat Objects category after Embedded Images.
It lists each radial, grid and mirror Repeat object by name with its
kind and the number of instances it makes. For a grid it gives the
rows and columns instead, followed by the number of instances it
draws when that is fewer. The count comes from the new
RepeatSpec::instances, which gives the number of instances a repeat
draws. That number is smaller than its options give when repeats
nested in its source would pass the instance budget. With Selection
Only the category lists the Repeat objects in the selection.
document.info gives them as repeatObjects, the panel's flyout offers
the category, and the text report that Document Info › Save… and
File › Package write has a REPEAT OBJECTS section. The title has a row
in every catalog.
Docs: docs/mcp.md, docs/target-app-parity.md.
Document Info had no Brushes category, and document.info refused
category "brushes". The reference app's Document Info panel menu lists
Brushes after Graphic Styles.
Document Info now has a Brushes category after Graphic Styles. For the
whole document it lists the Brushes panel's brushes. With Selection
Only it lists the brushes that the selected objects' strokes use, each
once. document.info gives the names as brushNames, the panel's flyout
offers the category, and the text report that Document Info › Save…
and File › Package write has a BRUSHES section.
Docs: docs/mcp.md, docs/target-app-parity.md.
Commands that read the selection through edit::selected_roots leave
out an object whose group is also selected (edit::roots_of). Fourteen
places that read `ids` kept an object listed together with its group.
Given ids that list an object and a group that holds it, Make Repeat
failed with "no such object", New Symbol failed or stored the object
twice in the symbol, and object.transform moved it twice (20 pt for a
10 pt move).
These places now pass explicit ids through edit::outermost, which
drops an id whose ancestor is also listed, with the filter that
roots_of runs on the selection (now edit::without_inner). Nothing else
is dropped or replaced: unlike roots_of, it keeps layers and
compound-path members. A list without nesting gives the same result as
before. Commands that take both ids and the selection as listed, such
as paint.setFill without item, are unchanged.
Docs: docs/mcp.md, docs/target-app-parity.md.
An Intertwine group keeps its objects as they are, in their own stacking
order; each member can be drawn over the others in an area of its own.
The group draws, hits, saves and exports through its live expansion, so the
members stay editable and Release gives them back unchanged.
object.intertwine.arrange picks an overlap area by a click point or by a
closed path drawn around overlaps and toggles which member is on top
there, or brings a member to the front or sends it to the back where three
or more objects overlap.
Document Info › Objects counts the paths but didn't say how long they are,
which sign and print work reads there (an LED strip along the letters, a
cut line). `document.info` now adds up the length of every path it counts,
the pieces of compound paths included and guides left out, and returns it
as `pathLength` (pt); the Objects section shows it as Path Length in the
document's units, right after the Paths count, so Selection Only gives the
selected paths' length. The label is translated in the catalogs that
cover the menus; pt-br only takes strings the UI itself shows.
Rarely set fields move into one optional boxed NodeExtras, and large NodeKind payloads (images,
live shapes, blends, envelopes) are boxed. Every object, and every undo step that copies it,
shrinks: a 50k-path move keeps ~24.5 MB per step instead of ~40 MB. Files stay byte-identical
(Node keeps its flat JSON through a borrowed Serialize and a from-wire Deserialize, no flatten),
and loading is slightly faster. Undo and redo reuse their step's size estimate instead of
walking the document again (8.3 -> 5.6 ms for a 50k-path move).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VmMmc1J8XeNLxhRihWv9cc
# Conflicts:
# crates/engine/src/cmd/graph.rs
# crates/svg/src/export.rs
A font library can hold two versions of one family and style (a new
Montserrat-Bold.ttf beside an old montserrat.ttf). The font database kept
only the first one loaded, so type set in the other couldn't be matched
when a PDF or .ai was opened: it came in as outlines. Now every version
loads (the first stays the one family and style resolve to), PDF import
tries the other versions when the glyphs differ, and type set in a version
the family and style alone wouldn't pick names it in CharStyle::font_version
(left out when None, so documents without it are unchanged). Layout,
shaping, the substituted-glyph highlight, Find Font, Package and Document
Info follow it; changing the font clears it.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
File › Package and Document Info › Font Details looked fonts up with
FontDb::face and compared the face's family with the name the document
stores. A font a document named by another of its names (a PostScript
or localized name, as SVG and PDF files do) was reported as not
available and left out of the package, although the canvas drew it and
exports embedded it.
- Package and Font Details resolve fonts with FontDb::resolve, as
text.fonts and the renderer do. A style the family lacks is still
copied as its closest style; the report now names the style it
copies, and Font Details lists the font as substituted, with that
style's file and permission.
- FontFace::embeddable reads fsType as exports do (Embedding), so fonts
that allow bitmap embedding only (bit 9), or that set the restricted
bit together with reserved bit 0 (0x0003), are no longer copied.
Document Info's permission labels follow the same rule: when a font
sets more than one usage bit, the label names the most permissive
one.
- The Package dialog and its status line name the fonts it didn't copy.
File > Package (saved documents; unsaved changes are saved first) writes
<folder>/<name>/<document>.vectorcraft, the linked files in Links/ (relinked in the
packaged copy), the fonts its type uses in Fonts/ (leaving out fonts whose licence
doesn't allow embedding) and <document> Report.txt, then offers Show Package. Without a
folder (the web, agents) the same files come back as a zip.
Document Info's flyout picks one category (document, objects, styles, spot colours,
patterns, gradients, symbols, fonts, font details, linked and embedded images) and Save…
writes the text report Package shares.
Engine: file.package {folder?, name?, copyLinks?, linksFolder?, relink?, copyFonts?,
report?}; document.info gains category, format: text and sections. Text: FontFace
path, fs_type and embeddable. UI: ui.packageDialog (dialog `package`), file.showPackage,
docInfo.save.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A linked image (`ImageObject.link`, now a LinkInfo: absolute path, path relative to the document,
size, modification time, hash, page; old path strings still load) keeps a low-resolution preview
(`ImageBlob.proxy`, at most 256 px a side) that a native save writes in place of the pixels of
images only linked images show. Opening a native document reads the linked files again, looking
for each at its path, then relative to the document and by name in its folder: missing files
show their preview, modified ones are read again only with Update Links: Automatically.
`document.open` reports `missingLinks`, `modifiedLinks` and `updatedLinks`.
links.check reports each link's status, links.update reads modified files again and
links.relink points images at another file or at same-named files in a folder (each keeps its
bounds; one undo step). In the app, a document opened without its linked files asks about each
(Replace…, Ignore, Apply to All), then offers to update modified links when the preference asks.
The renderer caches previews apart from the file's pixels; the Eyedropper samples previews in
the object's pixel space.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The Appearance panel names the style a linked object uses and its menu offers Redefine
Graphic Style "name", which updates every object still linked (edited objects keep their
look and are unlinked). The Graphic Styles panel breaks links (button and menu), selects
all unused styles, sorts by name, deletes several styles, and opens Graphic Style Options
(rename; links follow) on double-click; New Graphic Style from the menu or with Alt asks
for a name. Select > Same > Graphic Style and Appearance Attribute work, and Document Info
lists the style names.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Document::swatches_iter/_mut, swatch_mut, swatch_group_of, remove_swatch and a copy-on-write
walk over linked solid paints (map_solid_paints) cover every colour group.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>