Skip to content

Commit

Permalink
implement svg renderers (resvg and vello_svg)
Browse files Browse the repository at this point in the history
  • Loading branch information
Sharktheone committed Jun 23, 2024
1 parent 408ac7d commit 0d86229
Show file tree
Hide file tree
Showing 19 changed files with 709 additions and 139 deletions.
342 changes: 333 additions & 9 deletions Cargo.lock

Large diffs are not rendered by default.

1 change: 0 additions & 1 deletion crates/gosub_html5/src/node/arena.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,6 @@ impl NodeArena {
id
}


pub fn nodes(&self) -> &HashMap<NodeId, Node> {
&self.nodes
}
Expand Down
1 change: 0 additions & 1 deletion crates/gosub_html5/src/parser/document.rs
Original file line number Diff line number Diff line change
Expand Up @@ -496,7 +496,6 @@ impl Document {
false
}


pub fn nodes(&self) -> &HashMap<NodeId, Node> {
self.arena.nodes()
}
Expand Down
53 changes: 18 additions & 35 deletions crates/gosub_html5/src/writer.rs
Original file line number Diff line number Diff line change
@@ -1,29 +1,24 @@
use crate::{node::{Node, NodeData, NodeId}, parser::document::Document, visit::Visitor};




use crate::{
node::{Node, NodeData, NodeId},
parser::document::Document,
visit::Visitor,
};

impl Document {
pub fn write_document(&self) -> String {
Writer::write_from_node(NodeId::root(), self)
}


pub fn write_from_node(&self, node: NodeId) -> String {
Writer::write_from_node(node, self)
}
}




struct Writer {
buffer: String,
comments: bool,
}


impl Writer {
pub fn write_from_node(node: NodeId, doc: &Document) -> String {
let mut w = Self {
Expand All @@ -37,7 +32,7 @@ impl Writer {
}

pub fn visit_node(&mut self, id: NodeId, doc: &Document) {
let Some(node)= doc.get_node_by_id(id) else {
let Some(node) = doc.get_node_by_id(id) else {
return;
};

Expand Down Expand Up @@ -83,33 +78,27 @@ impl Writer {
}
}


pub fn visit_children(&mut self, children: &Vec<NodeId>, doc: &Document) {
for child in children {
self.visit_node(*child, doc);
}
}
}


impl Visitor<Node> for Writer {
fn text_enter(&mut self, _node: &Node, data: &crate::node::data::text::TextData) {
self.buffer.push_str(&data.value);
}

fn text_leave(&mut self, _node: &Node, _data: &crate::node::data::text::TextData) {

}
fn text_leave(&mut self, _node: &Node, _data: &crate::node::data::text::TextData) {}

fn doctype_enter(&mut self, _node: &Node, data: &crate::node::data::doctype::DocTypeData) {
self.buffer.push_str("<!DOCTYPE ");
self.buffer.push_str(&data.name);
self.buffer.push_str(">");
self.buffer.push('>');
}

fn doctype_leave(&mut self, _node: &Node, _data: &crate::node::data::doctype::DocTypeData) {

}
fn doctype_leave(&mut self, _node: &Node, _data: &crate::node::data::doctype::DocTypeData) {}

fn comment_enter(&mut self, _node: &Node, data: &crate::node::data::comment::CommentData) {
if self.comments {
Expand All @@ -119,35 +108,29 @@ impl Visitor<Node> for Writer {
}
}

fn comment_leave(&mut self, _node: &Node, _data: &crate::node::data::comment::CommentData) {

}
fn comment_leave(&mut self, _node: &Node, _data: &crate::node::data::comment::CommentData) {}

fn element_enter(&mut self, _node: &Node, data: &crate::node::data::element::ElementData) {
self.buffer.push_str("<");
self.buffer.push('<');
self.buffer.push_str(&data.name);
for (name, value) in &data.attributes {
self.buffer.push_str(" ");
self.buffer.push(' ');
self.buffer.push_str(name);
self.buffer.push_str("=\"");
self.buffer.push_str(value);
self.buffer.push_str("\"");
self.buffer.push('"');
}

self.buffer.push_str(">");
self.buffer.push('>');
}

fn element_leave(&mut self, node: &Node, data: &crate::node::data::element::ElementData) {
fn element_leave(&mut self, _node: &Node, data: &crate::node::data::element::ElementData) {
self.buffer.push_str("</");
self.buffer.push_str(&data.name);
self.buffer.push_str(">");
self.buffer.push('>');
}

fn document_enter(&mut self, _node: &Node, _data: &crate::node::data::document::DocumentData) {

}
fn document_enter(&mut self, _node: &Node, _data: &crate::node::data::document::DocumentData) {}

fn document_leave(&mut self, _node: &Node, _data: &crate::node::data::document::DocumentData) {

}
fn document_leave(&mut self, _node: &Node, _data: &crate::node::data::document::DocumentData) {}
}
1 change: 1 addition & 0 deletions crates/gosub_render_backend/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,5 @@ smallvec = "1.13.2"
image = "0.25.1"
raw-window-handle = "0.6.2"
gosub_shared = { path = "../gosub_shared" }
gosub_html5 = { path = "../gosub_html5" }

48 changes: 45 additions & 3 deletions crates/gosub_render_backend/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
use raw_window_handle::{HasDisplayHandle, HasWindowHandle};
use std::fmt::Debug;
use std::ops::{Div, Mul, MulAssign};

use raw_window_handle::{HasDisplayHandle, HasWindowHandle};
use smallvec::SmallVec;

use gosub_shared::types::Result;

use gosub_shared::types::Size as SizeT;

use crate::svg::SvgRenderer;

pub mod svg;

pub type Size = SizeT<f32>;
pub type SizeU32 = SizeT<u32>;

Expand All @@ -28,6 +31,7 @@ pub trait RenderBackend: Sized + Debug {
type Image: Image;
type Brush: Brush<Self>;
type Scene: Scene<Self>;
type SVGRenderer: SvgRenderer<Self>;

type ActiveWindowData<'a>;
type WindowData<'a>;
Expand Down Expand Up @@ -583,7 +587,10 @@ pub trait Color {
pub trait Image {
fn new(size: (FP, FP), data: Vec<u8>) -> Self;

fn from_img(img: &image::DynamicImage) -> Self;
fn from_img(img: image::DynamicImage) -> Self;

fn width(&self) -> u32;
fn height(&self) -> u32;
}

pub trait Brush<B: RenderBackend>: Clone {
Expand All @@ -593,3 +600,38 @@ pub trait Brush<B: RenderBackend>: Clone {

fn image(image: B::Image) -> Self;
}

pub enum ImageBuffer<B: RenderBackend> {
Image(B::Image),
Scene(B::Scene, SizeU32),
}

impl<B: RenderBackend> ImageBuffer<B> {
pub fn width(&self) -> u32 {
match self {
ImageBuffer::Image(img) => img.width(),
ImageBuffer::Scene(_, size) => size.width,
}
}

pub fn height(&self) -> u32 {
match self {
ImageBuffer::Image(img) => img.height(),
ImageBuffer::Scene(_, size) => size.height,
}
}

pub fn size(&self) -> SizeU32 {
match self {
ImageBuffer::Image(img) => SizeU32::new(img.width(), img.height()),
ImageBuffer::Scene(_, size) => *size,
}
}

pub fn size_tuple(&self) -> (FP, FP) {
match self {
ImageBuffer::Image(img) => (img.width() as FP, img.height() as FP),
ImageBuffer::Scene(_, size) => (size.width as FP, size.height as FP),
}
}
}
13 changes: 11 additions & 2 deletions crates/gosub_render_backend/src/svg.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,16 @@
use crate::RenderBackend;
use gosub_html5::node::NodeId;
use gosub_html5::parser::document::DocumentHandle;
use gosub_shared::types::Result;

use crate::{ImageBuffer, RenderBackend};

pub trait SvgRenderer<B: RenderBackend> {
type SvgDocument;

fn new(wd: &mut B::WindowData<'_>) -> Self;

pub trait SvgRenderer<B: RenderBackend> {
fn parse_external(data: String) -> Result<Self::SvgDocument>;
fn parse_internal(tree: DocumentHandle, id: NodeId) -> Result<Self::SvgDocument>;

fn render(&mut self, doc: &Self::SvgDocument) -> Result<ImageBuffer<B>>;
}
Loading

0 comments on commit 0d86229

Please sign in to comment.