Commit Graph
11033 Commits
Author SHA1 Message Date
BFlat 5f2592e4fa Merge pull request #6732 from dotCooCoo/fix/plugin-removed-rename-back
Plug-ins: a failed rename back of a removed plug-in's settings is reported and undone later
2026-11-12 09:07:24 +07:00
BFlat 30b8a1e8b5 Merge pull request #6733 from dotCooCoo/feat/symbols-sort-and-list-views
Symbols: the panel menu sorts by name and offers Small and Large List views
2026-11-12 09:07:13 +07:00
BFlat b9d056986d Merge pull request #6734 from dotCooCoo/feat/para-style-options-sections
Paragraph Styles: Style Options edits indents, spacing, composition, hyphenation and justification
2026-11-12 09:07:00 +07:00
BFlat 8869c137eb Merge pull request #6735 from dotCooCoo/fix/graph-param-types
Graphs: graph.setType, setData and create refuse params of the wrong type
2026-11-12 09:06:48 +07:00
dotCooCoo 23d371ca28 Graphs: graph.setType, setData and create refuse params of the wrong type
graph.setType read `axisMin: "10"` as a cleared bound, so the axis went
back to the calculated range, and it ignored a string or number given for
a true/false option, a string for a number and a number for a text option.
graph.setData and graph.create ignored a `csv` that is not a string and
`series`, `categories` or `rows` that are not lists, and read a string in
`rows` as a blank cell.

The three commands now refuse such a value with an error naming the key,
and leave the graph and the undo history as they were. A null is still
read as a key left out, and a null axis bound still goes back to the
calculated value. A negative tick count is refused too.
2026-11-11 16:41:13 -08:00
dotCooCoo e4a126f08d Paragraph Styles: Style Options edits indents, spacing, composition, hyphenation and justification
Double-clicking a paragraph style, or Paragraph Style Options... in the
Paragraph Styles panel menu, opens Paragraph Style Options
(`ui.paraStyleOptions`) instead of the rename dialog. Its sections are
General (name and stored attributes), Basic Paragraph Formats (Alignment,
indents, space before and after), Composition (composer, Roman Hanging
Punctuation), Hyphenation and Justification. OK runs the new
`paraStyle.edit {name, to, attrs}`, which replaces the name and attributes
in one undo step; paragraphs that use the style keep their local
overrides. Fields left as they were keep the style's values, empty fields
leave an attribute unset, Preview can be canceled, and each section's
Reset Panel (`ui.paraStyleOptions.resetPanel`) clears only its own
attributes. New Paragraph Style shows the same sections, filled in from
the selected paragraph or the interface language's paragraph defaults.

`paraStyle.new`, `paraStyle.setAttrs` and `paraStyle.edit` now reject a
changed indent or space outside -1296 to 1296 pt, Hyphenation counts and
zone outside their ranges, Justification values outside their ranges or
out of Minimum/Desired/Maximum order, and tab positions outside 0 to
100000 pt. A value the style already holds is kept.

Docs: docs/mcp.md, docs/target-app-parity.md.
2026-11-11 16:34:42 -08:00
dotCooCoo c0be73df11 Symbols: the panel menu sorts by name and offers Small and Large List views
The Symbols panel menu gains Sort by Name, which puts the document's
symbols in name order, ignoring case, as one undo step
(`symbol.sortByName`). Symbols whose names differ only in case keep their
order, the current symbol stays current, and no undo step is added when
the symbols are already in order.

The menu's Thumbnail View and List View become Thumbnail View, Small List
View (18-point rows, 14-point thumbnails) and Large List View (the former
List View's 26-point rows and 22-point thumbnails), as in the Graphic
Styles panel. Clicking, double-clicking and dragging a symbol work the
same in every view.

Docs: docs/mcp.md, docs/target-app-parity.md.
2026-11-11 16:29:20 -08:00
dotCooCoo 74f523ae8b Merge main into fix/plugin-removed-rename-back 2026-11-11 15:52:10 -08:00
dotCooCoo ef7fbaac31 Plug-ins: a failed rename back of a removed plug-in's settings is reported and undone later
When plugin.remove could not remove the grant and then could not rename
the plug-in's settings folder back from <folder>.removed, the failure was
only logged: the plug-in got empty settings, and the next removal deleted
the .removed folder with the settings in it.

- The error now names the .removed folder, the plug-in folder and the
  reason, and the plug-in gets no storage until the settings are back.
- The next load, install or plugin.remove of the plug-in renames a kept
  folder back while the plug-in has no folder of its own. When it has one,
  that folder is used and the kept one stays until plugin.remove deletes
  both. A removal while a kept .removed folder exists renames the plug-in
  folder to <folder>.removing.
- Before deleting a renamed folder, the store writes an empty
  <folder>.removed.delete file and removes it once the folder is gone, so
  what a failed deletion leaves is not moved back. When that file can't
  be written, nothing is deleted.
- A .removed folder without a .delete file, including one an earlier
  version left, counts as kept settings: a new install of the id needs
  replace: true, and plugin.remove of the id deletes it.
2026-11-11 15:51:11 -08:00
FredApps 7f3a046b18 CI: nightly release dry run (#6678)
release.yml also runs nightly on main with craft-common-actions' dry-run: every release build
except macOS, with nothing signed, pushed or drafted. Breakage that only the release build hits
(riscv64, Flatpak, FreeBSD, packaging) then shows up the next morning instead of on release
day, as it did on 11 Nov 2026.
2026-11-11 23:04:49 +01:00
Dylan M. Taylor 566f720868 SVG import: references follow an id's first element, one read per linked file, bounded blank lines (#5409)
* fix(svg): first element of an id, shared linked file reads, bounded blank lines

* address review: cache failed linked-image reads but give each href its own placeholder and link

* address review: charge only blank lines to the line-break budget

* address review: a collapsed line break keeps its measured leading in tiny type

* address review: blank lines use the same scaled leading tolerance
2026-11-11 16:11:34 -05:00
Dylan M. Taylor 8e8b43f045 ci: use StepSecurity's maintained actions (#6658)
Each third-party action that StepSecurity publishes a secure drop-in
replacement for now uses that replacement, pinned to a commit with its
version as a comment. Versions follow what we used: the newest
StepSecurity release in the same major, or the closest major they
publish. dtolnay/rust-toolchain refs that named a toolchain (stable,
nightly, 1.76) become the replacement's `toolchain` input.
2026-11-11 16:02:52 -05:00
BFlat b08e421445 Merge pull request #6651 from dotCooCoo/fix/simplify-flat-loops-keep-area
Simplify: a closed subpath whose refits enclose no area keeps its outline
2026-11-12 03:20:46 +07:00
BFlat 6e873b806c Merge pull request #6657 from dotCooCoo/fix/js-random-seed-test
Scripts: test that the OS random value seeds Math.random
2026-11-12 03:16:14 +07:00
BFlat dd6b00c228 Merge pull request #6653 from dotCooCoo/fix/script-throw-site-through-finally
Scripts: an uncaught error that passes through a finally block is reported where it was thrown
2026-11-12 02:53:22 +07:00
BFlat f9ff1caf54 Merge pull request #6648 from dotCooCoo/feat/dynamic-text-on-path
Type: Dynamic Text sizes type on a path to fill its brackets
2026-11-12 02:45:39 +07:00
BFlat e0779c6266 Merge pull request #6646 from dotCooCoo/fix/plugin-fuzz-fuel-slice
Plug-ins: the fuzz test reads the runtime's fuel slice instead of a copy
2026-11-12 02:28:28 +07:00
dotCooCoo 27c24a4f53 Scripts: test that the OS random value seeds Math.random
random_seed passes the OS random source's result to random_seed_from, so a test can
give it a known value and check the seed it makes, instead of only reading the source text.
2026-11-11 11:25:25 -08:00
BFlat 1c049233af Merge pull request #6645 from dotCooCoo/fix/js-random-seed-web
Scripts: Math.random gets a new seed on every web page load
2026-11-12 02:24:16 +07:00
BFlat 541f8beae7 Merge pull request #6643 from dotCooCoo/feat/pdf-large-pages-in-points
PDF: an option writes pages longer than 200 in at full size in points
2026-11-12 02:05:54 +07:00
BFlat c70d320d64 Merge pull request #6639 from dotCooCoo/fix/issue-6622
Part of #6622: Help Bar hints and tool names show in full on hover when clipped
2026-11-12 02:01:07 +07:00
dotCooCoo 796e2a7ebc Simplify: a closed subpath whose refits enclose no area keeps its outline
Follows #6614. When a closed subpath's refit in two and in three parts is
still lines that enclose no area, for example an S curve closed by a
straight edge whose cut points all lie on that edge, Simplify now splits
each segment in 2, 4, 8 and so on (up to 1,024 pieces, 65,536 in all)
until every piece is within the tolerance of the line between its ends
and those lines enclose an area. With Convert to Straight Lines those
lines are the result; without it the subpath stays as it is. A subpath
whose points are all in line keeps the refit's lines, so its extra
anchors are still removed. Lines count as enclosing no area when every
point is within 1e-6 pt of one line.
2026-11-11 11:00:51 -08:00
BFlat c6580dbda0 Merge pull request #6636 from dotCooCoo/fix/plugin-folder-tests-take-turns
Tests: plug-in folder tests take turns on the folder last loaded
2026-11-12 01:56:39 +07:00
BFlat 3dda59ce95 Merge pull request #6640 from dotCooCoo/fix/ids-null-takes-selection
Commands: ids null acts on the selection instead of being refused
2026-11-12 01:56:30 +07:00
BFlat d0bb662aa2 Merge pull request #6641 from dotCooCoo/fix/scriptcheck-identifier-chars
Script checker: names follow Unicode ID_Start and ID_Continue
2026-11-12 01:52:02 +07:00
dotCooCoo 1f835d94c4 Merge main into fix/script-throw-site-through-finally 2026-11-11 10:44:55 -08:00
dotCooCoo 8d094fc811 Scripts: an uncaught error that passes through a finally block is reported where it was thrown
An error a finally block passed on unchanged was reported at the end of
that block, in script.run's report and in the Script Console, because the
block's end raised the error again at a new site. The interpreter now keeps
the site of the exception each finally block runs for, keyed by the stack
slot that holds it, and the block's end throws the exception on from that
site. This holds through nested finally blocks, called functions, resumed
runs and marked host errors. An error the finally block throws is reported
at that throw, and one its return, break or continue discards is not
reported.
2026-11-11 10:44:16 -08:00
BFlat 6a4ef12091 Merge pull request #6603 from Messhias/feat/g5-brush-lib-energy-beams
G5: built-in Energy Beams brush library
2026-11-12 01:43:54 +07:00
dotCooCoo 2606b70604 Type: Dynamic Text sizes type on a path to fill its brackets
Type › Dynamic Text (`type.dynamicText`, also on the Contextual Task Bar
for type on a path) scales the text by one factor so it fills the span
between its start and end brackets, and the layout fits it again after
each edit to the text, the path or a bracket. The first character's
size moves in 0.1 pt steps within 0.1 to 1,296 pt. Turning it off, or
threading the type, keeps the sizes it was drawn at.

- The model saves `dynamicText` only when on.
- SVG, the legacy .ai writer and the .ai editing data write the drawn
  sizes through `vectorcraft_text::drawn`; the editing data warns that
  the setting is not written.
- Shrink Text to Fit and Dynamic Text step the size the Character panel
  shows when a size measures the cap height, x-height or ICF box.

Docs: docs/mcp.md, docs/type-parity.md, docs/target-app-parity.md.
Part of #4134.
2026-11-11 10:42:49 -08:00
BFlat 9840b65a85 Merge pull request #6626 from dotCooCoo/fix/js-xml-copy-and-insert-fuel
JavaScript: new XML copies a one-item list's node, and insertChildAfter and insertChildBefore take fuel per child scanned
2026-11-12 01:35:54 +07:00
BFlat 1e76791ae1 Merge pull request #6615 from dotCooCoo/feat/script-file-folder
Scripts: File and Folder read files in the script's own folder
2026-11-12 01:35:45 +07:00
dotCooCoo 3fba3a440c Merge main into fix/plugin-fuzz-fuel-slice 2026-11-11 10:32:47 -08:00
BFlat f83d916d8a Merge pull request #6631 from Hassan1305/docs-6340-rotation-direction
Commands: every angle and rotation param says which way it turns (#6340)
2026-11-12 01:32:17 +07:00
BFlat 210e9ad7d0 Merge pull request #6632 from dotCooCoo/feat/ruler-guides-as-objects
Guides: ruler guides are document objects on their layers
2026-11-12 01:32:07 +07:00
dotCooCoo 6fbaad6c5e Scripts: Math.random gets a new seed on every web page load
Each realm seeded Math.random from std's RandomState. On
wasm32-unknown-unknown its keys come from stack and heap addresses,
which are the same on every page load, so scripts in the web build
drew the same sequence each time the page opened.

The seed now comes from getrandom (crypto.getRandomValues in the
browser, as crates/pdf/src/encrypt.rs already does), with RandomState
kept as the fallback when it fails.
2026-11-11 10:31:32 -08:00
dotCooCoo ae5bb7b26e Plug-ins: the fuzz test reads the runtime's fuel slice instead of a copy
vectorcraft_plugins exports FUEL_SLICE and BYTES_COPIED_PER_FUEL (hidden
from the docs), and the bulk memory fuzz cases use them for the passes
around one slice, the lengths around one unit of fuel and the fuel
estimate, in place of the copied 20,000,000 and 64.
2026-11-11 10:29:22 -08:00
BFlat 69a021e0f7 Merge pull request #6630 from devius/ka-update
i18n(ka): update the Georgian catalog (55 strings)
2026-11-12 01:20:53 +07:00
dotCooCoo 3074560b07 PDF: an option writes pages longer than 200 in at full size in points
The Save PDF dialog's General section gets "Write pages longer than 200 in
at full size in points" (longPagesInPoints in document.exportPdf,
document.export, presets and document.pdfSettings), off by default. When it
is on, a page with a side longer than 14,400 pt is written with its media
box in points and no /UserUnit at every PDF version, and a PDF 1.5 file
stays PDF 1.5. The export's warning for such a page then says it is written
in points. With the option off, and for pages of 14,400 pt or less, the
file is the same as before.

Docs: docs/mcp.md, docs/target-app-parity.md. The new label has a row in
every catalog that lists the dialog's other options.
2026-11-11 10:17:24 -08:00
dotCooCoo 1643ab52a9 Commands: ids null acts on the selection instead of being refused
The 27 commands that act on `ids` or else the selection (Apply as
Filter, Print Ink Fixes, the Arrange, Cleanup and Path Tools plug-in
commands, Smooth, Text Wrap, variable.bind and variable.unbind among them)
refused `ids: null` with "ids must be an array of non-negative integer
object ids". They now read null as `ids` left out, as the other commands
that take `ids` do. Remove Breaks also reads null as left out when it
decides whether to act on the characters the Type tool selected.
2026-11-11 10:10:46 -08:00
BFlat 7c800f851f Merge pull request #6627 from storytold/fix/sec-eps-scan-charge
EPS import: charge scanned strings, end failed filter decodes, bound data sources and JPEG/TIFF headers
2026-11-12 01:08:41 +07:00
Fabio William Conceição 72c7cb5a73 G5: built-in Energy Beams brush library
Six brush libraries; MCP docs list Energy Beams with the other generated brush libraries.
2026-11-11 18:07:54 +00:00
FredApps a72412eb8f Release: VectorCraft v0.24.0 (#6599) 2026-11-11 19:04:49 +01:00
dotCooCoo 4825113906 Part of #6622: Help Bar hints and tool names show in full on hover when clipped
The status message already ends in an ellipsis and shows its full text
on hover when it is clipped. The Help Bar's hint and the tool name in
the status bar ran past the window edge instead; the Dimension tool's
hint is wider than an 800-point window. Both now end in an ellipsis and
show their full text in a tooltip on hover. Screen readers receive the
full text, and text that fits shows no tooltip.

In a narrow status bar the tool name now ends in an ellipsis before it
takes the status message's room. Before, the tool name could leave the
message almost no width.

The tooltips of the clipped hint, tool name and message wrap to fit
inside the window. egui's tooltips are 500 points wide, which is wider
than an 800-point window at UI Scaling 1.6 or more.

The hint and tool name tests fail without the change. The status
message test covers its existing ellipsis and tooltip.
2026-11-11 09:58:49 -08:00
Dylan M. Taylor 9e28b56354 Merge pull request #6633 from storytold/chore/craft-update-6e03f65
Updates: take craft-update from craft-libs main at 6e03f65bf
2026-11-11 12:53:15 -05:00
Dylan M. Taylor 3ef3afc51d Updates: take craft-update from craft-libs main at 6e03f65bf 2026-11-11 12:53:09 -05:00
dotCooCoo 5ac7d97d85 Guides: ruler guides are document objects on their layers
Ruler guides were a list kept beside the layers. Each guide is now an
object of its layer or sublayer, always directly in it and above the
layer's art. These behave as on main:

- Guides draw on screen only. Exports (SVG, PDF, PNG, PSD), Fit All,
  Select All, the art bounds, clicks and marquees, and a layer's
  Pathfinder and Transform effects leave them out. The Layers panel
  lists them as guide rows of their layer, the highest guide.list
  index first.
- Deleting a layer deletes its guides, and merging layers keeps their
  guides in the merged layer.
- The guide commands number guides as guide.list does, in the order
  they were made.

New: each guide takes an id from the document's object ids. An object
command given a guide's id fails with an error, and node.move cannot
put a guide into a group or out of its layers. A guide made while an
opacity mask, a symbol or a pattern is edited moves to the top
visible, unlocked layer when editing ends.

File format: native files still save the guides in the document's
guides list, in every file version, so older builds read them. Each
entry may now also carry the guide's id, name, locked and hidden
flags; older builds ignore those fields. Opening a file puts each
saved guide on its layer (on the top visible, unlocked layer when the
file names none or a layer it does not have), and each saved guide
counts against the object limit for opening a file. A ruler guide node
that a file holds below a layer's art moves up to the layer's guides,
and one anywhere else (in a group or another object, beside the
layers, or in a symbol) is removed. Ruler guides read from an .ai file
become guide objects on the layer they were on, numbered in the order
the file lists them.
2026-11-11 09:52:28 -08:00
BFlat ad70adf96e Merge pull request #6624 from Messhias/feat/g5-symbol-lib-skill-icons
G5: built-in Skill Icons symbol library
2026-11-12 00:50:41 +07:00
dotCooCoo 28042c2e92 JavaScript: test that new XML copies a list item's attributes and children
The test for new XML with a one-item list now starts from an item that
has a parent, an attribute and a child. It checks that the copy has no
parent and that changing the copy's attribute and child leaves the
original unchanged, so a copy that drops or shares the children fails.
2026-11-11 09:47:33 -08:00
dotCooCoo 8269e140ce Scripts: the backslash path test expects no lookups on Windows only
Outside Windows, `\\host\s\x.txt`, `\\?\C:\x.txt` and `\\.\pipe\x` are
relative file names in the script's folder, so `exists`, `open` and
`getFiles` look them up. The test now expects no lookups for them on
Windows only, and on macOS and Linux checks `//host/s/x.txt`, an absolute
path outside the folder, alone. The returned values are the same on every
platform.
2026-11-11 09:46:57 -08:00
BFlat adeacac9aa Merge pull request #6623 from dotCooCoo/fix/swatch-name-negative-zero
Swatches: default names read a -0 component as 0
2026-11-12 00:44:12 +07:00