[librsvg: 6/10] drawing_ctx: move all drawing_ctx code in cairo-draw.[ch]



commit 7843ee2d76c0d35db333e4387389c102b4a2330b
Author: Paolo Borelli <pborelli gnome org>
Date:   Sun May 13 15:51:56 2018 +0200

    drawing_ctx: move all drawing_ctx code in cairo-draw.[ch]
    
    The code for now is moved verbatim

 librsvg/rsvg-base.c       | 360 ----------------------------------------------
 librsvg/rsvg-cairo-draw.c | 360 ++++++++++++++++++++++++++++++++++++++++++++++
 librsvg/rsvg-cairo-draw.h |  86 ++++++++++-
 librsvg/rsvg-handle.c     |   1 +
 librsvg/rsvg-private.h    |  84 -----------
 5 files changed, 446 insertions(+), 445 deletions(-)
---
diff --git a/librsvg/rsvg-base.c b/librsvg/rsvg-base.c
index d0f58e6f..ad2aebfa 100644
--- a/librsvg/rsvg-base.c
+++ b/librsvg/rsvg-base.c
@@ -107,150 +107,6 @@ rsvg_error_quark (void)
     return g_quark_from_string ("rsvg-error-quark");
 }
 
-static void
-rsvg_cairo_transformed_image_bounding_box (cairo_matrix_t *affine,
-                                           double width, double height,
-                                           double *x0, double *y0, double *x1, double *y1)
-{
-    double x00 = 0, x01 = 0, x10 = width, x11 = width;
-    double y00 = 0, y01 = height, y10 = 0, y11 = height;
-    double t;
-
-    /* transform the four corners of the image */
-    cairo_matrix_transform_point (affine, &x00, &y00);
-    cairo_matrix_transform_point (affine, &x01, &y01);
-    cairo_matrix_transform_point (affine, &x10, &y10);
-    cairo_matrix_transform_point (affine, &x11, &y11);
-
-    /* find minimum and maximum coordinates */
-    t = x00  < x01 ? x00  : x01;
-    t = t < x10 ? t : x10;
-    *x0 = floor (t < x11 ? t : x11);
-
-    t = y00  < y01 ? y00  : y01;
-    t = t < y10 ? t : y10;
-    *y0 = floor (t < y11 ? t : y11);
-
-    t = x00  > x01 ? x00  : x01;
-    t = t > x10 ? t : x10;
-    *x1 = ceil (t > x11 ? t : x11);
-
-    t = y00  > y01 ? y00  : y01;
-    t = t > y10 ? t : y10;
-    *y1 = ceil (t > y11 ? t : y11);
-}
-
-RsvgDrawingCtx *
-rsvg_drawing_ctx_new (cairo_t *cr, RsvgHandle *handle)
-{
-    RsvgDimensionData data;
-    RsvgDrawingCtx *draw;
-    RsvgState *state;
-    cairo_matrix_t affine;
-    cairo_matrix_t state_affine;
-    double bbx0, bby0, bbx1, bby1;
-
-    rsvg_handle_get_dimensions (handle, &data);
-    if (data.width == 0 || data.height == 0)
-        return NULL;
-
-    draw = g_new0 (RsvgDrawingCtx, 1);
-
-    cairo_get_matrix (cr, &affine);
-
-    /* find bounding box of image as transformed by the current cairo context
-     * The size of this bounding box determines the size of the intermediate
-     * surfaces allocated during drawing. */
-    rsvg_cairo_transformed_image_bounding_box (&affine,
-                                               data.width, data.height,
-                                               &bbx0, &bby0, &bbx1, &bby1);
-
-    draw->initial_cr = cr;
-    draw->cr = cr;
-    draw->cr_stack = NULL;
-    draw->surfaces_stack = NULL;
-
-    draw->offset_x = bbx0;
-    draw->offset_y = bby0;
-    draw->width = bbx1 - bbx0;
-    draw->height = bby1 - bby0;
-
-    draw->state = NULL;
-
-    draw->defs = handle->priv->defs;
-    draw->dpi_x = handle->priv->dpi_x;
-    draw->dpi_y = handle->priv->dpi_y;
-    draw->vb.rect.width = data.em;
-    draw->vb.rect.height = data.ex;
-    draw->vb_stack = NULL;
-    draw->drawsub_stack = NULL;
-    draw->acquired_nodes = NULL;
-    draw->is_testing = handle->priv->is_testing;
-
-    rsvg_drawing_ctx_state_push (draw);
-    state = rsvg_drawing_ctx_get_current_state (draw);
-
-    state_affine = rsvg_state_get_affine (state);
-
-    /* apply cairo transformation to our affine transform */
-    cairo_matrix_multiply (&state_affine, &affine, &state_affine);
-
-    /* scale according to size set by size_func callback */
-    cairo_matrix_init_scale (&affine, data.width / data.em, data.height / data.ex);
-    cairo_matrix_multiply (&state_affine, &affine, &state_affine);
-
-    /* adjust transform so that the corner of the bounding box above is
-     * at (0,0) - we compensate for this in _set_rsvg_affine() in
-     * rsvg-cairo-render.c and a few other places */
-    state_affine.x0 -= draw->offset_x;
-    state_affine.y0 -= draw->offset_y;
-
-    rsvg_bbox_init (&draw->bbox, &state_affine);
-    rsvg_bbox_init (&draw->ink_bbox, &state_affine);
-
-    rsvg_state_set_affine (state, state_affine);
-
-#ifdef HAVE_PANGOFT2
-    draw->font_config_for_testing = NULL;
-    draw->font_map_for_testing = NULL;
-#endif
-
-    return draw;
-}
-
-void
-rsvg_drawing_ctx_free (RsvgDrawingCtx * handle)
-{
-    g_assert (handle->cr_stack == NULL);
-    g_assert (handle->surfaces_stack == NULL);
-
-    g_assert(handle->state);
-    g_assert(rsvg_state_parent(handle->state) == NULL);
-    rsvg_state_free (handle->state);
-
-       g_slist_free_full (handle->drawsub_stack, (GDestroyNotify) rsvg_node_unref);
-
-    g_warn_if_fail (handle->acquired_nodes == NULL);
-    g_slist_free (handle->acquired_nodes);
-
-    g_assert (handle->bb_stack == NULL);
-    g_assert (handle->ink_bb_stack == NULL);
-
-#ifdef HAVE_PANGOFT2
-    if (handle->font_config_for_testing) {
-        FcConfigDestroy (handle->font_config_for_testing);
-        handle->font_config_for_testing = NULL;
-    }
-
-    if (handle->font_map_for_testing) {
-        g_object_unref (handle->font_map_for_testing);
-        handle->font_map_for_testing = NULL;
-    }
-#endif
-
-    g_free (handle);
-}
-
 /**
  * rsvg_set_default_dpi:
  * @dpi: Dots Per Inch (aka Pixels Per Inch)
@@ -488,184 +344,6 @@ rsvg_push_discrete_layer (RsvgDrawingCtx *ctx, gboolean clipping)
     rsvg_cairo_push_discrete_layer (ctx, clipping);
 }
 
-RsvgState *
-rsvg_drawing_ctx_get_current_state (RsvgDrawingCtx *ctx)
-{
-    return ctx->state;
-}
-
-void
-rsvg_drawing_ctx_set_current_state (RsvgDrawingCtx *ctx, RsvgState *state)
-{
-    ctx->state = state;
-}
-
-/*
- * rsvg_drawing_ctx_acquire_node:
- * @ctx: The drawing context in use
- * @url: The IRI to lookup, or %NULL
- *
- * Use this function when looking up urls to other nodes. This
- * function does proper recursion checking and thereby avoids
- * infinite loops.
- *
- * Nodes acquired by this function must be released using
- * rsvg_drawing_ctx_release_node() in reverse acquiring order.
- *
- * Note that if you acquire a node, you have to release it before trying to
- * acquire it again.  If you acquire a node "#foo" and don't release it before
- * trying to acquire "foo" again, you will obtain a %NULL the second time.
- *
- * Returns: The node referenced by @url; or %NULL if the @url
- *          is %NULL or it does not reference a node.
- */
-RsvgNode *
-rsvg_drawing_ctx_acquire_node (RsvgDrawingCtx * ctx, const char *url)
-{
-  RsvgNode *node;
-
-  if (url == NULL)
-      return NULL;
-
-  node = rsvg_defs_lookup (ctx->defs, url);
-  if (node == NULL)
-    return NULL;
-
-  if (g_slist_find (ctx->acquired_nodes, node))
-    return NULL;
-
-  ctx->acquired_nodes = g_slist_prepend (ctx->acquired_nodes, node);
-
-  return node;
-}
-
-/**
- * rsvg_drawing_ctx_acquire_node_of_type:
- * @ctx: The drawing context in use
- * @url: The IRI to lookup
- * @type: Type which the node must have
- *
- * Use this function when looking up urls to other nodes, and when you expect
- * the node to be of a particular type. This function does proper recursion
- * checking and thereby avoids infinite loops.
- *
- * Malformed SVGs, for example, may reference a marker by its IRI, but
- * the object referenced by the IRI is not a marker.
- *
- * Nodes acquired by this function must be released using
- * rsvg_drawing_ctx_release_node() in reverse acquiring order.
- *
- * Note that if you acquire a node, you have to release it before trying to
- * acquire it again.  If you acquire a node "#foo" and don't release it before
- * trying to acquire "foo" again, you will obtain a %NULL the second time.
- *
- * Returns: The node referenced by @url or %NULL if the @url
- *          does not reference a node.  Also returns %NULL if
- *          the node referenced by @url is not of the specified @type.
- */
-RsvgNode *
-rsvg_drawing_ctx_acquire_node_of_type (RsvgDrawingCtx * ctx, const char *url, RsvgNodeType type)
-{
-    RsvgNode *node;
-
-    node = rsvg_drawing_ctx_acquire_node (ctx, url);
-    if (node == NULL || rsvg_node_get_type (node) != type) {
-        rsvg_drawing_ctx_release_node (ctx, node);
-        return NULL;
-    }
-
-    return node;
-}
-
-/*
- * rsvg_drawing_ctx_release_node:
- * @ctx: The drawing context the node was acquired from
- * @node: Node to release
- *
- * Releases a node previously acquired via rsvg_drawing_ctx_acquire_node() or
- * rsvg_drawing_ctx_acquire_node_of_type().
- *
- * if @node is %NULL, this function does nothing.
- */
-void
-rsvg_drawing_ctx_release_node (RsvgDrawingCtx * ctx, RsvgNode *node)
-{
-  if (node == NULL)
-    return;
-
-  g_return_if_fail (ctx->acquired_nodes != NULL);
-  g_return_if_fail (ctx->acquired_nodes->data == node);
-
-  ctx->acquired_nodes = g_slist_remove (ctx->acquired_nodes, node);
-}
-
-void
-rsvg_drawing_ctx_add_node_and_ancestors_to_stack (RsvgDrawingCtx *draw_ctx, RsvgNode *node)
-{
-    if (node) {
-        node = rsvg_node_ref (node);
-
-        while (node != NULL) {
-            draw_ctx->drawsub_stack = g_slist_prepend (draw_ctx->drawsub_stack, node);
-            node = rsvg_node_get_parent (node);
-        }
-    }
-}
-
-void
-rsvg_drawing_ctx_draw_node_from_stack (RsvgDrawingCtx *ctx,
-                                       RsvgNode *node,
-                                       int dominate,
-                                       gboolean clipping)
-{
-    RsvgState *state;
-    GSList *stacksave;
-
-    stacksave = ctx->drawsub_stack;
-    if (stacksave) {
-        RsvgNode *stack_node = stacksave->data;
-
-        if (!rsvg_node_is_same (stack_node, node))
-            return;
-
-        ctx->drawsub_stack = stacksave->next;
-    }
-
-    state = rsvg_node_get_state (node);
-
-    if (rsvg_state_is_visible (state)) {
-        rsvg_drawing_ctx_state_push (ctx);
-        rsvg_node_draw (node, ctx, dominate, clipping);
-        rsvg_drawing_ctx_state_pop (ctx);
-    }
-
-    ctx->drawsub_stack = stacksave;
-}
-
-void
-rsvg_drawing_ctx_get_offset (RsvgDrawingCtx *draw_ctx, double *x, double *y)
-{
-    if (x != NULL) {
-        *x = draw_ctx->offset_x;
-    }
-
-    if (y != NULL) {
-        *y = draw_ctx->offset_y;
-    }
-}
-
-void
-rsvg_drawing_ctx_insert_bbox (RsvgDrawingCtx *draw_ctx, RsvgBbox *bbox)
-{
-    rsvg_bbox_insert (&draw_ctx->bbox, bbox);
-}
-
-void
-rsvg_drawing_ctx_insert_ink_bbox (RsvgDrawingCtx *draw_ctx, RsvgBbox *ink_bbox)
-{
-    rsvg_bbox_insert (&draw_ctx->ink_bbox, ink_bbox);
-}
-
 cairo_surface_t *
 rsvg_cairo_surface_new_from_href (RsvgHandle *handle,
                                   const char *href,
@@ -742,44 +420,6 @@ rsvg_cairo_surface_new_from_href (RsvgHandle *handle,
     return surface;
 }
 
-void
-rsvg_drawing_ctx_push_view_box (RsvgDrawingCtx * ctx, double w, double h)
-{
-    RsvgViewBox *vb = g_new0 (RsvgViewBox, 1);
-    *vb = ctx->vb;
-    ctx->vb_stack = g_slist_prepend (ctx->vb_stack, vb);
-    ctx->vb.rect.width = w;
-    ctx->vb.rect.height = h;
-}
-
-void
-rsvg_drawing_ctx_pop_view_box (RsvgDrawingCtx * ctx)
-{
-    ctx->vb = *((RsvgViewBox *) ctx->vb_stack->data);
-    g_free (ctx->vb_stack->data);
-    ctx->vb_stack = g_slist_delete_link (ctx->vb_stack, ctx->vb_stack);
-}
-
-void
-rsvg_drawing_ctx_get_view_box_size (RsvgDrawingCtx *ctx, double *out_width, double *out_height)
-{
-    if (out_width)
-        *out_width = ctx->vb.rect.width;
-
-    if (out_height)
-        *out_height = ctx->vb.rect.height;
-}
-
-void
-rsvg_drawing_ctx_get_dpi (RsvgDrawingCtx *ctx, double *out_dpi_x, double *out_dpi_y)
-{
-    if (out_dpi_x)
-        *out_dpi_x = ctx->dpi_x;
-
-    if (out_dpi_y)
-        *out_dpi_y = ctx->dpi_y;
-}
-
 void
 rsvg_return_if_fail_warning (const char *pretty_function, const char *expression, GError ** error)
 {
diff --git a/librsvg/rsvg-cairo-draw.c b/librsvg/rsvg-cairo-draw.c
index 2f34f2c1..91c6e44e 100644
--- a/librsvg/rsvg-cairo-draw.c
+++ b/librsvg/rsvg-cairo-draw.c
@@ -874,3 +874,363 @@ rsvg_cairo_surface_to_pixbuf (cairo_surface_t *surface)
 
     return dest;
 }
+
+static void
+rsvg_cairo_transformed_image_bounding_box (cairo_matrix_t *affine,
+                                           double width, double height,
+                                           double *x0, double *y0, double *x1, double *y1)
+{
+    double x00 = 0, x01 = 0, x10 = width, x11 = width;
+    double y00 = 0, y01 = height, y10 = 0, y11 = height;
+    double t;
+
+    /* transform the four corners of the image */
+    cairo_matrix_transform_point (affine, &x00, &y00);
+    cairo_matrix_transform_point (affine, &x01, &y01);
+    cairo_matrix_transform_point (affine, &x10, &y10);
+    cairo_matrix_transform_point (affine, &x11, &y11);
+
+    /* find minimum and maximum coordinates */
+    t = x00  < x01 ? x00  : x01;
+    t = t < x10 ? t : x10;
+    *x0 = floor (t < x11 ? t : x11);
+
+    t = y00  < y01 ? y00  : y01;
+    t = t < y10 ? t : y10;
+    *y0 = floor (t < y11 ? t : y11);
+
+    t = x00  > x01 ? x00  : x01;
+    t = t > x10 ? t : x10;
+    *x1 = ceil (t > x11 ? t : x11);
+
+    t = y00  > y01 ? y00  : y01;
+    t = t > y10 ? t : y10;
+    *y1 = ceil (t > y11 ? t : y11);
+}
+
+RsvgDrawingCtx *
+rsvg_drawing_ctx_new (cairo_t *cr, RsvgHandle *handle)
+{
+    RsvgDimensionData data;
+    RsvgDrawingCtx *draw;
+    RsvgState *state;
+    cairo_matrix_t affine;
+    cairo_matrix_t state_affine;
+    double bbx0, bby0, bbx1, bby1;
+
+    rsvg_handle_get_dimensions (handle, &data);
+    if (data.width == 0 || data.height == 0)
+        return NULL;
+
+    draw = g_new0 (RsvgDrawingCtx, 1);
+
+    cairo_get_matrix (cr, &affine);
+
+    /* find bounding box of image as transformed by the current cairo context
+     * The size of this bounding box determines the size of the intermediate
+     * surfaces allocated during drawing. */
+    rsvg_cairo_transformed_image_bounding_box (&affine,
+                                               data.width, data.height,
+                                               &bbx0, &bby0, &bbx1, &bby1);
+
+    draw->initial_cr = cr;
+    draw->cr = cr;
+    draw->cr_stack = NULL;
+    draw->surfaces_stack = NULL;
+
+    draw->offset_x = bbx0;
+    draw->offset_y = bby0;
+    draw->width = bbx1 - bbx0;
+    draw->height = bby1 - bby0;
+
+    draw->state = NULL;
+
+    draw->defs = handle->priv->defs;
+    draw->dpi_x = handle->priv->dpi_x;
+    draw->dpi_y = handle->priv->dpi_y;
+    draw->vb.rect.width = data.em;
+    draw->vb.rect.height = data.ex;
+    draw->vb_stack = NULL;
+    draw->drawsub_stack = NULL;
+    draw->acquired_nodes = NULL;
+    draw->is_testing = handle->priv->is_testing;
+
+    rsvg_drawing_ctx_state_push (draw);
+    state = rsvg_drawing_ctx_get_current_state (draw);
+
+    state_affine = rsvg_state_get_affine (state);
+
+    /* apply cairo transformation to our affine transform */
+    cairo_matrix_multiply (&state_affine, &affine, &state_affine);
+
+    /* scale according to size set by size_func callback */
+    cairo_matrix_init_scale (&affine, data.width / data.em, data.height / data.ex);
+    cairo_matrix_multiply (&state_affine, &affine, &state_affine);
+
+    /* adjust transform so that the corner of the bounding box above is
+     * at (0,0) - we compensate for this in _set_rsvg_affine() in
+     * rsvg-cairo-render.c and a few other places */
+    state_affine.x0 -= draw->offset_x;
+    state_affine.y0 -= draw->offset_y;
+
+    rsvg_bbox_init (&draw->bbox, &state_affine);
+    rsvg_bbox_init (&draw->ink_bbox, &state_affine);
+
+    rsvg_state_set_affine (state, state_affine);
+
+#ifdef HAVE_PANGOFT2
+    draw->font_config_for_testing = NULL;
+    draw->font_map_for_testing = NULL;
+#endif
+
+    return draw;
+}
+
+void
+rsvg_drawing_ctx_free (RsvgDrawingCtx *ctx)
+{
+    g_assert (ctx->cr_stack == NULL);
+    g_assert (ctx->surfaces_stack == NULL);
+
+    g_assert(ctx->state);
+    g_assert(rsvg_state_parent(ctx->state) == NULL);
+    rsvg_state_free (ctx->state);
+
+       g_slist_free_full (ctx->drawsub_stack, (GDestroyNotify) rsvg_node_unref);
+
+    g_warn_if_fail (ctx->acquired_nodes == NULL);
+    g_slist_free (ctx->acquired_nodes);
+
+    g_assert (ctx->bb_stack == NULL);
+    g_assert (ctx->ink_bb_stack == NULL);
+
+#ifdef HAVE_PANGOFT2
+    if (ctx->font_config_for_testing) {
+        FcConfigDestroy (ctx->font_config_for_testing);
+        ctx->font_config_for_testing = NULL;
+    }
+
+    if (ctx->font_map_for_testing) {
+        g_object_unref (ctx->font_map_for_testing);
+        ctx->font_map_for_testing = NULL;
+    }
+#endif
+
+    g_free (ctx);
+}
+
+RsvgState *
+rsvg_drawing_ctx_get_current_state (RsvgDrawingCtx *ctx)
+{
+    return ctx->state;
+}
+
+void
+rsvg_drawing_ctx_set_current_state (RsvgDrawingCtx *ctx, RsvgState *state)
+{
+    ctx->state = state;
+}
+
+/*
+ * rsvg_drawing_ctx_acquire_node:
+ * @ctx: The drawing context in use
+ * @url: The IRI to lookup, or %NULL
+ *
+ * Use this function when looking up urls to other nodes. This
+ * function does proper recursion checking and thereby avoids
+ * infinite loops.
+ *
+ * Nodes acquired by this function must be released using
+ * rsvg_drawing_ctx_release_node() in reverse acquiring order.
+ *
+ * Note that if you acquire a node, you have to release it before trying to
+ * acquire it again.  If you acquire a node "#foo" and don't release it before
+ * trying to acquire "foo" again, you will obtain a %NULL the second time.
+ *
+ * Returns: The node referenced by @url; or %NULL if the @url
+ *          is %NULL or it does not reference a node.
+ */
+RsvgNode *
+rsvg_drawing_ctx_acquire_node (RsvgDrawingCtx *ctx, const char *url)
+{
+  RsvgNode *node;
+
+  if (url == NULL)
+      return NULL;
+
+  node = rsvg_defs_lookup (ctx->defs, url);
+  if (node == NULL)
+    return NULL;
+
+  if (g_slist_find (ctx->acquired_nodes, node))
+    return NULL;
+
+  ctx->acquired_nodes = g_slist_prepend (ctx->acquired_nodes, node);
+
+  return node;
+}
+
+/**
+ * rsvg_drawing_ctx_acquire_node_of_type:
+ * @ctx: The drawing context in use
+ * @url: The IRI to lookup
+ * @type: Type which the node must have
+ *
+ * Use this function when looking up urls to other nodes, and when you expect
+ * the node to be of a particular type. This function does proper recursion
+ * checking and thereby avoids infinite loops.
+ *
+ * Malformed SVGs, for example, may reference a marker by its IRI, but
+ * the object referenced by the IRI is not a marker.
+ *
+ * Nodes acquired by this function must be released using
+ * rsvg_drawing_ctx_release_node() in reverse acquiring order.
+ *
+ * Note that if you acquire a node, you have to release it before trying to
+ * acquire it again.  If you acquire a node "#foo" and don't release it before
+ * trying to acquire "foo" again, you will obtain a %NULL the second time.
+ *
+ * Returns: The node referenced by @url or %NULL if the @url
+ *          does not reference a node.  Also returns %NULL if
+ *          the node referenced by @url is not of the specified @type.
+ */
+RsvgNode *
+rsvg_drawing_ctx_acquire_node_of_type (RsvgDrawingCtx *ctx, const char *url, RsvgNodeType type)
+{
+    RsvgNode *node;
+
+    node = rsvg_drawing_ctx_acquire_node (ctx, url);
+    if (node == NULL || rsvg_node_get_type (node) != type) {
+        rsvg_drawing_ctx_release_node (ctx, node);
+        return NULL;
+    }
+
+    return node;
+}
+
+/*
+ * rsvg_drawing_ctx_release_node:
+ * @ctx: The drawing context the node was acquired from
+ * @node: Node to release
+ *
+ * Releases a node previously acquired via rsvg_drawing_ctx_acquire_node() or
+ * rsvg_drawing_ctx_acquire_node_of_type().
+ *
+ * if @node is %NULL, this function does nothing.
+ */
+void
+rsvg_drawing_ctx_release_node (RsvgDrawingCtx *ctx, RsvgNode *node)
+{
+  if (node == NULL)
+    return;
+
+  g_return_if_fail (ctx->acquired_nodes != NULL);
+  g_return_if_fail (ctx->acquired_nodes->data == node);
+
+  ctx->acquired_nodes = g_slist_remove (ctx->acquired_nodes, node);
+}
+
+void
+rsvg_drawing_ctx_add_node_and_ancestors_to_stack (RsvgDrawingCtx *draw_ctx, RsvgNode *node)
+{
+    if (node) {
+        node = rsvg_node_ref (node);
+
+        while (node != NULL) {
+            draw_ctx->drawsub_stack = g_slist_prepend (draw_ctx->drawsub_stack, node);
+            node = rsvg_node_get_parent (node);
+        }
+    }
+}
+
+void
+rsvg_drawing_ctx_draw_node_from_stack (RsvgDrawingCtx *ctx,
+                                       RsvgNode *node,
+                                       int dominate,
+                                       gboolean clipping)
+{
+    RsvgState *state;
+    GSList *stacksave;
+
+    stacksave = ctx->drawsub_stack;
+    if (stacksave) {
+        RsvgNode *stack_node = stacksave->data;
+
+        if (!rsvg_node_is_same (stack_node, node))
+            return;
+
+        ctx->drawsub_stack = stacksave->next;
+    }
+
+    state = rsvg_node_get_state (node);
+
+    if (rsvg_state_is_visible (state)) {
+        rsvg_drawing_ctx_state_push (ctx);
+        rsvg_node_draw (node, ctx, dominate, clipping);
+        rsvg_drawing_ctx_state_pop (ctx);
+    }
+
+    ctx->drawsub_stack = stacksave;
+}
+
+void
+rsvg_drawing_ctx_get_offset (RsvgDrawingCtx *draw_ctx, double *x, double *y)
+{
+    if (x != NULL) {
+        *x = draw_ctx->offset_x;
+    }
+
+    if (y != NULL) {
+        *y = draw_ctx->offset_y;
+    }
+}
+
+void
+rsvg_drawing_ctx_insert_bbox (RsvgDrawingCtx *draw_ctx, RsvgBbox *bbox)
+{
+    rsvg_bbox_insert (&draw_ctx->bbox, bbox);
+}
+
+void
+rsvg_drawing_ctx_insert_ink_bbox (RsvgDrawingCtx *draw_ctx, RsvgBbox *ink_bbox)
+{
+    rsvg_bbox_insert (&draw_ctx->ink_bbox, ink_bbox);
+}
+
+void
+rsvg_drawing_ctx_push_view_box (RsvgDrawingCtx *ctx, double w, double h)
+{
+    RsvgViewBox *vb = g_new0 (RsvgViewBox, 1);
+    *vb = ctx->vb;
+    ctx->vb_stack = g_slist_prepend (ctx->vb_stack, vb);
+    ctx->vb.rect.width = w;
+    ctx->vb.rect.height = h;
+}
+
+void
+rsvg_drawing_ctx_pop_view_box (RsvgDrawingCtx *ctx)
+{
+    ctx->vb = *((RsvgViewBox *) ctx->vb_stack->data);
+    g_free (ctx->vb_stack->data);
+    ctx->vb_stack = g_slist_delete_link (ctx->vb_stack, ctx->vb_stack);
+}
+
+void
+rsvg_drawing_ctx_get_view_box_size (RsvgDrawingCtx *ctx, double *out_width, double *out_height)
+{
+    if (out_width)
+        *out_width = ctx->vb.rect.width;
+
+    if (out_height)
+        *out_height = ctx->vb.rect.height;
+}
+
+void
+rsvg_drawing_ctx_get_dpi (RsvgDrawingCtx *ctx, double *out_dpi_x, double *out_dpi_y)
+{
+    if (out_dpi_x)
+        *out_dpi_x = ctx->dpi_x;
+
+    if (out_dpi_y)
+        *out_dpi_y = ctx->dpi_y;
+}
diff --git a/librsvg/rsvg-cairo-draw.h b/librsvg/rsvg-cairo-draw.h
index 18377a3b..89da9861 100644
--- a/librsvg/rsvg-cairo-draw.h
+++ b/librsvg/rsvg-cairo-draw.h
@@ -30,7 +30,91 @@
 
 #include "rsvg-private.h"
 
-G_BEGIN_DECLS 
+G_BEGIN_DECLS
+
+/* Contextual information for the drawing phase */
+struct RsvgDrawingCtx {
+    cairo_t *cr;
+    cairo_t *initial_cr;
+    GList *cr_stack;
+    GList *surfaces_stack;
+    RsvgState *state;
+    GError **error;
+    RsvgDefs *defs;
+    double dpi_x, dpi_y;
+    RsvgViewBox vb;
+    GSList *vb_stack;
+    GSList *drawsub_stack;
+    GSList *acquired_nodes;
+    gboolean is_testing;
+    double offset_x, offset_y;
+    double width, height;
+    RsvgBbox bbox;     /* Bounding box for path extents, without stroke width */
+    RsvgBbox ink_bbox; /* Bounding box for ink rectangle, with everything */
+    GList *bb_stack;
+    GList *ink_bb_stack;
+
+#ifdef HAVE_PANGOFT2
+    FcConfig *font_config_for_testing;
+    PangoFontMap *font_map_for_testing;
+#endif
+};
+
+G_GNUC_INTERNAL
+void rsvg_pop_discrete_layer    (RsvgDrawingCtx *ctx, gboolean clipping);
+G_GNUC_INTERNAL
+void rsvg_push_discrete_layer   (RsvgDrawingCtx *ctx, gboolean clipping);
+
+G_GNUC_INTERNAL
+RsvgDrawingCtx *rsvg_drawing_ctx_new (cairo_t *cr, RsvgHandle *handle);
+
+G_GNUC_INTERNAL
+void rsvg_drawing_ctx_free (RsvgDrawingCtx *draw_ctx);
+
+G_GNUC_INTERNAL
+RsvgState *rsvg_drawing_ctx_get_current_state   (RsvgDrawingCtx * ctx);
+G_GNUC_INTERNAL
+void rsvg_drawing_ctx_set_current_state         (RsvgDrawingCtx * ctx, RsvgState *state);
+
+/* Implemented in rust/src/drawing_ctx.rs */
+G_GNUC_INTERNAL
+void       rsvg_drawing_ctx_state_pop           (RsvgDrawingCtx * ctx);
+G_GNUC_INTERNAL
+void       rsvg_drawing_ctx_state_push          (RsvgDrawingCtx * ctx);
+
+G_GNUC_INTERNAL
+RsvgNode *rsvg_drawing_ctx_acquire_node         (RsvgDrawingCtx * ctx, const char *url);
+G_GNUC_INTERNAL
+RsvgNode *rsvg_drawing_ctx_acquire_node_of_type (RsvgDrawingCtx * ctx, const char *url, RsvgNodeType type);
+G_GNUC_INTERNAL
+void rsvg_drawing_ctx_release_node              (RsvgDrawingCtx * ctx, RsvgNode *node);
+
+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,
+                                            gboolean clipping);
+
+G_GNUC_INTERNAL
+void rsvg_drawing_ctx_get_offset (RsvgDrawingCtx *draw_ctx, double *x, double *y);
+
+G_GNUC_INTERNAL
+void rsvg_drawing_ctx_insert_bbox (RsvgDrawingCtx *draw_ctx, RsvgBbox *bbox);
+
+G_GNUC_INTERNAL
+void rsvg_drawing_ctx_insert_ink_bbox (RsvgDrawingCtx *draw_ctx, RsvgBbox *ink_bbox);
+
+G_GNUC_INTERNAL
+void rsvg_drawing_ctx_push_view_box (RsvgDrawingCtx * ctx, double w, double h);
+G_GNUC_INTERNAL
+void rsvg_drawing_ctx_pop_view_box  (RsvgDrawingCtx * ctx);
+G_GNUC_INTERNAL
+void rsvg_drawing_ctx_get_view_box_size (RsvgDrawingCtx *ctx, double *out_width, double *out_height);
+
+G_GNUC_INTERNAL
+void rsvg_drawing_ctx_get_dpi (RsvgDrawingCtx *ctx, double *out_dpi_x, double *out_dpi_y);
 
 G_GNUC_INTERNAL
 PangoContext    *rsvg_cairo_get_pango_context    (RsvgDrawingCtx *ctx);
diff --git a/librsvg/rsvg-handle.c b/librsvg/rsvg-handle.c
index 0ab35b30..03c8c3b4 100644
--- a/librsvg/rsvg-handle.c
+++ b/librsvg/rsvg-handle.c
@@ -122,6 +122,7 @@
 
 #include "rsvg-private.h"
 #include "rsvg-defs.h"
+#include "rsvg-cairo-draw.h"
 #include "rsvg-structure.h"
 
 enum {
diff --git a/librsvg/rsvg-private.h b/librsvg/rsvg-private.h
index cb78b39f..87d2fcd7 100644
--- a/librsvg/rsvg-private.h
+++ b/librsvg/rsvg-private.h
@@ -180,34 +180,6 @@ typedef struct {
     gboolean virgin;
 } RsvgBbox;
 
-/* Contextual information for the drawing phase */
-struct RsvgDrawingCtx {
-    cairo_t *cr;
-    cairo_t *initial_cr;
-    GList *cr_stack;
-    GList *surfaces_stack;
-    RsvgState *state;
-    GError **error;
-    RsvgDefs *defs;
-    double dpi_x, dpi_y;
-    RsvgViewBox vb;
-    GSList *vb_stack;
-    GSList *drawsub_stack;
-    GSList *acquired_nodes;
-    gboolean is_testing;
-    double offset_x, offset_y;
-    double width, height;
-    RsvgBbox bbox;     /* Bounding box for path extents, without stroke width */
-    RsvgBbox ink_bbox; /* Bounding box for ink rectangle, with everything */
-    GList *bb_stack;
-    GList *ink_bb_stack;
-
-#ifdef HAVE_PANGOFT2
-    FcConfig *font_config_for_testing;
-    PangoFontMap *font_map_for_testing;
-#endif
-};
-
 /* Keep this in sync with rust/src/length.rs:LengthUnit */
 typedef enum {
     LENGTH_UNIT_DEFAULT,
@@ -434,52 +406,6 @@ gboolean rsvg_cond_check_required_extensions (const char *value);
 G_GNUC_INTERNAL
 gboolean rsvg_cond_check_system_language (const char *value);
 
-G_GNUC_INTERNAL
-void rsvg_pop_discrete_layer    (RsvgDrawingCtx *ctx, gboolean clipping);
-G_GNUC_INTERNAL
-void rsvg_push_discrete_layer   (RsvgDrawingCtx *ctx, gboolean clipping);
-
-G_GNUC_INTERNAL
-RsvgDrawingCtx *rsvg_drawing_ctx_new (cairo_t *cr, RsvgHandle *handle);
-
-G_GNUC_INTERNAL
-void rsvg_drawing_ctx_free (RsvgDrawingCtx *draw_ctx);
-
-G_GNUC_INTERNAL
-RsvgState *rsvg_drawing_ctx_get_current_state   (RsvgDrawingCtx * ctx);
-G_GNUC_INTERNAL
-void rsvg_drawing_ctx_set_current_state         (RsvgDrawingCtx * ctx, RsvgState *state);
-
-/* Implemented in rust/src/drawing_ctx.rs */
-G_GNUC_INTERNAL
-void       rsvg_drawing_ctx_state_pop           (RsvgDrawingCtx * ctx);
-G_GNUC_INTERNAL
-void       rsvg_drawing_ctx_state_push          (RsvgDrawingCtx * ctx);
-
-G_GNUC_INTERNAL
-RsvgNode *rsvg_drawing_ctx_acquire_node         (RsvgDrawingCtx * ctx, const char *url);
-G_GNUC_INTERNAL
-RsvgNode *rsvg_drawing_ctx_acquire_node_of_type (RsvgDrawingCtx * ctx, const char *url, RsvgNodeType type);
-G_GNUC_INTERNAL
-void rsvg_drawing_ctx_release_node              (RsvgDrawingCtx * ctx, RsvgNode *node);
-
-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,
-                                            gboolean clipping);
-
-G_GNUC_INTERNAL
-void rsvg_drawing_ctx_get_offset (RsvgDrawingCtx *draw_ctx, double *x, double *y);
-
-G_GNUC_INTERNAL
-void rsvg_drawing_ctx_insert_bbox (RsvgDrawingCtx *draw_ctx, RsvgBbox *bbox);
-
-G_GNUC_INTERNAL
-void rsvg_drawing_ctx_insert_ink_bbox (RsvgDrawingCtx *draw_ctx, RsvgBbox *ink_bbox);
-
 G_GNUC_INTERNAL
 cairo_surface_t *rsvg_cairo_surface_from_pixbuf (const GdkPixbuf *pixbuf);
 G_GNUC_INTERNAL
@@ -515,16 +441,6 @@ double rsvg_length_hand_normalize (const RsvgLength *length,
 G_GNUC_INTERNAL
 RsvgLength rsvg_length_parse (const char *str, LengthDir dir);
 
-G_GNUC_INTERNAL
-void rsvg_drawing_ctx_push_view_box (RsvgDrawingCtx * ctx, double w, double h);
-G_GNUC_INTERNAL
-void rsvg_drawing_ctx_pop_view_box  (RsvgDrawingCtx * ctx);
-G_GNUC_INTERNAL
-void rsvg_drawing_ctx_get_view_box_size (RsvgDrawingCtx *ctx, double *out_width, double *out_height);
-
-G_GNUC_INTERNAL
-void rsvg_drawing_ctx_get_dpi (RsvgDrawingCtx *ctx, double *out_dpi_x, double *out_dpi_y);
-
 G_GNUC_INTERNAL
 void rsvg_return_if_fail_warning (const char *pretty_function,
                                   const char *expression, GError ** error);


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