Coordinates outside -32,768 to 32,767 plotter units (about 82 cm from the origin) are written as they are, with a warning that older devices may not read them. HP-GL/2 plots are not checked against this range.
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.
With one whole blend selected, the Selection and Blend tools show two
widgets at the halfway point of its spine. Dragging the upper widget
along the spine sets the color shift (-100 to 100), and dragging the
lower one sets the easing strength (0 to 100). The lower widget shows
only when the steps follow a spine (a replaced spine or Align to Path),
the rule the step placement uses; a blend made without a spine shows
neither. When the boxes of three or more other visible objects hold a
widget's spot, the widget moves out in 16 px steps, up to 144 px, and
its line to the halfway point grows with it. While a widget is held,
the arrow keys step its value by 1 (Shift: by 10), and Escape or a
switch to another tool cancels the drag. A drag is one undo step; a
click or a drag that ends where it started records none.
- object.blend.setEasing sets easingType, ramp and colorShift on one
blend, refuses a hidden or locked blend and easing on a blend without
a spine, and records no undo step when nothing changes.
- BlendSpec::eases_along_spine holds the rule the step placement and
the widget share.
- While a tool is busy, an arrow it claims arrives with the press's
Shift and Alt; before, it always arrived plain.
Docs: docs/mcp.md, docs/target-app-parity.md.
With Revolve (Classic) on a group, a member whose gradient has
transparent stops drew its whole surface in the members' order, so it
could cover a member in front of it or hide behind one it is in front
of. Its faces now take their places in the one back-to-front order of
every member's faces, in runs as a member with transparency of its own
does, and each run carries the member's opacity mask.
ui.dialog.set took every field whose name starts with `__`, so a control
request (or MCP's answer_dialog, which goes through it) could rewrite the
`__command` and `__params` of a confirmation or the generic parameter
dialog, a plug-in command dialog's `__command`, or the paste a swatch
conflict waits to finish, after a person opened the dialog. The person's
OK then ran something else.
A `__` field is now settable only when it is a control of that kind of
dialog: a section or tab shown, a link between two fields, a name or
search being typed (for example Save PDF's `__section`, Transform Each's
`__constrain`, the Preferences `__search`). Every other `__` field, held
or not, is refused with "the `<kind>` dialog cannot set protected field
`<field>`". The request sets no field, and with `action: "confirm"` OK
does not run. Flags a button sets together with other fields are refused
too: the style dialogs' `__reset*`, Artboard Options' `__fit`,
`__sizeChoice`, `__refx` and `__refy`, and Scribble's `__scribbleSetting`.
Recolor's Merge takes a row listed twice in the selection once, and
Randomize keeps a seed at u64::MAX instead of overflowing it.
Docs: docs/control-protocol.md, docs/mcp.md, docs/target-app-parity.md.
Effect > Refresh Deferred Effects looked up the objects asked for, the
stages reached, the objects drawn whole and the inputs that ran with
Vec::contains, and counted each target stage by scanning every deferred
record. Asking whether a stage stays deferred and replacing a stage's
records when it runs also scanned every record.
Deferrals::refresh now keeps the objects asked for and the objects drawn
whole in sets, and Refresh's ids, retried, visited and touched and
Pass.ran and seen are sets. The deferred records are kept in a BTreeMap
by the order they were made in, with an index by stage and input key, so
holds, State::remove, settle and the refresh's reconciliation and count
look at the records of the stages concerned only. The targets, counts,
records kept and their order, marks and revision are unchanged.
Docs: docs/target-app-parity.md.
After Replace Spine the keys are not pinned to spine anchors, so the
steps spread them evenly along the spine by arc length and put a moved
key straight back where it was. Once a key is moved off its place, the
spine is laid out pinned at the anchors where the keys were spread, and
the moved key takes its point of the spine along, as on a pinned spine.
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.
The 3D and Materials rows of target-app-parity.md's area tables now name
Rotate (Classic) and Map Art as the 3D (Classic) work that remains, as
effects-parity.md and gaps.md do.
Adds Gujarati to the target-app-parity localization evidence list and
the docs/roadmap.md milestone notes, following the Hindi entries, and
marks the catalog as reviewed by a native speaker with zero/one
singular plurals. Scores and estimates unchanged.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Gujarati takes the singular form for 0 and 1, as Hindi does, so gu now
uses plural_french. add_craft_fonts installs Gujr faces into the UI
families the way it installs Deva faces, so a bundled Gujarati face is
used and bundled_fonts_cover_the_catalogs holds when one is added.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A save or export that writes a file per artboard, linked images or image
maps names them after the file picked in the save panel, which asked only
about that name. A file already there under one of the other names was
replaced without a question.
Save As, Save a Copy, Save as Template, Save and Export now check those
files before writing anything. When any is there, nothing is written and
a replaceFiles question names it (and lists all of them when there are
several). OK runs the save or export again on the document that asked and
replaces the named files; a file it would now write that the question did
not name is asked about again. Cancel writes nothing. A background save
or export checks from its worker and asks once it ends, after a dialog
open then. Files the document's last Save or Save As wrote are replaced
without asking.
Services::exists is now an Arc<dyn Fn(&str) -> bool + Send + Sync>.
Under --automation-read-root, document.inspect gives `path` as null when
the document's file is outside the read roots. document.json names a
linked image or placed file outside them by its file name alone, without
its relative path, size or date, in the layers, symbols, graph designs,
patterns, the pattern being edited and opacity masks. It also names a
data set's image value outside them by its file name, and leaves the
Export for Screens folder outside them out of export_settings. The
document is not changed, and unconfined callers see the same replies as
before.
Type > Dynamic Text and the Contextual Task Bar now also take point
type. Turning it on makes the point type area type with Block on, in
the same undo step:
- Along the lines, the frame is as wide as the widest line as typed
with its paragraph's indents, measured with the word gap, so that
line keeps its size and stays where it was across the page by its
own alignment. The other lines are set to that width. When negative
indents take more than that line's width, the frame is as wide as
the line, placed so the line keeps its aligned point, and Block makes
the line larger.
- The frame starts at the top of the text and grows down (to the left
for vertical type) to hold every fitted line, around any Text Wrap
objects above it, so nothing overflows.
- The new frame takes the default Area Type Options and keeps only the
gaps; options kept from an earlier frame do not carry over.
- Point type with no line to fit (empty, or only spaces and breaks) is
left as it is, and so is point type when `on` is false. Without `on`,
point type counts as off, and the Type menu item is unchecked when
point type comes first in the selection. A gap given with nothing it
can apply to is an error.
Block now subtracts a list level's indent from the room it sets each
line to, as the layout does. Before, a nested list item was first set
too large for its line and then made smaller on a later pass.
Docs: docs/mcp.md, docs/target-app-parity.md.
A {Custom: {name, path}} head is refused when its path fills no area under the
non-zero rule: a single anchor, points on one line, or contours that cancel out.
A bow tie and a thin bar are taken. The params text and docs/mcp.md state the rule.
Window › Swatch Libraries › Gradients gains Holographic, after Organic
Fades: seven foils (opaque linear gradients of six narrow pastel and
pearl bands with off-center midpoints) and seven glows (radial
gradients from a bright center out to a clear edge), all mixed with the
Perceptual method. They also list in the Swatches panel's library menu,
swatch.library.list/get/add and the Gradient panel's Presets.
The names, colors and stops are VectorCraft's own. A saved preset that
already uses one of the new names is renamed with the first free number
when the preferences load.
Docs: docs/target-app-parity.md Swatches line, ROADMAP.
Window › Brush Libraries gains Ink and Wash after Art Ribbons: Tapered Ink, an art brush broad near its start that thins to a fine tip; Brush Pen, a calligraphic brush whose size follows the pen pressure; and Soft Wash and Pooling Wash, art brushes of translucent gray layers. The art brushes take the stroke color as tints. The names, shapes and opacities are VectorCraft's own.
Docs: docs/mcp.md, docs/gaps.md, docs/roadmap.md, docs/target-app-parity.md.
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.
Korean text broke after every Hangul syllable. A paragraph now has
Korean Line Break Anywhere, set from the Paragraph panel menu (with the
East Asian options), from the East Asian Composition Settings section of
Paragraph Style Options, and with `text.setFormat {koreanLineBreakAnywhere}`.
- Off, a word that contains Hangul (the characters between spaces) breaks
only at its spaces and after East Asian punctuation, or where the word
is wider than the line. Both composers follow it, and the word takes no
hyphen. On, a line may break between any two syllables, as before.
- New type has it off. Paragraphs and text objects saved before the
option read as on, so their lines do not move; the value is saved only
when it is off.
- Paragraph styles carry it, Reset Panel turns it off, and the .ai writer
reports it as lost for Korean paragraphs.
The help page: https://helpx.adobe.com/illustrator/desktop/design-with-text/fonts-and-scripts/set-line-breaks-korean-text.html
The command is described in docs/mcp.md, and docs/target-app-parity.md
lists the option.