Join removed each merged anchor from the path's anchor list as it went,
which moved every anchor after it, so a long selected run in front of
many other anchors took time quadratic in the path's length. It also
looked up each anchor's selection in the selected-anchor set.
Join now marks the merged anchors and removes them in one pass at the
end, reading the selection from one flag per anchor. Each corner or
smooth conversion sees the same neighbors as before, so the resulting
anchors are unchanged. Anchor::smooth_between holds the smoothing that
SubPath::smooth_anchor applies.
Tests compare the new merge bit for bit with the old one on 30,000
generated paths, and count the anchors moved when 300,000 selected
anchors in front of 300,000 others merge: each of the others moves
once.
Stroke is the widest feature that can be stroked, and it was applied to
each connected shape as a whole: a thick body with thin arms stayed one
filled area. Now a shape wider than Stroke somewhere keeps as its area
every disc wider than Stroke that fits in it, and each piece outside
those discs that reaches out of them at least one and a half times its
own width (and 3 px) is traced as a stroked center line. A line's end at
the area goes to the cut, so the line's cap closes the join. Corners and
edge slivers stay in the area, and a piece that cannot be traced stays
in it too. Shapes no wider than Stroke trace as before.
Each line keeps one width; without Fills, the area is still a 1 px
outline.
Docs: docs/target-app-parity.md.
The i18n test that main added for 3D refusals calls validate_three_d_at with this branch's (Option<usize>, usize) position: effect 0 of appearance item 0 is (Some(0), 0).
With both guides of an axis past the same edge, the art keeps its size
from the other edge of the instance, or shrinks to the instance's width
or height when the instance is smaller than the art. The module doc,
AxisMap::new and the docs/target-app-parity.md entry now say so.
A selected warp envelope now shows the points of its surface on a 4x4
grid (8x8 or 16x16 where 4x4 strays more than 0.1% of the warp's
diagonal from it). object.mesh.movePoint, movePoints, addLine,
deletePoint and object.envelope.setMeshPoint accept a warp: the first
edit turns it into a mesh envelope on that grid and applies the edit as
one undo step, so Undo or Escape gives the warp back with its style and
bend. An edit that moves no point leaves the warp and adds no undo
step. A warp that no such grid follows (some version 0 maps) shows no
points and its edits fail without changing anything.
movePoints and setPointColor on a gradient mesh record no undo step
when they change no point.
#5748 moved the Pencil's and the Paintbrush's Fidelity to screen pixels, but
docs/ui-parity.md still gave it in points. The Pencil row now gives the
slider's rail, the field and the key steps in px, and says the tool sends
path.freehand the value in points at the current zoom.
The Pencil row also appeared twice, the second copy without the Fidelity
text. The two rows are merged into one.
The comments on FIDELITY_MAX, fidelity_step, fidelity_at and fidelity_from
in the Tool Options dialog name the tool's unit, since the slider is shared
with Smooth and Blob Brush, which stay in points.
When a linked file lost its clipping path, the clip group holding the
image stayed as a plain group of the image. When the file had a clipping
path again, the image went into a new clip group inside that plain group,
so each round nested one more group. The plain group holding just the
image now becomes its clip group again, in the layers and in symbol,
pattern, graph design and mask art.
With the lowResProxyEps preference on, opening a document kept the saved
preview of a linked DCS file, so the link showed as EPS without its
plates. Opening now reads the first 1 MiB of each such EPS file and reads
a DCS file in full. The whole file is read only when a binary EPS header
puts the PostScript past those bytes or the header comments run past
them. Other EPS files keep their preview.
In the Touch workspace, a two-finger tap on the canvas now switches
between the Selection tool and the drawing tool chosen last, as the
help page describes. It no longer undoes there; outside Touch a
two-finger tap still undoes, and a three-finger tap still redoes in
every workspace.
- New UI command tool.toggleTouchMode (Switch Selection and Drawing
Modes, {} -> {tool}). From the Selection, Direct Selection, Group
Selection, Magic Wand, Lasso or Perspective Selection tool it chooses
the drawing tool chosen last in the window, or the Pencil tool when
none has been chosen; from any other tool it chooses the Selection
tool. The Hand, Rotate View, Zoom and Print Tiling tools never become
the drawing tool. It adds no undo step.
- These tool lists and Pencil as the first drawing tool are
VectorCraft's own rules.
- The label is in every catalog. Docs: docs/mcp.md, the touch row of
docs/hardware-parity.md and docs/target-app-parity.md.
After a rotation the Selection tool already shows and drags a bounding
box turned with the objects, but the Free Transform tool still used the
page-aligned box. Its handles sat on the wrong corners, a side handle
scaled along the page axes, and Perspective Distort and Free Distort
started from a box that did not match the art.
- The Free Transform tool keeps the selection's turned box for the
drag. Handles, the rotate zone and the move zone are read in its
frame; a handle scales along the selection's own sides from the
opposite handle (or the center with Alt) and snaps as the Selection
tool's does; Cmd/Ctrl on a side handle shears along that side; the
outline, handles and cursors are drawn on the turned box.
- Perspective Distort and Free Distort move the corners of the turned
box. `object.distort` takes `angle?` (degrees): `from`, or the
selection's bounds without it, is then a box in the frame turned by
that angle. Upright boxes send the same params as before.
- The Scale and Reflect tools, their dialogs and commands, and the
Transform panel's flips keep the page's axes.
Docs: docs/mcp.md, docs/target-app-parity.md.
A new Type preference, Show samples on white (`fontSamplesOnWhite`, off
by default), draws each family's sample in every font menu, and in
Type → Font in the in-window menu bar, in the Light brightness's text
color on a white area, in every interface brightness. A row's white
area is drawn while its sample is still rendering, and leaves 2 pt above
and below it where a highlighted row's color shows. The family names and
the rest of the menu keep the interface's colors. Preferences dims the
checkbox while Enable in-menu font previews is off.
Docs: docs/mcp.md (prefs), docs/target-app-parity.md evidence line.
The Drawing tools row in docs/target-app-parity.md now names the
measurement readout that the Pen, Smart Pen and Curvature tool show
with the rubber band off. The score, gaps and hours are unchanged.
The Paragraph panel's Mojikumi Set lists None, YakumonoHankaku,
GyomatsuYakumonoHankaku, GyomatsuYakumonoZenkaku and YakumonoZenkaku,
then Line-end Punctuation Half Width, and text.setFormat {mojikumi}
takes yakumonoHankaku, gyomatsuYakumonoHankaku, gyomatsuYakumonoZenkaku
and yakumonoZenkaku besides none and lineEndHalf.
The spacing of each set is VectorCraft's own rule, built on the help
page's one-line description of each set:
- YakumonoHankaku sets every bracket, comma and full stop half width,
takes a quarter em off each side of a middle dot, and puts a quarter
em between Japanese and Latin letters or digits.
- GyomatsuYakumonoHankaku keeps punctuation full width inside a line,
sets an opening bracket starting a line flush and a closing mark
ending it half width, and takes the quarter em after a middle dot
ending a line off.
- GyomatsuYakumonoZenkaku keeps punctuation full width and adds the
quarter em between Japanese and Latin text.
- YakumonoZenkaku sets characters as None does.
Both composers and vertical type measure each line as it is set. A
right-to-left paragraph, whose line ends are measured untrimmed, also
draws them untrimmed, and a right-to-left line that ends between a
Japanese and a Latin character is measured without the quarter em the
set adds there. With a Desired glyph scaling other than 100%, the
space a set takes off before an opening bracket or middle dot, and the
Japanese-Latin space recorded at a line's end, scale with the glyph.
The sets save with the document and paragraph styles; new type and
Reset Panel keep Line-end Punctuation Half Width. SVG export lays type
with middle dots out again for its positioned spans. A .ai save
reports a paragraph with one of the new sets as left out.
Docs: docs/mcp.md, docs/target-app-parity.md, docs/type-parity.md,
docs/gaps.md.
Copy now remembers the whole chain of layers around each object, not only
the name of the nearest one. With Paste Remembers Layers on:
- In the same document, art goes back into the sublayer it came from while
that sublayer exists, even after it was moved, so two sublayers of the
same name in different layers stay apart. A deleted sublayer is made
again inside the layer that held it.
- In another document, the sublayer and the layers around it are matched
by name from the top level down; of repeated names, the topmost chain
that matches the most names wins, a shown and unlocked one first. A
missing sublayer is made inside its layer, and a missing layer on top
with the sublayer inside it, in the paste's undo step.
- When the matched layer, or a layer around it, is hidden or locked, the
paste fails with "the target layer is locked or hidden" and nothing is
pasted, instead of putting art in a hidden layer or making a second
layer of the same name.