Rename gradient type to gradient form (#4405)

* Rename gradient type to gradient form

* Update the demo art for the gradient form rename

* Say form not type in the Gradient Form node's doc comment
This commit is contained in:
Keavon Chambers
2026-08-04 05:51:10 -07:00
committed by GitHub
parent ca44dbaf55
commit 788fe227c6
28 changed files with 173 additions and 164 deletions
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+1 -1
View File
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -24,7 +24,7 @@ use graphene_std::transform::{ReferencePoint, ScaleType};
use graphene_std::vector::misc::{
ArcType, BooleanOperation, BoxCorners, CentroidType, ExtrudeJoiningAlgorithm, GridType, InterpolationDistribution, MergeByDistanceAlgorithm, PointSpacingType, RowsOrColumns, SpiralType,
};
use graphene_std::vector::style::{DashPattern, FillChoice, GradientRamp, GradientSpread, GradientType, PaintOrder, StrokeAlign, StrokeCap, StrokeJoin};
use graphene_std::vector::style::{DashPattern, FillChoice, GradientForm, GradientRamp, GradientSpread, PaintOrder, StrokeAlign, StrokeCap, StrokeJoin};
use graphene_std::vector::{QRCodeErrorCorrectionLevel, Vector};
use graphene_std::{Artboard, Color, Context, Graphic};
use std::any::Any;
@@ -212,7 +212,7 @@ fn generate_layout(introspected_data: &Arc<dyn std::any::Any + Send + Sync + 'st
List<DVec2>,
List<DAffine2>,
List<BlendMode>,
List<GradientType>,
List<GradientForm>,
List<GradientSpread>,
List<DashPattern>,
List<BoxCorners>,
@@ -265,7 +265,7 @@ fn generate_layout(introspected_data: &Arc<dyn std::any::Any + Send + Sync + 'st
Item<DVec2>,
Item<DAffine2>,
Item<BlendMode>,
Item<GradientType>,
Item<GradientForm>,
Item<GradientSpread>,
Item<DashPattern>,
Item<BoxCorners>,
@@ -1001,7 +1001,7 @@ macro_rules! impl_table_item_layout_for_choice_enum {
}
impl_table_item_layout_for_choice_enum!(
BlendMode,
GradientType,
GradientForm,
GradientSpread,
StrokeJoin,
StrokeAlign,
@@ -1213,7 +1213,7 @@ macro_rules! known_item_types {
DashPattern,
BoxCorners,
BlendMode,
GradientType,
GradientForm,
GradientSpread,
StrokeJoin,
StrokeAlign,
@@ -10,7 +10,7 @@ use graphene_std::raster::BlendMode;
use graphene_std::raster_types::Image;
use graphene_std::subpath::Subpath;
use graphene_std::text::{Font, TypesettingConfig};
use graphene_std::vector::style::{GradientSpread, GradientType, Stroke};
use graphene_std::vector::style::{GradientForm, GradientSpread, Stroke};
use graphene_std::vector::{Gradient, PointId, VectorModificationType};
#[impl_message(Message, DocumentMessage, GraphOperation)]
@@ -24,7 +24,7 @@ pub enum GraphOperationMessage {
layer: LayerNodeIdentifier,
#[serde(skip)]
gradient: Gradient,
gradient_type: GradientType,
gradient_form: GradientForm,
gradient_spread: GradientSpread,
transform: DAffine2,
},
@@ -49,9 +49,9 @@ pub enum GraphOperationMessage {
layer: LayerNodeIdentifier,
transform: DAffine2,
},
GradientTypeSet {
GradientFormSet {
layer: LayerNodeIdentifier,
gradient_type: GradientType,
gradient_form: GradientForm,
},
GradientSpreadSet {
layer: LayerNodeIdentifier,
@@ -13,7 +13,7 @@ use graph_craft::document::{NodeId, NodeInput};
use graph_craft::list;
use graphene_std::renderer::convert_usvg_path::convert_usvg_path;
use graphene_std::text::{Font, TypesettingConfig};
use graphene_std::vector::style::{Gradient, GradientSpread, GradientStop, GradientType, PaintOrder, Stroke, StrokeAlign, StrokeCap, StrokeJoin};
use graphene_std::vector::style::{Gradient, GradientForm, GradientSpread, GradientStop, PaintOrder, Stroke, StrokeAlign, StrokeCap, StrokeJoin};
use graphene_std::{Artboard, Color};
#[derive(ExtractField)]
@@ -42,12 +42,12 @@ impl MessageHandler<GraphOperationMessage, GraphOperationMessageContext<'_>> for
GraphOperationMessage::FillGradientSet {
layer,
gradient,
gradient_type,
gradient_form,
gradient_spread,
transform,
} => {
if let Some(mut modify_inputs) = ModifyInputsContext::new_with_layer(layer, network_interface, responses) {
modify_inputs.fill_gradient_set(gradient, gradient_type, gradient_spread, transform);
modify_inputs.fill_gradient_set(gradient, gradient_form, gradient_spread, transform);
}
}
GraphOperationMessage::BlendingFillSet { layer, fill } => {
@@ -75,9 +75,9 @@ impl MessageHandler<GraphOperationMessage, GraphOperationMessageContext<'_>> for
modify_inputs.gradient_transform_set(transform);
}
}
GraphOperationMessage::GradientTypeSet { layer, gradient_type } => {
GraphOperationMessage::GradientFormSet { layer, gradient_form } => {
if let Some(mut modify_inputs) = ModifyInputsContext::new_with_layer(layer, network_interface, responses) {
modify_inputs.gradient_type_set(gradient_type);
modify_inputs.gradient_form_set(gradient_form);
}
}
GraphOperationMessage::GradientSpreadSet { layer, gradient_spread } => {
@@ -823,7 +823,7 @@ fn apply_usvg_fill(fill: &usvg::Fill, modify_inputs: &mut ModifyInputsContext, g
let direction = end - start;
let transform = DAffine2::from_cols(direction, direction.perp(), start);
let gradient_type = GradientType::Linear;
let gradient_form = GradientForm::Linear;
let gradient = match graphite_gradient_stops.get(linear.id()) {
Some(graphite_stops) => graphite_stops.clone(),
@@ -837,7 +837,7 @@ fn apply_usvg_fill(fill: &usvg::Fill, modify_inputs: &mut ModifyInputsContext, g
}
};
let gradient_spread = convert_gradient_spread(linear.spread_method());
modify_inputs.fill_gradient_set(gradient, gradient_type, gradient_spread, transform);
modify_inputs.fill_gradient_set(gradient, gradient_form, gradient_spread, transform);
}
usvg::Paint::RadialGradient(radial) => {
let gradient_transform = usvg_transform(radial.transform());
@@ -847,7 +847,7 @@ fn apply_usvg_fill(fill: &usvg::Fill, modify_inputs: &mut ModifyInputsContext, g
let direction = end - start;
let transform = DAffine2::from_cols(direction, direction.perp(), start);
let gradient_type = GradientType::Radial;
let gradient_form = GradientForm::Radial;
let gradient = match graphite_gradient_stops.get(radial.id()) {
Some(graphite_stops) => graphite_stops.clone(),
@@ -862,7 +862,7 @@ fn apply_usvg_fill(fill: &usvg::Fill, modify_inputs: &mut ModifyInputsContext, g
};
let gradient_spread = convert_gradient_spread(radial.spread_method());
modify_inputs.fill_gradient_set(gradient, gradient_type, gradient_spread, transform);
modify_inputs.fill_gradient_set(gradient, gradient_form, gradient_spread, transform);
}
usvg::Paint::Pattern(_) => warn!("SVG patterns are not currently supported"),
};
@@ -16,7 +16,7 @@ use graphene_std::raster::BlendMode;
use graphene_std::raster_types::Image;
use graphene_std::subpath::Subpath;
use graphene_std::text::{Font, TypesettingConfig};
use graphene_std::vector::style::{GradientSpread, GradientType, Stroke};
use graphene_std::vector::style::{GradientForm, GradientSpread, Stroke};
use graphene_std::vector::{Gradient, GradientRamp, PointId, Vector, VectorModification, VectorModificationType};
use graphene_std::{Artboard, Color, Graphic};
@@ -403,7 +403,7 @@ impl<'a> ModifyInputsContext<'a> {
self.set_input_with_refresh(input_connector, NodeInput::value(fill_value, false), false);
}
pub fn fill_gradient_set(&mut self, gradient: Gradient, gradient_type: GradientType, gradient_spread: GradientSpread, transform: DAffine2) {
pub fn fill_gradient_set(&mut self, gradient: Gradient, gradient_form: GradientForm, gradient_spread: GradientSpread, transform: DAffine2) {
let Some(fill_node_id) = self.existing_proto_node_id(graphene_std::vector_nodes::fill::IDENTIFIER, true) else {
return;
};
@@ -442,8 +442,8 @@ impl<'a> ModifyInputsContext<'a> {
}
self.set_input_with_refresh(
InputConnector::node(fill_node_id, graphene_std::vector::fill::GradientTypeInput),
NodeInput::value(TaggedValue::GradientType(gradient_type), false),
InputConnector::node(fill_node_id, graphene_std::vector::fill::GradientFormInput),
NodeInput::value(TaggedValue::GradientForm(gradient_form), false),
false,
);
}
@@ -660,20 +660,20 @@ impl<'a> ModifyInputsContext<'a> {
self.responses.add(NodeGraphMessage::RunDocumentGraph);
}
/// Write the gradient type to the last 'Gradient Type' node in the chain, inserting one only when the value differs
/// Write the Gradient Form to the last 'Gradient Form' node in the chain, inserting one only when the value differs
/// from the default (`Linear`).
pub fn gradient_type_set(&mut self, gradient_type: GradientType) {
pub fn gradient_form_set(&mut self, gradient_form: GradientForm) {
let Some(output_layer) = self.get_output_layer() else { return };
let target_input = gradient_chain_target_input(output_layer, self.network_interface);
let identifier = graphene_std::math_nodes::gradient_type::IDENTIFIER;
let create_if_nonexistent = gradient_type != GradientType::default();
let identifier = graphene_std::math_nodes::gradient_form::IDENTIFIER;
let create_if_nonexistent = gradient_form != GradientForm::default();
let Some(node_id) = self.existing_proto_node_id_at(&target_input, identifier, create_if_nonexistent) else {
return;
};
let input_connector = InputConnector::node(node_id, graphene_std::math_nodes::gradient_type::GradientTypeInput);
self.set_input_with_refresh(input_connector, NodeInput::value(TaggedValue::GradientType(gradient_type), false), false);
let input_connector = InputConnector::node(node_id, graphene_std::math_nodes::gradient_form::GradientFormInput);
self.set_input_with_refresh(input_connector, NodeInput::value(TaggedValue::GradientForm(gradient_form), false), false);
}
/// Write the gradient spread to the last 'Gradient Spread' node in the chain, inserting one only when the value differs
@@ -33,7 +33,7 @@ use graphene_std::vector::misc::{
ArcType, BoxCorners, CentroidType, ExtrudeJoiningAlgorithm, GridType, InterpolationDistribution, MergeByDistanceAlgorithm, PointSpacingType, RowsOrColumns, SpiralType,
};
use graphene_std::vector::style::{
FillChoice, Gradient, GradientRamp, GradientSpread, GradientStops, GradientType, PaintOrder, StrokeAlign, StrokeCap, StrokeJoin, build_transform_with_y_preservation,
FillChoice, Gradient, GradientForm, GradientRamp, GradientSpread, GradientStops, PaintOrder, StrokeAlign, StrokeCap, StrokeJoin, build_transform_with_y_preservation,
};
use graphene_std::vector::{QRCodeErrorCorrectionLevel, VectorModification};
use graphene_std::{NodeParameter, ParameterRef};
@@ -301,7 +301,7 @@ pub(crate) fn property_from_type(
// =========================
// AUTO-GENERATED ENUM TYPES
// =========================
Some(x) if id_is::<GradientType>(x) => enum_choice::<GradientType>().for_socket(default_info).property_row(),
Some(x) if id_is::<GradientForm>(x) => enum_choice::<GradientForm>().for_socket(default_info).property_row(),
Some(x) if id_is::<GradientSpread>(x) => enum_choice::<GradientSpread>().for_socket(default_info).property_row(),
Some(x) if id_is::<RealTimeMode>(x) => enum_choice::<RealTimeMode>().for_socket(default_info).property_row(),
Some(x) if id_is::<RedGreenBlue>(x) => enum_choice::<RedGreenBlue>().for_socket(default_info).property_row(),
@@ -2400,7 +2400,7 @@ pub(crate) fn fill_properties(node_id: NodeId, context: &mut NodePropertiesConte
Solid(Option<Color>),
Gradient {
gradient: Gradient,
gradient_type: GradientType,
gradient_form: GradientForm,
gradient_spread: GradientSpread,
transform: DAffine2,
/// Whether the transform input holds a plain value (so the "Reverse Direction" button may write to it) rather than a wire.
@@ -2430,7 +2430,7 @@ pub(crate) fn fill_properties(node_id: NodeId, context: &mut NodePropertiesConte
}) {
Some(gradient) => ResolvedFill::Gradient {
gradient: gradient.stops,
gradient_type: gradient.gradient_type,
gradient_form: gradient.gradient_form,
gradient_spread: gradient.gradient_spread,
transform: gradient.transform,
transform_is_value: gradient.transform_is_value,
@@ -2582,7 +2582,7 @@ pub(crate) fn fill_properties(node_id: NodeId, context: &mut NodePropertiesConte
widgets.push(fill_type_switch);
if let ResolvedFill::Gradient {
gradient_type,
gradient_form,
transform,
transform_is_value,
..
@@ -2601,7 +2601,7 @@ pub(crate) fn fill_properties(node_id: NodeId, context: &mut NodePropertiesConte
let reverse_direction_button = IconButton::new(if orientation_rightward { "ReverseRadialGradientToRight" } else { "ReverseRadialGradientToLeft" }, 24)
.tooltip_label("Reverse Direction")
.tooltip_description(graph_modification_utils::reverse_direction_tooltip_description(gradient_type))
.tooltip_description(graph_modification_utils::reverse_direction_tooltip_description(gradient_form))
.on_update(move |_| Message::Batched {
messages: Box::new([
NodeGraphMessage::SetInputValue {
@@ -2625,19 +2625,19 @@ pub(crate) fn fill_properties(node_id: NodeId, context: &mut NodePropertiesConte
add_blank_assist(&mut row);
}
let entries = [GradientType::Linear, GradientType::Radial]
let entries = [GradientForm::Linear, GradientForm::Radial]
.iter()
.map(|&gradient_type| {
RadioEntryData::new(format!("{:?}", gradient_type))
.label(format!("{:?}", gradient_type))
.on_update(update_value(move |_| TaggedValue::GradientType(gradient_type), node_id, GradientTypeInput))
.map(|&gradient_form| {
RadioEntryData::new(format!("{:?}", gradient_form))
.label(format!("{:?}", gradient_form))
.on_update(update_value(move |_| TaggedValue::GradientForm(gradient_form), node_id, GradientFormInput))
.on_commit(commit_value)
})
.collect();
row.extend_from_slice(&[
Separator::new(SeparatorStyle::Unrelated).widget_instance(),
RadioInput::new(entries).selected_index(Some(gradient_type as u32)).widget_instance(),
RadioInput::new(entries).selected_index(Some(gradient_form as u32)).widget_instance(),
]);
widgets.push(LayoutGroup::row(row));
@@ -167,6 +167,10 @@ const NODE_REPLACEMENTS: &[NodeReplacement<'static>] = &[
"graphic_nodes::graphic::ExtractElementNode",
],
},
NodeReplacement {
node: graphene_std::graphic::read_attribute_gradient_form::IDENTIFIER,
aliases: &["graphic_nodes::graphic::ReadAttributeGradientTypeNode"],
},
NodeReplacement {
node: graphene_std::graphic::read_attribute_gradient_spread::IDENTIFIER,
aliases: &["graphic_nodes::graphic::ReadAttributeSpreadMethodNode"],
@@ -266,6 +270,10 @@ const NODE_REPLACEMENTS: &[NodeReplacement<'static>] = &[
node: graphene_std::math_nodes::footprint_value::IDENTIFIER,
aliases: &["graphene_math_nodes::FootprintValueNode", "graphene_core::ops::FootprintValueNode"],
},
NodeReplacement {
node: graphene_std::math_nodes::gradient_form::IDENTIFIER,
aliases: &["math_nodes::GradientTypeNode"],
},
NodeReplacement {
node: graphene_std::math_nodes::gradient_spread::IDENTIFIER,
aliases: &["math_nodes::SpreadMethodNode"],
@@ -1626,7 +1634,7 @@ fn migrate_node(node_id: &NodeId, node: &DocumentNode, network_path: &[NodeId],
}
// Upgrade the legacy 4-input Fill node (content, fill: Fill, _backup_color, _backup_gradient: Gradient) to the value-model
// 7-input shape (content, fill: generic paint list, _backup_color, _backup_gradient, _gradient_type, _has_transform, _transform).
// 7-input shape (content, fill: generic paint list, _backup_color, _backup_gradient, _gradient_form, _has_transform, _transform).
if reference == DefinitionIdentifier::ProtoNode(graphene_std::vector_nodes::fill::IDENTIFIER) && inputs_count == 4 {
let mut node_template = resolve_document_node_type(&reference)?.default_node_template();
document.network_interface.replace_implementation(node_id, network_path, &mut node_template);
@@ -1655,7 +1663,7 @@ fn migrate_node(node_id: &NodeId, node: &DocumentNode, network_path: &[NodeId],
if let graphic_types::migrations::legacy::LegacyFill::Gradient(gradient) = old_fill {
document.network_interface.set_input(
&InputConnector::node_at_index(*node_id, 4),
NodeInput::value(TaggedValue::GradientType(gradient.gradient_type), false),
NodeInput::value(TaggedValue::GradientForm(gradient.gradient_type), false),
network_path,
);
@@ -1707,7 +1715,7 @@ fn migrate_node(node_id: &NodeId, node: &DocumentNode, network_path: &[NodeId],
) {
document.network_interface.set_input(
&InputConnector::node_at_index(*node_id, 4),
NodeInput::value(TaggedValue::GradientType(g.gradient_type), false),
NodeInput::value(TaggedValue::GradientForm(g.gradient_type), false),
network_path,
);
@@ -14,7 +14,7 @@ use graphene_std::subpath::Subpath;
use graphene_std::text::{Font, TypesettingConfig};
use graphene_std::vector::misc::ManipulatorPointId;
use graphene_std::vector::style::{FillChoice, PaintOrder, StrokeAlign, StrokeCap, StrokeJoin, initial_gradient_transform_for_bounding_box};
use graphene_std::vector::{Gradient, GradientSpread, GradientType, PointId, SegmentId, VectorModificationType};
use graphene_std::vector::{Gradient, GradientForm, GradientSpread, PointId, SegmentId, VectorModificationType};
use graphene_std::{NodeParameter, ParameterRef};
use std::collections::VecDeque;
@@ -381,11 +381,11 @@ pub fn gradient_space_transform(layer: LayerNodeIdentifier, network_interface: &
metadata.transform_to_viewport(layer)
}
/// Tooltip description for a "Reverse Direction" gradient button, phrased for the given gradient type.
pub fn reverse_direction_tooltip_description(gradient_type: GradientType) -> &'static str {
match gradient_type {
GradientType::Radial => "Reverse which end the gradient radiates from.",
GradientType::Linear => "Swap the start and end points of the gradient line.",
/// Tooltip description for a "Reverse Direction" gradient button, phrased for the given Gradient Form.
pub fn reverse_direction_tooltip_description(gradient_form: GradientForm) -> &'static str {
match gradient_form {
GradientForm::Radial => "Reverse which end the gradient radiates from.",
GradientForm::Linear => "Swap the start and end points of the gradient line.",
}
}
@@ -659,7 +659,7 @@ pub fn set_stroke_weight_for_selected_layers(weight: f64, document: &DocumentMes
/// A Fill node's decoded gradient inputs, with the transform kept in its raw form (not yet baked into `start`/`end`).
pub struct FillNodeGradient {
pub stops: Gradient,
pub gradient_type: GradientType,
pub gradient_form: GradientForm,
pub gradient_spread: GradientSpread,
pub transform: DAffine2,
/// Whether the transform input holds a plain value (so it may be written to) rather than a wire.
@@ -675,9 +675,9 @@ pub fn read_fill_node_gradient(fill_node: &DocumentNode, bounding_box: impl FnOn
};
let gradient_spread = ramp.gradient_spread;
let stops = Gradient::from(ramp);
let gradient_type = match fill_node.input(fill::GradientTypeInput).and_then(|input| input.as_value()) {
Some(&TaggedValue::GradientType(value)) => value,
_ => GradientType::default(),
let gradient_form = match fill_node.input(fill::GradientFormInput).and_then(|input| input.as_value()) {
Some(&TaggedValue::GradientForm(value)) => value,
_ => GradientForm::default(),
};
let has_transform = matches!(fill_node.input(fill::HasTransformInput).and_then(|input| input.as_value()), Some(&TaggedValue::Bool(true)));
let transform_input = fill_node.input(fill::TransformInput).and_then(|input| input.as_value());
@@ -689,7 +689,7 @@ pub fn read_fill_node_gradient(fill_node: &DocumentNode, bounding_box: impl FnOn
Some(FillNodeGradient {
stops,
gradient_type,
gradient_form,
gradient_spread,
transform,
transform_is_value: transform_input.is_some(),
@@ -824,9 +824,9 @@ pub fn set_fill_for_selected_layers(fill_choice: FillChoice, document: &Document
use graphene_std::vector::fill;
let fill_parameters = NodeGraphLayer::new(layer, &document.network_interface).find_node_parameters(fill::IDENTIFIER);
let gradient_type = match fill_parameters.as_ref().and_then(|parameters| parameters.value(fill::GradientTypeInput)) {
Some(TaggedValue::GradientType(value)) => *value,
_ => GradientType::default(),
let gradient_form = match fill_parameters.as_ref().and_then(|parameters| parameters.value(fill::GradientFormInput)) {
Some(TaggedValue::GradientForm(value)) => *value,
_ => GradientForm::default(),
};
let has_transform = matches!(fill_parameters.as_ref().and_then(|parameters| parameters.value(fill::HasTransformInput)), Some(TaggedValue::Bool(true)));
let transform = match (has_transform, fill_parameters.as_ref().and_then(|parameters| parameters.value(fill::TransformInput))) {
@@ -838,7 +838,7 @@ pub fn set_fill_for_selected_layers(fill_choice: FillChoice, document: &Document
responses.add(GraphOperationMessage::FillGradientSet {
layer,
gradient: Gradient::from(ramp),
gradient_type,
gradient_form,
gradient_spread: ramp.gradient_spread,
transform,
});
@@ -16,7 +16,7 @@ use glam::DMat2;
use graph_craft::document::value::TaggedValue;
use graphene_std::color::SRGBA8;
use graphene_std::raster::color::Color;
use graphene_std::vector::style::{FillChoice, Gradient, GradientRamp, GradientSpread, GradientStop, GradientType, build_transform_with_y_preservation};
use graphene_std::vector::style::{FillChoice, Gradient, GradientForm, GradientRamp, GradientSpread, GradientStop, build_transform_with_y_preservation};
#[derive(Default, ExtractField)]
pub struct GradientTool {
@@ -27,7 +27,7 @@ pub struct GradientTool {
#[derive(Default)]
pub struct GradientOptions {
gradient_type: GradientType,
gradient_form: GradientForm,
gradient_spread: GradientSpread,
}
@@ -60,7 +60,7 @@ pub enum GradientToolMessage {
#[cfg_attr(feature = "wasm", derive(tsify::Tsify))]
#[derive(PartialEq, Eq, Clone, Debug, Hash, serde::Serialize, serde::Deserialize)]
pub enum GradientOptionsUpdate {
Type(GradientType),
Form(GradientForm),
ReverseStops,
ReverseDirection,
}
@@ -82,14 +82,14 @@ impl<'a> MessageHandler<ToolMessage, &mut ToolActionMessageContext<'a>> for Grad
fn process_message(&mut self, message: ToolMessage, responses: &mut VecDeque<Message>, context: &mut ToolActionMessageContext<'a>) {
match message {
ToolMessage::Gradient(GradientToolMessage::UpdateOptions { options }) => match options {
GradientOptionsUpdate::Type(gradient_type) => {
self.options.gradient_type = gradient_type;
GradientOptionsUpdate::Form(gradient_form) => {
self.options.gradient_form = gradient_form;
apply_gradient_update(
&mut self.data,
context,
responses,
|(_gradient, appearance)| appearance.gradient_type != gradient_type,
|(_gradient, appearance)| appearance.gradient_type = gradient_type,
|(_gradient, appearance)| appearance.gradient_form != gradient_form,
|(_gradient, appearance)| appearance.gradient_form = gradient_form,
);
responses.add(ToolMessage::UpdateHints);
responses.add(ToolMessage::UpdateCursor);
@@ -167,8 +167,8 @@ impl<'a> MessageHandler<ToolMessage, &mut ToolActionMessageContext<'a>> for Grad
let mut needs_refresh = false;
if let Some((_gradient, appearance)) = &current_gradient {
if self.options.gradient_type != appearance.gradient_type {
self.options.gradient_type = appearance.gradient_type;
if self.options.gradient_form != appearance.gradient_form {
self.options.gradient_form = appearance.gradient_form;
needs_refresh = true;
}
if self.options.gradient_spread != appearance.gradient_spread {
@@ -230,21 +230,21 @@ impl LayoutHolder for GradientTool {
fn layout(&self) -> Layout {
let mut widgets: Vec<WidgetInstance> = Vec::new();
let gradient_type = RadioInput::new(vec![
let gradient_form = RadioInput::new(vec![
RadioEntryData::new("Linear").label("Linear").tooltip_label("Linear Gradient").on_update(move |_| {
GradientToolMessage::UpdateOptions {
options: GradientOptionsUpdate::Type(GradientType::Linear),
options: GradientOptionsUpdate::Form(GradientForm::Linear),
}
.into()
}),
RadioEntryData::new("Radial").label("Radial").tooltip_label("Radial Gradient").on_update(move |_| {
GradientToolMessage::UpdateOptions {
options: GradientOptionsUpdate::Type(GradientType::Radial),
options: GradientOptionsUpdate::Form(GradientForm::Radial),
}
.into()
}),
])
.selected_index(Some((self.options.gradient_type == GradientType::Radial) as u32))
.selected_index(Some((self.options.gradient_form == GradientForm::Radial) as u32))
.widget_instance();
// Display priority: the selected layer's stops, then any user-customized tool default, then the working colors
@@ -296,7 +296,7 @@ impl LayoutHolder for GradientTool {
};
let reverse_direction = IconButton::new(reverse_direction_icon, 24)
.tooltip_label("Reverse Direction")
.tooltip_description(reverse_direction_tooltip_description(self.options.gradient_type))
.tooltip_description(reverse_direction_tooltip_description(self.options.gradient_form))
.disabled(!self.data.has_selected_gradient)
.on_update(|_| {
GradientToolMessage::UpdateOptions {
@@ -311,7 +311,7 @@ impl LayoutHolder for GradientTool {
Separator::new(SeparatorStyle::Related).widget_instance(),
reverse_stops,
Separator::new(SeparatorStyle::Unrelated).widget_instance(),
gradient_type,
gradient_form,
Separator::new(SeparatorStyle::Related).widget_instance(),
reverse_direction,
]);
@@ -362,7 +362,7 @@ fn resolve_gradient(layer: LayerNodeIdentifier, network_interface: &NodeNetworkI
return Some((
gradient.stops,
GradientAppearance {
gradient_type: gradient.gradient_type,
gradient_form: gradient.gradient_form,
gradient_spread: gradient.gradient_spread,
transform: gradient.transform,
},
@@ -381,7 +381,7 @@ fn resolve_gradient(layer: LayerNodeIdentifier, network_interface: &NodeNetworkI
#[derive(Clone, Copy, Debug, Default)]
struct GradientAppearance {
transform: DAffine2,
gradient_type: GradientType,
gradient_form: GradientForm,
gradient_spread: GradientSpread,
}
@@ -392,11 +392,11 @@ fn read_gradient_chain_state(layer: LayerNodeIdentifier, network_interface: &Nod
let walk_from = network_interface.upstream_output_connector(&target_input, &[]).and_then(|out| out.node_id()).unwrap_or(layer.to_node());
let transform_reference = DefinitionIdentifier::ProtoNode(graphene_std::transform_nodes::transform::IDENTIFIER);
let gradient_type_reference = DefinitionIdentifier::ProtoNode(graphene_std::math_nodes::gradient_type::IDENTIFIER);
let gradient_form_reference = DefinitionIdentifier::ProtoNode(graphene_std::math_nodes::gradient_form::IDENTIFIER);
let gradient_spread_reference = DefinitionIdentifier::ProtoNode(graphene_std::math_nodes::gradient_spread::IDENTIFIER);
let mut transforms_downstream_to_upstream: Vec<DAffine2> = Vec::new();
let mut gradient_type: Option<GradientType> = None;
let mut gradient_form: Option<GradientForm> = None;
let mut gradient_spread: Option<GradientSpread> = None;
for node_id in network_interface
@@ -411,11 +411,11 @@ fn read_gradient_chain_state(layer: LayerNodeIdentifier, network_interface: &Nod
if reference == transform_reference {
transforms_downstream_to_upstream.push(read_transform_node_value(&document_node.inputs));
} else if reference == gradient_type_reference
&& gradient_type.is_none()
&& let Some(TaggedValue::GradientType(value)) = document_node.inputs.get(1).and_then(|input| input.as_value())
} else if reference == gradient_form_reference
&& gradient_form.is_none()
&& let Some(TaggedValue::GradientForm(value)) = document_node.inputs.get(1).and_then(|input| input.as_value())
{
gradient_type = Some(*value);
gradient_form = Some(*value);
} else if reference == gradient_spread_reference
&& gradient_spread.is_none()
&& let Some(TaggedValue::GradientSpread(value)) = document_node.inputs.get(1).and_then(|input| input.as_value())
@@ -429,7 +429,7 @@ fn read_gradient_chain_state(layer: LayerNodeIdentifier, network_interface: &Nod
GradientAppearance {
transform: composed_transform,
gradient_type: gradient_type.unwrap_or_default(),
gradient_form: gradient_form.unwrap_or_default(),
gradient_spread: gradient_spread.unwrap_or_default(),
}
}
@@ -552,7 +552,7 @@ impl SelectedGradient {
responses: &mut VecDeque<Message>,
snap_rotate: bool,
lock_angle: bool,
gradient_type: GradientType,
gradient_form: GradientForm,
drag_start: DVec2,
snap_data: SnapData,
snap_manager: &mut SnapManager,
@@ -565,7 +565,7 @@ impl SelectedGradient {
return;
}
self.appearance.gradient_type = gradient_type;
self.appearance.gradient_form = gradient_form;
let anchor_point = || {
let (start, end) = self.viewport_handle_positions();
@@ -765,7 +765,7 @@ impl SelectedGradient {
responses.add(GraphOperationMessage::FillGradientSet {
layer,
gradient: self.gradient.clone(),
gradient_type: self.appearance.gradient_type,
gradient_form: self.appearance.gradient_form,
gradient_spread: self.appearance.gradient_spread,
transform: self.appearance.transform,
});
@@ -797,9 +797,9 @@ fn dispatch_gradient_chain_writes(layer: LayerNodeIdentifier, gradient: &Gradien
layer,
transform: appearance.transform,
});
responses.add(GraphOperationMessage::GradientTypeSet {
responses.add(GraphOperationMessage::GradientFormSet {
layer,
gradient_type: appearance.gradient_type,
gradient_form: appearance.gradient_form,
});
responses.add(GraphOperationMessage::GradientSpreadSet {
layer,
@@ -808,9 +808,9 @@ fn dispatch_gradient_chain_writes(layer: LayerNodeIdentifier, gradient: &Gradien
}
impl GradientTool {
/// Get the gradient type of the selected gradient (if it exists)
pub fn selected_gradient(&self) -> Option<GradientType> {
self.data.selected_gradient.as_ref().map(|selected| selected.appearance.gradient_type)
/// Get the Gradient Form of the selected gradient (if it exists)
pub fn selected_gradient(&self) -> Option<GradientForm> {
self.data.selected_gradient.as_ref().map(|selected| selected.appearance.gradient_form)
}
}
@@ -1482,7 +1482,7 @@ impl Fsm for GradientToolFsmState {
]),
GradientAppearance {
transform: DAffine2::IDENTITY,
gradient_type: tool_options.gradient_type,
gradient_form: tool_options.gradient_form,
gradient_spread: tool_options.gradient_spread,
},
GradientSource::Direct,
@@ -1533,7 +1533,7 @@ impl Fsm for GradientToolFsmState {
responses,
input.keyboard.get(constrain_axis as usize),
input.keyboard.get(lock_angle as usize),
selected_gradient.appearance.gradient_type,
selected_gradient.appearance.gradient_form,
drag_start_viewport,
snap_data,
&mut tool_data.snap_manager,
@@ -1835,7 +1835,7 @@ fn apply_gradient_update(
responses.add(GraphOperationMessage::FillGradientSet {
layer,
gradient,
gradient_type: appearance.gradient_type,
gradient_form: appearance.gradient_form,
gradient_spread: appearance.gradient_spread,
transform: appearance.transform,
});
@@ -1882,7 +1882,7 @@ fn apply_stops_update(data: &mut GradientToolData, context: &mut ToolActionMessa
responses.add(GraphOperationMessage::FillGradientSet {
layer,
gradient: new_gradient.clone(),
gradient_type: appearance.gradient_type,
gradient_form: appearance.gradient_form,
gradient_spread,
transform: appearance.transform,
});
+2 -1
View File
@@ -551,7 +551,8 @@ tagged_value! {
StrokeJoin(vector::style::StrokeJoin),
StrokeAlign(vector::style::StrokeAlign),
PaintOrder(vector::style::PaintOrder),
GradientType(vector::style::GradientType),
#[serde(alias = "GradientType")] // TODO: Eventually remove this document upgrade code
GradientForm(vector::style::GradientForm),
#[serde(alias = "GradientSpreadMethod")] // TODO: Eventually remove this document upgrade code
GradientSpread(vector::style::GradientSpread),
ReferencePoint(vector::ReferencePoint),
@@ -24,7 +24,7 @@ use graphene_std::transform::{Footprint, ReferencePoint, ScaleType};
use graphene_std::vector::misc::{
ArcType, BooleanOperation, BoxCorners, CentroidType, ExtrudeJoiningAlgorithm, GridType, InterpolationDistribution, MergeByDistanceAlgorithm, PointSpacingType, RowsOrColumns, SpiralType,
};
use graphene_std::vector::style::{DashPattern, GradientSpread, GradientType, PaintOrder, StrokeAlign, StrokeCap, StrokeJoin};
use graphene_std::vector::style::{DashPattern, GradientForm, GradientSpread, PaintOrder, StrokeAlign, StrokeCap, StrokeJoin};
use graphene_std::vector::{QRCodeErrorCorrectionLevel, Vector, VectorModification};
use graphene_std::{Artboard, Context, Graphic, NodeIO, NodeIOTypes, ProtoNodeIdentifier, concrete, fn_type_fut, future};
use node_registry_macros::async_node;
@@ -74,7 +74,7 @@ fn node_registry() -> HashMap<ProtoNodeIdentifier, HashMap<NodeIOTypes, NodeCons
async_node!(graphene_core::memo::MonitorNode<_, _, _>, input: Context, fn_params: [Context => List<bool>]),
async_node!(graphene_core::memo::MonitorNode<_, _, _>, input: Context, fn_params: [Context => List<DAffine2>]),
async_node!(graphene_core::memo::MonitorNode<_, _, _>, input: Context, fn_params: [Context => List<BlendMode>]),
async_node!(graphene_core::memo::MonitorNode<_, _, _>, input: Context, fn_params: [Context => List<GradientType>]),
async_node!(graphene_core::memo::MonitorNode<_, _, _>, input: Context, fn_params: [Context => List<GradientForm>]),
async_node!(graphene_core::memo::MonitorNode<_, _, _>, input: Context, fn_params: [Context => List<GradientSpread>]),
async_node!(graphene_core::memo::MonitorNode<_, _, _>, input: Context, fn_params: [Context => Item<AttributeValueDyn>]),
async_node!(graphene_core::memo::MonitorNode<_, _, _>, input: Context, fn_params: [Context => ListDyn]),
@@ -108,7 +108,7 @@ fn node_registry() -> HashMap<ProtoNodeIdentifier, HashMap<NodeIOTypes, NodeCons
async_node!(graphene_core::memo::MemoizeNode<_, _>, input: Context, fn_params: [Context => List<bool>]),
async_node!(graphene_core::memo::MemoizeNode<_, _>, input: Context, fn_params: [Context => List<DAffine2>]),
async_node!(graphene_core::memo::MemoizeNode<_, _>, input: Context, fn_params: [Context => List<BlendMode>]),
async_node!(graphene_core::memo::MemoizeNode<_, _>, input: Context, fn_params: [Context => List<GradientType>]),
async_node!(graphene_core::memo::MemoizeNode<_, _>, input: Context, fn_params: [Context => List<GradientForm>]),
async_node!(graphene_core::memo::MemoizeNode<_, _>, input: Context, fn_params: [Context => List<GradientSpread>]),
async_node!(graphene_core::memo::MemoizeNode<_, _>, input: Context, fn_params: [Context => Item<Artboard>]),
async_node!(graphene_core::memo::MemoizeNode<_, _>, input: Context, fn_params: [Context => Item<Graphic>]),
@@ -331,7 +331,7 @@ fn node_registry() -> HashMap<ProtoNodeIdentifier, HashMap<NodeIOTypes, NodeCons
StrokeAlign,
StrokeCap,
PaintOrder,
GradientType,
GradientForm,
GradientSpread,
DashPattern,
BoxCorners,
@@ -420,7 +420,7 @@ fn node_registry() -> HashMap<ProtoNodeIdentifier, HashMap<NodeIOTypes, NodeCons
DVec2,
DAffine2,
BlendMode,
GradientType,
GradientForm,
GradientSpread
));
#[cfg(feature = "gpu")]
@@ -535,7 +535,7 @@ fn node_registry() -> HashMap<ProtoNodeIdentifier, HashMap<NodeIOTypes, NodeCons
attribute_value_node!(Item<DAffine2>),
attribute_value_node!(Item<Color>),
attribute_value_node!(Item<BlendMode>),
attribute_value_node!(Item<GradientType>),
attribute_value_node!(Item<GradientForm>),
attribute_value_node!(Item<GradientSpread>),
attribute_value_node!(Item<NodeIdPath>),
attribute_value_node!(List<String>),
+1 -1
View File
@@ -25,7 +25,7 @@ pub use graphene_hash;
pub use graphene_hash::CacheHash;
pub use list::{
ATTR_BACKGROUND, ATTR_BLEND_MODE, ATTR_CLIP, ATTR_CLIPPING_MASK, ATTR_DIMENSIONS, ATTR_EDITOR_CLICK_TARGET, ATTR_EDITOR_LAYER_PATH, ATTR_EDITOR_MERGED_LAYERS, ATTR_EDITOR_TEXT_FRAME, ATTR_END,
ATTR_FONT, ATTR_FONT_SIZE, ATTR_GRADIENT_SPREAD, ATTR_GRADIENT_TYPE, ATTR_LETTER_SPACING, ATTR_LETTER_TILT, ATTR_LINE_HEIGHT, ATTR_LOCATION, ATTR_MAX_HEIGHT, ATTR_MAX_WIDTH, ATTR_NAME,
ATTR_FONT, ATTR_FONT_SIZE, ATTR_GRADIENT_FORM, ATTR_GRADIENT_SPREAD, ATTR_LETTER_SPACING, ATTR_LETTER_TILT, ATTR_LINE_HEIGHT, ATTR_LOCATION, ATTR_MAX_HEIGHT, ATTR_MAX_WIDTH, ATTR_NAME,
ATTR_OPACITY, ATTR_OPACITY_FILL, ATTR_START, ATTR_TEXT_ALIGN, ATTR_TRANSFORM, ATTR_TYPE,
};
pub use memo::MemoHash;
+3 -3
View File
@@ -58,8 +58,8 @@ pub const ATTR_CLIP: &str = "clip";
// TODO: Consider adding "gradient_spread_left" and "gradient_spread_right" override attributes to allow setting different gradient spreads on each side of a gradient
/// Gradient's `GradientSpread` (`Pad`, `Reflect`, or `Repeat`).
pub const ATTR_GRADIENT_SPREAD: &str = "gradient_spread";
/// Gradient's `GradientType` (`Linear` or `Radial`).
pub const ATTR_GRADIENT_TYPE: &str = "gradient_type";
/// Gradient's `GradientForm` (`Linear` or `Radial`).
pub const ATTR_GRADIENT_FORM: &str = "gradient_form";
/// Gradient stop's `f64` position from 0 to 1 along the gradient, on the `List<Color>` inside a `Gradient`.
/// When the attribute is absent, stops distribute evenly across the 0 to 1 range.
pub const ATTR_POSITION: &str = "position";
@@ -1229,7 +1229,7 @@ impl<T: CacheHash> CacheHash for List<T> {
self.element.cache_hash(state);
// Hash every attribute attribute (key + values) rather than just the well-known ones, so changes to user-defined keys
// (e.g., gradient_type, gradient_spread) invalidate downstream graph caches as expected
// (e.g., gradient_form, gradient_spread) invalidate downstream graph caches as expected
for (key, attribute) in &self.attributes.attributes {
std::hash::Hash::hash(key.as_str(), state);
attribute.cache_hash_dyn(state);
@@ -29,7 +29,7 @@ pub mod migrations {
pub struct LegacyGradient {
#[serde(deserialize_with = "crate::migrations::migrate_to_gradient_ramp")]
pub stops: GradientRamp,
pub gradient_type: vector::style::GradientType,
pub gradient_type: vector::style::GradientForm,
pub start: DVec2,
pub end: DVec2,
#[serde(default)]
@@ -51,7 +51,7 @@ pub mod migrations {
// The legacy radial drew as a circle in the layer's own space; bake the adjustment that, composed with the
// endpoint frame, makes the new pipeline reproduce that circle through the (possibly non-uniform) layer transform.
let radial_invertible = self.gradient_type == vector::style::GradientType::Radial
let radial_invertible = self.gradient_type == vector::style::GradientForm::Radial
&& layer_transform.is_finite()
&& layer_transform.matrix2.determinant().recip().is_finite()
&& direction.length_squared() > 1e-20;
@@ -3,10 +3,10 @@ use crate::{Render, RenderSvgSegmentList, SvgRender};
use core_types::color::SRGBA8;
use core_types::list::List;
use core_types::uuid::generate_uuid;
use core_types::{ATTR_GRADIENT_SPREAD, ATTR_GRADIENT_TYPE, ATTR_TRANSFORM, Color};
use core_types::{ATTR_GRADIENT_FORM, ATTR_GRADIENT_SPREAD, ATTR_TRANSFORM, Color};
use glam::{DAffine2, DVec2};
use graphic_types::Graphic;
use graphic_types::vector_types::gradient::GradientType;
use graphic_types::vector_types::gradient::GradientForm;
use graphic_types::vector_types::vector::style::{PaintOrder, Stroke, StrokeAlign, StrokeCap, StrokeJoin};
use std::fmt::Write;
use vector_types::Gradient;
@@ -93,7 +93,7 @@ impl RenderExt for List<Gradient> {
let mut stop = String::new();
let Some(stops) = self.element(0) else { return 0 };
let gradient_type: GradientType = self.attribute_cloned_or_default(ATTR_GRADIENT_TYPE, 0);
let gradient_form: GradientForm = self.attribute_cloned_or_default(ATTR_GRADIENT_FORM, 0);
let local_gradient_transform: DAffine2 = self.attribute_cloned_or_default(ATTR_TRANSFORM, 0);
let gradient_spread: GradientSpread = self.attribute_cloned_or_default(ATTR_GRADIENT_SPREAD, 0);
@@ -126,7 +126,7 @@ impl RenderExt for List<Gradient> {
let document_transform = item_transform * local_gradient_transform;
let placement = gradient_placement(document_transform, gradient_type);
let placement = gradient_placement(document_transform, gradient_form);
let gradient_transform = format_transform_matrix(element_transform_inverse * placement);
let gradient_transform = if gradient_transform.is_empty() {
String::new()
@@ -142,15 +142,15 @@ impl RenderExt for List<Gradient> {
let gradient_id = generate_uuid();
match gradient_type {
GradientType::Linear => {
match gradient_form {
GradientForm::Linear => {
let _ = write!(
svg_defs,
r#"<linearGradient id="{}" gradientUnits="userSpaceOnUse" x1="0" y1="0" x2="1" y2="0"{gradient_spread}{gradient_transform}>{}</linearGradient>"#,
gradient_id, stop
);
}
GradientType::Radial => {
GradientForm::Radial => {
let _ = write!(
svg_defs,
r#"<radialGradient id="{}" gradientUnits="userSpaceOnUse" cx="0" cy="0" r="1"{gradient_spread}{gradient_transform}>{}</radialGradient>"#,
+21 -21
View File
@@ -14,7 +14,7 @@ use core_types::transform::Footprint;
use core_types::uuid::{NodeId, generate_uuid};
use core_types::{
ATTR_BACKGROUND, ATTR_BLEND_MODE, ATTR_CLIP, ATTR_CLIPPING_MASK, ATTR_DIMENSIONS, ATTR_EDITOR_CLICK_TARGET, ATTR_EDITOR_LAYER_PATH, ATTR_EDITOR_MERGED_LAYERS, ATTR_EDITOR_TEXT_FRAME, ATTR_FONT,
ATTR_FONT_SIZE, ATTR_GRADIENT_SPREAD, ATTR_GRADIENT_TYPE, ATTR_LETTER_SPACING, ATTR_LETTER_TILT, ATTR_LINE_HEIGHT, ATTR_LOCATION, ATTR_MAX_HEIGHT, ATTR_MAX_WIDTH, ATTR_OPACITY, ATTR_OPACITY_FILL,
ATTR_FONT_SIZE, ATTR_GRADIENT_FORM, ATTR_GRADIENT_SPREAD, ATTR_LETTER_SPACING, ATTR_LETTER_TILT, ATTR_LINE_HEIGHT, ATTR_LOCATION, ATTR_MAX_HEIGHT, ATTR_MAX_WIDTH, ATTR_OPACITY, ATTR_OPACITY_FILL,
ATTR_TEXT_ALIGN, ATTR_TRANSFORM,
};
use dyn_any::DynAny;
@@ -23,7 +23,7 @@ use graphene_hash::CacheHashWrapper;
use graphene_resource::Resource;
use graphic_types::graphic::{graphic_list_at, has_paint_at, is_paint_present, set_paint_attribute};
use graphic_types::raster_types::{BitmapMut, CPU, GPU, Image, Raster, Texture};
use graphic_types::vector_types::gradient::{Gradient, GradientType};
use graphic_types::vector_types::gradient::{Gradient, GradientForm};
use graphic_types::vector_types::subpath::Subpath;
use graphic_types::vector_types::vector::click_target::{ClickTarget, FreePoint};
use graphic_types::vector_types::vector::style::{PaintOrder, RenderMode, StrokeAlign, StrokeCap, StrokeJoin};
@@ -379,10 +379,10 @@ pub(crate) fn transform_is_invertible(transform: DAffine2) -> bool {
/// non-uniform transform makes an ellipse), while linear is reduced to the equivalent non-sheared gradient line (the
/// axis projected onto the band normal) so the iso-color bands keep following a sheared transform, which Vello can
/// represent since it stores only two endpoints.
pub(crate) fn gradient_placement(transform: DAffine2, gradient_type: GradientType) -> DAffine2 {
match gradient_type {
GradientType::Radial => transform,
GradientType::Linear => {
pub(crate) fn gradient_placement(transform: DAffine2, gradient_form: GradientForm) -> DAffine2 {
match gradient_form {
GradientForm::Radial => transform,
GradientForm::Linear => {
let axis = transform.matrix2.x_axis;
let band_normal = transform.matrix2.y_axis.perp();
let line = if band_normal.length_squared() > 0. { axis.project_onto(band_normal) } else { axis };
@@ -422,23 +422,23 @@ fn peniko_color_stops(gradient: &Gradient) -> peniko::ColorStops {
fn create_peniko_gradient_brush(gradient_list: &List<Gradient>, multiplied_transform: &DAffine2) -> Option<(peniko::Brush, DAffine2)> {
let stops = gradient_list.element(0)?;
let gradient_type: GradientType = gradient_list.attribute_cloned_or_default(ATTR_GRADIENT_TYPE, 0);
let gradient_form: GradientForm = gradient_list.attribute_cloned_or_default(ATTR_GRADIENT_FORM, 0);
let gradient_transform: DAffine2 = gradient_list.attribute_cloned_or_default(ATTR_TRANSFORM, 0);
let gradient_spread: GradientSpread = gradient_list.attribute_cloned_or_default(ATTR_GRADIENT_SPREAD, 0);
let peniko_stops = peniko_color_stops(stops);
// The unit gradient is placed by the desheared frame so a non-uniform transform produces the intended ellipse
let (start, end, gradient_to_device) = (DVec2::ZERO, DVec2::X, gradient_placement(multiplied_transform * gradient_transform, gradient_type));
let (start, end, gradient_to_device) = (DVec2::ZERO, DVec2::X, gradient_placement(multiplied_transform * gradient_transform, gradient_form));
let brush = peniko::Brush::Gradient(peniko::Gradient {
kind: match gradient_type {
GradientType::Linear => peniko::LinearGradientPosition {
kind: match gradient_form {
GradientForm::Linear => peniko::LinearGradientPosition {
start: to_point(start),
end: to_point(end),
}
.into(),
GradientType::Radial => peniko::RadialGradientPosition {
GradientForm::Radial => peniko::RadialGradientPosition {
start_center: to_point(start),
start_radius: 0.,
end_center: to_point(start),
@@ -2095,7 +2095,7 @@ impl Render for List<Gradient> {
let opacity_attr: f64 = self.attribute_cloned_or(ATTR_OPACITY, index, 1.);
let opacity_fill_attr: f64 = self.attribute_cloned_or(ATTR_OPACITY_FILL, index, 1.);
let gradient_spread: GradientSpread = self.attribute_cloned_or_default(ATTR_GRADIENT_SPREAD, index);
let gradient_type: GradientType = self.attribute_cloned_or_default(ATTR_GRADIENT_TYPE, index);
let gradient_form: GradientForm = self.attribute_cloned_or_default(ATTR_GRADIENT_FORM, index);
let tag = if thumbnail_rect.is_some() { "rect" } else { "polyline" };
render.leaf_tag(tag, |attributes| {
if let Some((min, size)) = thumbnail_rect {
@@ -2140,14 +2140,14 @@ impl Render for List<Gradient> {
};
// The unit gradient line is the +X unit vector in local space, before the item's transform is applied
match gradient_type {
GradientType::Linear => {
match gradient_form {
GradientForm::Linear => {
let _ = write!(
&mut attributes.0.svg_defs,
r#"<linearGradient id="{gradient_id}" gradientUnits="userSpaceOnUse" x1="0" y1="0" x2="1" y2="0"{gradient_spread_attribute}{gradient_transform_attribute}>{stop_string}</linearGradient>"#
);
}
GradientType::Radial => {
GradientForm::Radial => {
let _ = write!(
&mut attributes.0.svg_defs,
r#"<radialGradient id="{gradient_id}" gradientUnits="userSpaceOnUse" cx="0" cy="0" r="1"{gradient_spread_attribute}{gradient_transform_attribute}>{stop_string}</radialGradient>"#
@@ -2176,11 +2176,11 @@ impl Render for List<Gradient> {
return;
}
for (((index, gradient), gradient_spread), gradient_type) in self
for (((index, gradient), gradient_spread), gradient_form) in self
.iter_element_values()
.enumerate()
.zip(self.iter_attribute_values_or_default::<GradientSpread>(ATTR_GRADIENT_SPREAD))
.zip(self.iter_attribute_values_or_default::<GradientType>(ATTR_GRADIENT_TYPE))
.zip(self.iter_attribute_values_or_default::<GradientForm>(ATTR_GRADIENT_FORM))
{
let transform: DAffine2 = self.attribute_cloned_or_default(ATTR_TRANSFORM, index);
let blend_mode_attr: BlendMode = self.attribute_cloned_or_default(ATTR_BLEND_MODE, index);
@@ -2201,13 +2201,13 @@ impl Render for List<Gradient> {
// The unit gradient line is the +X unit vector in local space, before the item's transform is applied.
// For radial, the unit-radius circle at the origin scales out to the line's length once the brush transform applies.
let kind = match gradient_type {
GradientType::Linear => peniko::LinearGradientPosition {
let kind = match gradient_form {
GradientForm::Linear => peniko::LinearGradientPosition {
start: to_point(DVec2::ZERO),
end: to_point(DVec2::X),
}
.into(),
GradientType::Radial => peniko::RadialGradientPosition {
GradientForm::Radial => peniko::RadialGradientPosition {
start_center: to_point(DVec2::ZERO),
start_radius: 0.,
end_center: to_point(DVec2::ZERO),
@@ -2223,7 +2223,7 @@ impl Render for List<Gradient> {
interpolation_alpha_space: peniko::InterpolationAlphaSpace::Premultiplied,
..Default::default()
});
let brush_transform = kurbo::Affine::new(gradient_placement(gradient_transform, gradient_type).to_cols_array());
let brush_transform = kurbo::Affine::new(gradient_placement(gradient_transform, gradient_form).to_cols_array());
let rect = kurbo::Rect::from_origin_size(kurbo::Point::ZERO, kurbo::Size::new(1., 1.));
let mut layer = false;
@@ -9,7 +9,7 @@ use glam::{DAffine2, DVec2};
#[derive(Default, PartialEq, Eq, Clone, Copy, Debug, Hash, graphene_hash::CacheHash, DynAny, node_macro::ChoiceType)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[widget(Radio)]
pub enum GradientType {
pub enum GradientForm {
#[default]
Linear,
Radial,
+1 -1
View File
@@ -8,7 +8,7 @@ pub mod vector;
// Re-export commonly used types at the crate root
pub use core_types as gcore;
pub use gradient::{Gradient, GradientRamp, GradientSpread, GradientStop, GradientType};
pub use gradient::{Gradient, GradientForm, GradientRamp, GradientSpread, GradientStop};
pub use math::{QuadExt, RectExt};
pub use subpath::Subpath;
pub use vector::Vector;
+6 -6
View File
@@ -9,7 +9,7 @@ use rand::SeedableRng;
use rand::seq::SliceRandom;
use raster_types::{CPU, GPU, Raster};
use std::cmp::Ordering;
use vector_types::gradient::{GradientSpread, GradientType};
use vector_types::gradient::{GradientForm, GradientSpread};
use vector_types::{Gradient, ReferencePoint};
/// Returns the list with the item at the specified index removed.
@@ -567,7 +567,7 @@ async fn write_attribute<T: AnyHash + Clone + Send + Sync + CacheHash>(
List<Gradient>,
List<Artboard>,
List<BlendMode>,
List<GradientType>,
List<GradientForm>,
List<GradientSpread>,
)]
content: List<T>,
@@ -713,18 +713,18 @@ fn read_attribute_blend_mode(
result
}
/// Reads a named `GradientType` attribute from the input list, outputting each value as an element of a new `GradientType[]`.
/// Reads a named `GradientForm` attribute from the input list, outputting each value as an element of a new `GradientForm[]`.
#[node_macro::node(category("Attributes: Read"))]
fn read_attribute_gradient_type(
fn read_attribute_gradient_form(
_: impl Ctx,
content: ListDyn,
/// The attribute name (key) to read.
name: Item<String>,
) -> List<GradientType> {
) -> List<GradientForm> {
let name = name.into_element();
let mut result = List::with_capacity(content.len());
for index in 0..content.len() {
let Some(value) = content.attribute::<GradientType>(&name, index) else { continue };
let Some(value) = content.attribute::<GradientForm>(&name, index) else { continue };
result.push(Item::new_from_element(*value));
}
result
+3 -3
View File
@@ -1377,11 +1377,11 @@ fn gradient_value(_: impl Ctx, _primary: (), #[default(Color::BLACK, Color::WHIT
gradient
}
/// Sets the type (linear or radial) of each gradient in the input list.
/// Sets the form (linear or radial) of each gradient in the input list.
#[node_macro::node(category("Gradient"))]
fn gradient_type(_: impl Ctx, gradient: Item<Gradient>, gradient_type: Item<vector_types::GradientType>) -> Item<Gradient> {
fn gradient_form(_: impl Ctx, gradient: Item<Gradient>, gradient_form: Item<vector_types::GradientForm>) -> Item<Gradient> {
let mut gradient = gradient;
gradient.set_attribute(core_types::ATTR_GRADIENT_TYPE, *gradient_type.element());
gradient.set_attribute(core_types::ATTR_GRADIENT_FORM, *gradient_form.element());
gradient
}
+4 -4
View File
@@ -1,10 +1,10 @@
use core_types::list::{ATTR_FILL, Item, ItemAttributeValues, List};
use core_types::{
ATTR_BLEND_MODE, ATTR_CLIPPING_MASK, ATTR_EDITOR_LAYER_PATH, ATTR_EDITOR_MERGED_LAYERS, ATTR_GRADIENT_SPREAD, ATTR_GRADIENT_TYPE, ATTR_OPACITY, ATTR_OPACITY_FILL, ATTR_TRANSFORM, Color, Ctx,
ATTR_BLEND_MODE, ATTR_CLIPPING_MASK, ATTR_EDITOR_LAYER_PATH, ATTR_EDITOR_MERGED_LAYERS, ATTR_GRADIENT_FORM, ATTR_GRADIENT_SPREAD, ATTR_OPACITY, ATTR_OPACITY_FILL, ATTR_TRANSFORM, Color, Ctx,
};
use glam::{DAffine2, DVec2};
use graphic_types::graphic::{bake_paint_transforms, set_paint_attribute};
use graphic_types::vector_types::gradient::{GradientSpread, GradientType};
use graphic_types::vector_types::gradient::{GradientForm, GradientSpread};
use graphic_types::vector_types::subpath::{ManipulatorGroup, Subpath};
use graphic_types::vector_types::vector::PointId;
use graphic_types::vector_types::vector::algorithms::merge_by_distance::MergeByDistanceExt;
@@ -283,8 +283,8 @@ fn flatten_vector(graphic_list: &List<Graphic>) -> List<Vector> {
if let Some(transform) = attributes.remove::<DAffine2>(ATTR_TRANSFORM) {
gradient_paint.set_attribute(ATTR_TRANSFORM, 0, transform);
}
if let Some(gradient_type) = attributes.remove::<GradientType>(ATTR_GRADIENT_TYPE) {
gradient_paint.set_attribute(ATTR_GRADIENT_TYPE, 0, gradient_type);
if let Some(gradient_form) = attributes.remove::<GradientForm>(ATTR_GRADIENT_FORM) {
gradient_paint.set_attribute(ATTR_GRADIENT_FORM, 0, gradient_form);
}
if let Some(gradient_spread) = attributes.remove::<GradientSpread>(ATTR_GRADIENT_SPREAD) {
gradient_paint.set_attribute(ATTR_GRADIENT_SPREAD, 0, gradient_spread);
+7 -7
View File
@@ -8,7 +8,7 @@ use core_types::registry::types::{Angle, Length, Multiplier, Percentage, PixelLe
use core_types::transform::{Footprint, Transform};
use core_types::uuid::NodeId;
use core_types::{
ATTR_BLEND_MODE, ATTR_CLIPPING_MASK, ATTR_EDITOR_LAYER_PATH, ATTR_EDITOR_MERGED_LAYERS, ATTR_GRADIENT_TYPE, ATTR_OPACITY, ATTR_OPACITY_FILL, ATTR_TRANSFORM, CloneVarArgs, Color, Context, Ctx,
ATTR_BLEND_MODE, ATTR_CLIPPING_MASK, ATTR_EDITOR_LAYER_PATH, ATTR_EDITOR_MERGED_LAYERS, ATTR_GRADIENT_FORM, ATTR_OPACITY, ATTR_OPACITY_FILL, ATTR_TRANSFORM, CloneVarArgs, Color, Context, Ctx,
ExtractAll, OwnedContextImpl,
};
use glam::{DAffine2, DMat2, DVec2};
@@ -21,7 +21,7 @@ use kurbo::{Affine, BezPath, DEFAULT_ACCURACY, Line, ParamCurve, ParamCurveArcle
use rand::{Rng, SeedableRng};
use std::collections::hash_map::DefaultHasher;
use std::collections::{HashMap, HashSet};
use vector_types::GradientType;
use vector_types::GradientForm;
use vector_types::gradient::{build_transform_with_y_preservation, initial_gradient_transform_for_bounding_box};
use vector_types::subpath::{BezierHandles, ManipulatorGroup};
use vector_types::vector::algorithms::bezpath_algorithms::{self, TValue, eval_pathseg_euclidean, evaluate_bezpath, split_bezpath, tangent_on_bezpath};
@@ -191,14 +191,14 @@ async fn fill<V, F: IntoGraphicList + 'n + Send + 'static>(
fill: F,
_backup_color: Item<Color>,
#[default(Color::BLACK, Color::WHITE)] _backup_gradient: Item<Gradient>,
_gradient_type: Item<GradientType>,
_gradient_form: Item<GradientForm>,
_has_transform: Item<bool>,
_transform: Item<DAffine2>,
) -> Item<V>
where
Item<V>: VectorItemMut + 'n + Send,
{
let _gradient_type = _gradient_type.into_element();
let _gradient_form = _gradient_form.into_element();
let (_has_transform, _transform) = (_has_transform.into_element(), *_transform.element());
let mut content = content;
@@ -208,9 +208,9 @@ where
for graphic in fill.iter_element_values_mut() {
let Graphic::Gradient(gradient) = graphic else { continue };
if gradient.iter_attribute_values::<GradientType>(ATTR_GRADIENT_TYPE).is_none() {
for value in gradient.iter_attribute_values_mut_or_default::<GradientType>(ATTR_GRADIENT_TYPE) {
*value = _gradient_type;
if gradient.iter_attribute_values::<GradientForm>(ATTR_GRADIENT_FORM).is_none() {
for value in gradient.iter_attribute_values_mut_or_default::<GradientForm>(ATTR_GRADIENT_FORM) {
*value = _gradient_form;
}
}