mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-09-15 22:28:10 +08:00
Bring the editor onto the reconciled node catalog and paint carrier
This commit is contained in:
@@ -2767,7 +2767,7 @@ impl DocumentMessageHandler {
|
||||
}
|
||||
|
||||
let solidify_stroke_definition = document_node_definitions::resolve_proto_node_type(graphene_std::vector::solidify_stroke::IDENTIFIER).expect("Solidify Stroke node should exist");
|
||||
let item_at_index_definition = document_node_definitions::resolve_proto_node_type(graphene_std::graphic::item_at_index::IDENTIFIER).expect("Item at Index node should exist");
|
||||
let item_at_index_definition = document_node_definitions::resolve_proto_node_type(graphene_std::graphic::index_elements::IDENTIFIER).expect("Item at Index node should exist");
|
||||
|
||||
let mut resulting_layers: Vec<NodeId> = Vec::new();
|
||||
|
||||
@@ -2777,13 +2777,14 @@ impl DocumentMessageHandler {
|
||||
continue;
|
||||
}
|
||||
|
||||
let appearance = self.network_interface.document_metadata().layer_appearance_attributes.get(&layer);
|
||||
let metadata = self.network_interface.document_metadata();
|
||||
let fill_paint = metadata.layer_fill_attributes.get(&layer);
|
||||
let stroke_paint = metadata.layer_stroke_attributes.get(&layer);
|
||||
|
||||
let has_fill = appearance.is_some_and(|appearance| appearance.has_painted_cover(Cover::Fill));
|
||||
let has_fill = fill_paint.is_some_and(|paint| paint.element(0).is_some_and(|graphic| !graphic.is_guaranteed_fully_transparent()));
|
||||
// A visible stroke needs both renderable geometry (non-zero weight) and paint that draws something
|
||||
let has_stroke = appearance.is_some_and(|appearance| {
|
||||
appearance.first_coverage_of(Cover::Stroke).is_some_and(|coverage| coverage.stroke_params().has_renderable_stroke())
|
||||
&& appearance.first_paint_of(Cover::Stroke).is_some_and(|paint| !paint.is_guaranteed_fully_transparent())
|
||||
let has_stroke = stroke_paint.is_some_and(|paint| {
|
||||
graphene_std::renderer::stroke_params(paint).has_renderable_stroke() && paint.element(0).is_some_and(|graphic| !graphic.is_guaranteed_fully_transparent())
|
||||
});
|
||||
|
||||
// No stroke means there's nothing to solidify. Fill-only layers are already in the desired form, so skip.
|
||||
|
||||
@@ -12,7 +12,7 @@ use glam::{DAffine2, DVec2, IVec2};
|
||||
use graph_craft::application_io::resource::ResourceId;
|
||||
use graph_craft::document::value::TaggedValue;
|
||||
use graph_craft::document::{NodeId, NodeInput};
|
||||
use graph_craft::{ProtoNodeIdentifier, concrete};
|
||||
use graph_craft::{ProtoNodeIdentifier, concrete, descriptor};
|
||||
use graphene_std::list::List;
|
||||
use graphene_std::raster::BlendMode;
|
||||
use graphene_std::raster_types::Image;
|
||||
@@ -71,8 +71,8 @@ impl<'a> ModifyInputsContext<'a> {
|
||||
/// Creates an artboard as the primary export for the document network.
|
||||
pub fn create_artboard(&mut self, new_id: NodeId, location: DVec2, dimensions: DVec2, background: Color, clip: bool) -> LayerNodeIdentifier {
|
||||
let artboard_node_template = resolve_network_node_type("Artboard").expect("Node").node_template_input_override([
|
||||
Some(NodeInput::type_default(concrete!(List<Artboard>), true)),
|
||||
Some(NodeInput::type_default(concrete!(List<Graphic>), true)),
|
||||
Some(NodeInput::type_default(descriptor!(List<Artboard>), true)),
|
||||
Some(NodeInput::type_default(descriptor!(List<Graphic>), true)),
|
||||
Some(NodeInput::value(TaggedValue::DVec2(location), false)),
|
||||
Some(NodeInput::value(TaggedValue::DVec2(dimensions), false)),
|
||||
Some(NodeInput::value(TaggedValue::Color(background), false)),
|
||||
@@ -86,7 +86,7 @@ impl<'a> ModifyInputsContext<'a> {
|
||||
let boolean = resolve_proto_node_type(graphene_std::path_bool_nodes::boolean_operation::IDENTIFIER)
|
||||
.expect("Boolean node does not exist")
|
||||
.node_template_input_override([
|
||||
Some(NodeInput::type_default(concrete!(List<Graphic>), true)),
|
||||
Some(NodeInput::type_default(descriptor!(List<Graphic>), true)),
|
||||
Some(NodeInput::value(TaggedValue::BooleanOperation(operation), false)),
|
||||
]);
|
||||
|
||||
@@ -98,7 +98,7 @@ impl<'a> ModifyInputsContext<'a> {
|
||||
pub fn insert_blend_data(&mut self, layer: LayerNodeIdentifier, count: f64) -> NodeId {
|
||||
let blend = resolve_network_node_type("Blend")
|
||||
.expect("Blend node does not exist")
|
||||
.node_template_input_override([Some(NodeInput::type_default(concrete!(List<Graphic>), true)), Some(NodeInput::value(TaggedValue::F64(count), false))]);
|
||||
.node_template_input_override([Some(NodeInput::type_default(descriptor!(List<Graphic>), true)), Some(NodeInput::value(TaggedValue::F64(count), false))]);
|
||||
|
||||
let blend_id = NodeId::new();
|
||||
self.network_interface.insert_node(blend_id, blend, &[]);
|
||||
@@ -110,7 +110,7 @@ impl<'a> ModifyInputsContext<'a> {
|
||||
pub fn insert_morph_data(&mut self, layer: LayerNodeIdentifier) -> NodeId {
|
||||
let morph = resolve_proto_node_type(graphene_std::vector::morph::IDENTIFIER)
|
||||
.expect("Morph node does not exist")
|
||||
.node_template_input_override([Some(NodeInput::type_default(concrete!(List<Graphic>), true)), Some(NodeInput::value(TaggedValue::F64(0.5), false))]);
|
||||
.node_template_input_override([Some(NodeInput::type_default(descriptor!(List<Graphic>), true)), Some(NodeInput::value(TaggedValue::F64(0.5), false))]);
|
||||
|
||||
let morph_id = NodeId::new();
|
||||
self.network_interface.insert_node(morph_id, morph, &[]);
|
||||
@@ -859,9 +859,9 @@ impl<'a> ModifyInputsContext<'a> {
|
||||
self.set_input_with_refresh(input_connector, NodeInput::value(TaggedValue::StrokeJoin(stroke.join), false), true);
|
||||
let input_connector = InputConnector::node(stroke_node_id, graphene_std::vector::stroke::MiterLimitInput);
|
||||
self.set_input_with_refresh(input_connector, NodeInput::value(TaggedValue::F64(stroke.join_miter_limit), false), false);
|
||||
// Our stroke node keeps a paint order input rather than encoding the order by Fill/Stroke node adjacency
|
||||
// Our stroke node keeps a paint order input rather than encoding the order by Fill/Stroke node adjacency, and master's `Stroke` no longer carries one to copy
|
||||
let input_connector = InputConnector::node(stroke_node_id, graphene_std::vector::stroke::PaintOrderInput);
|
||||
self.set_input_with_refresh(input_connector, NodeInput::value(TaggedValue::PaintOrder(stroke.paint_order), false), false);
|
||||
self.set_input_with_refresh(input_connector, NodeInput::value(TaggedValue::PaintOrder(Default::default()), false), false);
|
||||
let input_connector = InputConnector::node(stroke_node_id, graphene_std::vector::stroke::DashPatternInput);
|
||||
self.set_input_with_refresh(input_connector, NodeInput::value(TaggedValue::DashPattern(stroke.dash_lengths), false), true);
|
||||
let input_connector = InputConnector::node(stroke_node_id, graphene_std::vector::stroke::DashOffsetInput);
|
||||
|
||||
@@ -14,6 +14,7 @@ use graph_craft::ProtoNodeIdentifier;
|
||||
use graph_craft::document::value::*;
|
||||
use graph_craft::document::*;
|
||||
use graph_craft::concrete;
|
||||
use graph_craft::descriptor;
|
||||
use graphene_std::extract_xy::XY;
|
||||
use graphene_std::list::List;
|
||||
use graphene_std::raster::{CellularDistanceFunction, CellularReturnType, Color, DomainWarpType, FractalType, NoiseType, RedGreenBlueAlpha};
|
||||
@@ -162,7 +163,7 @@ fn document_node_definitions() -> HashMap<DefinitionIdentifier, DocumentNodeDefi
|
||||
// Collection of the content into the layer's group; the wrap keeps the content level's element type for the legacy boundary
|
||||
NodeTemplate {
|
||||
inputs: vec![NodeInput::import(generic!(T), 1)],
|
||||
implementation: NodeTemplateImplementation::ProtoNode(graphic::wrap_graphic::IDENTIFIER),
|
||||
implementation: NodeTemplateImplementation::ProtoNode(graphic::into_group::IDENTIFIER),
|
||||
node_type_metadata: NodeTypePersistentMetadata::node(IVec2::new(-21, -1)),
|
||||
..Default::default()
|
||||
},
|
||||
@@ -203,7 +204,7 @@ fn document_node_definitions() -> HashMap<DefinitionIdentifier, DocumentNodeDefi
|
||||
.collect(),
|
||||
..Default::default()
|
||||
}),
|
||||
inputs: vec![NodeInput::type_default(concrete!(List<Graphic>), true), NodeInput::type_default(concrete!(List<Graphic>), true)],
|
||||
inputs: vec![NodeInput::type_default(descriptor!(List<Graphic>), true), NodeInput::type_default(descriptor!(List<Graphic>), true)],
|
||||
input_metadata: vec![("Base", "TODO").into(), ("Content", "TODO").into()],
|
||||
output_names: vec!["Out".to_string()],
|
||||
node_type_metadata: NodeTypePersistentMetadata::layer(IVec2::new(0, 0)),
|
||||
@@ -297,8 +298,8 @@ fn document_node_definitions() -> HashMap<DefinitionIdentifier, DocumentNodeDefi
|
||||
..Default::default()
|
||||
}),
|
||||
inputs: vec![
|
||||
NodeInput::type_default(concrete!(List<Artboard>), true),
|
||||
NodeInput::type_default(concrete!(List<Graphic>), true),
|
||||
NodeInput::type_default(descriptor!(List<Artboard>), true),
|
||||
NodeInput::type_default(descriptor!(List<Graphic>), true),
|
||||
NodeInput::value(TaggedValue::DVec2(DVec2::ZERO), false),
|
||||
NodeInput::value(TaggedValue::DVec2(DVec2::new(1920., 1080.)), false),
|
||||
NodeInput::value(TaggedValue::Color(Color::WHITE), false),
|
||||
@@ -493,11 +494,11 @@ fn document_node_definitions() -> HashMap<DefinitionIdentifier, DocumentNodeDefi
|
||||
..Default::default()
|
||||
}),
|
||||
inputs: vec![
|
||||
NodeInput::type_default(concrete!(List<Vector>), true),
|
||||
NodeInput::type_default(descriptor!(List<Vector>), true),
|
||||
NodeInput::value(TaggedValue::F64(10.), false),
|
||||
NodeInput::value(TaggedValue::Bool(Default::default()), false),
|
||||
NodeInput::value(TaggedValue::InterpolationDistribution(Default::default()), false),
|
||||
NodeInput::type_default(concrete!(List<Vector>), false),
|
||||
NodeInput::type_default(descriptor!(List<Vector>), false),
|
||||
],
|
||||
input_metadata: vec![
|
||||
("Content", "TODO").into(),
|
||||
@@ -583,7 +584,7 @@ fn document_node_definitions() -> HashMap<DefinitionIdentifier, DocumentNodeDefi
|
||||
.collect(),
|
||||
..Default::default()
|
||||
}),
|
||||
inputs: vec![NodeInput::type_default(concrete!(List<Vector>), true)],
|
||||
inputs: vec![NodeInput::type_default(descriptor!(List<Vector>), true)],
|
||||
input_metadata: vec![("Vector", "TODO").into()],
|
||||
output_names: vec!["Vector".to_string()],
|
||||
node_type_metadata: NodeTypePersistentMetadata::node(IVec2::new(0, 0)),
|
||||
@@ -673,7 +674,7 @@ fn document_node_definitions() -> HashMap<DefinitionIdentifier, DocumentNodeDefi
|
||||
..Default::default()
|
||||
}),
|
||||
inputs: vec![
|
||||
NodeInput::type_default(concrete!(List<Vector>), true),
|
||||
NodeInput::type_default(descriptor!(List<Vector>), true),
|
||||
NodeInput::value(
|
||||
TaggedValue::Footprint(Footprint {
|
||||
transform: DAffine2::from_scale_angle_translation(DVec2::new(1000., 1000.), 0., DVec2::new(0., 0.)),
|
||||
@@ -750,7 +751,7 @@ fn document_node_definitions() -> HashMap<DefinitionIdentifier, DocumentNodeDefi
|
||||
.collect(),
|
||||
..Default::default()
|
||||
}),
|
||||
inputs: vec![NodeInput::type_default(concrete!(List<Raster<CPU>>), true)],
|
||||
inputs: vec![NodeInput::type_default(descriptor!(List<Raster<CPU>>), true)],
|
||||
input_metadata: vec![("Image", "TODO").into()],
|
||||
output_names: vec!["".to_string(), "Red".to_string(), "Green".to_string(), "Blue".to_string(), "Alpha".to_string()],
|
||||
..Default::default()
|
||||
@@ -803,7 +804,7 @@ fn document_node_definitions() -> HashMap<DefinitionIdentifier, DocumentNodeDefi
|
||||
category: "",
|
||||
node_template: NodeTemplate {
|
||||
implementation: NodeTemplateImplementation::Extract,
|
||||
inputs: vec![NodeInput::type_default(concrete!(DocumentNode), true)],
|
||||
inputs: vec![NodeInput::type_default(descriptor!(DocumentNode), true)],
|
||||
input_metadata: vec![("Node", "TODO").into()],
|
||||
output_names: vec!["Document Node".to_string()],
|
||||
..Default::default()
|
||||
@@ -917,7 +918,7 @@ fn document_node_definitions() -> HashMap<DefinitionIdentifier, DocumentNodeDefi
|
||||
..Default::default()
|
||||
}),
|
||||
inputs: vec![
|
||||
NodeInput::type_default(concrete!(Vector), true),
|
||||
NodeInput::type_default(descriptor!(Vector), true),
|
||||
NodeInput::value(TaggedValue::VectorModification(Default::default()), false),
|
||||
],
|
||||
input_metadata: vec![("Content", "TODO").into(), ("Modification", "TODO").into()],
|
||||
@@ -1585,7 +1586,7 @@ impl InputTypeConstraint {
|
||||
|
||||
// Find the union of all the possible types from the dynamic executor implementations
|
||||
let mut result_accepted = Self::empty();
|
||||
for node_io in implementations.keys() {
|
||||
for node_io in implementations.iter().map(|entry| &entry.io) {
|
||||
if let Some(input_type) = node_io.inputs.get(input_index) {
|
||||
result_accepted.insert(input_type);
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@ impl FrontendGraphDataType {
|
||||
match TaggedValue::from_type_or_none(input) {
|
||||
TaggedValue::U32(_) | TaggedValue::U64(_) | TaggedValue::F32(_) | TaggedValue::F64(_) | TaggedValue::DVec2(_) | TaggedValue::F64Array(_) | TaggedValue::DAffine2(_) => Self::Number,
|
||||
TaggedValue::Color(_) => Self::Color,
|
||||
TaggedValue::LegacyGradient(_) | TaggedValue::Gradient(_) => Self::Gradient,
|
||||
TaggedValue::LegacyGradient(_) | TaggedValue::GradientRamp(_) => Self::Gradient,
|
||||
TaggedValue::String(_) => Self::Typography,
|
||||
// Types whose `TaggedValue` variant has been removed are routed through `TypeDefault` and identified by the descriptor's type name.
|
||||
TaggedValue::TypeDefault(td) => match td.name.as_ref() {
|
||||
|
||||
@@ -236,11 +236,8 @@ impl DocumentMetadata {
|
||||
/// bounds for non-vector layers (groups, raster, text, color, gradient).
|
||||
pub fn bounding_box_document_with_stroke(&self, layer: LayerNodeIdentifier) -> Option<[DVec2; 2]> {
|
||||
if let Some(vector) = self.layer_vector_data.get(&layer) {
|
||||
let stroke = self
|
||||
.layer_appearance_attributes
|
||||
.get(&layer)
|
||||
.and_then(|appearance| appearance.first_coverage_of(graphene_std::Cover::Stroke))
|
||||
.map(graphene_std::Coverage::stroke_params);
|
||||
// The stroke geometry rides the stroke paint list's own attribute columns, the carrier that replaced the deleted `Vector::stroke`.
|
||||
let stroke = self.layer_stroke_attributes.get(&layer).map(|paint| graphene_std::renderer::stroke_params(paint));
|
||||
if let Some(bounds) = vector.stroke_inclusive_bounding_box_with_transform(self.transform_to_document(layer), stroke.as_ref()) {
|
||||
return Some(bounds);
|
||||
}
|
||||
|
||||
@@ -194,7 +194,7 @@ impl NodeNetworkInterface {
|
||||
log::error!("Proto node {node:?} not found in the node registry, in layer_chain_hosts_node");
|
||||
return false;
|
||||
};
|
||||
implementations.keys().any(|node_io| node_io.inputs.first().is_some_and(|content| content.nested_type() == element))
|
||||
implementations.iter().map(|entry| &entry.io).any(|node_io| node_io.inputs.first().is_some_and(|content| content.nested_type() == element))
|
||||
}
|
||||
None => !matches!(chain_type, TypeSource::Invalid),
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ use glam::{DVec2, IVec2};
|
||||
use graph_craft::application_io::resource::{DataSource, Resource, ResourceHash, ResourceId};
|
||||
use graph_craft::document::DocumentNode;
|
||||
use graph_craft::document::{DocumentNodeImplementation, NodeInput, value::TaggedValue};
|
||||
use graph_craft::{Type, concrete};
|
||||
use graph_craft::{Type, concrete, descriptor};
|
||||
use graphene_std::Color;
|
||||
use graphene_std::ParameterRef;
|
||||
use graphene_std::ProtoNodeIdentifier;
|
||||
@@ -148,7 +148,7 @@ const NODE_REPLACEMENTS: &[NodeReplacement<'static>] = &[
|
||||
aliases: &["graphene_core::graphic::FlattenVectorNode", "graphene_core::graphic_element::FlattenVectorNode"],
|
||||
},
|
||||
NodeReplacement {
|
||||
node: graphene_std::graphic::item_at_index::IDENTIFIER,
|
||||
node: graphene_std::graphic::index_elements::IDENTIFIER,
|
||||
aliases: &[
|
||||
"graphene_core::graphic_element::IndexNode",
|
||||
"graphene_core::graphic::IndexNode",
|
||||
@@ -158,15 +158,7 @@ const NODE_REPLACEMENTS: &[NodeReplacement<'static>] = &[
|
||||
],
|
||||
},
|
||||
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"],
|
||||
},
|
||||
NodeReplacement {
|
||||
node: graphene_std::graphic::remove_at_index::IDENTIFIER,
|
||||
node: graphene_std::graphic::omit_element::IDENTIFIER,
|
||||
aliases: &["graphic_nodes::graphic::OmitElementNode"],
|
||||
},
|
||||
NodeReplacement {
|
||||
@@ -784,7 +776,7 @@ const NODE_REPLACEMENTS: &[NodeReplacement<'static>] = &[
|
||||
aliases: &["graphene_core::vector::ClosePathNode"],
|
||||
},
|
||||
NodeReplacement {
|
||||
node: graphene_std::vector::list_length::IDENTIFIER,
|
||||
node: graphene_std::vector::count_elements::IDENTIFIER,
|
||||
aliases: &["graphene_core::vector::CountElementsNode"],
|
||||
},
|
||||
NodeReplacement {
|
||||
@@ -1425,10 +1417,10 @@ fn migrate_node(node_id: &NodeId, node: &DocumentNode, network_path: &[NodeId],
|
||||
if reference == DefinitionIdentifier::ProtoNode(graphene_std::vector::copy_to_points::IDENTIFIER) {
|
||||
let mut node_template = node_definition.default_node_template();
|
||||
let old_inputs = document.network_interface.replace_inputs(node_id, network_path, &mut node_template)?;
|
||||
document.network_interface.set_input(&InputConnector::node(*node_id, 0), old_inputs[1].clone(), network_path);
|
||||
document.network_interface.set_input(&InputConnector::node(*node_id, 1), old_inputs[0].clone(), network_path);
|
||||
document.network_interface.set_input(&InputConnector::node_at_index(*node_id, 0), old_inputs[1].clone(), network_path);
|
||||
document.network_interface.set_input(&InputConnector::node_at_index(*node_id, 1), old_inputs[0].clone(), network_path);
|
||||
for (index, input) in old_inputs.into_iter().enumerate().skip(2) {
|
||||
document.network_interface.set_input(&InputConnector::node(*node_id, index), input, network_path);
|
||||
document.network_interface.set_input(&InputConnector::node_at_index(*node_id, index), input, network_path);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1436,10 +1428,10 @@ fn migrate_node(node_id: &NodeId, node: &DocumentNode, network_path: &[NodeId],
|
||||
if reference == DefinitionIdentifier::ProtoNode(graphene_std::repeat::repeat_on_points::IDENTIFIER) {
|
||||
let mut node_template = node_definition.default_node_template();
|
||||
let old_inputs = document.network_interface.replace_inputs(node_id, network_path, &mut node_template)?;
|
||||
document.network_interface.set_input(&InputConnector::node(*node_id, 0), old_inputs[1].clone(), network_path);
|
||||
document.network_interface.set_input(&InputConnector::node(*node_id, 1), old_inputs[0].clone(), network_path);
|
||||
document.network_interface.set_input(&InputConnector::node_at_index(*node_id, 0), old_inputs[1].clone(), network_path);
|
||||
document.network_interface.set_input(&InputConnector::node_at_index(*node_id, 1), old_inputs[0].clone(), network_path);
|
||||
for (index, input) in old_inputs.into_iter().enumerate().skip(2) {
|
||||
document.network_interface.set_input(&InputConnector::node(*node_id, index), input, network_path);
|
||||
document.network_interface.set_input(&InputConnector::node_at_index(*node_id, index), input, network_path);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1898,7 +1890,7 @@ fn migrate_node(node_id: &NodeId, node: &DocumentNode, network_path: &[NodeId],
|
||||
// The stored no-paint sentinel was the `List<Graphic>` type default before the paint connectors ranked down to `Item<Graphic>`.
|
||||
// This must run before the stale-List-default cleanup below, which would otherwise adopt the definition's default paint.
|
||||
{
|
||||
let legacy_no_paint = TaggedValue::TypeDefault(concrete!(List<graphene_std::Graphic>));
|
||||
let legacy_no_paint = TaggedValue::TypeDefault(descriptor!(List<graphene_std::Graphic>));
|
||||
let paint_parameters: &[ParameterRef] = &[graphene_std::vector::fill::PaintInput.into(), graphene_std::vector::stroke::PaintInput.into()];
|
||||
for parameter in paint_parameters {
|
||||
if reference != DefinitionIdentifier::ProtoNode(parameter.node_identifier.clone()) {
|
||||
@@ -2490,7 +2482,7 @@ fn migrate_node(node_id: &NodeId, node: &DocumentNode, network_path: &[NodeId],
|
||||
};
|
||||
|
||||
// Create List Length node: counts content `List` items → N
|
||||
let Some(list_length_def) = resolve_document_node_type(&DefinitionIdentifier::ProtoNode(graphene_std::vector::list_length::IDENTIFIER)) else {
|
||||
let Some(list_length_def) = resolve_document_node_type(&DefinitionIdentifier::ProtoNode(graphene_std::vector::count_elements::IDENTIFIER)) else {
|
||||
log::error!("Could not get list_length node from definition when upgrading morph");
|
||||
document.network_interface.set_input(&InputConnector::node_at_index(*node_id, 1), old_inputs[1].clone(), network_path);
|
||||
return None;
|
||||
@@ -2717,7 +2709,7 @@ fn migrate_node(node_id: &NodeId, node: &DocumentNode, network_path: &[NodeId],
|
||||
|
||||
document.network_interface.set_input(
|
||||
&InputConnector::node_at_index(*node_id, 0),
|
||||
NodeInput::type_default(concrete!(graphene_std::vector::Vector), true),
|
||||
NodeInput::type_default(descriptor!(graphene_std::vector::Vector), true),
|
||||
network_path,
|
||||
);
|
||||
|
||||
@@ -2767,7 +2759,8 @@ fn migrate_node(node_id: &NodeId, node: &DocumentNode, network_path: &[NodeId],
|
||||
.input_from_connector(&InputConnector::node_at_index(*node_id, index), network_path)
|
||||
.is_some_and(|stored_input| match stored_input {
|
||||
NodeInput::Value { tagged_value, .. } => match &**tagged_value {
|
||||
TaggedValue::TypeDefault(stored_type) if matches!(stored_type, Type::Record(_)) && !tagged_value.is_no_paint() => {
|
||||
// Our type defaults name their type rather than carrying a structural rank, so a list-carrying wire is recognized by its name.
|
||||
TaggedValue::TypeDefault(stored_type) if stored_type.name.contains("list::List<") && !tagged_value.is_no_paint() => {
|
||||
!matches!(definition_input, NodeInput::Value { tagged_value, .. } if matches!(&**tagged_value, TaggedValue::TypeDefault(definition_type) if definition_type == stored_type))
|
||||
}
|
||||
_ => false,
|
||||
@@ -2905,11 +2898,15 @@ fn migrate_removed_catalog_definitions(node_id: &NodeId, node: &DocumentNode, ne
|
||||
if let Some(DefinitionIdentifier::Network(name)) = document.network_interface.reference(node_id, network_path)
|
||||
&& name == "Upload Texture"
|
||||
{
|
||||
let mut node_template = resolve_proto_node_type(graphene_std::platform_application_io::upload_texture::IDENTIFIER)?.default_node_template();
|
||||
document.network_interface.replace_implementation(node_id, network_path, &mut node_template);
|
||||
let old_inputs = document.network_interface.replace_inputs(node_id, network_path, &mut node_template)?;
|
||||
if let Some(content) = old_inputs.first() {
|
||||
document.network_interface.set_input(&InputConnector::node_at_index(*node_id, 0), content.clone(), network_path);
|
||||
// Our `upload_texture` node belongs to the optional wgpu-executor crate rather than to platform_application_io, so the conversion only exists in a GPU build.
|
||||
#[cfg(feature = "gpu")]
|
||||
{
|
||||
let mut node_template = resolve_proto_node_type(wgpu_executor::texture_conversion::upload_texture::IDENTIFIER)?.default_node_template();
|
||||
document.network_interface.replace_implementation(node_id, network_path, &mut node_template);
|
||||
let old_inputs = document.network_interface.replace_inputs(node_id, network_path, &mut node_template)?;
|
||||
if let Some(content) = old_inputs.first() {
|
||||
document.network_interface.set_input(&InputConnector::node_at_index(*node_id, 0), content.clone(), network_path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -582,7 +582,7 @@ mod test_artboard {
|
||||
Err(e) => panic!("Failed to evaluate graph: {e}"),
|
||||
};
|
||||
let mut artboards = List::new();
|
||||
for list in instrumented.grab_all_input::<graphene_std::graphic::extend::NewInput<Artboard>, List<Artboard>>(&editor.runtime) {
|
||||
for list in instrumented.grab_all_input::<graphene_std::graphic::extend::NewInput, List<Artboard>>(&editor.runtime) {
|
||||
for index in 0..list.len() {
|
||||
if let Some(item) = list.clone_item(index) {
|
||||
artboards.push(item);
|
||||
|
||||
@@ -388,7 +388,7 @@ const ATTR_PAINT_ORDER: &str = "paint_order";
|
||||
/// `Vector::stroke` is gone upstream. In our paint model a lane's stroke is the `ATTR_STROKE`
|
||||
/// `List<Graphic>`, so the stroke's GEOMETRY parameters ride that list's own attribute columns, on the
|
||||
/// same names master's `Coverage` uses. Mirrors `vector_nodes::stroke_params`, which writes them.
|
||||
fn stroke_params(paint: &List<Graphic>) -> StrokeStyle {
|
||||
pub fn stroke_params(paint: &List<Graphic>) -> StrokeStyle {
|
||||
let defaults = StrokeStyle::default();
|
||||
StrokeStyle {
|
||||
weight: paint.attribute_cloned_or(ATTR_WEIGHT, 0, defaults.weight),
|
||||
|
||||
@@ -29,25 +29,21 @@ pub(crate) fn generate_node_input_references(
|
||||
let struct_name = format_ident!("{}Input", input_ident.ident.to_string().to_case(Case::Pascal));
|
||||
let (fn_generic_params, phantom_data_declerations) = generate_phantom_data(used.iter());
|
||||
|
||||
// Only create structs with phantom data where necessary.
|
||||
generated_input_accessor.push(if phantom_data_declerations.is_empty() {
|
||||
quote! {
|
||||
pub struct #struct_name;
|
||||
}
|
||||
} else {
|
||||
quote! {
|
||||
pub struct #struct_name <#(#used),*>{
|
||||
#(#phantom_data_declerations,)*
|
||||
}
|
||||
}
|
||||
});
|
||||
// The marker is always a unit struct so it can be passed as a value; its generics would only have described
|
||||
// `Result`, which nothing reads through the marker.
|
||||
let _ = &phantom_data_declerations;
|
||||
generated_input_accessor.push(quote! {
|
||||
impl <#(#used),*> #core_types::NodeInputDecleration for #struct_name <#(#fn_generic_params),*> {
|
||||
pub struct #struct_name;
|
||||
});
|
||||
let result_ty = if used.is_empty() { quote!(#ty) } else { quote!(()) };
|
||||
let _ = &fn_generic_params;
|
||||
generated_input_accessor.push(quote! {
|
||||
impl #core_types::NodeInputDecleration for #struct_name {
|
||||
const INDEX: usize = #input_index;
|
||||
fn identifier() -> #core_types::ProtoNodeIdentifier {
|
||||
#inputs_module_name::IDENTIFIER.clone()
|
||||
}
|
||||
type Result = #ty;
|
||||
type Result = #result_ty;
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -393,10 +393,11 @@ fn fill<'e>(
|
||||
_backup_gradient: IList<Gradient>,
|
||||
_gradient_form: GradientForm,
|
||||
_gradient_spread: GradientSpread,
|
||||
_transform: Option<DAffine2>,
|
||||
_has_transform: bool,
|
||||
_transform: DAffine2,
|
||||
) -> Result<(Vector, Attr<'e, Fill>), Interrupt> {
|
||||
let mut paint = paint_table(paint);
|
||||
default_gradient_paint(&mut paint, element.bounding_box(), _gradient_form, _gradient_spread, _transform);
|
||||
default_gradient_paint(&mut paint, element.bounding_box(), _gradient_form, _gradient_spread, _has_transform.then_some(_transform));
|
||||
let parked = park_paint(ctx.arena(), paint)?;
|
||||
Ok((element, Attr(Some(parked))))
|
||||
}
|
||||
@@ -413,14 +414,15 @@ fn fill_graphic_leveled<'e>(
|
||||
_backup_gradient: IList<Gradient>,
|
||||
_gradient_form: GradientForm,
|
||||
_gradient_spread: GradientSpread,
|
||||
_transform: Option<DAffine2>,
|
||||
_has_transform: bool,
|
||||
_transform: DAffine2,
|
||||
) -> Result<(Graphic<'static>, Attr<'e, Fill>), Interrupt> {
|
||||
let bounds = match BoundingBox::bounding_box(&element, DAffine2::IDENTITY, false) {
|
||||
RenderBoundingBox::Rectangle(bounds) => Some(bounds),
|
||||
_ => None,
|
||||
};
|
||||
let mut paint = paint_table(paint);
|
||||
default_gradient_paint(&mut paint, bounds, _gradient_form, _gradient_spread, _transform);
|
||||
default_gradient_paint(&mut paint, bounds, _gradient_form, _gradient_spread, _has_transform.then_some(_transform));
|
||||
let parked = park_paint(ctx.arena(), paint)?;
|
||||
Ok((element, Attr(Some(parked))))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user