Commit Graph
8025 Commits
Author SHA1 Message Date
dotCooCoo f581aa8a56 Select: the font Same commands take their reference from the type on a selected layer
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.
2026-11-04 12:44:48 +07:00
dotCooCoo 5c224a0d08 Symbols: Break Link keeps the instance's opacity mask
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.
2026-11-04 12:44:46 +07:00
ruchirguitarandClaude Opus 5.5 bf58f605fe Text Tweaker: refuse ranges that aren't whole bytes, make no step when nothing changes (#4924)
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>
2026-11-04 12:44:44 +07:00
dotCooCoo 0dba3afea9 Docs: the 1 pt default stroke weight on type is in the type's own units
docs/mcp.md says that the default weight text.setStyle and text.setRangeStyle give an unweighted stroke is in the type's own units, so scaled type draws it wider, while strokeWidth and strokeOptions lengths are in document points.
2026-11-04 12:44:43 +07:00
dotCooCoo 79102f6104 Tests: range stroke weight test joins the character stroke tests
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.
2026-11-04 12:44:42 +07:00
dotCooCoo b5301ca74d Fix range text stroke weight defaults and scaling 2026-11-04 12:44:42 +07:00
BFlat 01f30fdbce Merge pull request #5505 from dotCooCoo/fix/ai-look-copies-type
.ai import: copies drawn by a layer's or group's look keep their type
2026-11-04 12:18:30 +07:00
BFlat c938184831 Merge pull request #5503 from dotCooCoo/fix/ai-comparison-patch-pitch
.ai import: boxes of differing patches on an image-only page use the comparison raster's pixel size
2026-11-04 12:18:15 +07:00
dotCooCoo 22c2e2c9bd .ai import: copies drawn by a layer's or group's look keep their type
When an effect on a layer or a group draws copies of its art, the editing
data holds the type of each copy inside the drawn look. The reader skipped
that type, so the copies came in without text objects, the page's type for
them was given to other groups by painting order, and the import noted that
a text object may be in another group than it was.

The reader now keeps such type as a text slot without a story, in the
copy's group. The page's type that lies over a copy's other art (at least
half of it in the art's box) goes to that copy's slots by painting order,
before the rest is given out. Of overlapping copies, the one that holds
more of it takes it, and the smaller one on a tie. When the page's type
outside the copies is too little for the other text objects, a copy with
more of the page's text objects than slots leaves the extra ones to them.
A slot that gets no type
is removed and not counted as a text object that couldn't be read.

Type beside a copy's art, and every copy's type in a file past the import's
text-object limits or opened with its type as outlines, goes as before. A
text object with an appearance keeps its own type as before.
2026-11-04 12:06:08 +07:00
dotCooCoo a0c9726491 .ai import: boxes of differing patches on an image-only page use the pixel size of the comparison raster
The comparison of an image-only page draws at four times the comparison
scale and resizes the result to the comparison size. The two sizes round
differently along the shorter side, so a pixel is not 1/scale points
wide. A box at the far edge of a large page moved by up to 0.625/scale
points and could lie outside the object that holds it, so the import
used the PDF part instead of the layers. The boxes now use the size the
raster was drawn at.
2026-11-04 12:06:06 +07:00
BFlat 3c59751ebd Merge pull request #5501 from dotCooCoo/feat/graph-marks-keep-opacity
Graphs: series marks keep a fill or stroke opacity when the graph is drawn again
2026-11-04 11:59:28 +07:00
BFlat bb8a56e9d5 Merge pull request #5499 from storytold/fix/sec-engine-plugins-budgets
Cap radar graph dimensions, resume slice-name suffix search, weigh plug-in cache keys
2026-11-04 11:59:16 +07:00
BFlat 9946ea65ad Merge pull request #5498 from dotCooCoo/fix/help-documentation-own-wording
Docs: describe help-page behavior in our own words
2026-11-04 11:58:57 +07:00
BFlat 1c22e19ca0 Merge pull request #5436 from dotCooCoo/docs/kashida-parity-followups
Docs: reconcile Kashidas and Type options parity
2026-11-04 11:58:42 +07:00
BFlat 24dad35d6b Merge pull request #5431 from devius/ka-update-2026-11-03
i18n(ka): Georgian for 23 new strings
2026-11-04 11:58:26 +07:00
dotCooCoo c8128ee65b Graphs: series marks keep a fill or stroke opacity when the graph is drawn again
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.
2026-11-04 11:45:16 +07:00
Dylan M. Taylor 0cdcf3039b engine, plugins: cap radar dimensions, resume slice-name suffixes, weigh cache keys 2026-11-04 11:45:15 +07:00
dotCooCoo 64b1fa5ab2 Docs: describe help-page behavior in our own words
Remove copied sentences from workspace, Actions, symbol and export notes.
Keep source links, command identifiers, UI labels and behavior rules.
2026-11-04 11:45:13 +07:00
dotCooCoo 83d9ed1ee2 Docs: keep removed Type core evidence in the kept row
The duplicate Type core rows carried evidence the kept row did not: recent-font groups (#3515), Fractional Widths per type object, color emoji bitmap fonts, and the threading ports clause (#2572) with its test names. Move it into the kept row's evidence cell.
2026-11-04 11:45:12 +07:00
dotCooCoo cc4b492ef1 docs(type): remove stale duplicate parity rows
Follow CodeRabbit review on VectorCraft #5436; retain one current Type core row per table and one target header.
2026-11-04 11:45:12 +07:00
dotCooCoo 782071d1c7 Docs: reconcile Kashidas and Type options parity 2026-11-04 11:45:11 +07:00
Davit MatchakhelidzeandClaude Opus 5.5 cd53262faf i18n(ka): keep the 23 rows the maintainer asked for
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YMTAbGNRxnMEzRvYnQGphF
2026-11-04 11:45:09 +07:00
Davit MatchakhelidzeandClaude Sonnet 5.5 288bca85c2 i18n(ka): bring the Georgian catalog up to the other catalogs
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YMTAbGNRxnMEzRvYnQGphF
2026-11-04 11:45:09 +07:00
BFlat 15670ca9f3 Merge pull request #4968 from dotCooCoo/feat/ai-editing-data 2026-11-04 11:41:38 +07:00
Dylan M. Taylor 5cb58c0507 3D effects: every ring pair counts toward the containment budget; no zero-sized inflate cells (#5413)
* fix(three-d): charge every ring pair; refuse zero-sized inflate cells

* fix(three-d): clippy-friendly cell check

* address review: reject subnormal inflate cells
2026-11-03 23:21:52 -05:00
BFlat 3226c2ade7 Merge pull request #5497 from storytold/fix/sec-font-name-records
Fonts: cap the name records and decoded bytes read per name id
2026-11-04 11:13:41 +07:00
BFlat ef2f227a1d Merge pull request #5496 from dotCooCoo/fix/layer-options-several-layers
Layers: Layer Options for several rows sends only the settings set in it
2026-11-04 11:13:31 +07:00
BFlat cab4014bec Merge pull request #5495 from storytold/fix/sec-ps-filter-chain
EPS import: bound and charge the filter chain over a pending file
2026-11-04 11:13:16 +07:00
BFlat e6ceb466ee Merge pull request #5494 from dotCooCoo/fix/dimension-placement-preview-postmerge
Preview dimensions on placement press
2026-11-04 11:13:02 +07:00
Dylan M. Taylor daf224755a Fonts: cap the name records and decoded bytes read per name id 2026-11-04 10:52:13 +07:00
dotCooCoo 5e4f0720b0 Layers: Layer Options for several rows sends only the settings set in it
With several rows highlighted, Layer Options shows the first row's
settings, and OK sent Show, Lock, Color, Template, Print, Preview and
Dim Images to layer.setProps for every row. Changing one setting gave
every row the first row's values for all of the others as well.

The dialog now records each setting set by one of its controls or by
ui.dialog.set, and for several rows OK sends only those. A setting set
to the value the dialog shows is still sent, so choosing the first row's
color gives every row that color.

When Template changes and Lock and Dim Images are not set in the dialog,
OK does not send them. layer.setProps then locks each row that becomes
a template and dims it to 50%, unless a percentage is set in the dialog,
and unlocks and stops dimming each row that stops being one. When
Template is turned on, the dialog shows that 50%. When Template is set
back to the first row's value, the dialog shows the first row's Lock,
Dim Images and percentage again. A Dim Images percentage set in the
dialog is sent whenever Dim Images is on, also when Template turned it
on.

ui.dialog.set of template now also sets locked and dimImages, as the
Template checkbox does, for one row as well as several. Before, a script
that set template to true and confirmed the dialog left the layer
unlocked and undimmed.

The Dim Images percentage field now has the accessible name "Dim Images
to:", as its checkbox has.
2026-11-04 10:51:43 +07:00
Dylan M. Taylor bb03081a70 EPS import: bound and charge the filter chain over a pending file 2026-11-04 10:51:39 +07:00
dotCooCoo 38bac1114b Preview dimensions on placement press 2026-11-04 10:51:37 +07:00
BFlat d10c56773a Merge pull request #5492 from dotCooCoo/feat/manage-toolbars
Toolbars: Manage Toolbars renames, copies and deletes the toolbars made with New Toolbar
2026-11-04 10:47:42 +07:00
BFlat 49b3cd2777 Merge pull request #5490 from dotCooCoo/fix/type-drop-restore
Restore Type editing after a dropped press
2026-11-04 10:47:16 +07:00
dotCooCoo 46bb91275d Merge main into feat/ai-editing-data 2026-11-03 19:47:02 -08:00
BFlat 1c1a2df2f7 Merge pull request #4616 from mockydevs/fix/ai-open-path-2920
Fix #2920: an open path in a PDF-compatible .ai opens as drawn
2026-11-04 10:47:01 +07:00
dotCooCoo de78142dd8 Toolbars: Manage Toolbars renames, copies and deletes the toolbars made with New Toolbar
Window › Toolbars › Manage Toolbars… and Manage Toolbars… in the All Tools
drawer's menu open a dialog that lists the toolbars made with New Toolbar.
A name typed for the selected toolbar renames it, + copies the selected
toolbar or, with none selected, makes a new one, and the trash can deletes
it (https://helpx.adobe.com/illustrator/using/tools.html, Manage toolbars).

VectorCraft's own details:
- A rename applies at Enter, when the text box loses focus, or at OK. The
  name follows New Toolbar's rules: not empty, at most 200 characters, and
  not another toolbar's in any case.
- A copy is called "<name> Copy" (then "<name> Copy 2"), shows a little
  below the toolbar it copies and below earlier copies; a new toolbar is
  called "Toolbar N".
- Each change applies at once; deleting also removes the groups torn off
  the toolbar.
- When the typed name is refused, a click on +, the trash can or another
  toolbar is not applied, so the name can be corrected. When the selected
  toolbar is deleted elsewhere while the dialog is open, none is selected.
- Renaming or deleting a toolbar closes the All Tools drawer and a group's
  flyout open on it; a change of case only leaves them open, and the Tools
  panel's flyouts and other toolbars' stay open.
- Each change shows under Window › Toolbars and is kept with the workspace.

New commands: window.toolbar.manage, window.toolbar.rename,
window.toolbar.duplicate and window.toolbar.delete, with catalog rows for
their labels in every language.

Docs: control-protocol.md, gaps.md, target-app-parity.md, ui-parity.md.

Part of #1759
2026-11-04 10:26:01 +07:00
dotCooCoo a0a4633c26 Restore Type editing after a dropped press 2026-11-04 10:25:57 +07:00
Don Omondi 4f60ee47e8 Fix #2920: an open path in a PDF-compatible .ai opens as drawn
Squashed from #4616 onto main.
2026-11-04 10:25:55 +07:00
BFlat d41fc3b9b0 Merge pull request #5489 from storytold/fix/control-junk-test-reset
Control server: the junk-closes test leaves no unread input
2026-11-04 10:14:05 +07:00
BFlat c104ed9a9d Merge pull request #5488 from dotCooCoo/fix/action-record-command
Add command to begin recording Actions
2026-11-04 10:13:49 +07:00
BFlat aecf94f8d1 Merge pull request #5486 from dotCooCoo/fix/ai-page-mismatch-keeps-layers-2
.ai import: objects that draw differently from the page come in as its art, and the layers stay
2026-11-04 10:13:34 +07:00
BFlat c48404b9cf Merge pull request #5480 from dotCooCoo/feat/taskbar-type-on-path
Contextual Task Bar: type on a path offers Type on a Path Options
2026-11-04 10:13:19 +07:00
BFlat db1afa01c8 Merge pull request #5479 from dotCooCoo/fix/font-same-skips-unreachable-type
Select: the font Same commands take their reference from type that can be selected
2026-11-04 10:13:04 +07:00
bflatastic 821757acef Control server: the junk-closes test leaves no unread input
On Windows, closing a socket with unread input resets the connection, and
the reset can discard the reply before the client reads it, so the test
failed under load. The request after junk is still covered by the
in-memory tests.
2026-11-04 09:43:38 +07:00
dotCooCoo b5c69e25fd Add command to begin recording Actions 2026-11-04 09:43:35 +07:00
dotCooCoo 5e495cf900 .ai import: objects that draw differently from the page come in as its art, and the layers stay
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.
2026-11-04 09:43:28 +07:00
dotCooCoo 8cf4b90a65 Contextual Task Bar: type on a path offers Type on a Path Options
The task bar offered no Type on a Path item for a selected type on a
path: of the type actions, it showed only Create Outlines. It now also
offers Type on a Path Options, which opens the same dialog as Type ›
Type on a Path › Type on a Path Options, with the selected type's
effect, alignment and spacing filled in. Point and area type keep
their Convert To Area Type and Convert To Point Type buttons.
2026-11-04 09:43:25 +07:00
dotCooCoo 7fe42986c2 Select: the font Same commands take their reference from type that can be selected
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".
2026-11-04 09:43:21 +07:00