[librsvg] Pass a 'clipping' argument to all the drawing methods, draw_pango_layout() and draw_path_builder()



commit 682e489bd5e28d76793770b6b91b93f9cb9ba54e
Author: Federico Mena Quintero <federico gnome org>
Date:   Mon Mar 26 21:49:15 2018 -0600

    Pass a 'clipping' argument to all the drawing methods, draw_pango_layout() and draw_path_builder()
    
    We are going to remove RsvgCairoClip and its vtable, because the
    fundamental drawing functions just need to know whether they are
    clipping or not.  Instead, we'll pass a boolean argument to say
    whether we are in a clipping context or not.

 librsvg/rsvg-base.c               | 22 +++---------
 librsvg/rsvg-cairo-clip.c         | 16 +--------
 librsvg/rsvg-cairo-draw.c         | 16 ++-------
 librsvg/rsvg-cairo-draw.h         |  6 ----
 librsvg/rsvg-cairo-render.c       |  4 +--
 librsvg/rsvg-cairo-render.h       |  8 -----
 librsvg/rsvg-filter.c             |  2 +-
 librsvg/rsvg-handle.c             |  4 +--
 librsvg/rsvg-private.h            | 22 ++++--------
 rsvg_internals/src/clip_path.rs   |  2 +-
 rsvg_internals/src/cnode.rs       |  9 +++--
 rsvg_internals/src/draw.rs        | 39 +++------------------
 rsvg_internals/src/drawing_ctx.rs | 39 +++++----------------
 rsvg_internals/src/gradient.rs    |  2 +-
 rsvg_internals/src/image.rs       |  2 +-
 rsvg_internals/src/lib.rs         |  2 --
 rsvg_internals/src/link.rs        |  6 ++--
 rsvg_internals/src/marker.rs      | 27 +++++++++++----
 rsvg_internals/src/mask.rs        |  2 +-
 rsvg_internals/src/node.rs        | 26 +++++++++-----
 rsvg_internals/src/pattern.rs     |  4 +--
 rsvg_internals/src/shapes.rs      | 72 ++++++++++++++++++++++++++++++---------
 rsvg_internals/src/stop.rs        |  2 +-
 rsvg_internals/src/structure.rs   | 22 ++++++------
 rsvg_internals/src/text.rs        | 42 ++++++++++++-----------
 25 files changed, 177 insertions(+), 221 deletions(-)
---
diff --git a/librsvg/rsvg-base.c b/librsvg/rsvg-base.c
index 437bc75b..f235b507 100644
--- a/librsvg/rsvg-base.c
+++ b/librsvg/rsvg-base.c
@@ -478,7 +478,10 @@ rsvg_drawing_ctx_add_node_and_ancestors_to_stack (RsvgDrawingCtx *draw_ctx, Rsvg
 }
 
 void
-rsvg_drawing_ctx_draw_node_from_stack (RsvgDrawingCtx *ctx, RsvgNode *node, int dominate)
+rsvg_drawing_ctx_draw_node_from_stack (RsvgDrawingCtx *ctx,
+                                       RsvgNode *node,
+                                       int dominate,
+                                       gboolean clipping)
 {
     RsvgState *state;
     GSList *stacksave;
@@ -498,7 +501,7 @@ rsvg_drawing_ctx_draw_node_from_stack (RsvgDrawingCtx *ctx, RsvgNode *node, int
     if (state->visible) {
         rsvg_state_push (ctx);
 
-        rsvg_node_draw (node, ctx, dominate);
+        rsvg_node_draw (node, ctx, dominate, clipping);
 
         rsvg_state_pop (ctx);
     }
@@ -530,21 +533,6 @@ rsvg_drawing_ctx_get_pango_context (RsvgDrawingCtx *draw_ctx)
     return draw_ctx->render->get_pango_context (draw_ctx);
 }
 
-void
-rsvg_drawing_ctx_render_pango_layout (RsvgDrawingCtx *draw_ctx,
-                                      PangoLayout *layout,
-                                      double x,
-                                      double y)
-{
-    draw_ctx->render->render_pango_layout (draw_ctx, layout, x, y);
-}
-
-void
-rsvg_drawing_ctx_render_path_builder (RsvgDrawingCtx * ctx, RsvgPathBuilder *builder)
-{
-    ctx->render->render_path_builder (ctx, builder);
-}
-
 void
 rsvg_drawing_ctx_render_surface (RsvgDrawingCtx * ctx, cairo_surface_t *surface,
                                  double x, double y, double w, double h)
diff --git a/librsvg/rsvg-cairo-clip.c b/librsvg/rsvg-cairo-clip.c
index 428ba1bd..8e642ca7 100644
--- a/librsvg/rsvg-cairo-clip.c
+++ b/librsvg/rsvg-cairo-clip.c
@@ -49,18 +49,6 @@ struct RsvgCairoClipRender {
 
 #define RSVG_CAIRO_CLIP_RENDER(render) (_RSVG_RENDER_CIC ((render), RSVG_RENDER_TYPE_CAIRO_CLIP, 
RsvgCairoClipRender))
 
-static void
-rsvg_cairo_clip_render_pango_layout (RsvgDrawingCtx *ctx, PangoLayout * layout, double x, double y)
-{
-    rsvg_draw_pango_layout (ctx, layout, x, y, TRUE);
-}
-
-static void
-rsvg_cairo_clip_render_path_builder (RsvgDrawingCtx *ctx, RsvgPathBuilder *builder)
-{
-    rsvg_draw_path_builder (ctx, builder, TRUE);
-}
-
 static void
 rsvg_cairo_clip_render_surface (RsvgDrawingCtx *ctx,
                                 cairo_surface_t *surface,
@@ -108,8 +96,6 @@ rsvg_cairo_clip_render_new (cairo_t *cr, RsvgCairoRender *parent)
     render->free = rsvg_cairo_clip_render_free;
     render->set_affine_on_cr = rsvg_cairo_set_affine_on_cr;
     render->get_pango_context = rsvg_cairo_get_pango_context;
-    render->render_pango_layout = rsvg_cairo_clip_render_pango_layout;
-    render->render_path_builder = rsvg_cairo_clip_render_path_builder;
     render->render_surface = rsvg_cairo_clip_render_surface;
     render->pop_discrete_layer = rsvg_cairo_clip_pop_discrete_layer;
     render->push_discrete_layer = rsvg_cairo_clip_push_discrete_layer;
@@ -173,7 +159,7 @@ rsvg_cairo_clip (RsvgDrawingCtx * ctx, RsvgNode *node_clip_path, RsvgBbox * bbox
     }
 
     rsvg_state_push (ctx);
-    rsvg_node_draw_children (node_clip_path, ctx, 0);
+    rsvg_node_draw_children (node_clip_path, ctx, 0, TRUE);
     rsvg_state_pop (ctx);
 
     if (clip_units == objectBoundingBox) {
diff --git a/librsvg/rsvg-cairo-draw.c b/librsvg/rsvg-cairo-draw.c
index 35036ce8..5a3e0d73 100644
--- a/librsvg/rsvg-cairo-draw.c
+++ b/librsvg/rsvg-cairo-draw.c
@@ -164,18 +164,6 @@ rsvg_cairo_get_pango_context (RsvgDrawingCtx * ctx)
     return context;
 }
 
-void
-rsvg_cairo_render_pango_layout (RsvgDrawingCtx *ctx, PangoLayout *layout, double x, double y)
-{
-    rsvg_draw_pango_layout (ctx, layout, x, y, FALSE);
-}
-
-void
-rsvg_cairo_render_path_builder (RsvgDrawingCtx * ctx, RsvgPathBuilder *builder)
-{
-    rsvg_draw_path_builder (ctx, builder, FALSE);
-}
-
 void
 rsvg_cairo_render_surface (RsvgDrawingCtx *ctx,
                            cairo_surface_t *surface,
@@ -356,7 +344,7 @@ rsvg_cairo_generate_mask (cairo_t * cr, RsvgNode *mask, RsvgDrawingCtx *ctx, Rsv
     }
 
     rsvg_state_push (ctx);
-    rsvg_node_draw_children (mask, ctx, 0);
+    rsvg_node_draw_children (mask, ctx, 0, FALSE);
     rsvg_state_pop (ctx);
 
     if (content_units == objectBoundingBox) {
@@ -622,7 +610,7 @@ rsvg_cairo_get_surface_of_node (RsvgDrawingCtx *ctx,
     render = rsvg_cairo_render_new (cr, width, height);
     ctx->render = (RsvgRender *) render;
 
-    rsvg_drawing_ctx_draw_node_from_stack (ctx, drawable, 0);
+    rsvg_drawing_ctx_draw_node_from_stack (ctx, drawable, 0, FALSE);
 
     cairo_destroy (cr);
 
diff --git a/librsvg/rsvg-cairo-draw.h b/librsvg/rsvg-cairo-draw.h
index 17272f34..f78f26a4 100644
--- a/librsvg/rsvg-cairo-draw.h
+++ b/librsvg/rsvg-cairo-draw.h
@@ -37,14 +37,8 @@ void rsvg_cairo_set_affine_on_cr (RsvgDrawingCtx *ctx, cairo_t *cr, cairo_matrix
 
 G_GNUC_INTERNAL
 PangoContext    *rsvg_cairo_get_pango_context    (RsvgDrawingCtx *ctx);
-G_GNUC_INTERNAL
-void         rsvg_cairo_render_pango_layout        (RsvgDrawingCtx *ctx, PangoLayout *layout, 
-                                                 double x, double y);
 
 G_GNUC_INTERNAL
-void         rsvg_cairo_render_path_builder     (RsvgDrawingCtx *ctx, 
-                                                 RsvgPathBuilder *builder);
-G_GNUC_INTERNAL
 void         rsvg_cairo_render_surface          (RsvgDrawingCtx *ctx, cairo_surface_t *surface,
                                                  double x, double y, double w, double h);
 G_GNUC_INTERNAL
diff --git a/librsvg/rsvg-cairo-render.c b/librsvg/rsvg-cairo-render.c
index aabbdbd7..aa9892a1 100644
--- a/librsvg/rsvg-cairo-render.c
+++ b/librsvg/rsvg-cairo-render.c
@@ -75,9 +75,7 @@ rsvg_cairo_render_new (cairo_t * cr, double width, double height)
     cairo_render->super.free = rsvg_cairo_render_free;
     cairo_render->super.set_affine_on_cr = rsvg_cairo_set_affine_on_cr;
     cairo_render->super.get_pango_context = rsvg_cairo_get_pango_context;
-    cairo_render->super.render_pango_layout = rsvg_cairo_render_pango_layout;
     cairo_render->super.render_surface = rsvg_cairo_render_surface;
-    cairo_render->super.render_path_builder = rsvg_cairo_render_path_builder;
     cairo_render->super.pop_discrete_layer = rsvg_cairo_pop_discrete_layer;
     cairo_render->super.push_discrete_layer = rsvg_cairo_push_discrete_layer;
     cairo_render->super.add_clipping_rect = rsvg_cairo_add_clipping_rect;
@@ -251,7 +249,7 @@ rsvg_handle_render_cairo_sub (RsvgHandle * handle, cairo_t * cr, const char *id)
 
     cairo_save (cr);
 
-    rsvg_drawing_ctx_draw_node_from_stack (draw, handle->priv->treebase, 0);
+    rsvg_drawing_ctx_draw_node_from_stack (draw, handle->priv->treebase, 0, FALSE);
 
     cairo_restore (cr);
 
diff --git a/librsvg/rsvg-cairo-render.h b/librsvg/rsvg-cairo-render.h
index d4e11bc0..a92988a5 100644
--- a/librsvg/rsvg-cairo-render.h
+++ b/librsvg/rsvg-cairo-render.h
@@ -67,14 +67,6 @@ RsvgCairoRender *rsvg_cairo_render_new (cairo_t *cr, double width, double height
 G_GNUC_INTERNAL
 RsvgDrawingCtx *rsvg_cairo_new_drawing_ctx (cairo_t * cr, RsvgHandle * handle);
 
-/* Defined in rsvg_internals/src/draw.rs */
-G_GNUC_INTERNAL
-void rsvg_draw_path_builder (RsvgDrawingCtx * ctx, RsvgPathBuilder *builder, gboolean clipping);
-
-/* Defined in rsvg_internals/src/draw.rs */
-G_GNUC_INTERNAL
-void rsvg_draw_pango_layout (RsvgDrawingCtx *ctx, PangoLayout *layout, double x, double y, gboolean 
clipping);
-
 G_END_DECLS
 
 #endif
diff --git a/librsvg/rsvg-filter.c b/librsvg/rsvg-filter.c
index 00e9bafa..4a647a78 100644
--- a/librsvg/rsvg-filter.c
+++ b/librsvg/rsvg-filter.c
@@ -863,7 +863,7 @@ rsvg_filter_set_atts (RsvgNode *node, gpointer impl, RsvgHandle *handle, RsvgPro
 }
 
 static void
-rsvg_filter_draw (RsvgNode *node, gpointer impl, RsvgDrawingCtx *ctx, int dominate)
+rsvg_filter_draw (RsvgNode *node, gpointer impl, RsvgDrawingCtx *ctx, int dominate, gboolean clipping)
 {
     /* nothing; filters are drawn in rsvg-cairo-draw.c */
 }
diff --git a/librsvg/rsvg-handle.c b/librsvg/rsvg-handle.c
index caadb421..1cc6d7f8 100644
--- a/librsvg/rsvg-handle.c
+++ b/librsvg/rsvg-handle.c
@@ -847,7 +847,7 @@ rsvg_handle_get_dimensions_sub (RsvgHandle * handle, RsvgDimensionData * dimensi
         g_assert (sself != NULL);
         rsvg_drawing_ctx_add_node_and_ancestors_to_stack (draw, sself);
 
-        rsvg_drawing_ctx_draw_node_from_stack (draw, handle->priv->treebase, 0);
+        rsvg_drawing_ctx_draw_node_from_stack (draw, handle->priv->treebase, 0, FALSE);
         bbox = RSVG_CAIRO_RENDER (draw->render)->bbox;
 
         rsvg_drawing_ctx_free (draw);
@@ -934,7 +934,7 @@ rsvg_handle_get_position_sub (RsvgHandle * handle, RsvgPositionData * position_d
     g_assert (node != NULL);
     rsvg_drawing_ctx_add_node_and_ancestors_to_stack (draw, node);
 
-    rsvg_drawing_ctx_draw_node_from_stack (draw, handle->priv->treebase, 0);
+    rsvg_drawing_ctx_draw_node_from_stack (draw, handle->priv->treebase, 0, FALSE);
     bbox = RSVG_CAIRO_RENDER (draw->render)->bbox;
 
     rsvg_drawing_ctx_free (draw);
diff --git a/librsvg/rsvg-private.h b/librsvg/rsvg-private.h
index 7037efc7..1c3e6363 100644
--- a/librsvg/rsvg-private.h
+++ b/librsvg/rsvg-private.h
@@ -208,9 +208,6 @@ struct RsvgRender {
 
     void             (*set_affine_on_cr)        (RsvgDrawingCtx *ctx, cairo_t *cr, cairo_matrix_t *affine);
     PangoContext    *(*get_pango_context)       (RsvgDrawingCtx *ctx);
-    void             (*render_pango_layout)    (RsvgDrawingCtx *ctx, PangoLayout *layout,
-                                                 double x, double y);
-    void             (*render_path_builder)     (RsvgDrawingCtx *ctx, RsvgPathBuilder *builder);
     void             (*render_surface)          (RsvgDrawingCtx *ctx, cairo_surface_t *surface,
                                                  double x, double y, double w, double h);
     void             (*pop_discrete_layer)      (RsvgDrawingCtx *ctx);
@@ -320,7 +317,7 @@ typedef enum {
 } RsvgNodeType;
 
 typedef void (* CNodeSetAtts) (RsvgNode *node, gpointer impl, RsvgHandle *handle, RsvgPropertyBag pbag);
-typedef void (* CNodeDraw) (RsvgNode *node, gpointer impl, RsvgDrawingCtx *ctx, int dominate);
+typedef void (* CNodeDraw) (RsvgNode *node, gpointer impl, RsvgDrawingCtx *ctx, int dominate, gboolean 
clipping);
 typedef void (* CNodeFree) (gpointer impl);
 
 /* Implemented in rust/src/node.rs */
@@ -378,7 +375,7 @@ void rsvg_node_set_atts (RsvgNode *node, RsvgHandle *handle, RsvgPropertyBag att
 
 /* Implemented in rust/src/node.rs */
 G_GNUC_INTERNAL
-void rsvg_node_draw (RsvgNode *node, RsvgDrawingCtx *draw, int dominate);
+void rsvg_node_draw (RsvgNode *node, RsvgDrawingCtx *draw, int dominate, gboolean clipping);
 
 /* Implemented in rust/src/node.rs */
 G_GNUC_INTERNAL
@@ -408,7 +405,7 @@ void rsvg_node_children_iter_end (RsvgNodeChildrenIter *iter);
 
 /* Implemented in rust/src/node.rs */
 G_GNUC_INTERNAL
-void rsvg_node_draw_children (RsvgNode *node, RsvgDrawingCtx *ctx, int dominate);
+void rsvg_node_draw_children (RsvgNode *node, RsvgDrawingCtx *ctx, int dominate, gboolean clipping);
 
 typedef void (*RsvgPropertyBagEnumFunc) (const char *key, const char *value, gpointer user_data);
 
@@ -470,10 +467,10 @@ void rsvg_drawing_ctx_release_node              (RsvgDrawingCtx * ctx, RsvgNode
 G_GNUC_INTERNAL
 void rsvg_drawing_ctx_add_node_and_ancestors_to_stack (RsvgDrawingCtx *draw_ctx, RsvgNode *node);
 G_GNUC_INTERNAL
-void rsvg_drawing_ctx_draw_node_from_stack            (RsvgDrawingCtx *ctx, RsvgNode *node, int dominate);
-
-G_GNUC_INTERNAL
-void rsvg_drawing_ctx_render_path_builder (RsvgDrawingCtx * ctx, RsvgPathBuilder *builder);
+void rsvg_drawing_ctx_draw_node_from_stack (RsvgDrawingCtx *ctx,
+                                            RsvgNode *node,
+                                            int dominate,
+                                            gboolean clipping);
 
 G_GNUC_INTERNAL
 void rsvg_drawing_ctx_render_surface (RsvgDrawingCtx * ctx, cairo_surface_t *surface,
@@ -544,11 +541,6 @@ void rsvg_drawing_ctx_set_affine_on_cr (RsvgDrawingCtx *draw_ctx, cairo_t *cr, c
 G_GNUC_INTERNAL
 PangoContext *rsvg_drawing_ctx_get_pango_context (RsvgDrawingCtx *draw_ctx);
 
-G_GNUC_INTERNAL
-void rsvg_drawing_ctx_render_pango_layout (RsvgDrawingCtx *draw_ctx,
-                                           PangoLayout *layout,
-                                           double x,
-                                           double y);
 
 G_GNUC_INTERNAL
 double _rsvg_css_accumulate_baseline_shift (RsvgState * state, RsvgDrawingCtx * ctx);
diff --git a/rsvg_internals/src/clip_path.rs b/rsvg_internals/src/clip_path.rs
index 07d7d581..99856ced 100644
--- a/rsvg_internals/src/clip_path.rs
+++ b/rsvg_internals/src/clip_path.rs
@@ -38,7 +38,7 @@ impl NodeTrait for NodeClipPath {
         Ok(())
     }
 
-    fn draw(&self, _: &RsvgNode, _: *const RsvgDrawingCtx, _: i32) {
+    fn draw(&self, _: &RsvgNode, _: *mut RsvgDrawingCtx, _: i32, _: bool) {
         // nothing; clip paths are handled specially
     }
 
diff --git a/rsvg_internals/src/cnode.rs b/rsvg_internals/src/cnode.rs
index 79fc94d9..6b9626d0 100644
--- a/rsvg_internals/src/cnode.rs
+++ b/rsvg_internals/src/cnode.rs
@@ -1,3 +1,6 @@
+use glib::translate::*;
+use glib_sys;
+
 use drawing_ctx::RsvgDrawingCtx;
 use handle::*;
 use node::*;
@@ -15,8 +18,9 @@ type CNodeSetAtts = unsafe extern "C" fn(
 type CNodeDraw = unsafe extern "C" fn(
     node: *const RsvgNode,
     node_impl: *const RsvgCNodeImpl,
-    draw_ctx: *const RsvgDrawingCtx,
+    draw_ctx: *mut RsvgDrawingCtx,
     dominate: i32,
+    clipping: glib_sys::gboolean,
 );
 type CNodeFree = unsafe extern "C" fn(node_impl: *const RsvgCNodeImpl);
 
@@ -47,13 +51,14 @@ impl NodeTrait for CNode {
         Ok(())
     }
 
-    fn draw(&self, node: &RsvgNode, draw_ctx: *const RsvgDrawingCtx, dominate: i32) {
+    fn draw(&self, node: &RsvgNode, draw_ctx: *mut RsvgDrawingCtx, dominate: i32, clipping: bool) {
         unsafe {
             (self.draw_fn)(
                 node as *const RsvgNode,
                 self.c_node_impl,
                 draw_ctx,
                 dominate,
+                clipping.to_glib(),
             );
         }
     }
diff --git a/rsvg_internals/src/draw.rs b/rsvg_internals/src/draw.rs
index 70d63822..912d42d6 100644
--- a/rsvg_internals/src/draw.rs
+++ b/rsvg_internals/src/draw.rs
@@ -1,6 +1,5 @@
 use cairo;
 use glib::translate::*;
-use glib_sys;
 use pango::{self, ContextExt, LayoutExt};
 use pango_sys;
 use pangocairo;
@@ -119,7 +118,11 @@ impl From<FillRule> for cairo::FillRule {
     }
 }
 
-fn setup_cr_for_stroke(cr: &cairo::Context, draw_ctx: *mut RsvgDrawingCtx, state: *mut RsvgState) {
+fn setup_cr_for_stroke(
+    cr: &cairo::Context,
+    draw_ctx: *const RsvgDrawingCtx,
+    state: *mut RsvgState,
+) {
     cr.set_line_width(state::get_stroke_width(state).normalize(draw_ctx));
     cr.set_miter_limit(state::get_miter_limit(state));
     cr.set_line_cap(cairo::LineCap::from(
@@ -323,35 +326,3 @@ fn compute_text_bbox(
 
     bbox
 }
-
-#[no_mangle]
-pub extern "C" fn rsvg_draw_pango_layout(
-    draw_ctx: *mut RsvgDrawingCtx,
-    layout: *mut pango_sys::PangoLayout,
-    x: f64,
-    y: f64,
-    clipping: glib_sys::gboolean,
-) {
-    assert!(!draw_ctx.is_null());
-    assert!(!layout.is_null());
-
-    let layout = unsafe { from_glib_none(layout) };
-    let clipping: bool = from_glib(clipping);
-
-    draw_pango_layout(draw_ctx, &layout, x, y, clipping);
-}
-
-#[no_mangle]
-pub extern "C" fn rsvg_draw_path_builder(
-    draw_ctx: *mut RsvgDrawingCtx,
-    raw_builder: *const RsvgPathBuilder,
-    clipping: glib_sys::gboolean,
-) {
-    assert!(!draw_ctx.is_null());
-    assert!(!raw_builder.is_null());
-
-    let builder = unsafe { &*raw_builder };
-    let clipping: bool = from_glib(clipping);
-
-    draw_path_builder(draw_ctx, builder, clipping);
-}
diff --git a/rsvg_internals/src/drawing_ctx.rs b/rsvg_internals/src/drawing_ctx.rs
index 74eb0046..70991e88 100644
--- a/rsvg_internals/src/drawing_ctx.rs
+++ b/rsvg_internals/src/drawing_ctx.rs
@@ -1,6 +1,7 @@
 use cairo;
 use cairo_sys;
 use glib::translate::*;
+use glib_sys;
 use libc;
 use pango;
 use pango_sys;
@@ -8,7 +9,6 @@ use pango_sys;
 use bbox::RsvgBbox;
 use node::NodeType;
 use node::RsvgNode;
-use path_builder::RsvgPathBuilder;
 use state::RsvgState;
 
 pub enum RsvgDrawingCtx {}
@@ -77,6 +77,7 @@ extern "C" {
         draw_ctx: *const RsvgDrawingCtx,
         node: *const RsvgNode,
         dominate: i32,
+        clipping: glib_sys::gboolean,
     );
 
     fn rsvg_current_state(draw_ctx: *const RsvgDrawingCtx) -> *mut RsvgState;
@@ -93,16 +94,6 @@ extern "C" {
     fn rsvg_push_discrete_layer(draw_ctx: *const RsvgDrawingCtx);
     fn rsvg_pop_discrete_layer(draw_ctx: *const RsvgDrawingCtx);
 
-    fn rsvg_drawing_ctx_render_pango_layout(
-        draw_ctx: *const RsvgDrawingCtx,
-        layout: *const pango_sys::PangoLayout,
-        x: f64,
-        y: f64,
-    );
-    fn rsvg_drawing_ctx_render_path_builder(
-        draw_ctx: *const RsvgDrawingCtx,
-        builder: *const RsvgPathBuilder,
-    );
     fn rsvg_drawing_ctx_render_surface(
         draw_ctx: *const RsvgDrawingCtx,
         surface: *const cairo_sys::cairo_surface_t,
@@ -198,23 +189,6 @@ pub fn pop_discrete_layer(draw_ctx: *const RsvgDrawingCtx) {
     }
 }
 
-pub fn render_pango_layout(
-    draw_ctx: *const RsvgDrawingCtx,
-    layout: &pango::Layout,
-    x: f64,
-    y: f64,
-) {
-    unsafe {
-        rsvg_drawing_ctx_render_pango_layout(draw_ctx, layout.to_glib_none().0, x, y);
-    }
-}
-
-pub fn render_path_builder(draw_ctx: *const RsvgDrawingCtx, builder: &RsvgPathBuilder) {
-    unsafe {
-        rsvg_drawing_ctx_render_path_builder(draw_ctx, builder);
-    }
-}
-
 pub fn render_surface(
     draw_ctx: *const RsvgDrawingCtx,
     surface: &cairo::ImageSurface,
@@ -284,9 +258,14 @@ pub fn insert_bbox(draw_ctx: *const RsvgDrawingCtx, bbox: &RsvgBbox) {
     }
 }
 
-pub fn draw_node_from_stack(draw_ctx: *const RsvgDrawingCtx, node: *const RsvgNode, dominate: i32) {
+pub fn draw_node_from_stack(
+    draw_ctx: *const RsvgDrawingCtx,
+    node: *const RsvgNode,
+    dominate: i32,
+    clipping: bool,
+) {
     unsafe {
-        rsvg_drawing_ctx_draw_node_from_stack(draw_ctx, node, dominate);
+        rsvg_drawing_ctx_draw_node_from_stack(draw_ctx, node, dominate, clipping.to_glib());
     }
 }
 
diff --git a/rsvg_internals/src/gradient.rs b/rsvg_internals/src/gradient.rs
index fb7b4981..73a10123 100644
--- a/rsvg_internals/src/gradient.rs
+++ b/rsvg_internals/src/gradient.rs
@@ -643,7 +643,7 @@ impl NodeTrait for NodeGradient {
         Ok(())
     }
 
-    fn draw(&self, _: &RsvgNode, _: *const RsvgDrawingCtx, _: i32) {
+    fn draw(&self, _: &RsvgNode, _: *mut RsvgDrawingCtx, _: i32, _: bool) {
         // nothing; paint servers are handled specially
     }
 
diff --git a/rsvg_internals/src/image.rs b/rsvg_internals/src/image.rs
index b869757a..fb1cb144 100644
--- a/rsvg_internals/src/image.rs
+++ b/rsvg_internals/src/image.rs
@@ -95,7 +95,7 @@ impl NodeTrait for NodeImage {
         Ok(())
     }
 
-    fn draw(&self, node: &RsvgNode, draw_ctx: *const RsvgDrawingCtx, dominate: i32) {
+    fn draw(&self, node: &RsvgNode, draw_ctx: *mut RsvgDrawingCtx, dominate: i32, _: bool) {
         if let Some(ref surface) = *self.surface.borrow() {
             let x = self.x.get().normalize(draw_ctx);
             let y = self.y.get().normalize(draw_ctx);
diff --git a/rsvg_internals/src/lib.rs b/rsvg_internals/src/lib.rs
index b0fd5d53..b07fae78 100644
--- a/rsvg_internals/src/lib.rs
+++ b/rsvg_internals/src/lib.rs
@@ -37,8 +37,6 @@ pub use cond::{
     rsvg_cond_check_system_language,
 };
 
-pub use draw::{rsvg_draw_pango_layout, rsvg_draw_path_builder};
-
 pub use gradient::{rsvg_node_linear_gradient_new, rsvg_node_radial_gradient_new};
 
 pub use length::{
diff --git a/rsvg_internals/src/link.rs b/rsvg_internals/src/link.rs
index 63f9de46..caf27f02 100644
--- a/rsvg_internals/src/link.rs
+++ b/rsvg_internals/src/link.rs
@@ -38,7 +38,7 @@ impl NodeTrait for NodeLink {
         Ok(())
     }
 
-    fn draw(&self, node: &RsvgNode, draw_ctx: *const RsvgDrawingCtx, dominate: i32) {
+    fn draw(&self, node: &RsvgNode, draw_ctx: *mut RsvgDrawingCtx, dominate: i32, clipping: bool) {
         let link = self.link.borrow();
 
         if link.is_some() && link.as_ref().unwrap() != "" {
@@ -49,10 +49,10 @@ impl NodeTrait for NodeLink {
             drawing_ctx::get_cairo_context(draw_ctx).with_tag(
                 CAIRO_TAG_LINK,
                 attributes.as_ref().map(|i| i.as_str()),
-                || node.draw_children(draw_ctx, dominate),
+                || node.draw_children(draw_ctx, dominate, clipping),
             )
         } else {
-            node.draw_children(draw_ctx, dominate)
+            node.draw_children(draw_ctx, dominate, clipping)
         }
     }
 
diff --git a/rsvg_internals/src/marker.rs b/rsvg_internals/src/marker.rs
index 05d39f34..66704178 100644
--- a/rsvg_internals/src/marker.rs
+++ b/rsvg_internals/src/marker.rs
@@ -112,11 +112,12 @@ impl NodeMarker {
     fn render(
         &self,
         node: &RsvgNode,
-        draw_ctx: *const RsvgDrawingCtx,
+        draw_ctx: *mut RsvgDrawingCtx,
         xpos: f64,
         ypos: f64,
         computed_angle: f64,
         line_width: f64,
+        clipping: bool,
     ) {
         let marker_width = self.width.get().normalize(draw_ctx);
         let marker_height = self.height.get().normalize(draw_ctx);
@@ -188,7 +189,7 @@ impl NodeMarker {
             }
         }
 
-        node.draw_children(draw_ctx, -1); // dominate=-1 so it won't reinherit state / push a layer
+        node.draw_children(draw_ctx, -1, clipping); // dominate=-1 so it won't reinherit state / push a layer
 
         drawing_ctx::state_pop(draw_ctx);
         drawing_ctx::pop_discrete_layer(draw_ctx);
@@ -240,7 +241,7 @@ impl NodeTrait for NodeMarker {
         Ok(())
     }
 
-    fn draw(&self, _: &RsvgNode, _: *const RsvgDrawingCtx, _: i32) {
+    fn draw(&self, _: &RsvgNode, _: *mut RsvgDrawingCtx, _: i32, _: bool) {
         // nothing; markers are drawn by their referencing shapes
     }
 
@@ -590,12 +591,13 @@ enum MarkerType {
 }
 
 fn emit_marker_by_name(
-    draw_ctx: *const RsvgDrawingCtx,
+    draw_ctx: *mut RsvgDrawingCtx,
     marker_name: *const libc::c_char,
     xpos: f64,
     ypos: f64,
     computed_angle: f64,
     line_width: f64,
+    clipping: bool,
 ) {
     if marker_name.is_null() {
         return;
@@ -608,7 +610,15 @@ fn emit_marker_by_name(
         let node = acquired.get();
 
         node.with_impl(|marker: &NodeMarker| {
-            marker.render(&node, draw_ctx, xpos, ypos, computed_angle, line_width)
+            marker.render(
+                &node,
+                draw_ctx,
+                xpos,
+                ypos,
+                computed_angle,
+                line_width,
+                clipping,
+            )
         });
     }
 }
@@ -663,7 +673,11 @@ fn drawing_ctx_has_markers(draw_ctx: *const RsvgDrawingCtx) -> bool {
         || !get_marker_name_from_drawing_ctx(draw_ctx, MarkerType::End).is_null())
 }
 
-pub fn render_markers_for_path_builder(builder: &RsvgPathBuilder, draw_ctx: *const RsvgDrawingCtx) {
+pub fn render_markers_for_path_builder(
+    builder: &RsvgPathBuilder,
+    draw_ctx: *mut RsvgDrawingCtx,
+    clipping: bool,
+) {
     let state = drawing_ctx::get_current_state(draw_ctx);
 
     let line_width = state::get_stroke_width(state).normalize(draw_ctx);
@@ -686,6 +700,7 @@ pub fn render_markers_for_path_builder(builder: &RsvgPathBuilder, draw_ctx: *con
                 y,
                 computed_angle,
                 line_width,
+                clipping,
             );
         },
     );
diff --git a/rsvg_internals/src/mask.rs b/rsvg_internals/src/mask.rs
index c01ec874..fa186a3f 100644
--- a/rsvg_internals/src/mask.rs
+++ b/rsvg_internals/src/mask.rs
@@ -79,7 +79,7 @@ impl NodeTrait for NodeMask {
         Ok(())
     }
 
-    fn draw(&self, _: &RsvgNode, _: *const RsvgDrawingCtx, _: i32) {
+    fn draw(&self, _: &RsvgNode, _: *mut RsvgDrawingCtx, _: i32, _: bool) {
         // nothing; masks are handled specially
     }
 
diff --git a/rsvg_internals/src/node.rs b/rsvg_internals/src/node.rs
index 0baa28c6..a1aa36a3 100644
--- a/rsvg_internals/src/node.rs
+++ b/rsvg_internals/src/node.rs
@@ -31,7 +31,7 @@ pub trait NodeTrait: Downcast {
         handle: *const RsvgHandle,
         pbag: &PropertyBag,
     ) -> NodeResult;
-    fn draw(&self, node: &RsvgNode, draw_ctx: *const RsvgDrawingCtx, dominate: i32);
+    fn draw(&self, node: &RsvgNode, draw_ctx: *mut RsvgDrawingCtx, dominate: i32, clipping: bool);
     fn get_c_impl(&self) -> *const RsvgCNodeImpl;
 }
 
@@ -187,9 +187,15 @@ impl Node {
         *self.result.borrow_mut() = self.node_impl.set_atts(node, handle, pbag);
     }
 
-    pub fn draw(&self, node: &RsvgNode, draw_ctx: *const RsvgDrawingCtx, dominate: i32) {
+    pub fn draw(
+        &self,
+        node: &RsvgNode,
+        draw_ctx: *mut RsvgDrawingCtx,
+        dominate: i32,
+        clipping: bool,
+    ) {
         if self.result.borrow().is_ok() {
-            self.node_impl.draw(node, draw_ctx, dominate);
+            self.node_impl.draw(node, draw_ctx, dominate, clipping);
         }
     }
 
@@ -213,7 +219,7 @@ impl Node {
         }
     }
 
-    pub fn draw_children(&self, draw_ctx: *const RsvgDrawingCtx, dominate: i32) {
+    pub fn draw_children(&self, draw_ctx: *const RsvgDrawingCtx, dominate: i32, clipping: bool) {
         if dominate != -1 {
             drawing_ctx::state_reinherit_top(draw_ctx, self.state, dominate);
 
@@ -223,7 +229,7 @@ impl Node {
         for child in self.children() {
             let boxed_child = box_node(child.clone());
 
-            drawing_ctx::draw_node_from_stack(draw_ctx, boxed_child, 0);
+            drawing_ctx::draw_node_from_stack(draw_ctx, boxed_child, 0, clipping);
 
             rsvg_node_unref(boxed_child);
         }
@@ -429,13 +435,14 @@ pub extern "C" fn rsvg_node_set_atts(
 #[no_mangle]
 pub extern "C" fn rsvg_node_draw(
     raw_node: *const RsvgNode,
-    draw_ctx: *const RsvgDrawingCtx,
+    draw_ctx: *mut RsvgDrawingCtx,
     dominate: i32,
+    clipping: glib_sys::gboolean,
 ) {
     assert!(!raw_node.is_null());
     let node: &RsvgNode = unsafe { &*raw_node };
 
-    node.draw(node, draw_ctx, dominate);
+    node.draw(node, draw_ctx, dominate, from_glib(clipping));
 }
 
 #[no_mangle]
@@ -524,11 +531,12 @@ pub extern "C" fn rsvg_node_draw_children(
     raw_node: *const RsvgNode,
     draw_ctx: *const RsvgDrawingCtx,
     dominate: i32,
+    clipping: glib_sys::gboolean,
 ) {
     assert!(!raw_node.is_null());
     let node: &RsvgNode = unsafe { &*raw_node };
 
-    node.draw_children(draw_ctx, dominate);
+    node.draw_children(draw_ctx, dominate, from_glib(clipping));
 }
 
 #[cfg(test)]
@@ -546,7 +554,7 @@ mod tests {
             Ok(())
         }
 
-        fn draw(&self, _: &RsvgNode, _: *const RsvgDrawingCtx, _: i32) {}
+        fn draw(&self, _: &RsvgNode, _: *mut RsvgDrawingCtx, _: i32, _: bool) {}
 
         fn get_c_impl(&self) -> *const RsvgCNodeImpl {
             unreachable!();
diff --git a/rsvg_internals/src/pattern.rs b/rsvg_internals/src/pattern.rs
index 3951af0e..acbc1581 100644
--- a/rsvg_internals/src/pattern.rs
+++ b/rsvg_internals/src/pattern.rs
@@ -219,7 +219,7 @@ impl NodeTrait for NodePattern {
         Ok(())
     }
 
-    fn draw(&self, _: &RsvgNode, _: *const RsvgDrawingCtx, _: i32) {
+    fn draw(&self, _: &RsvgNode, _: *mut RsvgDrawingCtx, _: i32, _: bool) {
         // nothing; paint servers are handled specially
     }
 
@@ -407,7 +407,7 @@ fn set_pattern_on_draw_context(
 
     // Draw everything
     let pattern_node = pattern.node.clone().unwrap().upgrade().unwrap();
-    pattern_node.draw_children(draw_ctx, 2);
+    pattern_node.draw_children(draw_ctx, 2, false);
 
     // Return to the original coordinate system and rendering context
 
diff --git a/rsvg_internals/src/shapes.rs b/rsvg_internals/src/shapes.rs
index 07d492ff..fbca5c66 100644
--- a/rsvg_internals/src/shapes.rs
+++ b/rsvg_internals/src/shapes.rs
@@ -4,6 +4,7 @@ use std::cell::Cell;
 use std::cell::RefCell;
 
 use attributes::Attribute;
+use draw::draw_path_builder;
 use drawing_ctx;
 use drawing_ctx::*;
 use error::*;
@@ -19,16 +20,17 @@ use state::RsvgState;
 
 fn render_path_builder(
     builder: &RsvgPathBuilder,
-    draw_ctx: *const RsvgDrawingCtx,
+    draw_ctx: *mut RsvgDrawingCtx,
     state: *mut RsvgState,
     dominate: i32,
     render_markers: bool,
+    clipping: bool,
 ) {
     drawing_ctx::state_reinherit_top(draw_ctx, state, dominate);
-    drawing_ctx::render_path_builder(draw_ctx, builder);
+    draw_path_builder(draw_ctx, builder, clipping);
 
     if render_markers {
-        marker::render_markers_for_path_builder(builder, draw_ctx);
+        marker::render_markers_for_path_builder(builder, draw_ctx, clipping);
     }
 }
 
@@ -38,8 +40,9 @@ fn render_ellipse(
     rx: f64,
     ry: f64,
     node: &RsvgNode,
-    draw_ctx: *const RsvgDrawingCtx,
+    draw_ctx: *mut RsvgDrawingCtx,
     dominate: i32,
+    clipping: bool,
 ) {
     // Per the spec, rx and ry must be nonnegative
     if rx <= 0.0 || ry <= 0.0 {
@@ -92,7 +95,14 @@ fn render_ellipse(
 
     builder.close_path();
 
-    render_path_builder(&builder, draw_ctx, node.get_state(), dominate, false);
+    render_path_builder(
+        &builder,
+        draw_ctx,
+        node.get_state(),
+        dominate,
+        false,
+        clipping,
+    );
 }
 
 // ************ NodePath ************
@@ -126,9 +136,16 @@ impl NodeTrait for NodePath {
         Ok(())
     }
 
-    fn draw(&self, node: &RsvgNode, draw_ctx: *const RsvgDrawingCtx, dominate: i32) {
+    fn draw(&self, node: &RsvgNode, draw_ctx: *mut RsvgDrawingCtx, dominate: i32, clipping: bool) {
         if let Some(ref builder) = *self.builder.borrow() {
-            render_path_builder(builder, draw_ctx, node.get_state(), dominate, true);
+            render_path_builder(
+                builder,
+                draw_ctx,
+                node.get_state(),
+                dominate,
+                true,
+                clipping,
+            );
         }
     }
 
@@ -181,7 +198,7 @@ impl NodeTrait for NodePoly {
         Ok(())
     }
 
-    fn draw(&self, node: &RsvgNode, draw_ctx: *const RsvgDrawingCtx, dominate: i32) {
+    fn draw(&self, node: &RsvgNode, draw_ctx: *mut RsvgDrawingCtx, dominate: i32, clipping: bool) {
         if let Some(ref points) = *self.points.borrow() {
             let mut builder = RsvgPathBuilder::new();
 
@@ -197,7 +214,14 @@ impl NodeTrait for NodePoly {
                 builder.close_path();
             }
 
-            render_path_builder(&builder, draw_ctx, node.get_state(), dominate, true);
+            render_path_builder(
+                &builder,
+                draw_ctx,
+                node.get_state(),
+                dominate,
+                true,
+                clipping,
+            );
         }
     }
 
@@ -242,7 +266,7 @@ impl NodeTrait for NodeLine {
         Ok(())
     }
 
-    fn draw(&self, node: &RsvgNode, draw_ctx: *const RsvgDrawingCtx, dominate: i32) {
+    fn draw(&self, node: &RsvgNode, draw_ctx: *mut RsvgDrawingCtx, dominate: i32, clipping: bool) {
         let mut builder = RsvgPathBuilder::new();
 
         let x1 = self.x1.get().normalize(draw_ctx);
@@ -253,7 +277,14 @@ impl NodeTrait for NodeLine {
         builder.move_to(x1, y1);
         builder.line_to(x2, y2);
 
-        render_path_builder(&builder, draw_ctx, node.get_state(), dominate, true);
+        render_path_builder(
+            &builder,
+            draw_ctx,
+            node.get_state(),
+            dominate,
+            true,
+            clipping,
+        );
     }
 
     fn get_c_impl(&self) -> *const RsvgCNodeImpl {
@@ -327,7 +358,7 @@ impl NodeTrait for NodeRect {
         Ok(())
     }
 
-    fn draw(&self, node: &RsvgNode, draw_ctx: *const RsvgDrawingCtx, dominate: i32) {
+    fn draw(&self, node: &RsvgNode, draw_ctx: *mut RsvgDrawingCtx, dominate: i32, clipping: bool) {
         let x = self.x.get().normalize(draw_ctx);
         let y = self.y.get().normalize(draw_ctx);
 
@@ -462,7 +493,14 @@ impl NodeTrait for NodeRect {
             builder.close_path ();
         }
 
-        render_path_builder(&builder, draw_ctx, node.get_state(), dominate, false);
+        render_path_builder(
+            &builder,
+            draw_ctx,
+            node.get_state(),
+            dominate,
+            false,
+            clipping,
+        );
     }
 
     fn get_c_impl(&self) -> *const RsvgCNodeImpl {
@@ -508,12 +546,12 @@ impl NodeTrait for NodeCircle {
         Ok(())
     }
 
-    fn draw(&self, node: &RsvgNode, draw_ctx: *const RsvgDrawingCtx, dominate: i32) {
+    fn draw(&self, node: &RsvgNode, draw_ctx: *mut RsvgDrawingCtx, dominate: i32, clipping: bool) {
         let cx = self.cx.get().normalize(draw_ctx);
         let cy = self.cy.get().normalize(draw_ctx);
         let r = self.r.get().normalize(draw_ctx);
 
-        render_ellipse(cx, cy, r, r, node, draw_ctx, dominate);
+        render_ellipse(cx, cy, r, r, node, draw_ctx, dominate, clipping);
     }
 
     fn get_c_impl(&self) -> *const RsvgCNodeImpl {
@@ -568,13 +606,13 @@ impl NodeTrait for NodeEllipse {
         Ok(())
     }
 
-    fn draw(&self, node: &RsvgNode, draw_ctx: *const RsvgDrawingCtx, dominate: i32) {
+    fn draw(&self, node: &RsvgNode, draw_ctx: *mut RsvgDrawingCtx, dominate: i32, clipping: bool) {
         let cx = self.cx.get().normalize(draw_ctx);
         let cy = self.cy.get().normalize(draw_ctx);
         let rx = self.rx.get().normalize(draw_ctx);
         let ry = self.ry.get().normalize(draw_ctx);
 
-        render_ellipse(cx, cy, rx, ry, node, draw_ctx, dominate);
+        render_ellipse(cx, cy, rx, ry, node, draw_ctx, dominate, clipping);
     }
 
     fn get_c_impl(&self) -> *const RsvgCNodeImpl {
diff --git a/rsvg_internals/src/stop.rs b/rsvg_internals/src/stop.rs
index 683da379..58ce209e 100644
--- a/rsvg_internals/src/stop.rs
+++ b/rsvg_internals/src/stop.rs
@@ -168,7 +168,7 @@ impl NodeTrait for NodeStop {
         Ok(())
     }
 
-    fn draw(&self, _: &RsvgNode, _: *const RsvgDrawingCtx, _: i32) {
+    fn draw(&self, _: &RsvgNode, _: *mut RsvgDrawingCtx, _: i32, _: bool) {
         // nothing; paint servers are handled specially
     }
 
diff --git a/rsvg_internals/src/structure.rs b/rsvg_internals/src/structure.rs
index 3e497584..544db59e 100644
--- a/rsvg_internals/src/structure.rs
+++ b/rsvg_internals/src/structure.rs
@@ -34,8 +34,8 @@ impl NodeTrait for NodeGroup {
         Ok(())
     }
 
-    fn draw(&self, node: &RsvgNode, draw_ctx: *const RsvgDrawingCtx, dominate: i32) {
-        node.draw_children(draw_ctx, dominate);
+    fn draw(&self, node: &RsvgNode, draw_ctx: *mut RsvgDrawingCtx, dominate: i32, clipping: bool) {
+        node.draw_children(draw_ctx, dominate, clipping);
     }
 
     fn get_c_impl(&self) -> *const RsvgCNodeImpl {
@@ -57,7 +57,7 @@ impl NodeTrait for NodeDefs {
         Ok(())
     }
 
-    fn draw(&self, _: &RsvgNode, _: *const RsvgDrawingCtx, _: i32) {
+    fn draw(&self, _: &RsvgNode, _: *mut RsvgDrawingCtx, _: i32, _: bool) {
         // nothing
     }
 
@@ -80,7 +80,7 @@ impl NodeTrait for NodeSwitch {
         Ok(())
     }
 
-    fn draw(&self, node: &RsvgNode, draw_ctx: *const RsvgDrawingCtx, dominate: i32) {
+    fn draw(&self, node: &RsvgNode, draw_ctx: *mut RsvgDrawingCtx, dominate: i32, clipping: bool) {
         drawing_ctx::state_reinherit_top(draw_ctx, node.get_state(), dominate);
 
         drawing_ctx::push_discrete_layer(draw_ctx);
@@ -90,7 +90,7 @@ impl NodeTrait for NodeSwitch {
         {
             let boxed_child = box_node(child.clone());
 
-            drawing_ctx::draw_node_from_stack(draw_ctx, boxed_child, 0);
+            drawing_ctx::draw_node_from_stack(draw_ctx, boxed_child, 0, clipping);
 
             rsvg_node_unref(boxed_child);
         }
@@ -180,7 +180,7 @@ impl NodeTrait for NodeSvg {
         Ok(())
     }
 
-    fn draw(&self, node: &RsvgNode, draw_ctx: *const RsvgDrawingCtx, dominate: i32) {
+    fn draw(&self, node: &RsvgNode, draw_ctx: *mut RsvgDrawingCtx, dominate: i32, clipping: bool) {
         let nx = self.x.get().normalize(draw_ctx);
         let ny = self.y.get().normalize(draw_ctx);
         let nw = self.w.get().normalize(draw_ctx);
@@ -204,7 +204,7 @@ impl NodeTrait for NodeSvg {
             draw_ctx,
             || {
                 drawing_ctx::state_push(draw_ctx);
-                node.draw_children(draw_ctx, -1); // dominate==-1 so it won't reinherit or push a layer
+                node.draw_children(draw_ctx, -1, clipping); // dominate==-1 so it won't reinherit or push a 
layer
                 drawing_ctx::state_pop(draw_ctx);
             },
         );
@@ -265,7 +265,7 @@ impl NodeTrait for NodeUse {
         Ok(())
     }
 
-    fn draw(&self, node: &RsvgNode, draw_ctx: *const RsvgDrawingCtx, dominate: i32) {
+    fn draw(&self, node: &RsvgNode, draw_ctx: *mut RsvgDrawingCtx, dominate: i32, clipping: bool) {
         let link = self.link.borrow();
 
         if link.is_none() {
@@ -320,7 +320,7 @@ impl NodeTrait for NodeUse {
             drawing_ctx::push_discrete_layer(draw_ctx);
 
             let boxed_child = box_node(child.clone());
-            drawing_ctx::draw_node_from_stack(draw_ctx, boxed_child, 1);
+            drawing_ctx::draw_node_from_stack(draw_ctx, boxed_child, 1, clipping);
             rsvg_node_unref(boxed_child);
 
             drawing_ctx::pop_discrete_layer(draw_ctx);
@@ -342,7 +342,7 @@ impl NodeTrait for NodeUse {
                     draw_ctx,
                     || {
                         drawing_ctx::state_push(draw_ctx);
-                        child.draw_children(draw_ctx, 1);
+                        child.draw_children(draw_ctx, 1, clipping);
                         drawing_ctx::state_pop(draw_ctx);
                     },
                 );
@@ -388,7 +388,7 @@ impl NodeTrait for NodeSymbol {
         Ok(())
     }
 
-    fn draw(&self, _: &RsvgNode, _: *const RsvgDrawingCtx, _: i32) {
+    fn draw(&self, _: &RsvgNode, _: *mut RsvgDrawingCtx, _: i32, _: bool) {
         // nothing
     }
 
diff --git a/rsvg_internals/src/text.rs b/rsvg_internals/src/text.rs
index 163117ae..381ab40c 100644
--- a/rsvg_internals/src/text.rs
+++ b/rsvg_internals/src/text.rs
@@ -5,6 +5,7 @@ use std::cell::{Cell, RefCell};
 use std::str;
 
 use attributes::Attribute;
+use draw::draw_pango_layout;
 use drawing_ctx::{self, RsvgDrawingCtx};
 use handle::RsvgHandle;
 use length::*;
@@ -75,7 +76,7 @@ impl NodeChars {
         *length = f64::from(width) / f64::from(pango::SCALE);
     }
 
-    fn render(&self, draw_ctx: *const RsvgDrawingCtx, x: &mut f64, y: &mut f64) {
+    fn render(&self, draw_ctx: *mut RsvgDrawingCtx, x: &mut f64, y: &mut f64, clipping: bool) {
         let s = self.string.borrow();
         let layout = create_pango_layout(draw_ctx, &s);
         let (width, _) = layout.get_size();
@@ -89,10 +90,10 @@ impl NodeChars {
 
         let gravity = state::get_text_gravity(state);
         if gravity_is_vertical(gravity) {
-            drawing_ctx::render_pango_layout(draw_ctx, &layout, *x + offset, *y);
+            draw_pango_layout(draw_ctx, &layout, *x + offset, *y, clipping);
             *y += f64::from(width) / f64::from(pango::SCALE);
         } else {
-            drawing_ctx::render_pango_layout(draw_ctx, &layout, *x, *y - offset);
+            draw_pango_layout(draw_ctx, &layout, *x, *y - offset, clipping);
             *x += f64::from(width) / f64::from(pango::SCALE);
         }
     }
@@ -103,7 +104,7 @@ impl NodeTrait for NodeChars {
         Ok(())
     }
 
-    fn draw(&self, _: &RsvgNode, _: *const RsvgDrawingCtx, _: i32) {
+    fn draw(&self, _: &RsvgNode, _: *mut RsvgDrawingCtx, _: i32, _: bool) {
         // nothing
     }
 
@@ -146,7 +147,7 @@ impl NodeTrait for NodeText {
         Ok(())
     }
 
-    fn draw(&self, node: &RsvgNode, draw_ctx: *const RsvgDrawingCtx, dominate: i32) {
+    fn draw(&self, node: &RsvgNode, draw_ctx: *mut RsvgDrawingCtx, dominate: i32, clipping: bool) {
         drawing_ctx::state_reinherit_top(draw_ctx, node.get_state(), dominate);
 
         let mut x = self.x.get().normalize(draw_ctx);
@@ -179,7 +180,7 @@ impl NodeTrait for NodeText {
         x += dx;
         y += dy;
 
-        render_children(node, draw_ctx, &mut x, &mut y, false);
+        render_children(node, draw_ctx, &mut x, &mut y, false, clipping);
     }
 
     fn get_c_impl(&self) -> *const RsvgCNodeImpl {
@@ -216,7 +217,7 @@ impl NodeTRef {
         done
     }
 
-    fn render(&self, draw_ctx: *const RsvgDrawingCtx, x: &mut f64, y: &mut f64) {
+    fn render(&self, draw_ctx: *mut RsvgDrawingCtx, x: &mut f64, y: &mut f64, clipping: bool) {
         let l = self.link.borrow();
 
         if l.is_none() {
@@ -225,7 +226,7 @@ impl NodeTRef {
 
         if let Some(acquired) = drawing_ctx::get_acquired_node(draw_ctx, l.as_ref().unwrap()) {
             let c = acquired.get();
-            render_children(&c, draw_ctx, x, y, true)
+            render_children(&c, draw_ctx, x, y, true, clipping)
         }
     }
 }
@@ -242,7 +243,7 @@ impl NodeTrait for NodeTRef {
         Ok(())
     }
 
-    fn draw(&self, _: &RsvgNode, _: *const RsvgDrawingCtx, _: i32) {
+    fn draw(&self, _: &RsvgNode, _: *mut RsvgDrawingCtx, _: i32, _: bool) {
         // nothing
     }
 
@@ -293,10 +294,11 @@ impl NodeTSpan {
     fn render(
         &self,
         node: &RsvgNode,
-        draw_ctx: *const RsvgDrawingCtx,
+        draw_ctx: *mut RsvgDrawingCtx,
         x: &mut f64,
         y: &mut f64,
         usetextonly: bool,
+        clipping: bool,
     ) {
         drawing_ctx::state_push(draw_ctx);
         drawing_ctx::state_reinherit_top(draw_ctx, node.get_state(), 0);
@@ -336,7 +338,7 @@ impl NodeTSpan {
         }
         *y += dy;
 
-        render_children(node, draw_ctx, x, y, usetextonly);
+        render_children(node, draw_ctx, x, y, usetextonly, clipping);
 
         drawing_ctx::state_pop(draw_ctx);
     }
@@ -360,7 +362,7 @@ impl NodeTrait for NodeTSpan {
         Ok(())
     }
 
-    fn draw(&self, _: &RsvgNode, _: *const RsvgDrawingCtx, _: i32) {
+    fn draw(&self, _: &RsvgNode, _: *mut RsvgDrawingCtx, _: i32, _: bool) {
         // nothing
     }
 
@@ -536,15 +538,16 @@ fn measure_child(
 
 fn render_children(
     node: &RsvgNode,
-    draw_ctx: *const RsvgDrawingCtx,
+    draw_ctx: *mut RsvgDrawingCtx,
     x: &mut f64,
     y: &mut f64,
     textonly: bool,
+    clipping: bool,
 ) {
     drawing_ctx::push_discrete_layer(draw_ctx);
 
     for child in node.children() {
-        render_child(&child, draw_ctx, x, y, textonly);
+        render_child(&child, draw_ctx, x, y, textonly, clipping);
     }
 
     drawing_ctx::pop_discrete_layer(draw_ctx);
@@ -552,26 +555,27 @@ fn render_children(
 
 fn render_child(
     node: &RsvgNode,
-    draw_ctx: *const RsvgDrawingCtx,
+    draw_ctx: *mut RsvgDrawingCtx,
     x: &mut f64,
     y: &mut f64,
     textonly: bool,
+    clipping: bool,
 ) {
     match (node.get_type(), textonly) {
         (NodeType::Chars, _) => {
-            node.with_impl(|chars: &NodeChars| chars.render(draw_ctx, x, y));
+            node.with_impl(|chars: &NodeChars| chars.render(draw_ctx, x, y, clipping));
         }
         (_, true) => {
-            render_children(node, draw_ctx, x, y, textonly);
+            render_children(node, draw_ctx, x, y, textonly, clipping);
         }
         (NodeType::TSpan, _) => {
             node.with_impl(|tspan: &NodeTSpan| {
-                tspan.render(node, draw_ctx, x, y, textonly);
+                tspan.render(node, draw_ctx, x, y, textonly, clipping);
             });
         }
         (NodeType::TRef, _) => {
             node.with_impl(|tref: &NodeTRef| {
-                tref.render(draw_ctx, x, y);
+                tref.render(draw_ctx, x, y, clipping);
             });
         }
         (_, _) => {}



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