Commit bf196bdc authored by Bertram Felgenhauer's avatar Bertram Felgenhauer Committed by Dom Lachowicz

Bug 500787 - translation gets ignored when rendering an svg with cairo in

2008-01-19  Bertram Felgenhauer <bertram.felgenhauer@googlemail.com>

	* Bug 500787 - translation gets ignored when rendering an svg 
with cairo in the context of a cairo_push_group()


svn path=/trunk/; revision=1139
parent d9378cff
2008-01-19 Bertram Felgenhauer <bertram.felgenhauer@googlemail.com>
* Bug 500787 - translation gets ignored when rendering an svg with cairo in the context of a cairo_push_group()
2007-11-27 Dom Lachowicz <domlachowicz@gmail.com>
* rsvg-base.c: 499386 - rsvg_handle_close leads to segfault
......
......@@ -41,18 +41,21 @@ typedef struct RsvgCairoClipRender RsvgCairoClipRender;
struct RsvgCairoClipRender {
RsvgRender super;
cairo_t *cr;
RsvgCairoRender *parent;
};
static void
rsvg_cairo_clip_apply_affine (cairo_t *cr, const double affine[6])
rsvg_cairo_clip_apply_affine (RsvgCairoClipRender *render, const double affine[6])
{
cairo_matrix_t matrix;
gboolean nest = render->cr != render->parent->initial_cr;
cairo_matrix_init (&matrix,
affine[0], affine[1],
affine[2], affine[3],
affine[4], affine[5]);
cairo_set_matrix (cr, &matrix);
affine[4] + (nest ? 0 : render->parent->offset_x),
affine[5] + (nest ? 0 : render->parent->offset_y));
cairo_set_matrix (render->cr, &matrix);
}
static void
......@@ -62,14 +65,11 @@ rsvg_cairo_clip_render_path (RsvgDrawingCtx * ctx, const RsvgBpathDef * bpath_de
RsvgState *state = rsvg_state_current (ctx);
cairo_t *cr;
RsvgBpath *bpath;
cairo_matrix_t save;
int i;
cr = render->cr;
cairo_get_matrix (cr, &save);
rsvg_cairo_clip_apply_affine (cr, state->affine);
rsvg_cairo_clip_apply_affine (render, state->affine);
if (rsvg_state_current (ctx)->clip_rule == FILL_RULE_EVENODD)
cairo_set_fill_rule (((RsvgCairoRender *) ctx->render)->cr, CAIRO_FILL_RULE_EVEN_ODD);
......@@ -96,7 +96,6 @@ rsvg_cairo_clip_render_path (RsvgDrawingCtx * ctx, const RsvgBpathDef * bpath_de
break;
}
}
cairo_set_matrix (cr, &save);
}
static void
......@@ -130,7 +129,7 @@ rsvg_cairo_clip_add_clipping_rect (RsvgDrawingCtx * ctx, double x, double y, dou
}
static RsvgRender *
rsvg_cairo_clip_render_new (cairo_t * cr)
rsvg_cairo_clip_render_new (cairo_t * cr, RsvgCairoRender *parent)
{
RsvgCairoClipRender *cairo_render = g_new0 (RsvgCairoClipRender, 1);
......@@ -142,6 +141,7 @@ rsvg_cairo_clip_render_new (cairo_t * cr)
cairo_render->super.add_clipping_rect = rsvg_cairo_clip_add_clipping_rect;
cairo_render->super.get_image_of_node = NULL;
cairo_render->cr = cr;
cairo_render->parent = parent;
return &cairo_render->super;
}
......@@ -152,7 +152,7 @@ rsvg_cairo_clip (RsvgDrawingCtx * ctx, RsvgClipPath * clip, RsvgBbox * bbox)
RsvgCairoRender *save = (RsvgCairoRender *) ctx->render;
double affinesave[6];
int i;
ctx->render = rsvg_cairo_clip_render_new (save->cr);
ctx->render = rsvg_cairo_clip_render_new (save->cr, save);
/* Horribly dirty hack to have the bbox premultiplied to everything */
if (clip->units == objectBoundingBox) {
......
......@@ -417,6 +417,7 @@ _set_source_rsvg_pattern (RsvgDrawingCtx * ctx,
_rsvg_pop_view_box (ctx);
}
/* note: _set_source_rsvg_paint_server does not change cairo's CTM */
static void
_set_source_rsvg_paint_server (RsvgDrawingCtx * ctx,
guint32 current_color_rgb,
......@@ -440,14 +441,17 @@ _set_source_rsvg_paint_server (RsvgDrawingCtx * ctx,
}
static void
_set_rsvg_affine (cairo_t * cr, const double affine[6])
_set_rsvg_affine (RsvgCairoRender * render, const double affine[6])
{
cairo_t * cr = render->cr;
cairo_matrix_t matrix;
gboolean nest = cr != render->initial_cr;
cairo_matrix_init (&matrix,
affine[0], affine[1],
affine[2], affine[3],
affine[4], affine[5]);
affine[4] + (nest ? 0 : render->offset_x),
affine[5] + (nest ? 0 : render->offset_y));
cairo_set_matrix (cr, &matrix);
}
......@@ -471,11 +475,9 @@ rsvg_cairo_render_pango_layout (RsvgDrawingCtx * ctx, PangoLayout * layout, doub
PangoRectangle logical;
RsvgBbox bbox;
cairo_save (render->cr);
_rsvg_cairo_set_text_antialias (render->cr, state->text_rendering_type);
_set_rsvg_affine (render->cr, state->affine);
_set_rsvg_affine (render, state->affine);
cairo_set_line_width (render->cr, _rsvg_css_normalize_length (&state->stroke_width, ctx, 'h'));
pango_cairo_update_layout (render->cr, layout);
......@@ -513,8 +515,6 @@ rsvg_cairo_render_pango_layout (RsvgDrawingCtx * ctx, PangoLayout * layout, doub
bbox, rsvg_state_current (ctx)->current_color);
cairo_stroke (render->cr);
}
cairo_restore (render->cr);
}
void
......@@ -540,11 +540,9 @@ rsvg_cairo_render_path (RsvgDrawingCtx * ctx, const RsvgBpathDef * bpath_def)
cr = render->cr;
cairo_save (cr);
_rsvg_cairo_set_shape_antialias (cr, state->shape_rendering_type);
_set_rsvg_affine (cr, state->affine);
_set_rsvg_affine (render, state->affine);
cairo_set_line_width (cr, _rsvg_css_normalize_length (&state->stroke_width, ctx, 'h'));
cairo_set_miter_limit (cr, state->miter_limit);
......@@ -634,7 +632,6 @@ rsvg_cairo_render_path (RsvgDrawingCtx * ctx, const RsvgBpathDef * bpath_def)
cairo_stroke (cr);
}
cairo_restore (cr);
if (need_tmpbuf)
rsvg_cairo_pop_discrete_layer (ctx);
......@@ -670,8 +667,7 @@ rsvg_cairo_render_image (RsvgDrawingCtx * ctx, const GdkPixbuf * pixbuf,
bbox.h = h;
bbox.virgin = 0;
cairo_save (render->cr);
_set_rsvg_affine (render->cr, state->affine);
_set_rsvg_affine (render, state->affine);
cairo_scale (render->cr, w / dwidth, h / dheight);
pixbuf_x *= dwidth / w;
pixbuf_y *= dheight / h;
......@@ -763,8 +759,6 @@ rsvg_cairo_render_image (RsvgDrawingCtx * ctx, const GdkPixbuf * pixbuf,
cairo_surface_destroy (surface);
rsvg_bbox_insert (&render->bbox, &bbox);
cairo_restore (render->cr);
}
static void
......@@ -779,6 +773,7 @@ rsvg_cairo_generate_mask (cairo_t * cr, RsvgMask * self, RsvgDrawingCtx * ctx, R
guint32 rowstride = width * 4, row, i;
double affinesave[6];
double sx, sy, sw, sh;
gboolean nest = cr != render->initial_cr;
if (self->maskunits == objectBoundingBox)
_rsvg_push_view_box (ctx, 1, 1);
......@@ -845,7 +840,10 @@ rsvg_cairo_generate_mask (cairo_t * cr, RsvgMask * self, RsvgDrawingCtx * ctx, R
cairo_destroy (mask_cr);
cairo_mask_surface (cr, surface, 0, 0);
cairo_identity_matrix (cr);
cairo_mask_surface (cr, surface,
nest ? 0 : render->offset_x,
nest ? 0 : render->offset_y);
cairo_surface_destroy (surface);
g_free (pixels);
}
......@@ -948,9 +946,11 @@ rsvg_compile_bg (RsvgDrawingCtx * ctx)
cairo_surface_destroy (surface);
for (i = g_list_last (render->cr_stack); i != NULL; i = g_list_previous (i)) {
cairo_t *draw;
draw = i->data;
cairo_set_source_surface (cr, cairo_get_target (draw), 0, 0);
cairo_t *draw = i->data;
gboolean nest = draw != render->initial_cr;
cairo_set_source_surface (cr, cairo_get_target (draw),
nest ? 0 : -render->offset_x,
nest ? 0 : -render->offset_y);
cairo_paint (cr);
}
......@@ -967,6 +967,7 @@ rsvg_cairo_pop_render_stack (RsvgDrawingCtx * ctx)
GdkPixbuf *output = NULL;
cairo_surface_t *surface = NULL;
RsvgState *state = rsvg_state_current (ctx);
gboolean nest;
if (rsvg_state_current (ctx)->clip_path_ref)
if (((RsvgClipPath *) rsvg_state_current (ctx)->clip_path_ref)->units == objectBoundingBox)
......@@ -999,7 +1000,11 @@ rsvg_cairo_pop_render_stack (RsvgDrawingCtx * ctx)
render->cr = (cairo_t *) render->cr_stack->data;
render->cr_stack = g_list_delete_link (render->cr_stack, render->cr_stack);
cairo_set_source_surface (render->cr, surface, 0, 0);
nest = render->cr != render->initial_cr;
cairo_identity_matrix (render->cr);
cairo_set_source_surface (render->cr, surface,
nest ? 0 : render->offset_x,
nest ? 0 : render->offset_y);
if (lateclip)
rsvg_cairo_clip (ctx, rsvg_state_current (ctx)->clip_path_ref, &render->bbox);
......@@ -1040,15 +1045,11 @@ rsvg_cairo_add_clipping_rect (RsvgDrawingCtx * ctx, double x, double y, double w
{
RsvgCairoRender *render = (RsvgCairoRender *) ctx->render;
cairo_t *cr = render->cr;
cairo_matrix_t save;
cairo_get_matrix (cr, &save);
_set_rsvg_affine (cr, rsvg_state_current (ctx)->affine);
_set_rsvg_affine (render, rsvg_state_current (ctx)->affine);
cairo_rectangle (cr, x, y, w, h);
cairo_clip (cr);
cairo_set_matrix (cr, &save);
}
GdkPixbuf *
......
......@@ -65,6 +65,7 @@ rsvg_cairo_render_new (cairo_t * cr, double width, double height)
cairo_render->height = height;
cairo_render->offset_x = 0;
cairo_render->offset_y = 0;
cairo_render->initial_cr = cr;
cairo_render->cr = cr;
cairo_render->cr_stack = NULL;
cairo_render->bb_stack = NULL;
......@@ -176,8 +177,8 @@ rsvg_cairo_new_drawing_ctx (cairo_t * cr, RsvgHandle * handle)
_rsvg_affine_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 rsvg_handle_render_cairo_sub()
* below */
* at (0,0) - we compensate for this in _set_rsvg_affine() in
* rsvg-cairo-render.c and a few other places */
state->affine[4] -= render->offset_x;
state->affine[5] -= render->offset_y;
......@@ -203,9 +204,6 @@ rsvg_handle_render_cairo_sub (RsvgHandle * handle, cairo_t * cr, const char *id)
{
RsvgDrawingCtx *draw;
RsvgNode *drawsub = NULL;
RsvgCairoRender *render;
cairo_surface_t *surface = cairo_get_target (cr);
double save_dx, save_dy;
g_return_if_fail (handle != NULL);
......@@ -226,20 +224,9 @@ rsvg_handle_render_cairo_sub (RsvgHandle * handle, cairo_t * cr, const char *id)
rsvg_state_push (draw);
cairo_save (cr);
cairo_identity_matrix (cr);
/* adjust the underlying surface's device offset such that the
* bounding box from rsvg_cairo_new_drawing_ctx is placed correctly */
cairo_surface_get_device_offset (surface, &save_dx, &save_dy);
render = (RsvgCairoRender *) draw->render;
cairo_surface_set_device_offset (surface,
save_dx + render->offset_x,
save_dy + render->offset_y);
rsvg_node_draw ((RsvgNode *) handle->priv->treebase, draw, 0);
cairo_surface_set_device_offset (surface, save_dx, save_dy);
cairo_restore (cr);
rsvg_state_pop (draw);
rsvg_drawing_ctx_free (draw);
......
......@@ -37,6 +37,8 @@ struct _RsvgCairoRender {
cairo_t *cr;
double width;
double height;
cairo_t *initial_cr;
double offset_x;
double offset_y;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment