Select > Start Global Edit now also takes rotated copies of the selected
object or group, in the highlights before the start, in the Global Edit
Options' Results count and in the started edit. An edit reaches each copy
turned by that copy's angle, so an anchor moved to the right on the
selected object moves downward on a copy turned a quarter turn clockwise.
The copy's angle is the one that lays the selected object's anchors and
handles on the copy's in order (a least-squares fit in the unit box),
and the copy is the same shape when each point then lies within a
millionth of the larger side of the copy's box. Reflected copies and
copies stretched along one direction stay unmatched. With Size, a rotated
copy matches when it is the object rotated without scaling. The no-match
message now names only reflected copies, in every catalog that has it.
Docs: docs/mcp.md, docs/gaps.md, docs/ui-parity.md and the evidence list
in docs/target-app-parity.md.
The File formats area row no longer lists grouped column, stacked column,
line and area graphs among the live objects a saved .ai writes as their
art, and its evidence names the graph round-trip tests.
When only some frames of a threaded story are selected, Remove Line
Breaks and Remove Paragraph Breaks built the story's frame list again
for every selected frame of it, so the work grew with the square of the
frame count. The command now notes a thread once its story is found not
to be selected in full, and reads that thread's other selected frames
on their own without going through the thread again. Each selected
frame still loses its own breaks, in the order selected, as one undo
step.
A test-only counter in threads.rs counts story_in calls, and
remove_breaks_goes_through_a_partly_named_story_once checks both break
kinds with frames named out of order and twice.
paint.setFill, paint.setStroke, paint.invert and paint.complement with an
item, stroke.set, stroke.setAdvanced, paint.editGradient,
paint.setGradientGeom and the paint.freeform edits read an item given with
aligned: true and the art of a graph design in a series first as a row of
the art's stack, as appearance.setItem and transparency.set do. Each other
object edits the row equal to it and an object without one is left as it
is. A row the art does not have, a row of the other kind, or a row no
other object has is an error, also when the art is the only object given,
and the document and its undo history stay as they are. Without stroke,
the gradient commands edit the kind of the art's row.
The objects and ids the commands report, a gradient spanning the
selection, and the last color and last gradient count only the objects
whose row was edited.
Direct Selection on a dynamic symbol's instance picked an object in the
region its clipping path's effects give it, but cut the object's outline
to the plain clipping path, so the outline came out empty or cut short.
In a layer of the art whose Preview is off, it tested the effect-shaped
region and the fills, where the canvas draws the plain clipping path and
outlines.
- `hit::symbol_part_outline` cuts to the bounds of the effect-shaped
region. The new `hit::symbol_part_outline_in_view` takes the view's
outline state, and the Direct Selection overlay passes it.
- `hit::symbol_part_at` tests art in a layer whose Preview is off in
outline.
The bounds of a plot of the art's bounds no longer count the objects a
plot leaves out (placed images, objects at 0% opacity, unpainted paths)
when they sit in the art of a symbol. An instance whose symbol holds
nothing else is left out, so a document with only such instances is
refused with "nothing to export". The art of a dynamic symbol, and of a
group with effects, fills or strokes of its own, is measured whole.
The Gujarati catalog lists every menu and command label, and it had no
rows for Show Learn Tab, Show Skill and Back One Level. It now has them.
docs/mcp.md said the For you and Skills tab buttons run learn.tab. A tab
button runs it only when the panel shows the other tab, and the page now
says so.
usvg decodes an image data URL every time it converts the element that
holds it, a `<use>` copy, a filter or a nested SVG image included, before
the image resolver is called, and nothing bounded the bytes decoded per
import.
Before usvg reads the imported SVG and each SVG shown as an image, every
`href` and `xlink:href` of an `<image>` or `<feImage>` that is a data URL
is replaced with a key. The resolver decodes each URL once, the first
time its key comes, and every later use gets the same image. All data
URLs of one import decode to at most 512 MB together (MAX_DATA_URL_BYTES):
decoding stops where a URL would pass it, and that image is left out with
a warning. A link spelled like a key gets a key too and is still read as
that link.
- A graph opened from a .ai file now saves `placedArt` too. Moving or
restyling one of its labels before the first redraw no longer moves or
stretches the plot.
- Type > Create Outlines on a graph's labels now adjusts the saved bounds,
so the outlines do not read as a move at the next redraw. A move of
the graph made before the outlining is still followed.
- A `placedArt` with no width or height falls back to the bounds of all
of the art, as a graph saved without it does.
- `art_bounds` moves to the doc crate so the .ai reader can use it.
- docs/mcp.md describes `placedArt`, `placed` and when a redraw follows
a move.
- Tests: a legend across the top, a legend after a right value axis and
legend labels of several lines keep the plot in place through label
size changes; moving a category label on its own; outlining labels
before and after a move; a flat `placedArt`; a label moved in an
opened .ai graph.
The edge built from a closed path that nothing cuts started at the anchor the
planar map gave it, so dashes, a width profile or a brush began at a different
place than on the path. The edge now starts at the anchor where its path
starts. An edge with no anchor there takes its dashes from its own start and
leaves off the profile and brush.
The command description and the progress doc say that dashes aligned to
corners and path ends are not fitted to cut edges.
The continuous-tone check exempts a neutral or single-curve picture when
sixteen colors leave at most a fifth of the error of eight. The
exemption is for flat art of up to sixteen clean levels, where sixteen
colors leave no error. A gray photo with 0 to 2 levels of noise measures
0.19, under the cutoff, so it was classed as flat art and traced without
smoothing, while its color original and the same photo with more noise
were smoothed.
The cutoff is now a tenth (VectorCraft's own value). Clean gray, sepia,
single-hue and duotone art of up to sixteen levels stays flat art.
Docs: docs/target-app-parity.md.