With nothing selected, a click with the Eyedropper picks up an object's attributes and an Alt/Option-click on another object applies them, as the reference app's Eyedropper does. Alt-click only copied from a selected object, and with nothing selected it failed. The session now keeps a copy of what appearance.copyFrom picked up last, and a reversed copy with nothing selected applies it.
Preview, Embed ICC Profiles, Create PDF-Compatible File and the other VectorCraft Options went back to their defaults for every document not saved yet. A native Save or Save As now records the options it used in the preferences (not the artboards it picked, nor Use Compression, which its preference decides), and file.formatOptions offers them for a document not yet saved as a native file. A document saved before keeps its own.
While an opacity mask is edited the Layers panel lists only the mask, so a new layer was added where no row showed it, and only the panel's layer count went up. Both commands are now disabled then, as isolation commands already are (outside_mask_editing).
- In `shaper::refresh`, replace full document walks with `changed_shaper_groups`,
diffing `before` and `after` layers and short-circuiting on pointer-equal (`Arc::ptr_eq`)
subtrees in O(1).
- Return whether Shaper groups rebuilt or modified artwork (`Result<bool>`),
allowing `Session::edit` to skip the second `cmd::objects_on_path::refresh`
call when no artwork was modified.
- In `textwrap::refresh`, check pointer equality on layers against `before.layers`,
skipping untouched layers in O(1) and checking only modified layers.
With a layer selected, Object > Hide > Unselected Artwork hid every object
on that layer, since the selected layer was dropped from the objects to
keep. The objects of a selected layer now count as selected.
While Lock Guides is on, a group that held a guide path was hidden whole,
which hid the guide with it. Guide paths now count as selected, so the
command keeps such a group visible and hides its other members one by one.
svg_darkness_uses_rendered_shadow_in_non_srgb_working_space runs itself
again in a child process with --exact and checked only the exit status.
libtest exits 0 when --exact matches no test, so a rename of the test
would have left the parent passing without running the non-sRGB check.
The parent now also requires "1 passed" in the child's output, as
layout_cache_follows_fonts_added_later in crates/tools does.
With `includeSubdirs` and the destination folder the same as the source
folder, the Export for Screens folder of `a.svg` was `a`, and its
`Artboard-1.svg` replaced the source `a/Artboard-1.svg` before Batch
opened it. Batch now keeps the names of subfolders of the destination
folder that hold source files, so that export folder is `a-2`.
With the destination folder the same as the source folder, `a..svg` gets
the name `a` and was saved as `a.svg`, replacing the source `a.svg`
before Batch opened it. Batch now keeps the names of the source files in
the destination folder for their own output, so `a..svg` is saved as
`a-2.svg` and `a.svg` is saved over itself.
The Blend tool kept its first pick, its clicked anchor and the blend it
was adding to through edits made outside the tool. Picking A, recoloring
other art and clicking B made a blend of A and B; undoing A's creation
left the next click doing nothing.
History::step names the current step by the serial numbers of the newest
undo step and the next redo step. The session keeps the active document's
uid and step from the tool's last pointer event and calls the new
Tool::history_moved at the next pointer event, or before drawing
overlays, when they differ. The tool's own edits are recorded after its
actions; a selection tool lent by Cmd is not told. BlendTool clears its
pick and chain there, as Escape does. A selection change keeps them.
With the Folder destination, `a.svg` is saved as `destinationFolder/a.svg`.
A later source `a.svg.svg` then got the Export for Screens folder `a.svg`,
which already existed as a file, and its export failed. Batch now numbers a
source's name when its folder or any file it writes in the destination
folder has the name of a file or folder an earlier source wrote, so that
folder is `a.svg-2`.
A recolor of everything counted a locked or hidden object as left
unchanged when the pass would only have linked it, or the tiles of a
pattern it is filled with, to a swatch of the same color. With
`group`, it also counted one as changed when the group's rewrite only
removed its link to a dropped swatch, and as unchanged when the
rewrite recolored a pattern it is filled with.
The trial pass now leaves out changes to swatch links alone, patterns'
tiles included, and the count compares the colors the object shows,
its patterns' tiles included, before the recolor and after the
rewrite.
A source file named `a..svg` gave the folder `a.` and a data set named
`a.` gave `Untitled_a.`. Windows drops a trailing period from a folder
name, so these folders were the same as the ones for `a.svg` and the
data set `a`, and the second export replaced the first one's files.
Batch now passes each name through `safe_file_name` before it numbers
repeated names, so the second folder is `a-2` or `Untitled_a-2`.
When the selection is exactly what select.all takes, recolor.apply and
edit.colors.invert, toCMYK, toGrayscale, toRGB, saturate and
adjustBalance now count the objects select.all left out whose colors
they would have changed: locked or hidden objects, the objects of
locked or hidden layers and sublayers, and objects on locked artboards
(counted as locked). In isolation mode the count covers the isolated
group's members. An object both hidden and locked counts as hidden.
Template layers' art is not counted. Locked and hidden members of a
selected group are recolored as before and are not counted. With any
other selection, or with ids, both counts are 0. Lock and visibility
work as before.
The reply carries notChanged: {locked, hidden}, and a warning when a
count is above 0, which the app shows in the status bar, for example
"Recolor completed; 3 locked objects and 1 hidden object were left
unchanged". A trial pass over the left-out objects finds which ones
would change. In recolor.apply, an object that the group rewrite then
changes is not counted.
The message has rows in the 20 catalogs that translate messages.
docs/mcp.md describes the counts.
Main replaced the glob import of the command helpers in fileio/eps.rs
with an explicit list; the EPS Save path's selectedOnly check uses
bool_or, so it is added to that list.
File > Document Color Mode and document.open {colorMode} converted the
colors of the layers, symbols, pattern tiles and swatches only. Graph
designs, graphic styles, the art of opacity masks, the tile that
pattern editing's Cancel puts back and the art of brushes kept their
old color model (only a tint of a global swatch in a graphic style or
a mask followed the swatch), so a CMYK document could still apply,
place or print RGB colors from them.
These now convert with the rest, in the same undo step: their solid
colors, gradient stops, text runs and mesh points, nested masks
included. A Hue Shift brush's key color takes the converted color of
the art color it matches, a tint of a global swatch included. The
brush library is stored again only when one of its colors changed. A
tint of a global swatch in any of these places becomes the converted
swatch's color at its tint, as in the layers. The reply's changed
count covers the colors of the layers, symbols, graph designs, pattern
tiles and opacity masks; the colors of graphic styles and brushes
convert without being counted.
Docs: docs/mcp.md, docs/target-app-parity.md.
While an opacity mask or a pattern was edited, a Shaper scribble and
Object › Shaper › Release and Expand ended isolation, and a Shaper
double-click on a Shaper Group isolated the group's original shapes.
Each replaced the editing layer's isolation while the document stayed
in mask or pattern editing. A click on the Shaper Group's mode widget
did the same through object.isolate.
A scribble, Release and Expand now keep the editing layer isolated in
these modes, and end isolation as before outside them. A double-click
with Shaper selects the original shape under the pointer without
isolating the group's original shapes, and the mode widget does not
show while a mask or a pattern is edited.
Docs: docs/shaper.md, docs/target-app-parity.md.
The Live Paint Selection tool acted only on the press, so a drag
selected at most the one face or edge under the pointer. The reference
app selects every face and edge a marquee touches, partly enclosed ones
included, and a Shift-drag adds them to the selection or removes them.
A drag of 3 pixels or more now draws a marquee. On release, select.set
selects the faces and edges it touches, or select.none runs when it
touches none. With Shift held at the press, select.toggle runs with
what it touches, and nothing runs when it touches none. A face that holds the whole marquee counts. Select Fills off
leaves faces out, and Select Strokes off leaves edges out.
A click now changes the selection on release instead of on the press,
so Escape between the press and the release, which also removes the
marquee, leaves the selection as it was. The tool no longer highlights
or selects the faces and edges of a Live Paint group that is locked, on
a locked layer or on a locked artboard, or that is outside the isolated
art in isolation mode.
Docs: docs/mcp.md, docs/target-app-parity.md.
The editing data wrote art space with its origin at the first artboard's
bottom-left corner, its artboard records lacked keys a reader requires, and
its %%Creator line made the reader measure %AI3_TemplateBox on an
8640-point canvas. Other apps opened the art 3,871.5 points away from its
artboard.
Art space is now ruler space, as in the .ai files users sent: y up from the
first artboard's top-left corner. The artboards together are centered on the
16383-point canvas. Each artboard's record gives its top-left corner there
(RulerOrigin), its pixel aspect ratio (PAR), DisplayMark and whether it is
selected, and %AI3_TemplateBox holds the canvas's center. %%Creator names
the format's app and holds no version number. %AI3_Cropmarks and
%AI3_TileBox give the first artboard, %AI5_ArtSize is 14400 14400, and the
/Document dictionary gives the canvas size.
A file with several artboards carried the data on its first page only, and
other apps opened it as a PDF, page by page. Every page now refers to the
one data dictionary, as the files users sent do.
The format details come from users' own .ai files, static analysis of
Illustrator's program and the user's manual testing in Illustrator.
Pattern Brush Options has a menu below the Outer Corner Tile and the Inner
Corner Tile. Each can be the brush's own corner art (Original), None, or one
of four tiles made from the side tile at each corner of the path:
- Auto-Centered stretches one side tile around the corner, centered on it.
- Auto-Between bends a side tile on each side into the corner, the two
meeting on the corner's diagonal.
- Auto-Sliced lays a side tile on each side past the corner and masks it
at the diagonal, so the two meet like a mitered frame.
- Auto-Overlap lays a side tile on each side past the corner, overlapping.
The tiles are straight at the corner and follow the path towards the side
tiles, so they meet a curve that runs into the corner. A side tile taller
than the corner can reach is stretched along until the two sides meet. On a
short path, a corner's tile is squeezed along so that it covers at most the
path up to an open path's end and half way to the next corner, and its two sides still meet on the
corner's diagonal.
The definition stores the choice as `outer_source` and `inner_source`
(`none`, `autoCentered`, `autoBetween`, `autoSliced`, `autoOverlap`), which
`brush.options` sets. Corner art wins over a source. A brush saved without
a source draws as before: a kind of corner without art takes the other
kind's art. None leaves that kind of corner empty.
Docs: docs/mcp.md, docs/target-app-parity.md.
After a click picked the first object with the Blend tool, Escape did
nothing: the pick stayed, and the next click on another object blended
the two. After a blend was made, Escape did not stop the next click
adding to it either.
Escape now drops the object picked first and stops the next click
adding to the blend just made, as a click on empty canvas does, so the
next click picks a new first object. The document and the selection
stay as they are, and no undo step is added.
Docs: docs/mcp.md, docs/target-app-parity.md.
Enter Isolation Mode worked while an opacity mask was edited, and Edit
Opacity Mask and View Opacity Mask worked in isolation mode, so each
mode replaced the other's isolated art. In the reference app, isolation
mode can't be entered while a mask is edited, and mask editing can't be
entered in isolation mode.
object.isolate and perspective.editText, which shows type in isolation
mode, are now off while an opacity mask is edited, and a call returns
an error that ends "stop editing the opacity mask first". In isolation
mode transparency.editOpacityMask and transparency.viewOpacityMask are
off, and transparency.makeOpacityMask refuses one target, an object or
a layer, which it would take into mask editing; a call returns an error
that ends "exit isolation mode first". Make Opacity Mask with two
objects still masks one with the other. Pattern editing mode does not
count as isolation mode for these commands.
Object > Perspective > Edit Text, the canvas context menu and the
Transparency panel's menu and Make Mask button follow the commands'
enablement. A click or Alt-click on the mask thumbnail in isolation
mode shows the error and does not edit the mask. While a mask is
edited, the Contextual Task Bar leaves out Isolate, and the Properties
panel's Quick Actions leave out Isolate Group.
Docs: docs/mcp.md, docs/target-app-parity.md.