the aliasing svg renderer
Diffstat (limited to 'src/tree.rs')
-rw-r--r--src/tree.rs99
1 files changed, 69 insertions, 30 deletions
diff --git a/src/tree.rs b/src/tree.rs
index 23284a2..9dce2a8 100644
--- a/src/tree.rs
+++ b/src/tree.rs
@@ -1,18 +1,66 @@
use anyhow::Result;
use std::rc::Rc;
use tiny_skia_path::{NonZeroPositiveF32, NormalizedF32, Path, Point, Size, Transform};
-use usvg::{Color, Fill, Image, Opacity, Options, Paint, TreeParsing};
+use usvg::{Color, Fill, Opacity, Options, Paint, TreeParsing};
+use vecto::Vector2;
#[derive(Debug)]
pub struct Tree {
pub width: f32,
pub height: f32,
pub children: Box<[Node]>,
- pub osize: Size,
}
-#[derive(Debug)]
-pub enum PathNode {
+impl std::fmt::Debug for Node {
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ fn pack(Color { red, green, blue }: Color, a: Opacity) -> u64 {
+ ((red as u64) << 24)
+ | ((green as u64) << 16)
+ | ((blue as u64) << 8)
+ | (a.to_u8() as u64)
+ }
+
+ macro_rules! hex {
+ ($c:expr, $a:expr) => {
+ &format_args!("#{:x}", pack($c, $a))
+ };
+ }
+ // can be transmuted etc but takes much effort
+ fn vec(points: &[Point]) -> Vec<Vector2<u64>> {
+ points
+ .iter()
+ .map(|&Point { x, y }| Vector2::new(x.round() as u64, y.round() as u64))
+ .collect()
+ }
+ match self {
+ Self::Fill {
+ color,
+ opacity,
+ path,
+ } => f
+ .debug_struct("Fill")
+ .field("color", hex!(*color, *opacity))
+ .field("path", &format_args!("{:?}", vec(path)))
+ .finish(),
+ Self::Stroke {
+ color,
+ opacity,
+ stroke_color,
+ stroke_opacity,
+ stroke,
+ path,
+ } => f
+ .debug_struct("Stroke")
+ .field("color", hex!(*color, *opacity))
+ .field("stroke_color", hex!(*stroke_color, *stroke_opacity))
+ .field("stroke", &stroke.get())
+ .field("path", &format_args!("{:?}", vec(path)))
+ .finish(),
+ }
+ }
+}
+
+pub enum Node {
Fill {
color: Color,
opacity: Opacity,
@@ -28,12 +76,6 @@ pub enum PathNode {
},
}
-#[derive(Debug)]
-pub enum Node {
- Path(PathNode),
- Image(Image),
-}
-
fn pointify(p: &Rc<Path>, t: Transform) -> Box<[Point]> {
let mut p: Box<[Point]> = p.points().into();
t.map_points(&mut p);
@@ -42,16 +84,11 @@ fn pointify(p: &Rc<Path>, t: Transform) -> Box<[Point]> {
impl Node {
fn transform(&mut self, t: Transform) {
- match self {
- Self::Path(PathNode::Fill { path, .. } | PathNode::Stroke { path, .. }) => {
- if t.is_identity() {
- return;
- }
- t.map_points(path);
- }
- // TODO
- _ => {}
+ let (Self::Fill { path, .. } | Self::Stroke { path, .. }) = self;
+ if t.is_identity() {
+ return;
}
+ t.map_points(path);
}
}
@@ -60,7 +97,6 @@ impl From<usvg::Tree> for Tree {
let mut children = vec![];
collect(tree.root, &mut children);
Self {
- osize: tree.size,
width: tree.view_box.rect.width(),
height: tree.view_box.rect.height(),
children: children.into(),
@@ -95,14 +131,14 @@ fn convert(node: usvg::Node, to: &mut Vec<Node>) {
data: path,
..
}) => {
- to.push(Node::Path(PathNode::Stroke {
+ to.push(Node::Stroke {
color: paint.col(),
opacity: *opacity,
stroke: *stroke,
stroke_opacity: *stroke_opacity,
stroke_color: stroke_paint.col(),
path: pointify(path, *transform),
- }));
+ });
}
usvg::NodeKind::Path(usvg::Path {
stroke:
@@ -117,14 +153,14 @@ fn convert(node: usvg::Node, to: &mut Vec<Node>) {
data: path,
..
}) => {
- to.push(Node::Path(PathNode::Stroke {
+ to.push(Node::Stroke {
color: Color::black(),
opacity: NormalizedF32::new(0.0).unwrap(),
stroke: *stroke,
stroke_opacity: *stroke_opacity,
stroke_color: stroke_paint.col(),
path: pointify(path, *transform),
- }));
+ });
}
usvg::NodeKind::Path(usvg::Path {
transform,
@@ -133,11 +169,11 @@ fn convert(node: usvg::Node, to: &mut Vec<Node>) {
data: path,
..
}) => {
- to.push(Node::Path(PathNode::Fill {
+ to.push(Node::Fill {
color: paint.col(),
opacity: *opacity,
path: pointify(path, *transform),
- }));
+ });
}
usvg::NodeKind::Path(usvg::Path {
transform,
@@ -146,11 +182,11 @@ fn convert(node: usvg::Node, to: &mut Vec<Node>) {
data: path,
..
}) => {
- to.push(Node::Path(PathNode::Fill {
+ to.push(Node::Fill {
color: Color::black(),
opacity: NormalizedF32::new(0.0).unwrap(),
path: pointify(path, *transform),
- }));
+ });
}
usvg::NodeKind::Group(_) => {}
usvg::NodeKind::Image(_) => todo!(),
@@ -166,8 +202,10 @@ fn collect(node: usvg::Node, to: &mut Vec<Node>) {
}
impl Tree {
- pub fn new(svg: &str) -> Result<Self> {
- Ok(Tree::from(usvg::Tree::from_str(svg, &Options::default())?))
+ pub fn new(svg: &str) -> Result<(Self, Size)> {
+ let t = usvg::Tree::from_str(svg, &Options::default())?;
+ let ts = t.size;
+ Ok((Tree::from(t), ts))
}
pub fn resize(&mut self, w: f32, h: f32) {
@@ -177,5 +215,6 @@ impl Tree {
}
self.width = w;
self.height = h;
+ log::debug!("changed size to {w}x{h}");
}
}