A document or brush library file could hold two brushes of one name.
Renaming the first in Brush Options moved every stroke of that name and
left the second brush unreachable, deleting by name removed both, and
the Brushes panel could not select the second row.
Reading a stored brush library now keeps the first brush of a name as
stored and numbers each later one with the first "Name 2", "Name 3" and
so on that the file does not already have. Strokes name their brush,
and a name always found the first brush, so every stroke keeps drawing
the brush it drew before. The rule applies to opened documents and to
brush library files; brushes added to a document that already has the
name keep today's numbering.
Docs: docs/mcp.md, docs/target-app-parity.md.
The profiles Edit > Assign Profile gives a document stayed the active
color settings after another document came to the front, so a new,
opened or switched-to document drew and converted its colors through the
previous document's profile, and closing the last document left it in
use.
The session now puts the front document's profiles in use (the working
spaces where it has none, or no document is open) after a new or opened
document, a tab switch, a close, File > Revert, every command including
each batch step and Undo or Redo of Assign Profile, a failed batch or
plug-in call, a script's rollback and slice boundaries, a canceled
preview, undo group or undo scope, and for each document Export All Open
and the update of placed documents work in. The active settings are
rebuilt, and the documents redrawn, only when they change.
document.export and document.serialize to .ai with useArtboards: false
wrote the one page of the visible art, but embedded the one-artboard
stand-in as the native document and as the editing copy for other apps.
Reopened, the file replaced the document's artboards with one artboard
around the art.
- The .ai of the art's bounds now leaves out both editing copies and
returns the warning "Preserve editing was left out: an .ai file of the
art's bounds would replace the document's artboards when reopened",
as the PDF of the art's bounds does.
- useArtboards: false with pdfCompatible: false is refused, with or
without editingData, since the file would have blank pages and no
editing copy.
- Save, Save As, Save a Copy and exports of the artboards keep both
copies. Legacy version 7 .ai files are written as before.
Docs: docs/mcp.md, docs/target-app-parity.md, document.export params.
$.fileName gave the file being run, so a function defined in a file
that #include inserted, in a file $.evalFile ran, or in an earlier run
of a named engine reported the calling file instead of its own.
- vectorcraft_js: HostItem::SiteGetter gives a getter the CallSite
(source tag, line, column) of the code that reads it.
- $.fileName maps that place through the run's source maps, or the
maps a named engine kept, to the file the code is in. It is empty in
code from a script given as source and in kept code whose map was
dropped. Code that eval or Function compiled still gets the file
being run.
Docs: docs/mcp.md, docs/target-app-parity.md.
A Fit to Artwork Bounds step of `command.batch` that names neither
`index` nor `indices` now fits the artboards the Artboard tool has
selected when the step runs (two or more), as the command does when the
app runs it on its own. Before, the step took the batch's `artboard` as
its `index`, so an action played from the Actions panel fitted only the
active artboard while several were selected.
- A step's own `index` or `indices` is kept, and the batch no longer adds
an unused `index` to a step that names `indices`.
- The batch's journal entry records the `indices` the step took, so a
replay fits the same artboards. An action leaves them out and fits the
artboards selected when it plays.
Docs: command.batch params text, docs/mcp.md, docs/target-app-parity.md.
- With art, the bar is 10 pt tall and the Edit tab leaves out the gaps
above the wheel and above the sliders. The dialog is as tall on the
Edit tab as on the Assign tab, and all of it but the color chips fits
a 1024 by 576 screen.
- recolor.weigh counts a use for the first row that is not excluded
when an excluded row lists the same color first.
Insert Menu Item… now lists the Object › Align items and the View menu
commands the app runs itself (Outline, Pixel Preview, Trim View,
Presentation Mode, Screen Mode, zoom, fit, Rotate View, and the show,
hide and snap items).
- An Align step holds the params its click sends at insertion, so a
later Align To choice does not change it. A step that aligns to the
key object stops the playback when the selection has no key.
- A View menu step plays in its place at every speed and adds no undo
step. At Accelerated the steps on each side of it are one undo step
each. Playing it while recording records it.
- Batch… refuses an action with an included View menu step.
- An action set file with a View menu step is version 6.
- The steps before a stop now play as saved steps, as other playback
does, so a key that an older version recorded no longer fails there.
Docs: docs/mcp.md, docs/target-app-parity.md.
- recolor.weigh drops another row's entry for a color that moved, so
recolor.apply recolors it with the row it moved to and the shares
describe the recolor. A color that the first color of another row
with a new color also lists stays where it is.
- Linked swatch colors are grouped through a map, so a row with many
unlinked colors no longer compares each one with every group.
- The Prominent Colors bar reads the shares again when a row gains or
loses a new color, since that changes which row takes a shared color.
With Real-time Drawing off, a command that ends a drag first (Undo, Redo,
Clear History, a plug-in command and the others) applies the drag's
deferred preview, but dropped the warning that preview gave, which
releasing the drag shows in the status bar.
- The applied preview's warning is now kept while a top-level command or
the tool's actions run. A command's result carries it as
`previewWarning`, and as `warning` when the command has no warning of
its own, so the status bar shows it.
- Typing kept as its own step when a tool's drag begins, or when Cmd
lends the Selection tool, shows the warning in the status bar.
- The Cmd-lend path no longer ignores an error from keeping the typing.
Docs: docs/mcp.md (undo/redo row), docs/target-app-parity.md.
learn.skills {} shows the Learn panel on its Skills tab with the list of
skills, with no skill and no tutorial open, and returns what learn.list
returns. Back to skills after a skill's last tutorial and the Quick skill
guide card on the For you tab now run it, so the control channel and MCP
can reach the same view.
- The command is listed in both UI command catalogs, and its label has a
row in every catalog.
- Docs: docs/mcp.md, docs/target-app-parity.md, docs/ui-parity.md.
A toolbar made with New Toolbar now docks in a lane along the window's
left or right edge (on the left, right of the Tools panel docked there).
Dropping its title bar on an edge docks it, with the target lit while
the title bar is dragged over it; dragging it out of its lane floats it
under the pointer, and Escape or losing the window's focus during the
drag puts it back. The title bar's context menu has Dock to Left, Dock
to Right and Float Toolbar.
- Toolbars docked at one edge stack from the top, each with an equal
share of the lane's height, and the lane is as wide as its widest
toolbar. A lane too short for its stack wraps it into more columns,
up to half the width beside it; past that the toolbars show only
their title bars, a lone toolbar included, and a column too short
for those scrolls with the mouse wheel.
- With Keep Tools Beside the Canvas on and Tools docked on the left,
the left lane is laid out inside the canvas panel right of Tools, and
the canvas keeps room for one column of it and its 200 points.
- A release in the frame the pointer leaves the lane floats the toolbar
with its corner where the drag put it.
- window.toolbar.dock {name, side?, order?} and window.toolbar.float
{name, x?, y?} do the same from the control protocol; bad params are
errors and change nothing. window.toolbar.list reports floating, side
and order.
- CustomToolbar keeps dock (place in the edge's stack) and dock_right;
both default, so toolbars saved before load floating. Workspaces and
preferences keep the placement; New Toolbar still starts floating, a
copy floats, and deleting a docked toolbar closes up its stack.
- Dock to Left, Dock to Right, Dock Toolbar and Float Toolbar have rows
in every catalog.
Part of #1759
A top-object envelope gives each piece of a side a share of the content
in proportion to its control polygon's length. When anchors split a
curve without changing its shape, the pieces' polygons don't divide the
side where the curve's own parameter does, so the envelope bent its
contents differently although its outline was the same: Add Anchor
Points on a top object moved the art, and a top object whose .ai mesh
saves each side's curve split into thirds drew its type up to about
half a point off its drawn art, which follows the whole curve's
parameter.
Coons::from_top_object now checks whether a side's pieces, from corner
to corner, are all pieces of one cubic. The pieces' spans of that
curve's parameter come from the handle lengths either side of each
split, the curve from the outer ends and handles, and every piece must
lie within 0.02 pt of the curve's piece over its span (each control
point). Such a side runs along that curve, by its parameter. Any other
side keeps the polygon shares, including a side only partly made of one
curve and a smooth side drawn in many pieces that isn't one curve as a
whole. Corners found from the outline can still move when anchors are
added, as before. Gradient meshes made from a path are unchanged.
Existing top-object envelopes with such sides redraw.
a_split_curve_moves_the_top_object_share_to_its_new_anchor, which
pinned the earlier behaviour, becomes a_split_curve_keeps_the_top_object_patch.
Tests: a_split_curve_keeps_the_top_object_patch,
a_top_object_joins_a_split_curve_saved_with_rounded_coordinates,
a_top_object_keeps_smoothly_joined_curves_apart,
a_top_object_side_partly_of_one_curve_keeps_the_polygon_shares and
a_top_object_side_of_many_arcs_stays_on_them (vectorcraft-doc),
envelope_top_object_keeps_its_look_when_anchors_are_added
(vectorcraft-engine) and
a_top_object_whose_top_is_one_curve_split_in_thirds_opens_live
(vectorcraft-eps).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Control bar > Snapping > Pixel Snapping Options... opens a dialog with
three checkboxes: Snap to Pixel While Drawing, While Moving and While
Scaling. OK sets them; Cancel leaves them as they were. While View >
Snap to Pixel is off, the dialog notes that the options take effect once
it is on.
- view.snapToPixel.options {drawing?, moving?, scaling?} reads and sets
them. They are kept in the preferences as the pixelSnap group, all on
by default, so turning Snap to Pixel on behaves as before. An unknown
key or a value that is not a boolean is refused and changes nothing.
The command has a parameter schema, which raises the API level to 4.
- Drawing covers points the drawing tools place, the Knife's straight
cut, the Measure tool and the rulers' origin. Moving covers Selection
and Direct Selection moves, ruler guides, artboard moves and the
Rotate, Reflect and Shear tools' drags. Scaling covers bounding-box,
Free Transform, artboard and slice handles and the Scale tool's drag.
An edit whose option is off snaps as it does with Snap to Pixel off.
- Align New Objects to Pixel Grid and the objects' pixel-aligned
property do not depend on these options.
Docs: docs/mcp.md, docs/target-app-parity.md.
A paragraph whose characters differ in line metrics (type size, font,
leading, vertical scale, or an inline graphic taller than the text) was
broken with the Single-line Composer in area type of a shape other than
a rectangle, or with text wrap. The every-line composer now composes it
there too.
- The composer takes each line's width from a measure that follows
where the lines above it went (`composer::Measure`,
`compose_with`). The fixed widths by line number are one such measure.
- In a frame whose lines are not all as wide, each line the composer
tries is placed from the pen the lines above it left, at its own
tallest metrics, as the line loop places it (`layout/shaped.rs`).
Starts with the same placement are shared, and each start keeps the
placements it was tried with.
- A line too long for its room does not end the search from its start
while a glyph after it could make the line taller and set it lower,
where the frame may be wider.
- The line loop places a composed line in such a frame at the line's
tallest metrics, so it gets the room the composer measured for it.
- The search for one paragraph stops after 1,000,000 lines tried or
2,000,000 baseline steps. The searches of all the paragraphs of one
frame share a budget of 2,000,000 lines and 4,000,000 steps, kept
apart from the line loop's own steps. A paragraph whose search stops
is broken line by line. A paragraph the frame has no room for is
broken line by line too, and overflows as before.
Tests: crates/text/src/tests/combos.rs (a stepped frame, a frame that
widens, text wrap with two spans on a baseline, overflow, a long
paragraph) and crates/text/src/layout/wrapping_tests.rs (the composer
with a measure, and the shared search budget).
A right-click on a character style in the Libraries panel now opens Apply
Character Style, Add to Character Styles, Move to Group, Rename… and
Delete. Apply is enabled only with type selected. Opening the menu applies
nothing, and the paragraph style menu is unchanged.
- library.addToCharacterStyles adds the style to the document's character
styles without applying it, so no type needs to be selected. A document
style with the same name and attributes is reused with no undo step, and
a name taken by other attributes gets a number.
- library.renameItem renames a library item in place and keeps its group.
The name is trimmed and has 1 to 256 characters. Another item of the same
kind with that name is an error, the item's own name writes nothing, and
a rename is not a document undo step.
- library.use and library.addToCharacterStyles compare a library style
with the document's in the form the document stores it in. A whole
number size from a library file no longer adds a numbered copy.
- A character style color linked to a swatch that is not a global or spot
swatch of the document keeps the color it shows without the link.
Before, adding or applying such a style failed with "no swatch".
Help page: https://helpx.adobe.com/illustrator/desktop/design-with-text/fonts-and-scripts/add-and-use-text-and-character-styles-in-libraries.html
Under a tutorial's steps, View more opens the tutorial's practice sample
as a new untitled document, which becomes the active one; open documents
stay as they are, and Save asks where to save the copy. Each of the 12
tutorials has its own small SVG drawing in panels/learn/samples.rs, read
only when View more is pressed.
Once the sample is open, Finish tutorial marks the tutorial finished.
A finished tutorial shows Next Up with the next tutorial's title in the
same skill, and Next Up shows that tutorial without opening its sample.
After a skill's last tutorial the panel says so and shows Back to
skills; Next Up never moves to another skill. Finished tutorials are
kept while the app runs; the skill rings and counts do not show them
yet. The help page's short video is not part of this change.
- learn.openSample, learn.finish and learn.next run the three controls
and are listed in the UI command catalogs; a missing, non-string or
unknown tutorial id, or a step out of order, is an error and changes
nothing.
- New labels and messages have rows in every catalog.
- Docs: docs/mcp.md, docs/target-app-parity.md, docs/ui-parity.md and
the ASSETS.md line for art generated in code.
With art selected, the Edit tab shows a Prominent Colors bar under the
wheel: a part for each row in its new color, as wide as the row's share
of the art, the largest first. Dragging the edge between two parts moves
width from one to the other; when the drag ends, the rows' current
colors move toward the new widths and the art previews the result. OK
keeps the recolor as one undo step.
- recolor.weigh {map, weights?, ids?} returns each row's share of the
uses of the art's colors and, with weights, the rows with their
current colors moved: one color at a time between rows that have a
new color, while a move brings the shares nearer the weights, the
color nearest in Lab to the row it goes to first. A row keeps its
first color, the tints of one global swatch move together, colors
that stay keep their order, and the command changes nothing. A use
counts for the row recolor.apply recolors it with, and the work is
bounded at 50,000,000 color-by-row comparisons.
- The New Color Group menu beside the link button has Save All Colors
(the new colors in row order) and Save Prominent Colors (the bar's
colors in its order); each saves a color group as its own undo step.
- The dialog's weights field drives the bar from ui.dialog.set. A new
Colors count drops it.