A library called COM¹ is saved as COM¹-, which can be the file of a library
really called COM¹-, and the numbered file one of them then gets can be asked
for by a third name. Saving one replaced the other. Each now gets a free file
name, and saving it again goes back to that file.
Each visible object with a URL (Attributes panel) is written as a Link
annotation with a URI action over its bounds on the page, trimmed to its
clipping groups. Hidden objects, non-printing layers and printed sheets get
none; PDF/X files leave them out with a warning. URIs are percent-encoded
to 7-bit ASCII.
A colorized image whose pixels are all black or white (or clear) is
written as a 1-bit image mask (ImageMask 1): its color as the fill, a 0
bit for each black pixel and a 1 bit for each white or clear one. The
legacy reader opens it colorized again with the same clear pixels, so
the engine no longer flattens or omits it. Other colorized images are
written with their color in their pixels, over white, with the note
for transparent images.
object.blend.spine.moveAnchor now refuses any supplied `with` (even an
empty list) together with `handle`. Direct Selection builds the blend
spine once when drawing the picked points and once per drag preview,
instead of once per picked point. Part of #5285.
When a frame's text ends with a paragraph break and the next frame is empty, restyling that empty frame was undone on reflow: an unedited empty frame after it gave the story's last paragraph its own style again. A restyled empty frame now keeps its style against unedited empty frames that follow it. Unedited empty frames before it, later frames with text and later restyled frames still give the paragraph their style, as before.
The remaining flags under crates/engine/src/cmd that read a boolean with
get(..).and_then(Value::as_bool).unwrap_or(..) now go through switch_or,
so a value such as "false" or 1 is an error instead of the default.
Omitting a flag or giving null keeps the old behavior.
- effect.move: copy
- aligned on the appearance.*, stroke.set, transparency.set and effect.*
commands, checked before any early return
- transparency.viewOpacityMask: on
- view.printTiling: on
- plugin.install: replace and allowHeavy, checked for every plug-in
- edit.clear: guides, and path.deleteAnchors' read of it
- text.create and text.createInPath: vertical (already refused by
check_switches, so their behavior is unchanged)
The regression test for rebuilding fitted area type after a scale change
used text that overflowed at the minimum size both before and after the
change, so both layouts used the same fit scale and the pixel comparison
did not depend on the fit.
The fixture is now 2 pt type in a small frame, drawn 20 times zoomed in.
It fits at 0.7 of its size, and at 0.733 after a 1.5 times scale. The
test asserts that the two fit scales differ and that the words set at the
earlier fit draw different pixels, and keeps the comparison with a fresh
renderer and the check that the geometry is not reused.
Each definition's reader started with fresh blend layout and envelope
check budgets, so a file with many symbols, patterns or brush art
sections got those limits again for every definition. The reader of a
definition now takes the import's remaining budgets and hands back what
is left after reading, whether the definition is kept or not.
With the Artboard tool, the Properties panel now starts with a Transform
section: the reference point shared with the Transform panel and the
Control bar, the active artboard's X and Y (of that point), W and H with
the Constrain Width and Height Proportions link, its preset and
orientation, and Move and Scale Artwork with Artboard. The Artboards
section follows with the name, Artboard Options and Fill. A new W or H
now keeps the reference point in place, as in the Transform panel.
The Control bar's Stroke: and Opacity: and the Properties panel's Stroke
are links to their panels, so a drag on them did nothing while every
other field label scrubbed its field. A drag on such a link now scrubs
the field after it (same steps and modifiers, one undo step, Escape
cancels); a click still opens the panel, and the link's text is not
selected by the drag.
Loading a variable library deleted every variable of the document with its
bindings, including a text variable of the same name that the library
declares. Text made dynamic and then given a library's variable name lost its
binding, so selecting the library's data sets changed nothing. Such a
variable now stays bound, and the library's data sets change its text; other
variables are deleted as before.
Inner Glow clipped to the art's outline and bled in from outside it; for a
placed image that outline is the frame, so a PNG with transparent areas
glowed along the frame's edge, over pixels that don't show. For an image the
glow is now cast by its pixels' alpha (everything around them, blurred, or
the pixels themselves with Center) and kept to where the image shows, as
much as it shows.
One selected radial, grid or mirror repeat (or one object of its source
art in isolation mode) shows a Repeat Options button in the Properties
panel's Quick Actions. It runs Object › Repeat › Options, opening the
Repeat Options dialog with the repeat's current values.
The area an Intertwine member is drawn over another in was exactly the
overlap face, so its edge lay on the edge of the member below. Both edges
were anti-aliased, and the member below showed through as a thin line along
them. The area now reaches 2 pt past the face into the parts where only the
raised member paints (where drawing it again changes nothing), so its edge
lies inside that member.
From about 50% zoom on the file of #4155, the pixels drawn are the full 141-megapixel photo,
and in a CMYK document they were separated into ink planes (or colorized, or proofed) whole
for every view: 8 to 9 s of white canvas a zoom step.
When the pixels drawn are larger than a 1,024-pixel tile, their colours are made again for the
frame and part of them is out of view, only the tiles in view are made, each kept under its own
key (`ImageKey::tile`), and drawn together as one pixmap so their edges don't show. The colours
are made pixel by pixel, so the result is the same as for the whole image. CMYK images painting
their own inks are still made whole.
Zooming in to 50%, 100% and 200% on that file went from 9.0, 8.6 and 8.7 s to 0.78, 0.05 and
0.05 s (M3 Pro, one run each), with the same pixels on screen.
Direct Selection kept only one picked point of a blend's spine. Shift-click
now adds a point of the same spine or takes it away, and dragging any picked
point moves them all. object.blend.spine.moveAnchor takes `with`, the other
points to move by as much, with the key objects on them, in one undo step.
SVG text with a textLength came in at its natural width. Following
SVG 1.1 §10.9.1, the characters of each text or tspan with a textLength
are now fitted to it: by spacing them out (lengthAdjust="spacing", the
default), which becomes kerning, or by stretching them
(spacingAndGlyphs), which becomes horizontal scale (kept within
1–10000%). Inner elements are fitted first; vertical text is spaced out
only, with a warning for spacingAndGlyphs. Negative lengths are ignored.
The Join tool drew a segment between the open ends of two crossing paths
instead of trimming what overhangs the crossing. path.joinScrub now looks for
two crossing open subpaths whose overhanging ends the scrub runs over, cuts
both at the crossing and joins the kept parts there with a corner, in one undo
step. Without a crossing the endpoint join is unchanged.
A clipPath with several children was imported as one compound path under
the first child's fill rule, so children wound in opposite directions
cancelled where they overlapped, and an even-odd child after a non-zero
one lost its hole. SVG 1.1 §14.3.5 defines the clip as the union of the
children's silhouettes, each computed on its own.
A clipPath with several children now comes in as a group of them as the
clip group's clipping path, each child keeping its own rule; a group
clips to the union of its members. One child imports as before.