A pattern's or a brush's art was copied into the document with new ids,
but the art of an opacity mask inside it kept the ids of the reader that
read the definition. Those ids could repeat ids of objects in the
layers. The mask art now takes document ids, as a symbol's art already
does.
Switching documents, or windows of a document, deactivates the Type tool, which clears the tool its double-click came from, so Escape after a later edit goes to the Selection tool. The field's comment and the two checklist rows now say so.
Spine::at_length computed tangents from flattened polyline chords, which
are piecewise constant and jump discretely between chords on curved
spines. Steps oriented to the spine with Align to Path stuttered at
large step counts.
Fix: store the original PathData in Spine and compute the tangent from
the original cubic at the true arc-length position via ParamCurveDeriv,
proportionally mapping flattened arc-length s onto each segment's curve
arclength using anchor_length values, instead of using piecewise-constant
chord directions.
Updated segment-selection condition in Spine::at_length to skip segments
whose flattened end is not greater than start before checking whether s is
within the segment. Preserve the existing final-segment fallback so
at_length(0.0) selects a nonzero segment and uses its tangent.
Added zero-derivative fallback tangent for blend-step sampling to keep
Align to Path from passing a zero tangent to atan2.
Added missing docstrings for Spine::new and Spine::length to satisfy
docstring coverage requirements.
Co-authored-by: Craft Bot <bot@storytold.dev>
Spine::at_length computed tangents from flattened polyline chords, which
are piecewise constant and jump discretely between chords on curved
spines. Steps oriented to the spine with Align to Path stuttered at
large step counts.
Fix: store the original PathData in Spine and compute the tangent from
the original cubic at the true arc-length position via ParamCurveDeriv,
proportionally mapping flattened arc-length s onto each segment's curve
arclength using anchor_length values, instead of using piecewise-constant
chord directions.
Updated segment-selection condition in Spine::at_length to skip segments
whose flattened end is not greater than start before checking whether s is
within the segment. Preserve the existing final-segment fallback so
at_length(0.0) selects a nonzero segment and uses its tangent.
Added missing docstrings for Spine::new and Spine::length to satisfy
docstring coverage requirements.
Co-authored-by: Craft Bot <bot@storytold.dev>
Spine::at_length computed tangents from flattened polyline chords, which
are piecewise constant and jump discretely between chords on curved
spines. Steps oriented to the spine with Align to Path stuttered at
large step counts.
Fix: store the original PathData in Spine and compute the tangent from
the original cubic at the true arc-length position via ParamCurveDeriv,
proportionally mapping flattened arc-length s onto each segment's curve
arclength using anchor_length values, instead of using piecewise-constant
chord directions.
Added missing docstrings for Spine::new and Spine::length to satisfy
docstring coverage requirements.
Co-authored-by: Craft Bot <bot@storytold.dev>
Spine::at_length computed tangents from flattened polyline chords, which
are piecewise constant and jump discretely between chords on curved
spines. Steps oriented to the spine with Align to Path stuttered at
large step counts.
Fix: store the original PathData in Spine and compute the tangent from
the original cubic at the true arc-length position via ParamCurveDeriv,
proportionally mapping flattened arc-length s onto each segment's curve
arclength using anchor_length values, instead of using piecewise-constant
chord directions.
Reviewed-by: craft-house-rules
Co-authored-by: Craft Bot <bot@storytold.dev>
Spine::at_length computed tangents from flattened polyline chords, which
are piecewise constant and jump discretely between chords on curved
spines. Steps oriented to the spine with Align to Path stuttered at
large step counts.
Store the original PathData in Spine and compute the tangent from the
original cubic at the true arc-length position via ParamCurveDeriv,
instead of flattened chord directions.
Adds a regression test walking 200 samples along a curved spine and
asserting each tangent step stays under 0.1 radians.
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.
Type that SVG text can't draw is written as outlines: vertical type, ruby,
right-to-left text, type on a path with an effect other than Rainbow, an end
bracket, Align to Path, Spacing, hanging punctuation, bullets or inline
graphics. Only glyphs bent along a path gave the outlined group a
`role="img"` and `aria-label`; every other case left screen readers and
search with no text. Each of them now names the group with its text.
Convert to Outlines still writes the paths alone, as before.
Inline graphics' placeholder characters stay out of the name, and empty
type gets none. An object whose id is its name also gets `data-name`, so
opening the file again keeps the name instead of taking the label.
Revolve gave each side face a normal as long as its profile edge, and
the mesh kept that length, so the glTF, OBJ and USD files of a revolved
object carried normals of any length (100 for a wall 100 pt tall). A
face whose edge was shorter than about 0.71 pt fell back to its corners'
normal, which turns inward when the profile is drawn the other way, and
its triangles then faced into the solid.
The mesh now scales every given normal to unit length before choosing
between it and the corners' normal.
Only a double-click on type from another tool records the tool Escape and
Cmd+Enter return to, and the Type tool keeps it until another tool is
chosen. Choosing the Type tool from the toolbar records none, so Escape
goes to the Selection tool. The type and UI checklists and the doc
comments on prev_tool, end_editing and claims_key now say so.
docs/type-parity.md held four copies of the point, area and path type
row, three of them with older Escape wording. They are one row again,
with the Type Orientation sentence that only one copy had.
`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.