Commit Graph
6 Commits
Author SHA1 Message Date
dotCooCoo a5ea3a8002 Use Preview Bounds: a handle drag keeps the opposite visible edge in place
With Use Preview Bounds on, a bounding-box handle drag scaled the art by
the ratio of the visual box, so margins that stay (a stroke with Scale
Strokes & Effects off, an Offset Path reach) or scale by another factor
moved the opposite visible edge: dragging the right edge of a square with
Offset Path 10 from 210 to 310 left its left edge at 98.33 instead of 90.

The Selection tool now previews object.setBounds with the dragged visual
size and the opposite handle (with Alt, the center) as the reference
point, so the scale is solved from the geometric box and the margins the
visual box adds, for strokes with Scale Strokes & Effects on or off and
for geometry effects. Shift and Alt drags follow the same rule; a drag
that flips the box, and one with anchors selected, still scale by the
matrix. A previewed object.setBounds runs as object.transform with the
transform it finds, so Transform Again repeats the drag and the journal
holds that transform. The drag transforms a path of a compound path
selected on its own, as object.transform does, and leaves the art at
least 1e-4 of its width and height.
2026-10-21 17:11:08 +07:00
dotCooCoo d532e6d341 Use Preview Bounds: a clip group is measured where its clipping path's stroke paints
The renderer clips a clip group by its clipping path's geometry before
the path's geometry effects, and paints the path's strokes over the
clipped art without clipping them, with those effects. With Offset Path
on a stroked clipping path, the stroke paints along the offset shape
while the group was measured by the path's own stroke.

With Use Preview Bounds on, a clip group or layer whose clipping path
has strokes with geometry effects is now measured as the clipping
path's geometry and those strokes as drawn, in the Transform panel, the
bounding box, Align and Distribute. This holds inside groups and for a
clip group with a fill or stroke of its own. A clipping path
without a stroke still measures as the region it clips to, and a hidden
one adds no stroke.
2026-10-21 17:11:08 +07:00
dotCooCoo 9f31471042 Use Preview Bounds: the selection tools measure the selection once per revision
With Use Preview Bounds on, every hover frame's cursor and every
pointer move measured the selection again, and with Smart Guides on
each selected object too, evaluating their geometry effects each time.

The session now keeps a PreviewMemo, which ToolContext::preview_memo
passes to the tools. selection_bounds, selection_box and the object
bounds that Smart Guides find centers in while hovering read it. The
memo holds the measurements for one key: the document's uid and
revision, the selected objects and Use Preview Bounds. A new key
replaces them. VectorcraftApp::selection_box in the UI keys on the
uid, the revision and Use Preview Bounds. A ToolContext without a
memo measures on every call.
2026-10-21 17:11:08 +07:00
dotCooCoo 1267efbcf9 Use Preview Bounds: objects are measured with their geometry effects
With Use Preview Bounds on, the bounding box, the Transform panel,
Align, Distribute, Distribute Spacing and object.setBounds measured
each object without its geometry effects. A square with Offset Path
10 measured as the square, and type with Outline Object measured by
its layout box instead of its glyphs.

The new vectorcraft_effects::preview module measures objects as they
are drawn. A path is measured by its effected shape, with the
geometry effects of each fill and stroke that paints. Type, images,
live objects and symbol instances are measured by their reshaped art.
A group or layer with geometry or Pathfinder effects, or with a fill
or stroke of its own that has geometry effects or paints members with
geometry effects, is measured by its evaluated art. A blend, envelope
or repeat whose objects have geometry effects is measured by its
evaluated art, with those objects measured after their effects. Raster
effects are not measured. In one object, the art of at most 4,096 symbol
instances is measured with its geometry effects, and the other
instances are measured without them. With Use Preview Bounds off, the
measures are unchanged.

object.setBounds sizes objects with geometry effects by measuring
them after each scale it tries, so type with Outline Object set to
100 pt wide gets a glyph box 100 pt wide.

Selection::anchors_box is split out of Selection::anchor_bounds. The
doc comment of VectorcraftApp::selection_bounds said that it includes
effects; it now says that it leaves them out.
2026-10-21 17:11:08 +07:00
dotCooCoo d9bd9b134d Symbols: instances of imported symbols are measured by their art
Every symbol instance was measured as its transform applied to the
20 × 20 square around the origin, which symbols made in the app keep
their art in. The SVG and DXF importers keep symbol art as drawn, so
the box of an instance of an imported symbol did not match its art.
The SVG Star instance at x 20, y 30 draws from (20, 30) to (40, 50)
and was measured from (10, 20) to (30, 40). Align moved such an
instance by the wrong amount, clicks and marquees beside its art
selected it, and the canvas, exports and prints left it out when its
art reached the view or the page and the square did not.

An instance is now measured by its symbol's art, which
Document::symbol_boxes looks up in the document each time
(Node::geometric_bounds_with, visual_bounds_with and
reach_bounds_with). With Use Preview Bounds on, the strokes in the art
count at their own weight, as the canvas draws them, and
object.setBounds counts them at that weight when it sizes an instance
or an object that holds one. When strokes do not scale and a width or
height of 0 or more is smaller than what a path's stroke adds,
object.setBounds now gives the path no width or height, as it does
for an instance whose art has strokes; before, it mirrored the path.
With Use Preview Bounds on, object.setBounds now measures the margins
that strokes add object by object, the members of groups and the
objects in symbol instances' art included, and solves for the width,
height and reference point asked for when the width and height are 0
or more. Before, it measured the margins of the whole selection and
could miss the size or the reference point asked for when strokes did
not scale and the objects' strokes added different margins, and when
strokes scaled and the width and height were out of proportion, even
for one path. A clip group, a Shaper Group, a compound path, type, and
a group or instance with effects or an opacity mask of its own are each
measured as one object, and so is an instance in perspective or one
turned or slanted relative to the bounding box, other than by quarter
turns. When the selection holds more than 4,096 objects to measure this
way, each selected object is measured as one. Instances inside symbol
art are measured by their own symbol's art. An instance is measured as
the square when its symbol is missing, when its symbol or a symbol
nested in its art holds an instance of itself, and when symbols nest 32
deep in its art.

Align and Distribute, the Transform panel, the bounding box and the
selection outline, clicks, the marquee, document.inspect and
document.node, Fit to Artwork Bounds and Fit to Selected Art, canvas
culling, thumbnails, the SVG filter region of an instance with a
raster effect, raster effect images, Export Selection, the SVG of an
artboard, printing, and the PDF, EPS, EMF/WMF and DXF writers use the
new box. The renderer also culls an instance by the effects and
brushed strokes in its art, and it culls a blend, envelope or repeat
by the brush art of what it holds and the effects in the art of the
instances in it. It culls an instance with geometry effects of its own
by the effects in its art after those geometry effects reshape the art.
It measures the effects in a symbol's art once for each symbol and
linear part of the transform that places it. For symbols whose art
holds instances, it measures at most 4,096 placements a frame, and at
most 4,096 more for each pattern tile it rasterizes and each placed
document it draws. Past that, it estimates the reach from the symbol's
reach with no transform, which it measures once. When the drawn
document's symbols change, the renderer drops the cached bounds of the
instances and of the objects that hold them.

The PDF and EPS writers, the SVG of an artboard and Skip Blank
Artboards grow the box of an instance whose art holds brushed strokes
by 16 times the widest stroke (at least 1 pt) of the objects in that
art that have a brushed stroke, plus 8 pt, as the renderer grows the
cull bounds of a brushed path. They keep an instance whose brush art
reaches the page. The SVG of an artboard also keeps an object that
holds an instance when what the canvas paints for it, the effects in
the symbol's art and the instance's own included, reaches the artboard.

Not yet: other commands that measure objects, such as Select › All on
Active Artboard, Transform Each and Convert to Artboards, still measure
an instance by the square.

Docs: docs/mcp.md, docs/target-app-parity.md.
2026-10-14 04:56:30 +07:00
bflatasticandClaude Opus 5.5 65f0f34cd3 M3.67: Use Preview Bounds measures strokes in transforms, the bounding box and Align
With Use Preview Bounds on, the Transform panel, Properties and Control bar
X/Y/W/H, the Selection tool's bounding box, Align, Distribute and
Distribute Spacing measure visual bounds (the whole stroke). setBounds sets
the visual box, scaling the path so that kept or scaled strokes land on
the typed size. object.align/distribute/distributeSpacing take
bounds?: "preview"|"geometric"; the Align flyout item shows and toggles the
preference through prefs.set.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-05 03:59:37 +07:00