summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorReizner Evgeniy <razrfalcon@gmail.com>2018-02-22 17:59:38 +0200
committerReizner Evgeniy <razrfalcon@gmail.com>2018-02-22 17:59:38 +0200
commit36a08050811373d443c4ac6a9ef3f2e1de083ae6 (patch)
tree0050ecdd0902424d97c985012c720d484be7a9df
parentecd403f9204a306b39e98ee9d8e0fa4aaf18a818 (diff)
Reduced RenderTree propagation thanks to new ero_tree tree() method.
-rw-r--r--Cargo.toml3
-rw-r--r--capi/src/lib.rs1
-rw-r--r--examples/draw_bboxes.rs5
-rw-r--r--src/convert/clippath.rs4
-rw-r--r--src/convert/fill.rs2
-rw-r--r--src/convert/gradient.rs6
-rw-r--r--src/convert/image.rs2
-rw-r--r--src/convert/mod.rs4
-rw-r--r--src/convert/path.rs2
-rw-r--r--src/convert/pattern.rs4
-rw-r--r--src/convert/stroke.rs2
-rw-r--r--src/convert/text.rs2
-rw-r--r--src/lib.rs2
-rw-r--r--src/render_cairo/clippath.rs5
-rw-r--r--src/render_cairo/fill.rs7
-rw-r--r--src/render_cairo/mod.rs44
-rw-r--r--src/render_cairo/pattern.rs3
-rw-r--r--src/render_cairo/stroke.rs4
-rw-r--r--src/render_cairo/text.rs15
-rw-r--r--src/render_qt/clippath.rs5
-rw-r--r--src/render_qt/fill.rs4
-rw-r--r--src/render_qt/mod.rs34
-rw-r--r--src/render_qt/pattern.rs3
-rw-r--r--src/render_qt/stroke.rs4
-rw-r--r--src/render_qt/text.rs15
-rw-r--r--src/tree/mod.rs107
-rw-r--r--tools/rendersvg/src/main.rs6
27 files changed, 136 insertions, 159 deletions
diff --git a/Cargo.toml b/Cargo.toml
index 177f709..8b97f74 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -20,7 +20,8 @@ libflate = "0.1"
# lyon_geom = "0.9"
lyon_geom = { git = "https://github.com/nical/lyon.git" }
euclid = "0.17"
-ego-tree = "0.2"
+# ego-tree = "0.2"
+ego-tree = { git = "https://github.com/programble/ego-tree" }
[dependencies.error-chain]
version = "0.11"
diff --git a/capi/src/lib.rs b/capi/src/lib.rs
index bac7491..d062460 100644
--- a/capi/src/lib.rs
+++ b/capi/src/lib.rs
@@ -28,6 +28,7 @@ use resvg::qt;
use resvg::cairo;
use resvg::RectExt;
+use resvg::tree::prelude::*;
#[repr(C)]
pub struct Rect {
diff --git a/examples/draw_bboxes.rs b/examples/draw_bboxes.rs
index 6550fe8..5fb7d4a 100644
--- a/examples/draw_bboxes.rs
+++ b/examples/draw_bboxes.rs
@@ -4,11 +4,10 @@ use std::env;
use std::path::Path;
use resvg::{
- tree,
utils,
Options,
- NodeExt,
};
+use resvg::tree::prelude::*;
// TODO: write doc
@@ -42,7 +41,7 @@ fn main() {
let mut bboxes = Vec::new();
for node in rtree.root().descendants() {
if !rtree.is_in_defs(node) {
- if let Some(bbox) = backend.calc_node_bbox(&rtree, node, &opt) {
+ if let Some(bbox) = backend.calc_node_bbox(node, &opt) {
bboxes.push(bbox);
}
}
diff --git a/src/convert/clippath.rs b/src/convert/clippath.rs
index fbe944d..ae9abde 100644
--- a/src/convert/clippath.rs
+++ b/src/convert/clippath.rs
@@ -6,7 +6,7 @@
use svgdom;
// self
-use tree;
+use tree::prelude::*;
use short::{
AId,
EId,
@@ -27,7 +27,7 @@ pub fn convert(
) {
let attrs = node.attributes();
- let clip_node = rtree.append_defs(
+ let clip_node = rtree.append_to_defs(
tree::NodeKind::ClipPath(tree::ClipPath {
id: node.id().clone(),
units: super::convert_element_units(&attrs, AId::ClipPathUnits),
diff --git a/src/convert/fill.rs b/src/convert/fill.rs
index 49c60a8..6c453b6 100644
--- a/src/convert/fill.rs
+++ b/src/convert/fill.rs
@@ -9,7 +9,7 @@ use svgdom::{
};
// self
-use tree;
+use tree::prelude::*;
use short::{
AId,
AValue,
diff --git a/src/convert/gradient.rs b/src/convert/gradient.rs
index 9d03b6e..e0acfe7 100644
--- a/src/convert/gradient.rs
+++ b/src/convert/gradient.rs
@@ -6,7 +6,7 @@
use svgdom;
// self
-use tree;
+use tree::prelude::*;
use short::{
AId,
EId,
@@ -23,7 +23,7 @@ pub fn convert_linear(
let ref attrs = node.attributes();
let transform = attrs.get_transform(AId::GradientTransform).unwrap_or_default();
- let grad = rtree.append_defs(
+ let grad = rtree.append_to_defs(
tree::NodeKind::LinearGradient(tree::LinearGradient {
id: node.id().clone(),
x1: attrs.get_number(AId::X1).unwrap_or(0.0),
@@ -48,7 +48,7 @@ pub fn convert_radial(
let ref attrs = node.attributes();
let transform = attrs.get_transform(AId::GradientTransform).unwrap_or_default();
- let grad = rtree.append_defs(
+ let grad = rtree.append_to_defs(
tree::NodeKind::RadialGradient(tree::RadialGradient {
id: node.id().clone(),
cx: attrs.get_number(AId::Cx).unwrap_or(0.5),
diff --git a/src/convert/image.rs b/src/convert/image.rs
index 5f687b5..5963a10 100644
--- a/src/convert/image.rs
+++ b/src/convert/image.rs
@@ -9,7 +9,7 @@ use base64;
use svgdom;
// self
-use tree;
+use tree::prelude::*;
use short::{
AId,
};
diff --git a/src/convert/mod.rs b/src/convert/mod.rs
index d31ad46..edf5140 100644
--- a/src/convert/mod.rs
+++ b/src/convert/mod.rs
@@ -9,7 +9,7 @@ use svgdom::{
};
// self
-use tree;
+use tree::prelude::*;
use short::{
AId,
AValue,
@@ -58,7 +58,7 @@ pub fn convert_doc(
view_box: get_view_box(&svg)?,
};
- let mut rtree = tree::RenderTree::new(svg_kind);
+ let mut rtree = tree::RenderTree::create(svg_kind);
convert_ref_nodes(svg_doc, opt, &mut rtree);
convert_nodes(&svg, opt, rtree.root().id(), &mut rtree);
diff --git a/src/convert/path.rs b/src/convert/path.rs
index 0bfc02c..fdf15a7 100644
--- a/src/convert/path.rs
+++ b/src/convert/path.rs
@@ -10,7 +10,7 @@ use svgdom;
use lyon_geom;
// self
-use tree;
+use tree::prelude::*;
use short::{
AId,
};
diff --git a/src/convert/pattern.rs b/src/convert/pattern.rs
index 03761a2..85c33ca 100644
--- a/src/convert/pattern.rs
+++ b/src/convert/pattern.rs
@@ -9,7 +9,7 @@ use svgdom::{
};
// self
-use tree;
+use tree::prelude::*;
use short::{
AId,
};
@@ -34,7 +34,7 @@ pub fn convert(
debug_assert!(!rect.width().is_fuzzy_zero());
debug_assert!(!rect.height().is_fuzzy_zero());
- let patt_node = rtree.append_defs(tree::NodeKind::Pattern(tree::Pattern {
+ let patt_node = rtree.append_to_defs(tree::NodeKind::Pattern(tree::Pattern {
id: node.id().clone(),
units: super::convert_element_units(&attrs, AId::PatternUnits),
content_units: super::convert_element_units(&attrs, AId::PatternContentUnits),
diff --git a/src/convert/stroke.rs b/src/convert/stroke.rs
index 815aca2..593e799 100644
--- a/src/convert/stroke.rs
+++ b/src/convert/stroke.rs
@@ -10,7 +10,7 @@ use svgdom::{
};
// self
-use tree;
+use tree::prelude::*;
use short::{
AId,
AValue,
diff --git a/src/convert/text.rs b/src/convert/text.rs
index 3d2df82..f34bc16 100644
--- a/src/convert/text.rs
+++ b/src/convert/text.rs
@@ -9,7 +9,7 @@ use svgdom::{
};
// self
-use tree;
+use tree::prelude::*;
use short::{
AId,
EId,
diff --git a/src/lib.rs b/src/lib.rs
index d2179b5..a76dcfa 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -97,7 +97,6 @@ pub trait Render {
/// Renders SVG node to image.
fn render_node_to_image(
&self,
- rtree: &tree::RenderTree,
node: tree::NodeRef,
opt: &Options,
) -> Result<Box<OutputImage>>;
@@ -107,7 +106,6 @@ pub trait Render {
/// Note: this method can be pretty expensive.
fn calc_node_bbox(
&self,
- rtree: &tree::RenderTree,
node: tree::NodeRef,
opt: &Options,
) -> Option<Rect>;
diff --git a/src/render_cairo/clippath.rs b/src/render_cairo/clippath.rs
index e503e53..f30707c 100644
--- a/src/render_cairo/clippath.rs
+++ b/src/render_cairo/clippath.rs
@@ -28,7 +28,6 @@ use {
pub fn apply(
- rtree: &tree::RenderTree,
node: tree::NodeRef,
cp: &tree::ClipPath,
opt: &Options,
@@ -61,10 +60,10 @@ pub fn apply(
match *node.value() {
tree::NodeKind::Path(ref p) => {
- path::draw(rtree, p, opt, &clip_cr);
+ path::draw(node.tree(), p, opt, &clip_cr);
}
tree::NodeKind::Text(_) => {
- text::draw(rtree, node, opt, &clip_cr);
+ text::draw(node, opt, &clip_cr);
}
_ => {}
}
diff --git a/src/render_cairo/fill.rs b/src/render_cairo/fill.rs
index bbfd2d3..f53063d 100644
--- a/src/render_cairo/fill.rs
+++ b/src/render_cairo/fill.rs
@@ -6,7 +6,10 @@
use cairo;
// self
-use tree;
+use tree::{
+ self,
+ TreeExt,
+};
use math;
use super::{
gradient,
@@ -41,7 +44,7 @@ pub fn apply(
gradient::prepare_radial(node, rg, fill.opacity, bbox, cr);
}
tree::NodeKind::Pattern(ref pattern) => {
- pattern::apply(rtree, node, pattern, opt, bbox, cr);
+ pattern::apply(node, pattern, opt, bbox, cr);
}
_ => {}
}
diff --git a/src/render_cairo/mod.rs b/src/render_cairo/mod.rs
index f8dd2d4..8191afa 100644
--- a/src/render_cairo/mod.rs
+++ b/src/render_cairo/mod.rs
@@ -16,6 +16,7 @@ use pangocairo::functions as pc;
// self
use tree::{
self,
+ TreeExt,
NodeExt,
};
use math::*;
@@ -76,21 +77,19 @@ impl Render for Backend {
fn render_node_to_image(
&self,
- rtree: &tree::RenderTree,
node: tree::NodeRef,
opt: &Options,
) -> Result<Box<OutputImage>> {
- let img = render_node_to_image(rtree, node, opt)?;
+ let img = render_node_to_image(node, opt)?;
Ok(Box::new(img))
}
fn calc_node_bbox(
&self,
- rtree: &tree::RenderTree,
node: tree::NodeRef,
opt: &Options,
) -> Option<Rect> {
- calc_node_bbox(rtree, node, opt)
+ calc_node_bbox(node, opt)
}
}
@@ -134,11 +133,10 @@ pub fn render_to_image(
/// Renders SVG to image.
pub fn render_node_to_image(
- rtree: &tree::RenderTree,
node: tree::NodeRef,
opt: &Options,
) -> Result<cairo::ImageSurface> {
- let node_bbox = if let Some(bbox) = calc_node_bbox(rtree, node, opt) {
+ let node_bbox = if let Some(bbox) = calc_node_bbox(node, opt) {
bbox
} else {
warn!("Node {:?} has zero size.", node.svg_id());
@@ -156,7 +154,7 @@ pub fn render_node_to_image(
}
apply_viewbox_transform(node_bbox, img_view, &cr);
- render_node_to_canvas(rtree, node, opt, img_view.to_screen_size(), &cr);
+ render_node_to_canvas(node, opt, img_view.to_screen_size(), &cr);
Ok(surface)
}
@@ -169,12 +167,11 @@ pub fn render_to_canvas(
cr: &cairo::Context,
) {
apply_viewbox_transform(rtree.svg_node().view_box, img_view, cr);
- render_group(rtree, rtree.root(), opt, img_view.to_screen_size(), &cr);
+ render_group(rtree.root(), opt, img_view.to_screen_size(), &cr);
}
/// Renders SVG node to canvas.
pub fn render_node_to_canvas(
- rtree: &tree::RenderTree,
node: tree::NodeRef,
opt: &Options,
img_size: ScreenSize,
@@ -185,7 +182,7 @@ pub fn render_node_to_canvas(
ts.append(&node.transform());
cr.transform(ts.to_native());
- render_node(rtree, node, opt, img_size, cr);
+ render_node(node, opt, img_size, cr);
cr.set_matrix(curr_ts);
}
@@ -229,7 +226,6 @@ fn apply_viewbox_transform(
}
fn render_group(
- rtree: &tree::RenderTree,
node: tree::NodeRef,
opt: &Options,
img_size: ScreenSize,
@@ -241,7 +237,7 @@ fn render_group(
for node in node.children() {
cr.transform(node.transform().to_native());
- let bbox = render_node(rtree, node, opt, img_size, cr);
+ let bbox = render_node(node, opt, img_size, cr);
if let Some(bbox) = bbox {
g_bbox.expand(bbox);
@@ -254,7 +250,6 @@ fn render_group(
}
fn render_group_impl(
- rtree: &tree::RenderTree,
node: tree::NodeRef,
g: &tree::Group,
opt: &Options,
@@ -278,12 +273,12 @@ fn render_group_impl(
let sub_cr = cairo::Context::new(&sub_surface);
sub_cr.set_matrix(cr.get_matrix());
- let bbox = render_group(rtree, node, opt, img_size, &sub_cr);
+ let bbox = render_group(node, opt, img_size, &sub_cr);
if let Some(idx) = g.clip_path {
- let clip_node = rtree.defs_at(idx);
+ let clip_node = node.tree().defs_at(idx);
if let tree::NodeKind::ClipPath(ref cp) = *clip_node.value() {
- clippath::apply(rtree, clip_node, cp, opt, bbox, img_size, &sub_cr);
+ clippath::apply(clip_node, cp, opt, bbox, img_size, &sub_cr);
}
}
@@ -304,7 +299,6 @@ fn render_group_impl(
}
fn render_node(
- rtree: &tree::RenderTree,
node: tree::NodeRef,
opt: &Options,
img_size: ScreenSize,
@@ -312,16 +306,16 @@ fn render_node(
) -> Option<Rect> {
match *node.value() {
tree::NodeKind::Path(ref path) => {
- Some(path::draw(rtree, path, opt, cr))
+ Some(path::draw(node.tree(), path, opt, cr))
}
tree::NodeKind::Text(_) => {
- Some(text::draw(rtree, node, opt, cr))
+ Some(text::draw(node, opt, cr))
}
tree::NodeKind::Image(ref img) => {
Some(image::draw(img, cr))
}
tree::NodeKind::Group(ref g) => {
- render_group_impl(rtree, node, g, opt, img_size, cr)
+ render_group_impl(node, g, opt, img_size, cr)
}
_ => None,
}
@@ -331,28 +325,26 @@ fn render_node(
///
/// Note: this method can be pretty expensive.
pub fn calc_node_bbox(
- rtree: &tree::RenderTree,
node: tree::NodeRef,
opt: &Options,
) -> Option<Rect> {
// We can't use 1x1 image, like in Qt backend because otherwise
// text layouts will be truncated.
let (surface, img_view) = create_surface(
- rtree.svg_node().size.to_screen_size(),
+ node.tree().svg_node().size.to_screen_size(),
opt,
).unwrap();
let cr = cairo::Context::new(&surface);
// We also have to apply the viewbox transform,
// otherwise text hinting will be different and bbox will be different too.
- apply_viewbox_transform(rtree.svg_node().view_box, img_view, &cr);
+ apply_viewbox_transform(node.tree().svg_node().view_box, img_view, &cr);
let abs_ts = utils::abs_transform(node);
- _calc_node_bbox(rtree, node, opt, abs_ts, &cr)
+ _calc_node_bbox(node, opt, abs_ts, &cr)
}
fn _calc_node_bbox(
- rtree: &tree::RenderTree,
node: tree::NodeRef,
opt: &Options,
ts: tree::Transform,
@@ -394,7 +386,7 @@ fn _calc_node_bbox(
let mut bbox = Rect::from_xywh(f64::MAX, f64::MAX, 0.0, 0.0);
for child in node.children() {
- if let Some(c_bbox) = _calc_node_bbox(rtree, child, opt, ts2, cr) {
+ if let Some(c_bbox) = _calc_node_bbox(child, opt, ts2, cr) {
bbox.expand(c_bbox);
}
}
diff --git a/src/render_cairo/pattern.rs b/src/render_cairo/pattern.rs
index 0f1b68a..db05949 100644
--- a/src/render_cairo/pattern.rs
+++ b/src/render_cairo/pattern.rs
@@ -23,7 +23,6 @@ use {
pub fn apply(
- rtree: &tree::RenderTree,
node: tree::NodeRef,
pattern: &tree::Pattern,
opt: &Options,
@@ -66,7 +65,7 @@ pub fn apply(
sub_cr.transform(cairo::Matrix::from_bbox(bbox));
}
- super::render_group(rtree, node, opt, img_size, &sub_cr);
+ super::render_group(node, opt, img_size, &sub_cr);
let mut ts = tree::Transform::default();
ts.append(&pattern.transform);
diff --git a/src/render_cairo/stroke.rs b/src/render_cairo/stroke.rs
index 6cde7e4..401e27f 100644
--- a/src/render_cairo/stroke.rs
+++ b/src/render_cairo/stroke.rs
@@ -6,7 +6,7 @@
use cairo;
// self
-use tree;
+use tree::prelude::*;
use math;
use super::{
gradient,
@@ -43,7 +43,7 @@ pub fn apply(
gradient::prepare_radial(node, rg, stroke.opacity, bbox, cr);
}
tree::NodeKind::Pattern(ref pattern) => {
- pattern::apply(rtree, node, pattern, opt, bbox, cr);
+ pattern::apply(node, pattern, opt, bbox, cr);
}
_ => {}
}
diff --git a/src/render_cairo/text.rs b/src/render_cairo/text.rs
index 8c552ef..6e2d384 100644
--- a/src/render_cairo/text.rs
+++ b/src/render_cairo/text.rs
@@ -36,13 +36,12 @@ pub struct PangoData {
}
pub fn draw(
- rtree: &tree::RenderTree,
node: tree::NodeRef,
opt: &Options,
cr: &cairo::Context,
) -> Rect {
draw_tspan(node, opt, cr,
- |tspan, x, y, w, d| _draw_tspan(rtree, tspan, opt, x, y, w, d, cr))
+ |tspan, x, y, w, d| _draw_tspan(node, tspan, opt, x, y, w, d, cr))
}
pub fn draw_tspan<DrawAt>(
@@ -108,7 +107,7 @@ pub fn draw_tspan<DrawAt>(
}
fn _draw_tspan(
- rtree: &tree::RenderTree,
+ node: tree::NodeRef,
tspan: &tree::TSpan,
opt: &Options,
x: f64,
@@ -139,7 +138,7 @@ fn _draw_tspan(
if let Some(ref style) = tspan.decoration.underline {
line_rect.origin.y = y + baseline_offset
- font_metrics.get_underline_position() as f64 / PANGO_SCALE_64;
- draw_line(rtree, line_rect, &style.fill, &style.stroke, opt, cr);
+ draw_line(node.tree(), line_rect, &style.fill, &style.stroke, opt, cr);
}
// Draw overline.
@@ -147,17 +146,17 @@ fn _draw_tspan(
// Should be drawn before/under text.
if let Some(ref style) = tspan.decoration.overline {
line_rect.origin.y = y + font_metrics.get_underline_thickness() as f64 / PANGO_SCALE_64;
- draw_line(rtree, line_rect, &style.fill, &style.stroke, opt, cr);
+ draw_line(node.tree(), line_rect, &style.fill, &style.stroke, opt, cr);
}
// Draw text.
cr.move_to(x, y);
- fill::apply(rtree, &tspan.fill, opt, bbox, cr);
+ fill::apply(node.tree(), &tspan.fill, opt, bbox, cr);
pc::update_layout(cr, &pd.layout);
pc::show_layout(cr, &pd.layout);
- stroke::apply(rtree, &tspan.stroke, opt, bbox, cr);
+ stroke::apply(node.tree(), &tspan.stroke, opt, bbox, cr);
pc::layout_path(cr, &pd.layout);
cr.stroke();
@@ -170,7 +169,7 @@ fn _draw_tspan(
line_rect.origin.y = y + baseline_offset
- font_metrics.get_strikethrough_position() as f64 / PANGO_SCALE_64;
line_rect.size.height = font_metrics.get_strikethrough_thickness() as f64 / PANGO_SCALE_64;
- draw_line(rtree, line_rect, &style.fill, &style.stroke, opt, cr);
+ draw_line(node.tree(), line_rect, &style.fill, &style.stroke, opt, cr);
}
}
diff --git a/src/render_qt/clippath.rs b/src/render_qt/clippath.rs
index c962ed9..fcd394b 100644
--- a/src/render_qt/clippath.rs
+++ b/src/render_qt/clippath.rs
@@ -25,7 +25,6 @@ use {
pub fn apply(
- rtree: &tree::RenderTree,
node: tree::NodeRef,
cp: &tree::ClipPath,
opt: &Options,
@@ -57,10 +56,10 @@ pub fn apply(
match *node.value() {
tree::NodeKind::Path(ref path_node) => {
- path::draw(rtree, path_node, opt, &clip_p);
+ path::draw(node.tree(), path_node, opt, &clip_p);
}
tree::NodeKind::Text(_) => {
- text::draw(rtree, node, opt, &clip_p);
+ text::draw(node, opt, &clip_p);
}
_ => {}
}
diff --git a/src/render_qt/fill.rs b/src/render_qt/fill.rs
index c96817a..494af28 100644
--- a/src/render_qt/fill.rs
+++ b/src/render_qt/fill.rs
@@ -6,7 +6,7 @@
use qt;
// self
-use tree;
+use tree::prelude::*;
use math::{
self,
Rect,
@@ -47,7 +47,7 @@ pub fn apply(
}
tree::NodeKind::Pattern(ref pattern) => {
let ts = p.get_transform();
- pattern::apply(rtree, node, pattern, opt, ts, bbox, &mut brush);
+ pattern::apply(node, pattern, opt, ts, bbox, &mut brush);
}
_ => {}
}
diff --git a/src/render_qt/mod.rs b/src/render_qt/mod.rs
index 238ddae..643b6e1 100644
--- a/src/render_qt/mod.rs
+++ b/src/render_qt/mod.rs
@@ -10,10 +10,7 @@ use std::f64;
use qt;
// self
-use tree::{
- self,
- NodeExt,
-};
+use tree::prelude::*;
use math::*;
use traits::{
ConvTransform,
@@ -71,17 +68,15 @@ impl Render for Backend {
fn render_node_to_image(
&self,
- rtree: &tree::RenderTree,
node: tree::NodeRef,
opt: &Options,
) -> Result<Box<OutputImage>> {
- let img = render_node_to_image(rtree, node, opt)?;
+ let img = render_node_to_image(node, opt)?;
Ok(Box::new(img))
}
fn calc_node_bbox(
&self,
- _: &tree::RenderTree,
node: tree::NodeRef,
opt: &Options,
) -> Option<Rect> {
@@ -112,7 +107,6 @@ pub fn render_to_image(
/// Renders SVG node to image.
pub fn render_node_to_image(
- rtree: &tree::RenderTree,
node: tree::NodeRef,
opt: &Options,
) -> Result<qt::Image> {
@@ -127,7 +121,7 @@ pub fn render_node_to_image(
let painter = qt::Painter::new(&img);
apply_viewbox_transform(node_bbox, img_view, &painter);
- render_node_to_canvas(rtree, node, opt, img_view, &painter);
+ render_node_to_canvas(node, opt, img_view, &painter);
painter.end();
Ok(img)
@@ -171,12 +165,11 @@ pub fn render_to_canvas(
painter: &qt::Painter,
) {
apply_viewbox_transform(rtree.svg_node().view_box, img_view, painter);
- render_group(rtree, rtree.root(), opt, img_view.to_screen_size(), &painter);
+ render_group(rtree.root(), opt, img_view.to_screen_size(), &painter);
}
/// Renders SVG node to canvas.
pub fn render_node_to_canvas(
- rtree: &tree::RenderTree,
node: tree::NodeRef,
opt: &Options,
img_view: Rect,
@@ -187,7 +180,7 @@ pub fn render_node_to_canvas(
ts.append(&node.transform());
painter.apply_transform(&ts.to_native());
- render_node(rtree, node, opt, img_view.to_screen_size(), painter);
+ render_node(node, opt, img_view.to_screen_size(), painter);
painter.set_transform(&curr_ts);
}
@@ -207,7 +200,6 @@ pub fn apply_viewbox_transform(
// TODO: render groups backward to reduce memory usage
// current implementation keeps parent canvas until all children are rendered
fn render_group(
- rtree: &tree::RenderTree,
node: tree::NodeRef,
opt: &Options,
img_size: ScreenSize,
@@ -220,7 +212,7 @@ fn render_group(
// Apply transform.
p.apply_transform(&node.transform().to_native());
- let bbox = render_node(rtree, node, opt, img_size, p);
+ let bbox = render_node(node, opt, img_size, p);
if let Some(bbox) = bbox {
g_bbox.expand(bbox);
@@ -234,7 +226,6 @@ fn render_group(
}
fn render_group_impl(
- rtree: &tree::RenderTree,
node: tree::NodeRef,
g: &tree::Group,
opt: &Options,
@@ -259,12 +250,12 @@ fn render_group_impl(
let sub_p = qt::Painter::new(&sub_img);
sub_p.set_transform(&p.get_transform());
- let bbox = render_group(rtree, node, opt, img_size, &sub_p);
+ let bbox = render_group(node, opt, img_size, &sub_p);
if let Some(idx) = g.clip_path {
- let clip_node = rtree.defs_at(idx);
+ let clip_node = node.tree().defs_at(idx);
if let tree::NodeKind::ClipPath(ref cp) = *clip_node.value() {
- clippath::apply(rtree, clip_node, cp, opt, bbox, img_size, &sub_p);
+ clippath::apply(clip_node, cp, opt, bbox, img_size, &sub_p);
}
}
@@ -286,7 +277,6 @@ fn render_group_impl(
}
fn render_node(
- rtree: &tree::RenderTree,
node: tree::NodeRef,
opt: &Options,
img_size: ScreenSize,
@@ -294,16 +284,16 @@ fn render_node(
) -> Option<Rect> {
match *node.value() {
tree::NodeKind::Path(ref path) => {
- Some(path::draw(rtree, path, opt, p))
+ Some(path::draw(node.tree(), path, opt, p))
}
tree::NodeKind::Text(_) => {
- Some(text::draw(rtree, node, opt, p))
+ Some(text::draw(node, opt, p))
}
tree::NodeKind::Image(ref img) => {
Some(image::draw(img, p))
}
tree::NodeKind::Group(ref g) => {
- render_group_impl(rtree, node, g, opt, img_size, p)
+ render_group_impl(node, g, opt, img_size, p)
}
_ => None,
}
diff --git a/src/render_qt/pattern.rs b/src/render_qt/pattern.rs
index d0ff18d..3db3916 100644
--- a/src/render_qt/pattern.rs
+++ b/src/render_qt/pattern.rs
@@ -18,7 +18,6 @@ use {
};
pub fn apply(
- rtree: &tree::RenderTree,
pattern_node: tree::NodeRef,
pattern: &tree::Pattern,
opt: &Options,
@@ -61,7 +60,7 @@ pub fn apply(
p.apply_transform(&qt::Transform::from_bbox(bbox));
}
- super::render_group(rtree, pattern_node, opt, img_size, &p);
+ super::render_group(pattern_node, opt, img_size, &p);
p.end();
brush.set_pattern(img);
diff --git a/src/render_qt/stroke.rs b/src/render_qt/stroke.rs
index 4b7fdff..bac8b86 100644
--- a/src/render_qt/stroke.rs
+++ b/src/render_qt/stroke.rs
@@ -6,7 +6,7 @@
use qt;
// self
-use tree;
+use tree::prelude::*;
use math::{
self,
Rect,
@@ -49,7 +49,7 @@ pub fn apply(
}
tree::NodeKind::Pattern(ref pattern) => {
let ts = p.get_transform();
- pattern::apply(rtree, node, pattern, opt, ts, bbox, &mut brush);
+ pattern::apply(node, pattern, opt, ts, bbox, &mut brush);
}
_ => {}
}
diff --git a/src/render_qt/text.rs b/src/render_qt/text.rs
index 2333115..99a7ac7 100644
--- a/src/render_qt/text.rs
+++ b/src/render_qt/text.rs
@@ -21,13 +21,12 @@ use {
pub fn draw(
- rtree: &tree::RenderTree,
node: tree::NodeRef,
opt: &Options,
p: &qt::Painter,
) -> Rect {
draw_tspan(node, p,
- |tspan, x, y, w, font| _draw_tspan(rtree, tspan, opt, x, y, w, &font, p))
+ |tspan, x, y, w, font| _draw_tspan(node, tspan, opt, x, y, w, &font, p))
}
pub fn draw_tspan<DrawAt>(
@@ -80,7 +79,7 @@ pub fn draw_tspan<DrawAt>(
}
fn _draw_tspan(
- rtree: &tree::RenderTree,
+ node: tree::NodeRef,
tspan: &tree::TSpan,
opt: &Options,
x: f64,
@@ -107,7 +106,7 @@ fn _draw_tspan(
// Should be drawn before/under text.
if let Some(ref style) = tspan.decoration.underline {
line_rect.origin.y = y + font_metrics.height() - font_metrics.underline_pos();
- draw_line(rtree, line_rect, &style.fill, &style.stroke, opt, p);
+ draw_line(node.tree(), line_rect, &style.fill, &style.stroke, opt, p);
}
// Draw overline.
@@ -115,14 +114,14 @@ fn _draw_tspan(
// Should be drawn before/under text.
if let Some(ref style) = tspan.decoration.overline {
line_rect.origin.y = y + font_metrics.height() - font_metrics.overline_pos();
- draw_line(rtree, line_rect, &style.fill, &style.stroke, opt, p);
+ draw_line(node.tree(), line_rect, &style.fill, &style.stroke, opt, p);
}
let bbox = Rect::from_xywh(0.0, 0.0, width, font_metrics.height());
// Draw text.
- fill::apply(rtree, &tspan.fill, opt, bbox, p);
- stroke::apply(rtree, &tspan.stroke, opt, bbox, p);
+ fill::apply(node.tree(), &tspan.fill, opt, bbox, p);
+ stroke::apply(node.tree(), &tspan.stroke, opt, bbox, p);
p.draw_text(x, y, &tspan.text);
@@ -131,7 +130,7 @@ fn _draw_tspan(
// Should be drawn after/over text.
if let Some(ref style) = tspan.decoration.line_through {
line_rect.origin.y = y + baseline_offset - font_metrics.strikeout_pos();
- draw_line(rtree, line_rect, &style.fill, &style.stroke, opt, p);
+ draw_line(node.tree(), line_rect, &style.fill, &style.stroke, opt, p);
}
}
diff --git a/src/tree/mod.rs b/src/tree/mod.rs
index 0808cb4..d47bbca 100644
--- a/src/tree/mod.rs
+++ b/src/tree/mod.rs
@@ -16,6 +16,12 @@ mod attribute;
mod dump;
mod node;
+/// Basic modules and traits for tree manipulation.
+pub mod prelude {
+ pub use tree;
+ pub use super::NodeExt;
+ pub use super::TreeExt;
+}
/// Alias for ego_tree::NodeId<NodeKind>.
pub type NodeId = ego_tree::NodeId<NodeKind>;
@@ -29,28 +35,50 @@ pub type NodeMut<'a> = ego_tree::NodeMut<'a, NodeKind>;
/// A rendering tree container.
///
/// Contains all the nodes that are required for rendering.
-pub struct RenderTree(ego_tree::Tree<NodeKind>);
+///
+/// Alias for ego_tree::Tree<NodeKind>.
+pub type RenderTree = ego_tree::Tree<NodeKind>;
-impl RenderTree {
+/// Additional `RenderTree` methods.
+pub trait TreeExt {
/// Creates a new `RenderTree`.
- pub fn new(svg: Svg) -> Self {
- let mut tree = ego_tree::Tree::new(NodeKind::Svg(svg));
- tree.root_mut().append(NodeKind::Defs);
- RenderTree(tree)
- }
+ fn create(svg: Svg) -> Self;
- /// Returns the root node.
- pub fn root(&self) -> NodeRef {
- self.0.root()
- }
+ /// Returns the `Svg` node's data.
+ fn svg_node(&self) -> &Svg;
+
+ /// Returns the `Defs` node.
+ fn defs(&self) -> NodeRef;
+
+ /// Checks that `node` is part of the `Defs` children.
+ fn is_in_defs(&self, node: NodeRef) -> bool;
+
+ /// Appends `NodeKind` to the `Defs` node.
+ fn append_to_defs(&mut self, kind: NodeKind) -> NodeId;
+
+ /// Append `NodeKind` as a child to the node by `NodeId`.
+ fn append_child(&mut self, parent: NodeId, kind: NodeKind) -> NodeId;
+
+ /// Returns `Defs` node child by `NodeId`.
+ fn defs_at(&self, id: NodeId) -> NodeRef;
+
+ /// Searches for `NodeId` in `Defs` children by ID.
+ fn defs_id(&self, id: &str) -> Option<NodeId>;
+
+ /// Converts the document to `svgdom::Document`.
+ ///
+ /// Used to save document to file for debug purposes.
+ fn to_svgdom(&self) -> svgdom::Document;
+}
- /// Returns the mutable root node.
- pub fn root_mut(&mut self) -> NodeMut {
- self.0.root_mut()
+impl TreeExt for RenderTree {
+ fn create(svg: Svg) -> Self {
+ let mut tree = ego_tree::Tree::new(NodeKind::Svg(svg));
+ tree.root_mut().append(NodeKind::Defs);
+ tree
}
- /// Returns the `Svg` node's data.
- pub fn svg_node(&self) -> &Svg {
+ fn svg_node(&self) -> &Svg {
if let NodeKind::Svg(ref svg) = *self.root().value() {
svg
} else {
@@ -58,28 +86,26 @@ impl RenderTree {
}
}
- /// Returns the `Defs` node.
- pub fn defs(&self) -> NodeRef {
+ fn defs(&self) -> NodeRef {
self.root().first_child().unwrap()
}
- /// Checks that `node` is part of the `Defs` children.
- pub fn is_in_defs(&self, node: NodeRef) -> bool {
+ fn is_in_defs(&self, node: NodeRef) -> bool {
let defs = self.defs();
node.ancestors().find(|n| *n == defs).is_some()
}
- pub(crate) fn append_defs(&mut self, kind: NodeKind) -> NodeId {
+ fn append_to_defs(&mut self, kind: NodeKind) -> NodeId {
let defs_id = self.defs().id();
self.append_child(defs_id, kind)
}
- pub(crate) fn append_child(&mut self, parent: NodeId, kind: NodeKind) -> NodeId {
- let mut parent = self.0.get_mut(parent);
+ fn append_child(&mut self, parent: NodeId, kind: NodeKind) -> NodeId {
+ let mut parent = self.get_mut(parent);
parent.append(kind).id()
}
- pub(crate) fn defs_at(&self, id: NodeId) -> NodeRef {
+ fn defs_at(&self, id: NodeId) -> NodeRef {
for n in self.defs().children() {
if n.id() == id {
return n;
@@ -89,7 +115,7 @@ impl RenderTree {
unreachable!();
}
- pub(crate) fn defs_id(&self, id: &str) -> Option<NodeId> {
+ fn defs_id(&self, id: &str) -> Option<NodeId> {
for n in self.defs().children() {
if n.svg_id() == id {
return Some(n.id());
@@ -99,15 +125,12 @@ impl RenderTree {
unreachable!();
}
- /// Converts the document to `svgdom::Document`.
- ///
- /// Used to save document to file for debug purposes.
- pub fn to_svgdom(&self) -> svgdom::Document {
+ fn to_svgdom(&self) -> svgdom::Document {
dump::conv_doc(self)
}
}
-/// Additional `NodeRef` method.
+/// Additional `NodeRef` methods.
pub trait NodeExt {
/// Returns node's ID.
///
@@ -120,9 +143,6 @@ pub trait NodeExt {
/// If a current node doesn't support transformation - a default
/// transform will be returned.
fn transform(&self) -> Transform;
-
- /// Returns an iterator over this node and its descendants.
- fn descendants(&self) -> Descendants;
}
impl<'a> NodeExt for NodeRef<'a> {
@@ -133,25 +153,4 @@ impl<'a> NodeExt for NodeRef<'a> {
fn transform(&self) -> Transform {
self.value().transform()
}
-
- fn descendants(&self) -> Descendants {
- Descendants(self.traverse())
- }
-}
-
-/// Iterator over node and its descendants.
-pub struct Descendants<'a>(ego_tree::iter::Traverse<'a, NodeKind>);
-
-impl<'a> Iterator for Descendants<'a> {
- type Item = NodeRef<'a>;
-
- fn next(&mut self) -> Option<NodeRef<'a>> {
- loop {
- match self.0.next() {
- Some(ego_tree::iter::Edge::Open(node)) => return Some(node),
- Some(ego_tree::iter::Edge::Close(_)) => {}
- None => return None
- }
- }
- }
}
diff --git a/tools/rendersvg/src/main.rs b/tools/rendersvg/src/main.rs
index 728c4bf..5d3483c 100644
--- a/tools/rendersvg/src/main.rs
+++ b/tools/rendersvg/src/main.rs
@@ -29,13 +29,13 @@ use clap::{
};
use resvg::{
- tree,
FitTo,
Options,
NodeExt,
RectExt,
Render,
};
+use resvg::tree::prelude::*;
use svgdom::{
ChainedErrorExt,
@@ -125,7 +125,7 @@ fn process() -> Result<(), Error> {
if let Some(ref out_png) = args.out_png {
let img = if let Some(ref id) = args.export_id {
if let Some(node) = rtree.root().descendants().find(|n| n.svg_id() == id) {
- args.backend.render_node_to_image(&rtree, node, &opt)
+ args.backend.render_node_to_image(node, &opt)
} else {
return Err(Error::InvalidId(id.clone()));
}
@@ -186,7 +186,7 @@ fn query_all(
(v * 1000.0).round() / 1000.0
}
- if let Some(bbox) = args.backend.calc_node_bbox(&rtree, node, &opt) {
+ if let Some(bbox) = args.backend.calc_node_bbox(node, &opt) {
println!("{},{},{},{},{}", node.svg_id(),
round_len(bbox.x()), round_len(bbox.y()),
round_len(bbox.width()), round_len(bbox.height()));