Commit Graph

68 Commits

Author SHA1 Message Date
Dennis Kobert
149e1fc4e0 Carry eight dropped columns through flatten_graphic 2026-09-15 14:34:54 +02:00
Dennis Kobert
d4dc2e9e6b Adopt map_element in the mirror kernels 2026-09-15 14:34:30 +02:00
Dennis Kobert
c1704df0b3 Elide the arena lifetimes that the signatures do not need 2026-09-15 14:34:02 +02:00
Dennis Kobert
0a4288eca6 Read a named attribute at each value type it can hold
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>
2026-09-09 12:36:00 +00:00
Dennis Kobert
5baeb8fd46 Accept any record wire on an input read only for its attributes
An element generic declared on a reading input, absent from the output
and from every other input, has nowhere to go and nothing to be: the
node reads its declared attributes and never the element. That is an
attr-to-element map, so it accepts any upstream record wire.

The blessing is inferred rather than marked, since the signature already
says it. The two substrate pieces were both in place: the element rides
as the byte-carried token, so the registry takes one generic row instead
of a row per element type, and the reads resolve against the input's own
layout as they always have. Only the passthrough rule stood in the way,
in the three places that enforced it.

A generic the output carries, or one on an input with no reads, is
unchanged and still owes an implementations list.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-09-09 12:15:40 +00:00
Dennis Kobert
f04d439b33 Name the attribute read for the type it reads
The read is a number read, not a read of whatever the name holds: our
model has no coercion, so a name written at another value type is a graph
error rather than a conversion. The name says so.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-09-09 11:35:38 +00:00
Dennis Kobert
5eb80721dd Resolve a named read's offset when the graph compiles
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>
2026-09-09 10:50:08 +00:00
Dennis Kobert
fc94487d0b Keep the name placeholder out of the kernel entirely
A name input declares where a placeholder's name is wired and nothing
more. The name is spent resolving the layout when the graph compiles, so
the kernel neither declares it nor is passed it; the return type's
`Named<X, V>` is the only tie between the write slot and the folded name.

The wire is untouched: the input keeps its declared position and crosses
as constant text, so a document's input order is unchanged. The
placeholder stays a concrete token, so it adds no generic for the node
to carry and none to go unconstrained.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-09-09 10:20:22 +00:00
Dennis Kobert
9b92edc0e9 Write an attribute under a name the graph supplies
`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>
2026-09-09 09:26:17 +00:00
Dennis Kobert
9f0e0ebc96 Clear the remaining clippy warnings on the diff surface 2026-09-06 16:25:17 +00:00
Dennis Kobert
fbdba0e545 Drop narration and internal asides from comments 2026-09-06 15:59:41 +00:00
Dennis Kobert
9d3abe385f Sweep the data-flow wire and edge wording to input and source 2026-09-06 15:14:55 +00:00
Dennis Kobert
38d479bdfa Key the paint list park sites so a group-free paint moves 2026-09-05 13:12:17 +00:00
Dennis Kobert
30573e6eb6 Condense the narrative comments to their constraints 2026-09-05 13:12:17 +00:00
Dennis Kobert
a955d6b458 Run cargo fmt 2026-08-29 18:40:02 +00:00
Dennis Kobert
e5b910f840 Adopt serving lifetimes and the safe record surfaces in the node crates 2026-08-28 13:30:06 +00:00
Dennis Kobert
e8aea0728a Build native groups at the legacy conversion seams 2026-08-27 20:22:24 +00:00
Dennis Kobert
68a2fb2be3 Render root levels natively and remove the unconstructed stack form 2026-08-27 14:44:19 +00:00
Dennis Kobert
eb11eec5bb Store paint attributes in the paint markers' owned optional form 2026-08-26 14:02:01 +00:00
Dennis Kobert
ff99f3605c Drop unread index bounds from fold kernels and mark re-addressing nodes ModifyIndex 2026-08-25 11:05:38 +00:00
Dennis Kobert
9aef511891 Cargo fmt 2026-08-24 23:15:10 +02:00
Dennis Kobert
027218f16c Declare which index levels a node reads and nullify the rest 2026-08-24 17:06:07 +00:00
Dennis Kobert
dcc9059041 Give To Graphic a unit row so an unconnected content input renders as nothing 2026-08-24 12:02:46 +00:00
Dennis Kobert
d70eae205d Quiet the clippy type-complexity and closure lints on the record kernels 2026-08-24 11:07:14 +00:00
Dennis Kobert
ed6922d7eb Read the layer path in its owned form and retarget the introspection tests 2026-08-24 10:26:24 +00:00
Dennis Kobert
aba941e81d Collapse typed levels in To Graphic like the pre-flip list conversion 2026-08-24 01:35:32 +00:00
Dennis Kobert
8c67ad508f Restore pre-flip color parity: rng replay, typed wrap, boolean marker paints 2026-08-24 00:43:44 +00:00
Dennis Kobert
c0eb2ee4ff Remove the runtime-named attribute family and its type-erased bridges 2026-08-23 19:05:26 +00:00
Dennis Kobert
3fb8b10f80 Cache materialized spans per context and size emitter extents from the subject query 2026-08-23 00:57:37 +00:00
Dennis Kobert
c33f8ae75b Convert mirror to a fold emitter and bridge levels into the erased list 2026-08-22 22:15:03 +00:00
Dennis Kobert
f2b0f7c533 Defer an empty side's inner extent in extend 2026-08-22 19:11:48 +00:00
Dennis Kobert
4bceae26f2 Add the leveled fill rows and the graphic coercion entries 2026-08-22 16:13:01 +00:00
Dennis Kobert
fb71ea426d Bridge legacy seams and convert the transform family 2026-08-22 14:25:31 +00:00
Dennis Kobert
887dbaca2c Re-home the layer-path stamp and switch the node path to its plain value form 2026-08-22 12:35:48 +00:00
Dennis Kobert
56c772de4c Swap the map and index family nodes to their leveled forms in place 2026-08-22 12:27:53 +00:00
Dennis Kobert
93e34d00e5 Swap the graphic structural nodes to their leveled forms in place 2026-08-22 12:24:02 +00:00
Dennis Kobert
e4adf16eba Move the paint and merged-layer markers to graphic-types as optional references 2026-08-22 10:23:02 +00:00
Dennis Kobert
81a319430b Cut over to the graphene execution model 2026-07-31 23:19:42 +02:00
YohYamasaki
9f9899cfd0 Refactor the 'Fill' and 'Stroke' nodes to set "fill" and "stroke" attributes for paints (#4257)
* Allow using any graphics type for fill

* Adapt gradient/fill property panels and tools to handle List<T>

* Make the initial gradient transform covers the target's bounding box

* Introduce AnyGraphicListDyn to avoid combinatorial explosion

* Allow using any graphics type for stroke paint

* Add FIll node migration

* Add `for_each_vector_list_mut` instead of `set_paint_attribute`

* Adapt paint flow to read and write attributes instead of legacy Fill/Stroke.color

* Fix responsibilities of paint related node input setters

* Fix Morph by storing List<Graphic> for attributes rather than the concrete types

Store fill/stroke paints as List<Graphic> so Color/Gradient transitions
do not hit set_attribute_value_dyn's type-mismatch fallback to default paint.

* Preserve paint attributes in vector editing ops

* Enhance the clarity between direct and chained fill gradients

* Update demo arts

* Consolidate Fill node gradient appearance inputs

* Fix after the cubic review

* Revert "Consolidate Fill node gradient appearance inputs"

This reverts commit 9622feb20196e2c4da99e98ca95dcc2e34c2c98e.

* Replace AnyGraphicListDyn with generic paint connectors on the Fill and Stroke nodes

* Canonicalize paint attribute storage to List<Graphic> with a single write helper

* Fix Solidify Stroke missing fills stored in the legacy style

* Fix Solidify Stroke producing invisible strokes for legacy-only stroke colors

* Fix the initial gradient transform ignoring the bounding box's vertical extent

* Step paint at the morph midpoint instead of dropping it for unmixable pairings

* Remove migration-stage comments

* Clarify the initial gradient transform helper's doc and name

* Correct the bake_paint_transforms doc and prune dead tolerance arms

* Delete the unused Gradient::lerp

* Fix a comment typo

* Thread network paths through the legacy gradient bake so nested fills migrate

* Restore the legacy fill fallback in Expand Fill and Stroke

* Read gradient stops from the node's own input in the Fill properties panel

* Use the transform input constant instead of a hardcoded index

* Remove the unreachable wired color fallback in the Fill properties solid branch

* Narrow the fill overlay redraw check to actual fill inputs

* Coalesce the fill setter's graph runs into a single dispatch

* Position the Gradient Value node inserted for gradient stops

* Bake backup gradient placement during migration

* Persist pending gradient bakes so unfinished migrations retry on reopen

* Migrate the backup gradient's type and spread method

* Harden the gradient-migration pass against document switches and stale bakes

* Keep the Fill properties UI for layerless and nested Fill nodes

* Leave a wired gradient transform input connected instead of overwriting it

* Refuse to start a gradient chain ahead of existing layer content

* Decode a Fill node's gradient through one shared reader

* Nudge a degenerate bounding box so the Fill gradient transform stays invertible

* Broadcast Fill and Stroke paint with a single attribute-column pass

* Fix Morph stepping the target's stroke in near the source instead of the target

* Tidy conventions: clippy get_first, comment periods, sentence-case test messages

* Reattach the gradient orientation doc to its function

* Re-save demo artwork

---------

Co-authored-by: Keavon Chambers <keavon@keavon.com>
2026-07-04 23:08:21 +00:00
Keavon Chambers
f05a644bd9 Revamp the syntax to #[hard(a..b)] and #[soft(a..b)] bounds on node definitions (#4307)
* Revamp the syntax to #[hard(a..b)] and #[soft(a..b)] bounds on node definitions

* Address review feedback: error on empty bounds ranges and remove redundant count clamps

* Fix NaN transform from Repeat Array with a count of 1

* Remove redundant manual clamps already enforced by #[hard(...)] bounds
2026-07-03 18:48:58 -07:00
Jatin Bharti
5f100946f2 Add String[] as a graphic type for typography (#4141)
* feat: Render List<String> as raw paths in SVG and Vell mode

* chore: code review

* chore: change the hardcoded layout bounds to parley's

* chore: code review

* feat: Split text node to text_layer and text_to_vector node

* fix: CI fail because of difference in nature of Mac and github action

* chore: fix

* chore: replace FontStack as it got removed in parley 0.9

* chore: fmt

* chore: migrate the rendering as of new resource architechture

* chore: add text_layer node to text tool for testing

* code review

* Make boolean ops support the Text type

* chore: Move fallback_font_resource authority from editor to text node

* Fix 'Text Layer' node missing font dropdown

* Change node doc comments from Vec<T> to T[]

* Add migrations from the old Text node to Text -> Text to Vector

* Consolidate

* Rename the text attributes and reorder tilt to come before max_width/height

* Detect legacy Text nodes in the split migration by their trailing separate_glyphs input

* Code review

* Frame Text layer thumbnails by laying out their text for bounds

* Give Text layers click targets and selection outlines via collect_metadata

* Route Text tool through Text to Vector with fill, fixing editing-preview placement

---------

Co-authored-by: Keavon Chambers <keavon@keavon.com>
2026-06-19 19:39:52 +00:00
Keavon Chambers
34e0fd7757 Replace the 'Vec2 to Point' node with automatic conversion machinery (#4236)
* Replace the 'Vec2 to Point' node with an 'As Vector' node and automatic conversion

* Accept a Vec2 as content for the Wrap Graphic node

* Rename the type-assertion nodes from 'To' to 'As'

* Fix the Transform node reversing a Vec2 input's direction

* Fix text migration bug
2026-06-14 21:44:08 -07:00
Keavon Chambers
a28b9437aa Rename the "Table" type to "List" everywhere (#4133)
* Rename the "Table" type to "List" everywhere

* Fix a few missed ones

* Re-save demo artwork
2026-05-09 01:33:39 -07:00
Keavon Chambers
6b3e4757de Rename the Table type's "rows" -> "items" and "columns" -> "attributes" everywhere (#4130)
* Rename TableRow -> Item

* Rename row -> item and column -> attribute throughout

* Fix a few missed ones

* Format
2026-05-08 23:11:33 -07:00
Keavon Chambers
023cf1bedd Fix the 'Flatten Vector' node losing child layer transforms for the editor tools (#4116) 2026-05-06 04:35:23 -07:00
Keavon Chambers
644e9cf91e New nodes: 'Attach Attribute' and 'Read Attribute *' (#4100)
* New nodes: 'Zip Attribute' and 'Read Attribute {Vector, Number, Bool, String, Transform, Color, Blend Mode, Gradient Type, Spread Method}

* Cleanup

* Reduce type explosion
2026-05-05 04:03:41 -07:00
Keavon Chambers
a0d5f418d9 Replace Table<Table<Graphic>> with Table<Artboard> where Artboard is a type boundary newtype (#4093)
Replace Table<Table<Graphic>> with Table<Artboard> with Artboard as a type boundary newtype
2026-05-01 21:57:50 -07:00
Keavon Chambers
f52009b402 Fix hashing not being based on all attributes of Table (#4079)
* Fix hashing not being based on all attributes of Table

* Cover all attributes in Table PartialEq and CacheHash

---------
2026-04-29 04:37:51 -07:00
Keavon Chambers
ba63c26c62 Replace the Artboard struct with a Table<Table<Graphic>> shape (#4077)
* Replace the Artboard struct with a Table<Table<Graphic>> shape

* Remove the never-functional, seemingly unneeded migrate_type_descriptor_names due to typo

* Allow negative artboard sizes
2026-04-28 22:58:33 -07:00
Keavon Chambers
0847d7b0ab Centralize attribute strings in consts and rename "editor:layer" to "editor:layer_path" (#4076)
* Rename "editor:layer" to "editor:layer_path" and centralize it in a const

* Centralize "editor:merged_layers" in a const

* Centralize all other attributes in consts

* Rename consts with ATTR_ prefix

* Format
2026-04-28 21:53:30 -07:00