The renderer, metadata collection, hit testing, and clip-path reduction
all resolve a lane's paint as its own declared appearance or the
nearest ancestor's through the cascade, taking the first fill and
stroke coverages in one walk: the coverage's stroke parameters replace
the element-resident stroke, the paint cells' interior lists feed the
paint renderers, and the paint order reads off the coverage row order,
which the stroke nodes now place from their paint order input. The
paint overlay and its transmute dissolve into an inherited-appearance
parameter on the vector-level bodies, with the Render trait untouched.
Mask clones paint through a single black-fill appearance, and every
row-building node stamps the appearance beside the legacy markers it
still writes, so renders stay identical until the markers go.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
A paint row's opacity and fill-opacity attributes now fade the color it
contributes, and a color stack collapses to the one composited color
the SVG fast path emits: each pass mixes by its blend mode and then
composites source-over in straight alpha, with the alpha-only modes
moving only the backdrop's coverage. Gradient paints fade every emitted
stop the same way, on the SVG stop order and the vello ramp alike, and
a masker drops the fill half so it cannot reach the content clipped to
it. The blend-mode formula application lands beside the BlendMode enum,
with an overlay channel formula pinned as hard light with swapped
operands.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The fill's gradient placement input splits from one optional transform
into the has-transform toggle and a plain transform, so the toggle's
input name is fixed in the document format ahead of the transform
toggle's own arrival. An unset placement keeps the toggle's false
default and derives from the content's bounds at evaluation, which is
also the unbaked placeholder the deferred gradient bake probes for.
Documents saved with the optional form migrate by decomposing it, a
wired transform source keeping its connection marked explicit, and the
legacy fill migration now lands on the split shape directly.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The appearance cascade rides PaintReach beside the legacy paint push,
with the opposite arbitration: a lane's own declared appearance wins
wholesale and an undeclared lane inherits the nearest ancestor's, at
any depth, crossing the group boundaries the paint push resets at. A
fresh render entry starts bare, which is what clears the cascade for a
pattern's own content. Both flatten paths push a parent's declared
appearance into undeclared children without composing, pinned against
each other by a shared test. The appearance and paint markers move to
hand-written impls whose stored form is the bare value the appearance
writers use, collapsing an absent and an empty cell to the same
undeclared read at every seam.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The appearance promote carries the two-level sharing law the paint list
promote established: a group-free appearance moves its parked header
into the persistent region (once, however many lanes share it), a
paint-held group denies the move and clones through the Cow dispatch
that shares persistent interiors pointer for pointer, and stroke
parameter columns on a coverage deny nothing. Four regression tests pin
the move and share behavior, mirroring the paint promote suite.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Cover, Coverage, and Appearance mirror the upstream appearance model on
the record substrate with a 'static interior: the paint column stores
Graphic<'static>, and the appearance marker's value is Option<&Appearance>,
exactly as the Fill paint marker's is today. Stroke parameters ride the
coverage item as attributes elided at their defaults, with typed markers
whose defaults are pinned to Stroke::default() by test. The deep field
glue carries paint-held groups across the owned, resident, and
persistent seams as the paint list glue does.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
One read node per value type, mirroring master's read family. A name
means one value type, so there is no coercion between them: master's
number read silently widened integers, and these refuse instead, which
is the same rule the write side already enforces.
Each takes any record wire through the opaque reading input and serves
the name's own default where the attribute is absent, so the value
carries the declared type either way.
The gradient enums join the value-type rows now that a family exists to
read them at.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
An absent read of a name the census declares now serves that name's own
default rather than its value type's, which is the rule for a declared
name. The census stages it exactly as it fills any absent field, as the
declared default's bytes, so the read reuses the census's own mechanism
instead of a second one; the compiler takes them when the name folds and
`set_layout` installs them beside the offset.
A name the census does not declare keeps the value type's default, which
is that case's own rule. One name carries one value type, checked when
the name folds, so the row's value type and width agree with the read's.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The fold already holds the name and the read input's finished layout, so
the offset falls out there rather than at construction: `RecordLayout`
carries the resolved numbers and `set_layout` copies them into the read
slots. Constructors are untouched, and census-marker reads keep their
current installation.
A read meets the value type the name was written at, so a disagreement
between a read here and a write upstream is the same graph error as two
writes disagreeing; the one-name-one-type check now spans reads and
writes together. An absent attribute stays absent and the read serves
the forced default rather than reporting it.
`read_attribute` is the catalog's get half, typed and never `Option` at
the kernel boundary, with the name declared exactly as the write side
declares it.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The record fixtures spell their metas and resolved layouts out in full,
so the name-from-input fields reach them as empty. `named_value!`'s
example moves to `ignore`: its `for T` arm implements a core-types trait
on the value type, which only core-types itself may do.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
`Named<X>` in parameter position declares where a placeholder's name is
wired, and the macro gives that input constant text; `Attr<Named<X, V>>`
in the return writes under it. The kernel is handed the bare placeholder,
since the name is spent resolving the layout and a folded offset is all
the write needs, so the hot path matches a marker node's exactly.
A name-generic write names its value type through the wired generic,
which only an implementations row resolves, so those nodes emit their
layout meta per row rather than sharing one across rows.
`write_attribute` is the catalog's set half, restoring the identifier
master's documents carry with its input positions. Its name input is a
constant, so those documents resolve without migration, and the reset
marker that stood in for the missing node retires with it.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
An attribute's name and its value type separate: `AttrValue` declares
everything `Attribute` does except the name and its name-specific
default, and `Named<X, V>` pairs one with a name the graph supplies.
The value type stays concrete in the signature while the name varies
per instance, so a computed name has nowhere to come from.
`LayoutMeta` gains the name-from-input variant the fold consumes: a
`FieldWrite` template with every facet minted from the concrete type
and only the name left as a placeholder, plus the input position the
name's constant sits at. `fold_name` resolves one, preferring the
census row's descriptor where the name is declared so a known name
keeps its census default. `RecordLayout` carries the folded names so
`set_layout` can resolve offsets without a marker's `NAME`.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>