diff --git a/node-graph/libraries/vector-types/src/markers.rs b/node-graph/libraries/vector-types/src/markers.rs index 951bbeccce..54d3779e9e 100644 --- a/node-graph/libraries/vector-types/src/markers.rs +++ b/node-graph/libraries/vector-types/src/markers.rs @@ -15,6 +15,13 @@ core_types::attribute! { pub EditorClickTarget("editor:click_target"): Option<&crate::Vector>; } +// The value types a name-generic attribute can name here, so a compile-time +// named write or read reaches this crate's enums like any other plain value. +core_types::named_value! { + for crate::gradient::GradientSpreadMethod; + for crate::gradient::GradientType; +} + pub const ATTR_SPREAD_METHOD: &str = SpreadMethod::NAME; pub const ATTR_GRADIENT_TYPE: &str = GradientType::NAME; pub const ATTR_EDITOR_CLICK_TARGET: &str = EditorClickTarget::NAME; diff --git a/node-graph/nodes/graphic/src/graphic.rs b/node-graph/nodes/graphic/src/graphic.rs index 334175dad1..f978d0d43c 100644 --- a/node-graph/nodes/graphic/src/graphic.rs +++ b/node-graph/nodes/graphic/src/graphic.rs @@ -11,6 +11,7 @@ use graphic_types::graphic::{Graphic, IntoGraphicList}; use graphic_types::{ATTR_EDITOR_MERGED_LAYERS, Artboard, Vector}; use raster_types::{CPU, GPU, Raster}; +use vector_types::gradient::{GradientSpreadMethod, GradientType as GradientTypeValue}; use vector_types::{GradientStop, GradientStops, ReferencePoint}; /// Resolves a signed index over `total` lanes: negatives count from the end, @@ -387,22 +388,52 @@ pub fn write_attribute<'e, T, V: WireValue>( Ok((content, Attr(parked))) } -/// Reads the `f64` attribute `name` names off each lane. An absent attribute -/// reads as the name's own default, so the value is always a number; the name -/// is constant text the compiler folds into an offset when the graph compiles. -/// -/// A name written at another value type is a graph error rather than a -/// conversion, so reading a number is never a coercion of one. -#[node_macro::node(category("Attributes: Read"))] -pub fn read_number_attribute<'e, T>( - _: impl Ctx, - /// The content whose lanes carry the attribute; its element is never read. - (content, value): (T, Attr<'e, Named>), - /// The attribute name, folded into an offset when the graph compiles. - name: Named, -) -> f64 { - let _ = content; - *value +// The attribute reads: one node per value type, since a name means one type +// and there is no coercion between them. Each takes any record wire, never +// looks at its element, and serves the name's own default where the attribute +// is absent, so the value always carries the declared type. +// +// The name is constant text the compiler folds into an offset when the graph +// compiles; a name written at another value type is a graph error rather than +// a conversion. +macro_rules! attribute_reads { + ($($(#[$meta:meta])* $node:ident: $row:ty => $value:ty;)*) => { + $( + $(#[$meta])* + #[node_macro::node(category("Attributes: Read"))] + pub fn $node<'e, T>( + _: impl Ctx, + /// The content whose lanes carry the attribute; its element is never read. + (content, value): (T, Attr<'e, Named>), + /// The attribute name, folded into an offset when the graph compiles. + name: Named, + ) -> $value { + let _ = content; + *value + } + )* + }; +} + +attribute_reads! { + /// Reads a named `f64` attribute, such as `opacity` or `font_size`. + read_number_attribute: f64 => f64; + /// Reads a named `u64` attribute, such as a regex match's `start` or `end`. + read_integer_attribute: u64 => u64; + /// Reads a named `bool` attribute, such as `clipping_mask` or `clip`. + read_bool_attribute: bool => bool; + /// Reads a named `DVec2` attribute, such as an artboard's `location` or `dimensions`. + read_coordinate_attribute: DVec2 => DVec2; + /// Reads a named `DAffine2` attribute, such as `transform`. + read_transform_attribute: DAffine2 => DAffine2; + /// Reads a named `Color` attribute, such as an artboard's `background`. + read_color_attribute: Color => Color; + /// Reads a named `BlendMode` attribute, such as `blend_mode`. + read_blend_mode_attribute: core_types::blending::BlendMode => core_types::blending::BlendMode; + /// Reads a named gradient-shape attribute, such as `gradient_type`. + read_gradient_type_attribute: GradientTypeValue => GradientTypeValue; + /// Reads a named gradient-spread attribute, such as `spread_method`. + read_spread_method_attribute: GradientSpreadMethod => GradientSpreadMethod; } /// Joins two levels of the same type, the base's lanes followed by the new's.