An unlinked aligned dimension that was reflected on its own kept its
offset, which is measured along the left normal of a to b. A reflection
turns that normal to the other side, so a line 30 pt above two level
points stayed 30 pt above them after a flip top to bottom instead of
going below them. The offset now changes sign when the transform
reverses orientation, as a reflection or a scale by a negative factor
does. Other transforms leave it as before, and linked, horizontal and
vertical dimensions keep their own rules.
Docs: docs/dimensions.md.
With Cmd (Ctrl) held, the Bucket's presses go to the selection tool Cmd
lends, but the double-click and triple-click that follow reached the
Bucket and painted. They now paint nothing, as with Alt.
Expand kept a face only when its topmost fill had paint, and an edge only
when its topmost stroke had paint and a weight. A face or edge drawn by a
lower row under an unpainted top row was removed, and one whose only
painted row was hidden was kept as a visible path.
Expand now keeps a face or edge when it is shown, its opacity is above 0,
and any fill or stroke row is shown, has paint and an opacity above 0 (a
stroke also a weight above 0), with all of its rows. The rows are checked
with the new Appearance::has_drawn_fill and has_drawn_stroke.
Merge carried a face's topmost fill paint by the same topmost-row test.
It now carries every row of each face that draws by this rule, and of
each edge, pins their unplaced gradients to the old outline as
repaint_from does, and leaves the strokes' pen pressure, tilt, bearing
and rotation behind, since the rebuilt parts are other paths.
Docs: livePaint.expand params text, docs/mcp.md, and a line in
docs/target-app-parity.md, which also drops a repeated Live Paint
Selection marquee line.
A triple-click whose clicks land on a face, another face, then the first
face again matched the fill the first click gave that face. It now
matches the fill the face had before the first click that painted it, as
the tool's doc comment and docs/mcp.md say.
- With Space held for the view tools, the Live Paint Bucket outlines no
face or edge, as a press there paints nothing.
- A scoped livePaint.fill or livePaint.strokeEdge where every face or
edge reached already has the paint records no undo step; a test covers
it, and one where only some faces need the paint.
- An MCP test drives the bucket through ui.pointer with mods.space.
- The tool's doc comment and the progress line state the rule.
A required index given as something other than a whole number of 0 or
more, such as "3", 2.5, -1 or true, was reported as missing: `anchor` of
path.setHandle, path.moveAnchor and text.setPathHandle, `segment` of
path.insertAnchor, and `to` of artboard.reorder, library.moveGroup and
graphicStyle.move. Each now refuses it with "`anchor` must be a whole
number", naming the key; left out or null, it is still missing.
An optional `subpath` of path.appendAnchor, path.close and path.reverse
given that way was read as left out, so the command extended, closed or
reversed the default subpath (path.reverse reversed every subpath). The
`artboard` of the ruler origin commands answered "index out of range"
for such a value and for null. Both now refuse such a value with the
same message and change nothing. A null `artboard` is artboard 0, as one
left out is; a whole number past the artboards is still out of range.
warichu_is_a_character_attribute_set_saved_and_exported looked for Tj or
TJ anywhere in the exported PDF. The file ID in the trailer and the XMP is
a base64 hash that changes each second and now and then spells one of
them, so the test failed on main twice (bf3cf422e, 446bf59bc) while
export outlines warichu type every time. It now counts text-object lines
only, as the colour font PDF test already does.
The Smooth tool refit every anchor in the smoothed stretch with a corner
angle of 179°, so a drag across a corner rounded it off. An anchor is now
kept as a corner when the path turns there by more than 57.5° (an
interior angle under 122.5°) at the anchor itself, over the Smooth
radius and over twice the radius on either side. On a closed path the
distances are no more than an eighth of its length. The stretch is cut
at each corner, each part is refit on its own, and the corner keeps its
position. The threshold is the same on every pass and has no setting.
A jag or bump smaller than the radius is not kept: the path does not
turn by that much over twice the radius. A whole closed path with
corners keeps its start anchor when the refit keeps an anchor there. A
drag that changes nothing adds no anchors and no undo step.
Docs: params text for path.smoothRegion, docs/mcp.md,
docs/target-app-parity.md.
Changing Preferences › Hyphenation › Exceptions bumped each open
document's revision, but the caches of laid-out type outside the text
crate were keyed on the font generation alone. The renderer kept the
glyph geometry, raster-effect pixels, live-effect and envelope art,
pattern tiles and placed symbol art of unchanged type objects, so
hyphenated area type kept its old line breaks on the canvas. The
hit-test art of blends and envelopes, the Fit to Artwork Bounds answer,
the layout caches of the Type and Touch Type tools and the out port's
overflow mark were keyed the same way.
vectorcraft_text::layout_inputs() returns a number that changes with
the fonts and with the hyphenation exceptions. Every one of those
caches now keys on it instead of FontDb::generation(), and envelope ink
uses it in place of the private envelope_ink_inputs(). The hit-test key
hashes it together with the plug-in revision.
Tests: a renderer that drew hyphenated area type, alone, with a drop
shadow, in a group with a Transform effect, in a symbol instance and in
an envelope, draws it as a new renderer does after the exceptions
change; the out port of selected area type shows the overflow that the
new exceptions cause. The render test helpers that run a step again
when the fonts change during it now also run it again when the
exceptions change.
Object › Plug-ins › Cutting Tools › Nest Shapes… (`addon.cutting.nest`)
moves the selected objects close together onto a sheet or a roll of
material. The sheet starts at an artboard's top-left corner and is the
artboard's size or a set width and height; a roll is a set width with
no end. A margin (18 pt by default) is kept inside the sheet's edges and
a spacing (9 pt) between objects.
Objects are packed by their bounding boxes, with their strokes and
effects (the reach of shadows, glows and blurs included) or by their
geometry: the tallest first, each where its bottom edge is highest and
then furthest left. With Rotate, an object may turn 90° clockwise where
that puts its bottom edge higher or where only the turned object fits;
a turned object is measured after the turn. A path of a pixel-aligned
compound path is not turned. Objects that do not fit go in a column to
the right of the sheet, in stacking order. Objects on the pixel grid
move by whole points and take 1 pt more room, so they stay on the grid
and keep the margin and spacing. A path of a compound path selected on
its own moves alone. Objects without bounds, such as an empty group,
are not moved and are listed in the result.
The command is one undo step, and its result gives the objects placed,
put aside, turned and skipped and the length of material used. The
dialog has Preview.
The new Nest Shapes and Roll catalog rows are in every catalog.
Docs: docs/mcp.md (Cutting Tools add-on), docs/target-app-parity.md and
ROADMAP.
docs/mcp.md's line and stack row said $.stack shows at most 64 lines
and uses [global] only for the script's own code. It keeps the
innermost 64 frames after a leading line "…" when some are left out,
and [global] names any code outside a function, including code that
an included file, $.evalFile or eval runs. The row now also says how
a frame's file compares with $.fileName in each case: the same file
for code from a file, the run's name where $.fileName is empty for a
script given as source, [eval] where $.fileName is the file being run,
and [unknown] at line 0 where $.fileName is empty.
The engineName row now gives the #targetengine name, and the
script.run params text, the script module doc and the Scripts evidence
line say $.fileName is the file of the code that reads it rather than
the file being run.
After Reset Bounding Box on a turned symbol instance, Break Link to
Symbol and Object > Expand gave the art a box turned with the instance's
transform again. The art's boxes now turn with the instance's own box,
so they stand square when the instance's box did, and the angles the
art has inside the symbol are kept relative to it. The group that an
instance's opacity, blending mode or opacity mask adds around the art
takes the instance's box angle instead of standing square to the page.
A reflected instance can hold a box 180 degrees from the box its
transform gives in one step; the art now takes the instance's box
there too, the same rectangle with its handles where the instance had
them.
Compound shapes and Pathfinder receive an instance's art through the
same rule.
The clip groups and clip paths that 9-slice guides make for gradient
and pattern art take the angle of the cell that places them, and the
outer group keeps the object's angle turned by the instance, instead
of standing square to the page. This also changes the result for an
instance that was never reset: a 20 degree sliced instance gave clip
groups at 0 degrees and now gives them at 20.
Docs: params text, docs/mcp.md, docs/target-app-parity.md.
A command that needs a whole number of 0 or more, such as `index` of
`appearance.setItem`, `anchor` of `path.removeAnchor` and
`addon.pen.removePoint`, `sourceDocument` of `edit.dropSelection`, `index`
of `document.activate` and `to` of `document.move`, answered "missing
integer `index`" (or "missing index") both when the key was left out and
when it was given as a value that is not a whole number of 0 or more, such
as "3", 2.5, -1 or true. A value that is given but is not one is now
refused with "`index` must be a whole number", the message object ids
already use. A key left out or given as null is still missing, and an
optional index such as `subpath` keeps its default. Neither error changes
the document or records an undo step.
Docs: docs/mcp.md, docs/target-app-parity.md.
A swatch delete, Swatch Options edit, merge, Edit Color Group, Spot
Colors options change or Default Swatches replace run as a
command.batch step left the fill and stroke new art takes linked to the
old or deleted swatch, because the defaults were skipped whenever an
interaction was open. A batch step now rewrites them as the command run
on its own does; a live Swatch Options preview still leaves them alone,
and a failed batch or a canceled batch preview puts them back.
The same commands now also rewrite the fills and strokes of the
appearance new art takes, and record the change with their undo step,
so Undo and Redo put the paints for new art back with the swatches.
The test for a triple-click whose first click makes the group now also
builds the planar map from the same two paths and checks that the face
at the click takes its fill from the square. The doc comment of the
double-click flood names the three points it checks along each edge
segment.
- After a fill drag, the Live Paint Bucket stores the release point, so the
cursor swatch preview shows there instead of where the pointer last moved
before the press.
- Arrow nudges and Alt+arrow type spacing read Shift and Alt from the key
press, as the tool keys do, so a modifier released within the same frame
still makes a 10 pt nudge, a copy, or a spacing step.
- tool.setOption accepts cursorSwatchPreview for the Live Paint Bucket and
refuses a value that is not true or false.
Every built-in preset other than Auto Color and Flat Logo now traces at
Paths 50. Corners is 100 in Technical Drawing, 75 in Default, Black and
White Logo, Line Art and Outline, and 50 in the others. Noise is 1 px in
Technical Drawing, 5 in High Fidelity Photo, 10 in Low Fidelity Photo, 15
in 3 Colors, 6 Colors, 16 Colors and Shades of Gray, 20 in Sketched Art,
Line Art and Outline, 25 in Default and Black and White Logo, and 90 in
Silhouettes. Palettes, color counts and the other options are unchanged.
This changes the output of every preset but Default, Auto Color and Flat
Logo. The traces take fewer anchors (High Fidelity Photo 5,494 to 3,136
and Black and White Logo 27 to 14 in crates/trace/tests/quality), and
outlines on flat art lie further from the true edge (16 Colors 0.100 to
0.123 px off on average).
Docs: docs/image-trace-adjustments.md, docs/image-trace-quality.md,
docs/target-app-parity.md.
A closed freehand stroke is fitted as the open stroke would be and closed by a
straight segment from its end back to its start. Fitted as one loop, the
closing segment curved on past both ends and back, like a hat's brim.
- A face outline segment that runs along several edge segments (the
face has no corner where a crossing line splits the edge) now joins
the face to every edge segment it runs along, not only the one under
its middle, so a double-click flood no longer stops there.
- The first click of a triple-click on selected paths, which makes the
Live Paint group, takes the fill to match from the paths' closed
subpaths only, as the group's faces do; an open path in front no
longer gives the wrong fill.
craft_dxf::parse_recovering reads the tags (ASCII and binary, any code
page), model::Document::read the sections, tables, blocks, layouts and
entity followers, and Entity::read each entity. The pair parser, the
records, the header, layer, block and layout readers and the colour
palette are gone; what stays is the mapping onto VectorCraft art.
Binary DXF files now open instead of being refused. A damaged binary
file says so.