Add Table<GradientStops> gradient rendering (#3989)

* Add Table<GradientStops> gradient rendering

* Add SVG and Vello renderers for Table<GradientStops>

* Add thumbnail rendering for Table<GradientStops>

* Use row transform to map (0,0), (1,0) unit line to document space

* Set 100px width for the initially created gradient

* Add support of table gradients for the gradient tool

* Fix after review

* Thumbnail rendering of artboard with infinite gradient layer

* Hide radial gradient's reverse direction button for gradient table

* Remove unused imports

* Format

* Fix conflict with spread method

* Code review

* Fix thumbnails

* Connect up gradient_type and spread_method to attributes

---------

Co-authored-by: Keavon Chambers <keavon@keavon.com>
This commit is contained in:
YohYamasaki
2026-04-29 14:45:50 +02:00
committed by GitHub
parent 8cadafa063
commit e686ee9f42
19 changed files with 615 additions and 92 deletions

View File

@@ -3,15 +3,16 @@ use crate::application_io::PlatformEditorApi;
use crate::proto::{Any as DAny, FutureAny};
use brush_nodes::brush_cache::BrushCache;
use brush_nodes::brush_stroke::BrushStroke;
use core_types::table::Table;
use core_types::table::{Table, TableRow};
use core_types::transform::Footprint;
use core_types::uuid::NodeId;
use core_types::{CacheHash, Color, ContextFeatures, MemoHash, Node, Type};
use core_types::{ATTR_TRANSFORM, CacheHash, Color, ContextFeatures, MemoHash, Node, Type};
use dyn_any::DynAny;
pub use dyn_any::StaticType;
use glam::{Affine2, Vec2};
pub use glam::{DAffine2, DVec2, IVec2, UVec2};
use graphic_types::raster_types::{CPU, Image, Raster};
use graphic_types::vector_types::gradient::GRADIENT_TABLE_DEFAULT_SCALE;
use graphic_types::vector_types::vector::style::{Fill, Gradient, GradientStops, Stroke};
use graphic_types::vector_types::vector::{self, ReferencePoint};
use graphic_types::{Graphic, Vector};
@@ -118,7 +119,9 @@ macro_rules! tagged_value {
x if x == TypeId::of::<()>() => TaggedValue::None,
// Table-wrapped types need a single-item default with the element's default, not an empty table
x if x == TypeId::of::<Table<Color>>() => TaggedValue::Color(Table::new_from_element(Color::default())),
x if x == TypeId::of::<Table<GradientStops>>() => TaggedValue::GradientTable(Table::new_from_element(GradientStops::default())),
x if x == TypeId::of::<Table<GradientStops>>() => TaggedValue::GradientTable(Table::new_from_row(
TableRow::new_from_element(GradientStops::default()).with_attribute(ATTR_TRANSFORM, DAffine2::from_scale(DVec2::splat(GRADIENT_TABLE_DEFAULT_SCALE))),
)),
$( x if x == TypeId::of::<$ty>() => TaggedValue::$identifier(Default::default()), )*
_ => return None,
})