Commit Graph
285 Commits
Author SHA1 Message Date
dotCooCoo d5fc96327e Merge main into fix/shape-builder-merge-off-ui-thread
# Conflicts:
#	crates/engine/src/lib.rs
#	crates/engine/src/session/documents.rs
2026-11-08 11:33:51 -08:00
dotCooCoo fd3482c272 Merge main into fix/shape-builder-merge-off-ui-thread 2026-11-08 11:28:00 -08:00
Sven Lafebre 057978f61a Fix #6135: the importPdf row states when the dialog opens 2026-11-09 02:03:10 +07:00
Sven Lafebre 1e7e1d33e9 Fix #6135: opening a .ai with editing data skips the Import PDF dialog
The editing data of a .ai or .ait holds every artboard, so a multi-page
file has no pages to pick. Opening one now goes straight to it, as a
file carrying its VectorCraft document already does. The dialog stays
for PDFs, a .ai that is only a PDF, a password, and Place.
2026-11-09 02:03:10 +07:00
dotCooCoo fb413b39f3 Title bar: a Linux and BSD preference uses the app bar where the desktop draws the frame
Squashed from #6101 onto main.
2026-11-09 00:27:21 +07:00
dotCooCoo cd8e98c6cd DXF: a CNC / CAM preset sets the export options for cutting software
Squashed from #5500 onto main.
2026-11-09 00:25:53 +07:00
dotCooCoo 315ff52ffd Workspace: make keeping Tools beside the canvas an option, off by default
Docked Tools stays at the window's left edge again, outside any panels
docked on the left. Window › Toolbars › Keep Tools Beside the Canvas
(`window.toolsBesideCanvas {on?}`) docks it between those panels and the
canvas instead.

- The setting is its own field in the UI state and in workspaces, and a
  missing field reads as off, so saved state and workspaces keep Tools at
  the window's edge. Built-in workspaces have it off.
- Off, app.rs draws docked Tools before the docking layout, the canvas
  reserves no width for it, and only the full-height window-edge strip
  docks a floating Tools panel. On, the canvas panel draws it, the canvas
  keeps room for it, and both the window edge and the canvas edge dock it
  beside the canvas.
- Turning the setting off forgets the canvas-edge strip, so a strip laid
  out while it was on does not dock Tools. A floating Tools panel stays
  floating when the setting changes.
- `window.panel.dock {panel: "tools"}` docks Tools where the setting says.
- The menu label has a row in every catalog.

Docs: docs/mcp.md, docs/control-protocol.md, the ROADMAP progress log and
docs/target-app-parity.md. The headline-numbers row and the paragraphs
under the status lines are gone, and scores are unchanged.
2026-11-08 23:51:40 +07:00
dotCooCoo 8c7e7041fd Title bar: the app bar shows no brand mark under the desktop's own frame
On Linux, when the desktop draws the window's frame (KDE, Sway,
Hyprland, COSMIC and X11 sessions), the app bar painted the brand mark
under the desktop's title bar unless System Title Bar was on. The mark
followed the live preference instead of the frame the window has.

The desktop app now records the frame it opened the window with
(VectorcraftApp::desktop_frame), and system_title_bar reads it. A
change to System Title Bar during a session no longer shows or hides
the mark; it changes with the frame at the next start. Embedders
without a window of their own keep the mark.
2026-11-08 23:50:37 +07:00
dotCooCoo a33d6a6ec8 Canvas: a General option makes Cmd/Ctrl-wheel scroll the canvas sideways
Squashed from #5023 onto main.
2026-11-08 23:50:31 +07:00
dotCooCoo b7203714be Links: Relink can replace all instances, the folder's missing links or each link separately
The Links panel's Relink... button and menu item open a Relink dialog
(ui.relinkDialog) with a Replace menu. Selected Instances relinks the
selected images and placed documents, as Relink did before. All
Instances also relinks every other object in the layers linked to the
same file. Missing Links from This Folder relinks the selection to the
chosen file, then every other missing link to the file of its name in
that file's folder, and the status bar names the files not there. Each
Link Separately asks for a file for each selected link in turn, one OK
each, and relinks them all at the last one: the dialog has one row per
linked file, and each selected embedded image gets a row of its own.
Every choice is one undo step.

links.relink takes scope: selected (default), all, missingInFolder
(with path) or each (with paths: [{ids, path}] in place of ids, path
and folder). A scope or paths that doesn't fit is an error and relinks
nothing. With copy, every file is read and checked before any is
copied, copies made before a failed copy are removed, and
missingInFolder looks for missing images only.

Docs: params text, docs/mcp.md, docs/control-protocol.md,
docs/target-app-parity.md. Catalog rows for the new labels and messages
in every catalog.
2026-11-08 13:21:01 +07:00
Helen Kwok f9bf685cbd vectorcraft-web: window.vectorcraft takes its request functions from craft-web-api
request, execute, commands and screenshot move onto the shared crate (storytold/craft-libs#413): a timeout on every call, the screenshot's PNG also in data, and docInspect and uiInspect beside them. A call the page gave up on gives up its request if the app has not started it, so the app skips it. openFile, captureDownloads, files, readFile and inspect stay VectorCraft's own, on the same object.
2026-11-07 09:18:00 +07:00
dotCooCoo c7c8e5428d Artboards: the Artboard tool's canvas menu cuts, copies, pastes, renames, rearranges and exports artboards
With the Artboard tool, the canvas context menu lists the entries of the
public Use the artboard context menu page in its order, in place of the
entries for objects and the view. Lock Artboards and Unlock Artboards are
two submenus. An entry that cannot run is left out, and Undo and Redo stay
dimmed. A right-click on an artboard that is not selected selects it alone
first, and the menu measures the art for Delete Empty Artboards and Fit to
Artwork Bounds once, at the right-click.

Cut, Copy, Duplicate Artboards, Rename, Delete Artboards, Lock Selected,
Unlock Selected, Fit to Artwork Bounds, Switch Orientation and Export act on
the artboards the tool has selected, else the active one. docs/mcp.md lists
what the other entries act on.

- artboard.rename renames in one undo step and numbers several names. The
  menu's Rename opens a dialog that runs it, and the Artboards panel's name
  field runs it too.
- artboard.switchOrientation swaps width and height and keeps the top-left
  corner, skipping square and locked artboards.
- artboard.selectAll chooses the tool and selects every artboard.
- edit.paste takes artboardsAt, and the menu's Paste centers copied
  artboards on the right-click's point.
- The menu's Cut and Copy run artboard.cut and artboard.copy. In the desktop
  app those commands publish to the system clipboard, and the menu shows the
  Cut and Copy shortcuts for them.
- artboard.fitToArt and the panel's name field record no undo step when
  nothing changes.

artboard.duplicate, copy, cut, rename and switchOrientation take their
artboards from the tool's selection when a call names none. Each now records
them in the journal as selectedArtboards, which a replay reads and a recorded
action leaves out. The copy commands also record art. switchOrientation
records scaleArt, and it takes patterns and lockedAndHidden and records what
its artboard.setProps step resolved for them.

While the Artboard tool is in use, a command chosen from any menu or the
command palette moves the tool's selection as the Artboards panel does:
artboard.new makes the new artboard active, artboard.duplicate selects the
copies, and artboard.delete and artboard.deleteEmpty make a remaining
artboard active.
2026-11-07 08:37:44 +07:00
Kindmark 1b8d96433e Compound shapes default
Squashed from #5757 onto main.
2026-11-05 13:58:16 +07:00
NetterSilverandClaude Opus 5.5 1db874610f Keep Pencil and Paintbrush Fidelity in screen pixels at any zoom
Fixes #5729

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-05 11:52:34 +07:00
FractalEncrypt 77a86288e7 Transform Each: Relative and Absolute scaling, the scale link, and the documented panel order
Squashed from #5695 onto main.
2026-11-05 04:37:46 +07:00
dotCooCoo 12508e6c60 Dialogs: a color with an alpha part is refused instead of losing its alpha
`Color::from_hex` reads `#rrggbbaa` and keeps only its first six digits, so
a `color` set to `#ff000080` through `ui.dialog.set` was applied as
`#ff0000` without an error by Tile Edge Color, Live Paint Selection Tool
Options, Live Paint Bucket Options and Gap Options.

- A new `checked` next to `resolve` in `dialogs/tile_edge_color.rs` gives
  the existing "is not a colour" error for an 8-digit hex color, and
  otherwise reads the color as `resolve` does. `resolve` is unchanged, so
  the swatches the dialogs draw with it show such a color by its RGB as
  before.
- Each of the four dialogs' OK checks the color with `checked` first, and
  leaves the dialog open with nothing changed. Tile Edge Color and Gap
  Options already refused `#rgba`, which `from_hex` does not read. Live
  Paint Selection and Live Paint Bucket used to ignore a color they could
  not read, such as `#f008`, and apply their other fields; their OK now
  refuses it.
- With Preview on, Gap Options sends no color for a `#rrggbbaa` value, so
  the groups keep their own color, and the previewed gaps draw in black.

Docs: the params text, docs/mcp.md, docs/control-protocol.md and
docs/target-app-parity.md.
2026-11-04 18:29:13 +07:00
dotCooCoo 146d30502a Expand: selected symbol instances become their art, as Break Link places it
Object > Expand with Object on now turns each symbol instance in the
selection, including one in a selected group or in a placed document's
art, into its art, as Break Link to Symbol places it. It goes one level
deep: the instances in that art stay instances. The art keeps the
instance's id and place in the stacking order, and Expand stays one
undo step.

- Instances with effects stay instances, and Expand Appearance bakes
  them as before. Instances with an effect on a fill or stroke,
  instances in perspective, and those in blends, repeats and Intertwine
  groups stay instances.
- The art keeps the instance's opacity mask, as Break Link gives it.
- A hidden or locked instance's art stays hidden or locked.
- A placed document in an instance's art is expanded too.
- When the instances' art would make more than 1,000,000 objects, they
  stay instances, the limit Break Link uses.
- The Fill and Stroke options (object.expand.info, and the Expand
  dialog) count the fills, strokes and gradients in the art of those
  instances, with a dynamic instance's own changes applied. The info
  reports under symbolArt which of them only that art holds, and the
  dialog enables those options only while Object is on.
2026-11-04 15:14:02 +07:00
dotCooCoo de78142dd8 Toolbars: Manage Toolbars renames, copies and deletes the toolbars made with New Toolbar
Window › Toolbars › Manage Toolbars… and Manage Toolbars… in the All Tools
drawer's menu open a dialog that lists the toolbars made with New Toolbar.
A name typed for the selected toolbar renames it, + copies the selected
toolbar or, with none selected, makes a new one, and the trash can deletes
it (https://helpx.adobe.com/illustrator/using/tools.html, Manage toolbars).

VectorCraft's own details:
- A rename applies at Enter, when the text box loses focus, or at OK. The
  name follows New Toolbar's rules: not empty, at most 200 characters, and
  not another toolbar's in any case.
- A copy is called "<name> Copy" (then "<name> Copy 2"), shows a little
  below the toolbar it copies and below earlier copies; a new toolbar is
  called "Toolbar N".
- Each change applies at once; deleting also removes the groups torn off
  the toolbar.
- When the typed name is refused, a click on +, the trash can or another
  toolbar is not applied, so the name can be corrected. When the selected
  toolbar is deleted elsewhere while the dialog is open, none is selected.
- Renaming or deleting a toolbar closes the All Tools drawer and a group's
  flyout open on it; a change of case only leaves them open, and the Tools
  panel's flyouts and other toolbars' stay open.
- Each change shows under Window › Toolbars and is kept with the workspace.

New commands: window.toolbar.manage, window.toolbar.rename,
window.toolbar.duplicate and window.toolbar.delete, with catalog rows for
their labels in every language.

Docs: control-protocol.md, gaps.md, target-app-parity.md, ui-parity.md.

Part of #1759
2026-11-04 10:26:01 +07:00
ruchirguitarandClaude Opus 5.5 46f1ddf170 Fix #5236: find PhotoCraft where its Windows installer puts it
Per CodeRabbit on #5327: on Windows Edit Original looked for photocraft.exe
only on the PATH, but PhotoCraft's MSI installs it to ArtCraft\PhotoCraft
under %LOCALAPPDATA%\Programs (per user, the default) or Program Files (for
everyone), neither on the PATH. Look first at the path the installer
registers under App Paths (HKCU, then HKLM; `reg query`, as i18n reads the
locale, which also covers a folder chosen in setup), then those two default
folders, then the PATH. Each candidate must still be an .exe.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-03 19:57:04 +07:00
ruchirguitarandClaude Opus 5.5 d7aa1c561f Fix #5236: Edit Original is one checkbox, Use System Defaults for Edit Original
Per review on #5327: Preferences › File Handling › Edit Original With (an app
path and Choose…) becomes the checkbox Use System Defaults for Edit Original,
on by default. Off, Edit Original opens a raster image in the app that made
it, PhotoCraft, looked for only where it installs; any other file, or no
PhotoCraft, goes to the system's default app. The preference is a boolean, so
prefs.set over control or MCP can no longer name an executable. The label has
a row in all 26 catalogs.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-03 19:57:04 +07:00
ruchirguitarandClaude Opus 5.5 d11764c117 Fix #5236: Edit Original opens linked files in a chosen app
Preferences › File Handling › Edit Original With picks the app Links
panel › Edit Original opens a linked file in: System Default (as before),
PhotoCraft (found in /Applications or ~/Applications on macOS, on the
PATH elsewhere) or Other Application, with a path field and Choose….

The desktop host's new `open_file_with` service starts only an
application (an .app bundle on macOS, an .exe on Windows, an executable
file elsewhere), with the path as its only argument and never through a
shell. Edit Original still refuses control requests.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-03 19:57:04 +07:00
dotCooCoo 750c34c247 Recolor Artwork: the Edit tab shows the colors on a smooth wheel, a segmented wheel or as color bars
Buttons beside the Edit tab's wheel switch between the smooth color wheel,
a segmented wheel of solid patches (24 hues by 5 saturations, its markers
moving as freely as on the smooth wheel) and color bars: one solid bar per
recolored color in row order, where a click selects a bar's row for the
color sliders and a drag moves the row without changing a color. The
dialog opens on the smooth wheel and keeps the choice while it is open;
the dialog field is `display` (`smooth`, `segmented`, `bars`).
2026-11-02 04:35:56 -08:00
dotCooCoo 2fafe25c27 Asset Export: Import Preset and Export Preset read and write preset files
Squashed from #5032 onto main.
2026-11-02 14:33:29 +07:00
dotCooCoo b1c98821d6 Clipboard: a bitmap pasted from another app is decoded off the UI thread
Squashed from #4277 onto main.
2026-11-02 14:33:02 +07:00
dotCooCoo 6d369d013c Toolbars: New Toolbar makes a named toolbar filled from the All Tools drawer
Squashed from #5038 onto main.
2026-11-02 14:33:01 +07:00
dotCooCoo 05ac9ce040 Merge main into fix/shape-builder-merge-off-ui-thread 2026-11-01 22:20:23 -08:00
Brandon Thomas cfb30d8139 Merge pull request #5214 from dotCooCoo/feat/recolor-global-adjust
Recolor: the Global Adjust sliders change every color at once
2026-11-02 00:34:59 -05:00
Brandon Thomas 6daefef735 Merge pull request #5212 from dotCooCoo/feat/document-info-save-category
Document Info: Save writes the category the panel shows
2026-11-02 00:34:54 -05:00
dotCooCoo fa8d3b8de4 Fix #3797: documents open in Preview, and Outline is a setting of each document
View > Outline was one app-wide flag saved in the interface preferences,
so after Cmd+Y every later launch drew every opened or new document as
outlines, with no fills. The flag is now part of each document's view:
a document opens in Preview, each tab shows its own Outline or Preview,
and the setting is not saved at launch. An older preferences file that
holds the flag still loads, and its value is ignored.

The Outline command and ui.set's outline act on the active document and
are an error without one.
2026-11-02 12:03:30 +07:00
dotCooCoo 7389cc22d6 Document Info: Save writes the category the panel shows
Save… in the Document Info panel menu now writes only the category the
panel shows, with Selection Only applied. With All Categories shown it
writes every category, as before. docInfo.save takes an optional
category (a document.info category id) and passes it to document.info.
2026-11-01 18:18:19 -08:00
dotCooCoo 0567eaffbf Recolor: the Global Adjust sliders change every color at once
The Edit tab's color mode menu offers Global Adjust, with Saturation,
Brightness, Temperature and Luminosity sliders from -100% to 100% that
open at 0%, which changes nothing. One slider changes every recolored
color, each one separately, in its own model; the rows keep their new
colors and the art previews the change. The Edit tab also shows the
color sliders of the selected new color in the other modes.

recolor.apply takes globalAdjust {saturation, brightness, temperature,
luminosity}. Excluded rows and colors no row holds stay as they are, a
rewritten color group takes the same change, and with Limit to Library
each row's new color takes it before it snaps to the library.

Docs: docs/mcp.md, docs/control-protocol.md, docs/target-app-parity.md.
2026-11-01 17:20:56 -08:00
dotCooCoo 9b853004d5 Recolor Artwork: a slider edit changes the color mode of its own row only
The color sliders now mark the row they edit with `model: "new"`
instead of a dialog-wide flag, and `recolor.apply` reads a row's own
`model` before the command's. Rows the sliders did not edit keep each
color's model, so with RGB art and a CMYK color group, a slider edit of
one row no longer turns the other rows' art CMYK. Another edit of the
row's new color, Reset and rows reduced again remove the mark, and
`recolor.randomize` moves it with its new color.
2026-11-01 02:06:46 -08:00
dotCooCoo 46cb088eae Recolor Artwork: color sliders edit the selected row's new color in a chosen mode
The Assign tab gets a Color Mode menu (HSB, RGB, CMYK, Lab, and Tint when
the row's new color is a spot color of the Limit to Library library) and
its sliders under the rows. They edit the first selected row's new color
and are disabled with no row selected. Once they have edited a color in a
mode, the preview and OK send recolor.apply with model "new", so the art
takes the color in that mode.

recolor.apply rows take an optional tint (percent, default 100): art linked
to the row's global or spot library swatch takes that share of its tint.
recolor.randomize keeps a row's tint.
2026-10-31 21:42:42 -07:00
Taha-Mahmoodi 811ba8727b Fix #3604: automation file access refuses an NTFS alternate data stream name on Windows
With write root ...\out, a save to ...\out\x.svg:evil was accepted: it stays inside the root, but writes a hidden stream no folder listing shows. A ':' in any name after the drive is now refused with the device names. The check is a plain name test, so it is covered on every platform; the check-then-open race (item 1 of the report) is a documented limitation and is not touched.
2026-10-31 19:43:17 +07:00
dotCooCoo baaffd63e7 Blob Brush: Tool Options set the brush's Angle and Roundness
Blob Brush Tool Options gain Angle (-180 to 180 degrees, 0 by default)
and Roundness (0 to 100 percent, 100 by default), with a preview of the
tip and three dabs; a drag in the preview square sets the Angle. The
elliptical tip keeps its angle on the page along a stroke, a 0 percent
tip is drawn 0.1 percent as wide as it is long, and Size set to
Pressure still varies its size. path.blob takes angle and roundness,
and both values are kept with the tool's options.

While a non-round tip drags, the Blob Brush shows the outline of the
area it covers with its length label, and an Alt drag that smooths
shows the Smooth tool's thin line.
2026-10-31 19:43:15 +07:00
bflatastic 513b02233f Align: Align to Glyph Bounds for point and area type (#4231) 2026-10-30 02:01:58 +07:00
dotCooCoo c3cd065ef3 Character and Paragraph Styles: Alt-click on New asks for the new style's name
Squashed from #4402 onto main.
2026-10-30 00:15:55 +07:00
dotCooCoo 4e59c3f0be Merge main into fix/shape-builder-merge-off-ui-thread 2026-10-29 07:58:05 -07:00
Taha-Mahmoodi b41599f657 Fix #3089: a stroked line with an effect expands to a stroked line, then Expand outlines it
Squashed from #4169 onto main.
2026-10-29 18:54:59 +07:00
dotCooCoo 968642da45 Merge main into fix/shape-builder-merge-off-ui-thread
# Conflicts:
#	crates/ui-egui/src/menus/invoke.rs
2026-10-28 21:37:57 -07:00
dotCooCoo 7f7067bcba Blob Brush: Tool Options set its Fidelity
Squashed from #4414 onto main.
2026-10-29 10:11:42 +07:00
dotCooCoo 512036a81d Export: the ppi, width and height descriptions name the formats that store no resolution
GIF, WebP and Targa files hold no resolution field, so document.formats and
the export docs now say that ppi, and the resolution that width or height
gives, are stored in the file except in those three formats.
2026-10-29 10:10:58 +07:00
dotCooCoo 530cca3322 Export: document.export takes a pixel width or height for raster files
PNG, PNG-8, JPEG, WebP, GIF, TIFF, BMP, Targa and PSD exports take
`width` or `height` in pixels. Each file is scaled so that its own
artboard, `rect` or art bounds is that wide or high, so with
`useArtboards` every file gets its own scale. `width` wins over
`height`, and either wins over `ppi` and `scale`, in the order an
Export for Screens row reads its size. The scale stays within 0.01 to
64 pixels per point and the file stores the resolution that results.
A value that is not a positive number is refused.

The per-file scale comes from `ScreenSize::scale_for`, which Export for
Screens rows already use. Rows keep their own size: their format
settings still drop `width` and `height`. `document.formats` lists the
two options for every raster format.
2026-10-29 10:10:58 +07:00
dotCooCoo 3b01769d46 Export for Screens: a ZIP export deflates its files
With `zip: true`, document.exportForScreens deflated nothing: every file
went into the archive stored. Each file is now deflated, or stored when
deflating does not make it smaller, as file.package's archive does. The
file list, the names and the reply's fields stay the same; `bytes` and
the archive's contents change. Entries keep the fixed 1980-01-01 date, so
the same files still give the same archive.

The deflating writer moves from package.rs into fileio/zip.rs as
`zip::deflate`, beside `zip::store`, and file.package calls it there with
its own date and error text. The test reader `zip::entries` reads
deflated entries too. The `zip` option's text in docs/mcp.md,
docs/control-protocol.md and the command's params says the files are
deflated.
2026-10-29 10:03:27 +07:00
dotCooCoo 93677c26ec Shape Builder: a large selection merges on another thread
A Shape Builder click or drag over a selection of more than 128
segments merged on the UI thread, so the app stopped drawing and
answering until the merge was done. The tool now computes such a
merge on another thread from the map it built for the hover.
Meanwhile the canvas keeps drawing, the touched regions stay
highlighted and the pointer is the busy pointer. When the merge is
done, the tool runs shapeBuilder.merge with the gesture's params as
one undo step, and the command takes the computed shapes when it
would compute the same ones. The web build merges in the command, as
before.

A press while the map is still being built no longer waits for it on
the UI thread: the tool records the gesture and makes it once the map
is there.

Clicks, drags and the Shape Builder's arrow keys made during the
merge, and commands, menu items, the app's own dialogs, saves and tool
or document switches, run after it on the merged art; engine queries
that only read run at once. A change to the selected paths made
outside a command drops the merge. The headless host and ui.pointer
reply once the merge is applied.

The Shape Builder and the Live Paint Bucket keep their map of the
selection over a new revision of the document when the selected paths
and their outlines are unchanged, instead of building it again.
2026-10-27 17:26:38 -07:00
dotCooCoo 45440b5444 Toolbar: double-clicking the Type on a Path tool opens Type on a Path Options
A double-click on the Type on a Path or Vertical Type on a Path tool
reported that the tool has no options. It now opens Type on a Path
Options for the selected type on a path, the same dialog as Type ›
Type on a Path › Type on a Path Options…. With nothing selected, or
with no type on a path selected, nothing opens and `tool.options`
returns the menu command's error, as the Rotate tool's double-click
does without a selection.

Docs: docs/control-protocol.md, the `tool.options` params doc.
2026-10-26 15:44:50 +07:00
Taha-Mahmoodi 0a241a7fdd Brushes: Window › Brush Libraries opens brush libraries whose brushes click or drag into the document's Brushes
Squashed from #4020 onto main.
2026-10-26 15:17:30 +07:00
dotCooCoo ad75ea5d06 Type: Highlight Substituted Fonts moves to Preferences › Type and applies to every document
Highlight Substituted Fonts is now a preference in Preferences › Type,
next to Highlight Alternate Glyphs, on by default and saved with the
other preferences (`prefs.set highlightSubstitutedFonts`). The canvas
reads it through `RenderOptions::highlight_substituted_fonts` for every
open document; a document's own setup no longer decides it. File ›
Document Setup no longer shows the checkbox and keeps Highlight
Substituted Glyphs.

A file saved with Document Setup's Highlight Substituted Fonts off now
shows the pink highlight when it opens, while the preference is on.
The file still opens with the stored value, and saving it again keeps
that value.

`document.setup` no longer reports `highlightSubstitutedFonts`. It
ignores the key and adds a `warnings` entry that names `prefs.set` to
its reply, so an older reply passed back still applies its other keys.

The raster cache of type under a raster effect now also redraws when
Highlight Alternate Glyphs changes.
2026-10-26 09:09:47 +07:00
Taha-Mahmoodi 0dc9d9abb4 Fix #1732: Transform Each opens on the values it was last confirmed with and has a Copy button
Squashed from #4175 onto main.
2026-10-26 09:09:46 +07:00
dotCooCoo 3d8c40f500 Eraser: Angle and Roundness in Eraser Tool Options shape the tip
Squashed from #4180 onto main.
2026-10-26 09:09:46 +07:00