The .fig import gave a file one decoded value per byte of its compressed canvas (at least 20M, at
most 128M). Dense legitimate files decode past that, further since every scalar field counts, and
the whole import was refused as "not a valid FigCraft file: .fig file: message: too many values".
The budget is now four values per compressed byte; the floor and both ceilings (128M, 32M on 32-bit
targets) are unchanged, so a small file that unpacks past the floor is still refused and no file
decodes more values than the ceiling allowed before. Generated 21 MB and 15 MB canvases (220,044
and 108,012 layers) and a 49.7 MB one budgeted at the ceiling (530,106 layers) now open whole
without warnings; the 49.7 MB one's test peaks at about 9 GB.
Background blurs and glass read the pixels drawn under them, and a full
render's backdrops end where the view does. The retained renderer differed
in two ways.
render_into drew each damage rect with a margin all round, past the edge
too, so a backdrop there read content a full render never drew: with a
background blur of 60 across the left edge, moving a square beside it
patched 10 levels off a full render, and moving one entirely off the view
89. The margin now stops at the edge.
A pan re-rendered only the strips it uncovered. At the opposite edges, which
moved into the old frame, the shifted pixels kept what their backdrop had
read past the old edge: a background blur of 10 across the view was 89
levels off after a pan of 30. Those edges are now redrawn as far as a
backdrop reads.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
paint_bounds, the area a change to a layer can affect, was its paint bounds
(effects included) grown again by effect_margin, what its effects read from
outside. Drawing an area already takes that in, as culling does, so the
damage of an edit near effects was counted twice: moving a 120 x 120
rectangle with a shadow falling 40 rendered 122,844 pixels for 56,876 it can
change, and edits that would fit a partial render fell back to full ones.
The retained test that a group's shadow had pushed past the partial share
gets its 300 x 220 view back.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* M8: opening a file contacts no team library server it names until you check it (#1097)
* M8: translate the team library check strings (#1097)
* M8: the Assets panel library test checks what allows a library, without its own fake link (Sonar duplication and coverage)
* M8: cap the people a client keeps track of and the deleted ids a session remembers (#1121)
A hostile host or server could grow a client's presence, seen-peers and who-is-here lists without bound, and a session's deleted-id set only grew. Clients keep at most MAX_PEERS (4,096) others, leaving newcomers out with a warning; max_people is at most that; a session remembers at most 262,144 deleted ids, the lowest forgotten first.
* M8: a max_people above what clients track is lowered with a warning, not refused (#1121)
Refusing it would stop a server whose existing config says more from starting after an upgrade. Config::people() lowers max_people to MAX_PEERS for the core's limits, and the startup warnings name the configured and the used value.
* M8: the live welcome's handling in its own function (Sonar S3776)
UPDATE_APP (native builds; craft-update is a native-only dependency) carries our 128 px icon and accent (#02da96, its colour in ArtCraft Launcher). The updater, the self-update
helper and craft-update's startup prompt all get them through crate::UPDATE_APP; the
prompt draws the icon, the accent and "by ArtCraft" (craft-update's default developer).
craft-update is pinned to storytold/craft-libs main at 1065653e7 (#434).
local_reach gave up on transforms whose determinant was under 1e-12 and
kept the reach in page units, so a layer scaled to a ten millionth (a
billion units drawn 100 wide) had its shadow cut (245 levels). It now
converts any finite, non-zero scale, capping the result where the sums
would overflow.
Groups and stroked text spread their shadows as pixels, in page units:
their spread no longer also counts in local units.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* M8: a large selection's overlay and Design panel values are kept for frames where nothing changed (#1571)
The selection's outlines, box, size and slots on the canvas, and the Design panel's instance checks and position values, are kept with the document snapshot (held weakly), the selection and, for the overlay, the view's mapping to the screen and the overlay green, and made again when any changes. Dragging 648 selected layers: overlays 1.99 to 0.86 ms a frame, Design panel 2.54 to 1.40 ms.
* M8: split the position fields into one function per row (Sonar S3776)