[librsvg] draw_in_viewport(): Take in a ClipMode enum instead of an obscure boolean



commit 62f31feec7d7bb94b9e9fa0e525b67bbd4042414
Author: Federico Mena Quintero <federico gnome org>
Date:   Thu Sep 28 08:50:19 2017 -0500

    draw_in_viewport(): Take in a ClipMode enum instead of an obscure boolean
    
    I'm starting to understand
    https://www.w3.org/TR/SVG/masking.html#AutoClipAtViewportNotViewBox
    which mentions the difference between clipping to the viewport (the
    x/y/width/heigth attributes in the element being rendered), and
    clipping to the vbox (the viewBox attribute).

 rust/src/structure.rs |    6 +++---
 rust/src/viewport.rs  |   44 +++++++++++++++++++++++++++-----------------
 2 files changed, 30 insertions(+), 20 deletions(-)
---
diff --git a/rust/src/structure.rs b/rust/src/structure.rs
index 5d330d9..e5e07d6 100644
--- a/rust/src/structure.rs
+++ b/rust/src/structure.rs
@@ -18,7 +18,7 @@ use property_bag;
 use property_bag::*;
 use util::*;
 use viewbox::*;
-use viewport::draw_in_viewport;
+use viewport::{ClipMode,draw_in_viewport};
 
 /***** NodeGroup *****/
 
@@ -176,7 +176,7 @@ impl NodeTrait for NodeSvg {
         let do_clip = !drawing_ctx::state_is_overflow (state) && node.get_parent ().is_some ();
 
         draw_in_viewport(nx, ny, nw, nh,
-                         false,
+                         ClipMode::ClipToViewport,
                          do_clip,
                          self.vbox.get(),
                          self.preserve_aspect_ratio.get(),
@@ -304,7 +304,7 @@ impl NodeTrait for NodeUse {
                         && drawing_ctx::state_is_overflow (child.get_state ()));
 
                 draw_in_viewport(nx, ny, nw, nh,
-                                 true,
+                                 ClipMode::ClipToVbox,
                                  do_clip,
                                  symbol.vbox.get(),
                                  symbol.preserve_aspect_ratio.get(),
diff --git a/rust/src/viewport.rs b/rust/src/viewport.rs
index 6a8cfc6..15035f3 100644
--- a/rust/src/viewport.rs
+++ b/rust/src/viewport.rs
@@ -7,8 +7,14 @@ use drawing_ctx::RsvgDrawingCtx;
 use util::*;
 use viewbox::*;
 
+#[derive(Debug, Copy, Clone, PartialEq)]
+pub enum ClipMode {
+    ClipToViewport,
+    ClipToVbox
+}
+
 pub fn draw_in_viewport<F>(vx: f64, vy: f64, vw: f64, vh: f64,
-                           clip_before_layer_push: bool,
+                           clip_mode: ClipMode,
                            do_clip: bool,
                            vbox: Option<ViewBox>,
                            preserve_aspect_ratio: AspectRatio,
@@ -21,7 +27,7 @@ pub fn draw_in_viewport<F>(vx: f64, vy: f64, vw: f64, vh: f64,
 
     in_viewport(&mut ctx,
                 vx, vy, vw, vh,
-                clip_before_layer_push,
+                clip_mode,
                 do_clip,
                 vbox,
                 preserve_aspect_ratio,
@@ -68,7 +74,7 @@ impl ViewportCtx for RsvgDrawingCtxWrapper {
 
 fn in_viewport<F>(ctx: &mut ViewportCtx,
                   vx: f64, vy: f64, vw: f64, vh: f64,
-                  clip_before_layer_push: bool,
+                  clip_mode: ClipMode,
                   do_clip: bool,
                   vbox: Option<ViewBox>,
                   preserve_aspect_ratio: AspectRatio,
@@ -86,7 +92,7 @@ fn in_viewport<F>(ctx: &mut ViewportCtx,
         return;
     }
 
-    let vbox_size;
+    let old_affine = affine;
 
     if let Some(vbox) = vbox {
         // the preserveAspectRatio attribute is only used if viewBox is specified
@@ -99,25 +105,29 @@ fn in_viewport<F>(ctx: &mut ViewportCtx,
         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);
+        ctx.set_affine(affine);
+
+        ctx.push_view_box(vbox.0.width, vbox.0.height);
+
+        ctx.push_discrete_layer();
 
-        if clip_before_layer_push && do_clip {
+        if do_clip && clip_mode == ClipMode::ClipToVbox {
             ctx.add_clipping_rect(vbox.0.x, vbox.0.y, vbox.0.width, vbox.0.height);
         }
     } else {
         affine.translate(vx, vy);
-        vbox_size = (vw, vh);
-    }
+        ctx.set_affine(affine);
 
-    ctx.push_view_box(vbox_size.0, vbox_size.1);
-    ctx.push_discrete_layer();
+        ctx.push_view_box(vw, vh);
+        ctx.push_discrete_layer();
+    }
 
-    if !clip_before_layer_push && do_clip {
+    if do_clip && clip_mode == ClipMode::ClipToViewport {
+        ctx.set_affine(old_affine);
         ctx.add_clipping_rect(vx, vy, vw, vh);
+        ctx.set_affine(affine);
     }
 
-    ctx.set_affine(affine);
-
     draw_fn();
 
     ctx.pop_discrete_layer();
@@ -164,7 +174,7 @@ mod tests {
     }
 
     fn call_in_viewport(vx: f64, vy: f64, vw: f64, vh: f64,
-                        clip_before_layer_push: bool,
+                        clip_mode: ClipMode,
                         do_clip: bool,
                         vbox: Option<ViewBox>,
                         preserve_aspect_ratio: AspectRatio,
@@ -172,7 +182,7 @@ mod tests {
                         ctx: &mut Ctx) {
         in_viewport(ctx,
                     vx, vy, vw, vh,
-                    clip_before_layer_push,
+                    clip_mode,
                     do_clip,
                     vbox,
                     preserve_aspect_ratio,
@@ -200,7 +210,7 @@ mod tests {
         };
 
         call_in_viewport(10.0, 10.0, 10.0, 10.0,
-                         false,
+                         ClipMode::ClipToViewport,
                          true,
                          Some(ViewBox(cairo::Rectangle {
                              x: 50.0,
@@ -230,7 +240,7 @@ mod tests {
         };
 
         call_in_viewport(10.0, 10.0, 20.0, 20.0,
-                         true,
+                         ClipMode::ClipToVbox,
                          true,
                          Some(ViewBox(cairo::Rectangle {
                              x: 0.0,


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]