Skip to content

Commit

Permalink
Rebase onto master
Browse files Browse the repository at this point in the history
  • Loading branch information
TrueDoctor committed Aug 17, 2024
1 parent 14f8a28 commit 501d968
Show file tree
Hide file tree
Showing 5 changed files with 53 additions and 120 deletions.
35 changes: 5 additions & 30 deletions node-graph/gcore/src/graphic_element/renderer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -268,40 +268,15 @@ pub fn to_transform(transform: DAffine2) -> usvg::Transform {
usvg::Transform::from_row(cols[0] as f32, cols[1] as f32, cols[2] as f32, cols[3] as f32, cols[4] as f32, cols[5] as f32)
}

// TODO: Consider renaming this to better express what it does
pub trait GraphicElementRendered {
fn render_svg(&self, render: &mut SvgRender, render_params: &RenderParams);

fn bounding_box(&self, transform: DAffine2) -> Option<[DVec2; 2]>;

fn add_click_targets(&self, click_targets: &mut Vec<ClickTarget>);

fn to_usvg_node(&self) -> usvg::Node {
let mut render = SvgRender::new();
let render_params = RenderParams::new(crate::vector::style::ViewMode::Normal, ImageRenderMode::Base64, None, false, false, false);
self.render_svg(&mut render, &render_params);
render.format_svg(DVec2::ZERO, DVec2::ONE);
let svg = render.svg.to_svg_string();

let opt = usvg::Options::default();

let tree = usvg::Tree::from_str(&svg, &opt).expect("Failed to parse SVG");
usvg::Node::Group(Box::new(tree.root.clone()))
}

fn to_usvg_tree(&self, resolution: glam::UVec2, viewbox: [DVec2; 2]) -> usvg::Tree {
let root = match self.to_usvg_node() {
usvg::Node::Group(root_node) => *root_node,
_ => usvg::Group::default(),
};
usvg::Tree {
size: usvg::Size::from_wh(resolution.x as f32, resolution.y as f32).unwrap(),
view_box: usvg::ViewBox {
rect: usvg::NonZeroRect::from_ltrb(viewbox[0].x as f32, viewbox[0].y as f32, viewbox[1].x as f32, viewbox[1].y as f32).unwrap(),
aspect: usvg::AspectRatio::default(),
},
root,
}
#[cfg(feature = "vello")]
fn to_vello_scene(&self, transform: DAffine2, context: &mut RenderContext) -> Scene {
let mut scene = vello::Scene::new();
self.render_to_vello(&mut scene, transform, context);
scene
}
#[cfg(feature = "vello")]
fn render_to_vello(&self, _scene: &mut Scene, _transform: DAffine2, _render_condext: &mut RenderContext) {}
Expand Down
7 changes: 5 additions & 2 deletions node-graph/gstd/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,9 @@ web-sys = { workspace = true, optional = true, features = [
"HtmlImageElement",
"ImageBitmapRenderingContext",
] }
autoquant = { git = "https://github.com/truedoctor/autoquant", optional = true, features = [
"fitting",
] }

[dev-dependencies]
tokio = { workspace = true, features = ["macros", "rt"] }
# Optional dependencies
image-compare = { version = "0.4.1", optional = true }
68 changes: 7 additions & 61 deletions node-graph/gstd/src/wasm_application_io.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
use base64::Engine;
use dyn_any::StaticType;
use graphene_core::application_io::{ApplicationError, ApplicationIo, ExportFormat, RenderConfig, ResourceFuture, SurfaceHandle, SurfaceHandleFrame, SurfaceId};
pub use graph_craft::document::value::RenderOutput;
pub use graph_craft::wasm_application_io::*;
#[cfg(target_arch = "wasm32")]
use graphene_core::application_io::SurfaceHandle;
use graphene_core::application_io::{ApplicationIo, ExportFormat, RenderConfig};
#[cfg(target_arch = "wasm32")]
use graphene_core::raster::bbox::Bbox;
use graphene_core::raster::Image;
use graphene_core::raster::ImageFrame;
use graphene_core::renderer::{format_transform_matrix, GraphicElementRendered, ImageRenderMode, RenderParams, RenderSvgSegmentList, SvgRender};
Expand Down Expand Up @@ -186,66 +190,8 @@ async fn rasterize<_T: GraphicElementRendered + graphene_core::transform::Transf
.draw_image_with_html_image_element_and_dw_and_dh(&image_data, 0., 0., resolution.x as f64, resolution.y as f64)
.unwrap();

pub struct RasterizeVectorNode<Footprint, Surface> {
footprint: Footprint,
surface_handle: Surface,
}

#[node_macro::node_fn(RasterizeVectorNode)]
async fn rasterize_vector<_T: GraphicElementRendered>(data: _T, footprint: Footprint, surface_handle: Arc<SurfaceHandle<HtmlCanvasElement>>) -> ImageFrame<Color> {
let mut render = SvgRender::new();

let resolution = footprint.resolution;
// TODO: reenable once we switch to full node graph
let min = footprint.transform.inverse().transform_point2((0., 0.).into());
let max = footprint.transform.inverse().transform_point2(resolution.as_dvec2());
let render_params = RenderParams {
// TODO: Use correct bounds
culling_bounds: Some([min, max]),
..Default::default()
};

data.render_svg(&mut render, &render_params);
render.format_svg(min, max);
let svg_string = render.svg.to_svg_string();

let canvas = &surface_handle.surface;
canvas.set_width(resolution.x);
canvas.set_height(resolution.y);

let array = svg_string.as_bytes();
let context = canvas.get_context("2d").unwrap().unwrap().dyn_into::<CanvasRenderingContext2d>().unwrap();

let preamble = "data:image/svg+xml;base64,";
let mut base64_string = String::with_capacity(preamble.len() + array.len() * 4);
base64_string.push_str(preamble);
base64::engine::general_purpose::STANDARD.encode_string(array, &mut base64_string);

let image_data = web_sys::HtmlImageElement::new().unwrap();
image_data.set_src(base64_string.as_str());
wasm_bindgen_futures::JsFuture::from(image_data.decode()).await.unwrap();
context.draw_image_with_html_image_element(&image_data, 0., 0.).unwrap();

let rasterized = context.get_image_data(0., 0., resolution.x as f64, resolution.y as f64).unwrap();

let image = Image::from_image_data(&rasterized.data().0, resolution.x, resolution.y);
ImageFrame {
image,
transform: glam::DAffine2::from_scale(resolution.as_dvec2()),
..Default::default()
}
}

// Render with the data node taking in Footprint.
impl<'input, 'a: 'input, T: 'input + GraphicElementRendered, F: 'input + Future<Output = T>, Data: 'input, Surface: 'input, SurfaceFuture: 'input> Node<'input, WasmEditorApi<'a>>
for RenderNode<Data, Surface, Footprint>
where
Data: Node<'input, Footprint, Output = F>,
Surface: Node<'input, (), Output = SurfaceFuture>,
SurfaceFuture: core::future::Future<Output = Arc<SurfaceHandle<HtmlCanvasElement>>>,
{
type Output = core::pin::Pin<Box<dyn core::future::Future<Output = RenderOutput> + 'input>>;

let image = Image::from_image_data(&rasterized.data().0, resolution.x as u32, resolution.y as u32);
ImageFrame {
image,
Expand Down
34 changes: 15 additions & 19 deletions node-graph/interpreted-executor/src/node_registry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -651,25 +651,21 @@ fn node_registry() -> HashMap<ProtoNodeIdentifier, HashMap<NodeIOTypes, NodeCons
register_node!(graphene_core::quantization::QuantizeNode<_>, input: Color, params: [QuantizationChannels]),
register_node!(graphene_core::quantization::DeQuantizeNode<_>, input: PackedPixel, params: [QuantizationChannels]),
register_node!(graphene_core::ops::CloneNode<_>, input: &QuantizationChannels, params: []),
async_node!(graphene_std::wasm_application_io::RenderNode<_, _, _>, input: WasmEditorApi, output: RenderOutput, fn_params: [Footprint => ImageFrame<Color>, () => Arc<WasmSurfaceHandle>]),
async_node!(graphene_std::wasm_application_io::RenderNode<_, _, _>, input: WasmEditorApi, output: RenderOutput, fn_params: [Footprint => VectorData, () => Arc<WasmSurfaceHandle>]),
async_node!(graphene_std::wasm_application_io::RenderNode<_, _, _>, input: WasmEditorApi, output: RenderOutput, fn_params: [Footprint => GraphicGroup, () => Arc<WasmSurfaceHandle>]),
async_node!(graphene_std::wasm_application_io::RenderNode<_, _, _>, input: WasmEditorApi, output: RenderOutput, fn_params: [Footprint => Artboard, () => Arc<WasmSurfaceHandle>]),
async_node!(graphene_std::wasm_application_io::RenderNode<_, _, _>, input: WasmEditorApi, output: RenderOutput, fn_params: [Footprint => ArtboardGroup, () => Arc<WasmSurfaceHandle>]),
async_node!(graphene_std::wasm_application_io::RenderNode<_, _, _>, input: WasmEditorApi, output: RenderOutput, fn_params: [Footprint => Option<Color>, () => Arc<WasmSurfaceHandle>]),
async_node!(graphene_std::wasm_application_io::RenderNode<_, _, _>, input: WasmEditorApi, output: RenderOutput, fn_params: [Footprint => Vec<Color>, () => Arc<WasmSurfaceHandle>]),
async_node!(graphene_std::wasm_application_io::RenderNode<_, _, _>, input: WasmEditorApi, output: RenderOutput, params: [ImageFrame<Color>, Arc<WasmSurfaceHandle>]),
async_node!(graphene_std::wasm_application_io::RenderNode<_, _, _>, input: WasmEditorApi, output: RenderOutput, params: [VectorData, Arc<WasmSurfaceHandle>]),
async_node!(graphene_std::wasm_application_io::RenderNode<_, _, _>, input: WasmEditorApi, output: RenderOutput, params: [GraphicGroup, Arc<WasmSurfaceHandle>]),
async_node!(graphene_std::wasm_application_io::RenderNode<_, _, _>, input: WasmEditorApi, output: RenderOutput, params: [Artboard, Arc<WasmSurfaceHandle>]),
async_node!(graphene_std::wasm_application_io::RenderNode<_, _, _>, input: WasmEditorApi, output: RenderOutput, params: [bool, Arc<WasmSurfaceHandle>]),
async_node!(graphene_std::wasm_application_io::RenderNode<_, _, _>, input: WasmEditorApi, output: RenderOutput, params: [f32, Arc<WasmSurfaceHandle>]),
async_node!(graphene_std::wasm_application_io::RenderNode<_, _, _>, input: WasmEditorApi, output: RenderOutput, params: [f64, Arc<WasmSurfaceHandle>]),
async_node!(graphene_std::wasm_application_io::RenderNode<_, _, _>, input: WasmEditorApi, output: RenderOutput, params: [String, Arc<WasmSurfaceHandle>]),
async_node!(graphene_std::wasm_application_io::RenderNode<_, _, _>, input: WasmEditorApi, output: RenderOutput, params: [Option<Color>, Arc<WasmSurfaceHandle>]),
async_node!(graphene_std::wasm_application_io::RenderNode<_, _, _>, input: WasmEditorApi, output: RenderOutput, params: [Vec<Color>, Arc<WasmSurfaceHandle>]),
async_node!(graphene_std::wasm_application_io::RasterizeVectorNode<_, _>, input: VectorData, output: ImageFrame<SRGBA8>, params: [Footprint, Arc<WasmSurfaceHandle>]),
async_node!(graphene_std::wasm_application_io::RasterizeVectorNode<_, _>, input: GraphicGroup, output: ImageFrame<SRGBA8>, params: [Footprint, Arc<WasmSurfaceHandle>]),
async_node!(graphene_std::wasm_application_io::RenderNode<_, _, _>, input: RenderConfig, output: RenderOutput, fn_params: [() => &WasmEditorApi, Footprint => ImageFrame<Color>, () => Option<WgpuSurface>]),
async_node!(graphene_std::wasm_application_io::RenderNode<_, _, _>, input: RenderConfig, output: RenderOutput, fn_params: [() => &WasmEditorApi, Footprint => VectorData, () => Option<WgpuSurface>]),
async_node!(graphene_std::wasm_application_io::RenderNode<_, _, _>, input: RenderConfig, output: RenderOutput, fn_params: [() => &WasmEditorApi, Footprint => GraphicGroup, () => Option<WgpuSurface>]),
async_node!(graphene_std::wasm_application_io::RenderNode<_, _, _>, input: RenderConfig, output: RenderOutput, fn_params: [() => &WasmEditorApi, Footprint => Artboard, () => Option<WgpuSurface>]),
async_node!(graphene_std::wasm_application_io::RenderNode<_, _, _>, input: RenderConfig, output: RenderOutput, fn_params: [() => &WasmEditorApi, Footprint => ArtboardGroup, () => Option<WgpuSurface>]),
async_node!(graphene_std::wasm_application_io::RenderNode<_, _, _>, input: RenderConfig, output: RenderOutput, fn_params: [() => &WasmEditorApi, Footprint => Option<Color>, () => Option<WgpuSurface>]),
async_node!(graphene_std::wasm_application_io::RenderNode<_, _, _>, input: RenderConfig, output: RenderOutput, fn_params: [() => &WasmEditorApi, Footprint => Vec<Color>, () => Option<WgpuSurface>]),
async_node!(graphene_std::wasm_application_io::RenderNode<_, _, _>, input: RenderConfig, output: RenderOutput, fn_params: [() => &WasmEditorApi, Footprint => bool, () => Option<WgpuSurface>]),
async_node!(graphene_std::wasm_application_io::RenderNode<_, _, _>, input: RenderConfig, output: RenderOutput, fn_params: [() => &WasmEditorApi, Footprint => f32, () => Option<WgpuSurface>]),
async_node!(graphene_std::wasm_application_io::RenderNode<_, _, _>, input: RenderConfig, output: RenderOutput, fn_params: [() => &WasmEditorApi, Footprint => f64, () => Option<WgpuSurface>]),
async_node!(graphene_std::wasm_application_io::RenderNode<_, _, _>, input: RenderConfig, output: RenderOutput, fn_params: [() => &WasmEditorApi, Footprint => String, () => Option<WgpuSurface>]),
#[cfg(target_arch = "wasm32")]
async_node!(graphene_std::wasm_application_io::RasterizeNode<_, _>, input: VectorData, output: ImageFrame<Color>, params: [Footprint, Arc<WasmSurfaceHandle>]),
#[cfg(target_arch = "wasm32")]
async_node!(graphene_std::wasm_application_io::RasterizeNode<_, _>, input: GraphicGroup, output: ImageFrame<Color>, params: [Footprint, Arc<WasmSurfaceHandle>]),
async_node!(graphene_core::transform::TransformNode<_, _, _, _, _, _>, input: Footprint, output: VectorData, fn_params: [Footprint => VectorData, () => DVec2, () => f64, () => DVec2, () => DVec2, () => DVec2]),
// async_node!(graphene_core::transform::TransformNode<_, _, _, _, _, _>, input: Footprint, output: WasmSurfaceHandleFrame, fn_params: [Footprint => WasmSurfaceHandleFrame, () => DVec2, () => f64, () => DVec2, () => DVec2, () => DVec2]),
async_node!(graphene_core::transform::TransformNode<_, _, _, _, _, _>, input: Footprint, output: ImageFrame<Color>, fn_params: [Footprint => ImageFrame<Color>, () => DVec2, () => f64, () => DVec2, () => DVec2, () => DVec2]),
Expand Down
29 changes: 21 additions & 8 deletions shell.nix
Original file line number Diff line number Diff line change
Expand Up @@ -41,28 +41,41 @@ let
nodejs
cargo
cargo-watch
cargo-nextest
cargo-expand
wasm-pack
binaryen
wasm-bindgen-cli
vulkan-loader
libxkbcommon
llvm
gcc-unwrapped.lib
llvmPackages.libcxxStdenv
pkg-config
# used for profiling
gnuplot
samply
cargo-flamegraph

# For Tauri
openssl
glib
gtk3
libsoup
webkitgtk

pkg-config
# For Raw-rs tests
libraw

# Use Mold as a Linke
# Use Mold as a linker
mold
];
];
in
# Make a shell with the dependencies we need
pkgs.mkShell {
packages = packages;

pkgs.mkShell {
LD_LIBRARY_PATH = pkgs.lib.makeLibraryPath packages;
# Hacky way to run Cargo through Mold
LD_LIBRARY_PATH = pkgs.lib.makeLibraryPath [pkgs.openssl pkgs.vulkan-loader pkgs.libxkbcommon pkgs.llvmPackages.libcxxStdenv pkgs.gcc-unwrapped.lib pkgs.llvm pkgs.libraw];
shellHook = ''
export LD_LIBRARY_PATH=${pkgs.lib.makeLibraryPath packages}:$LD_LIBRARY_PATH
alias cargo='mold --run cargo'
'';
}

0 comments on commit 501d968

Please sign in to comment.