Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use graphene_std::list::List;
use graphene_std::memo::IORecord;
use graphene_std::raster_types::{CPU, GPU, Raster};
use graphene_std::vector::Vector;
use graphene_std::vector::style::{FillChoice, FillChoiceUI, GradientSpreadMethod, GradientType};
use graphene_std::vector::style::{FillChoice, FillChoiceUI, GradientSpreadMethod, GradientType, MeshGradient};
use graphene_std::{Artboard, Color, Context, Graphic};
use std::any::Any;
use std::sync::Arc;
Expand Down Expand Up @@ -336,6 +336,7 @@ impl TableItemLayout for Graphic {
Self::RasterGPU(list) => list.identifier(),
Self::Color(list) => list.identifier(),
Self::Gradient(list) => list.identifier(),
Self::MeshGradient(list) => list.identifier(),
Self::Text(list) => list.identifier(),
}
}
Expand All @@ -351,6 +352,7 @@ impl TableItemLayout for Graphic {
Self::RasterGPU(list) => list.layout_with_breadcrumb(data),
Self::Color(list) => list.layout_with_breadcrumb(data),
Self::Gradient(list) => list.layout_with_breadcrumb(data),
Self::MeshGradient(list) => list.layout_with_breadcrumb(data),
Self::Text(list) => list.layout_with_breadcrumb(data),
}
}
Expand Down Expand Up @@ -557,6 +559,21 @@ impl TableItemLayout for GradientStops {
}
}

impl TableItemLayout for MeshGradient {
fn type_name() -> &'static str {
"MeshGradient"
}
fn identifier(&self) -> String {
//FIXME: not implemented yet
format!("MeshGradient ({})", 1)
}
fn value_page(&self, _data: &mut LayoutData) -> Vec<LayoutGroup> {
//FIXME: not implemented yet
let widgets = vec![TextLabel::new("FIXME: MeshGradient cannot be displayed here").widget_instance()];
vec![LayoutGroup::row(widgets)]
}
}

impl TableItemLayout for f64 {
fn type_name() -> &'static str {
"Number (f64)"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2633,7 +2633,7 @@ pub(crate) fn fill_properties(node_id: NodeId, context: &mut NodePropertiesConte
let mut row = vec![TextLabel::new("").widget_instance()];
add_blank_assist(&mut row);

let entries = [GradientType::Linear, GradientType::Radial]
let entries = [GradientType::Linear, GradientType::Radial, GradientType::Mesh]
.iter()
.map(|&grad_type| {
RadioEntryData::new(format!("{:?}", grad_type))
Expand Down
8 changes: 7 additions & 1 deletion editor/src/messages/tool/tool_messages/gradient_tool.rs
Original file line number Diff line number Diff line change
Expand Up @@ -252,8 +252,14 @@ impl LayoutHolder for GradientTool {
}
.into()
}),
RadioEntryData::new("Mesh").label("Mesh").tooltip_label(" Gradient").on_update(move |_| {
GradientToolMessage::UpdateOptions {
options: GradientOptionsUpdate::Type(GradientType::Mesh),
}
.into()
}),
])
.selected_index(Some((self.options.gradient_type == GradientType::Radial) as u32))
.selected_index(Some(self.options.gradient_type as u32))
.widget_instance();

// Display priority: the selected layer's stops, then any user-customized tool default, then the working colors
Expand Down
20 changes: 18 additions & 2 deletions node-graph/libraries/graphic-types/src/graphic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ use raster_types::{CPU, GPU, Raster};
use std::borrow::Cow;
use vector_types::GradientStops;
pub use vector_types::Vector;
use vector_types::gradient::MeshGradient;

/// The possible forms of graphical content that can be rendered by the Render node into either an image or SVG syntax.
#[derive(Clone, Debug, CacheHash, PartialEq, DynAny)]
Expand All @@ -21,6 +22,7 @@ pub enum Graphic {
RasterGPU(List<Raster<GPU>>),
Color(List<Color>),
Gradient(List<GradientStops>),
MeshGradient(List<MeshGradient>),
Text(List<String>),
}

Expand Down Expand Up @@ -237,6 +239,7 @@ pub fn bake_paint_transforms(attributes: &mut ItemAttributeValues, transform: DA
Graphic::RasterCPU(list) => bake_list_transform(list, transform),
Graphic::RasterGPU(list) => bake_list_transform(list, transform),
Graphic::Gradient(list) => bake_list_transform(list, transform),
Graphic::MeshGradient(list) => bake_list_transform(list, transform),
Graphic::Text(list) => bake_list_transform(list, transform),
Graphic::Color(_) => {}
}
Expand Down Expand Up @@ -342,6 +345,12 @@ impl IntoGraphicList for List<GradientStops> {
}
}

impl IntoGraphicList for List<MeshGradient> {
fn into_graphic_list(self) -> List<Graphic> {
List::new_from_element(Graphic::MeshGradient(self))
}
}

impl IntoGraphicList for List<String> {
fn into_graphic_list(self) -> List<Graphic> {
let layer_path: List<NodeId> = self.attribute_cloned_or_default(ATTR_EDITOR_LAYER_PATH, 0);
Expand Down Expand Up @@ -429,6 +438,7 @@ impl Graphic {
Graphic::RasterGPU(list) => all_clipped(list),
Graphic::Color(list) => all_clipped(list),
Graphic::Gradient(list) => all_clipped(list),
Graphic::MeshGradient(list) => all_clipped(list),
Graphic::Text(list) => all_clipped(list),
}
}
Expand Down Expand Up @@ -468,7 +478,8 @@ impl Graphic {
}
Graphic::Color(list) => list.element(0).is_some_and(|color| color.is_opaque()),
Graphic::Gradient(list) => list.element(0).is_some_and(|stops| stops.iter().all(|stop| stop.color.is_opaque())),
Graphic::RasterCPU(_) | Graphic::RasterGPU(_) | Graphic::Text(_) => false,
// TODO: Graphic::MeshGradient should be able to have this check
Graphic::RasterCPU(_) | Graphic::RasterGPU(_) | Graphic::Text(_) | Graphic::MeshGradient(_) => false,
}
}

Expand All @@ -491,7 +502,8 @@ impl Graphic {
}),
Graphic::Color(list) => list.iter_element_values().all(|color| color.a() == 0.),
Graphic::Gradient(list) => list.iter_element_values().all(|stops| stops.iter().all(|stop| stop.color.a() == 0.)),
Graphic::RasterCPU(_) | Graphic::RasterGPU(_) | Graphic::Text(_) => false,
// TODO: Graphic::MeshGradient should be able to have this check
Graphic::RasterCPU(_) | Graphic::RasterGPU(_) | Graphic::Text(_) | Graphic::MeshGradient(_) => false,
}
}

Expand All @@ -508,6 +520,7 @@ impl Graphic {
Graphic::Vector(list) => list.is_empty(),
Graphic::Color(list) => list.is_empty(),
Graphic::Gradient(list) => list.is_empty(),
Graphic::MeshGradient(list) => list.is_empty(),
Graphic::RasterCPU(list) => list.is_empty(),
Graphic::RasterGPU(list) => list.is_empty(),
Graphic::Text(list) => list.is_empty(),
Expand All @@ -524,6 +537,7 @@ impl BoundingBox for Graphic {
Graphic::Graphic(list) => list.bounding_box(transform, include_stroke),
Graphic::Color(list) => list.bounding_box(transform, include_stroke),
Graphic::Gradient(list) => list.bounding_box(transform, include_stroke),
Graphic::MeshGradient(list) => list.bounding_box(transform, include_stroke),
Graphic::Text(list) => list.bounding_box(transform, include_stroke),
}
}
Expand All @@ -536,6 +550,7 @@ impl BoundingBox for Graphic {
Graphic::Graphic(graphic) => graphic.thumbnail_bounding_box(transform, include_stroke),
Graphic::Color(color) => color.thumbnail_bounding_box(transform, include_stroke),
Graphic::Gradient(gradient) => gradient.thumbnail_bounding_box(transform, include_stroke),
Graphic::MeshGradient(gradient) => gradient.thumbnail_bounding_box(transform, include_stroke),
Graphic::Text(list) => list.thumbnail_bounding_box(transform, include_stroke),
}
}
Expand Down Expand Up @@ -566,6 +581,7 @@ impl RenderComplexity for Graphic {
Self::RasterGPU(list) => list.render_complexity(),
Self::Color(list) => list.render_complexity(),
Self::Gradient(list) => list.render_complexity(),
Self::MeshGradient(list) => list.render_complexity(),
Self::Text(list) => list.render_complexity(),
}
}
Expand Down
6 changes: 3 additions & 3 deletions node-graph/libraries/rendering/src/render_ext.rs
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ impl RenderExt for List<GradientStops> {
let gradient_id = generate_uuid();

match gradient_type {
GradientType::Linear => {
GradientType::Linear | GradientType::Mesh => {
let _ = write!(
svg_defs,
r#"<linearGradient id="{}" gradientUnits="userSpaceOnUse" x1="0" y1="0" x2="1" y2="0"{spread_method}{gradient_transform}>{}</linearGradient>"#,
Expand Down Expand Up @@ -241,7 +241,7 @@ impl RenderExt for List<Graphic> {
let gradient_id = gradient_list.render(svg_defs, item_transform, element_transform, stroke_transform, bounds, render_params, target);
format!(r##" {paint_attr}="url(#{gradient_id})""##)
}
Some(Graphic::Vector(_)) | Some(Graphic::RasterCPU(_)) | Some(Graphic::RasterGPU(_)) | Some(Graphic::Graphic(_)) | Some(Graphic::Text(_)) => {
Some(Graphic::Vector(_)) | Some(Graphic::RasterCPU(_)) | Some(Graphic::RasterGPU(_)) | Some(Graphic::Graphic(_)) | Some(Graphic::Text(_)) | Some(Graphic::MeshGradient(_)) => {
let bounds = if target == PaintTarget::Stroke {
// To prevent a wraparound artefact occurring when the tile boundary and the stroke region are perfectly aligned, the local coordinate is expanded slightly.
let inverse = |len: f64| if len > 0. { 1. / len } else { 0. };
Expand All @@ -262,7 +262,7 @@ impl RenderExt for List<Graphic> {
}

/// Emits an SVG `<pattern>` paint server into `svg_defs` that renders the given graphic list as the paint content, and returns the pattern ID.
/// Currently, this function is only used for clipping-based filling and stroking, not considering tiling yet.
/// Currently, this function is only used for clipping-based filling and stroking and mesh gradient, not considering tiling yet.
fn render_svg_pattern(svg_defs: &mut String, fill_graphic_list: &List<Graphic>, stroke_transform: DAffine2, bounds: DAffine2, render_params: &RenderParams) -> Option<String> {
let min = bounds.transform_point2(DVec2::ZERO);
let max = bounds.transform_point2(DVec2::ONE);
Expand Down
Loading
Loading