Preferences > User Interface > Open Documents As Tabs was stored but did
nothing. With the box cleared, each document opened or created afterwards
opens in a floating window of its own, at the next cascade place, as
Window > Arrange > Float in Window floats it. Documents already open, and
documents open when the app starts, keep their tabs; checking the box
again leaves floating documents in their windows.
The engine records the preference on each document as it opens
(DocState::opened_as_tab), and the UI finds new documents by uid, so a
command batch that closes and opens documents, or changes the preference
between opening them, places each one as the preference was when it
opened.
A document tab dragged more than 24 pt above or below the tab strip
floats its document in a window under the pointer and makes it the
current document (window.arrange.floatInWindow takes index and at for
this). A shorter drag, or one along the strip, leaves the tabs as they
are. A document window dragged by its title bar onto the tab strip goes
back under the tabs; the strip shows an outline while a window is over
it. A desktop document window is an OS window, so it has the document's
tab at its top: dragging that tab moves the window, and dropping it on
the main window's tab strip docks it (window.arrange.consolidateAllWindows
takes index for one document).
A document floated again opens where it is asked to, not where its last
window was.
Window > Arrange > Float in Window (window.arrange.floatInWindow) moves
the current document out of the tab strip into a floating window of its
own, and Float All in Windows (window.arrange.floatAllInWindows), a new
item, does so for every tabbed document. Cascade (window.arrange.cascade)
floats every document and stacks the windows from the upper left of the
document area to its lower right, 30 pt apart, in tab order. On the
desktop each window is an OS window; on the web and on Wayland it is a
window inside the app's window, as floating panels are. While the
control channel is attached, the windows also open inside the app's
window, so ui.click, ui.drag and ui.screenshot reach them.
The current document's window holds the canvas. The other windows, and
the main window while the current document floats, draw their documents
as Tile's panes do, and a press in one makes its document the current
one. A document's OS window that takes the keyboard focus makes its
document the current one, and keys typed there run the main window's
shortcuts. Closing a window closes its document, asking to save unsaved
changes. Consolidate All Windows brings floating documents back under
the tabs, and Tile brings them back into its grid.
Cascade is enabled with two or more documents, Float in Window while the
current document is tabbed, Float All in Windows while any document is
tabbed, and Consolidate All Windows while documents are tiled or
floating. ui.inspect reports the floating documents.
A style whose features turn on pnum or lnum alone, or pair a figure tag with
one the shown entry turns off (onum with lnum, tnum with pnum), showed a Figure
entry that does not match its tags. Choosing that entry then left the field
unchanged, so the tags could not be cleared. Figure now opens unset for these
lists, and choosing Default Figure writes -tnum, -onum, -pnum and -lnum.
Character Style Options and New Character Style get a Character Color
section and an OpenType Features section.
Character Color sets the fill and stroke (None or a document swatch;
a global swatch or a tint of one stays linked, with a Tint from 0% to
100%), the stroke Weight, and Overprint Fill and Overprint Stroke. A
gradient or pattern paint the style already has stays until another
paint is chosen.
OpenType Features sets Figure, Position, Standard and Discretionary
Ligatures, Contextual, Stylistic and Titling Alternates, Swash,
Ordinals, Fractions and Stylistic Sets 1 to 20. A changed control
replaces only its own tags in the style's feature list, so other tags
stay, and Default Figure and Default Position are stored as their
features turned off, distinct from unset.
Empty controls stay unset, and each section's Reset Panel clears only
its own attributes.
charStyle.new, charStyle.edit and charStyle.setAttrs check a changed
fill, stroke, stroke weight or feature list: tints from 0 to 1, links
to global swatches of the document (the color follows the swatch),
weights from 0 to 4000000, and known feature tags, at most 256. Values
the style or the text it is made from already has are kept.
charStyle.duplicate keeps the copied style's values in the same way, so
a style with a language tag that is not in the list can be duplicated.
Editing a global swatch now also updates the fill and stroke stored in
character styles, so their text no longer shows as overriding the style
and text styled later takes the new color. swatch.unused counts a swatch
a character style links to as used.
The press picks the first object and selects it on the button-down. A dropped press now keeps
that pick with the selection, and still puts back the picks of earlier clicks.
A drag that takes a selected freeform gradient point out of the object previews its removal,
which deselects it. A dropped press now selects again the point that was selected once the
tool took the press, and Escape reselects a point dragged out and back inside the object.
Escape also clears state that earlier clicks set up, so taking Escape for a
dropped press lost it in five tools. Each now drops only the press:
- Blend: the object picked first and the blend being added to are put
back as they were at the press.
- Dimension: a dropped click picks nothing, and the points or lines picked
before stay; a dropped drag is canceled as before.
- Width: the drag ends and the width points selected at the press are
selected again.
- Gradient: a dropped click on a freeform gradient leaves the line being
drawn open.
- Selection: with the pointer loaded with text, a dropped press threads
nothing and the text stays loaded; a dropped press on a port loads none.
The progress line said a dropped press keeps nothing it began. A Curvature
press that adds a point and a press on another text object keep what they
did on press, as with Escape during the drag, so the line now says the drag
is canceled as Escape cancels it.
A dropped press on the Type tool no longer ends editing and switches tools:
the type being edited stays in editing, with the caret and selection it had
before the press, and the press does not count toward a double or triple
click. A dropped handle or move press with Crop Image puts the box back as it
was at the press and keeps earlier adjustments.
A dropped press (a long touch, a canceled touch, a second finger) now
goes to the tool through Tool::drop_press, which takes Escape as during
a drag by default. The Pen, Smart Pen and Curvature tools override it
so the path being drawn goes on: they forget the press, and a Curvature
point the press dragged goes back where it was.
The release that follows runs only the tool's Cancel and Notify actions,
so a Selection marquee selects nothing and a Shift-drag Artboard marquee
toggles nothing. The engine puts back the persistent options the tool
had at the press (the Polygon tool's sides changed with the arrow keys),
and stores none of them.
A long touch, a canceled touch or a second finger drops the tool press in
progress. The tool used to get a plain mouse-up, which it cannot tell from a
release: the options the drag changed (the Polygon tool's sides set with the
arrow keys) were stored, and a shape tool pressed and held still opened its
size dialog.
Session::drop_tool_press undoes the press's interaction, sends the tool
Escape as during a drag, and then a release that returns it to rest without
storing the tool's options. What the tool asks of the UI along the way is
dropped.
When the release frame held moves after the button-up, the last move
before it was dropped as the pointer's position, although the release
event carries its own position. That move's sample was lost from the
stroke. It is now kept unless it is at the button-up's position, and its
tilt and rotation still give the release's pose.
A Pencil or brush stroke takes every pointer move of a frame. In the
frame that releases the button, the moves that came after the button-up
were sent as drags before the release, so the stroke ran out to them
and back. The moves now stop at the primary button-up, and the pen pose
for the end of the stroke is the one kept for the last move before it.
The Measure tool and the Measure & Inspect tool snapped the end point of
a drag without Shift, but with Shift held they only turned the pointer
onto its 45° step and kept its distance: with Snap to Grid on the
measurement ended off the grid, with Smart Guides on it did not land in
line with an anchor, and with no snapping a drag of (37.3, 12.1) measured
39.2 pt at 0°.
Both now project the pointer onto the 45° step nearest its direction and
snap it there as the Line Segment tool snaps a Shift-drawn end, so it
stays on the step: (37.3, 12.1) measures 36 pt at 0° on a 9 pt grid, and
37.3 pt with no snapping. With Snap to Point alone, the anchor the pointer
snaps to is projected onto the step instead, so the end lands on an
anchor on the step and in line with one beside it.
A stroke color given without strokeWidth left characters at weight 0, so
nothing was drawn. As paint.setStroke does, a painted stroke now gives a
run with no weight 1 pt, for the characters and for the label styles a
graph keeps; an explicit strokeWidth still sets the weight.
text.setStyle takes stroke (a color or "none") and strokeWidth (the character
stroke's weight in document points, as stroke.set gives it), with keepModel
for both colors. They apply to all the text or to the start..end range, and
to graph label styles, in the same undo step as the command's other keys.
A stroke key was ignored before.
A drawing could make the importer keep far more than its own size: every dashed path held its
own copy of its linetype, every text object and symbol instance of an array copied its text,
font family or block name, and each placement of a block looked at all of its items, hidden or
not, without charging the work budget.
- Dash lengths kept across the import are capped; past the cap lines are drawn solid.
- Text, font family and block-name bytes copied into objects share one 64 MB budget, and a
font family longer than 256 bytes falls back to the default.
- Each block placement charges one visit per item it looks at, and stops once the budget is spent.
moxcms parses every entry of the tag table, so a profile listing one
description, copyright or table tag thousands of times, each pointing at
the same large data, made it decode and copy that data once per entry.
The ICC specification allows each tag signature once; such a table is now
refused before parsing.
A successful Export for Screens stored its params in the document's
export settings, which native saves write, PDF security passwords
included, although the PDF settings themselves are saved without them.
Saved export presets kept them in the preferences the same way. Both now
drop openPassword and permissionsPassword wherever they appear in the
settings, keeping the other security choices.
The overlap grouping swept left to right comparing each object's bounds
with every box still open at its left edge, so many objects sharing a
horizontal extent (stacked in a column) cost a comparison per pair
before any of the flattener's geometry limits applied, and the grouping
could not be cancelled.
Open boxes are now kept in a tree by their tops that knows the lowest
bottom below each branch, so each box meets only the open boxes it
overlaps; an open box inside a later box of its group, ending no further
right, is closed early. The grouping checks for cancellation as it goes.
Groups are unchanged: a test compares them with every-pair grouping.
Copy scaled its PNG down to fit 4096 pixels a side but never below 0.01
pixels a point, so art over 409,600 pt across produced a PNG far past
that side, up to the general raster export limit of a gigabyte of
pixels, on an ordinary copy. Such art now gets no PNG flavour.
A filter over `currentfile` waits until it is first read, and it took
its data from whichever file was running by then. One made over the
program's own file and first read inside a file run with `cvx exec`
read that file instead, and one made over a file being run, first read
in a file that one runs, read the inner file. The pending stream now
records the file it was made over (a chained filter inherits it), and
`materialize` decodes from that file.
A file run with `cvx exec` was read whole and run as a separate
program, while `currentfile` stayed the outer EPS. The PLRM has
`currentfile` return the topmost file being run, positioned after the
last token read. Ghostscript's eps2write runs each page's content and
each Type 3 glyph from a SubFileDecode filter, and its `ID` reads the
inline image's samples through `currentfile`, so they were read from
the outer file and then ran as program.
A file being run is now read object by object from its own data, and
while it runs it is `currentfile`. A filter made over it waits to
read, as one over the program's own file does, so it starts where the
program is when the filter is first read.
`known` raised a typecheck for any key that can't be a key here (an
array, a dictionary, a real with a fraction). The PLRM allows any
object but null as a key, and since `put` refuses such keys, no
dictionary holds one: `known` now answers false, and null still raises
the typecheck. Ghostscript's eps2write prolog looks each inline-image
value up in a dictionary of abbreviations, and an image with two
filters has an array there.
The standard encodings were names in systemdict only, and the Encoding
category was empty, so `/StandardEncoding /Encoding findresource`
failed with undefinedresource. The PLRM (3rd ed.) has both as
instances of the Encoding category, the same arrays as the names.
Ghostscript's eps2write prolog takes StandardEncoding that way for a
font whose encoding is a Differences dictionary with no BaseEncoding,
so files with its Type 3 text stopped there.
An agent confined to automation roots could load the place cursor, with
file.place.queue or tool.setOption, and the files were placed later, by
a click of the person at the keyboard, outside any roots. tool.setOption
checked a queued path but not files given inline, whose linked files (an
SVG's referenced images) were then read with the keyboard user's
unrestricted access.
The session now keeps the automation roots in force when the cursor's
queue is loaded, and both the engine's own placement and the desktop
app's background placement read the queued file within them. A queue
loaded outside any roots places as before.
Reflow copied each listed frame's text into its thread's story, so a
document that listed one frame several times in a thread, or in several
threads, repeated that text in the story and wrote the grown story back
for the next thread to copy again, growing the text with every
repetition while the document opened. Reflow now keeps each frame at its
first place in the thread list only.
The filter that keeps brush pieces from drawing a brush again walked a
mask's art but never looked at the mask's root itself. A symbol instance
at the root of a mask, whose symbol draws a stroke with the brush, then
survived and re-entered the brush while the mask was rendered, without
end. The mask goes now, as such an instance goes among the children.