Commit Graph
1583 Commits
Author SHA1 Message Date
BFlat dab8b9a494 Merge pull request #6584 from dotCooCoo/fix/web-plugin-budget-clock
Plug-ins: the web build times the first-view budget and each run's limit
2026-11-11 19:14:55 +07:00
BFlat e8a570cb0e Merge pull request #6578 from dotCooCoo/fix/print-bitmap-side-limit
Print: Print as Bitmap prints all of a page longer than 32,768 pixels
2026-11-11 19:05:50 +07:00
BFlat c443a25016 Merge pull request #6569 from dotCooCoo/feat/script-strict-on
Scripts: #strict on runs the script with strict write checks instead of refusing it
2026-11-11 18:45:03 +07:00
dotCooCoo c03fe29ad8 Plug-ins: the web build times the first-view budget and each run's limit
The web build had no clock for plug-in runs, so its first view deferred
every plug-in live effect until Effect > Refresh Deferred Effects, and a
run's wall-clock limit was not enforced there. The deferrals clock and
the run deadline now read `web_time::Instant`, which is the system's
monotonic clock on the desktop and the page's `performance.now()` in the
web build. The web's first view now shares the same 2,000 ms budget, and
its runs stop at the 5 s, 60 s and 300 s limits as on the desktop.

Docs: docs/plugins.md, docs/mcp.md, docs/target-app-parity.md.
2026-11-11 03:41:05 -08:00
BFlat 7e9633e3cb Merge pull request #6573 from dotCooCoo/fix/rasterize-side-limit
Rasterize: art longer than 32,768 pixels at the resolution is refused, not cut off
2026-11-11 18:35:36 +07:00
BFlat 31971bc090 Merge pull request #6555 from dotCooCoo/feat/plugin-effect-open-budget
Plug-ins: live effects of a document's first view share a 2,000 ms budget
2026-11-11 18:22:28 +07:00
dotCooCoo 68f3095cfd Print: Print as Bitmap prints all of a page longer than 32,768 pixels
Print as Bitmap limited each page's image to 65,535 pixels a side, but the
renderer draws at most 32,768. A 9000 x 100 pt artboard at a 300 ppi raster
effects resolution printed as an image that stopped at 7,864 pt and was
placed as if whole. The resolution is now lowered until the longest side
fits.
2026-11-11 03:21:57 -08:00
BFlat d5c75d3699 Merge pull request #6567 from dotCooCoo/fix/flatten-long-area-side-limit
Flatten Transparency: a long rasterized area is placed whole
2026-11-11 18:16:31 +07:00
dotCooCoo ee40cc10d7 Rasterize: art longer than 32,768 pixels at the resolution is refused, not cut off
Object > Rasterize and the redrawn path of Crop Image allowed images up to
65,535 pixels a side, but the renderer draws at most 32,768. A 100 x 5569 pt
rectangle rasterized at 600 ppi came back 32,768 pixels tall, and the bottom
29% of the art was gone. Such an image is now refused like one over the
64 megapixel limit, and the art stays as it was.
2026-11-11 02:55:59 -08:00
BFlat 4e0e1c8af7 Merge pull request #6564 from dotCooCoo/fix/graph-unpainted-row-opacity
Docs: a series mark's row without paint leaves the stored paint, not its opacity
2026-11-11 17:55:48 +07:00
BFlat 6244ac54bf Merge pull request #6560 from dotCooCoo/fix/pasted-svg-filter-names
Effects: pasted art keeps an SVG filter whose name the document gives another filter
2026-11-11 17:37:26 +07:00
BFlat 81bfed87d4 Merge pull request #6561 from dotCooCoo/fix/graph-labels-keep-paragraph-settings
Graphs: labels keep their paragraph settings and anti-aliasing when the graph is drawn again
2026-11-11 17:37:16 +07:00
dotCooCoo 1da6e899d3 Merge main into feat/script-strict-on 2026-11-11 02:33:33 -08:00
BFlat 6a2b5b9c06 Merge pull request #6459 from Messhias/feat/g5-style-lib-status-effects
G5: built-in Status Effects graphic style library
2026-11-11 17:30:34 +07:00
dotCooCoo c81ae88c85 Flatten Transparency: a long rasterized area is placed whole
The flattener limited an image's resolution only by its total pixels, while
the renderer draws at most 32,768 pixels a side. A long area, such as a narrow
see-through gradient strip down a 2 m banner at 1200 ppi, came back cut off
at that length and was placed as if whole, so the rest of the strip was lost
in Flatten Transparency and in PDF/X-1a, PDF/X-3 and PDF 1.3 exports. The
resolution is now also limited by the longest side, as raster effects are.
2026-11-11 02:23:59 -08:00
BFlat 264ca9bf4e Merge pull request #6559 from dotCooCoo/fix/dimension-expand-keeps-live
Dimension tool: a dimension selected with its art stays live through Expand and Outline Stroke
2026-11-11 17:16:39 +07:00
BFlat 9a28264cfe Merge pull request #6557 from dotCooCoo/feat/script-alert-confirm-prompt
Scripts: alert, confirm and prompt open dialogs with Stop, and headless runs take their answers from script.run
2026-11-11 17:13:46 +07:00
dotCooCoo 16cc5c107c Docs: a row without paint leaves the series' stored paint, not its opacity
The graph still stores an opacity or blend mode set on a series mark's row
that has no paint, as it does for transparency.set. The sentence now says
that such a row leaves only the stored paint unchanged.
2026-11-11 02:09:08 -08:00
dotCooCoo 08eca05731 Scripts: #strict on runs the script with strict write checks instead of refusing it
`#strict on` and `//@strict on` no longer end the run as unsupported. They
turn on the checks the dollar-object help page gives for `$.strict`
(https://extendscript.docsforadobe.dev/extendscript-tools-features/dollar-object/):
an assignment to a read-only property throws a TypeError, and so does a new
property on an object that takes none.

VectorCraft's own rules: a getter-only property counts as read-only; the
objects that take no new properties are the non-extensible ones
(preventExtensions, seal, freeze, and the frozen vc and $ objects); the last
`#strict` line of the script and its includes sets the whole run, and runs
without one are unchanged; eval and Function take the checks of the code
that compiles them; a file $.evalFile runs keeps its own line's checks for
its code and functions, or takes the caller's without one. The rest of ES5
strict mode stays with 'use strict'.

The js crate carries the setting per compiled source
(Realm::set_strict_writes, and a strict_writes callback on
HostItem::Evaluator), and applies it only to property assignments.
2026-11-11 02:04:49 -08:00
dotCooCoo 32e22cb442 Effects: pasted art keeps an SVG filter whose name the document gives another filter
Pasted art whose svg.filter effect named one of the document's SVG filters
but drew another definition kept that name, so editing or deleting the
document's filter rewrote the pasted art's filter. Paste now renames such
a filter to a free name ("Soft 2") when the art comes from another
document or from SVG, and takes the document's filter when the art is
pasted back into the document it was copied from. Symbols, patterns,
brushes and graphic styles on the clipboard follow the same rule.
2026-11-11 01:44:11 -08:00
Fabio William Conceição 3c44a8ad7c G5: built-in Status Effects graphic style library
Eight style libraries; MCP docs list Status Effects and catch up Symbol libraries with UI Frames and Map Markers.
2026-11-11 09:38:28 +00:00
dotCooCoo d13f7324f9 Dimension tool: a dimension selected with its art stays live through Expand and Outline Stroke
A dimension selected with the art it measures became a plain group of
paths and text when Object › Expand, Object › Expand Appearance or
Object › Path › Outline Stroke ran, so it no longer redrew when moved
or restyled.

These commands now leave such a dimension's lines and label as they
are, also inside selected groups without fills, strokes or effects of
their own, and change only the other art. The dimension keeps its
export assets and variable bindings. When the new art no longer fits
the dimension's link, for example because the outlined stroke has
other anchors, the dimension stays where it was, no longer linked, as
it does when its art is deleted. Undo links it again.

When the dimension is all the command would change, the command
changes nothing and reports the error it gives for a selection with
nothing to change. Object › Expand… is no longer dimmed for the label
of such a dimension. A dimension selected without the art it measures,
a part of one, and one inside a selected group with an appearance of
its own still become plain groups, and Type › Create Outlines still
outlines the label.

Docs: docs/dimensions.md, docs/mcp.md, docs/target-app-parity.md.
2026-11-11 01:26:12 -08:00
dotCooCoo c0adc6e9d7 Merge main into feat/script-alert-confirm-prompt 2026-11-11 01:09:54 -08:00
Fabio William Conceição f23f7ef321 G5: list Inventory Icons in the MCP symbol libraries docs 2026-11-11 08:35:19 +00:00
dotCooCoo e22f4c4ec5 Merge main into feat/plugin-effect-open-budget 2026-11-11 00:11:50 -08:00
BFlat ed234780f2 Merge pull request #6540 from dotCooCoo/fix/pdfx1a-flatten-clipping
PDF export: PDF/X-1a, X-3 and 1.3 keep the art under the hidden part of cropped art
2026-11-11 15:08:42 +07:00
BFlat df7a185cb2 Merge pull request #6534 from dotCooCoo/fix/reshape-earlier-steps
Reshape: a step recorded without focal points plays by the earlier rule
2026-11-11 14:48:26 +07:00
BFlat 05f2be5588 Merge pull request #6528 from dotCooCoo/fix/insert-anchor-keeps-selection
Paths: Add Anchor Point keeps the same anchors and segments selected
2026-11-11 14:48:16 +07:00
dotCooCoo cba56d2602 Merge main into fix/graph-labels-keep-paragraph-settings 2026-11-10 23:41:28 -08:00
dotCooCoo e76524fd8b Graphs: labels keep paragraph settings and anti-aliasing when the graph is drawn again
Paragraph settings given to all of a graph label's text with
text.setFormat (indents, spacing, hyphenation, Justification options,
composer, direction, kashida, kinsoku, mojikumi, burasagari and the
rest) and the label's anti-aliasing method were lost when the graph
drew its labels again, because the graph kept only a character style
for each kind of label. Each kind now also keeps its paragraph settings
and anti-aliasing method, saved with the graph in its label styles, and
the graph still sets each label's alignment for its place.

The legend spaces its entries by the kept legend settings: Legend
Across Top measures each label with its indents and spacing, both
legend layouts make room for extra leading or paragraph spacing, and a
label with a negative indent or negative space before moves right or
down so it stays clear of its swatch and of the entry above it.
2026-11-10 23:40:25 -08:00
BFlat 0127ed3ec9 Merge pull request #6536 from dotCooCoo/feat/script-include-directives
Scripts: #include and the other preprocessor lines run, and $.evalFile runs a file
2026-11-11 14:31:44 +07:00
BFlat 3e642efce6 Merge pull request #6530 from dotCooCoo/fix/vertical-path-sideways-glyphs
Type: on a vertical path, letters lie a quarter turn clockwise from upright glyphs, in a column centered on the path
2026-11-11 14:22:33 +07:00
dotCooCoo 22189986a9 PDF export: flattening for PDF/X-1a, X-3 and 1.3 keeps art across clipping layers
- PDF/X-1a, PDF/X-3 and PDF 1.3 files leave the layers they don't print
  out of the flattening. A flattened group no longer takes the place of
  art in a layer that doesn't print, so the art of a clipping layer over
  such a layer prints, and art of a layer that doesn't print stays out
  of the file.
- A flattened group goes into a lower layer only when that layer prints,
  shows and is a template as the clipping layer does, the clipping layer
  and the groups it leaves have no opacity, blend mode or isolation, and
  the clipping path has no fill. Otherwise the group holds only the art
  inside the clipping layer, drawn over the clipping path's fill and the
  art below, and the art below is flattened on its own. Before, the fill
  covered the group, the group lost the layer's opacity, or the clipping
  path cut the art below.
- Transparent art that a clipping path hides entirely, such as one of
  area type holding only a space, is removed. Before, the export failed
  because the art kept its transparency.

Object › Flatten Transparency follows the same rules. Documents without
clipping layers or layers that don't print export the same bytes as
before.
2026-11-10 23:08:31 -08:00
dotCooCoo 9bfd6b7be5 Paths: describe the anchor added on a selected segment as an end of its halves
A selected segment that path.insertAnchor splits stays selected as its
two halves. The new anchor is the end both halves share, so it moves
with them, and Delete cuts both halves. docs/mcp.md and the comment on
renumber_after_insert called it a direct-selected anchor; they now
describe it as an end of the halves that moves with them.
2026-11-10 23:00:40 -08:00
dotCooCoo e74f953b7b Merge main into feat/plugin-effect-open-budget 2026-11-10 22:49:07 -08:00
dotCooCoo 2fc07fe3c0 Merge main into feat/script-alert-confirm-prompt
# Conflicts:
#	crates/engine/src/tests.rs
#	crates/ui-egui/src/app.rs
#	docs/target-app-parity.md
2026-11-10 22:40:45 -08:00
dotCooCoo 08387a22ec Merge main into feat/script-include-directives 2026-11-10 22:39:32 -08:00
BFlat b421c03d03 Merge pull request #6525 from dotCooCoo/feat/scripts-folder
Scripts: File › Scripts lists the Scripts folder, subfolders as submenus
2026-11-11 13:33:56 +07:00
dotCooCoo 4110f8c24e Reshape: a step recorded without focal points plays by the earlier rule
Before the Reshape tool had focal points it sent path.reshape without
focal or radius, and the command stretched an open path from the grabbed
point to its ends whatever the selection, and moved the anchors of a
closed path within half the diagonal of its bounding box with a
falloff. Such a step, in a saved action or a script, now moved a closed
path whole. A step without focal (or with focal null) and without
radius now plays by that earlier rule. The Reshape tool always sends
focal, an empty list included, so its drags keep the focal-point rule.
2026-11-10 22:30:19 -08:00
dotCooCoo 5a8a57d5f6 Type: upright glyphs on a vertical path keep vertical point type's cells, and the caret spans the column
On a vertical path, an upright glyph is now placed in its column as
vertical point type places it, then the column is centered on the path.

- Its cell starts at its place on the path; it started 0.12 em earlier
  with fonts whose cell top is less than a full cell above the baseline.
- A baseline shift moves it across the column instead of along the path.
- A horizontal scale widens it evenly about the column's center.
- A combining mark stays on its upright letter.
- The caret and the selection highlight span the column, half its em on
  each side of the path, instead of the font's ascent and descent.

With Skew, 3D Ribbon and Stair Step on a path that runs to the left,
letters are a quarter turn counterclockwise from upright glyphs: Skew and
3D Ribbon mirror both kinds there, and Stair Step keeps letters level. The
test, the progress doc and the params text of Tate-chu-yoko Settings now
state these conditions and the block's directions on a path.
2026-11-10 22:27:53 -08:00
dotCooCoo f4496d61aa Paths: Add Anchor Point keeps the same anchors and segments selected
path.insertAnchor (the Add Anchor Point tool, the Pen's Auto Add, the
Smart Pen's Alt-click on a segment and Alt-click with the Scissors)
added the anchor without changing the selection, so the direct-selected
anchors and selected segments after it on the subpath kept their old
numbers and the selection shifted onto the next points along. It now
renumbers them with renumber_after_insert, the helper path.reshape
uses. A selected segment that the new anchor splits stays selected as
its two halves, and the new anchor is direct-selected with them. Undo
restores the path and the selection in one step.

Docs: params text, docs/mcp.md, docs/target-app-parity.md.
2026-11-10 22:17:08 -08:00
dotCooCoo feda950bc8 Plug-ins: live effects of a document's first view share a 2,000 ms budget
While the app draws a document on screen, the live-effect plug-in runs of
its first view share a 2,000 ms budget (VectorCraft's own value); each run
takes the lesser of its 5,000 ms limit and what is left. A stage left out
for time, or one that times out, fails, has no plug-in or meets Safe Mode,
draws its input art unchanged and is deferred, and the status bar says how
many. Later drawings leave a deferred stage as it is until its input or
parameters change.

- effect.deferredStatus lists the deferred stages with object, effect
  index, fill or stroke, plug-in and reason, objects in symbol, pattern,
  brush and opacity-mask art included.
- Effect › Refresh Deferred Effects (effect.refreshDeferred {ids?}) runs
  them again with a fresh budget and returns {refreshed, stillDeferred,
  failed}.
- Each document has its own budget and deferred stages; exports, Expand
  Appearance and commands run every stage under the per-call limit.
- The web build has no clock for the budget: its first view runs no
  plug-in effect, and a refresh runs them.

Docs: docs/mcp.md, docs/plugins.md, docs/target-app-parity.md.
2026-11-10 22:16:01 -08:00
dotCooCoo 58623b34b1 Merge main into feat/script-alert-confirm-prompt 2026-11-10 22:14:59 -08:00
dotCooCoo df0373aa26 Scripts: alert, confirm and prompt open dialogs with Stop, and headless runs take their answers from script.run
alert(message[, title, errorIcon]), confirm(message[, noAsDflt, title])
and prompt(message, preset[, title]) are globals in a script run. In the
app the run waits at the call for the person's answer, spends no
instructions while it waits, and every dialog has Stop, which ends the
run and puts every document back. A run over MCP or the command line
takes its answers in order from script.run's answers, a list of
{kind, value} records; a missing, mismatched or unused answer ends the
run. The report lists each dialog with its answer in dialogs, with
dialogCount and dialogsTruncated.

The interpreter gains a host call that waits at the call for its
result, from the script's own code only; a dialog called in a callback
of a built-in, a getter or a conversion throws in the app.

Docs: docs/mcp.md, docs/target-app-parity.md.
2026-11-10 22:14:01 -08:00
dotCooCoo 693031c509 Scripts: #include and the other preprocessor lines run, and $.evalFile runs a file
Before a script runs, `script.run` reads its preprocessor lines (`#` or
`//@` at the start of a line, outside strings and comments):

- `#include` and `//@include` put another file's text in place of the
  line, looked for beside the including file, then in each
  `#includepath` folder, then in each `JSINCLUDE` folder. A later
  `#includepath` replaces the list.
- `#script` names the run unless `name` is given; `#target` takes any
  value; `#strict off` is taken. `#strict on`, `#targetengine` and
  `#engine` are refused as unsupported, and any other `#name` as
  unknown.

`$.evalFile(path, timeout?)` runs a file in the same global environment
and returns its last value, `$.fileName` is the file being run and
`$.includePath` the include folders.

A script run from a file reads these files only in its folder and the
folders below it. Paths with a `..` name, links or junctions that lead
out, device names, streams and network paths are refused; a script
given as text reads none. A run reads at most 64 files 16 levels deep,
32 MiB of source in all and 1,024 paths looked up. An error in an
included or evaluated file is reported at that file's line and column,
and the report's new `file` field names it.

Docs: docs/mcp.md (script.run, Script Console), docs/target-app-parity.md.
2026-11-10 21:59:22 -08:00
BFlat 0695db3ec0 Merge pull request #6519 from dotCooCoo/feat/reshape-focal-points
Reshape: a click sets a focal point and a drag moves every focal point
2026-11-11 12:53:37 +07:00
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 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