[librsvg] viewport.rs: new draw_in_viewport() function
- From: Federico Mena Quintero <federico src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [librsvg] viewport.rs: new draw_in_viewport() function
- Date: Wed, 27 Sep 2017 16:43:40 +0000 (UTC)
commit 2a66e60257225b6d784431097d4aba47df7af9f8
Author: Federico Mena Quintero <federico gnome org>
Date: Wed Sep 27 08:44:40 2017 -0500
viewport.rs: new draw_in_viewport() function
The general "establish a new viewport" pattern is done in different
ways in several places in the code. We capture this pattern in a
single function which takes care of setting up a clipping rectangle
and a transformation matrix, and call a lambda to actually draw the
contents.
Makefile.am | 3 +-
rust/src/lib.rs | 1 +
rust/src/structure.rs | 68 +++++++++++--------------------------------------
rust/src/viewport.rs | 60 +++++++++++++++++++++++++++++++++++++++++++
4 files changed, 78 insertions(+), 54 deletions(-)
---
diff --git a/Makefile.am b/Makefile.am
index ae3f1c9..b18babc 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -96,7 +96,8 @@ RUST_SOURCES = \
rust/src/structure.rs \
rust/src/transform.rs \
rust/src/util.rs \
- rust/src/viewbox.rs
+ rust/src/viewbox.rs \
+ rust/src/viewport.rs
RUST_EXTRA = \
rust/Cargo.lock \
diff --git a/rust/src/lib.rs b/rust/src/lib.rs
index 2533e22..9dd7cec 100644
--- a/rust/src/lib.rs
+++ b/rust/src/lib.rs
@@ -155,3 +155,4 @@ mod structure;
mod transform;
mod util;
mod viewbox;
+mod viewport;
diff --git a/rust/src/structure.rs b/rust/src/structure.rs
index abe4ecf..c52ff75 100644
--- a/rust/src/structure.rs
+++ b/rust/src/structure.rs
@@ -18,6 +18,7 @@ use property_bag;
use property_bag::*;
use util::*;
use viewbox::*;
+use viewport::draw_in_viewport;
/***** NodeGroup *****/
@@ -171,60 +172,21 @@ impl NodeTrait for NodeSvg {
let nw = self.w.get ().normalize (draw_ctx);
let nh = self.h.get ().normalize (draw_ctx);
- // width or height set to 0 disables rendering of the element
- // https://www.w3.org/TR/SVG/struct.html#SVGElementWidthAttribute
- if double_equals (nw, 0.0) || double_equals (nh, 0.0) {
- return;
- }
-
- drawing_ctx::state_reinherit_top (draw_ctx, node.get_state (), dominate);
-
let state = drawing_ctx::get_current_state (draw_ctx);
-
- let affine_old = drawing_ctx::get_current_state_affine (draw_ctx);
-
- if let Some (vbox) = self.vbox.get () {
- // viewBox width==0 or height==0 disables rendering of the element
- // https://www.w3.org/TR/SVG/coords.html#ViewBoxAttribute
- if double_equals (vbox.0.width, 0.0) || double_equals (vbox.0.height, 0.0) {
- return;
- }
-
- let (x, y, w, h) = self.preserve_aspect_ratio.get ().compute (vbox.0.width, vbox.0.height,
- nx, ny, nw, nh);
-
- let mut affine = affine_old;
- affine.translate (x, y);
- affine.scale (w / vbox.0.width, h / vbox.0.height);
- affine.translate (-vbox.0.x, -vbox.0.y);
- drawing_ctx::set_current_state_affine (draw_ctx, affine);
-
- drawing_ctx::push_view_box (draw_ctx, vbox.0.width, vbox.0.height);
- } else {
- let mut affine = affine_old;
- affine.translate (nx, ny);
-
- drawing_ctx::set_current_state_affine (draw_ctx, affine);
- drawing_ctx::push_view_box (draw_ctx, nw, nh);
- }
-
- let affine_new = drawing_ctx::get_current_state_affine (draw_ctx);
-
- drawing_ctx::push_discrete_layer (draw_ctx);
-
- // Bounding box addition must be AFTER the discrete layer
- // push, which must be AFTER the transformation happens.
-
- if !drawing_ctx::state_is_overflow (state) && node.get_parent ().is_some () {
- drawing_ctx::set_current_state_affine (draw_ctx, affine_old);
- drawing_ctx::add_clipping_rect (draw_ctx, nx, ny, nw, nh);
- drawing_ctx::set_current_state_affine (draw_ctx, affine_new);
- }
-
- node.draw_children (draw_ctx, -1); // dominate==-1 so it won't reinherit or push a layer
-
- drawing_ctx::pop_discrete_layer (draw_ctx);
- drawing_ctx::pop_view_box (draw_ctx);
+ let do_clip = !drawing_ctx::state_is_overflow (state) && node.get_parent ().is_some ();
+
+ draw_in_viewport(nx, ny, nw, nh,
+ do_clip,
+ self.vbox.get(),
+ self.preserve_aspect_ratio.get(),
+ drawing_ctx::get_current_state_affine(draw_ctx),
+ draw_ctx,
+ |affine| {
+ drawing_ctx::state_push(draw_ctx);
+ drawing_ctx::set_current_state_affine(draw_ctx, affine);
+ node.draw_children(draw_ctx, -1); // dominate==-1 so it won't reinherit or push
a layer
+ drawing_ctx::state_pop(draw_ctx);
+ });
}
fn get_c_impl (&self) -> *const RsvgCNodeImpl {
diff --git a/rust/src/viewport.rs b/rust/src/viewport.rs
new file mode 100644
index 0000000..f05caa7
--- /dev/null
+++ b/rust/src/viewport.rs
@@ -0,0 +1,60 @@
+use cairo;
+use cairo::MatrixTrait;
+
+use aspect_ratio::AspectRatio;
+use drawing_ctx;
+use drawing_ctx::RsvgDrawingCtx;
+use util::*;
+use viewbox::*;
+
+pub fn draw_in_viewport<F>(vx: f64, vy: f64, vw: f64, vh: f64,
+ do_clip: bool,
+ vbox: Option<ViewBox>,
+ preserve_aspect_ratio: AspectRatio,
+ mut affine: cairo::Matrix,
+ draw_ctx: *const RsvgDrawingCtx,
+ draw_fn: F)
+ where F: FnOnce(cairo::Matrix)
+{
+ // width or height set to 0 disables rendering of the element
+ // https://www.w3.org/TR/SVG/struct.html#SVGElementWidthAttribute
+ // https://www.w3.org/TR/SVG/struct.html#UseElementWidthAttribute
+ // https://www.w3.org/TR/SVG/struct.html#ImageElementWidthAttribute
+ // https://www.w3.org/TR/SVG/painting.html#MarkerWidthAttribute
+
+ if double_equals(vw, 0.0) || double_equals(vh, 0.0) {
+ return;
+ }
+
+ let vbox_size;
+
+ if let Some(vbox) = vbox {
+ // the preserveAspectRatio attribute is only used if viewBox is specified
+ // https://www.w3.org/TR/SVG/coords.html#PreserveAspectRatioAttribute
+
+ let (x, y, w, h) = preserve_aspect_ratio.compute(vbox.0.width, vbox.0.height,
+ vx, vy, vw, vh);
+
+ affine.translate(x, y);
+ affine.scale(w / vbox.0.width, h / vbox.0.height);
+ affine.translate(-vbox.0.x, -vbox.0.y);
+
+ vbox_size = (vbox.0.width, vbox.0.height);
+ } else {
+ affine.translate(vx, vy);
+ vbox_size = (vw, vh);
+ }
+
+ drawing_ctx::push_view_box(draw_ctx, vbox_size.0, vbox_size.1);
+ drawing_ctx::push_discrete_layer(draw_ctx);
+
+ if do_clip {
+ drawing_ctx::add_clipping_rect(draw_ctx, vx, vy, vw, vh);
+ }
+
+ draw_fn(affine);
+
+ drawing_ctx::pop_discrete_layer(draw_ctx);
+ drawing_ctx::pop_view_box(draw_ctx);
+
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]