SVG export wrote an SVG filter as a live <filter> when its SVG 1.1 form
was at most 64 KB, without counting the region and id it writes into
it. A filter close to the limit came back over it, SVG import dropped
it, and the reopened object had no filter.
Export now leaves room for the id and the measured region, checks the
SVG 1.1 form the way import does, and counts each character past U+00FF
as the character reference Latin-1 output writes. A filter that does not
fit is exported as the other pixel effects are. The SVG 1.1 form and its
check are kept for the filters seen last, as checked filters already
are, so export does not check one filter again for each object.
`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.
Align to Path moved the whole line by the largest ascent and descent
among its characters. Each character now moves by its own font, size
and vertical scale. Ascender runs the top of the font's em box along
the path: the ideographic em box that the font's BASE table gives, or
in a Chinese, Japanese or Korean font the one that its typographic or
hhea box, a one-em box-drawing cross or its ideographs give; else an
em box centered on the cap height. Descender runs the bottom of the font's
bounding box along the path, and Center runs a line at half the height
of the top of the font's H along it. In vertical type, Ascender and
Descender move the characters half an em, and Center leaves them on
the path.
Existing documents with Align to Path set to Ascender, Descender or
Center lay their type out at a new distance from the path.
Generic CMYK's tone curves now pass through the CGATS TR 001 tone value
increase of each ink at 40% and 50% (C 20.0, M 17.6, Y 16.8, K 21.6 at
50%), and its 16 Neugebauer primaries mix linearly, so a single ink's
tints gain as TR 001 gives. The 300% ink limit stays. The primaries, the
black-generation curve and the black point are VectorCraft's own values.
- The black point is 90% black under neutral CMY that fills the ink
limit: sRGB black separates to C75 M68 Y67 K90 instead of C67 M67 Y67
K100.
- Black follows a curve over the gray component of the black-free
solve, raised by how far that solve stays lighter than the target.
Grays from sRGB 177 up carry no black, and sRGB 128 gray separates to
C50.5 M42.2 Y42.0 K7.5 instead of C38.8 M26.3 Y29.9 K24.4.
- Display of CMYK fills, swatches and imported CMYK values and the
separation of RGB and Lab colors use the same model.
Paper white still separates to C0 M0 Y0 K0, but other separations
change, and so does the display of CMYK colors with ink. Tests that held
numbers of the old model are updated.
The 2,000,000-triangle limit on a 3D object's meshes is now checked as
each mesh is built, so an object past it is refused before the rest of
its meshes are built:
- Revolve counts each fill's and stroke's mesh as it builds it, instead
of building every one first.
- Inflate still solves every shape's membrane at once (the eye depends
on the highest puff), but builds each solid only when its mesh is
reached (inflate_meshes), so a refused object leaves the later
solids unbuilt.
- All the objects of one 3D asset share one budget
(three_d_meshes_of), so assets.export3D refuses an asset whose
objects pass the limit together.
Found while testing crates/engine/src/cmd/typemenu.rs:614 (unicode_char)
Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Found while testing crates/engine/src/cmd/patternlib.rs:99 (existing_pattern)
Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
The artboard and asset file stems came from unique_file_names, which turned
every character except letters, digits, - and _ into a dash, so the dot of
example.artboard became a dash. Export for Screens now uses a variant that keeps
dots (a name of only dots takes the Artboard-N fallback); safe_file_name still
drops trailing periods and guards device names.
Test: an_artboard_name_keeps_its_dots.
With the Rectangle and Ellipse tools, Cmd lends the selection tool chosen
last, and Copy already took the anchors Direct Selection picked. The
Curvature tool, which Cmd lends Direct Selection, copied the whole path
before this PR, as the Pen did.
The remembered selection is now tied to the document it was made in, by its
uid, instead of being cleared on every tool reset: another view of the same
document, or closing an inactive tab, kept the anchors picked but made Copy
take the whole path.
A lent gesture that leaves the selection as it found it (a Cmd+Shift marquee
over nothing) is no longer recorded as a pick, so the Pen's last anchor stays
its own and Copy takes the whole path.
Also records #6123 in target-app-parity.md.
With the Pen or Curvature tool, Copy and Cut ignore the anchor selection,
so that the last anchor the Pen leaves selected doesn't make Copy take just
that anchor (#2122). Anchors picked with the Direct Selection that Cmd/Ctrl
lends those tools were ignored too, and the whole path was copied.
The session now remembers the selection the lent tool leaves when it gives
the tool back. While that is still the selection, Copy and Cut take the
picked anchors and segments, as with Direct Selection chosen.