mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-10-29 20:27:05 -06:00
b74235d77a8081461e2fd2abb8499cf19f14f1a9
15
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
b74235d77a |
chore(deps): bump the cargo-dependencies group across 2 directories with 23 updates
Bumps the cargo-dependencies group with 22 updates in the / directory: | Package | From | To | | --- | --- | --- | | [vello_cpu](https://github.com/linebender/vello) | `0.2.0` | `0.3.0` | | [skrifa](https://github.com/googlefonts/fontations) | `0.47.0` | `0.48.0` | | [harfrust](https://github.com/harfbuzz/harfrust) | `0.13.3` | `0.14.0` | | [hayro-ccitt](https://github.com/LaurenzV/hayro) | `0.3.0` | `0.4.0` | | [jpeg-encoder](https://github.com/vstroebel/jpeg-encoder) | `0.6.1` | `0.7.1` | | [egui](https://github.com/emilk/egui) | `0.36.2` | `0.37.0` | | [egui_extras](https://github.com/emilk/egui) | `0.36.2` | `0.37.0` | | [eframe](https://github.com/emilk/egui) | `0.36.2` | `0.37.0` | | [egui_kittest](https://github.com/emilk/egui) | `0.36.2` | `0.37.0` | | [moxcms](https://github.com/awxkee/moxcms) | `0.8.1` | `0.9.1` | | [fax](https://github.com/pdf-rs/fax) | `0.2.7` | `0.3.0` | | [weezl](https://github.com/image-rs/weezl) | `0.1.12` | `0.2.1` | | [aes](https://github.com/RustCrypto/block-ciphers) | `0.8.4` | `0.9.3` | | [md-5](https://github.com/RustCrypto/hashes) | `0.10.6` | `0.11.0` | | [sha2](https://github.com/RustCrypto/hashes) | `0.10.9` | `0.11.1` | | [vello_common](https://github.com/linebender/vello) | `0.2.0` | `0.3.0` | | [resvg](https://github.com/linebender/resvg) | `0.45.1` | `0.48.1` | | [write-fonts](https://github.com/googlefonts/fontations) | `0.48.1` | `0.54.1` | | [windows-registry](https://github.com/microsoft/windows-rs) | `0.6.1` | `0.100.0` | | [muda](https://github.com/tauri-apps/muda) | `0.21.1` | `0.21.2` | | [x11rb](https://github.com/psychon/x11rb) | `0.13.2` | `0.14.0` | | [zbus](https://github.com/z-galaxy/zbus) | `5.19.0` | `6.0.0` | Bumps the cargo-dependencies group with 1 update in the /crates/plugins/example directory: [serde_json](https://github.com/serde-rs/json). Updates `vello_cpu` from 0.2.0 to 0.3.0 - [Release notes](https://github.com/linebender/vello/releases) - [Changelog](https://github.com/linebender/vello/blob/v0.3.0/CHANGELOG.md) - [Commits](https://github.com/linebender/vello/compare/v0.2.0...v0.3.0) Updates `skrifa` from 0.47.0 to 0.48.0 - [Release notes](https://github.com/googlefonts/fontations/releases) - [Changelog](https://github.com/googlefonts/fontations/blob/main/docs/RELEASE.md) - [Commits](https://github.com/googlefonts/fontations/compare/skrifa-v0.47.0...skrifa-v0.48.0) Updates `harfrust` from 0.13.3 to 0.14.0 - [Release notes](https://github.com/harfbuzz/harfrust/releases) - [Changelog](https://github.com/harfbuzz/harfrust/blob/main/CHANGELOG.md) - [Commits](https://github.com/harfbuzz/harfrust/compare/0.13.3...0.14.0) Updates `hayro-ccitt` from 0.3.0 to 0.4.0 - [Commits](https://github.com/LaurenzV/hayro/compare/hayro-ccitt-v0.3.0...hayro-ccitt-v0.4.0) Updates `jpeg-encoder` from 0.6.1 to 0.7.1 - [Release notes](https://github.com/vstroebel/jpeg-encoder/releases) - [Commits](https://github.com/vstroebel/jpeg-encoder/compare/v0.6.1...v0.7.1) Updates `egui` from 0.36.2 to 0.37.0 - [Release notes](https://github.com/emilk/egui/releases) - [Changelog](https://github.com/emilk/egui/blob/main/CHANGELOG.md) - [Commits](https://github.com/emilk/egui/compare/0.36.2...0.37.0) Updates `egui_extras` from 0.36.2 to 0.37.0 - [Release notes](https://github.com/emilk/egui/releases) - [Changelog](https://github.com/emilk/egui/blob/main/CHANGELOG.md) - [Commits](https://github.com/emilk/egui/compare/0.36.2...0.37.0) Updates `eframe` from 0.36.2 to 0.37.0 - [Release notes](https://github.com/emilk/egui/releases) - [Changelog](https://github.com/emilk/egui/blob/main/CHANGELOG.md) - [Commits](https://github.com/emilk/egui/compare/0.36.2...0.37.0) Updates `egui_kittest` from 0.36.2 to 0.37.0 - [Release notes](https://github.com/emilk/egui/releases) - [Changelog](https://github.com/emilk/egui/blob/main/CHANGELOG.md) - [Commits](https://github.com/emilk/egui/compare/0.36.2...0.37.0) Updates `moxcms` from 0.8.1 to 0.9.1 - [Release notes](https://github.com/awxkee/moxcms/releases) - [Commits](https://github.com/awxkee/moxcms/compare/0.8.1...0.9.1) Updates `fax` from 0.2.7 to 0.3.0 - [Commits](https://github.com/pdf-rs/fax/commits) Updates `weezl` from 0.1.12 to 0.2.1 - [Changelog](https://github.com/image-rs/weezl/blob/master/Changes.md) - [Commits](https://github.com/image-rs/weezl/compare/v0.1.12...v0.2.1) Updates `aes` from 0.8.4 to 0.9.3 - [Commits](https://github.com/RustCrypto/block-ciphers/compare/aes-v0.8.4...aes-v0.9.3) Updates `md-5` from 0.10.6 to 0.11.0 - [Commits](https://github.com/RustCrypto/hashes/compare/md-5-v0.10.6...md2-v0.11.0) Updates `sha2` from 0.10.9 to 0.11.1 - [Commits](https://github.com/RustCrypto/hashes/compare/sha2-v0.10.9...sha2-v0.11.1) Updates `vello_common` from 0.2.0 to 0.3.0 - [Release notes](https://github.com/linebender/vello/releases) - [Changelog](https://github.com/linebender/vello/blob/v0.3.0/CHANGELOG.md) - [Commits](https://github.com/linebender/vello/compare/v0.2.0...v0.3.0) Updates `resvg` from 0.45.1 to 0.48.1 - [Release notes](https://github.com/linebender/resvg/releases) - [Changelog](https://github.com/linebender/resvg/blob/main/CHANGELOG.md) - [Commits](https://github.com/linebender/resvg/compare/v0.45.1...v0.48.1) Updates `write-fonts` from 0.48.1 to 0.54.1 - [Release notes](https://github.com/googlefonts/fontations/releases) - [Changelog](https://github.com/googlefonts/fontations/blob/main/docs/RELEASE.md) - [Commits](https://github.com/googlefonts/fontations/compare/write-fonts-v0.48.1...write-fonts-v0.54.1) Updates `windows-registry` from 0.6.1 to 0.100.0 - [Release notes](https://github.com/microsoft/windows-rs/releases) - [Commits](https://github.com/microsoft/windows-rs/commits) Updates `muda` from 0.21.1 to 0.21.2 - [Release notes](https://github.com/tauri-apps/muda/releases) - [Changelog](https://github.com/tauri-apps/muda/blob/dev/CHANGELOG.md) - [Commits](https://github.com/tauri-apps/muda/compare/muda-v0.21.1...muda-v0.21.2) Updates `x11rb` from 0.13.2 to 0.14.0 - [Changelog](https://github.com/psychon/x11rb/blob/master/doc/changelog.md) - [Commits](https://github.com/psychon/x11rb/compare/v0.13.2...v0.14.0) Updates `zbus` from 5.19.0 to 6.0.0 - [Release notes](https://github.com/z-galaxy/zbus/releases) - [Changelog](https://github.com/z-galaxy/zbus/blob/main/release-plz.toml) - [Commits](https://github.com/z-galaxy/zbus/compare/zbus-5.19.0...zbus-6.0.0) Updates `serde_json` from 1.0.151 to 1.0.154 - [Release notes](https://github.com/serde-rs/json/releases) - [Commits](https://github.com/serde-rs/json/compare/v1.0.151...v1.0.154) Updates `serde_json` from 1.0.151 to 1.0.154 - [Release notes](https://github.com/serde-rs/json/releases) - [Commits](https://github.com/serde-rs/json/compare/v1.0.151...v1.0.154) --- updated-dependencies: - dependency-name: aes dependency-version: 0.9.3 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: cargo-dependencies - dependency-name: eframe dependency-version: 0.37.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: cargo-dependencies - dependency-name: egui dependency-version: 0.37.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: cargo-dependencies - dependency-name: egui_extras dependency-version: 0.37.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: cargo-dependencies - dependency-name: egui_kittest dependency-version: 0.37.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: cargo-dependencies - dependency-name: fax dependency-version: 0.3.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: cargo-dependencies - dependency-name: harfrust dependency-version: 0.14.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: cargo-dependencies - dependency-name: hayro-ccitt dependency-version: 0.4.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: cargo-dependencies - dependency-name: jpeg-encoder dependency-version: 0.7.1 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: cargo-dependencies - dependency-name: md-5 dependency-version: 0.11.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: cargo-dependencies - dependency-name: moxcms dependency-version: 0.9.1 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: cargo-dependencies - dependency-name: muda dependency-version: 0.21.2 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: cargo-dependencies - dependency-name: resvg dependency-version: 0.48.1 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: cargo-dependencies - dependency-name: serde_json dependency-version: 1.0.154 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: cargo-dependencies - dependency-name: serde_json dependency-version: 1.0.154 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: cargo-dependencies - dependency-name: sha2 dependency-version: 0.11.1 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: cargo-dependencies - dependency-name: skrifa dependency-version: 0.48.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: cargo-dependencies - dependency-name: vello_common dependency-version: 0.3.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: cargo-dependencies - dependency-name: vello_cpu dependency-version: 0.3.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: cargo-dependencies - dependency-name: weezl dependency-version: 0.2.1 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: cargo-dependencies - dependency-name: windows-registry dependency-version: 0.100.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: cargo-dependencies - dependency-name: write-fonts dependency-version: 0.54.1 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: cargo-dependencies - dependency-name: x11rb dependency-version: 0.14.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: cargo-dependencies - dependency-name: zbus dependency-version: 6.0.0 dependency-type: direct:production update-type: version-update:semver-major dependency-group: cargo-dependencies ... Signed-off-by: dependabot[bot] <support@github.com> |
||
|
|
e2a870e602 |
Security: bounded flattening, plug-in budgets and caches, loaded textures, Revolve paint copies, color book names and ICC names
CodeRabbit findings #4, #34, #46, #51, #77, #101, #170, #171, #188: - `vectorcraft_geom::flatten`: kurbo's flatten with each curve's tolerance raised so it makes at most ~4096 segments (non-finite curves become a line); the canvas outline and variable-width strokes use it. - Plug-ins: a heavy filter's budget is the host's `Limits::heavy_fuel`/`heavy_wall_time_ms`, never more; a start function runs on one fuel slice; the effect cache holds at most ~1M anchors of inputs and results, and doesn't keep a result past a quarter of that. - Loaded textures are cached by their PNG (base64 spacing doesn't matter), and live textures hold at most 512 MB together. - Revolve draws the source path when the faces' paint copies would pass 256 MB. - Color books: names with prefix and suffix take at most 64 MB. - ICC: localized-name (`mluc`) records over 1 MB together are refused before moxcms copies them. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> |
||
|
|
79cb38f678 |
Plug-ins: heavy filters, allowed at install and run in the background (G17)
A filter plug-in gets 50 M instructions and a minute for each run. Filters that order a plotter's paths, pack shapes or run a simulation need minutes, and the app shouldn't freeze while they compute. A filter's manifest may now ask for "budget": "heavy" (Budget): each run gets HEAVY_FUEL (1 G instructions) and HEAVY_WALL_TIME_MS (300 s). Only a filter may ask. plugin.install refuses such a filter without allowHeavy: true, and plugin.inspect returns the entry a module would have without installing it. Install Plug-in… and File › Open ask the user and install on OK; the plug-in store keeps the answer, and folder loads skip heavy filters with a note, since they ask nobody. The app runs a heavy filter on a thread of its own (plugin_runs), not in Background Save's queue, with the status bar and a progress window (Cancel, Continue in Background) that it shares with Background Export (export_progress::window). FilterRun splits plugin.run: prepared on the session, run on any thread, its output handed in, and the next plugin.run with the same params applies that output instead of running the plug-in again, so the edit stays one guarded, journaled command. A result whose document or plug-in changed meanwhile is dropped, and the status bar says to run it again. A cancelled plug-in run is now EngineError::Cancelled. What a filter keeps with the document (#3720) goes with the run: it is given _context.documentData when the run is prepared, and the documentData of its output is applied with its objects, in the same undo step, when the run is handed in (FilterRun::finish). Tests: plugins/tests/abi.rs (100 M loop steps out of a light budget, within a heavy one; folders skip heavy filters), manifest.rs, engine tests_plugins.rs (consent, inspect, the store, hand-in, a handed-in run's document data, cancel) and ui-egui tests_plugin_runs.rs (installing asks, no Preview, a background run as one undo step, a stale result kept out, the progress window). CRAFT_UI_HEAVY_FILTER_WASM=<folder> writes a test filter to try in the app. Its strings and messages have rows in each complete catalog (COMPLETE_MESSAGES). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HhvnnnD5fTFupK8WWq35un |
||
|
|
1505384501 |
Plug-ins: filters keep data with the document (G17)
A filter plug-in had nowhere to keep settings that belong to the whole document rather than to one object, such as the pens a plotter holds or a machine profile: it could only ask for them again on every run. - A filter's output may hold documentData: any JSON of at most 1 MiB (objects::MAX_DOCUMENT_DATA) that replaces what the plug-in keeps with the document, null removing it, in the same undo step as its objects (objects::decode_output). Too much refuses the output and the document stays as it was. - A filter gets it back in _context.documentData (null until it keeps something). A filter reads and writes only its own. - It is the document's foreign data, Document::unknown["pluginData"] by plug-in id (vectorcraft_doc::plugin_data), where the perspective grid and the brushes keep theirs. So the native file needs no section of its own for it, and hosts from before keep it when they save. An exporter is given the whole document, so it can read every plug-in's. Nothing else lists it, as the reference app's Document Info lists no plug-in data. A live effect isn't given it: its geometry is worked out from the object alone wherever it is drawn. Tests: plugin_data.rs (each plug-in its own entry, forgetting what isn't kept copies nothing, a damaged value holds nothing), objects/tests.rs (kept, forgotten, refused over the limit), tests_plugins.rs (one undo step with the objects, read back, not given to another filter, kept by the native file among its foreign data, refused over the limit with the document unchanged, null removes it) and tests/plugin_export.rs (an exporter finds another plug-in's). The size error has its row in each complete catalog (COMPLETE_MESSAGES). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HhvnnnD5fTFupK8WWq35un |
||
|
|
8bc117eb8b |
Plug-ins: doc comments for the functions the filter changes touch
The docstring check of the review counts the functions a pull request touches: effect.apply, effect.setParams, plugin.run, the line cap name, the reader of an output object and seven of the object tests had no doc comment. Each now says what it does or checks; the join and cap names get one each. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HhvnnnD5fTFupK8WWq35un |
||
|
|
78105cc695 |
Plug-ins: filters read and set effects and stroke styles (G17)
A filter could reshape and repaint objects, but not set the stroke's
join, cap or miter limit, nor the effects an object's appearance holds.
A tool that prepares objects for a live effect (a sheet of samples,
each with the effect at its own settings) had to leave the user to
apply the effect to each object by hand.
- Each input stroke has its join, cap and miterLimit beside its paint
and width (live effects get the same, through the shared encoder),
and each object its own effect records, {id, params, visible}.
- An output stroke may set them (miter limit clamped to 1-500), and an
output object's "effects" replaces its own effects.
- The host admits each record as effect.apply does: an effect that
effect.list lists or an installed live-effect plug-in, parameters it
takes (filled in to their defaults; a plug-in's checked against its
manifest), one 3D effect that fits the object (its fills' and
strokes' own effects counted), and the texture of an effect with
Load Texture (Glass, Texturizer) as the effect stores it, never a
file to read. A record the object already had stays as
it is, so a filter that hands its input back changes nothing. One
refused record refuses the whole output and the document stays as
it was.
The plug-ins crate checks the records' form; which effects exist is the
engine's to say (objects::AdmitEffects, engine plugin::admit_effects).
effects::validate_three_d is the one check of whether a 3D effect fits
an object, for effect.apply, effect.setParams and the filters.
A path handed back as it was now stays the live shape it was: write()
dropped a live rectangle's or ellipse's parameters whenever the output
held a path, changed or not, so a filter that returned its input
turned a live rectangle into a plain path.
objects/tests.rs checks the round trip, stroke styles on existing and
new strokes, the host's refusal, the bad forms refused, and a live
rectangle handed back unchanged (a plain path before the fix);
tests_plugins.rs runs filters that set a built-in and a plug-in effect,
an echo that changes nothing, and six refused outputs.
CRAFT_PLUGIN_FRAME_WASM=<folder> saves a test filter to try in the app.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HhvnnnD5fTFupK8WWq35un
|
||
|
|
2e4666a364 |
Plug-ins: live effects read their object's fills and strokes (G17)
A live-effect plug-in was given only its object's geometry. An effect
that draws as wide as the stroke it sits on, or tells its fills apart,
had to ask for them again as parameters, which then went stale when
the paint changed.
A live effect's input object now holds the object's fills and strokes
too, read only and in the form a filter gets them (one encoder,
objects::paint_lists, for both), and _context.item says where the
effect sits: "object", or {"fill": i} / {"stroke": i} for an effect in
a fill's or a stroke's own effects. effects::GeomContext carries the
object's appearance and the item, and the plug-in cache keys on the
paints, so a change of paint runs the plug-in again. Hosts from before
this give geometry only; nothing in the output changes.
Expand worked a fill's geometry effects out in the object's context, so
a plug-in effect there would be told "object" and a gradient fill was
expanded into a shape the canvas doesn't draw: fill_shape now gives them
the fill's context, as drawing does (expand.rs).
Siblings named with a declared prefix, the other half of such context,
are left out: the effected geometry is worked out from the object alone
wherever it is drawn, measured, hit-tested or expanded.
wat::when_given is a plug-in whose output depends on whether its input
or parameters hold a text. tests_plugins.rs uses it to check that an
effect sees the stroke's width and the fill, runs again for a thinner
stroke, and on a second stroke is told so; effect.rs checks the item
counting; a gradient fill under such an effect is drawn and expanded
into the same triangle. CRAFT_PLUGIN_PAINTS_WASM=<folder> saves a test
effect to try in the app.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HhvnnnD5fTFupK8WWq35un
|
||
|
|
c755909d67 |
Plug-ins: labels, units, groups, help and conditions for parameters (G17)
A plug-in's dialog labelled each field with its parameter's name spaced
out ("Line_spacing_mm:"), showed numbers without their unit and listed
at most 64 parameters in one column. A plug-in with many settings, such
as a generator's or an exporter's, could neither explain nor sort them,
and its dialog showed settings that don't apply to the choices made.
Each parameter may now say how dialogs show it, in keys that hosts
from before them ignore (plugins::dialog):
- label; unit, after the value ("0.25 mm"); help, on the label; and
helpUrl, an https:// page opened from a button after the field.
- group: the parameters outside any group come first, then each group
as a section that folds, in the order the groups first appear, the
fields lined up down the dialog.
- visibleWhen: {"pattern": ["lines"]} shows a parameter only
while each checkbox or choice it names, declared before it, has one
of the values listed and is shown itself. Manifest::visible decides
every parameter in one pass, in declaration order. A hidden parameter
still goes to the plug-in with its value, so a run never depends on
what the dialog showed.
Two types join number, int, bool and choice: string, a text field cut
to maxLength, and numberList, numbers typed separated by commas or
spaces, each clamped, minItems to maxItems of them. A plug-in declares
up to 256 parameters, at most 64 outside groups. The filter, live-effect
and exporter dialogs use every key. The Appearance panel's editor of a
plug-in effect uses the labels, units, help and conditions, and reads a
typed number list as the dialog does.
dialog.rs tests parsing, the round trip of a manifest written out,
sections, visibility (also of 256 overlapping conditions, which a
recursive check would take forever on) and the keys refused;
manifest.rs the new types and limits. tests_plugin_fields.rs draws a
dialog with kittest: labels and units, sections in order with their
fields lined up, visibleWhen hiding and showing rows, and the help
button opening its page.
appearance.rs checks the editor's labels, units, conditions and a
typed number list, and form.rs units after numbers (a unit starting
with a digit is spaced from it) and typed lists.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HhvnnnD5fTFupK8WWq35un
# Conflicts:
# docs/gaps.md
# docs/target-app-parity.md
|
||
|
|
24936cd006 |
Plug-ins: exporters write file formats of their own (G17)
A plug-in could filter objects or reshape them as a live effect, but
nothing it made could leave the app: pen plotters, cutting machines and
laser cutters read formats VectorCraft doesn't write. An exporter is a
third kind of plug-in ("kind": "exporter", with the file "extensions"
it writes), in the same sandbox and with the same ABI v1 exports.
- It adds a write-only format, plugin.<id>. document.formats lists it
with its plug-in id, and document.export writes it by that id, or by
a path ending in one of its extensions that no built-in format has;
"params" carries its parameters, checked against its manifest as a
filter's are.
- File › Export › Export As lists it after the built-in formats, with
Use Artboards greyed out, since the plug-in writes the whole
document. One with parameters asks for them in a dialog generated
from its schema (pluginExport) once the file is picked.
- The plug-in is given the native file's JSON (format::json_part:
images of 8 KiB or more without their data) and _context {mode:
"export", extension, name}. It returns {"dataBase64", "warnings"?}
or {"error"}. The host writes the file, and nothing when the plug-in
declines or returns bad data.
- An export gets 10 G instructions plus 4,000 per byte and 300 s.
Background Export's Cancel stops it between two slices of that
budget (Error::Cancelled), and a cancelled live-effect run is not
cached as a failure.
- plugin.run and Object › Plug-ins say where an exporter is instead of
calling it a live effect.
engine/tests/plugin_export.rs reads back what an exporter is handed
with wat::echo_exporter, an exporter whose file is its input or its
parameters (its base64 encoder is written in WAT). The document it is
given is document.save's JSON, without the large image's data, and its
parameters arrive defaulted, clamped and with the file's name and
extension. It also covers listing and removal, built-in extensions
winning, selectedOnly, declines, bad base64, missing data, warnings,
and Cancel stopping a plug-in that never returns. It is a test binary
of its own: installed plug-ins are process-wide, and the format-list
unit tests check exact lists. dialogs/tests_plugin_export.rs drives
Export As headlessly; plugins/tests/abi.rs covers the budget, the
parameters and the echo exporter; format/tests/native_v4.rs covers
json_part.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HhvnnnD5fTFupK8WWq35un
|
||
|
|
08c8c11798 | Plug-ins: numeric defaults stay in their declared range | ||
|
|
5e9b7d09a2 |
Review: a whole number past i64::MAX is past any maximum; ROADMAP (#1091)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> |
||
|
|
aecf88c1c1 | Plug-ins: whole-number parameters keep their exact value and stay in range | ||
|
|
9f875050ef |
Fix #832: --automation-read-root and --automation-write-root confine the MCP server's files
vectorcraft-cli mcp and vectorcraft --control take the flags PhotoCraft takes. While roots are in force, every path a command reads (open, place, relink, SVG image links, library and profile loads, plug-ins, preset imports, font searches) must lie inside the read root and every path it writes (save, export, package, Export for Screens and for Web, print to file, captures, library saves) inside the write root. Paths are made absolute, links are followed (a missing file's nearest folder's), and the result is compared by whole components, ignoring case on Windows; `..` below a missing folder, dangling links and device names are refused. A root left out grants none of its access; without the flags nothing changes. The checks live in one place, vectorcraft_engine::file_access, consulted by the engine's file helpers and the app's file services. The headless server confines its whole process; the app confines control requests, the frames carrying input they inject and the background saves they start, leaving the person at the keyboard and the app's own folders alone. The screenshot tool now has the backend write its file. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> |
||
|
|
d1d78e61da | M0.CI: restore checks without optional fonts | ||
|
|
811ad1efd8 |
Fix #121: sandboxed WebAssembly plug-ins: object filters and live effects
VectorCraft had an Additional Plug-ins Folder preference but nothing loaded from it. Port PhotoCraft's wasmi plug-in host (same sandbox, manifest and parameter schema) as the new vectorcraft-plugins crate (L2), extended for vector documents: - Object filters read the selected paths and compound paths as JSON (native PathData and Paint forms: geometry, fills, strokes, gradients, opacity) and return the objects to keep, change, add or delete; the output is validated in full and applied as one undo step (plugin.run). A failing plug-in leaves the document untouched. - Live-effect plug-ins are geometry effects in the appearance stack (effect id plugin.<id>), re-evaluated (and cached) when the object or parameters change, editable, exported and baked by Expand Appearance; a missing plug-in leaves the geometry as is. - plugin.list / info / run / install / remove / reload; the preference folder installs every *.wasm at startup and when it changes; File > Open of a .wasm installs it (web). - Object > Plug-ins and Effect > Plug-ins menus with dialogs generated from the parameter schema (live preview), the Appearance panel's fx menu, docs/plugins.md, an original example plug-in (Desaturate, a Rust crate outside the workspace) and fuzzing of the plug-in boundary (engine/tests/plugin_fuzz.rs). Tool plug-ins and paint-changing live effects are left for later (docs/plugins.md). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> |