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.
The params docs now state the direction (and the zero) of each angle or
rotation a command takes; behaviour is unchanged. Shape creation, text.create,
the grids, add-on shapes, saved views, Liquify, Puppet Warp pins, Mirror and
Radial Repeat and Vector Halftone turn clockwise; text character rotation,
gradients, the eraser tip and print screen angles turn counter-clockwise.
view.saved.new's rotation note changes its schema, so the API level goes to 3.
A test walks every command's params doc and fails when a param named like an
angle or rotation doesn't say clockwise or counter-clockwise.
With Measure Type by Glyph Bounds on, point type is measured by its
glyph outlines and its underline and strikethrough bars, as the canvas
draws them. A typed W or H gives what is drawn that size, and underlined
or struck-through spaces are measured by their bars instead of the em
box.
The texts now say that each point type object selected as an object
(not inside a selected group) is measured this way, that moved type
snaps by its ink box, and which Arrange Tools commands follow the
option: Swap Objects, Replace with Top Object, Set Size of Each and
Sort Objects. Arrange in Grid and Group Overlapping Objects keep
measuring visual bounds.
Measure Type by Glyph Bounds (`typeGlyphBounds`, off by default) is in
Preferences > Type > Glyph Bounds and the Transform panel menu. With it
on, the bounding box, the Transform, Control bar and Properties X, Y, W
and H, `object.setBounds`, the transform tools' reference point and the
Arrange commands measure point type selected on its own by the ink of
its glyphs instead of its em box. A typed W or H scales the live type
until its ink has that size.
- The engine caches each type object's ink in text space with its
layout bounds; the cache is not saved.
- Use Preview Bounds adds the characters' strokes, and type with
geometry effects is measured as drawn. Skewed type is measured by its
outlines.
- Type that draws nothing, area type, type on a path and type inside a
selected group are measured as before. Align and Distribute keep
following Align to Glyph Bounds.
Docs: docs/mcp.md, docs/control-protocol.md, docs/target-app-parity.md,
object.setBounds params text.
With Use Preview Bounds on, the visual box of a butt-capped stroke on an
open path grew by half the stroke weight past each end of the path, where
a butt cap paints nothing. A 2 pt vertical line set to H: 10 mm in the
Transform panel drew about 9.3 mm long.
The box of an open subpath with butt caps no longer reaches past its
ends. A straight segment's box comes from the four corners of its stroked
rectangle, and a curve's box comes from the stroke at its ends and where
its tangent is square to an axis. Bevel joins, and miter joins the limit
bevels, are measured by the stroked corners, and round joins by the arc
they paint outside the turn, instead of half the weight all round. Round
and projecting caps, arrowheads, closed paths and miter tips measure as
before. Two cases can still measure larger than the stroke paints: a
curve that bends more tightly than half the weight, and a butt-dashed
path whose first or last dash is a gap, which is measured to the path's
ends.
A horizontal or vertical butt line now measures one stroke weight less
along its length in W or H, and Align places it by its end points. A
slanted line's box shrinks by less: the stroke's corners still reach
past the end points across the line. object.setBounds measures as drawn,
after each scale it tries, a butt-capped open path with a segment at a
slant, symbol instances' art included.
Commands that read `id` and otherwise act on the selection, the highlighted
layer row or a new object read it with a lenient helper, so `{"id": "abc"}`,
`true` or `{}` acted on the selection instead. They now read it with
`object_param`, which refuses any value that is not a non-negative integer
with "`id` must be a whole number" under the command's name and changes
nothing; an omitted or null `id` keeps the default.
Commands: object.isolate, layer.locate, layer.releaseToLayers,
graphicStyle.new and redefine, charStyle and paraStyle new, apply and
redefine, image.info, links.info, links.goTo, links.unembed, shaper.release,
shaper.expand (whose errors now carry their own name),
transparency.editOpacityMask, transparency.viewOpacityMask, symbol.edit, the
object.blend.spine commands, path.curvature and the type commands that read
type ranges.
object.envelope.makeWithWarp, resetWithWarp and options read `style`
and `orientation`, and options read `preserveShape`, as text and
ignored any other value, so `{"style": 5}` kept the default style and
`{"orientation": "diagonal"}` kept the current orientation. They now
return "`style` must be a string" or "`preserveShape` must be a
string" for a value other than text or null, and "`orientation` must
be one of horizontal, vertical" for any other orientation, through
the shared `choice` helper. object.envelope.options checks the warp
keys whatever is selected, so a call with no envelope or only mesh
envelopes selected gets the same errors, an unknown style name
included. Omitted and null values keep today's defaults.
Docs: docs/mcp.md, docs/target-app-parity.md.
An object opacity or blend mode set on a path directly in a graph series, and
the blend mode of its topmost visible fill or stroke, were lost when the graph
was drawn again. The graph now stores them per series next to the row opacity
it already stores, and puts them on every path directly in the series when it
draws the series again.
- transparency.set and object.setProps store the object's opacity and blend
mode. A value the mark already has still replaces the value another mark of
the series stored.
- appearance.clear, appearance.transfer, appearance.copyFrom with Transparency
picked up, graphicStyle.apply without add and graphicStyle.redefine store
the object's opacity and blend mode they leave on the mark.
- The other Appearance and style commands store them when they change them
on a mark.
- Every command that stores the opacity of the topmost visible fill or stroke
also stores its blend mode. A Filled Lines band's outline takes the stored
stroke opacity and blend mode and keeps its black 0.25 pt stroke.
- An opacity and blend mode are stored as a pair from the edited mark:
setting only the opacity of one mark also stores that mark's blend mode.
- A graph design's copy in a series keeps its own values.
Docs: docs/mcp.md, docs/target-app-parity.md.
symbol.edit checks the new placement before it ends the symbol being edited, so a call with an out-of-range x or y fails and leaves the current edit open. While a symbol is edited, object.isolate refuses art outside the editing layer, and object.exitIsolation goes back to the editing layer only from a group inside it; from any other isolation it leaves symbol editing mode.
Ungroup multiplied each member's opacity by the group's, so a member of a
50% group stayed at 50% after the group was gone, and members that
overlapped showed through each other. Each member now keeps its own
opacity, and the group's opacity is removed with the group.
A built-in add-on in Object › Plug-ins › Arrange Tools (#4830, #4831, #4832, #4833, #4834):
- addon.arrange.grid lays the top-level selected objects out in rows and
columns, a row or a column (stacking order from the back, visual bounds,
each object centred in its cell), from the selection's top-left or
centred on the artboard.
- addon.arrange.swap swaps two objects' bounds centres, and with `size`
their widths and heights.
- addon.arrange.replace puts a copy of the topmost selected object centred
on each of the others, in its stacking place, kept, stretched or fitted
in proportion; the replaced objects are deleted unless `keep`.
- addon.arrange.size gives each selected object an exact width and/or
height about a reference point.
- addon.arrange.zoomSelection (a UI command) fits the active view to the
selection.
Places and sizes are measured as object.setBounds measures them (its
transform, now also available per object), strokes scale as Scale Strokes
& Effects says, each command is one undo step, and Arrange in Grid,
Replace with Top Object and Set Size of Each open previewed dialogs.
Catalog rows, command sweep cases, docs/mcp.md, parity docs and the
ROADMAP progress log.
Path Precision Tools gains two tools, kept out of the toolbars (All Tools
drawer and Object › Plug-ins › Path Precision Tools, no shortcuts):
- Corner Tool (cornerTool): editable corners on any path through the
existing Live Corners. Hover shows an eligible anchor, a click cuts a
corner with the tool's radius and kind, a drag sizes it (Shift: whole
values), a corner's marker selects it and loads its values, resizes it
and removes it at 0 or on a double-click; a corner never grows past
what fits; an Alt-marquee cuts every eligible anchor inside.
- Corners section in the Anchor Inspector: radius, kind, selected count,
Apply to Selected Anchors.
- Slide Anchor Along Path (slideAnchor): a drag runs an anchor along its
curve, the neighbouring segments refitted by the keep-shape kernel;
Shift snaps where the tangent is a multiple of 45° from the constrain
angle.
- Commands addon.pathtools.cornerSet, cornerRemove and slideAnchor, one
undo step each, params validated and covered by the command sweep.
- Cursor stand-ins, catalog rows in every language, docs and tests.
Enter Isolation Mode worked while an opacity mask was edited, and Edit
Opacity Mask and View Opacity Mask worked in isolation mode, so each
mode replaced the other's isolated art. In the reference app, isolation
mode can't be entered while a mask is edited, and mask editing can't be
entered in isolation mode.
object.isolate and perspective.editText, which shows type in isolation
mode, are now off while an opacity mask is edited, and a call returns
an error that ends "stop editing the opacity mask first". In isolation
mode transparency.editOpacityMask and transparency.viewOpacityMask are
off, and transparency.makeOpacityMask refuses one target, an object or
a layer, which it would take into mask editing; a call returns an error
that ends "exit isolation mode first". Make Opacity Mask with two
objects still masks one with the other. Pattern editing mode does not
count as isolation mode for these commands.
Object > Perspective > Edit Text, the canvas context menu and the
Transparency panel's menu and Make Mask button follow the commands'
enablement. A click or Alt-click on the mask thumbnail in isolation
mode shows the error and does not edit the mask. While a mask is
edited, the Contextual Task Bar leaves out Isolate, and the Properties
panel's Quick Actions leave out Isolate Group.
Docs: docs/mcp.md, docs/target-app-parity.md.
The reference app disables its Lock, Hide and Show All menus in
isolation mode. In VectorCraft every item of Object › Lock and
Object › Hide, Unlock All and Show All worked there.
In isolation mode, object.lock, object.lock.above,
object.lock.otherLayers, object.hide, object.hide.above,
object.hide.otherLayers, object.unlockAll and object.showAll are now
off. Their menu items are greyed out, and a call returns an error
that ends "exit isolation mode first". The Contextual Task Bar's
Lock button is greyed out too, and the Properties panel's Quick
Actions leave out Lock. Pattern editing mode and opacity mask editing do not count as
isolation mode for these commands. The check is outside_isolation in
cmd.rs, with has_selection_outside_isolation beside it.
Docs: docs/mcp.md, docs/target-app-parity.md.