The canvas, the gradient chips and the SVG, PDF, EPS and EMF writers mixed
freeform points in display RGB, while Object > Expand and Create Gradient
Mesh mixed them in the model the points share. Points that are all CMYK,
Gray, Lab or RGB now mix in that model in those places too. Points in
different models mix as before: in display RGB, and on ink planes as the
inks of each point.
This changes how existing art looks:
- CMYK and Lab points. With the default Generic CMYK working space and no
ink planes, halfway between C100 and K100 the canvas drew (17, 106, 139)
and now draws (54, 118, 143).
- RGB points in a working RGB space other than sRGB mix in that space.
- On ink planes (a CMYK document that shows transparency), RGB and Lab
points mix first and then separate.
Gray mixes keep their values, and CMYK and Gray points on ink planes draw
as before. RGB points in an sRGB working space draw as before except on
ink planes.
- PDF and EPS write a gradient whose points are all CMYK, or all Gray in a
CMYK file, as a CMYK image. PDF's Output settings convert it as they
convert any CMYK image.
- Darkening applies to the points before they mix.
- With Appearance of Black set to Rich, the canvas mixes a gradient with a
pure CMYK black point in display RGB, and the point fades from RGB black.
File › Open imports .vccomposite files as composite fonts, so an importer
listing that extension no longer shows it under its own filter or in
document.formats. File › Open gets a Composite fonts filter.
document.open refuses dataBase64 that decodes past the importer input
limit before decoding it. A file whose start shows a built-in format
still opens as that format, as it does by path.
`plugin.clearCache` without an id empties the cache of every plug-in
installed in the process. In the engine's library tests it could empty
the cache of another storage test running at the same time, and its
`bytesFreed` could count that test's cache. It now runs in
`crates/engine/tests/plugin_clear_cache.rs`, and the library test checks
that clearing one plug-in's cache leaves the other plug-in's cache.
The storage fuzz test starts each case with an empty plug-in store,
deletes the store when the case ends, and installs `fuzz.storage` with
`replace: true`, so the cases that shrink a failure install their
module.
docs/mcp.md says that files `plugin.remove` can't delete stay in the
folder renamed with `.removed` until the plug-in is removed again.
app.open with params and no importer ran file.open with the path alone, so the desktop app ran the importer on its defaults while headless app.open passed the params to document.open. file.open now carries params to the importer that opens the file.
The importer parameters test installs its module with replace from the second pass on, as plugin.install requires. The permission table in docs/plugins.md lists doc.read for filter, effect and exporter.
An import's instruction and time budgets are now host limits on Limits, as a heavy filter's are, so a test can give an importer a small budget. An importer past its instruction or time limit, and a file past the input limit, return their error and leave an open document and its undo history unchanged. The manifest fuzz varies extensions (missing, dotted, mixed-case, repeated, too long and too many).
plugin.install wrote the grant and the module as two separate writes,
and either could fail with only a log record. With a grant tied to the
module's hash, the stored pair then no longer matched and the plug-in
was skipped at the next start.
The module is now written first and its grant only once it is there.
When the grant can't be written, the store gets its old module back, or
loses the new one on a first install, and a disabled plug-in stays
disabled. A stored module that can't be read back is not replaced by
one that needs a grant.