The canvas kept the art of an image whose own fill or stroke follows the
outline of its pixels for as long as the image object stayed the same. When
the document's pixels for the image changed under the same key (Update Link
replacing a preview with the linked file's pixels), the stroke kept the old
outline while hit testing and Use Preview Bounds used the new one. The
renderer now keys that art by the document's pixels for the image too.
- vectorcraft-effects: `follows_image_pixels` names such images.
- vectorcraft-render: `reads_outside` counts them, and the resources key
hashes the address of the document's pixels for them; their walk is not
kept between frames.
- A test places an off-center opaque area in a smaller copy of the pixels
under a turned and reflected placement.
- Docs: the Outline Object params text names every case that keeps the frame
and the 50% cutoff as VectorCraft's own; docs/mcp.md's `effect.apply` entry
for Outline Object, how long an outline is kept and the 16-bit RGBA limit;
docs/target-app-parity.md's evidence lines.
An image's own fill or stroke with Outline Object now follows the outline of
the image's pixels that are at least 50% opaque, traced from the alpha and
fitted with curves, instead of the image's frame. An image without
transparency, one whose pixels can't be read, one of more than 64 megapixels
or whose decoded pixels take more than 256 MB, and one whose outline would
need more than 100,000 anchor points keep the frame. An image with no pixel
at least half opaque gives nothing to paint. Images of more than 4 megapixels
are traced from their alpha averaged down to 4 megapixels, and an averaged
pixel that covers a pixel at least half opaque stays at least half opaque, so
thin opaque lines stay in the outline. Each outline is traced once for its
pixels, kept for the next redraw while those pixels are loaded, and dropped
after them; a second thread that needs the same outline waits for the trace.
- vectorcraft-trace: `decode_alpha` reads an image's alpha, and
`opaque_outline` traces it as Black and White mode at threshold 128.
- vectorcraft-effects: the reshaped image art uses it for rows whose first
effect is Outline Object; Convert to Shape rows keep the frame.
- Docs: docs/mcp.md, the Outline Object params text and an evidence line in
docs/target-app-parity.md. docs/mcp.md also says that Use Preview Bounds
takes in the shapes an image's fills and strokes paint.
A selected image offers Remove Background in the Contextual Task Bar, Properties'
Quick Actions and the Control bar, as the reference app does. A click runs it at
once with its defaults, as one undo step; Object > Plug-ins > Image Tools keeps
the dialog with Preview.
A function an earlier run of a named engine defined was reported without
a line, column or file when it threw in a later run. The realm now gives
each source a tag that stays the same from run to run (Realm::error_tag,
Realm::script_tag), and no two sources share one once the tags run out.
Each named engine keeps the source maps of its runs' scripts, included
files and $.evalFile files, within 8 MiB, dropping the oldest first, and
an error in kept code is reported at that file, line and column. The
report's name and the console line keep the calling run's name. For an
earlier script given as source, file is that run's name.
Docs: docs/mcp.md (Script engines), script.run params text,
docs/target-app-parity.md.
The 3D and Materials row of docs/target-app-parity.md names Revolve
(Classic) with its options and surfaces among what ships, and its
evidence names the tests that cover it.
text.tabs.set takes a list of more than 256 stops when every paragraph it
targets already holds at least that many, so a paragraph loaded with more
stops can lose them one at a time (the Tabs panel's Delete Tab). Any
other list of more than 256 stops is still refused, counted as supplied
before stops at one position merge.
Docs: docs/mcp.md.
When a dynamic symbol is redefined or edited, each instance kept every
appearance change whose path still named an object, even when that
object is now one that draws no fill or stroke of its own (an image, a
blend, a mesh) or a symbol instance given a gradient or pattern fill.
symbol.instance.setAppearance refuses such a paint, but the change stayed
on the instance and still counted as a color the document uses.
Fitting the changes to the new art now also clears a fill or stroke the
object at that path does not draw, and drops a change left empty.
Coordinates outside -32,768 to 32,767 plotter units (about 82 cm from the origin) are written as they are, with a warning that older devices may not read them. HP-GL/2 plots are not checked against this range.
Effect > Refresh Deferred Effects looked up the objects asked for, the
stages reached, the objects drawn whole and the inputs that ran with
Vec::contains, and counted each target stage by scanning every deferred
record. Asking whether a stage stays deferred and replacing a stage's
records when it runs also scanned every record.
Deferrals::refresh now keeps the objects asked for and the objects drawn
whole in sets, and Refresh's ids, retried, visited and touched and
Pass.ran and seen are sets. The deferred records are kept in a BTreeMap
by the order they were made in, with an index by stage and input key, so
holds, State::remove, settle and the refresh's reconciliation and count
look at the records of the stages concerned only. The targets, counts,
records kept and their order, marks and revision are unchanged.
Docs: docs/target-app-parity.md.
Effect › 3D and Materials › 3D (Classic) › Rotate (Classic)… turns every
fill and stroke as one flat plane, as Rotate does, and shades it with the
classic No Shading or Diffuse surface.
- `effect.apply` with `threeD.classicRotate`: the Position rotation and
Perspective, `surface` (`none` or `diffuse`), the classic lights,
Ambient Light, Blend Steps and Shading Color. It has no highlight, no
Draw Hidden Faces and no shadow.
- The dialog shows Position on the Rotation tab and the surface and
lights on the Lighting tab, with no Object tab.
- Groups and layers turn about one shared center, and the effect also
goes on a fill or stroke, as Rotate's does.
- `effect.lightingPreset` refuses it, as it refuses the other classic
3D effects.
- Unknown parameters, numbers out of range, bad flags, a surface other
than No Shading or Diffuse and bad shading colors are refused with an
error.