the aliasing svg renderer
small opts
bendn 2023-10-18
parent c19c4a2 · commit d81aba6
-rw-r--r--Cargo.toml6
-rw-r--r--src/render.rs8
-rw-r--r--src/tree.rs47
3 files changed, 34 insertions, 27 deletions
diff --git a/Cargo.toml b/Cargo.toml
index 7a7bc9a..e838b6e 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -11,3 +11,9 @@ clap = { version = "4.4.6", features = ["derive"] }
fimg = "0.4.16"
tiny-skia-path = "0.11.2"
usvg = { version = "0.36.0", default-features = false }
+
+[profile.release]
+debug = 2
+opt-level = 3
+lto = "thin"
+incremental = true
diff --git a/src/render.rs b/src/render.rs
index 705a8ce..db6c1c3 100644
--- a/src/render.rs
+++ b/src/render.rs
@@ -1,6 +1,6 @@
use crate::tree::{Node, PathNode, Tree};
use fimg::Image;
-use tiny_skia_path::{NormalizedF32, Path, Point};
+use tiny_skia_path::{NormalizedF32, Point};
use usvg::Color;
impl Tree {
@@ -24,13 +24,13 @@ impl Col for Color {
}
}
-fn point(p: &Path) -> Vec<(i32, i32)> {
+fn point(p: &Box<[Point]>) -> Vec<(i32, i32)> {
let mut points = Vec::with_capacity(p.len() + 1);
let r = |p: Point| (p.x.round() as i32, p.y.round() as i32);
- for &point in p.points() {
+ for &point in &**p {
points.push(r(point));
}
- points.push(r(*p.points().first().unwrap()));
+ points.push(r(*p.first().unwrap()));
points
}
diff --git a/src/tree.rs b/src/tree.rs
index 4aa2aab..2020342 100644
--- a/src/tree.rs
+++ b/src/tree.rs
@@ -1,6 +1,7 @@
use anyhow::Result;
-use tiny_skia_path::{NonZeroPositiveF32, NormalizedF32, Path, Rect, Size, Transform};
-use usvg::{BBox, Color, Fill, Image, Opacity, Options, Paint, TreeParsing};
+use std::rc::Rc;
+use tiny_skia_path::{NonZeroPositiveF32, NormalizedF32, Path, Point, Size, Transform};
+use usvg::{Color, Fill, Image, Opacity, Options, Paint, TreeParsing};
#[derive(Debug)]
pub struct Tree {
@@ -15,7 +16,7 @@ pub enum PathNode {
Fill {
color: Color,
opacity: Opacity,
- path: Path,
+ path: Box<[Point]>,
},
Stroke {
color: Color,
@@ -23,7 +24,7 @@ pub enum PathNode {
stroke_color: Color,
stroke_opacity: Opacity,
stroke: NonZeroPositiveF32,
- path: Path,
+ path: Box<[Point]>,
},
}
@@ -31,18 +32,26 @@ pub enum PathNode {
pub enum Node {
Group {
opacity: Opacity,
- bbox: BBox,
children: Box<[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);
+ p
+}
+
impl Node {
fn transform(&mut self, t: Transform) {
match self {
Self::Path(PathNode::Fill { path, .. } | PathNode::Stroke { path, .. }) => {
- *path = path.clone().transform(t).unwrap(); // idc
+ if t.is_identity() {
+ return;
+ }
+ t.map_points(path);
}
// TODO
_ => {}
@@ -75,21 +84,19 @@ impl PColor for Paint {
}
}
}
-fn convert(node: usvg::Node, to: &mut Vec<Node>) -> Option<Rect> {
+fn convert(node: usvg::Node, to: &mut Vec<Node>) {
match &*node.clone().borrow() {
usvg::NodeKind::Group(g) => {
let mut children = vec![];
- let bbox = collect(node, &mut children);
+ collect(node, &mut children);
let mut children = children.into_boxed_slice();
for child in &mut *children {
child.transform(g.transform);
}
to.push(Node::Group {
opacity: g.opacity,
- bbox,
children,
});
- bbox.to_rect()
}
usvg::NodeKind::Path(usvg::Path {
stroke:
@@ -110,9 +117,8 @@ fn convert(node: usvg::Node, to: &mut Vec<Node>) -> Option<Rect> {
stroke: *stroke,
stroke_opacity: *stroke_opacity,
stroke_color: stroke_paint.col(),
- path: (**path).clone().transform(*transform).unwrap(),
+ path: pointify(path, *transform),
}));
- Some(path.bounds())
}
usvg::NodeKind::Path(usvg::Path {
stroke:
@@ -133,9 +139,8 @@ fn convert(node: usvg::Node, to: &mut Vec<Node>) -> Option<Rect> {
stroke: *stroke,
stroke_opacity: *stroke_opacity,
stroke_color: stroke_paint.col(),
- path: (**path).clone().transform(*transform).unwrap(),
+ path: pointify(path, *transform),
}));
- Some(path.bounds())
}
usvg::NodeKind::Path(usvg::Path {
transform,
@@ -147,9 +152,8 @@ fn convert(node: usvg::Node, to: &mut Vec<Node>) -> Option<Rect> {
to.push(Node::Path(PathNode::Fill {
color: paint.col(),
opacity: *opacity,
- path: (**path).clone().transform(*transform).unwrap(),
+ path: pointify(path, *transform),
}));
- Some(path.bounds())
}
usvg::NodeKind::Path(usvg::Path {
transform,
@@ -161,22 +165,19 @@ fn convert(node: usvg::Node, to: &mut Vec<Node>) -> Option<Rect> {
to.push(Node::Path(PathNode::Fill {
color: Color::black(),
opacity: NormalizedF32::new(0.0).unwrap(),
- path: (**path).clone().transform(*transform).unwrap(),
+ path: pointify(path, *transform),
}));
- Some(path.bounds())
}
usvg::NodeKind::Image(_) => todo!(),
usvg::NodeKind::Text(_) => unimplemented!(),
}
}
-fn collect(node: usvg::Node, to: &mut Vec<Node>) -> BBox {
- let mut bbox = BBox::default();
+fn collect(node: usvg::Node, to: &mut Vec<Node>) {
for child in node.children() {
- bbox = bbox.expand(collect(child.clone(), to));
- bbox = bbox.expand(convert(child, to).map_or(BBox::default(), BBox::from));
+ collect(child.clone(), to);
+ convert(child, to);
}
- bbox
}
impl Tree {