- The "`axes` must be [a, b, c, d] ..." refusal gets an @msg row in each of
the 24 complete-message catalogs, next to the other svg.filter rows.
- docs/mcp.md and the params text say that absent or [1, 0, 0, 1] axes are
the document's, that effect.setParams sets them back with [1, 0, 0, 1]
(the commands refuse null), and that moving, turning, scaling or skewing
the object moves `origin` and leaves `axes` as they are.
A filter in a turned or skewed user space runs on a canvas whose axes are the
user space's. Its morphology radii, kernel units and blur deviations are now
measured in that canvas's pixels, and a length in the object's box against
the art's box on the canvas, which a skew can spread far wider than the art's
box in the raster. When one would span more than 32 or 512 canvas pixels,
the canvas runs on coarser pixels.
In a turned or skewed user space, the source is drawn onto the filter's
canvas pixels first and cut to the pixels it draws there, so the image
lies along the user space's axes. A region in objectBoundingBox units
(the default filterUnits) and primitive lengths with
primitiveUnits="objectBoundingBox" are then measured against the
object's box in that user space instead of the raster's box turned into
it.
SVG export and the image fallback keep a filter live only when SVG
import can store its user space again: scale and axes together can
scale it past 0.001 to 1000 points to a unit while each is valid alone
(scale 1000 with axes [2, 0, 0, 2]). Such an object is written as an
image. Import and export share the user-space check.
An SVG whose filtered element sits under a rotate, skew, uneven scale or
matrix transform now opens with the filter as a live Effect > SVG Filters
effect instead of losing it with a warning.
- The svg.filter effect takes an optional axes [a, b, c, d]: the document
directions of one unit along the filter's x and y axes, before scale.
effect.apply and effect.setParams refuse axes with an entry outside
-1000..1000 or a determinant within 0.001 of 0.
- With axes, the filter runs on a canvas lined up with its user space, so
offsets, blurs and the region run along the element's axes, and the
result is drawn back through axes. The canvas holds at most 4 times the
object's raster pixels. A region measured against the object's box uses
the object's box in that user space.
- SVG import stores the element's user space as scale, origin and axes.
- SVG export writes such a filter live: a group's transform holds the
user space, and the art is written in document coordinates in a group
with the inverse transform, so strokes keep their widths.
* CI: FreeBSD builds with two jobs
The nightly FreeBSD run has been killed for memory (exit 137) while
compiling the workspace's test targets, on both architectures, every
night since at least 9 November. Two rustc processes at a time fit in
the VM's 12 GB.
* CI: one FreeBSD build job at a time
With two jobs the engine and ui-egui test builds were still killed when
they compiled together.
The panel collected the objects for its nested rows from the document
as it is between commands, where the art of the stored brushes is not
set, so rows whose owner is a brush found no object and drew a blank
thumbnail. When an id is not found otherwise, the panel now sets that
art on a copy of the document, as links.list does, and collects the
objects from it. A recheck of the files at the same revision keeps the
objects collected before.
A computed name such as o[key], where key's toString returns a rope,
is flattened into a copy that only native code held. A getter or
setter that started a collection dropped that copy from the heap
estimate, so the live heap could pass the limit by one name per
nested access. Indexed reads, ++ and -- on an indexed property, and
Object.defineProperty now keep the converted name reachable while the
accessor runs.
The Japanese row in docs/localization-parity.md said every message is
translated, and the Japanese catalog line in docs/target-app-parity.md
said 38 messages were missing, one of them waiting on #7214, which has
merged. On main the untranslated report lists 98 messages without a
Japanese row, 77 of which every complete-message language lacks. Both
lines now give the counted rows and the report's count, and name the
open pull requests that translate part of them.
A block's line took the tallest ascent and deepest descent of its
characters, or the height of the stack's em boxes, whichever was larger.
The top block line's characters reach above the stack by their ascent
past the em box, and the bottom line's below it by their descent, so with
a wide Line Gap the line was too short for them. The line's ascent and
descent now also take in each character's reach from its own block line's
baseline.
- Outline Stroke on a graph's strokes, including Object > Expand with
Stroke on, adjusts the bounds the graph keeps, the same way
Create Outlines on its labels does. Before, the stroke outlines
changed the bounds of the art without type, and the next redraw
stretched the plot by the width the outlines added.
- A graph that keeps `placedArt` and has no art other than type left
is no longer measured on the bounds of all its art. A label edit on
such a graph moved and stretched the plot at the next redraw; the
plot now stays where it is.
- A redraw no longer measures a move or scale on art that has no width
or no height now, such as a graph left with one axis line. Before,
the plot collapsed to no width.
- A clipping group in a graph that holds type is measured on its clip
when the clip does not depend on type, so moving art outside the clip
does not change the bounds. Blends, envelopes and repeats are
measured whole, as they are drawn.
- The doc crate's helper is named `graph_art_without_type` and sits
with the file's other free functions.
- docs/mcp.md lists Outline Stroke and states that moving an outlined
label, a swatch, an axis or a tick mark on its own can move or scale
the plot, and that a graph left with only labels, or with art that
has no width or height, does not follow a move.
- Tests: a scale of the graph made before outlining a label, a move of
a graph opened from `.ai` after its label is restyled and moved,
Outline Stroke after a move, a graph left with only its labels or
with one line, and clipping groups holding type.
A WMF without a placeable box picks its scale from the map mode its
drawing records are played in. Lines and shapes drawn under R2_NOP or
R2_XORPEN, and PATBLT records the reader does not fill, no longer count,
with the mix mode saved and restored with SAVEDC and RESTOREDC.
An open stroke that reaches far outside the picture is left out before
it joins the strokes waiting to be joined, so the strokes drawn before
it are still added.
A fill in a glyph's clip marked the clip as filled before the fill was
added. When the fill painted nothing (a palette index past the palette,
or a radial gradient that draws no circle), the next glyph painted in
the same clip became the clip's only child, and closing the clip kept
that glyph on its own, so it drew outside the clip.
The clip is now marked filled only when the fill adds the clip's first
child, and a fill that adds nothing leaves the mark as it was.