Add Table<Color> as a graphical type (#3033)

* Reduce code duplication in bounding box impls on Table

* Working Table<Color> rendering in the graph

* Implement color and fix other rendering with Vello and polish
This commit is contained in:
Keavon Chambers
2025-08-10 01:34:33 -07:00
committed by GitHub
parent 81abfe147a
commit 2f4aef34e5
24 changed files with 462 additions and 198 deletions

View File

@@ -15,6 +15,7 @@ use graphene_std::text::FontCache;
use graphene_std::transform::Footprint;
use graphene_std::vector::Vector;
use graphene_std::vector::style::ViewMode;
use graphene_std::wasm_application_io::RenderOutputType;
use interpreted_executor::dynamic_executor::ResolvedDocumentNodeTypesDelta;
mod runtime_io;
@@ -33,7 +34,7 @@ pub struct ExecutionResponse {
execution_id: u64,
result: Result<TaggedValue, String>,
responses: VecDeque<FrontendMessage>,
transform: DAffine2,
footprint: Footprint,
vector_modify: HashMap<NodeId, Vector>,
/// The resulting value from the temporary inspected during execution
inspect_result: Option<InspectResult>,
@@ -223,7 +224,7 @@ impl NodeGraphExecutor {
fn export(&self, node_graph_output: TaggedValue, export_config: ExportConfig, responses: &mut VecDeque<Message>) -> Result<(), String> {
let TaggedValue::RenderOutput(RenderOutput {
data: graphene_std::wasm_application_io::RenderOutputType::Svg { svg, .. },
data: RenderOutputType::Svg { svg, .. },
..
}) = node_graph_output
else {
@@ -263,7 +264,7 @@ impl NodeGraphExecutor {
execution_id,
result,
responses: existing_responses,
transform,
footprint,
vector_modify,
inspect_result,
} = execution_response;
@@ -286,9 +287,9 @@ impl NodeGraphExecutor {
let execution_context = self.futures.remove(&execution_id).ok_or_else(|| "Invalid generation ID".to_string())?;
if let Some(export_config) = execution_context.export_config {
// Special handling for exporting the artwork
self.export(node_graph_output, export_config, responses)?
self.export(node_graph_output, export_config, responses)?;
} else {
self.process_node_graph_output(node_graph_output, transform, responses)?
self.process_node_graph_output(node_graph_output, footprint, responses)?;
}
responses.add_front(DeferMessage::TriggerGraphRun(execution_id, execution_context.document_id));
@@ -332,12 +333,12 @@ impl NodeGraphExecutor {
Ok(())
}
fn debug_render(render_object: impl Render, transform: DAffine2, responses: &mut VecDeque<Message>) {
fn debug_render(render_object: impl Render, footprint: Footprint, responses: &mut VecDeque<Message>) {
// Setup rendering
let mut render = SvgRender::new();
let render_params = RenderParams {
view_mode: ViewMode::Normal,
culling_bounds: None,
footprint,
thumbnail: false,
hide_artboards: false,
for_export: false,
@@ -349,24 +350,25 @@ impl NodeGraphExecutor {
render_object.render_svg(&mut render, &render_params);
// Concatenate the defs and the SVG into one string
render.wrap_with_transform(transform, None);
render.wrap_with_transform(footprint.transform, None);
let svg = render.svg.to_svg_string();
// Send to frontend
responses.add(FrontendMessage::UpdateDocumentArtwork { svg });
}
fn process_node_graph_output(&mut self, node_graph_output: TaggedValue, transform: DAffine2, responses: &mut VecDeque<Message>) -> Result<(), String> {
fn process_node_graph_output(&mut self, node_graph_output: TaggedValue, footprint: Footprint, responses: &mut VecDeque<Message>) -> Result<(), String> {
let mut render_output_metadata = RenderMetadata::default();
match node_graph_output {
TaggedValue::RenderOutput(render_output) => {
match render_output.data {
graphene_std::wasm_application_io::RenderOutputType::Svg { svg, image_data } => {
RenderOutputType::Svg { svg, image_data } => {
// Send to frontend
responses.add(FrontendMessage::UpdateImageData { image_data });
responses.add(FrontendMessage::UpdateDocumentArtwork { svg });
}
graphene_std::wasm_application_io::RenderOutputType::CanvasFrame(frame) => {
RenderOutputType::CanvasFrame(frame) => {
let matrix = format_transform_matrix(frame.transform);
let transform = if matrix.is_empty() { String::new() } else { format!(" transform=\"{matrix}\"") };
let svg = format!(
@@ -375,29 +377,23 @@ impl NodeGraphExecutor {
);
responses.add(FrontendMessage::UpdateDocumentArtwork { svg });
}
graphene_std::wasm_application_io::RenderOutputType::Texture { .. } => {}
_ => {
return Err(format!("Invalid node graph output type: {:#?}", render_output.data));
}
RenderOutputType::Texture { .. } => {}
_ => return Err(format!("Invalid node graph output type: {:#?}", render_output.data)),
}
render_output_metadata = render_output.metadata;
}
TaggedValue::Bool(render_object) => Self::debug_render(render_object, transform, responses),
TaggedValue::String(render_object) => Self::debug_render(render_object, transform, responses),
TaggedValue::F64(render_object) => Self::debug_render(render_object, transform, responses),
TaggedValue::DVec2(render_object) => Self::debug_render(render_object, transform, responses),
TaggedValue::OptionalColor(render_object) => Self::debug_render(render_object, transform, responses),
TaggedValue::Vector(render_object) => Self::debug_render(render_object, transform, responses),
TaggedValue::Graphic(render_object) => Self::debug_render(render_object, transform, responses),
TaggedValue::Raster(render_object) => Self::debug_render(render_object, transform, responses),
TaggedValue::Palette(render_object) => Self::debug_render(render_object, transform, responses),
_ => {
return Err(format!("Invalid node graph output type: {node_graph_output:#?}"));
}
TaggedValue::Bool(render_object) => Self::debug_render(render_object, footprint, responses),
TaggedValue::F64(render_object) => Self::debug_render(render_object, footprint, responses),
TaggedValue::DVec2(render_object) => Self::debug_render(render_object, footprint, responses),
TaggedValue::String(render_object) => Self::debug_render(render_object, footprint, responses),
TaggedValue::OptionalColor(render_object) => Self::debug_render(render_object, footprint, responses),
TaggedValue::Palette(render_object) => Self::debug_render(render_object, footprint, responses),
_ => return Err(format!("Invalid node graph output type: {node_graph_output:#?}")),
};
let graphene_std::renderer::RenderMetadata {
upstream_footprints: footprints,
upstream_footprints,
local_transforms,
first_element_source_id,
click_targets,
@@ -406,7 +402,7 @@ impl NodeGraphExecutor {
// Run these update state messages immediately
responses.add(DocumentMessage::UpdateUpstreamTransforms {
upstream_footprints: footprints,
upstream_footprints,
local_transforms,
first_element_source_id,
});