object.blend.spine.moveAnchor now refuses any supplied `with` (even an
empty list) together with `handle`. Direct Selection builds the blend
spine once when drawing the picked points and once per drag preview,
instead of once per picked point. Part of #5285.
Direct Selection kept only one picked point of a blend's spine. Shift-click
now adds a point of the same spine or takes it away, and dragging any picked
point moves them all. object.blend.spine.moveAnchor takes `with`, the other
points to move by as much, with the key objects on them, in one undo step.
Hovering looks up the bounds of every selected object, and each lookup
went through the memo key check, which compares the whole selection. That
made a hover quadratic in the selection: 1.5 s at 50,000 selected paths.
The walk now checks the key once and shares it across its lookups.
Part of #1280.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Extend vectorcraft-geom::shapes with clean-room open/pie/chord/arc ellipse and rectangle builders, per-corner radii, polygon/star corner rounding and deterministic vertex randomization, logarithmic/Archimedean spiral divergence and inner radius, and perspective/isometric 3D box face builders.
- Isolate 3D Box and customizable shape parameters as a VectorCraft add-on under crates/*/src/**/addons/:
- crates/tools/src/addons/box3d.rs (Box3dTool and CustomShape extras stored under Node::extras["vc-shape-tools"])
- crates/engine/src/cmd/addons/shapes.rs (addon.shapes.rectangle, addon.shapes.ellipse, addon.shapes.polygon, addon.shapes.star, addon.shapes.spiral, addon.shapes.box3d, and addon.shapes.configure)
- crates/ui-egui/src/addons/shapes.rs (Object > Plug-ins > 3D Box > 3D Box Tool and context-sensitive Control bar options)
- Keep crates/engine/src/cmd/create.rs, crates/tools/src/shape.rs, and crates/tools/src/draw2/family.rs byte-for-byte identical to main.
- Add translations for "3D Box" and "3D Box Tool" across all 26 .tsv catalogs in crates/ui-egui/src/i18n/.
A `backquote` given as a string or a number, on the request or on an
event, was read as absent, so `"true"` moved the object's geometry
instead of its pattern. `pointer_gesture` and `ui.pointer`, headless
and desktop, now answer with an error before any event runs.
Where two open paths lie along the same stretch, the planar map gave
that stretch to one of them only, so a merge or an erase across it left
the other path in place there. Every other open path along an edge now
has its own piece in `lines_under`, under a closed path's outline or
along a line in front. `lines`, `edges` and Live Paint's edges stay one
per stretch, and an Alt-click there still takes the piece in front.
Review of #5694 asked for two changes.
Add-on, not a core tool, as Enclosing Lasso is:
- The command is addon.contour.set, in an add-on module of its own
(crates/engine/src/cmd/addons/contour.rs) with its tests beside it.
- The tool is listed under Object > Plug-ins > Contour and under its own
"Contour" heading in All Tools. It has no Basic or Advanced toolbar
slot and no default shortcut. The Contour bar is unchanged.
- The add-on drawer test lists Contour with the other add-on tools.
- Docs (mcp.md, the parity documents, ROADMAP) say add-on and use the
new command name; mcp.md gains a Contour add-on section.
Translations: rows for "Contour", "Contour Tool", "Sharp", "Bake" and
"Turn the Contour into plain paths" in all 26 catalogs ("Round" and
"Square" already had them). Drafted from each catalog's own vocabulary
(for Bake, the verb it uses for Expand Appearance; a word other than the
catalog's Stroke or Path word for the tool's name where they collide);
they are not native-speaker reviewed.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Two fixes from review of #5694, each with a test that fails without it:
- Dragging a selected Contour sent the tool's own corner options, so a
Round or Square Contour came back Sharp and lost its miter limit, and
the Contour bar (which reads the effect) disagreed with the shape. The
press now reads the Contour's own corners and miter limit and every
preview of that drag carries them; a new Contour still takes the tool's
options.
- A drag that never moved the distance (along the edge, or rounded to
nothing by Shift) previewed offset 0 and committed an unchanged copy
and an undo step. Nothing is previewed until the distance leaves where
it started.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Add a Contour tool (Modify group). Dragging away from a selected path or
shape's edge makes a copy of it that carries a live Offset Path effect,
grown by the drag; dragging toward the inside shrinks it. The result is
one undo step and stays editable until baked with Expand Appearance. A
second drag on a selected Contour changes its distance instead of
nesting another effect.
- object.contour: the command behind it (offset, sharp/round/square
corners, miter limit), usable over MCP and the control channel too.
- Contour tool: live preview, Shift rounds to whole points, Escape
cancels, a dashed guide with a white halo shows the outline the shape
had, and a pill shows the distance.
- Contour bar: a floating bar above the selection with the offset box,
Sharp / Round / Square and Bake (Expand Appearance).
- Toolbar slot under Modify (Basic and Advanced) and dc-contour.svg, an
original icon with its ASSETS.md row.
- Tests for the command, the tool's pointer gestures and the bar; the
border-with-a-gap recipe (two Contours, bake, Minus Front) is covered
end to end.
- Docs: beyond-Illustrator row, revision histories and the ROADMAP log.
Beyond Illustrator: a VectorCraft design built on Offset Path. Scores and
estimates unchanged.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
An upright glyph in vertical type has its frame's up axis along its column, parallel to the
line, so Touch Type split no drag or arrow-key nudge into kerning and baseline shift and sent
no movement. Such a glyph now takes the line's cross axis, right of its column, as the way
baseline shift moves it.
The marquee's segment test built a two-anchor path for every segment and ran
hit::intersects_rect on it. It now skips a segment whose anchors and handles
all lie past one side of the marquee, and tests the rest directly with the same
bounds and edge checks, so it selects the same segments.
A marquee over 10,000 anchors, press to release (anchor_bench, median of 7):
one open path of 200,000 anchors 84.9 ms -> 24.1 ms, 2,000 closed paths of 50
anchors 27.5 ms -> 13.5 ms, one closed path of 50,000 anchors 14.6 ms -> 8.5 ms.
While the Type tool edits a frame of threaded text, Select All selects
the text of every frame of the story, highlighted in each frame. The
tool edits the first frame that holds text.
- Typing, Delete and Cut replace the whole story as one undo step
(`text.editRange` takes `clear`, the other frames whose text goes).
- Copy and Cut take the whole story (`text.getRange {id, story: true}`).
- Fills and strokes, `type.step`, `appearance.copyFrom`, the Character,
Paragraph, OpenType and text style panels, the Tabs panel's tab
stops, the font menus and the Justification dialog act on every
frame's text (`text.setRangeStyle {id, story: true}` styles them in
one edit).
- A caret move, a click or a word or paragraph selection ends it.
Select All in unthreaded type is unchanged.
Docs: docs/mcp.md, docs/target-app-parity.md.
Add Anchor Points builds the new anchor list in one pass, Swatch Library add looks names up in sets, full_documents dedups placed keys with a set, width profile lookups and mark insertion use binary search, and the symbolism tools cap and thin the previews of a long drag as Liquify does.
With Snap to Point alone, an anchor behind the start could pull the
projected end behind it, and the measurement read 180 degrees from the
pointer's step. Such an end is now turned back onto the pointer's step,
keeping its length, as an end rounded nearer another step is.
With a Constrain Angle other than 0, the grid point a Shift-drag's end
rounds to can lie nearer another 45-degree step, and the measurement then
reported that step. A Shift-drag from (0, 0) to (5, -3) with a 30-degree
Constrain Angle and a 9 pt grid measured -15 degrees instead of 30. The
end is now turned back onto the step nearest the pointer's direction,
keeping its length.
With one Objects on Path group of two or more objects selected, the
Selection and Objects on Path tools show a square Space widget beyond the
last object, ahead along the path. Dragging it moves the last object
along the path, around its bends, as far as the pointer moves along it,
and the objects between follow evenly while the first one stays. With
Alt (Option on macOS) the objects spread from both ends toward or away
from the center of an open path, or of the first anchor of a closed one.
The distance between the objects shows next to the pointer in the
document's units; the drag is one undo step, and Escape cancels it.
- object.objectsOnPath.options takes spacing (points, or "auto", the
default even spread) and start (points from the first anchor). A
spacing the path has no room for is drawn smaller and kept, so a
longer path brings it back. Older files read as Auto.
- Moving the group, Pivot, Rotate, path edits, copies and saving keep
the Space. Scaling, rotating or shearing the group keeps the first
and last objects where the transform takes them on the new path, live
shapes included; a value that cannot be kept that way scales with the
path's length.
- The Rotate All widget follows the first object when Space moves it.
Behavior: https://helpx.adobe.com/illustrator/desktop/manage-objects/arrange-objects/rearrange-and-edit-objects-on-a-path.html
and https://helpx.adobe.com/illustrator/using/objects-on-path.html.
The press picks the first object and selects it on the button-down. A dropped press now keeps
that pick with the selection, and still puts back the picks of earlier clicks.
A drag that takes a selected freeform gradient point out of the object previews its removal,
which deselects it. A dropped press now selects again the point that was selected once the
tool took the press, and Escape reselects a point dragged out and back inside the object.
Escape also clears state that earlier clicks set up, so taking Escape for a
dropped press lost it in five tools. Each now drops only the press:
- Blend: the object picked first and the blend being added to are put
back as they were at the press.
- Dimension: a dropped click picks nothing, and the points or lines picked
before stay; a dropped drag is canceled as before.
- Width: the drag ends and the width points selected at the press are
selected again.
- Gradient: a dropped click on a freeform gradient leaves the line being
drawn open.
- Selection: with the pointer loaded with text, a dropped press threads
nothing and the text stays loaded; a dropped press on a port loads none.
A dropped press on the Type tool no longer ends editing and switches tools:
the type being edited stays in editing, with the caret and selection it had
before the press, and the press does not count toward a double or triple
click. A dropped handle or move press with Crop Image puts the box back as it
was at the press and keeps earlier adjustments.
A dropped press (a long touch, a canceled touch, a second finger) now
goes to the tool through Tool::drop_press, which takes Escape as during
a drag by default. The Pen, Smart Pen and Curvature tools override it
so the path being drawn goes on: they forget the press, and a Curvature
point the press dragged goes back where it was.
The release that follows runs only the tool's Cancel and Notify actions,
so a Selection marquee selects nothing and a Shift-drag Artboard marquee
toggles nothing. The engine puts back the persistent options the tool
had at the press (the Polygon tool's sides changed with the arrow keys),
and stores none of them.
The Measure tool and the Measure & Inspect tool snapped the end point of
a drag without Shift, but with Shift held they only turned the pointer
onto its 45° step and kept its distance: with Snap to Grid on the
measurement ended off the grid, with Smart Guides on it did not land in
line with an anchor, and with no snapping a drag of (37.3, 12.1) measured
39.2 pt at 0°.
Both now project the pointer onto the 45° step nearest its direction and
snap it there as the Line Segment tool snaps a Shift-drawn end, so it
stays on the step: (37.3, 12.1) measures 36 pt at 0° on a 9 pt grid, and
37.3 pt with no snapping. With Snap to Point alone, the anchor the pointer
snaps to is projected onto the step instead, so the end lands on an
anchor on the step and in line with one beside it.
While a symbol with Enable Guides for 9-Slice Scaling on is edited in
symbol editing mode, the canvas draws its two horizontal and two vertical
guides as dotted lines across its art, with any tool and with ruler guides
hidden. With the Selection tool the pointer near a guide shows the Move
cursor, and dragging the guide sets it through `symbol.options`'s
`nineSliceGuides` as one undo step; Escape during the drag puts it back.
A guide within 4 screen pixels takes the press before the art and the
bounding box. A dragged guide stays within the art's box and stops short
of the opposite guide; positions outside the art are not supported yet.
The snap targets of a Shift-drag that starts on a highlighted Global Edit
match are gathered when the drag begins, for the selection with the match
added, before the first preview moves it. The first preview is now snapped
to the grid or to points, and later previews snap from the original
position.
A Shift-press on a highlighted object of the Global Edit waits for the release
to leave it out of the edit. A drag from it now selects it when the drag starts
and moves it with the selection, as a Shift-drag from an unselected object did.
The snap targets are gathered after the object joins the selection.
A match that sits inside a selected object is no longer highlighted, and a
Shift-click on it with the Selection tool deselects that object as before
instead of leaving the match out of the Global Edit.
While Global Edit is on, a Shift-click (not a Shift-drag) with the
Selection tool on a highlighted match, or on an object inside a matched
group, leaves that match out: it is no longer highlighted and later
edits leave it as it is. The object the edit started from stays in, and
Global Edit ends when fewer than two matches are left. Leaving a match
out is not an undo step.
- New command `select.globalEditExclude {id}` returns `{active, count,
ids}`; the Selection tool calls it on the release of a Shift-click.
- `ToolContext::global_edit` gives the tools the Global Edit's objects.
- Label and messages in the i18n catalogs; docs/mcp.md,
docs/ui-parity.md and docs/target-app-parity.md updated.
Source: https://helpx.adobe.com/ph_fil/illustrator/how-to/global-editing-sensei.html