Commit Graph
1931 Commits
Author SHA1 Message Date
NetterSilverandClaude Opus 5.5 2264edd0c9 Lasso picks gradient mesh points instead of dropping the mesh
Fixes #5351

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-03 22:16:53 +07:00
dotCooCoo 4db6e7b448 Paint: use the document color model for new gradient defaults 2026-11-03 20:18:34 +07:00
bflatastic bc70180047 Text Tweaker: an id that isn't type is refused as ids of it is 2026-11-03 20:07:58 +07:00
ruchirguitarandClaude Opus 5.5 8850b923ce Fix #4924: Text Tweaker ramps or randomises one character attribute letter by letter
A built-in Type Tools add-on (Object › Plug-ins › Type Tools › Text Tweaker…,
`addon.type.textTweaker`): size, baseline shift, rotation, horizontal or vertical
scale, tracking, leading or stroke weight go from a start value to an end value
along a straight ramp, an ease, a bow, a spike or at random with a seed, set as
the Character panel sets them, while the text stays live. One undo step, a
dialog with Preview, catalog rows in all 26 languages, docs/mcp.md and the
parity docs.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-03 20:07:58 +07:00
ruchirguitarandClaude Opus 5.5 d7aa1c561f Fix #5236: Edit Original is one checkbox, Use System Defaults for Edit Original
Per review on #5327: Preferences › File Handling › Edit Original With (an app
path and Choose…) becomes the checkbox Use System Defaults for Edit Original,
on by default. Off, Edit Original opens a raster image in the app that made
it, PhotoCraft, looked for only where it installs; any other file, or no
PhotoCraft, goes to the system's default app. The preference is a boolean, so
prefs.set over control or MCP can no longer name an executable. The label has
a row in all 26 catalogs.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-03 19:57:04 +07:00
ruchirguitarandClaude Opus 5.5 d11764c117 Fix #5236: Edit Original opens linked files in a chosen app
Preferences › File Handling › Edit Original With picks the app Links
panel › Edit Original opens a linked file in: System Default (as before),
PhotoCraft (found in /Applications or ~/Applications on macOS, on the
PATH elsewhere) or Other Application, with a path field and Choose….

The desktop host's new `open_file_with` service starts only an
application (an .app bundle on macOS, an .exe on Windows, an executable
file elsewhere), with the path as its only argument and never through a
shell. Edit Original still refuses control requests.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-03 19:57:04 +07:00
Prin.IngandClaude Opus 5.5 2380e889bc Group flattened multi-line transparent type by line
Fixes #5252

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-03 17:00:52 +07:00
dotCooCoo e1ea0ecad1 Type: the caret, a click and the arrow keys reach the characters inside a ligature
Squashed from #5225 onto main.
2026-11-03 16:38:36 +07:00
dotCooCoo 86deb546ad Variables: Import Data Sets reads every column as a variable and replaces the data sets
Squashed from #5151 onto main.
2026-11-03 16:38:29 +07:00
dotCooCoo af17c648c0 Find Font: Change and Change All add no undo step when no text changes
Squashed from #5204 onto main.
2026-11-03 16:38:17 +07:00
dotCooCoo 2b29a680f3 Objects on Path: the Space widget spaces the attached objects along the path
With one Objects on Path group of two or more objects selected, the
Selection and Objects on Path tools show a square Space widget beyond the
last object, ahead along the path. Dragging it moves the last object
along the path, around its bends, as far as the pointer moves along it,
and the objects between follow evenly while the first one stays. With
Alt (Option on macOS) the objects spread from both ends toward or away
from the center of an open path, or of the first anchor of a closed one.
The distance between the objects shows next to the pointer in the
document's units; the drag is one undo step, and Escape cancels it.

- object.objectsOnPath.options takes spacing (points, or "auto", the
  default even spread) and start (points from the first anchor). A
  spacing the path has no room for is drawn smaller and kept, so a
  longer path brings it back. Older files read as Auto.
- Moving the group, Pivot, Rotate, path edits, copies and saving keep
  the Space. Scaling, rotating or shearing the group keeps the first
  and last objects where the transform takes them on the new path, live
  shapes included; a value that cannot be kept that way scales with the
  path's length.
- The Rotate All widget follows the first object when Space moves it.

Behavior: https://helpx.adobe.com/illustrator/desktop/manage-objects/arrange-objects/rearrange-and-edit-objects-on-a-path.html
and https://helpx.adobe.com/illustrator/using/objects-on-path.html.
2026-11-03 16:03:40 +07:00
dotCooCoo c633e09d3a Exclude empty runs from matching text selections 2026-11-03 16:03:40 +07:00
dotCooCoo 4b683c3a98 Window: with Open Documents As Tabs cleared, new documents open in windows
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.
2026-11-03 16:03:39 +07:00
dotCooCoo 84e344c475 Character Styles: Style Options sets character color and OpenType features
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.
2026-11-03 16:03:39 +07:00
dotCooCoo e01823c2eb Gradient: a dropped or canceled point drag keeps the point selected
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.
2026-11-03 16:03:39 +07:00
dotCooCoo 641ac7e301 Canvas: a dropped press puts back the tool's options and keeps the path being drawn
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.
2026-11-03 16:03:38 +07:00
dotCooCoo 2d6cf9020b Canvas: a dropped press cancels the tool's drag instead of ending it
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.
2026-11-03 16:03:38 +07:00
dotCooCoo 58e6ce9f02 Type: a text.setStyle stroke gives unstroked characters 1 pt
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.
2026-11-03 16:03:38 +07:00
dotCooCoo b1dc20b811 Type: text.setStyle sets the text's stroke as well as its fill
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.
2026-11-03 16:03:38 +07:00
bflatastic c59cd281db Format with rustfmt 2026-11-03 16:03:38 +07:00
Dylan M. Taylor 06139d0011 Export for Screens: keep PDF passwords out of remembered settings
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.
2026-11-03 16:03:38 +07:00
bflatastic 47bc3dd58c Flatten Transparency: iterate the test's groups directly (clippy needless_range_loop) 2026-11-03 16:03:38 +07:00
bflatastic 6b30867eba Flatten Transparency: use is_multiple_of (clippy) 2026-11-03 15:57:57 +07:00
Dylan M. Taylor e505bccd5e Format with rustfmt 2026-11-03 15:57:52 +07:00
Dylan M. Taylor b032766a66 Flatten Transparency: group overlapping objects without comparing every open pair
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.
2026-11-03 15:57:52 +07:00
bflatastic 4ab16b7760 Clipboard: compare the PNG scale directly (clippy neg_cmp_op_on_partial_ord) 2026-11-03 15:57:51 +07:00
Dylan M. Taylor 15cd642be8 Clipboard: leave out the PNG of art too large to scale to 4096 pixels
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.
2026-11-03 15:57:05 +07:00
Dylan M. Taylor 2fec613353 Place: the place cursor reads its files within the roots it was loaded in
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.
2026-11-03 15:56:55 +07:00
Dylan M. Taylor a4aa1960cf Threaded text: a frame listed twice flows the story once
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.
2026-11-03 15:56:53 +07:00
Brandon Thomas 065a646799 Merge pull request #5280 from dotCooCoo/feat/symbol-nine-slice-guides-on-canvas
Symbols: 9-slice guides are shown and dragged on the canvas while editing a symbol
2026-11-03 00:19:44 -05:00
Brandon Thomas d232a29591 Merge pull request #5237 from dotCooCoo/feat/global-edit-shift-exclude
Global Edit: a Shift-click on a highlighted match leaves it out of the edit
2026-11-03 00:19:36 -05:00
Brandon Thomas 7f484253d2 Merge pull request #5304 from storytold/fix/sec-export-name-linear
Export for Screens: name patterns and taken names take linear work
2026-11-03 00:19:29 -05:00
Brandon Thomas 69fa98dc94 Merge pull request #5302 from storytold/fix/sec-affinity-master-copy-cost
Affinity import: count path segments and masks in master page copies; range-check vector masks
2026-11-03 00:19:26 -05:00
Brandon Thomas 9c91939701 Merge pull request #5300 from storytold/fix/sec-resource-name-index
Brush and symbol libraries: look definitions up by name
2026-11-03 00:19:22 -05:00
Brandon Thomas 57e0e55bba Merge pull request #5244 from dotCooCoo/feat/select-same-text-fill-stroke
Select: Same › Text Fill & Stroke Color selects type whose fill and stroke both match
2026-11-03 00:18:46 -05:00
Brandon Thomas a824ea9ea1 Merge pull request #5260 from dotCooCoo/fix/document-info-counts-each-object-once
Document Info: Objects counts each object once
2026-11-03 00:18:35 -05:00
Brandon Thomas cc1d906c4c Merge pull request #5259 from dotCooCoo/fix/tcy-style-offsets-in-range
Type: Tate-chu-yoko offsets in character style definitions stay in range
2026-11-03 00:18:32 -05:00
Brandon ThomasandClaude Opus 5.5 14d617f1d4 Format the symbol library test (rustfmt)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-02 23:44:01 -05:00
Dylan M. Taylor 9086842f4b Format with rustfmt 2026-11-03 04:31:56 +00:00
Dylan M. Taylor 9a1ac9dad3 Brush and symbol libraries: look definitions up by name
Making a brush or symbol library, and gathering the resources copied
art uses, found each referenced swatch, symbol, pattern, graphic style,
text style and brush by scanning all the definitions of its kind, and
checked library membership and panel order by scanning the lists again,
so a library or document of N definitions cost N squared comparisons.
Each kind is now indexed by name the first time a reference to it is
followed, and the library code looks names up in sets and maps built
once.
2026-11-02 20:38:22 -05:00
Dylan M. Taylor 1d7c8f93ab Export for Screens: name patterns and taken names take linear work
The file name pattern searched the rest of the pattern for a closing
bracket at every opening bracket, so a pattern of many unmatched brackets
took quadratic time to render, in the export and its live preview. A
token's name never holds a bracket, so the search now stops at the next
opening one.

Output naming tried -2, -3 and so on from the start for every file given
a taken name, so one name pattern over many artboards rebuilt and looked
up every number used before for each file. It now goes on from the last
number given for that name, and remembers which file got a name from it.
2026-11-02 20:35:58 -05:00
Dylan M. Taylor 653f178b28 Affinity import: count path segments and masks in master page copies
Master page copies were charged one unit per shape whatever its number
of segments, and nothing for attached vector or pixel masks, so a master
holding one huge curve or mask could be rebuilt on thousands of pages
within the copy allowance. Copy costs now count every subpath and
segment of a shape's path and its vector mask, and a pixel mask's
pixels.

A node's vector mask also skipped the document range check the node's
own art passes; its control points are now checked as mapped into the
document (non-finite ones included) and an object whose mask reaches
beyond the range is left out, as one whose art does.
2026-11-02 20:33:10 -05:00
dotCooCoo eaab849f42 Document Info: count objects that share an id as separate objects
The walk that skips objects it has already visited keys them by address
instead of id, so two objects that share an id in a damaged file are
both counted. An object reached through a selected group and again on
its own still counts once.
2026-11-02 17:01:29 -08:00
dotCooCoo 33f429972b Merge main (11862f61) into feat/native-save-precision 2026-11-02 16:29:45 -08:00
dotCooCoo e2b6903a3a Symbols: test that a guide dragged on the canvas changes how a scaled instance draws
A 200 x 150 instance of a 9-slice symbol draws its 10 pt corner square about 17.14 pt wide once the left guide is dragged from 25% to 5% in symbol editing mode, as the square then reaches into the stretched center band.
2026-11-02 13:41:39 -08:00
dotCooCoo 537511ae65 Symbols: a dragged 9-slice guide moves with Real-time Drawing off
With Performance > Real-time Drawing and Editing off, tool previews are
applied only on release. A ruler guide being dragged was already exempt;
a symbol's 9-slice guide, a symbol.options preview that sets only
nineSliceGuides, now is too, so the dotted guide follows the pointer
while it is dragged. The release still leaves one Symbol Options step.
2026-11-02 13:03:45 -08:00
dotCooCoo 5f20bbc3e8 Document Info: test that a Repeat object in a selected group is listed once
With Selection Only, a selection that holds a group and the Repeat object
inside it, in either order, lists that Repeat object once.
2026-11-02 08:25:02 -08:00
dotCooCoo 588ff039a9 Type: Tate-chu-yoko offsets in character style definitions stay in range
A character style whose Up/Down or Left/Right offset lies past MAX_COORD
either way now opens with the nearer end, as text runs already do, so
text that takes the style no longer gets the out-of-range offset. An
offset within range is not rewritten.
2026-11-02 06:32:52 -08:00
dotCooCoo 8b249f8275 Document Info: Objects counts each object once
An object with a gradient or a pattern on both its fill and its stroke
counted twice in Objects. It now counts once for each paint kind it uses.

With Selection Only, a selection that holds a group and an object inside
it walked that object twice, so the object counts, the paths' total
length and Repeat Objects counted it twice. The walk now visits each
object once.
2026-11-02 05:06:38 -08:00
dotCooCoo fa8addaa12 Select: Same › Text Fill & Stroke Color selects type whose fill and stroke both match
Select › Same › Text Fill & Stroke Color (select.same.textFillAndStrokeColor) selects the type
objects with a run of characters whose fill and stroke both match the first character of the
first selected type. Type that matches only the fill or only the stroke, or has the fill in one
run and the stroke in another, is left out. The entry follows Text Stroke Color in the menu and
has a row in every catalog.
2026-11-02 03:37:17 -08:00