Done (pattern editing), Stop Editing Opacity Mask and Exit Isolation
Mode end the Type tool's edit first, so point type a click placed and
left empty is discarded. While a Cmd/Ctrl press had lent a selection
tool, the Type tool was not the active tool, its edit was not ended,
and the empty point type was saved into the pattern tile or the mask.
The lent tool is now given back first. A drag the lent tool started is
kept as its own step, with its last position applied when Real-time
Drawing and Editing is off.
A layer nested in a group whose art was all locked counted for nothing,
so the group was hidden or locked with the layer inside it. The selected
layer now counts as selected itself.
While Lock Guides was on, a guide path that was locked itself, or sat in
a locked object, was not kept, so the group around it was hidden. Guide
paths inside locked objects are now kept too.
Remove Text Tweaker's own start and end check: range_of already refuses
a bad offset given with an id, and like the other type commands Text
Tweaker now ignores start and end without one. The test's "2" case
gets an id so it still reaches the check, and docs/mcp.md lists
addon.type.textTweaker with the commands that refuse such offsets.
text.startList read a negative or fractional `at` as the end of the
text, so it could remove a typed list marker there and start a list.
The `start` and `end` of text.editRange, text.getRange,
text.setRangeStyle and the type shortcut commands given an `id` read
such values as the start or end of the text.
These now return "`at` must be a whole number" (naming the key) and
change nothing. Omitted or null keys keep their defaults, and 2.0 is
read as 2.
Opening a .ai or a PDF read and checked the whole file up to five
times: for the document it carries, for whether it holds the editor's
private data, for the import, for the editor's copy and for its File
Info. Each pass parses the file and walks every object, about 190 ms on
a 15 MB .ai.
- vectorcraft_pdf::open_pdf reads and checks the file once, on the
import's deep-stack thread, and import_opened imports pages from that
reading. document.open takes the carried document, the page count,
the editor's copy and the File Info from it. The editor's copy is read
after the page import and only when the file is not restored from a
carried document; so is the File Info.
- A .ai saved without PDF compatibility opened with pages that name
every page reads its editor's copy from the same reading.
- document.pdfInfo reads the file once for its pages and the thumbnail.
- The Open and Place dialogs read the file once to decide whether to
ask for pages, instead of twice.
A file whose PDF part fails the check still reads its editing data
separately, as before.
Object > Expand with Object on now turns each symbol instance in the
selection, including one in a selected group or in a placed document's
art, into its art, as Break Link to Symbol places it. It goes one level
deep: the instances in that art stay instances. The art keeps the
instance's id and place in the stacking order, and Expand stays one
undo step.
- Instances with effects stay instances, and Expand Appearance bakes
them as before. Instances with an effect on a fill or stroke,
instances in perspective, and those in blends, repeats and Intertwine
groups stay instances.
- The art keeps the instance's opacity mask, as Break Link gives it.
- A hidden or locked instance's art stays hidden or locked.
- A placed document in an instance's art is expanded too.
- When the instances' art would make more than 1,000,000 objects, they
stay instances, the limit Break Link uses.
- The Fill and Stroke options (object.expand.info, and the Expand
dialog) count the fills, strokes and gradients in the art of those
instances, with a dynamic instance's own changes applied. The info
reports under symbolArt which of them only that art holds, and the
dialog enables those options only while Object is on.
While the Type tool edits a frame of threaded text, Select All selects
the text of every frame of the story, highlighted in each frame. The
tool edits the first frame that holds text.
- Typing, Delete and Cut replace the whole story as one undo step
(`text.editRange` takes `clear`, the other frames whose text goes).
- Copy and Cut take the whole story (`text.getRange {id, story: true}`).
- Fills and strokes, `type.step`, `appearance.copyFrom`, the Character,
Paragraph, OpenType and text style panels, the Tabs panel's tab
stops, the font menus and the Justification dialog act on every
frame's text (`text.setRangeStyle {id, story: true}` styles them in
one edit).
- A caret move, a click or a word or paragraph selection ends it.
Select All in unthreaded type is unchanged.
Docs: docs/mcp.md, docs/target-app-parity.md.
Convert to Smooth or Corner on a blend whose spine came from Replace
Spine stored key anchors with the converted spine, so the spine's
points then moved onto the key centers. It now changes only the
spine's handles: the points stay where they are and the keys stay
spread along the spine. Direct Selection's spine conversion and the
other spine edits are unchanged.
Capture sweep-piece source attribution before endpoint pinning can move its
midpoint off the original outlines. Keep the existing lookup after pinning
when the original piece has no source.
Add planar coverage and native compound Make/Expand/undo regressions, and
document the existing front-most source-fill rule.
With a group isolated, a selected layer or group that holds the isolated
group is not selectable itself, so the type inside the isolated group was
never reached and the font Same commands returned "select a text object".
The walk now goes through such a layer or group to the type inside the
isolated group that can be selected.
A save as .ai or .ait (file.saveCopy, file.saveAs, document.save and
file.saveAsTemplate) set range to "all" before the file was written.
The one exception was a legacy .ai of version 7 given a range, which
its encoder checks. Every other save accepted an artboard, artboards or
range that names an artboard the document does not have (artboards: [5]
on a document of three artboards) and wrote every artboard.
document.export refuses the same value.
The save now refuses such a value with the export's error, under the
name of the command that was run, and writes no file. A range that is
not text, such as range: 42, was also replaced by "all". The save now
leaves it for the encoder, which refuses it as an export does. An
artboard the document has, or an empty artboards list, is still saved
with every artboard, and a legacy .ai still writes the artboards of its
range.
Select > Same > Fill Color, Stroke Color, Fill & Stroke, Stroke Weight,
Opacity, Blending Mode, Appearance, Shape, Graphic Style and Appearance
Attribute compared the other objects with the first selected object,
even when select.set had put a hidden or locked object, one on a
template layer or one outside the isolated group first. They now take
the first selected object that the Select commands could select, in
selection order, and keep the compound path and isolation rules for it.
A selection that holds no such object returns "nothing selected".
A layer that was selected (for example with select.set) gave no reference to
Select > Same > Font Family, Font Family & Style, Font Family, Style & Size,
Font Size and the text fill and stroke color commands: the layer itself is
not selectable, so the type on it was never reached and the command returned
"select a text object". A selected layer or sublayer now gives the type on it
that can be selected. A hidden, locked or template layer gives none.
Break Link to Symbol dropped the instance's opacity mask. The art now
keeps it, or a group around the art holds it when the symbol's art has
a mask of its own. The objects in the instance's mask art count against
Break Link's limit of 1,000,000 objects.
A `start` or `end` such as -1 or 1.5 was read as absent and changed text
before the range; it is now refused. Characters that already have the value
are left out, so a run that changes nothing returns count 0 and makes no
undo step. docs/mcp.md cites the public formatting-type page.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The test moves from an inline module in cmd/textedit.rs to
tests/charstroke.rs and uses that file's helpers. docs/mcp.md says that
text.setRangeStyle gives a range's stroke a 1 pt weight as text.setStyle
does, and that its strokeWidth and strokeOptions lengths are in document
points.
A graph keeps the paint and stroke weight given to a series' marks, but not
the opacity of their fill or stroke row. An opacity set with
`transparency.set {item}` or `appearance.setItem {opacity}` on a column,
bar, line or other series path was lost the next time the graph was drawn
(a data, type or option change).
- `SeriesPaint` gains `fillOpacity` and `strokeOpacity`. A setItem opacity
on the topmost fill or stroke of a series path stores it, in the same
undo step, and the generator puts it on the topmost fill and stroke of
every path directly in that series' group. Graph designs keep their own
opacity. A value read from a file is held to 0..1.
- The Appearance commands that change the opacity of a series path's
topmost fill or stroke (add, remove, duplicate and move a row, Clear
Appearance, Reduce to Basic Appearance, `appearance.transfer` and the
Eyedropper) update the stored opacity. They do not change the stored
paint, which only `paint.setFill` and `paint.setStroke` set.
- An edit that leaves a series path fully opaque stores nothing for a
series the graph keeps nothing for.
When the layers fail the comparison with the file's own page because some objects draw
differently (an object in another color, or one that only one side draws), the import finds
each top-level object whose bounds hold a patch of such pixels (the smallest one that holds it)
and replaces it with the page's art in its bounds, in the same way as an unread object. It then
compares the layers with the page again. When that comparison passes, the layers stay, and a
warning names the layer or sublayer of each replaced object (`<Layer>` for one without a name)
and how many were replaced on it. Like the warning for unread objects, this warning counts as
a loss, so an export or Save As to the file's own path needs `acknowledgeLoss: true`. A
replaced wrap object keeps its wrap options, and area type is wrapped again around the page's
art. Placed files at their other placement are tried too when the first placement can't be
kept.
The file still comes in as its PDF part, with the same reason, when only edges or type differ,
when a difference lies outside every top-level object, when more than half of the top-level
objects (or more than 64) hold one, when such an object is or holds type or holds a wrap object
inside a group, when the page's type of a text object that stays would be copied into a
replacement, when the page's art can't replace an object for the reasons it can't replace an
unread one, when matching the differences to the objects would take too much work, or when the
second comparison still fails. Trusting the editing data keeps the objects as read.
Select > Same > Font Family, Font Family & Style, Font Family, Style & Size,
Font Size and the text fill and stroke color commands took the type to match
from the first type found among the selected objects. Type that is hidden or
locked inside a selected group, type on a template layer and type outside the
isolated group could set the reference. They now take it from the type that
Link Block Series starts from, in the same selection order. A selection whose
only type cannot be selected returns "select a text object".
Window > New Window was grayed out. It now opens another view of the
current document, with its own zoom, center, rotation, artboard and
Outline or Preview, as a tab of its own. While a document has more than
one view, each tab shows the view's number after the name
("Untitled-1:2"). An edit in one view shows in every view of the
document.
Tile, Cascade, Float in Window, Float All in Windows and Consolidate All
Windows arrange each view as they arrange a document, and Tile and
Cascade are enabled with two views of one document. A new view of a view
in a floating window opens in a floating window too. File > Close and a
tab's close button close the view; the document's last view closes the
document, asking to save it first. Next Document and Previous Document
step through the views in tab order.
Each Tile pane and floating window draws its view in its own Outline or
Preview, and switching views with the Artboard tool targets the artboard
the view shows. A switch to another view of the current document resets
the tool, as a switch to another document does (Session::reset_tool).
Artwork held over another view's tab during a drag switches to that
view, and a drop there moves it.
Fixes#4116
Add Anchor Points builds the new anchor list in one pass, Swatch Library add looks names up in sets, full_documents dedups placed keys with a set, width profile lookups and mark insertion use binary search, and the symbolism tools cap and thin the previews of a long drag as Liquify does.
Option errors and notes for a .ai save called the file a
"PDF-compatible .ai" even when the save wrote a version 7 file
(aiVersion: "7") or a file without PDF content (pdfCompatible: false).
- Option errors: a version 7 .ai is now called a "legacy .ai
(version 7)" in the errors for its artboard, artboards and range
options. A .ai saved without PDF content is called a
"non-PDF-compatible .ai" in every .ai option error (includeLinked and
embedProfiles included), and a "non-PDF-compatible .ait template"
when Save as Template writes it. aiVersion: "7" takes precedence over
pdfCompatible: false, as it does when the file is written.
- The error for encoding a version 7 .ai of several artboards as one
file names the legacy .ai.
- The note for a native option the file does not read (version,
preview, precision) names the same kind of file.
- The error for aiVersion: "7" on a .ait template no longer says that a
.ait template is always PDF-compatible, since Save as Template writes
one without PDF content. It now reads "aiVersion 7 writes legacy .ai
files, not .ait templates", with its rows in the message catalogs
updated.
A PDF-compatible file keeps its name.
Follow-up to #5301. flavour_types (and clipboard.flavours) still listed PNG for art too large to render at the smallest scale, and the omission was only logged. PNG eligibility is now shared, and flavours_with_warnings returns a warning the status bar shows.
Follow-up to #5305. Stripping passwords from remembered settings made the next export of a password-protected PDF row write an unencrypted file without a word. The stripped settings now keep a non-secret passwordRequired flag, and an export refuses them until a password is given again (or security without the flag is given).
Follow-up to #5303. When deduplication shortens a thread ([[a, b], [b, c]] -> [[a, b], [c]]) and no frame changed, the fast path dropped [c] without clearing its threaded continuation. A thread that lost a listing now counts as changed and is flowed again.