Commit Graph
1918 Commits
Author SHA1 Message Date
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
dotCooCoo c5bfa08663 Merge branch 'main' into feat/global-edit-shift-exclude 2026-11-02 02:17:18 -08:00
dotCooCoo c88d88548c Global Edit: a Shift-drag from a highlighted match selects it and moves it
A Shift-press on a highlighted object of the Global Edit waits for the release
to leave it out of the edit. A drag from it now selects it when the drag starts
and moves it with the selection, as a Shift-drag from an unselected object did.
The snap targets are gathered after the object joins the selection.
2026-11-02 01:41:48 -08:00
dotCooCoo 1cd5bc4016 Global Edit: a Shift-click on a match inside a selected group deselects the group
A match that sits inside a selected object is no longer highlighted, and a
Shift-click on it with the Selection tool deselects that object as before
instead of leaving the match out of the Global Edit.
2026-11-02 01:28:57 -08:00
dotCooCoo 8ab68e4223 .ai import: open the variable library and data sets from the editing data
Squashed from #5156 onto main.
2026-11-02 16:19:19 +07:00
dotCooCoo 952446253f File formats: Pixar (.pxr) images open and place
Squashed from #5231 onto main.
2026-11-02 16:18:48 +07:00
dotCooCoo 205e5b3e8b Global Edit: a Shift-click on a highlighted match leaves it out of the edit
While Global Edit is on, a Shift-click (not a Shift-drag) with the
Selection tool on a highlighted match, or on an object inside a matched
group, leaves that match out: it is no longer highlighted and later
edits leave it as it is. The object the edit started from stays in, and
Global Edit ends when fewer than two matches are left. Leaving a match
out is not an undo step.

- New command `select.globalEditExclude {id}` returns `{active, count,
  ids}`; the Selection tool calls it on the release of a Shift-click.
- `ToolContext::global_edit` gives the tools the Global Edit's objects.
- Label and messages in the i18n catalogs; docs/mcp.md,
  docs/ui-parity.md and docs/target-app-parity.md updated.

Source: https://helpx.adobe.com/ph_fil/illustrator/how-to/global-editing-sensei.html
2026-11-02 01:06:40 -08:00
dotCooCoo b30f7ad34c Fix #3118: PDF export writes CMYK inks, gray and spot tints as the document holds them
Squashed from #5080 onto main.
2026-11-02 15:22:38 +07:00
dotCooCoo d324440afb Pathfinder: blends, envelopes and warped objects can be compound shape members
Squashed from #5226 onto main.
2026-11-02 15:22:32 +07:00
dotCooCoo 83f2bfe9d6 Symbols: a scaled instance of a symbol with 9-slice guides keeps its corners and edges unstretched
Squashed from #5079 onto main.
2026-11-02 15:22:07 +07:00
dotCooCoo e68bf6af55 Variables: art on a locked artboard is not bound or rewritten by a data set
Squashed from #5118 onto main.
2026-11-02 15:21:58 +07:00
dotCooCoo 30dd4fe8f5 Select: Link Block Series checks the selection in linear time
The type objects in the selection are deduplicated with a set, each frame's
thread is looked up in a map built once, the locked artboards are measured
once per call, and the menu check stops at the first selected type object.
2026-11-02 15:21:51 +07:00
dotCooCoo 405cc83cae Select: Link Block Series ignores selected type that Select All cannot reach
Type selected by id on a hidden, locked or template layer, or outside
the isolated group, no longer counts as selected type: the command stays
off and does not select that frame's thread. The check reads the
object's ancestry, so the Select menu does not walk the whole document.
2026-11-02 15:21:51 +07:00
dotCooCoo 012a50815f Select: Link Block Series skips hidden and locked type in selected groups
Select › Same › Link Block Series no longer counts hidden or locked type
inside a selected group, or type inside a hidden or locked object there,
as selected. A group that holds only such type leaves the command off, and
the command does not select the other frames of that type's thread.
2026-11-02 15:21:51 +07:00