craft-update and craft-vectorcraft-format move from storytold/craft-libs
at 6e03f65bf to e98299546, craft-libs main with 47b6bbadf. The startup
check's thread now reads whether the copy installs itself, so a slow
disk no longer stalls a frame when the startup prompt is built. Both
crates stay on one craft-libs revision; the other craft-libs pins are
unchanged. Cargo.lock changes only the two crates' source.
When the action New Action made for the recording in progress is deleted,
Stop Playing/Recording keeps none of the recorded steps. The step and
file limits measured a new action in the original set instead, so a
recorded command could be refused while the set's file was near 8 MiB.
The recording now has no target in that case, and no limit applies.
With Size 0, Roughen moved no point but still replaced each segment
with its Detail's points joined by straight lines (Corner) or by a
smoothed curve through them (Smooth), so a curved path lost its shape.
At Size 0 each segment is now split at the Detail spacing into pieces
of equal length on the segment itself, with `pathtools::insert_at`: a
straight segment gets corner points without handles, and a curve gets
smooth points whose handles follow it. The path keeps its outline with
Smooth or Corner points alike. The params text of `distort.roughen`
describes size 0.
`insert_at` now counts the anchors added before each returned mark in
one pass. It counted them again for every split segment, which took
quadratic time on a path with many split segments. Its results are
unchanged.
Existing documents with a Roughen of Size 0 on a curved path, or with
Smooth points, draw differently.
This is VectorCraft's own rule. What Roughen does is described in
https://helpx.adobe.com/illustrator/desktop/manage-objects/reshape-transform-objects/distort-and-transform-effects-in-illustrator.html
Under automation read roots, `ui.inspect` kept a folder preference whose
stored value was readable even when the trimmed path the app uses was
not: ` /outside/fonts` reads as a name in the working folder, while the
app uses `/outside/fonts`. A folder preference now stays only when both
forms are readable. A reply string is decoded for path matching only when
it holds a `%XX` escape, so a string such as `width="100%"` is no longer
decoded and thrown away. The library list line in the progress doc now
states when a hidden library's `loaded/<file name>` id moves.
docs/file-format-parity.md held 36 copies of the paragraph on the
editing copy of a file. #6202 and #6249 each added a combined copy
without removing the copies it replaced, so the count went from 34 to
35 and then to 36. The section now holds one copy: #6249's combined
copy, with the Align to Path distance clause that seven of the other
copies carry from #6247. Every other clause of the removed copies is in
the kept one, word for word or in the newer, longer form another copy
wrote. The older Align to Path clause, with its measurements for one
font at 24 pt, is removed because #6247's wording replaces it. The
paragraph now starts with a capital letter.
The summary table also repeated its "Formats opened or placed" and
"Formats saved (Save As)" rows. The older row of each is removed: the
one that still lists HEIC/HEIF as missing, and the one that lists fewer
contents of the editing copy that `.ai` saves write.
The doc comments of the Transform, Free Distort, Tweak and Zig Zag
readers, and the Pucker & Bloat and Twist arms, now name the public
pages that list each effect's dictionary keys. No code changes.
The .ai writers write RGB and Lab values to four decimals next to a CMYK
equivalent, but converted that equivalent from the color at full precision.
When a file was read back and saved again, its CMYK equivalents differed in
the fourth decimal (for example 0.6831 and 0.6832). In the editing data this
affected plain RGB colors, RGB gradient stops, global process and spot colors
and the header's custom colors; in the legacy .ai writer it affected RGB
gradient stops.
The CMYK equivalent of an RGB color, and of a global process or spot color,
is now converted from the values as they are written, so both saves convert
the same values. Lab values of global process and spot colors are now written
clamped to the range the reader reads (L 0 to 100, a and b -128 to 127).
A plain Lab fill or stroke and a Lab gradient stop are still written as RGB
with a CMYK equivalent converted from the Lab values. The reopened file holds
them as RGB, so their CMYK equivalents change once on its next save.
The art style round-trip test now compares the program exactly; its blanked
CMYK values and the four-decimal tolerance are no longer needed.
A Recent Colors chip in the Color or Swatches panel now starts a paint
drag. Dropped on the Swatches panel's list it becomes a swatch of its
color, in its color model, through swatch.new as one undo step: on a
color group or one of its swatches it joins that group, elsewhere it
joins the ungrouped swatches. A click on a chip still paints the
selected art, and a drag does not.
A paint Alt-dropped on Registration now becomes a new swatch instead of
ending in a "can't be edited" error from swatch.edit.
Each writer marks its notes as a loss (something of the document that the
file leaves out or that reaches it changed) or as a note on the options
(an option it didn't apply or applied another way while the art reaches
the file as it looks, or something an option turns off). The PDF, SVG,
EPS, legacy .ai, DXF and HP-GL writers return their notes on the options
in a list of their own (`setting_notes`) beside `warnings`, and the
engine's `Encoded` does the same.
The replies of the save and export commands, and of
`clipboard.exportPdf` and `clipboard.exportPng`, list the losses first,
each kind in the order the writers gave them, across every file that
Export for Screens writes. The status bar names the first note, so an
export to lossy WebP of type in a font that isn't installed now names the
fallback-font note instead of the lossy WebP note. A print to a file
keeps the order its notes are given in.
With a Shaper Group or one of its faces selected, a Shaper click within
3 screen pixels of one of the group's original shapes' outlines enters
Construction mode with that shape selected, also where the outline runs
through a merged face. shaper.select takes a tolerance in points
(default 3, at most 1000); hidden and locked shapes are skipped, and a
Shaper Group above the selected one still takes the click.
The text document reader never read a story's manual kerning, so type
kerned by hand in a .ai or EPS editing copy came in with automatic
kerning on every pair and drifted from the file's page from each kerned
pair on. Envelopes of such type drew apart from their drawn art and
kept it.
Key 8 of a story's text holds the kerning as runs of characters (key 1),
each with a value in thousandths of an em (key 0 of key 0) or empty
where the automatic kerning applies. Each character with a value now
takes it as its Kerning, the space after it, and the style runs split
where the value changes. A value that can't be read keeps the automatic
kerning, a run whose length can't be read ends the runs there, and past
65,536 runs the characters keep the automatic kerning.
- ate.rs: Story reads the runs (manual_kerning) and node() splits its
text runs at them (Kerns), with a unit test over values, style-run
boundaries, hostile values and the laid-out gap, and one that pins
the limit of runs.
- tests_native.rs: an imported story with kerned and automatic runs.
- docs/file-format-parity.md: status line, mapping line, revision row.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The new General preference Show Bounding Box While Moving and Drawing
(`boundingBoxWhileMovingAndDrawing`, off by default) keeps the bounding
box and its handles visible during two kinds of drag, with View › Show
Bounding Box on. While a drag moves the selection (a Selection tool
move, an Alt-drag copy, or a shape tool's move by the center point),
the box is drawn where the drag has moved the selection. The box is
measured once when the drag starts and offset by each step's move.
While the Rectangle, Rounded Rectangle, Ellipse, Polygon and Star tools
draw a shape, the box is drawn around the shape. A rotation and a
widget drag still hide the box until the release. The Line Segment
tool, the Pen, the Pencil and the Paintbrush draw no box.
With the preference off, the box hides during a move (#737, for #712)
and while a shape is drawn (#5839), as before. A Selection tool move
with Real-time Drawing off still moves the box with the pointer, and a
shape tool's move by the center point hides it in both modes.
With Real-time Drawing off, the box of a shape being drawn is measured
from the pending preview, in the color of the layer the shape goes on.
A shape being drawn shows no box until a preview step has succeeded,
so a failed preview does not show the box of the selection from before
the drag. The preference's label has a row in every catalog.
Session::deferred_move() is replaced by Session::move_drag_box(), which
returns the moved box, and Session::deferred_transform_box() now also
returns the layer color of the box.
Docs: docs/mcp.md, docs/target-app-parity.md.
ui.action.record's params text now says that a recorded command whose
step passes a limit only from the values it adds as it runs keeps its
edit and result, that later recorded commands are an error and do not
run, and that ui.action.stop leaves its step out.
crates/mcp/src/ui_catalog.rs now matches the desktop table again
(cargo xtask ui-commands --check), including the action-limit params
texts of the earlier commit.
A blend between two strokes drawn with a pressure-sensitive brush gave
every step the pen recording of the nearer key, so the brush jumped at
the middle step. The steps now interpolate the pressure, tilt, bearing
and rotation at every position either key has a sample. A key without a
recording counts as half pressure, half tilt and 0 degrees, as brushes
read it. Angles turn the shorter way round, and steps and whole turns in
a recording stay in the steps. Different brushes still switch halfway.
A path with an effect, or a path linked to a graphic style, can have a
solid stroke a plain line can't draw, such as one with a width profile.
When the reader reads the path back from an art style, the path is
written with that style, and the style holds the stroke. The path's
drawn look still writes the stroke as a filled outline, and the save
warned that such strokes are written as filled outlines.
The warning is now left out while a drawn look is written, as the
effects warning already is. A styled group's style holds no fills or
strokes, and its members are written again after the look, so a
member's stroke still warns. Strokes that no art style holds (gradient
or pattern strokes, for example) still warn.
The font menu opened at its field's width, so from the Control bar's narrow
Character field the filters wrapped one chip per line and family names were
cut off after a few letters.
- The filters keep the same four rows wherever the menu opens: the scripts;
the star, Any Kind, Serif / Mincho, Sans Serif / Gothic and Rounded;
Script / Brush, Monospaced and Decorative; Font Technology with Variable.
- The menu opens at least wide enough for those rows and for a family name
up to 220 points wide with room for its sample, up to 60% of the window,
and stays in the window. A field wider than that keeps its width.
- Where the row has room, the sample starts after the widest name instead of
halfway along the row. It takes the row's whole height instead of 4 points
less, so samples draw larger at every Font Preview Size.
Requested by POGO.
pattern::tests::kept_tiles_count_the_images_they_could_not_decode
draws a pattern whose art is an image three times and expects one tile
to be rasterized. A tile of art with an image is kept only while
FontDb::global().generation() is the one it was drawn at (Deps::current
in pattern.rs). The render tests that hold adding_fonts() add fonts,
which increases it (tests/fontchange.rs, tests/typeedges.rs,
tests/alternate.rs, tests/colrglyphs.rs and tests/bitmapglyphs.rs).
When one of them added a font between the frames, the next frame drew
the tile again and the test failed with left 2 or 3, right 1. Run with
the tests in tests/fontchange.rs and tests/typeedges.rs, it failed in
23 of 30 runs on main.
The test now holds fonts_steady() and takes its counts from
with_fonts_unchanged(), as the other render tests that count kept work
do. Each run builds a new document, so its first frame does not find a
tile from an earlier run. Run with the same tests, it passed in all 30
runs.
A recorded command whose step passes a limit only from the values it adds
as it runs keeps its edit. The status bar names the limit, later recorded
commands do not run, and Stop Playing/Recording leaves its step out.