Commit Graph
12393 Commits
Author SHA1 Message Date
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
FredApps ef4740f6f0 Merge pull request #5284 from vangel76/perf/web-wasm-simd128-2786
Fix #2786: the web build uses WebAssembly SIMD, so the canvas renders about 2.5x faster
2026-11-08 16:54:58 +01:00
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 ca3527e780 Plug-ins: kept rasters over painted pieces follow the swatches and patterns they name
A blur or shadow over a painted piece is drawn again when a swatch or
pattern the piece names is deleted, or when the tiles of a named pattern
change. The raster's inputs now include the swatch and pattern names and
the pattern definitions for content with a plug-in effect.
2026-11-08 07:37:07 -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
dotCooCoo 76bb829e3a Graphs: a style that removes a mark's painted row resets the stored opacity
Applying or redefining a graphic style on a series mark whose fill or
stroke had paint, when the style leaves that row without paint, now
stores the row's opacity and blend mode on the graph. Before, the
opacity and blend mode another mark of the series left stayed, so a
Filled Lines band's outline kept a stroke opacity after a style without
a stroke went on a stroked marker. A row with no paint before and after
the edit still keeps what the graph stores.
2026-11-08 06:50:03 -08:00
dotCooCoo 517e0b7ae8 Effects: hiding a 3D effect still checks the values given with it
effect.setParams with visible: false skipped every 3D parameter check,
so a hidden edit could store a Classic depth of 2001, an unknown
surface or bevel, an empty light list or a Revolve edge other than left
or right. The values given are now checked by validate_three_d_params
(the checks of validate_three_d that do not build the art); after a
change of 3D type the values the effect keeps are checked too. The
object still does not need to fit while the effect is hidden.
2026-11-08 06:35:39 -08:00
dotCooCoo f384d27bee 3D (Classic): the solids test checks the classic faces' hue
every_solid_draws_shaded_faces_and_leaves_the_source_editable no longer
skips the color check for Extrude & Bevel (Classic). Its faces must be
the fill's red or the stroke's black, shaded, or lightened toward white
by the Plastic highlight, which keeps r - g to r - b at 6 to 7.
2026-11-08 06:35:38 -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 b6404f2f8b JavaScript: toLocaleString calls toString on the boxed value, and overwriting an element reserves no heap
Object.prototype.toLocaleString passed the primitive this value to
toString; section 15.2.4.3 calls it on ToObject(this), so a strict
toString now sees the object. The array methods' element write reserved
room for a new element even when it only replaced an own property, so a
heap at its limit stopped reverse or sort writes that add nothing.
2026-11-08 05:54:07 -08:00
dotCooCoo 923faeb35a JavaScript: the test262 interpreter runs fail when a harness file is missing or no test runs
run_tests read an unreadable harness, include or test file as an empty
string, so a broken suite checkout passed with every run counted as a
failure. It now stops with the file's path. The language run checks
that test/language exists, and the language and built-ins runs check
that at least one ES5 test ran.
2026-11-08 05:52:46 -08: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
dotCooCoo 56f8e3208a i18n: French rows keep the no-break space before punctuation 2026-11-08 05:13:18 -08:00
dotCooCoo 58f5789e9a Plug-ins: Open With passes an importer its parameters and adds the file to Open Recent
File › Open With asks for the parameters of an importer that declares
any, at their defaults, once the file is picked (dialog `pluginImport`),
and opens the file with the values set. `file.openWith`, `app.open` and
MCP's `open_file` take `params` and pass them to the importer;
`app.open` without them runs the importer on their defaults, with no
dialog. A file opened with Open With is added to Open Recent, as File ›
Open adds the files it opens.
2026-11-08 05:07:08 -08:00
dotCooCoo 96bdb813a6 Plug-ins: read-only inputs count toward the input's memory share
A filter's input is now encoded within the half of the plug-in's memory
cap that the input and the parameters share. Every object counts toward
it in paint order, with its id, bounds, transform and name. Type runs
and image pixels that don't fit what is left come with truncated or
pixelsOmitted, and a type, image or symbol instance whose other fields
alone don't fit fails the run before the plug-in starts with
"memory budget (object N needs S bytes of input, L left)".
2026-11-08 04:42:17 -08:00
dotCooCoo 36eec28617 MCP: open_file takes an importer plug-in to open the file with
open_file passes `importer` (an importer plug-in's format id,
plugin.<id>) on to app.open. Headless, it becomes document.open's
`importer`; in the app, app.open with `importer` runs file.openWith, so
the file opens with that importer as File > Open With does, also when a
built-in format reads its extension.
2026-11-08 04:40:23 -08:00
dotCooCoo ca7c0462fb Merge main into fix/ai-writer-object-limit-2 2026-11-08 04:38:21 -08:00
dotCooCoo 9316c17967 .ai save: the editing copy stops at the reader's object limit
The reader stops a whole file past 4,000,000 objects (MAX_NODES), and
the writer had no limit of its own. The writer now counts the objects
it writes as the reader counts them, across layers, symbol and pattern
definitions, opacity masks and art styles, and leaves out art past the
limit with a warning. Art that does not fit is given back as a whole:
a mask, a pattern or a symbol definition is left out with all its art,
and a symbol's definition is written only with room for its instance.
The limit is the reader's own constant, re-exported as
MAX_EDITING_OBJECTS.
2026-11-08 04:38:15 -08:00
dotCooCoo 95678340b0 .ai import: a symbol's linked color named like a color group is renamed
A global or spot color that a symbol library's art links to and whose
name a color group of the document has now comes in under a free variant
of the name, which the art then names, as for a name another swatch has.
Swatches and color groups share one set of names.
2026-11-08 04:34:49 -08:00
Don Omondi 9d706a9a6d Parity doc: paths with an older Art brush keep their drawn look 2026-11-08 06:41:09 -05:00
Don Omondi d87844bba6 Merge remote-tracking branch 'upstream/main' into fix/eps01-editing-overlay
# Conflicts:
#	docs/gaps.md
2026-11-08 06:36:42 -05:00
ruchirguitar 655a16fa67 #5925: add collapse arrows to floating panels and rail flyouts 2026-11-08 17:02:29 +05:30
Taha-Mahmoodi ff6a4be475 Glyphs: Entire Font applies a glyph no feature reaches to the selected letter as a glyph choice; text tests for ligatures, word probe, candidate cap and aalt order 2026-11-08 15:06:29 +04:30
HassanKhan f71952730f Contributors: Hassan1305's name for the About window 2026-11-08 15:07:37 +05:00
dotCooCoo 7a38e2c990 Merge main into feat/plugin-menu-commands 2026-11-08 02:04:06 -08:00
HassanKhan 7a145576d4 Part of #4936: text.spelling.check lists unknown words, text.spelling.suggest suggests
The Edit > Spelling items have been placeholders with nothing behind them. This adds the
engine half of Check Spelling on craft-proof, the shared spelling engine in craft-libs (at the
revision the other craft-libs crates already pin), so no word list is copied here:

- text.spelling.check {ids?} lists the words the dictionaries don't know in every visible,
  unlocked type object (or ids), each run checked in its Character panel Language (English
  when it has none; nothing in a language without a dictionary), as {id, start, end, word,
  lang}. start/end are byte offsets in the object's text, the ones text.editRange takes, so a
  word is changed with text.editRange as one undo step. At most 10,000 words, with `more`.
- text.spelling.suggest {word, max?, lang?} gives the dictionary's suggestions, asked for one
  word at a time as craft-proof recommends.

English comes from the public-domain Moby word list built into craft-proof. Its dependencies
(log, miniz_oxide, toml, unicode-normalization) are already in the lockfile. The Check
Spelling dialog, Auto Spell Check and Edit Custom Dictionary follow in later PRs.
2026-11-08 14:59:52 +05:00
dotCooCoo 065170b735 Merge main into feat/js-builtins-text 2026-11-08 01:44:20 -08:00
Don Omondi e5674ba1c5 EPS/.ai editing data: test a stack of a solid fill and a stroke without a brush
A path whose style is a solid fill under a 50% Screen stroke comes in as
itself with both, each with its own transparency.
2026-11-08 04:40:55 -05:00
dotCooCoo c66f6b2068 Merge main into fix/export-unknown-options 2026-11-08 01:40:37 -08:00
dotCooCoo f17e700421 Merge main into fix/edit-copy-artboard-route 2026-11-08 01:11:05 -08:00
dotCooCoo 0801e4373f Merge main into feat/js-builtins-core 2026-11-08 01:04:44 -08:00
Don Omondi ba1abb73b0 .ai import: tests for Pattern brushes' number counts and an older Art brush's first number
A Pattern brush reads its scale from 3 or more numbers (the older form's
8 too) and isn't read with fewer; an 8-number Art brush is the older form
whatever its first number. The module notes say the count tells the form.
2026-11-08 03:51:30 -05:00
Don Omondi 6abe10583a Merge remote-tracking branch 'upstream/main' into fix/ai-import-brushes
# Conflicts:
#	docs/file-format-parity.md
2026-11-08 03:35:43 -05:00
dotCooCoo 9f629418e9 Merge main into perf/contours-cover-lists 2026-11-08 00:21:42 -08:00
dotCooCoo 66a01584ae Plug-ins: inputs need a granted doc.read and stay within totals
A filter manifest that lists `inputs` must now list `doc.read` in
`permissions`, so installing it asks the user to grant them and the
Additional Plug-ins Folder loads it only once granted. Left out, the
manifest does not install.

The pixels of all images in one filter input take at most 16 MiB of
base64, and the runs and paragraphs of all its type at most 16 MiB of
JSON. An image whose pixels do not fit what is left comes with
`pixelsOmitted`, checked before it is decoded, and type that does not
fit comes with `truncated`. The read-only objects are kept once and
written into the input from there.

A field a filter adds to a read-only object is named in the refusal
with control and bidirectional characters escaped, cut to 64
characters.
2026-11-08 00:15:36 -08:00
Taha-Mahmoodi 397f5b64c8 Merge fixup: close the Cmd-held bounding box test the merge left open 2026-11-08 12:44:29 +04:30