mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-10-02 19:38:12 +08:00
Convert rasterize to an async record source with an owned merged-layers write
This commit is contained in:
@@ -1038,6 +1038,7 @@ fn document_node_definitions() -> HashMap<DefinitionIdentifier, DocumentNodeDefi
|
|||||||
},
|
},
|
||||||
DocumentNode {
|
DocumentNode {
|
||||||
inputs: vec![
|
inputs: vec![
|
||||||
|
NodeInput::value(TaggedValue::None, false),
|
||||||
NodeInput::import(generic!(T), 0),
|
NodeInput::import(generic!(T), 0),
|
||||||
NodeInput::import(concrete!(Footprint), 1),
|
NodeInput::import(concrete!(Footprint), 1),
|
||||||
NodeInput::node(NodeId(1), 0),
|
NodeInput::node(NodeId(1), 0),
|
||||||
|
|||||||
@@ -132,11 +132,13 @@ pub(crate) fn generate_node_code(crate_ident: &CrateIdent, parsed: &ParsedNodeFn
|
|||||||
// Flipped nodes carry their kernel generics as struct parameters: record
|
// Flipped nodes carry their kernel generics as struct parameters: record
|
||||||
// edges no longer bind them through `Output`, so the struct must. A
|
// edges no longer bind them through `Output`, so the struct must. A
|
||||||
// ranked input's element generic is carried on any node kind for the
|
// ranked input's element generic is carried on any node kind for the
|
||||||
// same reason: the materialized view monomorphizes the kernel per row.
|
// same reason: the materialized view monomorphizes the kernel per row. A
|
||||||
|
// record-io node's secondary inputs read erased off their wire, so a
|
||||||
|
// generic one of them names is carried too.
|
||||||
let ctx_ident_for_flip = context_param(parsed).map(|ctx| ctx.ident.clone());
|
let ctx_ident_for_flip = context_param(parsed).map(|ctx| ctx.ident.clone());
|
||||||
let ranked_carries = |ident: &Ident| {
|
let ranked_carries = |ident: &Ident| {
|
||||||
regular_fields.iter().any(|field| match &field.ty {
|
regular_fields.iter().enumerate().any(|(index, field)| match &field.ty {
|
||||||
ParsedFieldType::Regular(RegularParsedField { ty, list_levels, .. }) => *list_levels > 0 && type_contains_ident(ty, ident),
|
ParsedFieldType::Regular(RegularParsedField { ty, list_levels, .. }) => (*list_levels > 0 || (record_io && index > 0)) && type_contains_ident(ty, ident),
|
||||||
_ => false,
|
_ => false,
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -5,7 +5,9 @@ use canvas_utils::{Canvas, CanvasHandle};
|
|||||||
use core_types::color::SRGBA8;
|
use core_types::color::SRGBA8;
|
||||||
use core_types::gpoll::GPoll;
|
use core_types::gpoll::GPoll;
|
||||||
#[cfg(target_family = "wasm")]
|
#[cfg(target_family = "wasm")]
|
||||||
use core_types::list::{Item, List};
|
use core_types::attribute::{Attr, OwnedAttr, Transform};
|
||||||
|
#[cfg(target_family = "wasm")]
|
||||||
|
use core_types::list::List;
|
||||||
|
|
||||||
#[cfg(target_family = "wasm")]
|
#[cfg(target_family = "wasm")]
|
||||||
use core_types::math::bbox::Bbox;
|
use core_types::math::bbox::Bbox;
|
||||||
@@ -21,10 +23,10 @@ pub use graph_craft::document::value::RenderOutputType;
|
|||||||
#[cfg(target_family = "wasm")]
|
#[cfg(target_family = "wasm")]
|
||||||
pub use graphene_canvas_utils as canvas_utils;
|
pub use graphene_canvas_utils as canvas_utils;
|
||||||
#[cfg(target_family = "wasm")]
|
#[cfg(target_family = "wasm")]
|
||||||
use graphic_types::ATTR_EDITOR_MERGED_LAYERS;
|
|
||||||
#[cfg(target_family = "wasm")]
|
|
||||||
use graphic_types::Graphic;
|
use graphic_types::Graphic;
|
||||||
#[cfg(target_family = "wasm")]
|
#[cfg(target_family = "wasm")]
|
||||||
|
use graphic_types::markers::EditorMergedLayers;
|
||||||
|
#[cfg(target_family = "wasm")]
|
||||||
use graphic_types::IntoGraphicList;
|
use graphic_types::IntoGraphicList;
|
||||||
#[cfg(target_family = "wasm")]
|
#[cfg(target_family = "wasm")]
|
||||||
use graphic_types::Vector;
|
use graphic_types::Vector;
|
||||||
@@ -204,6 +206,7 @@ fn create_canvas(_: impl Ctx) -> CanvasHandle {
|
|||||||
#[node_macro::node(category(""))]
|
#[node_macro::node(category(""))]
|
||||||
async fn rasterize<T: WasmNotSend + Clone>(
|
async fn rasterize<T: WasmNotSend + Clone>(
|
||||||
_: impl Ctx,
|
_: impl Ctx,
|
||||||
|
_: (),
|
||||||
#[implementations(
|
#[implementations(
|
||||||
List<Vector>,
|
List<Vector>,
|
||||||
List<Raster<CPU>>,
|
List<Raster<CPU>>,
|
||||||
@@ -214,7 +217,7 @@ async fn rasterize<T: WasmNotSend + Clone>(
|
|||||||
mut data: List<T>,
|
mut data: List<T>,
|
||||||
footprint: Footprint,
|
footprint: Footprint,
|
||||||
mut canvas: CanvasHandle,
|
mut canvas: CanvasHandle,
|
||||||
) -> List<Raster<CPU>>
|
) -> (Raster<CPU>, Attr<Transform>, OwnedAttr<EditorMergedLayers>)
|
||||||
where
|
where
|
||||||
List<T>: Render + Clone + graphic_types::IntoGraphicList,
|
List<T>: Render + Clone + graphic_types::IntoGraphicList,
|
||||||
{
|
{
|
||||||
@@ -222,12 +225,15 @@ where
|
|||||||
|
|
||||||
if footprint.transform.matrix2.determinant() == 0. {
|
if footprint.transform.matrix2.determinant() == 0. {
|
||||||
log::trace!("Invalid footprint received for rasterization");
|
log::trace!("Invalid footprint received for rasterization");
|
||||||
return List::new();
|
// A zero-size raster renders as nothing, matching the legacy empty list
|
||||||
|
return (Raster::new_cpu(Image::default()), Attr(DAffine2::IDENTITY), OwnedAttr::new(None));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Snapshot the input as a List<Graphic> so the renderer can recurse into the original child layers
|
// Snapshot the input as a List<Graphic> so the renderer can recurse into the original child layers
|
||||||
// when collecting metadata, exposing their click targets to editor tools (same mechanism as Boolean Operation).
|
// when collecting metadata, exposing their click targets to editor tools (same mechanism as Boolean Operation).
|
||||||
|
// The copy is owned before the first await: the input's arena content dies with the spawning evaluation.
|
||||||
let upstream_graphic_list = data.clone().into_graphic_list();
|
let upstream_graphic_list = data.clone().into_graphic_list();
|
||||||
|
let merged_layers = OwnedAttr::new(Some(&upstream_graphic_list));
|
||||||
|
|
||||||
let mut render = SvgRender::new();
|
let mut render = SvgRender::new();
|
||||||
let aabb = Bbox::from_transform(footprint.transform).to_axis_aligned_bbox();
|
let aabb = Bbox::from_transform(footprint.transform).to_axis_aligned_bbox();
|
||||||
@@ -264,11 +270,7 @@ where
|
|||||||
let rasterized = context.get_image_data(0, 0, resolution.x as i32, resolution.y as i32).unwrap();
|
let rasterized = context.get_image_data(0, 0, resolution.x as i32, resolution.y as i32).unwrap();
|
||||||
|
|
||||||
let image = Image::from_image_data(&rasterized.data().0, resolution.x as u32, resolution.y as u32);
|
let image = Image::from_image_data(&rasterized.data().0, resolution.x as u32, resolution.y as u32);
|
||||||
List::new_from_item(
|
(Raster::new_cpu(image), Attr(footprint.transform), merged_layers)
|
||||||
Item::new_from_element(Raster::new_cpu(image))
|
|
||||||
.with_attribute(ATTR_TRANSFORM, footprint.transform)
|
|
||||||
.with_attribute(ATTR_EDITOR_MERGED_LAYERS, Some(upstream_graphic_list)),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[node_macro::node(category(""), inject_scope)]
|
#[node_macro::node(category(""), inject_scope)]
|
||||||
|
|||||||
Reference in New Issue
Block a user