Commit Graph
893 Commits
Author SHA1 Message Date
dotCooCoo 67ebbf0b53 Merge main into feat/warp-images 2026-11-12 04:59:37 -08:00
BFlat 7f9866f42a Merge pull request #6818 from dotCooCoo/feat/korean-line-break-anywhere
Type: Korean words break at spaces unless Korean Line Break Anywhere is on
2026-11-12 19:13:57 +07:00
BFlat 0b4ccdfb5d Merge pull request #6830 from dotCooCoo/fix/artboard-files-ask-before-replacing
Save and Export: files written beside the picked one ask before replacing a file there
2026-11-12 19:13:47 +07:00
BFlat 4306a1d1fb Merge pull request #6808 from dotCooCoo/feat/stencil-bridges
Cutting Tools: Stencil Bridges keeps the islands of a stencil attached
2026-11-12 18:19:57 +07:00
BFlat f4df78ef4a Merge pull request #6790 from dotCooCoo/feat/hpgl-export
File formats: HP-GL (.plt) plots export for pen plotters and cutters
2026-11-12 18:19:22 +07:00
BFlat 61650e44a2 Merge pull request #6814 from dotCooCoo/feat/brush-replace-art
Brushes: Alt-drag art onto a brush to replace its art
2026-11-12 16:02:52 +07:00
BFlat 87c0d5cb5e Merge pull request #6826 from dotCooCoo/feat/3d-classic-rotate
3D (Classic): Rotate (Classic) turns flat art in 3D with the No Shading and Diffuse surfaces
2026-11-12 16:02:41 +07:00
dotCooCoo cc2d090335 Merge main into fix/artboard-files-ask-before-replacing 2026-11-12 00:41:07 -08:00
dotCooCoo fdbf49d73a Merge main into feat/korean-line-break-anywhere 2026-11-12 00:40:59 -08:00
BFlat 1a7aa834db Merge pull request #6786 from dotCooCoo/fix/save-export-show-every-note
Save and Export: the status bar's hover lists every note
2026-11-12 15:13:51 +07:00
BFlat ba2aefb5dd Merge pull request #6815 from dotCooCoo/feat/para-style-options-tabs
Paragraph Styles: Style Options edits a style's tab stops
2026-11-12 15:12:55 +07:00
dotCooCoo 7da7c2c456 Merge main into fix/artboard-files-ask-before-replacing 2026-11-11 23:51:03 -08:00
dotCooCoo 08de741ca9 3D (Classic): Rotate (Classic) turns flat art in 3D with the No Shading and Diffuse surfaces
Effect › 3D and Materials › 3D (Classic) › Rotate (Classic)… turns every
fill and stroke as one flat plane, as Rotate does, and shades it with the
classic No Shading or Diffuse surface.

- `effect.apply` with `threeD.classicRotate`: the Position rotation and
  Perspective, `surface` (`none` or `diffuse`), the classic lights,
  Ambient Light, Blend Steps and Shading Color. It has no highlight, no
  Draw Hidden Faces and no shadow.
- The dialog shows Position on the Rotation tab and the surface and
  lights on the Lighting tab, with no Object tab.
- Groups and layers turn about one shared center, and the effect also
  goes on a fill or stroke, as Rotate's does.
- `effect.lightingPreset` refuses it, as it refuses the other classic
  3D effects.
- Unknown parameters, numbers out of range, bad flags, a surface other
  than No Shading or Diffuse and bad shading colors are refused with an
  error.
2026-11-11 23:44:11 -08:00
dotCooCoo b262d10e89 Save and Export: files written beside the picked one ask before replacing a file there
A save or export that writes a file per artboard, linked images or image
maps names them after the file picked in the save panel, which asked only
about that name. A file already there under one of the other names was
replaced without a question.

Save As, Save a Copy, Save as Template, Save and Export now check those
files before writing anything. When any is there, nothing is written and
a replaceFiles question names it (and lists all of them when there are
several). OK runs the save or export again on the document that asked and
replaces the named files; a file it would now write that the question did
not name is asked about again. Cancel writes nothing. A background save
or export checks from its worker and asks once it ends, after a dialog
open then. Files the document's last Save or Save As wrote are replaced
without asking.

Services::exists is now an Arc<dyn Fn(&str) -> bool + Send + Sync>.
2026-11-11 23:39:32 -08:00
dotCooCoo 96ad9344ee Merge main into fix/warp-styles-map 2026-11-11 23:31:05 -08:00
dotCooCoo 9c5d22bccc Merge main into feat/hpgl-export 2026-11-11 23:31:04 -08:00
BFlat 5e63104d88 Merge pull request #6800 from dotCooCoo/fix/plugin-automation-install-approval
Plug-ins: an install that automation asked for is not approved in its dialog
2026-11-12 14:16:59 +07:00
BFlat abfd776ef4 Merge pull request #6797 from dotCooCoo/feat/dxf-leave-out-images-hatches
DXF: export options leave placed images and fill hatches out, and CNC / CAM turns both off
2026-11-12 14:16:20 +07:00
dotCooCoo ff826ed1bd Type: Korean words break at spaces unless Korean Line Break Anywhere is on
Korean text broke after every Hangul syllable. A paragraph now has
Korean Line Break Anywhere, set from the Paragraph panel menu (with the
East Asian options), from the East Asian Composition Settings section of
Paragraph Style Options, and with `text.setFormat {koreanLineBreakAnywhere}`.

- Off, a word that contains Hangul (the characters between spaces) breaks
  only at its spaces and after East Asian punctuation, or where the word
  is wider than the line. Both composers follow it, and the word takes no
  hyphen. On, a line may break between any two syllables, as before.
- New type has it off. Paragraphs and text objects saved before the
  option read as on, so their lines do not move; the value is saved only
  when it is off.
- Paragraph styles carry it, Reset Panel turns it off, and the .ai writer
  reports it as lost for Korean paragraphs.

The help page: https://helpx.adobe.com/illustrator/desktop/design-with-text/fonts-and-scripts/set-line-breaks-korean-text.html

The command is described in docs/mcp.md, and docs/target-app-parity.md
lists the option.
2026-11-11 23:06:55 -08:00
dotCooCoo 5d8065e929 3D (Classic): Revolve (Classic) sweeps a profile with Angle, Cap and Offset and the classic surfaces
Effect › 3D and Materials › 3D (Classic) › Revolve (Classic)… sweeps the
profile round a vertical axis, as Revolve does, and draws every face with
the Wireframe, No Shading, Diffuse and Plastic surfaces of Extrude & Bevel
(Classic).

- `effect.apply` with `threeD.classicRevolve`: Angle (0 to 360), Cap,
  Offset (0 to 1000 pt) from the left or right edge of the profile's
  bounds, the Position rotation and Perspective, and the classic lights,
  Ambient Light, highlight, Blend Steps and Shading Color.
- Groups and layers revolve about one shared axis, and the effect also
  goes on a fill or stroke, as Revolve's does.
- `effect.lightingPreset` refuses it, as it refuses Extrude & Bevel
  (Classic).
- Revolve faces carry their view-space normal, and
  `three_d::revolve_facets` hands them to the classic surface code.
- Unknown parameters, numbers out of range and bad flags, edges,
  surfaces and colors are refused with an error.
2026-11-11 23:04:22 -08:00
dotCooCoo 44d5d20f58 Paragraph Styles: Style Options edits a style's tab stops
Paragraph Style Options and New Paragraph Style gain a Tabs section. It
lists the style's stops and edits the selected stop's Alignment, position
(X:, or Y: for vertical type), Leader and Align On character. Add puts a
left stop 36 pt past the furthest one, Delete Tab removes the selected
stop, and Clear All Tabs leaves the style with no stops. OK sorts the
stops by position and keeps the stop edited last when two share one
position. Reset Panel removes the style's tabs.

paraStyle.new, paraStyle.setAttrs and paraStyle.edit check changed tabs
stop by stop: at most 256 stops, and each changed stop's position from 0
to 100000 pt and leader of at most 8 characters. Stops the style already
has are kept as they are. Changed tabs are sorted by position, keeping
the first of stops at one position. text.tabs.set rejects a leader longer
than 8 characters, an Align On value of more than one character and more
than 256 stops. Loading paragraph styles skips a style whose indents,
spacing, hyphenation, justification or tabs are out of range.

Docs: docs/mcp.md, docs/target-app-parity.md.
2026-11-11 23:02:47 -08:00
dotCooCoo 60c2130960 Merge main into feat/hpgl-export 2026-11-11 22:29:22 -08:00
dotCooCoo 2a494dec50 Cutting Tools: Stencil Bridges keeps the islands of a stencil attached
Object › Plug-ins › Cutting Tools › Stencil Bridges… (`addon.cutting.bridges`)
cuts strips of a set width out of the selected art so that a stencil cut
from it holds together: every island (the inside of an O, A or 8, a hole in
a shape) stays joined to the sheet, directly or through another island.
Bridges take the shortest crossings that fit first, then spread around each
island up to the count asked for, at least two widths apart. They run
vertically, horizontally or along the shortest crossing among 12
directions 15° apart.

- The art is measured by the area its outlines enclose, whatever their
  paint, with hidden objects left out; type by its glyph outlines, without
  converting the type. The result is one compound path with the strips cut
  out, painted as the topmost selected shape with outlines, in the place of
  the topmost selected object with outlines. Selected objects with no
  outlines in the art stay where they are.
- Keep Original (on by default) moves the selected objects that make up the
  art to a new hidden layer, Stencil Original; off replaces them.
- Art with no islands, or none a bridge of the width fits, is left as it is
  with a message and no undo step. Islands the cut result still encloses
  are counted in `unbridged`, with a message. Otherwise the run is one undo
  step.
- Curves are followed within a twentieth of the width (0.002 to 0.25 pt).
  Art that reaches more than 10000000 pt from the origin or has more than
  200000 anchors is refused before it is combined. Art is also refused when
  its combined area has more than 4000 outlines, when its outlines need
  more than 200000 straight segments, or when placing the outlines or
  joining every island takes more work than a fixed budget allows; when
  the budget runs out while extra bridges are added, the bridges found so
  far are kept.

Tests in vectorcraft-pathops, vectorcraft-engine and vectorcraft-ui-egui,
command_sweep cases, catalog rows in all 27 languages, docs/mcp.md, the
evidence list in docs/target-app-parity.md and the ROADMAP progress log.
2026-11-11 22:17:43 -08: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
dotCooCoo d69e9c10d7 Brushes: Alt-drag art onto a brush to replace its art
Art Alt-dragged (Option-dragged on macOS) from the canvas onto a
scatter, art or pattern brush in the Brushes panel becomes its art
(brush.replaceArt). When strokes use the brush, the app checks the art
first, then a dialog offers Apply to Strokes, which redraws them with
the new art, Leave Strokes, which keeps the brush and its strokes as
they were and adds "<name> copy" with the new art as the current brush,
and Cancel. Each change is one undo step.

A pattern brush takes back the tile groups brush.placeArt places, frames
included, and takes other art as its side tile. Calligraphic and
bristle brushes, an empty selection and art with no width are refused.

Art Alt-dragged off the canvas now reaches the panels as the art the
drag started with. Before, the panels got the ids of the copy the drag
previews, which no longer exist once the release over a panel ends the
move.

brush.new now also measures a symbol instance in the selected art by its
symbol's art when it checks that the art has width.

Docs: docs/mcp.md, docs/target-app-parity.md.
2026-11-11 22:11:17 -08:00
dotCooCoo ad05c3b99d Plug-ins: an install that automation asked for is not approved in its dialog
An approval question that a control request, MCP, injected input, or a
file dialog one of them opened leads to now keeps OK disabled and
refuses every confirm, a person's click included. The dialog says to
choose Object › Plug-ins › Install Plug-in…, and ui.installPlugin answers
approval: "personMustStartInstall". The person's own Install Plug-in…,
File › Open or drop inspects the module again and asks a new question
with its half-second delay.

The origin is fixed when the request is made and goes with a native
file dialog's deferred answer and the web picker's answers, which now
arrive apart from drops and from window.vectorcraft.openFile (always
automation). A question about taking another module's place now opens
in the approval dialog, and automation's replace: true no longer skips
it. A module that needs no approval still installs at once.
2026-11-11 21:56:58 -08: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 72adc36f55 Merge pull request #6767 from dotCooCoo/feat/document-setup-color
Document Setup: a Color tab sets the color mode and the assigned profiles
2026-11-12 12:39:38 +07:00
BFlat 35a5b7fbad Merge pull request #6774 from dotCooCoo/fix/plugin-approval-held-input
Plug-ins: a key or button held before the approval's OK took input approves nothing
2026-11-12 12:39:29 +07:00
dotCooCoo f1251af6e4 DXF: export options leave placed images and fill hatches out, and CNC / CAM turns both off
DXF Options gets Include Placed Images and Include Fill Hatches, and
document.exportDxf and document.export {format: dxf} take
includeImages and includeHatches. Both are VectorCraft's own options
and default to true, so Custom exports write what they wrote before.

- includeImages: false writes no IMAGE entity, IMAGEDEF, reactor or
  linked file for a placed image, and does not decode its pixels.
- includeHatches: false writes each filled area's outlines without the
  solid HATCH after them.
- Each adds one note to warnings when it left something out. R12,
  which has neither, keeps its own notes.
- The CNC / CAM preset sets both to false, so its drawing holds the
  cutting paths alone; the options given still override it, and
  changing either checkbox shows Custom.

Docs: docs/mcp.md, docs/control-protocol.md, docs/target-app-parity.md.
2026-11-11 21:10:30 -08:00
dotCooCoo 651041fc0c Merge main into fix/options-dialog-menus
# Conflicts:
#	docs/mcp.md
2026-11-11 20:48:58 -08:00
dotCooCoo 35be7952c8 Save and Export: the status bar's hover lists every note
A save or an export with several notes named only the first of them in
the status bar, with the count, and the others could not be seen. The
status bar now keeps every note of a save or an export for the status
message's hover, as it does for an open's notes since #6752: resting
the pointer on the message lists them in the order the reply gives them
(a save's notes start with what the format loses), and screen readers
receive the list after the message. The status text is unchanged.

This covers Save, Save As, Save a Copy, Save as Template, Save a
Timestamped Copy, Save as PDF, Export As, Export Selection, Export for
Screens, Asset Export, Save for Web, Preview in Browser, Save for Office
Documents, Text Export Options, a print to a file and the CSS Properties
panel's export. The open, the saves and the exports read a reply's notes
through one helper.

Docs: docs/mcp.md and the css.exportFile params text,
docs/control-protocol.md, docs/target-app-parity.md.
2026-11-11 20:44:53 -08:00
dotCooCoo 987dd18aff File formats: HP-GL (.plt) plots export for pen plotters and cutters
VectorCraft could open and place HP-GL plot files but not write them,
so art for a pen plotter or a vinyl cutter had to go through another
program.

Export As, document.export and Export Selection now write HP-GL.
vectorcraft_cad::hpgl::export draws each visible path once along its
own line: a filled shape is its closed outline and a stroked path its
center line. Type is drawn as glyph outlines, a gradient mesh as its
outline, and a symbol instance as its art with its effects and the
instance's stain. Clipping masks cut the art they clip, and the art is
cut at the artboard's edges. Hidden and non-printing layers, hidden objects,
objects at 0% opacity, template layers, guides and placed images are
left out. Coordinates are plotter units (1016 to the inch, y up) from
the artboard's bottom-left corner or its center, and art more than
8,388,607 units from the origin is cut off.

Each color is a pen, in the order the plot first draws in it (up to
255), or a pen table maps each path to the pen of the nearest color.
With Use Artboards every file of the export uses the same numbering.
The pens draw in turn, each in paint order or, with sortPaths, nearest
path first. Curves are flattened to curveTolerance (0.1 pt by default).
hpglVersion "hpgl" writes IN, SP, PU and PD; "hpgl2" also writes the
palette (NP, PC) and each pen's paths as one encoded polyline (PE).
Options are checked, and Export As writes the file with the defaults.
Plots read back by the HP-GL reader give the same lines.

Docs: docs/mcp.md, docs/control-protocol.md, docs/file-format-parity.md,
docs/target-app-parity.md.
2026-11-11 20:44:32 -08: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 95325e8ef0 Merge pull request #6694 from dotCooCoo/feat/char-style-options-tcy-offsets
Type: Character Style Options sets Tate-chu-yoko Up/Down and Left/Right
2026-11-12 11:41:41 +07:00
BFlat d349c4b586 Merge pull request #6775 from dotCooCoo/feat/image-remove-background
Image Tools: Remove Background clears an image's background in its pixels
2026-11-12 11:41:32 +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
dotCooCoo c792bdf0d3 Plug-ins: a key or button held before the approval's OK took input approves nothing
The install approval's OK now also waits for these to be let go of:

- Enter or Space held down while OK was disabled, whose key repeat
  clicked OK once it had the keyboard focus.
- A pointer button held while OK was disabled, even after another
  button is pressed once OK takes input.
- A pointer button held on the question before, when a new question
  takes its place.

The wait also starts over when the window lost the focus since the
frame before, even if it has the focus again by the next frame.
2026-11-11 19:49:06 -08:00
dotCooCoo f65f3029a6 Image Tools: Remove Background clears an image's background in its pixels
A new built-in add-on, Image Tools (Object › Plug-ins › Image Tools),
adds Remove Background… (`addon.image.removeBackground`). It makes the
background of the selected images transparent by lowering the alpha of
their own pixels, in one undo step, with no service or model. The
background is the most common color along the image's edges, the
average of the image's corners, or colors the user picks. Contiguous
(on by default) clears it only where it reaches in from an edge; off,
it is cleared wherever it is. Tolerance and Softness (0 to 100, 10 by
default) set how near a color must be to be cleared and the band over
which pixels fade out. Match measures that nearness as the RGB
distance or as the largest difference on one channel. It is a
VectorCraft addition.

- The image stays an image: an embedded PNG with alpha, the source's
  ICC profile and resolution, and 16 bits or gray when the source is.
  A linked image is embedded and keeps its Placement Options.
- When the edges hold at least as many clear pixels as pixels of their
  most common color, edge mode clears nothing, so a second run leaves
  the subject alone. Corner mode leaves clear corners out of the
  average and clears nothing when all four are clear.
- With Match set to Each Channel, a tolerance of t / 255 × 100 clears
  the colors within t 8-bit steps on every channel.
- A CMYK image, a linked image that shows its preview, an image that
  would need more than the decode allowance (checked from its header)
  and a result with no pixel left are refused, and the document stays
  as it was. When no pixel changes, no undo step is added. The result
  reports `cleared`, the pixels made fully clear.
- Picked colors are hex colors, with or without `#`, or black, white,
  red, green or blue.
- The dialog opens with Preview off; with Preview on, the canvas shows
  the result, and Cancel puts the image back. While the dialog
  previews, the session keeps the images' decoded pixels (at most
  128 MiB, 32 MiB in the web app) so each preview step does not decode
  them again, and releases them when the dialog closes with OK or
  Cancel. A run that is not a preview step keeps nothing.

Docs: docs/mcp.md (Image Tools add-on), docs/target-app-parity.md.
2026-11-11 19:47:28 -08:00
dotCooCoo e609b26a95 Warp: bend each style as one Bézier patch, and keep saved warps' look
Each of the fifteen Warp styles now bends the bounds as one Bézier patch.
The style sets the patch's control points from the bend and the size of
the bounds, the horizontal distortion scales each column of control
points about its middle, and the vertical distortion scales each row.
The Warp effects and warp envelopes share the map (`WarpNet`). Content
with no width or no height takes the middle of the patch along that
side.

A warp carries the map it draws with as `version`. New warps, the
built-in graphic styles' Warps and warps opened from .ai files get 1.
Warps in .vectorcraft documents saved before the version existed read
as 0 and keep the earlier map, so those documents keep their look.
Edits keep a warp's version, and Warp Options editing several objects
keeps each one's own. effect.apply, effect.setParams and the warp
envelope commands take `version` 0 or 1 (`1.0` counts as 1) and refuse
any other value. An .ai file holds a warp's settings and not its
version, so a version 0 warp saved to .ai opens again with version 1.
The .ai writer compares a style's settings without the version, so
saved warps still export as editable effects.

Docs: docs/mcp.md (Envelopes), docs/effects-parity.md (Warp),
docs/target-app-parity.md.
2026-11-11 19:40:01 -08:00
dotCooCoo 7559607037 Document Setup: a Color tab sets the color mode and the assigned profiles
Document Setup gets a Color tab with the document color mode (RGB Color
or CMYK Color), a Convert to CMYK or Convert to RGB box for a mode
change (cleared, the colors keep their numbers), and the RGB and CMYK
profiles assigned to the document, with a working-space entry for none.

When the tab changes something, OK runs document.setup, then
edit.assignProfile, then file.documentColorMode in one command.batch,
and the document's changes are one undo step. Assign Profile runs first,
so a mode change converts through the profile picked with it. An
unchanged Color tab adds no color commands, and Cancel, or OK with
nothing changed, records no undo step. A Color tab field with a value of
the wrong kind is an error, and the dialog stays open with nothing
changed. File › Document Color Mode and Edit › Assign Profile… stay
where they are.

Catalogs: "Working RGB (don't tag)" and "Assign Profile" rows in every
complete catalog, and the "`{key}` must be a profile name or null"
message in every complete-message catalog. Docs: docs/mcp.md,
docs/control-protocol.md, docs/target-app-parity.md.
2026-11-11 19:08:06 -08:00
dotCooCoo 935ebccc25 EPS: Save As options are menus with readable names, and Export As's Range shows an example
Save As to an EPS file showed Preview Format, Overprints and Flattener
Preset as text fields holding their ids (tiffColor, preserve, medium),
the PostScript level as a number field, and labeled every EPS option
except Use Artboards from its name ("Cmyk Post Script", "Thumbnails").

The dialog now shows the options Export's EPS Options shows. Preview,
Overprints, Flattener preset (the built-in presets, then saved ones) and
PostScript are menus of readable names. Transparent and Opaque apply to
the color TIFF preview only. Embed Fonts shows checked and disabled. The
PostScript level comes last. A pick writes the same values as before
(previewFormat "tiffColor", a built-in preset's id, a saved preset's
name, the level as a number). A value that the save would reject shows
as it is.

Every option the dialog shows has a written label. "Preview:" has a row
in every catalog, and the de, it, ja, ko, uk, vi and zh-hant catalogs
gain the menu names, which Export's EPS Options also showed in English.

Export As's Range field shows the "1-3, 5" example when emptied, as
Save As's does.
2026-11-11 19:04:27 -08:00
dotCooCoo 7e071feb4d Merge main into feat/pixel-align-new-objects 2026-11-11 18:57:23 -08:00
dotCooCoo 269a75c45c Merge main into feat/eps-save-use-artboards 2026-11-11 18:49:02 -08:00
dotCooCoo c02f2a5d75 Merge main into fix/links-read-roots 2026-11-11 18:46:20 -08:00
BFlat eb35bd6b3b Merge pull request #6754 from dotCooCoo/feat/3d-shadows
3D and Materials: shadows behind or below the object, with Distance and Bounds
2026-11-12 09:45:11 +07:00
dotCooCoo 09c35cce38 Merge main into feat/char-style-options-tcy-offsets 2026-11-11 18:45:03 -08:00
BFlat aeffe1d004 Merge pull request #6731 from dotCooCoo/feat/actions-insert-menu-item
Actions: Insert Menu Item adds a menu command to an action
2026-11-12 09:40:12 +07:00
BFlat 6c68e13732 Merge pull request #6655 from dotCooCoo/fix/plugin-approval-ok-delay
Plug-ins: the approval dialog takes OK only once its question was shown for half a second
2026-11-12 09:23:52 +07:00
BFlat ac8c60cad4 Merge pull request #6675 from dotCooCoo/fix/plugin-filter-progress-cancel
Plug-ins: a light filter that reports progress runs in the background with Cancel
2026-11-12 09:14:14 +07:00