A block with the pins the caller resolved for it. In the document a pin is
its own entity owned by the block, so nothing about a block’s boundary can
be read off the block alone; the scope that draws it hands the set in, in
the order it wants them painted.
Snap a resized block rect to the grid. When is_block, the height is
further constrained to a valid block height (see snap_block_height) by
moving the dragged edge, so a block resizes in lockstep with its pin-pitch
lattice and never falls below the single-slot minimum. Without this the
height snaps to GRID_SIZE (a quarter pitch), so max_pin_slot only steps
every fourth grid row and the pins sub-step up and down against the moving edge.
The fixed edge stays put, keeping it grid-aligned.
Whether a resize also holds the block height to its 4-cell pitch, or just
snaps to the grid (ports, areas, images and text boxes have no pitch).
Clamp a corner-resize delta so resize_rect(bbox, mode, delta) keeps the
dragged corner within bounds (the fixed corner is assumed already inside),
so a resized icon can’t grow past its block.
Translate inner minimally so it lies within bounds — shifting, not
shrinking. On an axis where inner is larger than bounds, it is centered.
Used to keep a block’s icon inside the block.
Where a block’s icon lands when the block’s rect goes from old to new:
it rides the block’s center, then is shifted back inside if the block shrank
past it. Shared by the resize preview and the commit so the icon doesn’t jump
when the drag is released.
How many slots every pin shifts up when a block holding pins at offsets
is resized to new_height px, so the lowest pin keeps its bottom clearance
instead of blocking the resize. Bounded by the top margin (the smallest pin
offset) so the highest pin never rises above slot 0. Zero when the pins
already fit — i.e. only a height that would push the lowest pin out shifts
them.
If the corner-mode box resized (grown from bbox) is within radius of
the image’s intrinsic aspect (intrinsic_w / intrinsic_h), return the box
snapped so w/h == aspect exactly — the dragged corner projected onto the
aspect diagonal from the fixed corner; else None. Every point on that
diagonal has w/h == aspect by construction.