Commit Graph
10700 Commits
Author SHA1 Message Date
dotCooCoo 561dcb20d3 Docs: the Scripts folder lines say which path each command checks and which platforms read it on File 2026-11-10 21:08:32 -08:00
dotCooCoo 39996d3d2c Merge main into feat/scripts-folder
# Conflicts:
#	crates/engine/src/cmd/scripts.rs
#	crates/engine/src/tests.rs
#	docs/gaps.md
#	docs/mcp.md
#	docs/target-app-parity.md
2026-11-10 21:08:10 -08:00
BFlat 22ec820569 Merge pull request #6513 from dotCooCoo/fix/break-link-keeps-hidden-locked
Symbols: Break Link keeps a hidden or locked instance's art hidden or locked
2026-11-11 12:00:47 +07:00
BFlat acc6acfdb2 Merge pull request #6266 from Silvertree2010/fix/h13526-graph-csv-round-trip-drops-a-bla
Keep blank value row in single-column graph CSV round trip
2026-11-11 11:52:07 +07:00
BFlat 3e780a8026 Merge pull request #6512 from dotCooCoo/fix/native-open-pdf-preference-one-pass
Native files: open reads the PDF preference in the same pass as the document
2026-11-11 11:51:57 +07:00
BFlat bc814012d9 Merge pull request #6511 from dotCooCoo/feat/artboard-color-labels
Artboards: an artboard's guide label colors its own guides
2026-11-11 11:27:16 +07:00
NetterSilverandClaude Haiku 5.5 aaf27e1ec6 Keep blank value row in single-column graph CSV round trip
Found while testing crates/engine/src/cmd/graph/data.rs:51 (parse_csv); written by crates/doc/src/graph.rs:497 (GraphSpec::to_csv)

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-11 04:16:30 +00:00
dotCooCoo 2faadd28f4 Symbols: Break Link keeps a hidden or locked instance's art hidden or locked
Break Link to Symbol on a selected group, and Delete Symbol with its
instances expanded, turned a hidden or locked instance into visible,
unlocked art. The art now keeps the instance's hidden and locked state,
as Object > Expand does, and Break Link leaves hidden or locked art out of
the selection.
2026-11-10 20:09:28 -08:00
BFlat 726d2b6e13 Merge pull request #6508 from jmverges/fix/3179-warps-of-type-as-mesh
.ai import: warps of type open as mesh envelopes on their saved grid
2026-11-11 10:48:16 +07:00
BFlat 98fe060bb0 Merge pull request #6499 from dotCooCoo/feat/script-console
Scripts: Window › Script Console shows script output, errors and run reports
2026-11-11 10:48:06 +07:00
dotCooCoo 8002598d64 Native files: open reads the PDF preference in the same pass as the document
Opening a native file read its JSON twice: once for the document and once
more for the saved pdfCompatible preference. The format crate now takes
the preference from craft-vectorcraft-format's
Contents::read_with_pdf_preference (craft-libs#562), so a file is read in
one pass.

That method refuses a pdfCompatible that is not a boolean, which main
opens by skipping the value and falling back to whether the file carries
a PDF. Such a file, or one with any other data error, is read again with
Contents::read and scanned for the preference as before, so the files
that open today still open with the same result.

The craft-vectorcraft-format pin moves to 1b34eba41e, the craft-libs
revision craft-update already uses.
2026-11-10 19:42:29 -08:00
dotCooCoo 29437fed48 Merge main into feat/artboard-color-labels 2026-11-10 19:38:12 -08:00
dotCooCoo beef32b8a3 Artboards: an artboard's guide label colors its own guides
Each artboard can carry a guide label: one of the layer colors or a
custom RGB. Guides that belong to an artboard draw in its label color,
and guides without an artboard, or on an artboard without a label, keep
the guide color from the preferences. Selected guides still draw in the
selection color.

- Artboard Options has a Guide Label row (None, the layer colors with
  swatches, or Custom with a color swatch).
- artboard.new and artboard.setProps take guideLabel: null, a layer
  color's name, or #rrggbb. Any other value is an error. The inspect
  summary lists guideLabel when one is set.
- The native format saves the label and skips it when unset; a preset
  index outside the layer colors reads as no label.
- artboard.setProps no longer adds an undo step when nothing changes.

Docs: docs/mcp.md, docs/target-app-parity.md.
2026-11-10 19:37:17 -08:00
BFlat add0fcbe03 Merge pull request #6503 from dotCooCoo/fix/fx-menu-flicker
Menus: a long menu stays in one place instead of jumping between two places
2026-11-11 10:29:19 +07:00
dotCooCoo d7a89d3243 Scripts: the read after a script left the folder asks for a frame when it ends
When File › Scripts runs a listed script that is no longer in the Scripts folder, the folder is read again on a thread. That read now has the window's context, so it asks for a frame when it ends and an idle window takes in the new listing (and the macOS menu bar follows it) without waiting for the next input event.
2026-11-10 19:24:35 -08:00
dotCooCoo 259bd8ee25 Merge main into feat/scripts-folder 2026-11-10 19:10:00 -08:00
BFlat aaa2ea51a8 Merge pull request #6493 from dotCooCoo/fix/pattern-options-null-docs
Docs: pattern.options keeps a pattern's current values for omitted params
2026-11-11 10:09:23 +07:00
jmvergesandClaude Opus 5.5 d85a967fb7 docs: envelope grid orientation and retry budget for warps of type
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-11 03:06:48 +00:00
jmvergesandClaude Opus 5.5 d0c99cba4b .ai import: a warp of type's second try leaves checks for the envelopes after it
A warp of type may now spend up to four checks (its warp and its saved
grid, each with and without strokes). A try after the first is only
made while more checks are left than there are envelopes of type and
warped text objects still to come, so one envelope's retries don't use
up the checks of the others.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-11 03:06:24 +00:00
jmvergesandClaude Opus 5.5 198bb6dffd .ai import: an envelope's grid reads its way round from every row and column
Summing only the end rows and columns let a grid symmetric about its
middle (a mesh bent halfway round) read by rounding, so it came out
turned or not depending on where it sat on the page. Every row and
column is now summed, a sum shorter than 1% of its parts (or than the
grid's reach) counts as no direction and falls back to the first row or
column, and the same comparison decides both cases.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-11 03:06:24 +00:00
jmvergesandClaude Opus 5.5 8820a15e20 docs: warps of type as mesh envelopes on their saved grid
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-11 03:06:24 +00:00
jmvergesandClaude Opus 5.5 37e3c0215a .ai import: type in an envelope may map from its bounds with strokes
With Distort Appearance, an envelope's contents map from the box the
file measured for them: their bounds with their strokes or without
them. For type, the size the file saves for that box is often out of
date, so it can't say which. Envelopes of type are now checked both
ways: as before, and mapping from their bounds with their strokes.
Whichever draws as the drawn art opens live.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-11 03:06:13 +00:00
jmvergesandClaude Opus 5.5 7504a0e2e4 .ai import: an envelope mesh bent far round reads the way it runs
An envelope's mesh is turned upright by which way its rows and columns
run. That was read from the first row alone, so a warp bent past halfway
(its end columns leaning more than 45 degrees) read as turned round and
mapped its contents across instead of along. Read it from the first and
last rows and columns added up instead.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-11 03:06:13 +00:00
jmvergesandClaude Opus 5.5 8f3f6a82d7 .ai import: a warp of type opens as a mesh envelope on its saved grid
A warp of type whose own warp doesn't draw as its drawn art is checked
again as a mesh envelope on the grid the editing data saves for it, its
points and handles as saved. Where that draws as the drawn art, it opens
live in its place: the type stays editable in that shape, and the warp's
style and bend are lost.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-11 03:06:13 +00:00
BFlat 858b63082f Merge pull request #6500 from jmverges/fix/6472-ai-type-stroke-join
.ai import: stroked type keeps its cap, join and miter limit
2026-11-11 10:01:10 +07:00
BFlat ec89f3f26e Merge pull request #6501 from dotCooCoo/feat/prefs-export-import
Preferences: export and import preferences as a JSON file
2026-11-11 10:01:01 +07:00
dotCooCoo 37f140925e Scripts: Run Script's params text names the four-level limit on subfolders
ui.runInstalledScript runs a .js or .jsx file in the Scripts folder or in a
subfolder at most 4 levels below it, whether or not a capped listing read
that subfolder. The params text now says so instead of naming only listed
subfolders.
2026-11-10 18:58:54 -08:00
dotCooCoo e4830a0e2c Docs: the Script Console note shows only after dropped or cut lines
The panel's note and the doc comment on ui.copyScriptConsole now say the
count of dropped and cut lines appears only when there are any, and the
returned lines count leaves that line out.
2026-11-10 18:51:13 -08:00
dotCooCoo a06ab45911 Scripts: every script label in a Scripts folder level stays distinct
A script renamed to its whole file name could take the label another
script kept, as with tidy.js, tidy.jsx and tidy.js.js in one folder.
The rename now repeats until no label is shared. A folder entry whose
type cannot be read now marks the listing as incomplete.
2026-11-10 18:48:59 -08:00
dotCooCoo 6643991710 Docs: ui.copyScriptConsole adds the count line only after dropped or cut lines
A copy of every Script Console line starts with the count of dropped and
cut lines only when there are any, and the returned lines count leaves
that line out. The end-line text is described without a code span that
ends in a space.
2026-11-10 18:30:11 -08:00
dotCooCoo ef07aecd96 Menus: a long menu stays in one place instead of jumping between two places
A scrolling menu list took its height from its own top down to the
window's bottom bars. egui picks a popup's side from its size on the
previous frame and moves a popup that does not fit back into the
window, so the list's height changed with where the popup was drawn.
In a short window the Add New Effect menu and other long menus moved
between two places while open, and a menu that did not fit crept a
few points per frame.

The list now takes its height from the room below and above the
button, row or point it opens from: below while that side leaves the
120 pt minimum, otherwise on the side with more room. A submenu
measures down from its row's top or up from its row's bottom. The
change is in menu_scroll, so it applies to every menu built on it.
2026-11-10 18:29:20 -08:00
dotCooCoo ea9b93d3ce Merge main into feat/scripts-folder 2026-11-10 18:28:59 -08:00
dotCooCoo d399b17605 Docs: pattern.options accepts a null width or height as omitted
The width and height check in pattern.options applies only to values
that are not null; null keeps the current value.
2026-11-10 18:27:23 -08:00
BFlat 4c2b8df865 Merge pull request #6498 from dotCooCoo/fix/smart-guides-snap
Smart Guides: tools do not snap to Smart Guides while Pixel Preview is on
2026-11-11 09:26:08 +07:00
dotCooCoo 04c20fc8b9 Merge main into feat/scripts-folder 2026-11-10 18:24:29 -08:00
dotCooCoo f78d715fee Scripts: a Scripts folder read asked for during another starts when that one ends
A File menu opening or a failed ui.runInstalledScript while a read of the
Scripts folder was under way was dropped, so a script added after that
read passed the folder stayed unlisted until the next window activation
or File menu opening. The request is now kept and the next frame starts
the read once the running one is taken in.
2026-11-10 18:23:33 -08:00
jmvergesandClaude Opus 5.5 83245cfe54 .ai import: stroked type keeps its cap, join and miter limit (#6472)
The text document reader set a type stroke's paint and weight but never
its cap, join or miter limit, so every stroked text object imported from
a .ai or EPS editing copy drew with a miter join at a limit of 10. Type
the file strokes with round joins, or with a miter limit of 4 or less,
drew long spikes at its sharp corners.

Keys 61, 62 and 64 of a run's character attributes (the run, its
character style, then the document defaults) are now read as the
stroke's cap (0 butt, 1 round, 2 projecting), join (0 miter, 1 round,
2 bevel) and miter limit, as PostScript numbers caps and joins. In the
users' files the page strokes type with exactly these settings. Other
values keep the defaults, a miter limit is capped at 500, and type
without a stroke keeps the defaults.

- ate.rs: Style reads the three keys and char_style passes them on,
  with a unit test over defaults, character styles, run overrides,
  hostile values and unstroked type.
- tests_native.rs: an imported story with round, bevel, default and
  unstroked runs.
- docs/file-format-parity.md: revision row, status line, one line on
  the mapping.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-11 02:20:38 +00:00
dotCooCoo d426c70a92 Preferences: export and import preferences as a JSON file
Part of #6435. An optional VectorCraft feature: the Preferences dialog's
Export Preferences... saves the applied preferences to a JSON file (the
web build downloads it), and Import Preferences... applies such a file and
shows the imported values. They run the new commands prefs.export {path?}
and prefs.import {path | data}.

The file holds every preference prefs.list lists and the eyedropper,
perspectiveWidget, pathfinder and glyphSnap groups, without the four
folder preferences and saved presets. prefs.import reads at most 1 MB and
checks every value first: another format, a newer version, an unknown
preference, a bad value or a folder preference is an error, and nothing
changes. It keeps the open document's units, records no undo step, and is
refused as a command.batch step. prefs.set now rejects a group value that
is not an object.
2026-11-10 18:11:01 -08:00
BFlat af66951c41 Merge pull request #6496 from dotCooCoo/feat/ruler-artboard-guides
Guides: an option makes Cmd/Ctrl ruler drags artboard guides
2026-11-11 09:04:35 +07:00
dotCooCoo 5bc51a7c35 Merge main into feat/scripts-folder 2026-11-10 18:04:28 -08:00
BFlat d2b1fe74cf Merge pull request #6495 from dotCooCoo/fix/canvas-redraws-on-plugin-change
Canvas: installing or removing a plug-in draws its effects again
2026-11-11 08:58:49 +07:00
dotCooCoo e60b0c3aa6 Docs: pattern.options rejects a bad width or height while sizeTileToArt is on
With sizeTileToArt on, pattern.options ignores width and height for sizing but
still rejects a value that is not a positive number, such as width 0, and
changes nothing.
2026-11-10 17:57:41 -08:00
BFlat 69d36e961d Merge pull request #6494 from dotCooCoo/feat/dimension-horizontal-vertical
Dimension tool: linear dimensions measure horizontally, vertically or aligned
2026-11-11 08:50:56 +07:00
dotCooCoo 899b7bdb3d Merge main into feat/scripts-folder 2026-11-10 17:47:11 -08:00
dotCooCoo 52efba54aa Scripts: File › Scripts lists the Scripts folder, subfolders as submenus
File › Scripts now lists the .js and .jsx files of the Scripts folder next
to the preferences, each named after its file without the extension, with
each subfolder as a submenu, above Check Script… and Other Script…. The
help page describes this listing:
https://helpx.adobe.com/illustrator/desktop/automate-visualize-data/automate-actions/install-and-run-scripts.html

Choosing a listed script runs it through script.run without the warning
Other Script… shows. script.listInstalled returns the same listing, and
ui.runInstalledScript {path} runs one entry.

VectorCraft's own rules: the folder is read off the UI thread when the
app starts, when its window becomes active and when the File menu of the
window's menu bar opens; only names are read; links, junctions, hidden
and system entries are left out and checked again before a run; one read
stops at 2,048 entries, 512 scripts, 128 subfolders, 4 levels or 250 ms
and the menu then notes that some scripts were not listed. Under an
automation read root, script.listInstalled and ui.menu.list leave out a
folder outside the root.

#1183 (LloydNicholson) also proposed a Scripts menu listing a folder.
2026-11-10 17:46:36 -08:00
dotCooCoo 4060480ef1 Smart Guides: tools do not snap to Smart Guides while Pixel Preview is on
With View > Pixel Preview on, the tools still snapped to Smart Guides
and showed their guides; only the Object Highlighting outline was
hidden. Work with Smart Guides says Smart Guides cannot be used while
Snap to Grid or Pixel Preview is on.

ViewInfo has a pixel_preview field, and Session::with_tool_cx turns
Smart Guides (and Snap to Glyph, which needs them) off in the tools'
context while it is set. VectorcraftApp::view_info passes View > Pixel
Preview. View > Smart Guides keeps its setting.

Docs: docs/target-app-parity.md.
2026-11-10 17:43:29 -08:00
BFlat 4302b7bde4 Merge pull request #6492 from dotCooCoo/fix/reshape-stretches-whole-path
Reshape: a drag stretches an open path from the dragged point to its two ends
2026-11-11 08:31:45 +07:00
dotCooCoo 8430715ec7 Docs: pattern.options sizes the tile to the art while sizeTileToArt is on
A brick tileType or gridType with brickOffset omitted or null sets the
offset to 0.5. While sizeTileToArt is on, every pattern.options call
sizes the tile to the art plus hSpacing and vSpacing again and ignores
width and height, so a new hSpacing changes the tile's width.
2026-11-10 17:27:50 -08:00
dotCooCoo df9c8d992d Merge main into feat/script-console 2026-11-10 17:27:35 -08:00
dotCooCoo 342d082c2b Scripts: Window › Script Console shows script output, errors and run reports
Scripts write to a new Script Console with $.write(...values) and
$.writeln(...values), each value as String(value) gives it. vc.log
entries, a run's uncaught error as name:line:column: message, and a
start, end and report line for each run go there too. The report line
gives the run's time, host calls and slowest commands.

- The console keeps at most 2,048 lines and 1 MiB of text, dropping the
  oldest and counting what it dropped. A line is cut at 4,096 bytes and
  a script's name at 256 bytes, with a count of cut lines. Line feeds,
  carriage returns and CRLF break lines; other control characters show
  as Unicode Control Pictures.
- script.run's result and scriptReport gain runTimeMs, timingAvailable,
  hostCallCounts, slowestCommands and the run's own console. A failed
  run's report has them too.
- script.console and script.console.clear read and empty the console;
  ui.copyScriptConsole {first?, last?} copies lines as the panel shows
  them.
- The panel lays out only the rows in view, selects with click and
  Shift-click, and has Clear, Copy Selected and Copy All. Output goes on
  while it is closed, and Clear works during a run.

Docs: docs/mcp.md, docs/gaps.md, docs/roadmap.md,
docs/target-app-parity.md.
2026-11-10 17:26:30 -08:00