Commit Graph
1053 Commits
Author SHA1 Message Date
dotCooCoo 175f51827d Symbols: redefining a dynamic symbol drops paints its new objects do not draw
When a dynamic symbol is redefined or edited, each instance kept every
appearance change whose path still named an object, even when that
object is now one that draws no fill or stroke of its own (an image, a
blend, a mesh) or a symbol instance given a gradient or pattern fill.
symbol.instance.setAppearance refuses such a paint, but the change stayed
on the instance and still counted as a color the document uses.

Fitting the changes to the new art now also clears a fill or stroke the
object at that path does not draw, and drops a change left empty.
2026-11-12 00:18:05 -08:00
BFlat 8782f6c697 Merge pull request #6794 from dotCooCoo/feat/blend-create-spine
Blend: the Blend panel's Create Spine menu sets whether new blends get a spine
2026-11-12 14:17:20 +07:00
BFlat 354a12be3f Merge pull request #6805 from dotCooCoo/fix/read-roots-prefs
MCP: preferences replies leave out folders outside a confined client's read roots
2026-11-12 14:16:11 +07:00
BFlat 053dc7ab8c Merge pull request #6746 from dotCooCoo/fix/plugin-ignored-grants-shared
Plug-ins: a grant one session stops counting stops counting for every session in the process on its folder
2026-11-12 14:15:46 +07:00
BFlat ccfe14f671 Merge pull request #6799 from Hassan1305/docs-6340-followup
Commands: draw_shape and object.reflect say which way they turn (#6340 follow-up)
2026-11-12 14:15:37 +07:00
BFlat e65da617cc Merge pull request #6787 from dotCooCoo/fix/convert-artboards-ids
Artboards: Convert to Artboards gives each new artboard its id without reading every artboard
2026-11-12 13:18:19 +07:00
BFlat 959f3dc609 Merge pull request #6779 from dotCooCoo/fix/script-sleep-reads-doc-cancel
Scripts: a canceled request stops a run asleep in $.sleep at its next slice
2026-11-12 13:18:11 +07:00
BFlat 41e4126089 Merge pull request #6679 from dotCooCoo/fix/plugin-grants-delete-test-portable
Plug-ins: the failed delete of grants.json is tested on every platform
2026-11-12 13:18:04 +07:00
BFlat c7f3c87c5c Merge pull request #6766 from dotCooCoo/fix/recovery-retake-lock
Data Recovery: a running app locks its area again when the lock file is removed
2026-11-12 13:17:40 +07:00
BFlat 880033c2bb Merge pull request #6793 from dotCooCoo/feat/gradients-organic-fades
Swatch libraries: Gradients › Organic Fades adds soft multi-stop fades that thin out to transparent
2026-11-12 13:17:19 +07:00
BFlat ee6aae1d1d Merge pull request #6769 from dotCooCoo/fix/options-dialog-menus
EPS: Save As options are menus with readable names, and Export As's Range shows an example
2026-11-12 13:17:11 +07:00
BFlat 37a392f154 Merge pull request #6621 from makesomethingshit/fix/6373-live-paint-drag
Fix #6373: Live Paint Bucket fills faces crossed by a drag
2026-11-12 13:17:02 +07:00
dotCooCoo 00624da7ad MCP: preferences replies leave out folders outside the read roots
Under --automation-read-root, prefs.get, prefs.list, prefs.set and
prefs.reset returned the folder preferences (fontsFolder, pluginsFolder,
scratchPrimary, scratchSecondary, recoveryFolder, templatesFolder) and
the export presets' folder even when they were outside the read roots.
Such a folder preference is now null, as ui.inspect leaves it out, and
such a preset's folder is left out. An empty folder and the scratch disk
choices stay; without roots the replies are unchanged.
2026-11-11 22:13:53 -08:00
dotCooCoo 1eb02f2f7a Merge main into fix/plugin-ignored-grants-shared 2026-11-11 22:03:31 -08:00
HassanKhan 386e405800 Commands: draw_shape and object.reflect say which way they turn; test the notes the key walk misses (#6340)
draw_shape's rotation also turns rectangles and ellipses; object.reflect's numeric axis is counter-clockwise from horizontal. A test covers that axis and the Scatter brush's rotation range, which every_turn_param_says_which_way_it_turns can't reach.
2026-11-12 10:47:06 +05:00
BFlat 485d4e3fff Merge pull request #6747 from dotCooCoo/fix/plugin-grant-sealed-api
Plug-ins: only an approval records a grant, and installs need one
2026-11-12 12:41:15 +07:00
BFlat a8ac772c53 Merge pull request #6753 from dotCooCoo/feat/pixel-align-new-objects
Transform: Align New Objects to Pixel Grid makes new paths pixel-aligned
2026-11-12 12:41:07 +07:00
BFlat 7e27e6e4c9 Merge pull request #6761 from dotCooCoo/feat/dynamic-text-path-presets
Type: Dynamic Text Presets put type on a circle, arch or bow
2026-11-12 12:40:55 +07:00
BFlat 4eb0915795 Merge pull request #6781 from dotCooCoo/feat/diamond-gradient
Gradients: diamond gradients run the stops from the center out to a square
2026-11-12 12:40:46 +07:00
BFlat 247f9e1569 Merge pull request #6763 from dotCooCoo/feat/styles-textures-library
Graphic Styles: built-in Textures library with grain, canvas, craquelure and tile styles
2026-11-12 12:40:38 +07:00
BFlat 63bdfc1655 Merge pull request #6758 from dotCooCoo/test/select-skips-raster-effects
Selection: a click on a drop shadow or glow selects the object under it
2026-11-12 12:40:12 +07:00
BFlat fee2b1340a Merge pull request #6773 from dotCooCoo/perf/flatten-opaque-chain
Flatten Transparency: opaque art that touches only opaque art stays vector
2026-11-12 12:39:46 +07:00
dotCooCoo 1e70274189 Swatch libraries: Gradients › Organic Fades adds soft multi-stop fades that thin out to transparent
Window › Swatch Libraries › Gradients gains Organic Fades, a gradient
library of fifteen fades (ten linear, five radial). Each runs through
three to five unevenly spaced stops with off-center midpoints, mixes
with the Perceptual method, and thins out to transparent at the end of
a linear fade or at the edge of a radial one. The colors are computed
from VectorCraft's own OKLCH anchors.

The library also lists in the Swatches panel's library menu, in
swatch.library.list (category "gradients") and in the Gradient panel's
Presets. swatch.library.add keeps each fade's stops, opacities,
midpoints and method in RGB and CMYK documents.

The other built-in libraries are unchanged: their gradients still mix
with Classic and keep centered midpoints, and a test checks it.

- Gradient previews in the Swatch Libraries panel, the Gradient
  panel's Presets menu, swatch tiles and the toolbar drew every stop
  opaque. Each chip vertex now takes the sampled opacity as its alpha
  (freeform points too), and a chip with any translucent vertex draws
  a white and gray checkerboard under the gradient. Opaque gradients
  draw as before.
- When the preferences are applied, a saved gradient preset whose name
  matches a built-in preset, or an earlier saved preset, in any case,
  is renamed to the first free "<name> N" (N from 2), so a saved
  preset named like a new built-in fade stays listed and can be
  applied and deleted.
2026-11-11 21:26:11 -08:00
dotCooCoo f82a31045c Blend: the Blend panel's Create Spine menu sets whether new blends get a spine
The Blend panel gets a Create Spine menu (Auto, Always, Never) under Make,
and object.blend.createSpine {mode?} sets or reads it. It is kept with the
preferences, is not an undo step and leaves blends already made as they are.
object.blend.make takes createSpine to choose for one new blend.

Auto and Always give every new blend a straight spine, as before. Never
makes a blend without one: its steps sit where a straight spine puts them,
object.blend.info reports hasSpine: false, easing is refused and dimmed,
Reverse Spine and the spine point commands refuse it, Release gives back
no spine path, and Replace Spine gives it a spine. A blend taking more keys
keeps whether it has a spine. Native files save noSpine; older files open
with their spines.

Builds on #5177 by adambelis.
2026-11-11 21:11:12 -08:00
dotCooCoo cdeb7946e0 Data Recovery: a left copy that can't be removed yet stays the session's own
drop_left forgot a copy in an area the session left before removing it, so a copy whose removal failed (the area read-only for a moment) could later be offered back to the same session as a crash's copy. The entry now stays until both files are removed, and the next heartbeat tries again.
2026-11-11 21:05:30 -08:00
dotCooCoo 2f7c3854c7 Merge main into fix/script-sleep-reads-doc-cancel
# Conflicts:
#	docs/target-app-parity.md
2026-11-11 21:01:53 -08:00
dotCooCoo 2846fb3f43 Merge main into fix/plugin-grants-delete-test-portable 2026-11-11 21:01:50 -08:00
dotCooCoo 605a74f19f Artboards: Convert to Artboards gives each new artboard its id without reading every artboard
Convert to Artboards found the highest artboard id twice for each object it
converted: once for the new artboard's name and once in
Document::next_artboard_id. Converting N objects read about N^2 artboards.

The command now keeps the highest id as it adds artboards, and
Document::next_artboard_id_above gives the next id from it. When an artboard
has id u32::MAX, it falls back to next_artboard_id, which takes the smallest
free id. The ids and names it gives are unchanged.
2026-11-11 20:56:36 -08:00
dotCooCoo 480d2763e0 Merge feat/eps-save-use-artboards into fix/options-dialog-menus 2026-11-11 20:48:58 -08:00
dotCooCoo 651041fc0c Merge main into fix/options-dialog-menus
# Conflicts:
#	docs/mcp.md
2026-11-11 20:48:58 -08:00
makesomethingshit 88894ef27c Merge latest main and retain Live Paint and Eyedropper evidence 2026-11-12 13:48:23 +09:00
makesomethingshit dfa8403ed0 Fix #6373: Keep painting through long Live Paint drags 2026-11-12 13:46:51 +09:00
BFlat aa4657e1ce Merge pull request #6704 from dotCooCoo/fix/shape-tool-handles-scale
Shape tools: a drag on a bounding-box handle scales the selection
2026-11-12 11:43:06 +07:00
BFlat b945662f75 Merge pull request #6700 from dotCooCoo/fix/script-files-followups
Scripts: File and Folder exists checks the kind, encode keeps slashes, every call is counted
2026-11-12 11:42:26 +07:00
BFlat d843a4f1ec Merge pull request #6670 from dotCooCoo/fix/plugin-put-back-result
Plug-ins: an update left in the store by a failed put-back turns a disabled plug-in on
2026-11-12 11:42:01 +07:00
BFlat 5e181e2aec Merge pull request #6699 from dotCooCoo/fix/links-read-roots
MCP: links.list, links.check, links.info and document.open leave out paths outside the read roots
2026-11-12 11:41:52 +07:00
BFlat 3ba9ae2b47 Merge pull request #6738 from christianlappin/codex/fix-6404-eyedropper-text-scale
Fix Eyedropper font size and horizontal scale on transformed text
2026-11-12 11:41:23 +07:00
BFlat ea3a4ec373 Merge pull request #3145 from adambelis/feat/width-smooth-profile
Width profiles run smooth between their points
2026-11-12 11:41:15 +07:00
makesomethingshit 7a5486d15d Merge upstream main into Live Paint Bucket fix 2026-11-12 13:39:41 +09:00
dotCooCoo 3fd653a25a EPS: Save As shows the saved artboard as the range when Use Artboards was on
A save that set useArtboards: true and named an artboard with artboard
or artboards, without range, wrote that artboard, but file.formatOptions
reported the default range. The Save As dialog then opened on All, and
OK saved every artboard. file.formatOptions now reports those artboards
as the range unless Use Artboards was saved off.
2026-11-11 20:35:16 -08:00
dotCooCoo 66d21471ae Gradients: diamond gradients run the stops from the center out to a square
A new gradient kind, `diamond`, runs its stops from the center (the
start) out to a square with a corner at the end of the vector; the
aspect stretches the square across the vector into a rhombus. The
Gradient panel's Type row has a Diamond button, the Gradient tool draws
the square with the aspect handle and center ring, and a gradient
fitted to an object covers its box.

- Model and canvas: the level is |x| + |y| in the square's frame; a
  square with no area (no vector, an aspect of 0, numbers out of range)
  paints the last stop. The canvas draws it as pixels, out to a
  stroke's miters, caps and arrowheads. Transforms keep the vector and
  take the mapped size across it as the aspect.
- Commands: `paint.setFill`, `paint.editGradient` and
  `paint.setGradientGeom` take `kind: "diamond"`; a negative aspect or
  a focal point is an error. A conic or diamond gradient that a plug-in
  returns with a focal point loses the focal point.
- Gradient tool: dragging the aspect handle of a radial or diamond
  gradient whose file gave it a negative aspect now sets a positive
  aspect; only a conic's negative aspect mirrors it.
- Export: PDF, SVG, EPS and legacy .ai write four linear gradients, one
  for each quarter of the square, clipped to the shape (PDF as axial
  shadings). PDF and SVG write an image for translucent stops, a
  dithered fill or a flat square, and for the Perceptual method unless
  PDF writes the stops as spot color shadings. SVG writes a diamond on
  type characters as a radial gradient through the corners, and so
  does CSS. A swatch library saved as CSS gets four corner layers, a
  value for the `background` property (a circle when the swatch is
  turned by an angle that is not a multiple of 90 degrees). The .ai
  editing data holds a radial gradient through the corners. The
  document exports give a warning.
- SVG export: a stroke drawn as an image, as conic wedges or as diamond
  quarters now covers the miters, caps and arrowheads that reach past
  its paint box.
- PDF import reads a function-based shading whose color is the same
  along each square about the origin of its space as a diamond.
- Object > Expand gives nested squares or a mesh of rings.

Docs: docs/mcp.md, docs/target-app-parity.md.
2026-11-11 20:27:48 -08:00
dotCooCoo 8bd437687a Scripts: a canceled request stops a sleeping or waiting run at its next slice
script_pump read vectorcraft_doc::cancel only after the guard that keeps
a run waiting, so a run asleep in $.sleep went on waiting until its wake
time (up to 1,000 ms), and a run waiting at a dialog or for approval to
grow waited until someone answered. The check now runs before that
guard, after the dialog-failure check, so a canceled request ends the
run at the next slice and every document goes back.
2026-11-11 20:01:25 -08:00
dotCooCoo a9e7dfb2f8 Merge main into fix/options-dialog-menus 2026-11-11 19:59:50 -08:00
dotCooCoo d1ceb73b39 Merge main into fix/recovery-retake-lock 2026-11-11 19:59:49 -08:00
dotCooCoo f3b089f83f Merge main into feat/styles-textures-library 2026-11-11 19:59:30 -08:00
dotCooCoo a447b78ac4 Merge main into fix/plugin-grants-delete-test-portable 2026-11-11 19:59:24 -08:00
dotCooCoo bfabe4f980 Merge main into perf/flatten-opaque-chain 2026-11-11 19:18:07 -08:00
dotCooCoo f95c4b51c9 Flatten Transparency: opaque art that touches only opaque art stays vector
Grouping for flattening joined every pair of objects whose 1 pt reach
boxes touched, transitively, so a row or grid of opaque objects next to
one see-through object became one group and was flattened with it.

Now a group holds each see-through object and every object its reach
touches. An object without transparency joins only where its reach
touches a member and it lies above that member but below the group's
topmost object, whose place the group takes, so the stacking order
stays the same. In files without transparency with Clip Complex Regions
on, art under a group within one image pixel of a member joins it too,
with the pixel size taken from the image's actual resolution. Objects in
an overlap set that includes one inside a clip group or clipping layer
keep the previous grouping.

The 1 pt antialiasing margin now goes around a group's art once instead
of once per nested group (a stroked path's plain art is a group, so it
had 2 pt).

On 3,000 stroked rectangles, 60 with a drop shadow, the Flattener Preview
counts 180 affected objects where it counted 3,000, and Flatten
Transparency with the Medium preset makes 240 flat regions and 2 images
where it made one image of the whole grid.
2026-11-11 19:17:06 -08:00
BFlat 6b8be09699 Merge pull request #6688 from dotCooCoo/fix/plugin-call-reprepare-test
Edit: a command that ends a drag keeps its unapplied preview
2026-11-12 10:06:12 +07:00
dotCooCoo 17a51fc591 Data Recovery: a running app locks its area again when the lock file is removed
While an app runs, its Data Recovery area's .lock file, or the whole area
folder, can be removed by the user, a cleaner or another program. The app
kept writing copies into an area that no lock held, and another app could
lock that area and offer the copies as a crash's copies.

Each recovery save and heartbeat now checks that the file at the area's
.lock path is still the file the app locked. When the lock file or the
folder is gone, or another file is in its place, the app makes the area
again if it is gone, locks it again, and writes again the copies that went
with the folder. A lock file that can't be read for another reason still
counts as held. When another app holds the area by then, the app takes a
new area and writes every copy there. The app does not offer or discard
its own copies in the old area as a crash's copies. It removes each one
when its document has a copy in the new area, or is saved, reverted or
closed, and removes all of them when it quits with nothing unsaved. The
app that holds the old area also removes them when it quits with nothing
unsaved.

A copy that was being written when the Data Recovery folder preference
changed is now removed from the folder it was written to. Before, the
document took that copy as its current one, and the copy stayed in the old
folder after the document was saved or closed.
2026-11-11 19:04:16 -08:00