[librsvg: 4/6] Remove RsvgRender base struct
- From: Federico Mena Quintero <federico src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [librsvg: 4/6] Remove RsvgRender base struct
- Date: Sat, 28 Apr 2018 16:19:51 +0000 (UTC)
commit fa1be476e4f1d890f6ba030b671b092ca95fa94b
Author: Paolo Borelli <pborelli gnome org>
Date: Sat Apr 28 15:08:16 2018 +0200
Remove RsvgRender base struct
All the code is already assuming that the only render is the cairo
render and casting back and forth. Once we are in rust we can bring
back a Render trait, but at the moment the "base" struct only gets
in the way.
While at it some code is also moved around: the draw_ctx creation
goes in base.c and the handle methods go in handle.c.
librsvg/filters/common.c | 2 +-
librsvg/rsvg-base.c | 125 +++++++++++++++++++++++---
librsvg/rsvg-cairo-draw.c | 49 ++++-------
librsvg/rsvg-cairo-render.c | 209 ++++----------------------------------------
librsvg/rsvg-cairo-render.h | 7 +-
librsvg/rsvg-handle.c | 74 +++++++++++++++-
librsvg/rsvg-private.h | 44 ++--------
7 files changed, 226 insertions(+), 284 deletions(-)
---
diff --git a/librsvg/filters/common.c b/librsvg/filters/common.c
index 9d65d889..6354814d 100644
--- a/librsvg/filters/common.c
+++ b/librsvg/filters/common.c
@@ -579,7 +579,7 @@ surface_get_alpha (cairo_surface_t *source,
static cairo_surface_t *
rsvg_compile_bg (RsvgDrawingCtx * ctx)
{
- RsvgCairoRender *render = RSVG_CAIRO_RENDER (ctx->render);
+ RsvgCairoRender *render = ctx->render;
cairo_surface_t *surface;
cairo_t *cr;
GList *i;
diff --git a/librsvg/rsvg-base.c b/librsvg/rsvg-base.c
index ca117718..bd174b19 100644
--- a/librsvg/rsvg-base.c
+++ b/librsvg/rsvg-base.c
@@ -108,10 +108,117 @@ 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;
+ RsvgCairoRender *render;
+ 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);
+
+ render = rsvg_cairo_render_new (cr, bbx1 - bbx0, bby1 - bby0);
+
+ if (!render)
+ return NULL;
+
+ draw->render = render;
+ render->offset_x = bbx0;
+ render->offset_y = 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->pango_context = NULL;
+ 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 -= render->offset_x;
+ state_affine.y0 -= render->offset_y;
+
+ rsvg_bbox_init (&((RsvgCairoRender *) draw->render)->bbox, &state_affine);
+ rsvg_bbox_init (&((RsvgCairoRender *) draw->render)->ink_bbox, &state_affine);
+
+ rsvg_state_set_affine (state, state_affine);
+
+ return draw;
+}
+
void
rsvg_drawing_ctx_free (RsvgDrawingCtx * handle)
{
- rsvg_render_free (handle->render);
+ rsvg_cairo_render_free (handle->render);
rsvg_state_free_all (handle->state);
@@ -520,7 +627,7 @@ rsvg_drawing_ctx_draw_node_from_stack (RsvgDrawingCtx *ctx,
void
rsvg_drawing_ctx_set_affine_on_cr (RsvgDrawingCtx *draw_ctx, cairo_t *cr, cairo_matrix_t *affine)
{
- RsvgCairoRender *render = RSVG_CAIRO_RENDER (draw_ctx->render);
+ RsvgCairoRender *render = draw_ctx->render;
gboolean nest = cr != render->initial_cr;
cairo_matrix_t matrix;
@@ -541,17 +648,13 @@ rsvg_drawing_ctx_get_pango_context (RsvgDrawingCtx *draw_ctx)
void
rsvg_drawing_ctx_insert_bbox (RsvgDrawingCtx *draw_ctx, RsvgBbox *bbox)
{
- RsvgCairoRender *render = RSVG_CAIRO_RENDER (draw_ctx->render);
-
- rsvg_bbox_insert (&render->bbox, bbox);
+ rsvg_bbox_insert (&draw_ctx->render->bbox, bbox);
}
void
rsvg_drawing_ctx_insert_ink_bbox (RsvgDrawingCtx *draw_ctx, RsvgBbox *ink_bbox)
{
- RsvgCairoRender *render = RSVG_CAIRO_RENDER (draw_ctx->render);
-
- rsvg_bbox_insert (&render->ink_bbox, ink_bbox);
+ rsvg_bbox_insert (&draw_ctx->render->ink_bbox, ink_bbox);
}
cairo_surface_t *
@@ -630,12 +733,6 @@ rsvg_cairo_surface_new_from_href (RsvgHandle *handle,
return surface;
}
-void
-rsvg_render_free (RsvgRender * render)
-{
- render->free (render);
-}
-
void
rsvg_drawing_ctx_push_view_box (RsvgDrawingCtx * ctx, double w, double h)
{
diff --git a/librsvg/rsvg-cairo-draw.c b/librsvg/rsvg-cairo-draw.c
index b0d512a9..da649bfb 100644
--- a/librsvg/rsvg-cairo-draw.c
+++ b/librsvg/rsvg-cairo-draw.c
@@ -120,12 +120,11 @@ rsvg_cairo_get_pango_context (RsvgDrawingCtx * ctx)
{
PangoFontMap *fontmap;
PangoContext *context;
- RsvgCairoRender *render = RSVG_CAIRO_RENDER (ctx->render);
double dpi_y;
#ifdef HAVE_PANGOFT2
if (ctx->is_testing) {
- fontmap = get_font_map_for_testing (render);
+ fontmap = get_font_map_for_testing (ctx->render);
} else {
#endif
fontmap = pango_cairo_font_map_get_default ();
@@ -134,7 +133,7 @@ rsvg_cairo_get_pango_context (RsvgDrawingCtx * ctx)
#endif
context = pango_font_map_create_context (fontmap);
- pango_cairo_update_context (render->cr, context);
+ pango_cairo_update_context (ctx->render->cr, context);
rsvg_drawing_ctx_get_dpi (ctx, NULL, &dpi_y);
pango_cairo_context_set_resolution (context, dpi_y);
@@ -151,9 +150,7 @@ rsvg_cairo_get_pango_context (RsvgDrawingCtx * ctx)
cairo_t *
rsvg_cairo_get_cairo_context (RsvgDrawingCtx *ctx)
{
- RsvgCairoRender *render = RSVG_CAIRO_RENDER (ctx->render);
-
- return render->cr;
+ return ctx->render->cr;
}
/* FIXME: Usage of this function is more less a hack. Some code does this:
@@ -177,15 +174,13 @@ rsvg_cairo_get_cairo_context (RsvgDrawingCtx *ctx)
void
rsvg_cairo_set_cairo_context (RsvgDrawingCtx *ctx, cairo_t *cr)
{
- RsvgCairoRender *render = RSVG_CAIRO_RENDER (ctx->render);
-
- render->cr = cr;
+ ctx->render->cr = cr;
}
static void
rsvg_cairo_generate_mask (cairo_t * cr, RsvgNode *mask, RsvgDrawingCtx *ctx, RsvgBbox *bbox)
{
- RsvgCairoRender *render = RSVG_CAIRO_RENDER (ctx->render);
+ RsvgCairoRender *render = ctx->render;
cairo_surface_t *surface;
cairo_t *mask_cr, *save_cr;
RsvgState *state;
@@ -323,7 +318,7 @@ rsvg_cairo_generate_mask (cairo_t * cr, RsvgNode *mask, RsvgDrawingCtx *ctx, Rsv
static void
rsvg_cairo_clip (RsvgDrawingCtx *ctx, RsvgNode *node_clip_path, RsvgBbox *bbox)
{
- RsvgCairoRender *save = RSVG_CAIRO_RENDER (ctx->render);
+ RsvgCairoRender *save = ctx->render;
cairo_matrix_t affinesave;
RsvgState *clip_path_state;
cairo_t *cr;
@@ -392,7 +387,7 @@ rsvg_cairo_clip (RsvgDrawingCtx *ctx, RsvgNode *node_clip_path, RsvgBbox *bbox)
static void
rsvg_cairo_push_render_stack (RsvgDrawingCtx * ctx)
{
- RsvgCairoRender *render = RSVG_CAIRO_RENDER (ctx->render);
+ RsvgCairoRender *render = ctx->render;
RsvgState *state;
char *clip_path;
char *filter;
@@ -487,20 +482,16 @@ rsvg_cairo_push_render_stack (RsvgDrawingCtx * ctx)
void
rsvg_cairo_push_discrete_layer (RsvgDrawingCtx * ctx, gboolean clipping)
{
- RsvgCairoRender *render = RSVG_CAIRO_RENDER (ctx->render);
-
- if (clipping) {
- return;
+ if (!clipping) {
+ cairo_save (ctx->render->cr);
+ rsvg_cairo_push_render_stack (ctx);
}
-
- cairo_save (render->cr);
- rsvg_cairo_push_render_stack (ctx);
}
static void
rsvg_cairo_pop_render_stack (RsvgDrawingCtx * ctx)
{
- RsvgCairoRender *render = RSVG_CAIRO_RENDER (ctx->render);
+ RsvgCairoRender *render = ctx->render;
RsvgState *state;
char *clip_path;
char *filter;
@@ -615,14 +606,10 @@ rsvg_cairo_pop_render_stack (RsvgDrawingCtx * ctx)
void
rsvg_cairo_pop_discrete_layer (RsvgDrawingCtx * ctx, gboolean clipping)
{
- RsvgCairoRender *render = RSVG_CAIRO_RENDER (ctx->render);
-
- if (clipping) {
- return;
+ if (!clipping) {
+ rsvg_cairo_pop_render_stack (ctx);
+ cairo_restore (ctx->render->cr);
}
-
- rsvg_cairo_pop_render_stack (ctx);
- cairo_restore (render->cr);
}
cairo_surface_t *
@@ -634,7 +621,7 @@ rsvg_cairo_get_surface_of_node (RsvgDrawingCtx *ctx,
cairo_surface_t *surface;
cairo_t *cr;
- RsvgCairoRender *save_render = (RsvgCairoRender *) ctx->render;
+ RsvgCairoRender *save_render = ctx->render;
RsvgCairoRender *render;
surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height);
@@ -646,14 +633,14 @@ rsvg_cairo_get_surface_of_node (RsvgDrawingCtx *ctx,
cr = cairo_create (surface);
render = rsvg_cairo_render_new (cr, width, height);
- ctx->render = (RsvgRender *) render;
+ ctx->render = render;
rsvg_drawing_ctx_draw_node_from_stack (ctx, drawable, 0, FALSE);
cairo_destroy (cr);
- rsvg_render_free (ctx->render);
- ctx->render = (RsvgRender *) save_render;
+ rsvg_cairo_render_free (ctx->render);
+ ctx->render = save_render;
return surface;
}
diff --git a/librsvg/rsvg-cairo-render.c b/librsvg/rsvg-cairo-render.c
index a7568d5c..7bd6ed17 100644
--- a/librsvg/rsvg-cairo-render.c
+++ b/librsvg/rsvg-cairo-render.c
@@ -41,39 +41,12 @@
#include "rsvg-styles.h"
#include "rsvg-structure.h"
-static void
-rsvg_cairo_render_free (RsvgRender * self)
-{
- RsvgCairoRender *me = RSVG_CAIRO_RENDER (self);
-
- g_assert (me->cr_stack == NULL);
- g_assert (me->bb_stack == NULL);
- g_assert (me->ink_bb_stack == NULL);
- g_assert (me->surfaces_stack == NULL);
-
-#ifdef HAVE_PANGOFT2
- if (me->font_config_for_testing) {
- FcConfigDestroy (me->font_config_for_testing);
- me->font_config_for_testing = NULL;
- }
-
- if (me->font_map_for_testing) {
- g_object_unref (me->font_map_for_testing);
- me->font_map_for_testing = NULL;
- }
-#endif
-
- g_free (me);
-}
-
RsvgCairoRender *
rsvg_cairo_render_new (cairo_t * cr, double width, double height)
{
RsvgCairoRender *cairo_render = g_new0 (RsvgCairoRender, 1);
cairo_matrix_t matrix;
- cairo_render->super.type = RSVG_RENDER_TYPE_CAIRO;
- cairo_render->super.free = rsvg_cairo_render_free;
cairo_render->width = width;
cairo_render->height = height;
cairo_render->offset_x = 0;
@@ -97,175 +70,25 @@ rsvg_cairo_render_new (cairo_t * cr, double width, double height)
return cairo_render;
}
-static void rsvg_cairo_transformed_image_bounding_box (
- cairo_matrix_t * transform,
- double width, double height,
- double *x0, double *y0, double *x1, double *y1)
+void
+rsvg_cairo_render_free (RsvgCairoRender *render)
{
- 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 (transform, &x00, &y00);
- cairo_matrix_transform_point (transform, &x01, &y01);
- cairo_matrix_transform_point (transform, &x10, &y10);
- cairo_matrix_transform_point (transform, &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_cairo_new_drawing_ctx (cairo_t * cr, RsvgHandle * handle)
-{
- RsvgDimensionData data;
- RsvgDrawingCtx *draw;
- RsvgCairoRender *render;
- 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);
-
- render = rsvg_cairo_render_new (cr, bbx1 - bbx0, bby1 - bby0);
-
- if (!render)
- return NULL;
-
- draw->render = (RsvgRender *) render;
- render->offset_x = bbx0;
- render->offset_y = bby0;
-
- draw->state = NULL;
+ g_assert (render->cr_stack == NULL);
+ g_assert (render->bb_stack == NULL);
+ g_assert (render->ink_bb_stack == NULL);
+ g_assert (render->surfaces_stack == 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->pango_context = NULL;
- 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 -= render->offset_x;
- state_affine.y0 -= render->offset_y;
-
- rsvg_bbox_init (&((RsvgCairoRender *) draw->render)->bbox, &state_affine);
- rsvg_bbox_init (&((RsvgCairoRender *) draw->render)->ink_bbox, &state_affine);
-
- rsvg_state_set_affine (state, state_affine);
-
- return draw;
-}
-
-/**
- * rsvg_handle_render_cairo_sub:
- * @handle: A #RsvgHandle
- * @cr: A Cairo renderer
- * @id: (nullable): An element's id within the SVG, or %NULL to render
- * the whole SVG. For example, if you have a layer called "layer1"
- * that you wish to render, pass "##layer1" as the id.
- *
- * Draws a subset of a SVG to a Cairo surface
- *
- * Returns: %TRUE if drawing succeeded.
- *
- * Since: 2.14
- */
-gboolean
-rsvg_handle_render_cairo_sub (RsvgHandle * handle, cairo_t * cr, const char *id)
-{
- RsvgDrawingCtx *draw;
- RsvgNode *drawsub = NULL;
-
- g_return_val_if_fail (handle != NULL, FALSE);
-
- if (handle->priv->hstate != RSVG_HANDLE_STATE_CLOSED_OK)
- return FALSE;
-
- if (id && *id)
- drawsub = rsvg_defs_lookup (handle->priv->defs, id);
-
- if (drawsub == NULL && id != NULL) {
- /* todo: there's no way to signal that @id doesn't exist */
- return FALSE;
+#ifdef HAVE_PANGOFT2
+ if (render->font_config_for_testing) {
+ FcConfigDestroy (render->font_config_for_testing);
+ render->font_config_for_testing = NULL;
}
- draw = rsvg_cairo_new_drawing_ctx (cr, handle);
- if (!draw)
- return FALSE;
-
- rsvg_drawing_ctx_add_node_and_ancestors_to_stack (draw, drawsub);
-
- cairo_save (cr);
-
- rsvg_drawing_ctx_draw_node_from_stack (draw, handle->priv->treebase, 0, FALSE);
-
- cairo_restore (cr);
-
- rsvg_drawing_ctx_free (draw);
-
- return TRUE;
-}
+ if (render->font_map_for_testing) {
+ g_object_unref (render->font_map_for_testing);
+ render->font_map_for_testing = NULL;
+ }
+#endif
-/**
- * rsvg_handle_render_cairo:
- * @handle: A #RsvgHandle
- * @cr: A Cairo renderer
- *
- * Draws a SVG to a Cairo surface
- *
- * Returns: %TRUE if drawing succeeded.
- * Since: 2.14
- */
-gboolean
-rsvg_handle_render_cairo (RsvgHandle * handle, cairo_t * cr)
-{
- return rsvg_handle_render_cairo_sub (handle, cr, NULL);
+ g_free (render);
}
diff --git a/librsvg/rsvg-cairo-render.h b/librsvg/rsvg-cairo-render.h
index a2365455..14402b32 100644
--- a/librsvg/rsvg-cairo-render.h
+++ b/librsvg/rsvg-cairo-render.h
@@ -35,10 +35,9 @@
#include <pango/pangofc-fontmap.h>
#endif
-G_BEGIN_DECLS typedef struct _RsvgCairoRender RsvgCairoRender;
+G_BEGIN_DECLS
struct _RsvgCairoRender {
- RsvgRender super;
cairo_t *cr;
double width;
double height;
@@ -69,13 +68,11 @@ struct _RsvgCairoRender {
#endif
};
-#define RSVG_CAIRO_RENDER(render) (_RSVG_RENDER_CIC ((render), RSVG_RENDER_TYPE_CAIRO, RsvgCairoRender))
-
G_GNUC_INTERNAL
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);
+void rsvg_cairo_render_free (RsvgCairoRender *render);
G_END_DECLS
diff --git a/librsvg/rsvg-handle.c b/librsvg/rsvg-handle.c
index 126fd505..da0af8b8 100644
--- a/librsvg/rsvg-handle.c
+++ b/librsvg/rsvg-handle.c
@@ -744,6 +744,72 @@ rsvg_handle_get_desc (RsvgHandle * handle)
return NULL;
}
+/**
+ * rsvg_handle_render_cairo_sub:
+ * @handle: A #RsvgHandle
+ * @cr: A Cairo renderer
+ * @id: (nullable): An element's id within the SVG, or %NULL to render
+ * the whole SVG. For example, if you have a layer called "layer1"
+ * that you wish to render, pass "##layer1" as the id.
+ *
+ * Draws a subset of a SVG to a Cairo surface
+ *
+ * Returns: %TRUE if drawing succeeded.
+ *
+ * Since: 2.14
+ */
+gboolean
+rsvg_handle_render_cairo_sub (RsvgHandle * handle, cairo_t * cr, const char *id)
+{
+ RsvgDrawingCtx *draw;
+ RsvgNode *drawsub = NULL;
+
+ g_return_val_if_fail (handle != NULL, FALSE);
+
+ if (handle->priv->hstate != RSVG_HANDLE_STATE_CLOSED_OK)
+ return FALSE;
+
+ if (id && *id)
+ drawsub = rsvg_defs_lookup (handle->priv->defs, id);
+
+ if (drawsub == NULL && id != NULL) {
+ /* todo: there's no way to signal that @id doesn't exist */
+ return FALSE;
+ }
+
+ draw = rsvg_drawing_ctx_new (cr, handle);
+ if (!draw)
+ return FALSE;
+
+ rsvg_drawing_ctx_add_node_and_ancestors_to_stack (draw, drawsub);
+
+ cairo_save (cr);
+
+ rsvg_drawing_ctx_draw_node_from_stack (draw, handle->priv->treebase, 0, FALSE);
+
+ cairo_restore (cr);
+
+ rsvg_drawing_ctx_free (draw);
+
+ return TRUE;
+}
+
+/**
+ * rsvg_handle_render_cairo:
+ * @handle: A #RsvgHandle
+ * @cr: A Cairo renderer
+ *
+ * Draws a SVG to a Cairo surface
+ *
+ * Returns: %TRUE if drawing succeeded.
+ * Since: 2.14
+ */
+gboolean
+rsvg_handle_render_cairo (RsvgHandle * handle, cairo_t * cr)
+{
+ return rsvg_handle_render_cairo_sub (handle, cr, NULL);
+}
+
/**
* rsvg_handle_get_dimensions:
* @handle: A #RsvgHandle
@@ -835,7 +901,7 @@ rsvg_handle_get_dimensions_sub (RsvgHandle * handle, RsvgDimensionData * dimensi
1, 1);
cr = cairo_create (target);
- draw = rsvg_cairo_new_drawing_ctx (cr, handle);
+ draw = rsvg_drawing_ctx_new (cr, handle);
if (!draw) {
cairo_destroy (cr);
@@ -848,7 +914,7 @@ rsvg_handle_get_dimensions_sub (RsvgHandle * handle, RsvgDimensionData * dimensi
rsvg_drawing_ctx_add_node_and_ancestors_to_stack (draw, sself);
rsvg_drawing_ctx_draw_node_from_stack (draw, handle->priv->treebase, 0, FALSE);
- ink_bbox = RSVG_CAIRO_RENDER (draw->render)->ink_bbox;
+ ink_bbox = draw->render->ink_bbox;
rsvg_drawing_ctx_free (draw);
cairo_destroy (cr);
@@ -927,7 +993,7 @@ rsvg_handle_get_position_sub (RsvgHandle * handle, RsvgPositionData * position_d
target = cairo_image_surface_create (CAIRO_FORMAT_RGB24, 1, 1);
cr = cairo_create (target);
- draw = rsvg_cairo_new_drawing_ctx (cr, handle);
+ draw = rsvg_drawing_ctx_new (cr, handle);
if (!draw)
goto bail;
@@ -935,7 +1001,7 @@ rsvg_handle_get_position_sub (RsvgHandle * handle, RsvgPositionData * position_d
rsvg_drawing_ctx_add_node_and_ancestors_to_stack (draw, node);
rsvg_drawing_ctx_draw_node_from_stack (draw, handle->priv->treebase, 0, FALSE);
- ink_bbox = RSVG_CAIRO_RENDER (draw->render)->ink_bbox;
+ ink_bbox = draw->render->ink_bbox;
rsvg_drawing_ctx_free (draw);
diff --git a/librsvg/rsvg-private.h b/librsvg/rsvg-private.h
index 9c51e546..42d04665 100644
--- a/librsvg/rsvg-private.h
+++ b/librsvg/rsvg-private.h
@@ -46,8 +46,8 @@
G_BEGIN_DECLS
typedef struct RsvgSaxHandler RsvgSaxHandler;
+typedef struct _RsvgCairoRender RsvgCairoRender;
typedef struct RsvgDrawingCtx RsvgDrawingCtx;
-typedef struct RsvgRender RsvgRender;
typedef void *RsvgPropertyBag;
typedef struct _RsvgState RsvgState;
typedef struct _RsvgDefs RsvgDefs;
@@ -169,7 +169,7 @@ typedef struct {
/*Contextual information for the drawing phase*/
struct RsvgDrawingCtx {
- RsvgRender *render;
+ RsvgCairoRender *render;
RsvgState *state;
GError **error;
RsvgDefs *defs;
@@ -189,34 +189,6 @@ typedef struct {
gboolean virgin;
} RsvgBbox;
-/*Abstract base class for context for our backends (one as yet)*/
-
-typedef enum {
- RSVG_RENDER_TYPE_INVALID,
-
- RSVG_RENDER_TYPE_BASE,
-
- RSVG_RENDER_TYPE_CAIRO = 8,
- RSVG_RENDER_TYPE_CAIRO_CLIP
-} RsvgRenderType;
-
-struct RsvgRender {
- RsvgRenderType type;
-
- void (*free) (RsvgRender * self);
-};
-
-static inline RsvgRender *
-_rsvg_render_check_type (RsvgRender *render,
- RsvgRenderType type)
-{
- g_assert ((render->type & type) == type);
- return render;
-}
-
-#define _RSVG_RENDER_CIC(render, render_type, RenderCType) \
- ((RenderCType*) _rsvg_render_check_type ((render), (render_type)))
-
/* Keep this in sync with rust/src/length.rs:LengthUnit */
typedef enum {
LENGTH_UNIT_DEFAULT,
@@ -444,6 +416,12 @@ 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
@@ -470,9 +448,6 @@ void rsvg_drawing_ctx_draw_node_from_stack (RsvgDrawingCtx *ctx,
int dominate,
gboolean clipping);
-G_GNUC_INTERNAL
-void rsvg_render_free (RsvgRender * render);
-
G_GNUC_INTERNAL
cairo_surface_t *rsvg_cairo_surface_from_pixbuf (const GdkPixbuf *pixbuf);
G_GNUC_INTERNAL
@@ -487,9 +462,6 @@ void rsvg_drawing_ctx_insert_ink_bbox (RsvgDrawingCtx *draw_ctx, RsvgBbox *ink_b
G_GNUC_INTERNAL
cairo_surface_t *rsvg_cairo_surface_new_from_href (RsvgHandle *handle, const char *href, GError ** error);
-G_GNUC_INTERNAL
-void rsvg_drawing_ctx_free (RsvgDrawingCtx * handle);
-
/* Implemented in rust/src/bbox.rs */
G_GNUC_INTERNAL
void rsvg_bbox_init (RsvgBbox * self, cairo_matrix_t *matrix);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]