Commit Graph
3580 Commits
Author SHA1 Message Date
dotCooCoo bd78bb0b11 Docs: paraphrase the HEIF help-page reference 2026-11-08 23:51:41 +07:00
dotCooCoo d5e1c00470 File formats: HEIC and HEIF images open and place
File › Open and File › Place read HEIC and HEIF still images (.heic,
.heif) through heic-rs 0.1.4, the pure-Rust decoder photocraft-heif
uses, and store the pixels as PNG. Single pictures and grids of tiles,
8 to 10 bits, with or without an alpha image, are read with the
container's rotation, mirror and crop applied. A grid without a color
box of its own takes its tiles'. When neither the image nor its tiles
have an nclx box, the HEVC stream's video signal type gives the
samples' matrix and range. An RGB ICC profile, or Display P3 with the
sRGB curve named by an nclx box or, without a color box, by the
stream, is converted to sRGB. The EXIF resolution tags size the image;
without them it is 72 ppi. When the container's rotations turn the
image an odd number of quarter turns, the resolution's axes swap with
the pixels'.

Image sequences, images that aren't HEVC-coded, grids of cropped tiles
and images past the pixel allowance are refused with a message before
the pixels are decoded. The allowance counts each coded picture at the
size its sequence parameter sets give it.

The decoder is in the engine's `heif` feature, which is on by default
and listed by the desktop, CLI and web apps. A build without it still
recognizes the files and refuses them with a message.
2026-11-08 23:51:41 +07:00
dotCooCoo 4ca33bc7a3 Toolbars: document that a null on toggles Keep Tools Beside the Canvas
window.toolsBesideCanvas reads on with opt_bool, which treats null like an omitted value. docs/mcp.md and the params text now say that an omitted or null on toggles the setting and that any other non-boolean value is an error.
2026-11-08 23:51:40 +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 a8f21ac0f6 UI: keep docked Tools beside the canvas with left panels 2026-11-08 23:51:39 +07:00
dotCooCoo 3405620151 Docs: update marquee feature status and revision history 2026-11-08 23:51:23 +07:00
dotCooCoo 6d87514055 Selection: show marquee rules and offer enclosed and directional modes 2026-11-08 23:51:12 +07:00
dotCooCoo 368f1c1f83 Document Info: Pattern Objects lists the objects painted with patterns
Squashed from #5220 onto main.
2026-11-08 23:50:38 +07:00
dotCooCoo 2049082ce7 Drawing tools: Escape on an arc, spiral or grid drag puts back the options it changed
Squashed from #5202 onto main.
2026-11-08 23:50:37 +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 023ee90657 Perspective grid: Snap to Grid moves objects at every depth by one plane offset
With Snap to Grid on, a move of objects on one perspective plane at
different depths applied the snap correction only to the objects at the
first object's depth, and every other object moved by the pointer's
offset read at its own depth. Those objects left the grid and lost their
spacing.

Every object on the first object's plane now moves by that object's
plane offset plus the correction, so the edge of the joint bounds nearer
a gridline lands on it and the objects keep their spacing. A selection
at one depth snaps as before, and objects on other planes keep their own
offset.
2026-11-08 23:50:37 +07:00
dotCooCoo eaa42374a3 Shortcuts: F2, F3 and F4 also cut, copy and paste on Windows and Linux
Squashed from #5041 onto main.
2026-11-08 23:50:36 +07:00
dotCooCoo 246b8ed8cd Type: typed +, # and > start lists with a hollow circle, square and dash
Typed list detection gave every bulleted trigger the filled dot. Now
`*` and a space start a list with the filled dot (•), `+` with the
hollow circle (◦), `#` with the filled square (▪) and `>` with the dash
(–), each one of the existing Bullets presets. `1.`, `1)`, `A.` and `A)`
start the same numbered lists as before.

Only the list a typed trigger starts changes. Lists already in a
document keep their bullets, pasted triggers start no list, and Undo
and Redo of a typed list work as before.

Docs: docs/mcp.md (typed list paragraph), docs/target-app-parity.md.
2026-11-08 23:50:35 +07:00
dotCooCoo c1164f271f Type: Start Lists From Typed Markers turns typed list detection off
Preferences > Type gets Start Lists From Typed Markers (`typedLists`, on
by default). With it off, a list marker and a space typed with the Type
tool at the start of a paragraph (`1. `, `1) `, `A. `, `A) `, `* `,
`# `, `> `, `+ `) stay as text and start no list. `text.startList`,
`text.setFormat {list}` and the Bullets and Numbered List buttons work
as before.

The preference reaches the Type tool through `ToolContext::typed_lists`.
The label has a row in every catalog.
2026-11-08 23:50:33 +07:00
dotCooCoo 3f4d1a2512 Render: the decoded-image cache can grow to a quarter of installed memory on every desktop OS
Squashed from #5034 onto main.
2026-11-08 23:50:32 +07:00
dotCooCoo be391e541a Type: Type Orientation is a setting of the whole thread
Squashed from #5027 onto main.
2026-11-08 23:50:32 +07:00
dotCooCoo 6cd4171fbd Paragraph: Reset Panel also resets the Mojikumi Set and tab stops
Squashed from #5025 onto main.
2026-11-08 23:50:31 +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 0d1a8b6ffa Actions: Batch Save and Close over data sets counts only saves that make the file the document's own
A recorded save in the template format writes a copy and leaves the
document's file as it was, so it no longer clears the warning or the
refusals. A recorded Save or Save As with its own path gives a never-saved,
converted or restored document its file before Save and Close, so the
batch runs and warns that every data set saves over that one file.
2026-11-08 23:50:30 +07:00
dotCooCoo 427029def6 Actions: Batch Save and Close over data sets follows a redirected Save step
With a destination folder and Override Save on, a recorded Save or Save As
step writes each data set to its own file in that folder and makes that
file the document's own, so Save and Close then saves each data set to its
own file. The batch no longer warns that every data set saves over one
file in that case, and no longer refuses a document that was never saved,
converted or restored, since the recorded step gives it a file first.
2026-11-08 23:50:30 +07:00
dotCooCoo 64cfa8b553 Actions: Batch over data sets warns about PDF, EPS, DXF and web exports and refuses Save and Close on converted documents
A recorded PDF, EPS, DXF, Save for Web or Save for Office Documents step
that gives a `path` writes the same file for every data set, because the
batch does not point these steps into the destination folder. The one-file
rule now counts them, so the dialog and `action.batch` warn.

Save and Close over the data sets of a document converted from an older
version or restored by Data Recovery is refused with "save the document
with Save As before Save and Close" before a data set is selected. Saving
such a document does not write its file, so the batch reported success
without saving anything. The message has a row in each of the 26 catalogs.
2026-11-08 23:50:29 +07:00
dotCooCoo 2ad0268388 Actions: Batch over data sets keeps Save and Close and warns when each data set saves over one file
Batch… with a Data Sets source offers None, Save and Close and Folder again.
Save and Close saves the open document over its own file after each data
set. When every data set saves over the same file, the dialog shows a
warning and `action.batch` returns `warning`: with Save and Close, or with
a recorded step that writes a file and that the batch does not point into
the destination folder. A Save step without a path counts when it writes
the document's own file; Save As, Save a Copy, Save as Template and Export
steps count when they give a path; Export for Screens counts when its
folder, given or from its preset, names a folder. Save and Close over the
data sets of a document that was never saved is refused with "the
document has never been saved" before a data set is selected.
2026-11-08 23:50:28 +07:00
dotCooCoo 7fd287238f Actions: Batch refuses Save and Close over data sets instead of saving each one over the open document
Data sets share one open document, so Save and Close saved every data set
over the same file and only the last one survived. action.batch now
returns an error for source datasets with destination saveAndClose before
it selects a data set or runs a step, and the Batch dialog offers None and
Folder for a Data Sets source, moving a Save and Close choice to Folder.
2026-11-08 23:50:27 +07:00
dotCooCoo f118cf6aa6 Image Trace: Expand can group the traced paths by color
Squashed from #4058 onto main.
2026-11-08 23:50:26 +07:00
dotCooCoo 7c813e7171 Document: document.compare measures how far an artboard's render is from an image
Squashed from #3995 onto main.
2026-11-08 23:50:25 +07:00
dotCooCoo 8888128822 Image Trace: Flat Logo can trace only the named colors, without a white of its own
Squashed from #3946 onto main.
2026-11-08 23:50:25 +07:00
dotCooCoo 4b4a97ce1e Variables: a second text variable on one type object is refused
Squashed from #2642 onto main.
2026-11-08 23:50:24 +07:00
dotCooCoo 394bbb37c0 Effects: placed gradients move and scale with the Warp effects
A gradient placed with the Gradient tool stayed where it was when the
object's Warp effect changed the outline, so the warped shape no longer
matched its gradient.

Under each Warp style the placed gradients of a path now move and scale
from the path's bounds before the warp to its bounds after it, as they
do under Free Distort. This applies to an object's own Warp and to a
fill's or stroke's own (a stroke uses its stroke-inflated bounds), on
the canvas and in Object > Expand of the fill. In a group with a Warp
effect, each path's and compound path's gradient follows its own
bounds, and the own fills of the group and of the groups inside it
follow those groups' bounds. A warp with no bend and no distortion
leaves gradients exactly where they are, and gradients fitted to the
object are unchanged.

This changes how existing documents draw: a placed gradient on art with
a Warp effect now follows the warped outline instead of staying in
place.

How gradients follow the warp is VectorCraft's own rule. What the Warp
effects do to the object is described in
https://helpx.adobe.com/illustrator/using/reshaping-objects-effects.html
2026-11-08 08:43:27 -08:00
dotCooCoo f51aa41328 Merge main into fix/plugin-grant-module-hash 2026-11-08 08:40:10 -08:00
dotCooCoo 91d9639e6a Plug-ins: a permission grant covers only the module that was approved
A grant records the module's SHA-256, but only its permissions were
compared, so a module with other bytes under a granted id inherited the
grant when it listed no new permission.

A grant now covers a module only when the id, the SHA-256 and every
listed permission match. plugin.inspect reports needsApproval for a
changed module, plugin.install refuses it without a new grant and leaves
the installed module and its grant as they are, Install Plug-in and
File > Open ask again, and the plug-in store and plug-in folders skip it.
The same bytes install again without asking, and a module with no
permissions list or an empty one needs no grant. A grant whose hash is
not 64 lower-case hexadecimal digits covers nothing.

plugin.install still trusts the client that sends grant; the docs say so.
2026-11-08 08:40:00 -08:00
dotCooCoo 5522059417 Save: the save commands and Export for Screens refuse an unknown option key
document.save, file.saveAs, file.saveCopy and file.saveAsTemplate wrote
the file when given a key that no save format reads, beside the path or
in options, or an unknown key inside a PDF option object such as
marks.useDocumentBleed. document.exportForScreens did the same for an
unknown top-level key, a key in a format row and a key in the settings
of a format.

These commands now refuse such a key and name its path
(options.noSuchOption, formats[1].marks.useDocumentBleed). The svg
object is checked in every save, export and format row, also when the
file written is not SVG. A save still leaves out a key that only another
save format reads, and warns as before. A format row and a format's
settings still take includeArtboardFill and richBlack, which the
encoders read. document.exportPresets.save checks its settings, with the
rows and settings in it, the same way.

In the app, file.save and file.exportForScreens sent as commands are
checked as document.save and document.exportForScreens, and app.save is
checked before anything is written; MCP's app.save, file.save and
file.exportForScreens are checked the same way. The SVG Options dialog
no longer passes its internal fields on to the save.
2026-11-08 08:31:24 -08:00
dotCooCoo f3d4233394 Merge main into feat/plugin-importers 2026-11-08 08:15:31 -08:00
dotCooCoo 975c67681c Merge main into fix/spiral-decay-per-wind 2026-11-08 08:13:27 -08:00
M Balazs PC 8f001495ea Merge branch 'fix/ai-type-leading-forced-breaks' into fix/ai-right-aligned-tabs
# Conflicts:
#	docs/file-format-parity.md
#	docs/roadmap.md
#	docs/target-app-parity.md
2026-11-08 17:12:11 +01:00
M Balazs PC 2d47b11624 Merge remote-tracking branch 'origin/main' into fix/ai-type-leading-forced-breaks
# Conflicts:
#	docs/file-format-parity.md
#	docs/roadmap.md
#	docs/target-app-parity.md
2026-11-08 17:11:12 +01:00
dotCooCoo 2772a44efd Plug-ins: Open With runs an importer off the UI thread, and Cancel stops it
File › Open With reads a picked file on the thread File › Open uses, with the importer and its parameters, so a slow importer does not freeze the window. A call that names path still gets document.open's result. Cancel in the progress window now raises a cancel token on that thread, which stops a running importer between two slices of its budget.
2026-11-08 08:09:23 -08:00
HassanKhan d45a538476 Merge remote-tracking branch 'upstream/main' into feat-4936-spell-check
# Conflicts:
#	docs/roadmap.md
#	docs/target-app-parity.md
2026-11-08 21:07:06 +05:00
HassanKhan 1e52ef587d Part of #4936: refuse malformed ids in text.spelling.check; dictionary-independent test; docs
- text.spelling.check checks a given `ids` as edit.findReplace does
  (checked_ids_param): a non-array, a negative, non-numeric or unknown id is
  an error instead of a check of the whole document. Null still means every
  visible, unlocked type object.
- The byte-offset test puts an em dash, not "café", before the unknown word,
  so it passes whichever dictionaries craft-proof is built with (CI builds
  with craft-i18n's, where "café" is unknown).
- Docs: the spell check engine in target-app-parity.md (Type advanced rows
  and evidence), gaps.md (G4), roadmap.md (M7) and the Language per
  character rows of type-parity.md, with status lines and revision history.
2026-11-08 21:01:59 +05:00
FredApps 65adb7b211 Merge pull request #2480 from vangel76/fix/2414-svg-classes
SVG: keep CSS classes of imported elements on export (#2414)
2026-11-08 17:01:22 +01:00
ruchirguitar 04e71eceb8 #5925: merge CI base and target the Layers Filter button by name 2026-11-08 21:26:30 +05:30
dotCooCoo a5ea32b386 Effects: fitted gradients turn with the Transform effect
A gradient fitted to the object refit to the outline after the object's
Transform effect rotated, reflected or scaled it unevenly, so the
gradient kept running left to right while the shape turned under it.
Object › Transform already turns such a gradient.

A Transform effect that a refit would not reproduce now fixes the
gradient to its fit on the geometry the effect takes, and then maps it
with that effect and the effects after it, as a placed gradient. Under
moves and even scales it draws as a refit does, and an effect that
scales the object to nothing across leaves it fitted. This applies to
an object's own effects, a fill's or stroke's own effects, and a
group's: in a group, the gradients fitted to its paths, to its own
fill, to the groups inside it and to its images' and symbol instances'
own fills each fix to the fit on their own object. Object › Expand of
the fill draws the same.

This changes how existing documents draw: art with a fitted gradient
and a Transform effect that rotates, reflects or scales it unevenly
now shows the gradient turned with the art. How gradients follow the
effect is VectorCraft's own rule.
2026-11-08 07:50:26 -08:00
dotCooCoo edd6acd9c0 Plug-ins: File › Open lists only the importer extensions it opens with an importer
An importer may declare an extension that File › Open handles another
way: a plug-in, shortcut set, script, preset, library or swatch library
such as .ase, or one a built-in format reads. "All readable files" and
the importer's own filter no longer list those extensions, and an
importer with none left gets no filter. Open With still opens them.
2026-11-08 07:31:40 -08:00
dotCooCoo 9f2db12ec2 Plug-ins: a painted live effect's paint keys are checked at every level
A key that a paint does not have, such as `opacity` on a solid fill, was
dropped when the paint was read, and the fill was drawn opaque. The
result is now refused and `lastError` names the field, for keys on the
paint and on its colors, gradient, stops, placement and freeform points.
2026-11-08 07:24:55 -08:00
Ahmed Gomaa f12cf9a545 G13: merge main and strengthen snapping regression checks 2026-11-08 16:24:25 +02:00
ruchirguitar 3984874728 M2.1: avoid discarded path copies during deletion (#3380) 2026-11-08 19:35:48 +05:30
M Balazs PC a24ab06c6d Merge branch 'fix/ai-type-leading-forced-breaks' into fix/ai-right-aligned-tabs
# Conflicts:
#	crates/engine/tests/import_fuzz.rs
#	crates/eps/src/import/ate.rs
2026-11-08 14:58:13 +01:00
M Balazs PC f5c3f47612 Merge remote-tracking branch 'origin/main' into fix/ai-type-leading-forced-breaks
# Conflicts:
#	crates/eps/src/import/ate.rs
#	crates/text/src/layout.rs
2026-11-08 14:57:14 +01:00
dotCooCoo d8afed1562 Plug-ins: painted pieces keep their swatches in Pathfinder and baked art
Pathfinder effects, compound shapes, Expand Appearance and pattern
expansion now pass the document to the effects they evaluate, so a
painted piece that names a swatch or pattern takes part as drawn instead
of being refused. A path with a painted effect takes part in Pathfinder
and compound shapes as its pieces, each with its own paint, inside the
path's opacity and blend mode.

The renderer's kept effect art and live evaluations now count the
document's swatch and pattern names for objects with a plug-in effect,
so deleting or restoring a swatch a piece names redraws the object.
2026-11-08 05:52:39 -08:00
dotCooCoo 01c89d4bc5 JavaScript: a small heap limit no longer leaves a realm without built-ins
Installing the built-ins is not bounded by the heap limit: Math and JSON
no longer reserve heap while they install, so a realm made with a tiny
heap_bytes gets every built-in and runs once the limit is raised. If
installing fails, the realm keeps the reason and every run ends with an
internal error instead of running against missing built-ins.

The json2.js test skips only when the built-in check returns false, and
fails on any other result. The parser's progress line says the app does
not run scripts yet.
2026-11-08 05:35:27 -08:00
dotCooCoo d65207dc62 Plug-ins: only File › Open lists importers' files, and imported art at the canvas edge keeps an editable artboard
New from Template, Load Character/Paragraph/All Styles, Recolor's Other
Library… and the library panels' Other Library… read files with the
built-in readers, so their open dialogs now use builtin_open_filters(),
which leaves out the extensions only importer plug-ins read. File › Open
keeps open_filters() with the importers' files.

The artboard of a document an importer opens is now kept within
±4,000,000 pt. Art at the edge (a zero-width path at x = 4,000,000, or a
stroke past the edge) gave an artboard beyond it, and every later edit
of the document was rejected.
2026-11-08 05:35:23 -08:00