An entry `<area>/keeps-<left area>` kept the copies in the left area
whenever the lock check on `<area>` failed, so an entry in a folder of
another account, or in one whose lock file can't be opened, kept a
crashed app's copies from being offered. Such an entry now keeps
nothing: only an area that this session holds, or that a running app of
this account has locked, keeps the copies it names.
When a running app has to leave its recovery area (its lock file was
removed and another app locked the area), its copies stay in the old area
until it writes them again in its new area. Only that app knew this, so
once the other app let the old area go, any app could offer, restore or
discard those copies while their app still ran.
The app now writes an entry `<new area>/keeps-<old area>` in its own area
while copies of its documents are left in the old one, and removes it
when none are. Another app that finds an area unlocked checks for such an
entry, and treats the area as a running app's while the area that names
it is held. After a crash the new area is no longer held, so the copies
are offered as before. The heartbeat writes the entry again if it was
removed.
Effect › 3D and Materials › 3D (Classic) › Rotate (Classic)… turns every
fill and stroke as one flat plane, as Rotate does, and shades it with the
classic No Shading or Diffuse surface.
- `effect.apply` with `threeD.classicRotate`: the Position rotation and
Perspective, `surface` (`none` or `diffuse`), the classic lights,
Ambient Light, Blend Steps and Shading Color. It has no highlight, no
Draw Hidden Faces and no shadow.
- The dialog shows Position on the Rotation tab and the surface and
lights on the Lighting tab, with no Object tab.
- Groups and layers turn about one shared center, and the effect also
goes on a fill or stroke, as Rotate's does.
- `effect.lightingPreset` refuses it, as it refuses the other classic
3D effects.
- Unknown parameters, numbers out of range, bad flags, a surface other
than No Shading or Diffuse and bad shading colors are refused with an
error.
effect.list's catalog lists the plug-ins installed in the process-wide
registry, which the plug-in tests change while the id and ids comparisons
run in the same test binary. Both comparisons, id against ids of one and
ids against the selection, now take the plug-in effects (plugin.<id>) out
of effect.list's catalog before comparing. The built-in catalog, applied,
activeItem, errors and the document are still compared.
Effect › 3D and Materials › 3D (Classic) › Revolve (Classic)… sweeps the
profile round a vertical axis, as Revolve does, and draws every face with
the Wireframe, No Shading, Diffuse and Plastic surfaces of Extrude & Bevel
(Classic).
- `effect.apply` with `threeD.classicRevolve`: Angle (0 to 360), Cap,
Offset (0 to 1000 pt) from the left or right edge of the profile's
bounds, the Position rotation and Perspective, and the classic lights,
Ambient Light, highlight, Blend Steps and Shading Color.
- Groups and layers revolve about one shared axis, and the effect also
goes on a fill or stroke, as Revolve's does.
- `effect.lightingPreset` refuses it, as it refuses Extrude & Bevel
(Classic).
- Revolve faces carry their view-space normal, and
`three_d::revolve_facets` hands them to the classic surface code.
- Unknown parameters, numbers out of range and bad flags, edges,
surfaces and colors are refused with an error.
Paragraph Style Options and New Paragraph Style gain a Tabs section. It
lists the style's stops and edits the selected stop's Alignment, position
(X:, or Y: for vertical type), Leader and Align On character. Add puts a
left stop 36 pt past the furthest one, Delete Tab removes the selected
stop, and Clear All Tabs leaves the style with no stops. OK sorts the
stops by position and keeps the stop edited last when two share one
position. Reset Panel removes the style's tabs.
paraStyle.new, paraStyle.setAttrs and paraStyle.edit check changed tabs
stop by stop: at most 256 stops, and each changed stop's position from 0
to 100000 pt and leader of at most 8 characters. Stops the style already
has are kept as they are. Changed tabs are sorted by position, keeping
the first of stops at one position. text.tabs.set rejects a leader longer
than 8 characters, an Align On value of more than one character and more
than 256 stops. Loading paragraph styles skips a style whose indents,
spacing, hyphenation, justification or tabs are out of range.
Docs: docs/mcp.md, docs/target-app-parity.md.
stroke.set without an item always went to the painted leaves, so a join
set on a group whose stroke is its own (a row in the group's stack)
left that stroke alone and gave every member without a stroke a new
black 1 pt one: on a PDF map, every glyph path got an outline. A
selected group or layer with a stroke row of its own now edits that
row, as the Stroke panel does with the group targeted; other targets
reach their leaves as before. A stroke row made for options alone
(cap, join, miter limit, dashes, alignment) has no paint, so nothing
becomes visible; a weight, an arrowhead or a profile still gives the
black stroke.
Fixes#6739
On Windows, removing a copy whose path runs through a file reports the copy as missing, so the removal counted as done and the file in the way went unreported, while a listing names it. The removal now names that file, and a copy that is just not there still counts as removed.
effect.deferredStatus lists a stage in the art of a symbol, pattern, brush
or opacity mask by the id of the object in that art. effect.refreshDeferred
took such an id only while the object still had a deferred stage; an
existing object there without one was refused as no such object, while a
layer object without a stage was accepted. An id is now valid when it names
an object in the layers or in that art, an object without a stage adds
nothing to the counts, and an id of no object is an error.
The params text and docs/mcp.md said `id` names one object, but the params
text did not list the key, so `{id: N}` was refused as an unknown
parameter. It is now `{ids?|id?}`, and the command checks only the form of
the ids before it looks them up itself.
The requested ids are held in a set while the art is walked, and only those
with a stage are handed to the refresh.
The zero point dragged out of the box where the rulers meet snaps as a
Pen or shape tool's point does: with Smart Guides onto the anchors,
centres, edges and paths of the art and the artboards or into line with
them, with Snap to Point onto the anchors and along the ruler guides,
else onto whole pixels or the grid. The guides showing what it snapped
to show during the drag and go when it is released or cancelled
(Escape, focus loss, another document). The origin is still set once,
on release (document.setRulerOrigin, one undo step).
The engine snaps it (Session::ruler_origin_drag, with the tools crate's
rulerguide::OriginDrag over PointSnap::drawn), as it does a guide
dragged out of a ruler.
Under --automation-read-root, prefs.get, prefs.list, prefs.set and
prefs.reset returned the folder preferences (fontsFolder, pluginsFolder,
scratchPrimary, scratchSecondary, recoveryFolder, templatesFolder) and
the export presets' folder even when they were outside the read roots.
Such a folder preference is now null, as ui.inspect leaves it out, and
such a preset's folder is left out. An empty folder and the scratch disk
choices stay; without roots the replies are unchanged.
When a folder on the way to the Data Recovery folder was missing and
couldn't be made, or was a file, the error named the area folder or the
copy inside it, for example `<recovery>/1794385145-1: Not a directory
(os error 20)`. Errors on the store's folders and files now name the
first folder on the way, from the top, that is not a folder ("<path> is
not a folder: <OS error>") or is missing ("couldn't make <path>: <OS
error>" while the store makes it, "<path> is missing" otherwise). When
every folder on the way is there, the error names the folder or file it
happened on. When reading a folder reports it missing, listing checks
the folders on the way, so a file there is an error and not an empty
list.
A scatter, art or pattern brush dragged from the Brushes panel onto an
empty part of the canvas places a copy of its art there to edit,
centered where it is dropped (brush.placeArt). Dropped on a path, a
brush is still applied to it. A pattern brush is placed as its tiles in
a row, 10 pt apart, each in a group named for its tile, with an
unpainted rectangle at the back of a tile that has a repeat frame.
Calligraphic and bristle brushes have no art and are refused. A symbol
instance in the art is measured by its symbol's art.
Docs: docs/mcp.md, docs/target-app-parity.md.
document.exportForScreens without a folder writes into the folder its
exportPreset keeps. When that folder is outside the client's read roots
and the export fails, for example because the folder is also outside the
write roots, the error now names the folder by its name, as the reply of
a successful export leaves it out. A granted root in the same message
stays whole, and a folder the client gives stays whole in the error.