Merge upstream main into pencil-no-guides

# Conflicts:
#	docs/target-app-parity.md
This commit is contained in:
ncic
2026-11-13 23:52:26 +01:00
142 changed files with 5868 additions and 783 deletions
+94 -10
View File
@@ -761,8 +761,15 @@ outline, so these commands do not store a stroke paint or weight for a series th
`paint.swap`, they still store a stroke opacity and blend mode set on a band, and the band's outline takes them. Graph
designs keep their own paint. A row that had no
paint before the command and has none after it does not change the paint the graph stores. `paint.setFill`,
`paint.setStroke`, `paint.none` and the commands that apply one paint kind to the other store the topmost row of the kind
even when it is hidden, and store a stroke set on a band.
`paint.setStroke`, `paint.none`, `addon.color.fillToStroke` and `addon.color.strokeToFill` follow the same rules, and so
does `library.use` when it applies a gradient or pattern. They write the topmost row of the kind; `paint.setFill` and
`paint.setStroke` write the row `item` names instead, and without ids the three `paint.*` commands write the active
row of the Appearance panel when it is of that kind. The graph stores only the paint of the topmost visible row of the
kind, and only when the command wrote that row or changed its paint or weight. A paint written to a hidden row or to a
row under the topmost visible one is not stored, also when that row shows through a translucent row above it, and the
mark loses it when the graph is drawn again. A mark whose row
already has the paint counts as written, so its paint replaces the one another mark of the series left on the graph.
When one of these commands writes several paths of a series, the frontmost of them sets what the graph stores.
`appearance.addFill`, `appearance.addStroke`, `appearance.setItem`, `appearance.removeItem`,
`appearance.duplicateItem`, `appearance.moveItem`, `appearance.clear`, `appearance.reduceToBasic`,
@@ -809,6 +816,22 @@ kind takes them when the graph is drawn again. The graph saves the paragraph att
`categoriesPara` and `legendPara` in its label styles, and still sets each label's alignment for its place. The legend
leaves room for a legend label's stored indents, spacing and leading.
The `appearance.*` commands, `graphicStyle.apply` and `graphicStyle.redefine`, and the paint, stroke, gradient and
transparency commands given an `item` (or the Appearance panel's active row) store a graph label's object rows for its
kind of label: the paint, weight, opacity and blend mode of its topmost visible fill and stroke row, their order and
their place relative to the Characters row, and the label's object opacity and blend mode. They store them even when the
label already showed them. `transparency.set` without an `item`, `object.setProps` with an opacity or blend mode, and
an `appearance.copyFrom` (Eyedropper) pick of transparency store only the label's object opacity and blend mode;
`appearance.copyFrom` with `append` stores the rows. When the graph is drawn again, every label of that kind gets what
is stored, with a placed gradient fitted to each label, and the graph saves it as `valuesRows`, `categoriesRows` and
`legendRows` in its label styles. Rows below the topmost one of each kind, a row's effects, other stroke options (caps,
joins, dashes) and effects applied with `effect.*` are not stored. When labels of one kind are edited together, the
last one in the order of the targets (`ids` as given, otherwise paint order) sets what the kind keeps.
`appearance.copyFrom` onto the whole text of a label also stores the character attributes it applies and, from type,
the paragraph attributes. `paint.setFill` and `paint.setStroke` store a character fill or stroke when the paint goes to
the label's characters (the whole label, or all of its text highlighted with the Type tool), and the row when it goes to
a row. A stored character gradient also fits each label.
`effect.apply {"effect": "path.outlineObject"}` (Effect › Path › Outline Object) takes no parameters. Type that carries
it is drawn, exported and expanded as its glyph outlines and stays editable type, and the effects after it reshape
those outlines. On paths, compound paths and images it does not change what is drawn. On an image's own fill or stroke
@@ -1065,6 +1088,8 @@ Images follow the `compression` settings of their kind (`color`, `gray`, or `mon
`abovePpi` as placed they are resampled (`downsample`: `average`, `subsample` or `bicubic`) to `ppi`, and compressed
with `zip`, `jpeg` (at `quality`; images with transparency stay lossless) or `auto` (JPEGs stay JPEG, the others
lossless). `none`, `jpeg2000`, CCITT and `runLength` are written as ZIP, with a warning when an image needs them.
The pieces of an image bent by a Warp effect are resampled once, for the widest and the highest size any piece places
the image at, and all paint that one image.
A 16-bit PNG that is not resampled, recompressed or converted keeps its 16 bits a sample in PDF 1.5 and later files,
and is written at 8 bits in PDF 1.3 and 1.4 files.
CMYK images stay CMYK (DeviceCMYK, or ICC-based with the CMYK profile when colours are tagged, as in PDF/X-3 and
@@ -1098,7 +1123,10 @@ ignore `UserUnit` show such a page at its full size. The option applies
only to files without a standard: PDF/X files write such a page in points anyway, and PDF/A files keep the `UserUnit`, which
keeps their page boundaries within PDF/A-2's limit of 14,400 units (ISO 19005-2, 6.1.13), a PDF/A file at PDF 1.4
included (written as PDF 1.6). The dialog disables the
checkbox when a standard is chosen. In PDF 1.3 and 1.4 files, PDF/X-1a and PDF/X-3 among them, a real number can
checkbox when a standard is chosen. In a PDF without a standard (the option
off, PDF 1.5 or later), the warning for a page written with a `UserUnit` above 1 ends by naming the option; in PDF/A
files and `.ai` saves it does not.
In PDF 1.3 and 1.4 files, PDF/X-1a and PDF/X-3 among them, a real number can
be at most 32,767, and whole numbers are written as integers: a page longer than 32,767 pt whose sides aren't whole
numbers of points fails the export with an error naming the page before the thumbnails are drawn and the transparency is
flattened, and one whose art needs a real number past 32,767 fails with the same error when the file is written. A page whose short side is 3 pt or longer but would be under 3 units at that
@@ -2664,7 +2692,10 @@ compound path or symbol instance selected, it finds the objects of the same shap
ones), among those `select.all` would take and the objects in their groups, and returns `{active: true, count, ids}`,
the selected object first (at most 10,000). With a group of such objects selected (nested groups and clipping paths
included; not type or images), it finds the groups like it: as many objects, in the same order, each of the same
shape, lying the same way relative to each other (the group moved or scaled as a whole). `appearance` also asks for
shape, lying the same way relative to each other (the group moved or scaled as a whole). While Global Edit is off,
the command is disabled for any other selection, including a group that holds type, an image or nothing (it is off in
the Select menu, the Properties panel's Quick Actions do not show it, and the Control bar does not show its Global Edit
Options). `appearance` also asks for
the same fill and stroke (for groups, of each object in them), `size` for the same width and height; `artboards` is
`"all"` or a range such as `"1, 3-5"`, and `includeCanvas: false` leaves out the objects on no artboard. Missing
params come from `select.globalEditOptions` (the Global Edit Options, kept for the session; it returns them with
@@ -3440,7 +3471,10 @@ already walks Image Trace. Short agent entry points:
tool opens them, dialog `livePaintSelectionOptions`) are `selectFills` and `selectStrokes` (both on), `color` (the
highlight color, `#rrggbb` or a layer color's name; `#ff2a2a`) and `width` (the highlight's width, 1 to 20 screen
pixels; 4). The dialog's OK gives an error for a `color` with an alpha part (`#rrggbbaa` or `#rgba`) and changes
nothing.
nothing. `tool.setOption` gives an error that names the option and sets none of the values, whether the tool is
chosen or not, for a `selectFills` or `selectStrokes` that is not `true` or `false`, a `color` that is not `#rrggbb`,
`#rgb` (with or without `#`), a layer color's name or a basic color name such as `white`, or that has an alpha part,
a `width` that is not a number, and an option the tool does not have. A `width` outside 1 to 20 is set to 1 or 20.
With `selectStrokes` off, Alt-click selects the face under the pointer as a click does; with
`selectFills` off, a click selects the edge nearest the pointer as Alt-click does; with both off, a click selects
no face or edge. A drag of 3 screen pixels or more draws a marquee, and the release runs `select.set {ids}` with
@@ -3457,7 +3491,11 @@ already walks Image Trace. Short agent entry points:
them, dialog `livePaintBucketOptions`) are `paintFills` (on), `paintStrokes` (off), `highlight` (on), `color` (the
highlight color, `#rrggbb` or a layer color's name; `#ff2a2a`) and `width` (the face highlight's width, 1 to 20 screen
pixels; 4; an edge's highlight is half as wide). The dialog's OK gives an error for a `color` with an alpha part
(`#rrggbbaa` or `#rgba`) and changes nothing. With `paintFills` alone on, a click runs `livePaint.fill` and Shift-click runs `livePaint.strokeEdge`.
(`#rrggbbaa` or `#rgba`) and changes nothing. `tool.setOption` gives an error that names the option and sets none of
the values, whether the tool is chosen or not, for a `paintFills`, `paintStrokes` or `highlight` that is not `true`
or `false`, a `color` that is not `#rrggbb`, `#rgb` (with or without `#`), a layer color's name or a basic color name
such as `white`, or that has an alpha part, a `width` that is not a number, and an option the tool does not have. A
`width` outside 1 to 20 is set to 1 or 20. With `paintFills` alone on, a click runs `livePaint.fill` and Shift-click runs `livePaint.strokeEdge`.
With `paintStrokes` alone on, a click runs `livePaint.strokeEdge` on the edge within 4 screen pixels of the pointer,
or nothing when none is in reach, and Shift-click runs `livePaint.fill`. With both on, a click runs
`livePaint.strokeEdge` when an edge is within 4 screen pixels of the pointer and `livePaint.fill` otherwise, and
@@ -5442,6 +5480,11 @@ length that isn't a number above 0 is an error. An ellipse (Ellipse Properties):
counterclockwise from 3 o'clock; 0 to 360 is the whole ellipse) and `invertPie: true`, which swaps them. Each call is
one undo step.
`object.setLiveShape` returns a parameter error, and leaves the document and its undo history as they were, for a key
it does not take, at the top level (`` unknown parameter `path` ``) or in one of `items`
(`` unknown parameter `items[0].corner`; did you mean `items[0].corners`? ``), for a `sides` that is not a whole number
from 3 to 1000, such as 2.5, 2 or 1001, and for a negative `radius`. A `radius` of 0 removes the rounding.
```json
{"name":"run_command","arguments":{"command":"object.setLiveShape","params":{"sides":8,"polygonAngle":22.5,"sideLength":40}}}
{"name":"run_command","arguments":{"command":"object.setLiveShape","params":{"makeSidesEqual":true}}}
@@ -9752,6 +9795,11 @@ active the active artboard (the navigator's and the Artboards panel's).
{"name":"run_command","arguments":{"command":"tool.setOption","params":{"tool":"twirl","values":{"width":60,"rate":90}}}}
```
The Pencil's, the Paintbrush's and the Smooth tool's `fidelity` is in screen pixels: the tools send `path.freehand` and
`path.smoothRegion` the option divided by the zoom, so a stroke keeps as many points and a Smooth drag smooths as much
at any zoom. The Smooth tool's `fidelity` (0.05 to 100 px, 2.5 by default) is also the one an Alt smoothing drag with
the Pencil, Paintbrush or Blob Brush uses. The Blob Brush's `fidelity` is in points.
`tool.options {tool}` opens what double-clicking the tool's button opens (its params doc lists every tool), in the
desktop app. The Flare tool's are its Flare Tool Options (dialog `flareOptions`): `diameter` and `pathLength` (pt),
`opacity`, `brightness`, `growth`, `fuzziness`, `longest`, `rayFuzziness` and `largest` (%), `rays`, `rings`,
@@ -9791,7 +9839,12 @@ pointer show the current fill and the swatches before and after it), `selection`
default; when it is off, merge mode shades no regions), `gapDetection` (off) with `gapLength` (pt, 0 to 72; 3), `clickStrokeSplitsPath` (In Merge Mode,
Clicking Stroke Splits the Path; off), `highlightStroke` (Highlight Stroke When Editable; on) and `highlightColor`
(`#rrggbb` or a layer color's name; `#ff4f4f`, the layer color Red). The dialog's OK gives an error for a
`highlightColor` with an alpha part (`#rrggbbaa` or `#rgba`) and changes nothing. With `clickStrokeSplitsPath` on, in merge mode,
`highlightColor` with an alpha part (`#rrggbbaa` or `#rgba`) and changes nothing. `tool.setOption` gives an error that
names the option and sets none of the values, whether the tool is chosen or not, for a switch that is not `true` or
`false`, a `pickColorFrom` other than `artwork` or `swatches`, a `selection` other than `freeform` or `straightLine`, a
`gapLength` that is not a number, a `highlightColor` that is not `#rrggbb`, `#rgb` (with or without `#`), a layer
color's name or a basic color name such as `white`, or that has an alpha part, and an option the tool does not have. A
`gapLength` outside 0 to 72 is set to 0 or 72. With `clickStrokeSplitsPath` on, in merge mode,
the pointer shows scissors within 4 screen pixels of a stroke, `highlightStroke` draws the run of stroke under it in
`highlightColor`, and a click splits that run off its path: the run goes from the anchor or crossing point before the
pointer to the one after it, the path keeps the rest of it, and a copy of the path with the run, in the path's
@@ -10876,9 +10929,9 @@ it ends up in front), baked with `effect.expandAppearance`, then `object.pathfin
## Cutting Tools add-on
Cutting Tools is a built-in add-on that prepares art for cutting. Its commands are `addon.cutting.bridges` and
`addon.cutting.weed`; in the desktop app they are Object › Plug-ins › Cutting Tools › Stencil Bridges… and Weed Box and
Lines….
Cutting Tools is a built-in add-on that prepares art for cutting. Its commands are `addon.cutting.bridges`,
`addon.cutting.weed` and `addon.cutting.banner`; in the desktop app they are Object › Plug-ins › Cutting Tools › Stencil
Bridges…, Weed Box and Lines… and Banner Hems and Grommets….
### Stencil Bridges
@@ -10968,6 +11021,37 @@ dialog with Preview; a Spacing above 0 is used instead of the Count.
{"name":"run_command","arguments":{"command":"addon.cutting.weed","params":{"margin":"0.25 in","direction":"both","spacing":"2 in","gap":1}}}
```
### Banner Hems and Grommets
`addon.cutting.banner {hem?, grommets?, spacing?, grommetInset?, diameter?, top?, right?, bottom?, left?, weight?,
swatch?, allArtboards?}` marks where a printed banner is hemmed, its edge folded back and sewn
([hem](https://en.wikipedia.org/wiki/Hem)), and where grommets, rings set into the material to hang it, are punched
([grommet](https://en.wikipedia.org/wiki/Grommet)). The ranges, defaults and rules below are VectorCraft's own. The banner
is the bounds of the selected art, or each artboard when `allArtboards` is true (the default when nothing is selected).
`top`, `right`, `bottom` and `left` (each true by default) choose the sides that get marks. On each chosen side a hem
line runs the whole length of the edge, `hem` points inside it (0 to 100000, default 72; 0 leaves the hem lines out).
With `grommets` on (the default), each chosen side gets grommet marks `grommetInset` points inside the edge (0 to
100000, default 36): one at each end of the side, `grommetInset` from the edges across it, and the rest spread evenly
between them, as few as keep them at most `spacing` points apart (more than 0 and at most 100000, default 1728, 24 in). A corner that two
chosen sides share has one grommet. Each grommet mark is a circle `diameter` points wide (0.01 to 1000, default 27) with
a cross through its center. The marks are stroked `weight` points wide (0.01 to 1000, default 0.3) in the color swatch
`swatch` (default `"[Registration]"`), with no fill.
Each banner gets one group named "Banner Marks", holding its hem lines (named "Hem") and its grommets (groups named
"Grommet"), added on top of the current layer and selected, as one undo step. While a clip group, or a group inside one,
is edited in isolation, the groups go on top of the container that holds the outermost clip group around it. The command
fails with every side off, with no hem and no grommets, with nothing selected while `allArtboards` is false, when a
banner has no width or height, when a `hem` above 0 reaches the far edge of the banner (the full height with only one
of the top and bottom chosen, or the full width with only one of the left and right) or meets the hem on the opposite
side (half the height or width with both chosen), when a `grommetInset` does the same for the grommets or is more than half
the length of a chosen side, and when the grommets would be more than 100000. Result:
`{id, ids, hems, grommets}`: the first group's id, every group's id, and the number of hem lines and grommet marks.
Banner Hems and Grommets… opens the command dialog with Preview.
```json
{"name":"run_command","arguments":{"command":"addon.cutting.banner","params":{"hem":"1 in","grommetInset":"0.5 in","spacing":"2 ft"}}}
```
## Color Effects add-on
Color Effects is a built-in add-on: its effects are colour adjustments in Effect › Color Effects, its command is