Rename GradientStops to Gradient and the legacy Gradient/Fill structs to LegacyGradient/LegacyFill

This commit is contained in:
Keavon Chambers
2026-07-20 15:27:21 -07:00
committed by Dennis Kobert
parent 149e1fc4e0
commit 9dd1e2bdf9
45 changed files with 296 additions and 300 deletions

View File

@@ -17,7 +17,7 @@ pub use dyn_any::StaticType;
pub use glam::{DAffine2, DVec2, IVec2, UVec2};
use graphene_application_io::resource::ResourceHash;
use graphic_types::raster_types::{CPU, Image, Raster};
use graphic_types::vector_types::vector::style::GradientStops;
use graphic_types::vector_types::vector::style::Gradient;
use graphic_types::vector_types::vector::{self, ReferencePoint};
use graphic_types::{Artboard, Graphic, Vector};
use rendering::RenderMetadata;
@@ -67,11 +67,11 @@ macro_rules! tagged_value {
#[serde(deserialize_with = "core_types::misc::migrate_to_optional_color")] // TODO: Eventually remove this migration document upgrade code
#[serde(alias = "ColorTable", alias = "OptionalColor", alias = "ColorNotInTable")]
Color(Option<Color>),
/// Stored compactly as a `GradientStops`, materializes as a single-row `List<GradientStops>` at runtime via `to_dynany`/`to_any`. Aliases recover legacy on-disk shapes.
/// Stored compactly as a `Gradient`, materializes as a single-row `List<Gradient>` at runtime via `to_dynany`/`to_any`. Aliases recover legacy on-disk shapes.
/// (Old documents that stored a full `Gradient` struct under this same `"Gradient"` tag are routed to `LegacyGradient` by `deserialize_tagged_value_with_legacy_migration`.)
#[serde(deserialize_with = "graphic_types::vector_types::gradient::migrate_to_gradient_stops")] // TODO: Eventually remove this migration document upgrade code
#[serde(deserialize_with = "graphic_types::vector_types::gradient::migrate_to_gradient")] // TODO: Eventually remove this migration document upgrade code
#[serde(alias = "GradientTable", alias = "GradientPositions", alias = "GradientStops")]
Gradient(GradientStops),
Gradient(Gradient),
/// Stored compactly as a `Vec<BrushStroke>`, materializes as `List<BrushStroke>` at runtime via `to_dynany`/`to_any`. Aliases recover legacy on-disk shapes.
#[serde(deserialize_with = "brush_nodes::migrations::migrate_to_brush_strokes")] // TODO: Eventually remove this migration document upgrade code
#[serde(alias = "BrushStrokeTable")]
@@ -160,7 +160,7 @@ macro_rules! tagged_value {
let list: List<Color> = color.into_iter().map(core_types::list::Item::new_from_element).collect();
Box::new(list)
}
Self::Gradient(stops) => Box::new(List::<GradientStops>::new_from_element(stops)),
Self::Gradient(stops) => Box::new(List::<Gradient>::new_from_element(stops)),
Self::BrushStrokes(strokes) => {
let list: List<BrushStroke> = strokes.into_iter().map(core_types::list::Item::new_from_element).collect();
Box::new(list)
@@ -207,7 +207,7 @@ macro_rules! tagged_value {
let list: List<Color> = color.into_iter().map(core_types::list::Item::new_from_element).collect();
Arc::new(list)
}
Self::Gradient(stops) => Arc::new(List::<GradientStops>::new_from_element(stops)),
Self::Gradient(stops) => Arc::new(List::<Gradient>::new_from_element(stops)),
Self::BrushStrokes(strokes) => {
let list: List<BrushStroke> = strokes.into_iter().map(core_types::list::Item::new_from_element).collect();
Arc::new(list)
@@ -248,7 +248,7 @@ macro_rules! tagged_value {
}
Self::F64Array(_) => concrete!(f64),
Self::Color(_) => concrete!(Color),
Self::Gradient(_) => concrete!(GradientStops),
Self::Gradient(_) => concrete!(Gradient),
Self::BrushStrokes(_) => concrete!(BrushStroke),
// =======================
// AUTO-GENERATED VARIANTS
@@ -297,7 +297,7 @@ macro_rules! tagged_value {
}
Self::F64Array(_) => leveled::<f64>(),
Self::Color(_) => leveled::<Color>(),
Self::Gradient(_) => leveled::<GradientStops>(),
Self::Gradient(_) => leveled::<Gradient>(),
Self::BrushStrokes(_) => leveled::<BrushStroke>(),
$( Self::$identifier(_) => scalar::<$ty>(), )*
Self::RenderOutput(_) => scalar::<RenderOutput>(),
@@ -443,14 +443,14 @@ macro_rules! tagged_value {
if name == core_types::normalize_type_name(std::any::type_name::<()>()) { return Some(TaggedValue::None) }
// List-wrapped types need a single-item default with the element's default, not an empty list
if name == core_types::normalize_type_name(std::any::type_name::<List<Color>>()) { return Some(TaggedValue::Color(Some(Color::default()))) }
if name == core_types::normalize_type_name(std::any::type_name::<List<GradientStops>>()) { return Some(TaggedValue::Gradient(GradientStops::default())) }
if name == core_types::normalize_type_name(std::any::type_name::<List<Gradient>>()) { return Some(TaggedValue::Gradient(Gradient::default())) }
$( if name == core_types::normalize_type_name(std::any::type_name::<$ty>()) { return Some(TaggedValue::$identifier(Default::default())) } )*
if name == core_types::normalize_type_name(std::any::type_name::<List<f64>>()) { return Some(TaggedValue::F64Array(Vec::new())) }
if name == core_types::normalize_type_name(std::any::type_name::<List<BrushStroke>>()) { return Some(TaggedValue::BrushStrokes(Vec::new())) }
// Leveled inputs type by their element; each element name maps to the
// same tagged default as its legacy list form.
if name == core_types::normalize_type_name(std::any::type_name::<Color>()) { return Some(TaggedValue::Color(Some(Color::default()))) }
if name == core_types::normalize_type_name(std::any::type_name::<GradientStops>()) { return Some(TaggedValue::Gradient(GradientStops::default())) }
if name == core_types::normalize_type_name(std::any::type_name::<Gradient>()) { return Some(TaggedValue::Gradient(Gradient::default())) }
if name == core_types::normalize_type_name(std::any::type_name::<BrushStroke>()) { return Some(TaggedValue::BrushStrokes(Vec::new())) }
if name == core_types::normalize_type_name(std::any::type_name::<Graphic>()) { return Some(TaggedValue::TypeDefault(core_types::descriptor!(List<Graphic>))) }
if name == core_types::normalize_type_name(std::any::type_name::<Artboard>()) { return Some(TaggedValue::TypeDefault(core_types::descriptor!(List<Artboard>))) }
@@ -540,7 +540,7 @@ tagged_value! {
DAffine2(DAffine2),
OptionalDAffine2(Option<DAffine2>),
#[serde(alias = "FillGradient")]
LegacyGradient(graphic_types::migrations::legacy::Gradient),
LegacyGradient(graphic_types::migrations::legacy::LegacyGradient),
Font(Font),
Footprint(Footprint),
VectorModification(Box<VectorModification>),
@@ -550,7 +550,7 @@ tagged_value! {
// ENUM TYPES
// ==========
#[serde(alias = "Fill")]
LegacyFill(graphic_types::migrations::legacy::Fill),
LegacyFill(graphic_types::migrations::legacy::LegacyFill),
BlendMode(core_types::blending::BlendMode),
LuminanceCalculation(raster_nodes::adjustments::LuminanceCalculation),
QRCodeErrorCorrectionLevel(vector_nodes::generator_nodes::QRCodeErrorCorrectionLevel),
@@ -648,11 +648,11 @@ impl TaggedValue {
None
}
fn to_gradient(input: &str) -> Option<GradientStops> {
fn to_gradient(input: &str) -> Option<Gradient> {
// String syntax: (e.g. "000000ff, ff0000ff")
let stops = input.split(',').filter_map(|s| to_color(s.trim())).collect::<Vec<_>>();
if stops.len() == 1 {
Some(GradientStops::new(vec![
Some(Gradient::new(vec![
GradientStop {
position: 0.,
midpoint: 0.5,
@@ -666,7 +666,7 @@ impl TaggedValue {
]))
} else if stops.len() >= 2 {
let step = 1. / (stops.len() - 1) as f64;
Some(GradientStops::new(stops.into_iter().enumerate().map(|(i, color)| GradientStop {
Some(Gradient::new(stops.into_iter().enumerate().map(|(i, color)| GradientStop {
position: i as f64 * step,
midpoint: 0.5,
color,
@@ -726,7 +726,7 @@ impl TaggedValue {
() if ty == TypeId::of::<List<Color>>() => to_color(string).map(|color| TaggedValue::Color(Some(color)))?,
// The Fill and Stroke nodes' paint connectors default to `List<Graphic>`, their first registered implementation row
() if ty == TypeId::of::<List<Graphic>>() => to_color(string).map(|color| TaggedValue::Color(Some(color)))?,
() if ty == TypeId::of::<List<GradientStops>>() => to_gradient(string).map(TaggedValue::Gradient)?,
() if ty == TypeId::of::<List<Gradient>>() => to_gradient(string).map(TaggedValue::Gradient)?,
() if ty == TypeId::of::<ReferencePoint>() => to_reference_point(string).map(TaggedValue::ReferencePoint)?,
_ => return None,
};
@@ -794,10 +794,10 @@ pub fn deserialize_tagged_value_with_legacy_migration<'de, D: serde::Deserialize
}
return Ok(MemoHash::new(TaggedValue::TypeDefault(descriptor!(List<Vector>))));
}
// The `Gradient` tag was reused: it used to carry a full `Gradient` struct (now `LegacyGradient`), and now carries an `Option<GradientStops>`.
// Disambiguate by payload shape: a Gradient struct has `start`/`end` keys; a `GradientStops` has none of those (it has `position`/`midpoint`/`color`).
// The `Gradient` tag was reused: it used to carry a full `Gradient` struct (now `LegacyGradient`), and now carries an `Option<Gradient>`.
// Disambiguate by payload shape: a Gradient struct has `start`/`end` keys; a `Gradient` has none of those (it has `position`/`midpoint`/`color`).
"Gradient" if content.as_object().is_some_and(|c| c.contains_key("start") && c.contains_key("end")) => {
let gradient: graphic_types::migrations::legacy::Gradient = serde_json::from_value(content.clone()).map_err(serde::de::Error::custom)?;
let gradient: graphic_types::migrations::legacy::LegacyGradient = serde_json::from_value(content.clone()).map_err(serde::de::Error::custom)?;
return Ok(MemoHash::new(TaggedValue::LegacyGradient(gradient)));
}
_ => {}

View File

@@ -140,7 +140,7 @@ fn node_registry() -> HashMap<ProtoNodeIdentifier, Vec<RegistryEntry>> {
"List<Raster<CPU>>",
"List<Raster<GPU>>",
"List<Color>",
"List<GradientStops>",
"List<Gradient>",
"List<String>",
])
.map(|(entry, target)| (ProtoNodeIdentifier::with_owned_string(format!("graphene_core::ops::ConvertNode<{target}>")), entry)),

View File

@@ -16,7 +16,7 @@ pub trait BoundingBox {
/// Returns the bounding box to use when sizing this value's thumbnail in the Layers panel.
///
/// Diverges from `bounding_box` for types where the rendering bounds wouldn't make a useful thumbnail frame.
/// For instance, `GradientStops` is `Infinite` for rendering but returns the line's AABB here, so a `List<Graphic>`
/// For instance, `Gradient` is `Infinite` for rendering but returns the line's AABB here, so a `List<Graphic>`
/// group of a gradient and a vector frames around the vector's geometry rather than infinity.
/// Types with no meaningful contribution (e.g., `Color`) return `Infinite` from both; the runtime substitutes a
/// small fallback rectangle at the end if no finite bounds remain after combining.

View File

@@ -13,7 +13,7 @@ use core_types::node::Node;
use core_types::record::{Group, GroupItem, LevelStatus, materialize_level};
use core_types::uuid::NodeId;
use glam::{DAffine2, DVec2};
use vector_types::GradientStops;
use vector_types::Gradient;
/// The outcome of materializing a leveled wire into a group.
// The group is the render path's success payload; boxing it would add a heap allocation per materialized level.
@@ -93,7 +93,7 @@ pub fn batch_to_legacy(layout: &core_types::record::Layout, batch: core_types::n
.or_else(|| typed::<Raster<CPU>>(&item))
.or_else(|| typed::<Raster<GPU>>(&item))
.or_else(|| typed::<Color>(&item))
.or_else(|| typed::<GradientStops>(&item))
.or_else(|| typed::<Gradient>(&item))
.or_else(|| typed::<String>(&item))
.or_else(|| typed::<f64>(&item))
.or_else(|| typed::<u64>(&item))

View File

@@ -6,7 +6,7 @@ use crate::markers::{ATTR_FILL, ATTR_STROKE};
use core_types::Color;
use core_types::list::{Item, List};
use raster_types::{CPU, GPU, Raster};
use vector_types::{GradientStops, Vector};
use vector_types::{Gradient, Vector};
/// One typed run as an owned list, elements cloned and every attribute copied
/// through its erased read. Content keeps its native form; the legacy
@@ -69,7 +69,7 @@ pub fn group_to_legacy_graphic(group: &core_types::record::Group) -> Graphic<'st
.or_else(|| run_to_legacy_list::<Raster<CPU>>(item).map(|list| detable_items(list, Graphic::RasterCPU)))
.or_else(|| run_to_legacy_list::<Raster<GPU>>(item).map(|list| detable_items(list, Graphic::RasterGPU)))
.or_else(|| run_to_legacy_list::<Color>(item).map(|list| detable_items(list, Graphic::Color)))
.or_else(|| run_to_legacy_list::<GradientStops>(item).map(|list| detable_items(list, Graphic::Gradient)))
.or_else(|| run_to_legacy_list::<Gradient>(item).map(|list| detable_items(list, Graphic::Gradient)))
.or_else(|| run_to_legacy_list::<String>(item).map(|list| detable_items(list, Graphic::Text)));
if let Some(typed) = typed {
return Graphic::Graphic(typed);
@@ -93,7 +93,7 @@ pub fn group_to_legacy_list(group: &core_types::record::Group) -> List<Graphic<'
.or_else(|| run_to_legacy_list::<Raster<CPU>>(item).map(|list| detable_items(list, Graphic::RasterCPU)))
.or_else(|| run_to_legacy_list::<Raster<GPU>>(item).map(|list| detable_items(list, Graphic::RasterGPU)))
.or_else(|| run_to_legacy_list::<Color>(item).map(|list| detable_items(list, Graphic::Color)))
.or_else(|| run_to_legacy_list::<GradientStops>(item).map(|list| detable_items(list, Graphic::Gradient)))
.or_else(|| run_to_legacy_list::<Gradient>(item).map(|list| detable_items(list, Graphic::Gradient)))
.or_else(|| run_to_legacy_list::<String>(item).map(|list| detable_items(list, Graphic::Text)))
.unwrap_or_default()
}

View File

@@ -24,7 +24,7 @@ use core_types::{ATTR_CLIPPING_MASK, ATTR_EDITOR_LAYER_PATH, ATTR_OPACITY, ATTR_
use dyn_any::DynAny;
use glam::{DAffine2, DVec2};
use raster_types::{CPU, GPU, Raster};
use vector_types::GradientStops;
use vector_types::Gradient;
pub use vector_types::Vector;
/// The possible forms of graphical content that can be rendered by the Render node into either an image or SVG syntax.
@@ -38,7 +38,7 @@ pub enum Graphic<'e> {
RasterCPU(Raster<CPU>),
RasterGPU(Raster<GPU>),
Color(Color),
Gradient(GradientStops),
Gradient(Gradient),
Text(String),
Group(core_types::record::Group<'e>),
}
@@ -101,7 +101,7 @@ into_graphic_element! {
RasterCPU: Raster<CPU>;
RasterGPU: Raster<GPU>;
Color: Color;
Gradient: GradientStops;
Gradient: Gradient;
Text: String;
}
@@ -146,9 +146,9 @@ impl From<Color> for Graphic<'_> {
}
// Note: List<Color> -> Option<Color> is in gcore (Color is defined there)
// GradientStops
impl From<GradientStops> for Graphic<'_> {
fn from(gradient: GradientStops) -> Self {
// Gradient
impl From<Gradient> for Graphic<'_> {
fn from(gradient: Gradient) -> Self {
Graphic::Gradient(gradient)
}
}
@@ -251,7 +251,7 @@ impl TryFromGraphic for Color {
}
}
impl TryFromGraphic for GradientStops {
impl TryFromGraphic for Gradient {
fn try_from_graphic(graphic: Graphic) -> Option<List<Self>> {
if let Graphic::Gradient(t) = graphic { Some(List::new_from_element(t)) } else { None }
}
@@ -306,7 +306,7 @@ impl IntoGraphicList for List<Color> {
}
}
impl IntoGraphicList for List<GradientStops> {
impl IntoGraphicList for List<Gradient> {
fn into_graphic_list(self) -> List<Graphic<'static>> {
detable_items(self, Graphic::Gradient)
}
@@ -612,7 +612,7 @@ mod graphic_is_opaque_tests {
Graphic::Color(color)
}
fn gradient_graphic(gradient: GradientStops) -> Graphic<'static> {
fn gradient_graphic(gradient: Gradient) -> Graphic<'static> {
Graphic::Gradient(gradient)
}
@@ -638,7 +638,7 @@ mod graphic_is_opaque_tests {
fn gradient_with_all_opaque_stops_is_opaque() {
let color_1 = Color::from_rgbaf32(1., 0., 0., 1.).unwrap();
let color_2 = Color::from_rgbaf32(1., 0., 0., 1.).unwrap();
let gradient = GradientStops::new(vec![
let gradient = Gradient::new(vec![
GradientStop {
position: 0.,
midpoint: 0.5,
@@ -658,7 +658,7 @@ mod graphic_is_opaque_tests {
fn gradient_with_transparent_stop_is_not_opaque() {
let color_1 = Color::from_rgbaf32(1., 0., 0., 0.5).unwrap();
let color_2 = Color::from_rgbaf32(1., 0., 0., 1.).unwrap();
let gradient = GradientStops::new(vec![
let gradient = Gradient::new(vec![
GradientStop {
position: 0.,
midpoint: 0.5,

View File

@@ -13,7 +13,7 @@ use core_types::uuid::NodeId;
use core_types::{ATTR_EDITOR_LAYER_PATH, ATTR_OPACITY, ATTR_OPACITY_FILL, ATTR_TRANSFORM, Color};
use glam::{DAffine2, DVec2};
use raster_types::{CPU, GPU, Raster};
use vector_types::{GradientStops, Vector};
use vector_types::{Gradient, Vector};
/// One run's attribute tokens, minted once so the lane loops read at an offset.
struct RunAttrs {
@@ -117,7 +117,7 @@ pub(in crate::graphic) fn group_bounding_box(group: &core_types::record::Group,
.or_else(|| typed_run::<Raster<CPU>>(item, transform, include_stroke, thumbnail))
.or_else(|| typed_run::<Raster<GPU>>(item, transform, include_stroke, thumbnail))
.or_else(|| typed_run::<Color>(item, transform, include_stroke, thumbnail))
.or_else(|| typed_run::<GradientStops>(item, transform, include_stroke, thumbnail))
.or_else(|| typed_run::<Gradient>(item, transform, include_stroke, thumbnail))
.or_else(|| typed_run::<String>(item, transform, include_stroke, thumbnail))
.unwrap_or(RenderBoundingBox::Infinite)
}
@@ -497,7 +497,7 @@ pub(in crate::graphic) fn group_render_complexity(group: &core_types::record::Gr
.or_else(|| typed_run::<Raster<CPU>>(item))
.or_else(|| typed_run::<Raster<GPU>>(item))
.or_else(|| typed_run::<Color>(item))
.or_else(|| typed_run::<GradientStops>(item))
.or_else(|| typed_run::<Gradient>(item))
.or_else(|| typed_run::<String>(item))
.unwrap_or(item.len())
}

View File

@@ -23,11 +23,11 @@ pub mod migrations {
use dyn_any::DynAny;
use glam::{DAffine2, DVec2};
use vector_types::vector::{PointDomain, RegionDomain, SegmentDomain, misc::HandleId, style::Stroke};
use vector_types::{GradientStops, Vector, vector};
use vector_types::{Gradient, Vector, vector};
#[derive(Default, Debug, Clone, PartialEq, graphene_hash::CacheHash, DynAny, serde::Serialize, serde::Deserialize)]
pub struct Gradient {
pub stops: GradientStops,
pub struct LegacyGradient {
pub stops: Gradient,
pub gradient_type: vector::style::GradientType,
pub start: DVec2,
pub end: DVec2,
@@ -39,11 +39,11 @@ pub mod migrations {
pub transform: DAffine2,
}
impl Gradient {
impl LegacyGradient {
/// Converts a legacy bounding-box-relative gradient (`start`/`end` in [0,1]) into an absolute one in the geometry's local space.
/// `bounding_box` maps [0,1] onto the geometry's bounding box; `layer_transform` is the layer's own transform,
/// used to bake the elliptical adjustment that reproduces the legacy isotropic radial through a non-uniform layer.
pub fn to_absolute(&self, bounding_box: DAffine2, layer_transform: DAffine2) -> Gradient {
pub fn to_absolute(&self, bounding_box: DAffine2, layer_transform: DAffine2) -> LegacyGradient {
let start = bounding_box.transform_point2(self.start);
let end = bounding_box.transform_point2(self.end);
let direction = end - start;
@@ -66,7 +66,7 @@ pub mod migrations {
DAffine2::IDENTITY
};
Gradient {
LegacyGradient {
start,
end,
transform,
@@ -83,15 +83,15 @@ pub mod migrations {
}
#[derive(Default, Debug, Clone, PartialEq, graphene_hash::CacheHash, DynAny, serde::Serialize, serde::Deserialize)]
pub enum Fill {
pub enum LegacyFill {
#[default]
None,
Solid(Color),
Gradient(Gradient),
Gradient(LegacyGradient),
}
/// The legacy `fill` field is intentionally omitted because vector payload migration only
/// recovers editable vector data. The fill/stroke paints are migrated from the the node inputs.
/// recovers editable vector data. The fill/stroke paints are migrated from the node inputs.
#[derive(serde::Deserialize)]
#[cfg_attr(test, derive(Default, serde::Serialize))]
pub(super) struct PathStyle {
@@ -165,7 +165,7 @@ pub mod migrations {
.unwrap()
.as_object_mut()
.unwrap()
.insert("fill".into(), serde_json::to_value(legacy::Fill::default()).unwrap());
.insert("fill".into(), serde_json::to_value(legacy::LegacyFill::default()).unwrap());
let migrated = migrate_to_optional_vector(value).unwrap().unwrap();
assert_eq!(migrated.stroke.unwrap().weight, 12.);

View File

@@ -11,7 +11,7 @@ use graphic_types::vector_types::gradient::GradientType;
use graphic_types::vector_types::markers::{GradientType as GradientTypeAttr, SpreadMethod};
use graphic_types::vector_types::vector::style::{PaintOrder, Stroke, StrokeAlign, StrokeCap, StrokeJoin};
use std::fmt::Write;
use vector_types::GradientStops;
use vector_types::Gradient;
use vector_types::gradient::GradientSpreadMethod;
#[derive(Copy, Clone, PartialEq)]
@@ -83,7 +83,7 @@ impl RenderExt for List<Color> {
}
}
impl RenderExt for List<GradientStops> {
impl RenderExt for List<Gradient> {
type Output = u64;
/// Adds the gradient def through mutating the first argument, returning the gradient ID.
@@ -103,7 +103,7 @@ impl RenderExt for List<GradientStops> {
/// Adds the gradient def through mutating `svg_defs`, returning the gradient
/// ID, over any gradient lane source.
pub fn render_gradient_paint<S: core_types::lane::LaneSource<Element = GradientStops>>(source: &S, svg_defs: &mut String, item_transform: DAffine2, element_transform: DAffine2) -> u64 {
pub fn render_gradient_paint<S: core_types::lane::LaneSource<Element = Gradient>>(source: &S, svg_defs: &mut String, item_transform: DAffine2, element_transform: DAffine2) -> u64 {
let mut stop = String::new();
{

View File

@@ -26,7 +26,7 @@ use graphene_resource::Resource;
use graphic_types::graphic::{PaintColumns, PaintOverlay, PaintReach, has_paint, is_paint_present, paint_graphics, set_paint_attribute, vector_can_reduce_to_clip_path};
use graphic_types::markers::{EditorMergedLayers, Fill, Stroke};
use graphic_types::raster_types::{BitmapMut, CPU, GPU, Image, Raster, Texture};
use graphic_types::vector_types::gradient::{GradientStops, GradientType};
use graphic_types::vector_types::gradient::{Gradient, GradientType};
use graphic_types::vector_types::markers::{GradientType as GradientTypeAttr, SpreadMethod};
use graphic_types::vector_types::subpath::Subpath;
use graphic_types::vector_types::vector::click_target::{ClickTarget, FreePoint};
@@ -400,7 +400,7 @@ pub(crate) fn gradient_placement(transform: DAffine2, gradient_type: GradientTyp
}
}
fn create_peniko_gradient_brush<S: LaneSource<Element = GradientStops>>(gradient_list: &S, multiplied_transform: &DAffine2) -> Option<(peniko::Brush, DAffine2)> {
fn create_peniko_gradient_brush<S: LaneSource<Element = Gradient>>(gradient_list: &S, multiplied_transform: &DAffine2) -> Option<(peniko::Brush, DAffine2)> {
let stops = gradient_list.element(0)?;
let gradient_type: GradientType = gradient_list.attr::<GradientTypeAttr>(0);
@@ -694,7 +694,7 @@ fn collect_group_row_metadata(group: &Group, metadata: &mut RenderMetadata, elem
.or_else(|| lane_zero_transform::<Raster<CPU>>(item))
.or_else(|| lane_zero_transform::<Raster<GPU>>(item))
.or_else(|| lane_zero_transform::<Color>(item))
.or_else(|| lane_zero_transform::<GradientStops>(item))
.or_else(|| lane_zero_transform::<Gradient>(item))
.or_else(|| lane_zero_transform::<String>(item));
if let Some(transform) = transform {
metadata.local_transforms.insert(element_id, transform);
@@ -741,7 +741,7 @@ fn render_group_svg<'a>(group: &'a Group, reach: PaintReach<'a>, render: &mut Sv
} else if item.typed_lanes::<Raster<GPU>>().is_some() {
} else if let Some(run) = RunView::<Color>::new(item) {
render_color_svg(&run, render, render_params)
} else if let Some(run) = RunView::<GradientStops>::new(item) {
} else if let Some(run) = RunView::<Gradient>::new(item) {
render_gradient_svg(&run, render, render_params)
} else if let Some(run) = RunView::<String>::new(item) {
render_text_svg(&run, render, render_params)
@@ -763,7 +763,7 @@ fn render_group_vello<'a>(group: &'a Group, reach: PaintReach<'a>, scene: &mut S
render_raster_gpu_vello(&run, scene, transform, context, render_params)
} else if let Some(run) = RunView::<Color>::new(item) {
render_color_vello(&run, scene, render_params)
} else if let Some(run) = RunView::<GradientStops>::new(item) {
} else if let Some(run) = RunView::<Gradient>::new(item) {
render_gradient_vello(&run, scene, transform, render_params)
} else if let Some(run) = RunView::<String>::new(item) {
render_text_vello(&run, scene, transform, render_params)
@@ -786,7 +786,7 @@ fn collect_group_metadata<'a>(group: &'a Group, reach: PaintReach<'a>, metadata:
collect_raster_metadata(&run, metadata, footprint, element_id)
} else if let Some(run) = RunView::<Raster<GPU>>::new(item) {
collect_raster_metadata(&run, metadata, footprint, element_id)
} else if item.typed_lanes::<Color>().is_some() || item.typed_lanes::<GradientStops>().is_some() {
} else if item.typed_lanes::<Color>().is_some() || item.typed_lanes::<Gradient>().is_some() {
} else if let Some(run) = RunView::<String>::new(item) {
collect_text_metadata(&run, metadata, footprint, element_id)
}
@@ -2282,7 +2282,7 @@ impl Render for List<Color> {
}
}
fn render_gradient_svg<S: LaneSource<Element = GradientStops>>(source: &S, render: &mut SvgRender, render_params: &RenderParams) {
fn render_gradient_svg<S: LaneSource<Element = Gradient>>(source: &S, render: &mut SvgRender, render_params: &RenderParams) {
// For thumbnails the gradient fills a finite rect at the footprint's document space bounds, with a 1-unit margin to cover the `as u32` truncation of `Footprint::resolution`.
// The viewBox crops the overshoot. Canvas rendering keeps the polyline path since Chrome rejects rects larger than ~20 million.
let thumbnail_rect = if render_params.thumbnail {
@@ -2374,7 +2374,7 @@ fn render_gradient_svg<S: LaneSource<Element = GradientStops>>(source: &S, rende
}
}
fn render_gradient_vello<S: LaneSource<Element = GradientStops>>(source: &S, scene: &mut Scene, parent_transform: DAffine2, render_params: &RenderParams) {
fn render_gradient_vello<S: LaneSource<Element = Gradient>>(source: &S, scene: &mut Scene, parent_transform: DAffine2, render_params: &RenderParams) {
use vello::peniko;
if let RenderMode::Outline = render_params.render_mode {
@@ -2458,7 +2458,7 @@ fn render_gradient_vello<S: LaneSource<Element = GradientStops>>(source: &S, sce
}
}
impl Render for List<GradientStops> {
impl Render for List<Gradient> {
fn render_svg(&self, render: &mut SvgRender, render_params: &RenderParams) {
render_gradient_svg(self, render, render_params)
}
@@ -2926,7 +2926,7 @@ impl Render for RunView<'_, Color> {
}
}
impl Render for RunView<'_, GradientStops> {
impl Render for RunView<'_, Gradient> {
fn render_svg(&self, render: &mut SvgRender, render_params: &RenderParams) {
render_gradient_svg(self, render, render_params)
}

View File

@@ -17,10 +17,10 @@ pub enum GradientType {
// TODO: Someday we could switch this to a Box[T] to avoid over-allocation
/// A list of colors (linear, unassociated alpha) associated with positions (in the range 0 to 1) along a gradient.
///
/// Not exposed via Tsify; use [`GradientStopsUI`] at the JS boundary.
/// Not exposed via Tsify; use [`GradientUI`] at the JS boundary.
#[derive(Debug, Clone, PartialEq, graphene_hash::CacheHash, DynAny)]
#[cfg_attr(feature = "serde", derive(serde::Serialize))]
pub struct GradientStops {
pub struct Gradient {
/// The position of this stop, a factor from 0-1 along the length of the full gradient.
pub position: Vec<f64>,
/// The midpoint to the right of this stop, a factor from 0-1 along the distance to the next stop. The final stop's midpoint is ignored.
@@ -29,18 +29,18 @@ pub struct GradientStops {
pub color: Vec<Color>,
}
/// JS-boundary version of [`GradientStops`] where stop colors are [`SRGBA8`] byte triples instead of linear-light [`Color`].
/// JS-boundary version of [`Gradient`] where stop colors are [`SRGBA8`] byte triples instead of linear-light [`Color`].
#[cfg_attr(feature = "wasm", derive(tsify::Tsify), tsify(from_wasm_abi))]
#[derive(Debug, Clone, PartialEq, Default, DynAny)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct GradientStopsUI {
pub struct GradientUI {
pub position: Vec<f64>,
pub midpoint: Vec<f64>,
pub color: Vec<SRGBA8>,
}
impl From<&GradientStops> for GradientStopsUI {
fn from(s: &GradientStops) -> Self {
impl From<&Gradient> for GradientUI {
fn from(s: &Gradient) -> Self {
Self {
position: s.position.clone(),
midpoint: s.midpoint.clone(),
@@ -49,8 +49,8 @@ impl From<&GradientStops> for GradientStopsUI {
}
}
impl From<&GradientStopsUI> for GradientStops {
fn from(s: &GradientStopsUI) -> Self {
impl From<&GradientUI> for Gradient {
fn from(s: &GradientUI) -> Self {
Self {
position: s.position.clone(),
midpoint: s.midpoint.clone(),
@@ -59,7 +59,7 @@ impl From<&GradientStopsUI> for GradientStops {
}
}
impl GradientStopsUI {
impl GradientUI {
/// CSS `linear-gradient(...)` string. Stops are emitted as `#rrggbbaa` hex (already gamma-encoded bytes).
pub fn to_css_linear_gradient(&self) -> String {
if self.position.len() <= 1 {
@@ -67,7 +67,7 @@ impl GradientStopsUI {
return format!("linear-gradient(to right, #{hex} 0%, #{hex} 100%)");
}
// Sample via the midpoint-aware subdivision used for SVG/Vello stops so browser interpolation matches
let stops: GradientStops = self.into();
let stops: Gradient = self.into();
let pieces = stops
.interpolated_samples()
.into_iter()
@@ -83,7 +83,7 @@ impl GradientStopsUI {
}
// TODO: Eventually remove this migration document upgrade code
impl<'de> serde::Deserialize<'de> for GradientStops {
impl<'de> serde::Deserialize<'de> for Gradient {
fn deserialize<D: serde::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
#[derive(serde::Deserialize)]
struct NewFormat {
@@ -117,7 +117,7 @@ impl<'de> serde::Deserialize<'de> for GradientStops {
}
}
impl Default for GradientStops {
impl Default for Gradient {
fn default() -> Self {
Self {
position: vec![0., 1.],
@@ -127,7 +127,7 @@ impl Default for GradientStops {
}
}
impl RenderComplexity for GradientStops {
impl RenderComplexity for Gradient {
fn render_complexity(&self) -> usize {
1
}
@@ -158,7 +158,7 @@ pub struct GradientStop {
}
pub struct GradientStopsIter<'a> {
stops: &'a GradientStops,
stops: &'a Gradient,
index: usize,
}
@@ -187,7 +187,7 @@ impl<'a> Iterator for GradientStopsIter<'a> {
impl ExactSizeIterator for GradientStopsIter<'_> {}
impl<'a> IntoIterator for &'a GradientStops {
impl<'a> IntoIterator for &'a Gradient {
type Item = GradientStop;
type IntoIter = GradientStopsIter<'a>;
@@ -196,7 +196,7 @@ impl<'a> IntoIterator for &'a GradientStops {
}
}
impl IntoIterator for GradientStops {
impl IntoIterator for Gradient {
type Item = GradientStop;
type IntoIter = std::vec::IntoIter<GradientStop>;
@@ -211,7 +211,7 @@ impl IntoIterator for GradientStops {
}
}
impl GradientStops {
impl Gradient {
pub fn new(stops: impl IntoIterator<Item = GradientStop>) -> Self {
let mut position = Vec::new();
let mut midpoint = Vec::new();
@@ -465,7 +465,7 @@ impl GradientStops {
let color = a.color.lerp(&b.color, time as f32);
GradientStop { position, midpoint: 0.5, color }
});
GradientStops::new(stops)
Gradient::new(stops)
}
}
@@ -540,19 +540,19 @@ pub fn initial_gradient_transform_for_bounding_box(bounds: [DVec2; 2]) -> DAffin
}
// TODO: Eventually remove this migration document upgrade code
pub fn migrate_to_gradient_stops<'de, D: serde::Deserializer<'de>>(deserializer: D) -> Result<GradientStops, D::Error> {
pub fn migrate_to_gradient<'de, D: serde::Deserializer<'de>>(deserializer: D) -> Result<Gradient, D::Error> {
use serde::Deserialize;
#[derive(serde::Deserialize)]
struct LegacyTable {
#[serde(alias = "instances", alias = "instance")]
element: Vec<GradientStops>,
element: Vec<Gradient>,
}
#[derive(serde::Deserialize)]
#[cfg_attr(feature = "serde", serde(untagged))]
enum GradientStopsFormat {
Stops(GradientStops),
Stops(Gradient),
List(LegacyTable),
}
@@ -562,7 +562,7 @@ pub fn migrate_to_gradient_stops<'de, D: serde::Deserializer<'de>>(deserializer:
})
}
impl core_types::bounds::BoundingBox for GradientStops {
impl core_types::bounds::BoundingBox for Gradient {
fn bounding_box(&self, _transform: DAffine2, _include_stroke: bool) -> core_types::bounds::RenderBoundingBox {
core_types::bounds::RenderBoundingBox::Infinite
}

View File

@@ -9,7 +9,7 @@ pub mod vector;
// Re-export commonly used types at the crate root
pub use core_types as gcore;
pub use gradient::{GradientSpreadMethod, GradientStop, GradientStops, GradientType};
pub use gradient::{Gradient, GradientSpreadMethod, GradientStop, GradientType};
pub use markers::{ATTR_EDITOR_CLICK_TARGET, ATTR_GRADIENT_TYPE, ATTR_SPREAD_METHOD};
pub use math::{QuadExt, RectExt};
pub use subpath::Subpath;

View File

@@ -10,7 +10,7 @@ use std::f64::consts::{PI, TAU};
/// Describes an editable fill choice, storing color or gradient stops without gradient placement metadata.
///
/// Can be None, a solid [Color], or a linear/radial [GradientStops].
/// Can be None, a solid [Color], or a linear/radial [Gradient].
///
/// In the future we'll probably also add a pattern fill.
///
@@ -22,11 +22,11 @@ pub enum FillChoice {
#[default]
None,
Solid(Color),
Gradient(GradientStops),
Gradient(Gradient),
}
// TODO: Deprecate [`FillChoice`] and keep this, renamed, as the main widget-controlling type
/// JS-boundary version of [`FillChoice`] where the solid color is [`SRGBA8`] and the gradient is [`GradientStopsUI`].
/// JS-boundary version of [`FillChoice`] where the solid color is [`SRGBA8`] and the gradient is [`GradientUI`].
#[cfg_attr(feature = "wasm", derive(tsify::Tsify), tsify(from_wasm_abi))]
#[derive(Default, Debug, Clone, PartialEq, DynAny)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
@@ -34,7 +34,7 @@ pub enum FillChoiceUI {
#[default]
None,
Solid(SRGBA8),
Gradient(GradientStopsUI),
Gradient(GradientUI),
}
impl From<&FillChoice> for FillChoiceUI {
@@ -42,7 +42,7 @@ impl From<&FillChoice> for FillChoiceUI {
match value {
FillChoice::None => Self::None,
FillChoice::Solid(color) => Self::Solid(SRGBA8::from(*color)),
FillChoice::Gradient(stops) => Self::Gradient(GradientStopsUI::from(stops)),
FillChoice::Gradient(stops) => Self::Gradient(GradientUI::from(stops)),
}
}
}
@@ -52,7 +52,7 @@ impl From<&FillChoiceUI> for FillChoice {
match value {
FillChoiceUI::None => Self::None,
FillChoiceUI::Solid(srgba) => Self::Solid(Color::from(*srgba)),
FillChoiceUI::Gradient(stops) => Self::Gradient(GradientStops::from(stops)),
FillChoiceUI::Gradient(stops) => Self::Gradient(Gradient::from(stops)),
}
}
}
@@ -63,7 +63,7 @@ impl FillChoiceUI {
Some(*c)
}
pub fn as_gradient(&self) -> Option<&GradientStopsUI> {
pub fn as_gradient(&self) -> Option<&GradientUI> {
let Self::Gradient(g) = self else { return None };
Some(g)
}
@@ -88,7 +88,7 @@ impl FillChoice {
Some(*color)
}
pub fn as_gradient(&self) -> Option<&GradientStops> {
pub fn as_gradient(&self) -> Option<&Gradient> {
let Self::Gradient(gradient) = self else { return None };
Some(gradient)
}

View File

@@ -598,7 +598,7 @@ mod tests {
async fn rasterize<T: Send + Clone>(
_: impl Ctx,
_: (),
#[implementations(List<Vector>, List<Raster<CPU>>, List<Graphic>, List<Color>, List<GradientStops>)] data: List<T>,
#[implementations(List<Vector>, List<Raster<CPU>>, List<Graphic>, List<Color>, List<Gradient>)] data: List<T>,
footprint: Footprint,
canvas: CanvasHandle,
) -> (Raster<CPU>, Attr<Transform>, OwnedAttr<EditorMergedLayers>) {
@@ -607,7 +607,7 @@ mod tests {
),
);
assert!(entries.contains("fn rasterize_entries"), "a registrable record-io source must emit its entries fn");
for element in ["Vector", "Raster < CPU >", "Graphic", "Color", "GradientStops"] {
for element in ["Vector", "Raster < CPU >", "Graphic", "Color", "Gradient"] {
let row = format!("record_source_type :: < List < {element} > > ()");
assert!(entries.contains(&row), "the implementations row {element} is missing: {entries}");
}

View File

@@ -2186,10 +2186,10 @@ mod tests {
#[implementations(
() -> List<Raster<CPU>>,
() -> List<Color>,
() -> List<GradientStops>,
() -> List<Gradient>,
Footprint -> List<Raster<CPU>>,
Footprint -> List<Color>,
Footprint -> List<GradientStops>,
Footprint -> List<Gradient>,
)]
image: impl Node<F, Output = T>,
) -> T {

View File

@@ -3,7 +3,7 @@ use core_types::list::List;
use core_types::transform::Footprint;
use core_types::{CacheHash, Color, Context, Ctx, DeriveCtx, ExtractAnimationTime, ExtractPointerPosition, ExtractRealTime};
use glam::{DAffine2, DVec2};
use graphic_types::vector_types::GradientStops;
use graphic_types::vector_types::Gradient;
use graphic_types::{Artboard, Graphic, Vector};
use raster_types::{CPU, GPU, Raster};
@@ -80,7 +80,7 @@ fn quantize_real_time<T>(
Context -> List<Raster<GPU>>,
Context -> List<Color>,
Context -> List<Artboard>,
Context -> List<GradientStops>,
Context -> List<Gradient>,
Context -> List<String>,
Context -> List<f64>,
Context -> (),
@@ -120,7 +120,7 @@ fn quantize_animation_time<T>(
Context -> List<Raster<GPU>>,
Context -> List<Color>,
Context -> List<Artboard>,
Context -> List<GradientStops>,
Context -> List<Gradient>,
Context -> List<String>,
Context -> List<f64>,
Context -> (),

View File

@@ -3,7 +3,7 @@ use core_types::list::List;
use core_types::{Color, ExtractVarArgs};
use core_types::{Ctx, ExtractIndex, ExtractIndices, ExtractPosition};
use glam::DVec2;
use graphic_types::vector_types::GradientStops;
use graphic_types::vector_types::Gradient;
use graphic_types::{Graphic, Vector};
use raster_types::{CPU, Raster};
@@ -40,7 +40,7 @@ fn read_color(ctx: impl Ctx + ExtractVarArgs) -> List<Color> {
}
#[node_macro::node(category("Context"), path(graphene_core::vector))]
fn read_gradient(ctx: impl Ctx + ExtractVarArgs) -> List<GradientStops> {
fn read_gradient(ctx: impl Ctx + ExtractVarArgs) -> List<Gradient> {
let Ok(var_arg) = ctx.vararg(0) else { return Default::default() };
let var_arg = var_arg as &dyn std::any::Any;
@@ -111,12 +111,12 @@ fn read_color_row_extent<C: Ctx + ExtractVarArgs>(_: &ReadColorRowNode, ctx: &C,
/// Rank-model vararg source: the mapped row's items as lanes, elements only.
#[node_macro::node(category("Test"), extent_raw(read_gradient_row_extent))]
pub fn read_gradient_row(ctx: impl Ctx + ExtractVarArgs + ExtractIndex) -> Result<IList<GradientStops>, Interrupt> {
pub fn read_gradient_row(ctx: impl Ctx + ExtractVarArgs + ExtractIndex) -> Result<IList<Gradient>, Interrupt> {
vararg_element(ctx)
}
fn read_gradient_row_extent<C: Ctx + ExtractVarArgs>(_: &ReadGradientRowNode, ctx: &C, level: u8) -> GPoll<Extent> {
vararg_lanes::<GradientStops>(ctx, level)
vararg_lanes::<Gradient>(ctx, level)
}
#[node_macro::node(category("Context"), path(core_types::vector))]

View File

@@ -13,7 +13,7 @@ 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};
use vector_types::{Gradient, GradientStop, ReferencePoint};
/// Resolves a signed index over `total` lanes: negatives count from the end,
/// out of range resolves to nothing.
@@ -100,7 +100,7 @@ fn omit_element_extent(list: ExtentIn<'_>, index: ValueIn<'_, f64>, level: Level
pub fn extract_element<T: Clone + Default + Send + Sync + CacheHash + 'static>(
_: impl Ctx,
/// The `List` of data to extract from.
#[implementations(String, f64, NodeId, Color, GradientStops, Vector, Raster<CPU>, Graphic, Artboard)]
#[implementations(String, f64, NodeId, Color, Gradient, Vector, Raster<CPU>, Graphic, Artboard)]
list: IList<T>,
/// The index of the item to retrieve, starting from 0 for the first item. Negative indices count backwards from the end of the list, starting from -1 for the last item.
index: SignedInteger,
@@ -114,7 +114,7 @@ pub fn extract_element<T: Clone + Default + Send + Sync + CacheHash + 'static>(
#[node_macro::node(category("General"))]
fn map<Row: Clone + Send + Sync + CacheHash + 'static, T>(
ctx: impl Ctx + DeriveCtx + ExtractIndex + InjectIndex + Copy,
#[implementations(Graphic, Vector, Raster<CPU>, Color, GradientStops, String)] content: IList<Row>,
#[implementations(Graphic, Vector, Raster<CPU>, Color, Gradient, String)] content: IList<Row>,
mapped: impl Node<Context<'_>, Output = IList<T>>,
) -> Result<IList<T>, Interrupt> {
let mut remaining = ctx.index();
@@ -429,9 +429,9 @@ fn extend_extent(base: ExtentIn<'_>, new: ExtentIn<'_>, level: LevelIn) -> GPoll
#[node_macro::node(category(""))]
pub fn legacy_layer_extend<T: Send + Clone>(
_: impl Ctx,
#[implementations(List<Artboard>, List<Graphic>, List<Vector>, List<String>, List<Raster<CPU>>, List<Raster<GPU>>, List<Color>, List<GradientStops>)] base: List<T>,
#[implementations(List<Artboard>, List<Graphic>, List<Vector>, List<String>, List<Raster<CPU>>, List<Raster<GPU>>, List<Color>, List<Gradient>)] base: List<T>,
#[expose]
#[implementations(List<Artboard>, List<Graphic>, List<Vector>, List<String>, List<Raster<CPU>>, List<Raster<GPU>>, List<Color>, List<GradientStops>)]
#[implementations(List<Artboard>, List<Graphic>, List<Vector>, List<String>, List<Raster<CPU>>, List<Raster<GPU>>, List<Color>, List<Gradient>)]
new: List<T>,
nested_node_path: List<NodeId>,
) -> List<T> {
@@ -458,7 +458,7 @@ pub fn legacy_layer_extend<T: Send + Clone>(
#[node_macro::node(category("General"), extent(wrap_graphic_extent))]
pub fn wrap_graphic<'e, T: Clone + Send + Sync + core_types::CacheHash + 'static>(
_: impl Ctx,
#[implementations(Graphic, Vector, Raster<CPU>, Raster<GPU>, Color, GradientStops, String)] content: IList<T>,
#[implementations(Graphic, Vector, Raster<CPU>, Raster<GPU>, Color, Gradient, String)] content: IList<T>,
) -> Result<IList<Graphic<'e>>, Interrupt> {
let item = content.as_group_item();
Ok(Graphic::Group(core_types::record::Group { row: None, content: item }))
@@ -483,7 +483,7 @@ pub fn to_graphic<'e, T: graphic_types::graphic::IntoGraphicElement>(
List<Raster<CPU>>,
List<Raster<GPU>>,
List<Color>,
List<GradientStops>,
List<Gradient>,
List<String>,
)]
content: T,
@@ -503,14 +503,14 @@ pub fn to_graphic_element<'e, T: graphic_types::graphic::IntoGraphicElement>(
Raster<CPU>,
Raster<GPU>,
Color,
GradientStops,
Gradient,
String,
List<Graphic>,
List<Vector>,
List<Raster<CPU>>,
List<Raster<GPU>>,
List<Color>,
List<GradientStops>,
List<Gradient>,
List<String>,
)]
content: T,
@@ -524,7 +524,7 @@ pub fn to_graphic_element<'e, T: graphic_types::graphic::IntoGraphicElement>(
#[node_macro::node(category(""), extent(wrap_graphic_extent))]
pub fn to_graphic_typed<'e, T: Clone + Send + Sync + core_types::CacheHash + 'static>(
_: impl Ctx,
#[implementations(Vector, Raster<CPU>, Raster<GPU>, Color, GradientStops, String)] content: IList<T>,
#[implementations(Vector, Raster<CPU>, Raster<GPU>, Color, Gradient, String)] content: IList<T>,
) -> Result<IList<Graphic<'e>>, Interrupt> {
let item = content.as_group_item();
Ok(Graphic::Group(core_types::record::Group { row: None, content: item }))
@@ -548,7 +548,7 @@ fn to_graphic_unit_extent(_content: core_types::extent::ValueIn<'_, ()>, _level:
#[node_macro::node(category(""))]
pub fn level_to_list<T: Clone + Send + Sync + CacheHash + dyn_any::StaticTypeSized>(
_: impl Ctx,
#[implementations(Graphic, Vector, Raster<CPU>, Raster<GPU>, Color, GradientStops, String)] value: IList<T>,
#[implementations(Graphic, Vector, Raster<CPU>, Raster<GPU>, Color, Gradient, String)] value: IList<T>,
_converter: (),
) -> List<T> {
let item = value.as_group_item();
@@ -650,19 +650,19 @@ pub fn flatten_color<T: IntoGraphicList>(_: impl Ctx, #[implementations(List<Gra
content.into_flattened_list()
}
/// Converts a `Graphic[]` into a `GradientStops[]` by deeply flattening any gradient content it contains, and discarding any non-gradient content.
/// Converts a `Graphic[]` into a `Gradient[]` by deeply flattening any gradient content it contains, and discarding any non-gradient content.
#[node_macro::node(category("General"))]
pub fn flatten_gradient<T: IntoGraphicList>(_: impl Ctx, #[implementations(List<Graphic>, List<GradientStops>)] content: T) -> List<GradientStops> {
pub fn flatten_gradient<T: IntoGraphicList>(_: impl Ctx, #[implementations(List<Graphic>, List<Gradient>)] content: T) -> List<Gradient> {
content.into_flattened_list()
}
/// Constructs a gradient from a `Color[]`, where the colors are evenly distributed as gradient stops across the range from 0 to 1.
#[node_macro::node(category("Color"))]
fn colors_to_gradient(_: impl Ctx, colors: IList<Color>) -> GradientStops {
fn colors_to_gradient(_: impl Ctx, colors: IList<Color>) -> Gradient {
let stop = |position: f64, color: Color| GradientStop { position, midpoint: 0.5, color };
match colors.len() {
0 => GradientStops::new(vec![stop(0., Color::BLACK), stop(1., Color::BLACK)]),
1 => GradientStops::new(vec![stop(0., colors.get(0)), stop(1., colors.get(0))]),
total => GradientStops::new((0..total).map(|index| stop(index as f64 / (total - 1) as f64, colors.get(index)))),
0 => Gradient::new(vec![stop(0., Color::BLACK), stop(1., Color::BLACK)]),
1 => Gradient::new(vec![stop(0., colors.get(0)), stop(1., colors.get(0))]),
total => Gradient::new((0..total).map(|index| stop(index as f64 / (total - 1) as f64, colors.get(index)))),
}
}

View File

@@ -11,7 +11,7 @@ use glam::DAffine2;
use graphic_types::Vector;
use graphic_types::graphic::Graphic;
use raster_types::{CPU, Raster};
use vector_types::{GradientStop, GradientStops};
use vector_types::{Gradient, GradientStop};
/// Whether the walk can descend into a group: the run holds `Graphic`
/// elements.
@@ -113,12 +113,12 @@ fn wrap_extent(_content: ListIn<'_, Graphic>, _level: LevelIn) -> GPoll<Extent>
/// Rank-model colors-to-gradient: the color level folds into one gradient
/// with evenly spaced stops.
#[node_macro::node(category("Test"))]
fn to_gradient(_: impl Ctx, colors: IList<Color>) -> GradientStops {
fn to_gradient(_: impl Ctx, colors: IList<Color>) -> Gradient {
let stop = |position: f64, color: Color| GradientStop { position, midpoint: 0.5, color };
match colors.len() {
0 => GradientStops::new(vec![stop(0., Color::BLACK), stop(1., Color::BLACK)]),
1 => GradientStops::new(vec![stop(0., colors.get(0)), stop(1., colors.get(0))]),
total => GradientStops::new((0..total).map(|index| stop(index as f64 / (total - 1) as f64, colors.get(index)))),
0 => Gradient::new(vec![stop(0., Color::BLACK), stop(1., Color::BLACK)]),
1 => Gradient::new(vec![stop(0., colors.get(0)), stop(1., colors.get(0))]),
total => Gradient::new((0..total).map(|index| stop(index as f64 / (total - 1) as f64, colors.get(index)))),
}
}
@@ -135,7 +135,7 @@ pub(crate) fn vararg_row<Row: Clone + Send + Sync + 'static>(content: core_types
#[node_macro::node(category("Test"))]
fn map<Row: Clone + Send + Sync + core_types::CacheHash + 'static, T>(
ctx: impl Ctx + DeriveCtx + ExtractIndex + InjectIndex + Copy,
#[implementations(Graphic, Vector, Raster<CPU>, Color, GradientStops, String)] content: IList<Row>,
#[implementations(Graphic, Vector, Raster<CPU>, Color, Gradient, String)] content: IList<Row>,
mapped: impl Node<Context<'_>, Output = IList<T>>,
) -> Result<IList<IList<T>>, Interrupt> {
let mut remaining = ctx.index();
@@ -159,7 +159,7 @@ fn map<Row: Clone + Send + Sync + core_types::CacheHash + 'static, T>(
#[node_macro::node(category("Test"))]
fn flat_map<Row: Clone + Send + Sync + core_types::CacheHash + 'static, T>(
ctx: impl Ctx + DeriveCtx + ExtractIndex + InjectIndex + Copy,
#[implementations(Graphic, Vector, Raster<CPU>, Color, GradientStops, String)] content: IList<Row>,
#[implementations(Graphic, Vector, Raster<CPU>, Color, Gradient, String)] content: IList<Row>,
mapped: impl Node<Context<'_>, Output = IList<T>>,
) -> Result<IList<T>, Interrupt> {
let mut remaining = ctx.index();
@@ -820,14 +820,14 @@ mod tests {
let ctx = ContextImpl::root(&scope);
let layout = Layout::default().with_writes(1, record::element_write_hashed::<Color>(), &[]);
let out = Layout::default().with_writes(0, record::element_write_hashed::<GradientStops>(), &[]);
let out = Layout::default().with_writes(0, record::element_write_hashed::<Gradient>(), &[]);
let build = |colors: Vec<Color>| install_flip(ToGradientNode::new(RecordSource::new(ColorSource { layout: layout.clone(), colors }, &layout, &layout), &layout), &out);
let stops_of = |colors: Vec<Color>| {
let node = build(colors);
let GPoll::Final(record) = record::capture(&node, &ctx, &frames) else {
panic!("expected a final record");
};
record.element::<GradientStops>()
record.element::<Gradient>()
};
let three = stops_of(vec![Color::BLACK, Color::WHITE, Color::BLACK]);

View File

@@ -58,7 +58,7 @@ pub mod subpath {
}
pub mod gradient {
pub use vector_types::{GradientStop, GradientStops};
pub use vector_types::{Gradient, GradientStop};
}
pub mod transform {

View File

@@ -33,7 +33,7 @@ use graphic_types::markers::EditorMergedLayers;
use graphic_types::raster_types::Image;
use graphic_types::raster_types::{CPU, Raster};
#[cfg(target_family = "wasm")]
use graphic_types::vector_types::gradient::GradientStops;
use graphic_types::vector_types::gradient::Gradient;
#[cfg(target_family = "wasm")]
use rendering::{Render, RenderParams, RenderSvgSegmentList, SvgRender};
use std::sync::Arc;
@@ -212,7 +212,7 @@ async fn rasterize<T: Clone + Send + Sync + dyn_any::StaticTypeSized>(
Raster<CPU>,
Graphic,
Color,
GradientStops,
Gradient,
)]
mut data: IList<T>,
footprint: Footprint,

View File

@@ -8,7 +8,7 @@ use graphic_types::raster_types::{CPU, Raster};
use graphic_types::{Artboard, Graphic, Vector};
use rendering::{Render, RenderMetadata, RenderOutputType as RenderOutputTypeRequest, RenderParams, SvgRender, SvgRenderOutput};
use std::sync::Arc;
use vector_types::GradientStops;
use vector_types::Gradient;
use wgpu_executor::RenderContext;
#[derive(Clone, dyn_any::DynAny)]
@@ -60,7 +60,7 @@ fn render_intermediate<T: dyn_any::StaticTypeSized + 'static + Render + WasmNotS
Context -> List<Vector>,
Context -> List<Raster<CPU>>,
Context -> List<Color>,
Context -> List<GradientStops>,
Context -> List<Gradient>,
Context -> List<String>,
)]
data: impl Node<Context<'_>, Output = T>,
@@ -80,7 +80,7 @@ fn render_intermediate<T: dyn_any::StaticTypeSized + 'static + Render + WasmNotS
#[node_macro::node(category(""))]
fn render_intermediate_leveled<T: Clone + Send + Sync + core_types::CacheHash + dyn_any::StaticTypeSized + 'static>(
ctx: impl Ctx + ExtractVarArgs + ExtractIndex + InjectIndex + Copy,
#[implementations(Artboard, Graphic, Vector, Raster<CPU>, Color, GradientStops, String)] data: IList<T>,
#[implementations(Artboard, Graphic, Vector, Raster<CPU>, Color, Gradient, String)] data: IList<T>,
) -> Result<RenderIntermediate, Interrupt>
where
for<'a> core_types::record::RunView<'a, T>: Render,

View File

@@ -11,7 +11,7 @@ use math_parser::value::{Number, Value};
use num_traits::Pow;
use rand::{Rng, SeedableRng};
use std::ops::{Add, Div, Mul, Rem, Sub};
use vector_types::GradientStops;
use vector_types::Gradient;
use vector_types::markers::{GradientType as GradientTypeAttr, SpreadMethod as SpreadMethodAttr};
/// The struct that stores the context for the maths parser.
@@ -819,25 +819,25 @@ fn hex_to_color(ctx: impl Ctx + ExtractIndex + InjectIndex + Copy, hex_code: Str
/// Constructs a gradient value which may be set to any sequence of color stops to represent the transition between colors.
#[node_macro::node(category("Value"))]
fn gradient_value(_: impl Ctx, _primary: (), gradient: GradientStops) -> GradientStops {
fn gradient_value(_: impl Ctx, _primary: (), gradient: Gradient) -> Gradient {
gradient
}
/// Sets the type (linear or radial) of each gradient in the input list.
#[node_macro::node(category("Color"))]
fn gradient_type(_: impl Ctx, gradient: GradientStops, gradient_type: vector_types::GradientType) -> (GradientStops, Attr<GradientTypeAttr>) {
fn gradient_type(_: impl Ctx, gradient: Gradient, gradient_type: vector_types::GradientType) -> (Gradient, Attr<GradientTypeAttr>) {
(gradient, Attr(gradient_type))
}
/// Sets how each gradient in the input list extends past its endpoints: Pad, Reflect, or Repeat.
#[node_macro::node(category("Color"))]
fn spread_method(_: impl Ctx, gradient: GradientStops, spread_method: vector_types::GradientSpreadMethod) -> (GradientStops, Attr<SpreadMethodAttr>) {
fn spread_method(_: impl Ctx, gradient: Gradient, spread_method: vector_types::GradientSpreadMethod) -> (Gradient, Attr<SpreadMethodAttr>) {
(gradient, Attr(spread_method))
}
/// Gets the color at the specified position along the gradient, given a position from 0 (left) to 1 (right).
#[node_macro::node(category("Color"))]
fn sample_gradient(ctx: impl Ctx + ExtractIndex + InjectIndex + Copy, _primary: (), gradient: IList<GradientStops>, position: Fraction) -> Result<IList<Color>, Interrupt> {
fn sample_gradient(ctx: impl Ctx + ExtractIndex + InjectIndex + Copy, _primary: (), gradient: IList<Gradient>, position: Fraction) -> Result<IList<Color>, Interrupt> {
// An unwired gradient serves an empty level: no color
if gradient.is_empty() || ctx.index() != 0 {
return Err(GraphError::past_end().into());

View File

@@ -7,7 +7,7 @@ use glam::{DAffine2, DVec2};
use graphic_types::graphic::{GraphicLevel, PaintColumns, PaintReach, bake_paint_transforms, is_paint_present, set_paint_attribute, set_paint_attribute_at};
use graphic_types::markers::{EditorMergedLayers, Fill, Stroke};
use graphic_types::raster_types::{CPU, GPU, Raster};
use graphic_types::vector_types::GradientStops;
use graphic_types::vector_types::Gradient;
use graphic_types::vector_types::gradient::{GradientSpreadMethod, GradientType};
use graphic_types::vector_types::subpath::{ManipulatorGroup, Subpath};
use graphic_types::vector_types::vector::PointId;
@@ -283,7 +283,7 @@ fn color_paint_row(color: Color, mut attributes: core_types::list::ItemAttribute
/// A gradient row: an empty vector carrying the stops as its fill paint, the
/// gradient keys moved onto the paint.
fn gradient_paint_row(stops: GradientStops, mut attributes: core_types::list::ItemAttributeValues) -> Item<Vector> {
fn gradient_paint_row(stops: Gradient, mut attributes: core_types::list::ItemAttributeValues) -> Item<Vector> {
let mut gradient_paint = List::new_from_element(Graphic::Gradient(stops));
if let Some(transform) = attributes.remove::<DAffine2>(ATTR_TRANSFORM) {
gradient_paint.set_attribute(ATTR_TRANSFORM, 0, transform);
@@ -409,7 +409,7 @@ fn flatten_group(out: &mut List<Vector>, group: &core_types::record::Group, comp
out,
(0..color.len()).filter_map(|i| Some(color_paint_row(*color.element(i)?, color.clone_item_attributes(i)))).collect(),
);
} else if let Some(gradient) = graphic_types::graphic::run_to_list::<GradientStops>(item) {
} else if let Some(gradient) = graphic_types::graphic::run_to_list::<Gradient>(item) {
push_rows(
out,
(0..gradient.len())

View File

@@ -13,7 +13,7 @@ impl Adjust<Color> for Color {
mod adjust_std {
use super::*;
use raster_types::{CPU, Raster};
use vector_types::GradientStops;
use vector_types::Gradient;
impl Adjust<Color> for Raster<CPU> {
fn adjust(&mut self, map_fn: impl Fn(&Color) -> Color) {
@@ -22,7 +22,7 @@ mod adjust_std {
}
}
}
impl Adjust<Color> for GradientStops {
impl Adjust<Color> for Gradient {
fn adjust(&mut self, map_fn: impl Fn(&Color) -> Color) {
for color in self.color.iter_mut() {
*color = map_fn(color);

View File

@@ -14,7 +14,7 @@ use num_traits::float::Float;
#[cfg(feature = "std")]
use raster_types::{CPU, Raster};
#[cfg(feature = "std")]
use vector_types::GradientStops;
use vector_types::Gradient;
// TODO: Implement the following:
// Color Balance
@@ -53,7 +53,7 @@ fn luminance<T: Adjust<Color> + Clone + Send + Sync + no_std_types::context::Cac
#[implementations(
Raster<CPU>,
Color,
GradientStops,
Gradient,
)]
#[gpu_image]
mut input: T,
@@ -78,7 +78,7 @@ fn gamma_correction<T: Adjust<Color> + Clone + Send + Sync + no_std_types::conte
#[implementations(
Raster<CPU>,
Color,
GradientStops,
Gradient,
)]
#[gpu_image]
mut input: T,
@@ -100,7 +100,7 @@ fn extract_channel<T: Adjust<Color> + Clone + Send + Sync + no_std_types::contex
#[implementations(
Raster<CPU>,
Color,
GradientStops,
Gradient,
)]
#[gpu_image]
mut input: T,
@@ -124,7 +124,7 @@ fn make_opaque<T: Adjust<Color> + Clone + Send + Sync + no_std_types::context::C
#[implementations(
Raster<CPU>,
Color,
GradientStops,
Gradient,
)]
#[gpu_image]
mut input: T,
@@ -146,7 +146,7 @@ fn brightness_contrast_classic<T: Adjust<Color> + Clone + Send + Sync + no_std_t
#[implementations(
Raster<CPU>,
Color,
GradientStops,
Gradient,
)]
#[gpu_image]
mut input: T,
@@ -177,7 +177,7 @@ fn brightness_contrast<T: Adjust<Color> + Clone + Send + Sync + no_std_types::co
#[implementations(
Raster<CPU>,
Color,
GradientStops,
Gradient,
)]
#[gpu_image]
mut input: T,
@@ -258,7 +258,7 @@ fn levels<T: Adjust<Color> + Clone + Send + Sync + no_std_types::context::CacheH
#[implementations(
Raster<CPU>,
Color,
GradientStops,
Gradient,
)]
#[gpu_image]
mut image: T,
@@ -337,7 +337,7 @@ fn black_and_white<T: Adjust<Color> + Clone + Send + Sync + no_std_types::contex
#[implementations(
Raster<CPU>,
Color,
GradientStops,
Gradient,
)]
#[gpu_image]
mut image: T,
@@ -420,7 +420,7 @@ fn hue_saturation<T: Adjust<Color> + Clone + Send + Sync + no_std_types::context
#[implementations(
Raster<CPU>,
Color,
GradientStops,
Gradient,
)]
#[gpu_image]
mut input: T,
@@ -452,7 +452,7 @@ fn invert<T: Adjust<Color> + Clone + Send + Sync + no_std_types::context::CacheH
#[implementations(
Raster<CPU>,
Color,
GradientStops,
Gradient,
)]
#[gpu_image]
mut input: T,
@@ -473,7 +473,7 @@ fn threshold<T: Adjust<Color> + Clone + Send + Sync + no_std_types::context::Cac
#[implementations(
Raster<CPU>,
Color,
GradientStops,
Gradient,
)]
#[gpu_image]
mut image: T,
@@ -519,7 +519,7 @@ fn vibrance<T: Adjust<Color> + Clone + Send + Sync + no_std_types::context::Cach
#[implementations(
Raster<CPU>,
Color,
GradientStops,
Gradient,
)]
#[gpu_image]
mut image: T,
@@ -721,7 +721,7 @@ fn channel_mixer<T: Adjust<Color> + Clone + Send + Sync + no_std_types::context:
#[implementations(
Raster<CPU>,
Color,
GradientStops,
Gradient,
)]
#[gpu_image]
mut image: T,
@@ -853,7 +853,7 @@ fn selective_color<T: Adjust<Color> + Clone + Send + Sync + no_std_types::contex
#[implementations(
Raster<CPU>,
Color,
GradientStops,
Gradient,
)]
#[gpu_image]
mut image: T,
@@ -999,7 +999,7 @@ fn posterize<T: Adjust<Color> + Clone + Send + Sync + no_std_types::context::Cac
#[implementations(
Raster<CPU>,
Color,
GradientStops,
Gradient,
)]
#[gpu_image]
mut input: T,
@@ -1028,7 +1028,7 @@ fn exposure<T: Adjust<Color> + Clone + Send + Sync + no_std_types::context::Cach
#[implementations(
Raster<CPU>,
Color,
GradientStops,
Gradient,
)]
#[gpu_image]
mut input: T,

View File

@@ -6,7 +6,7 @@ use no_std_types::registry::types::PercentageF32;
#[cfg(feature = "std")]
use raster_types::{CPU, Raster};
#[cfg(feature = "std")]
use vector_types::{GradientStop, GradientStops};
use vector_types::{Gradient, GradientStop};
pub trait Blend<P: Pixel> {
fn blend(&self, under: &Self, blend_fn: impl Fn(P, P) -> P) -> Self;
@@ -36,7 +36,7 @@ mod blend_std {
}
}
impl Blend<Color> for GradientStops {
impl Blend<Color> for Gradient {
fn blend(&self, under: &Self, blend_fn: impl Fn(Color, Color) -> Color) -> Self {
let mut combined_stops = self.position.iter().chain(under.position.iter()).copied().collect::<Vec<_>>();
combined_stops.dedup_by(|a, b| (*a - *b).abs() < 1e-6);
@@ -47,7 +47,7 @@ mod blend_std {
let color = blend_fn(over_color, under_color);
GradientStop { position, midpoint: 0.5, color }
});
GradientStops::new(stops)
Gradient::new(stops)
}
}
}
@@ -111,7 +111,7 @@ fn mix<T: Blend<Color> + Clone + Send + Sync + core_types::CacheHash + 'static>(
#[implementations(
Raster<CPU>,
Color,
GradientStops,
Gradient,
)]
#[gpu_image]
over: T,
@@ -119,7 +119,7 @@ fn mix<T: Blend<Color> + Clone + Send + Sync + core_types::CacheHash + 'static>(
#[implementations(
Raster<CPU>,
Color,
GradientStops,
Gradient,
)]
#[gpu_image]
under: T,
@@ -135,7 +135,7 @@ fn color_overlay<T: Adjust<Color> + Clone + Send + Sync + no_std_types::context:
#[implementations(
Raster<CPU>,
Color,
GradientStops,
Gradient,
)]
#[gpu_image]
mut image: T,

View File

@@ -1,9 +1,9 @@
//! Not immediately shader compatible due to needing [`GradientStops`] as a param, which needs [`Vec`]
//! Not immediately shader compatible due to needing [`Gradient`] as a param, which needs [`Vec`]
use crate::adjust::Adjust;
use core_types::{Color, Ctx};
use raster_types::{CPU, Raster};
use vector_types::GradientStops;
use vector_types::Gradient;
// Aims for interoperable compatibility with:
// https://www.adobe.com/devnet-apps/photoshop/fileformatashtml/#:~:text=%27grdm%27%20%3D%20Gradient%20Map
@@ -14,10 +14,10 @@ fn gradient_map<T: Adjust<Color> + Clone + Send + Sync + core_types::CacheHash +
#[implementations(
Raster<CPU>,
Color,
GradientStops,
Gradient,
)]
mut image: T,
gradient: IList<GradientStops>,
gradient: IList<Gradient>,
reverse: bool,
) -> T {
if gradient.is_empty() {

View File

@@ -9,7 +9,7 @@ use glam::{DAffine2, DMat2, DVec2};
use graphic_types::Graphic;
use graphic_types::Vector;
use graphic_types::raster_types::{CPU, GPU, Raster};
use vector_types::GradientStops;
use vector_types::Gradient;
/// Applies the specified transform to each lane of the input, composing onto the lane's transform attribute.
#[node_macro::node(category("Math: Transform"), extent(transform_extent))]
@@ -97,7 +97,7 @@ fn replace_transform<T>(_: impl Ctx + InjectFootprint, (element, _content_transf
// TODO: Figure out how this node should behave once #2982 is implemented.
/// Obtains the transform of the first lane of the input, if present.
#[node_macro::node(category("Math: Transform"), path(core_types::vector))]
fn extract_transform<T: Clone + Send + Sync + CacheHash + 'static>(_: impl Ctx, #[implementations(Graphic, Vector, Raster<CPU>, Raster<GPU>, Color, GradientStops)] content: IList<T>) -> DAffine2 {
fn extract_transform<T: Clone + Send + Sync + CacheHash + 'static>(_: impl Ctx, #[implementations(Graphic, Vector, Raster<CPU>, Raster<GPU>, Color, Gradient)] content: IList<T>) -> DAffine2 {
match content.len() {
0 => DAffine2::default(),
_ => content.lane(0).attr::<TransformAttr>(),

View File

@@ -37,14 +37,14 @@ use vector_types::vector::misc::{
CentroidType, ExtrudeJoiningAlgorithm, HandleId, InterpolationDistribution, MergeByDistanceAlgorithm, PointSpacingType, RowsOrColumns, bezpath_from_manipulator_groups,
bezpath_to_manipulator_groups, handles_to_segment, is_linear, point_to_dvec2, segment_to_handles,
};
use vector_types::vector::style::{GradientStops, PaintOrder, Stroke, StrokeAlign, StrokeCap, StrokeJoin};
use vector_types::vector::style::{Gradient, PaintOrder, Stroke, StrokeAlign, StrokeCap, StrokeJoin};
use vector_types::vector::{FillId, PointId, RegionId, SegmentDomain, SegmentId, StrokeId, VectorExt};
use vector_types::{ATTR_GRADIENT_TYPE, ATTR_SPREAD_METHOD};
use vector_types::{GradientSpreadMethod, GradientType};
/// The gradient color for one assign-colors position, replaying the
/// randomized draws up to it.
fn assign_color_at(gradient: &GradientStops, position: usize, length: usize, randomize: bool, seed: SeedValue, repeat_every: u32) -> Color {
fn assign_color_at(gradient: &Gradient, position: usize, length: usize, randomize: bool, seed: SeedValue, repeat_every: u32) -> Color {
let factor = match randomize {
true => {
let mut rng = rand::rngs::StdRng::seed_from_u64(seed.into());
@@ -77,7 +77,7 @@ fn assign_colors<'e>(
stroke: bool,
/// The range of colors to select from.
#[widget(ParsedWidgetOverride::Custom = "assign_colors_gradient")]
gradient: IList<GradientStops>,
gradient: IList<Gradient>,
/// Whether to reverse the gradient.
reverse: bool,
/// Whether to randomize the color selection for each element from throughout the gradient.
@@ -132,7 +132,7 @@ fn assign_colors_extent(
content: ListIn<'_, Vector>,
_fill: ValueIn<'_, bool>,
_stroke: ValueIn<'_, bool>,
_gradient: ListIn<'_, GradientStops>,
_gradient: ListIn<'_, Gradient>,
_reverse: ValueIn<'_, bool>,
_randomize: ValueIn<'_, bool>,
_seed: ValueIn<'_, SeedValue>,
@@ -155,7 +155,7 @@ fn assign_colors_graphic<'e>(
#[data] lane_offsets: std::sync::Arc<std::sync::Mutex<Option<LaneOffsets>>>,
#[default(true)] fill: bool,
stroke: bool,
gradient: IList<GradientStops>,
gradient: IList<Gradient>,
reverse: bool,
randomize: bool,
seed: SeedValue,
@@ -247,7 +247,7 @@ fn assign_colors_graphic_extent(
content: ListIn<'_, Graphic>,
_fill: ValueIn<'_, bool>,
_stroke: ValueIn<'_, bool>,
_gradient: ListIn<'_, GradientStops>,
_gradient: ListIn<'_, Gradient>,
_reverse: ValueIn<'_, bool>,
_randomize: ValueIn<'_, bool>,
_seed: ValueIn<'_, SeedValue>,
@@ -322,7 +322,7 @@ fn fill<'e>(
#[default(Color::BLACK)]
fill: IList<Graphic<'static>>,
_backup_color: IList<Color>,
_backup_gradient: IList<GradientStops>,
_backup_gradient: IList<Gradient>,
_gradient_type: GradientType,
_spread_method: GradientSpreadMethod,
_transform: Option<DAffine2>,
@@ -342,7 +342,7 @@ fn fill_graphic_leveled<'e>(
(element, _content_fill): (Graphic<'static>, Attr<Fill>),
#[default(Color::BLACK)] fill: IList<Graphic<'static>>,
_backup_color: IList<Color>,
_backup_gradient: IList<GradientStops>,
_backup_gradient: IList<Gradient>,
_gradient_type: GradientType,
_spread_method: GradientSpreadMethod,
_transform: Option<DAffine2>,
@@ -2780,7 +2780,7 @@ fn morph_core(flattened: List<Vector>, snapshot: List<Graphic<'static>>, progres
};
// This keeps the gradient metadata attributes, which ride the paint lane
let gradient_paint = |metadata_source: &List<Graphic>, stops: GradientStops, transform: Option<DAffine2>| -> List<Graphic> {
let gradient_paint = |metadata_source: &List<Graphic>, stops: Gradient, transform: Option<DAffine2>| -> List<Graphic> {
let mut out = List::new_from_item(Item::from_parts(Graphic::Gradient(stops), metadata_source.clone_item_attributes(0)));
if let Some(transform) = transform {
out.set_attribute(ATTR_TRANSFORM, 0, transform);
@@ -3666,7 +3666,7 @@ fn point_inside(_: impl Ctx, source: IList<Vector>, point: DVec2) -> bool {
// TODO: Return u32, u64, or usize instead of f64 after #1621 is resolved and has allowed us to implement automatic type conversion in the node graph for nodes with generic type inputs.
// TODO: (Currently automatic type conversion only works for concrete types, via the Graphene preprocessor and not the full Graphene type system.)
#[node_macro::node(category("General"), path(graphene_core::vector))]
fn count_elements<T: Clone + Send + Sync + CacheHash + 'static>(_: impl Ctx, #[implementations(Graphic, Artboard, Vector, Raster<CPU>, Color, GradientStops, String)] content: IList<T>) -> f64 {
fn count_elements<T: Clone + Send + Sync + CacheHash + 'static>(_: impl Ctx, #[implementations(Graphic, Artboard, Vector, Raster<CPU>, Color, Gradient, String)] content: IList<T>) -> f64 {
content.len() as f64
}