Commit d90ab322 authored by Caleb Michael Moore's avatar Caleb Michael Moore

moved libart crap out of RsvgState

parent a3786dac
......@@ -3,6 +3,10 @@
* rsvg-paint-server.c: modified to allow patterns to be rendered on a
pixbuf of the exact nessisary size. Not Cairo based I know, but it
needed to be done.
* rsvg-styles.c: moved pretty much all libart dependant stuff out of RsvgState
* rsvg-private.c: created a new function in RsvgRender: add_clipping_rect
which basically sets up a clipping viewport
* rsvg-art-composite.c: broke clip paths in a hardcore way
2005-2-16 Caleb Moore <c.moore@student.unsw.edu.au>
......
......@@ -46,6 +46,17 @@ rsvg_pixmap_destroy (gchar *pixels, gpointer data)
g_free (pixels);
}
typedef struct _RsvgArtDiscreteLayer RsvgArtDiscreteLayer;
struct _RsvgArtDiscreteLayer
{
GdkPixbuf *save_pixbuf;
ArtIRect underbbox;
RsvgState * state;
ArtSVP * clippath_save;
gboolean clippath_loaded;
};
void
rsvg_art_push_discrete_layer (RsvgDrawingCtx *ctx)
{
......@@ -54,51 +65,68 @@ rsvg_art_push_discrete_layer (RsvgDrawingCtx *ctx)
RsvgArtRender *render = (RsvgArtRender *)ctx->render;
art_u8 *pixels;
int width, height, rowstride;
RsvgArtDiscreteLayer * layer;
state = rsvg_state_current(ctx);
pixbuf = render->pixbuf;
rsvg_state_clip_path_assure(ctx);
layer = g_new(RsvgArtDiscreteLayer, 1);
render->layers = g_slist_prepend(render->layers, layer);
layer->state = state;
layer->save_pixbuf = NULL;
if (state->filter == NULL && state->opacity == 0xFF &&
!state->backgroundnew && state->mask == NULL && !state->adobe_blend)
return;
state->save_pixbuf = pixbuf;
state->underbbox = ctx->bbox;
ctx->bbox.x0 = 0;
ctx->bbox.x1 = 0;
ctx->bbox.y0 = 0;
ctx->bbox.y1 = 0;
if (pixbuf == NULL)
if (state->filter != NULL || state->opacity != 0xFF ||
state->backgroundnew || state->mask != NULL || state->adobe_blend)
{
/* FIXME: What warning/GError here? */
return;
layer->save_pixbuf = pixbuf;
layer->underbbox = render->bbox;
render->bbox.x0 = 0;
render->bbox.x1 = 0;
render->bbox.y0 = 0;
render->bbox.y1 = 0;
if (pixbuf == NULL)
{
/* FIXME: What warning/GError here? */
return;
}
width = gdk_pixbuf_get_width (pixbuf);
height = gdk_pixbuf_get_height (pixbuf);
rowstride = gdk_pixbuf_get_rowstride (pixbuf);
pixels = g_new (art_u8, rowstride * height);
memset (pixels, 0, rowstride * height);
pixbuf = gdk_pixbuf_new_from_data (pixels,
GDK_COLORSPACE_RGB,
TRUE,
gdk_pixbuf_get_bits_per_sample (pixbuf),
width,
height,
rowstride,
(GdkPixbufDestroyNotify)rsvg_pixmap_destroy,
NULL);
render->pixbuf = pixbuf;
}
if (!gdk_pixbuf_get_has_alpha (pixbuf))
{
g_warning (_("push/pop transparency group on non-alpha buffer nyi\n"));
return;
}
width = gdk_pixbuf_get_width (pixbuf);
height = gdk_pixbuf_get_height (pixbuf);
rowstride = gdk_pixbuf_get_rowstride (pixbuf);
pixels = g_new (art_u8, rowstride * height);
memset (pixels, 0, rowstride * height);
pixbuf = gdk_pixbuf_new_from_data (pixels,
GDK_COLORSPACE_RGB,
TRUE,
gdk_pixbuf_get_bits_per_sample (pixbuf),
width,
height,
rowstride,
(GdkPixbufDestroyNotify)rsvg_pixmap_destroy,
NULL);
render->pixbuf = pixbuf;
if (state->clip_path_ref)
{
ArtSVP * tmppath;
rsvg_state_push(ctx);
tmppath = rsvg_clip_path_render (state->clip_path_ref, ctx);
rsvg_state_pop(ctx);
render->clippath = rsvg_clip_path_merge(render->clippath, tmppath, 'i');
layer->clippath_loaded = TRUE;
layer->clippath_save = render->clippath;
}
else
{
layer->clippath_save = render->clippath;
layer->clippath_loaded = FALSE;
}
}
static void
......@@ -111,6 +139,7 @@ rsvg_use_opacity (RsvgDrawingCtx *ctx, int opacity,
int rowstride;
int x, y;
int tmp;
RsvgArtRender *render = (RsvgArtRender *)ctx->render;
if (tos == NULL || nos == NULL)
......@@ -132,12 +161,12 @@ rsvg_use_opacity (RsvgDrawingCtx *ctx, int opacity,
tos_pixels = gdk_pixbuf_get_pixels (tos);
nos_pixels = gdk_pixbuf_get_pixels (nos);
tos_pixels += rowstride * MAX(ctx->bbox.y0, 0);
nos_pixels += rowstride * MAX(ctx->bbox.y0, 0);
tos_pixels += rowstride * MAX(render->bbox.y0, 0);
nos_pixels += rowstride * MAX(render->bbox.y0, 0);
for (y = MAX(ctx->bbox.y0, 0); y < MIN(ctx->bbox.y1 + 1, height); y++)
for (y = MAX(render->bbox.y0, 0); y < MIN(render->bbox.y1 + 1, height); y++)
{
for (x = MAX(ctx->bbox.x0, 0); x < MIN(ctx->bbox.x1 + 1, width); x++)
for (x = MAX(render->bbox.x0, 0); x < MIN(render->bbox.x1 + 1, width); x++)
{
art_u8 r, g, b, a;
a = tos_pixels[4 * x + 3];
......@@ -180,34 +209,35 @@ get_next_out(gint * operationsleft, GdkPixbuf * in, GdkPixbuf * tos,
static GdkPixbuf *
rsvg_compile_bg(RsvgDrawingCtx *ctx, RsvgState *topstate)
{
RsvgArtRender *render = (RsvgArtRender *)ctx->render;
int i, foundstate;
GdkPixbuf *intermediate, *lastintermediate;
RsvgState *state, *lastvalid;
RsvgArtDiscreteLayer *state, *lastvalid;
ArtIRect save;
lastvalid = NULL;
RsvgArtRender *render = (RsvgArtRender *)ctx->render;
foundstate = 0;
lastintermediate = gdk_pixbuf_copy(topstate->save_pixbuf);
lastvalid = render->layers->data;
lastintermediate = gdk_pixbuf_copy(lastvalid->save_pixbuf);
lastvalid = NULL;
save = ctx->bbox;
save = render->bbox;
ctx->bbox.x0 = 0;
ctx->bbox.y0 = 0;
ctx->bbox.x1 = gdk_pixbuf_get_width(render->pixbuf);
ctx->bbox.y1 = gdk_pixbuf_get_height(render->pixbuf);
render->bbox.x0 = 0;
render->bbox.y0 = 0;
render->bbox.x1 = gdk_pixbuf_get_width(render->pixbuf);
render->bbox.y1 = gdk_pixbuf_get_height(render->pixbuf);
for (i = 0; (state = g_slist_nth_data(ctx->state, i)) != NULL; i++)
for (i = 0; (state = g_slist_nth_data(render->layers, i)) != NULL; i++)
{
if (state == topstate)
if (state->state == topstate)
{
foundstate = 1;
}
else if (!foundstate)
continue;
if (state->backgroundnew)
if (state->state->backgroundnew)
break;
if (state->save_pixbuf)
{
......@@ -222,7 +252,7 @@ rsvg_compile_bg(RsvgDrawingCtx *ctx, RsvgState *topstate)
}
}
ctx->bbox = save;
render->bbox = save;
return lastintermediate;
}
......@@ -318,22 +348,33 @@ rsvg_art_pop_discrete_layer(RsvgDrawingCtx *ctx)
GdkPixbuf *tos, *nos;
RsvgState *state;
RsvgArtRender *render = (RsvgArtRender *)ctx->render;
GSList * link;
RsvgArtDiscreteLayer * layer;
state = rsvg_state_current(ctx);
if (state->filter == NULL && state->opacity == 0xFF &&
!state->backgroundnew && state->mask == NULL && !state->adobe_blend)
return;
link = g_slist_nth(render->layers, 0);
layer = link->data;
tos = render->pixbuf;
nos = state->save_pixbuf;
if (nos != NULL)
rsvg_composite_layer(ctx, state, tos, nos);
g_object_unref (tos);
render->pixbuf = nos;
art_irect_union(&ctx->bbox, &ctx->bbox, &state->underbbox);
if (layer->save_pixbuf)
{
tos = render->pixbuf;
nos = layer->save_pixbuf;
if (nos != NULL)
rsvg_composite_layer(ctx, state, tos, nos);
g_object_unref (tos);
render->pixbuf = nos;
art_irect_union(&render->bbox, &render->bbox, &layer->underbbox);
}
if (layer->clippath_loaded)
{
art_free(render->clippath);
}
render->clippath = layer->clippath_save;
g_free (layer);
render->layers = g_slist_delete_link(render->layers, link);
}
gboolean
......@@ -573,3 +614,15 @@ rsvg_art_clip_image(GdkPixbuf *intermediate, ArtSVP *path)
basepix[i * 3 + j * basestride] / 255;
}
}
void
rsvg_art_add_clipping_rect(RsvgDrawingCtx *ctx, double x, double y, double w, double h)
{
ArtSVP * temppath;
RsvgArtRender * render = (RsvgArtRender *)ctx->render;
RsvgArtDiscreteLayer * data = g_slist_nth(render->layers, 0)->data;
temppath = rsvg_rect_clip_path(x, y, w, h, ctx);
data->clippath_loaded = TRUE;
render->clippath = rsvg_clip_path_merge(render->clippath, temppath, 'i');
}
......@@ -31,6 +31,7 @@
#define RSVG_ART_COMPOSITE_H
#include "rsvg-private.h"
#include <libart_lgpl/art_svp.h>
G_BEGIN_DECLS
......@@ -44,7 +45,7 @@ void rsvg_art_alpha_blt (GdkPixbuf * src, gint srcx, gint srcy,
void rsvg_art_clip_image (GdkPixbuf *intermediate, ArtSVP *path);
void rsvg_art_affine_image(GdkPixbuf *img, GdkPixbuf *intermediate,
double * affine, double w, double h);
void rsvg_art_add_clipping_rect(RsvgDrawingCtx *ctx, double x, double y, double w, double h);
G_END_DECLS
#endif
......@@ -209,6 +209,7 @@ rsvg_render_svp (RsvgDrawingCtx *ctx, ArtSVP *svp,
{
GdkPixbuf *pixbuf;
ArtRender *render;
RsvgArtRender *arender = (RsvgArtRender *)ctx->render;
gboolean has_alpha;
RsvgFRect temprect;
ArtIRect temptemprect;
......@@ -216,8 +217,6 @@ rsvg_render_svp (RsvgDrawingCtx *ctx, ArtSVP *svp,
RsvgState *state;
int i;
rsvg_state_clip_path_assure(ctx);
pixbuf = ((RsvgArtRender *)ctx->render)->pixbuf;
if (pixbuf == NULL)
{
......@@ -242,18 +241,18 @@ rsvg_render_svp (RsvgDrawingCtx *ctx, ArtSVP *svp,
temprect = rsvg_calculate_svp_bounds(svp, state->affine);
if (state->clippath != NULL)
if (arender->clippath != NULL)
{
ArtSVP * svpx;
svpx = art_svp_intersect(svp, state->clippath);
svp = svpx;
svpx = art_svp_intersect(svp, arender->clippath);
svp = svpx;
}
art_render_svp (render, svp);
art_render_mask_solid (render, (opacity << 8) + opacity + (opacity >> 7));
temptemprect = rsvg_frect_pixelspaceise(temprect, state->affine);
art_irect_union(&ctx->bbox, &ctx->bbox, &temptemprect);
art_irect_union(&arender->bbox, &arender->bbox, &temptemprect);
gradctx.x0 = temprect.x0;
gradctx.y0 = temprect.y0;
......@@ -268,7 +267,7 @@ rsvg_render_svp (RsvgDrawingCtx *ctx, ArtSVP *svp,
rsvg_render_paint_server (render, ps, &gradctx);
art_render_invoke (render);
if (state->clippath != NULL) /*we don't need svpx any more*/
if (arender->clippath != NULL) /*we don't need svpx any more*/
art_free(svp);
}
......@@ -546,6 +545,7 @@ void rsvg_art_render_image (RsvgDrawingCtx *ctx, GdkPixbuf * img,
double tmp_tmp_affine[6];
RsvgState *state = rsvg_state_current(ctx);
GdkPixbuf *intermediate;
RsvgArtRender *arender = (RsvgArtRender *)ctx->render;
double basex, basey;
ArtIRect temprect;
/*this will have to change*/
......@@ -568,9 +568,9 @@ void rsvg_art_render_image (RsvgDrawingCtx *ctx, GdkPixbuf * img,
rsvg_art_affine_image(img, intermediate, tmp_affine, w, h);
if (state->clippath)
if (arender->clippath)
{
rsvg_art_clip_image(intermediate, state->clippath);
rsvg_art_clip_image(intermediate, arender->clippath);
}
/*slap it down*/
......@@ -596,7 +596,7 @@ void rsvg_art_render_image (RsvgDrawingCtx *ctx, GdkPixbuf * img,
temprect.y1 = MAX(basey, temprect.y1);
}
art_irect_union(&ctx->bbox, &ctx->bbox, &temprect);
art_irect_union(&arender->bbox, &arender->bbox, &temprect);
g_object_unref (G_OBJECT (intermediate));
}
......@@ -35,9 +35,12 @@ RsvgArtRender * rsvg_art_render_new(GdkPixbuf * pb)
output->super.render_image = rsvg_art_render_image;
output->super.pop_discrete_layer = rsvg_art_pop_discrete_layer;
output->super.push_discrete_layer = rsvg_art_push_discrete_layer;
output->super.add_clipping_rect = rsvg_art_add_clipping_rect;
output->bbox.x0 = output->bbox.y0 = output->bbox.x1 = output->bbox.y1 = 0;
output->pixbuf = pb;
output->layers = NULL;
output->clippath = NULL;
return output;
}
......@@ -50,6 +53,10 @@ image_bogus(RsvgDrawingCtx *ctx, GdkPixbuf *pb,
double x, double y, double w, double h)
{
}
static void
cr_bogus(RsvgDrawingCtx *ctx, double x, double y, double w, double h)
{
}
RsvgArtSVPRender * rsvg_art_svp_render_new()
......@@ -61,6 +68,7 @@ RsvgArtSVPRender * rsvg_art_svp_render_new()
output->super.render_image = image_bogus;
output->super.pop_discrete_layer = bogus;
output->super.push_discrete_layer = bogus;
output->super.add_clipping_rect = cr_bogus;
output->outline = NULL;
return output;
......
......@@ -26,6 +26,8 @@
#define RSVG_ART_RENDER_H
#include "rsvg-private.h"
#include <libart_lgpl/art_rect.h>
#include <libart_lgpl/art_svp.h>
G_BEGIN_DECLS
......@@ -36,6 +38,8 @@ struct RsvgArtRender {
RsvgRender super;
GdkPixbuf *pixbuf;
GSList * layers;
ArtIRect bbox;
ArtSVP * clippath;
};
struct RsvgArtSVPRender {
......
......@@ -31,6 +31,7 @@
#include <glib/ghash.h>
#include <glib/gmem.h>
#include <glib/gslist.h>
#include <glib/gstrfuncs.h>
#include <glib/gmessages.h>
......@@ -39,6 +40,15 @@ struct _RsvgDefs {
GPtrArray *unnamed;
GHashTable *externs;
gchar * base_uri;
GSList * toresolve;
};
typedef struct _RsvgResolutionPending RsvgResolutionPending;
struct _RsvgResolutionPending
{
RsvgDefVal ** tochange;
GString * name;
};
RsvgDefs *
......@@ -50,6 +60,7 @@ rsvg_defs_new (void)
result->externs = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
result->unnamed = g_ptr_array_new ();
result->base_uri = NULL;
result->toresolve = NULL;
return result;
}
......@@ -152,3 +163,29 @@ rsvg_defs_free (RsvgDefs *defs)
g_free (defs);
}
void
rsvg_defs_add_resolver(RsvgDefs *defs, RsvgDefVal ** tochange,
const gchar * name)
{
RsvgResolutionPending * data;
data = g_new(RsvgResolutionPending, 1);
data->tochange = tochange;
data->name = g_string_new(name);
defs->toresolve = g_slist_prepend(defs->toresolve, data);
}
void
rsvg_defs_resolve_all(RsvgDefs *defs)
{
while (defs->toresolve)
{
RsvgResolutionPending * data;
data = defs->toresolve->data;
*(data->tochange) = rsvg_defs_lookup (defs, data->name->str);
g_free(data);
defs->toresolve = g_slist_delete_link(defs->toresolve,
defs->toresolve);
}
}
......@@ -68,6 +68,13 @@ rsvg_defs_free (RsvgDefs *defs);
void
rsvg_defs_set_base_uri (RsvgDefs * self, gchar * base_uri);
void
rsvg_defs_add_resolver(RsvgDefs *defs, RsvgDefVal ** tochange,
const gchar * name);
void
rsvg_defs_resolve_all(RsvgDefs *defs);
G_END_DECLS
#endif
......@@ -236,16 +236,17 @@ rsvg_filter_fix_coordinate_system (RsvgFilterContext * ctx, RsvgState * state)
int i;
guchar *pixels;
int stride;
ArtIRect bbox = ((RsvgArtRender *)ctx->ctx->render)->bbox;
/* First for object bounding box coordinates we need to know how much of the
source has been drawn on */
pixels = gdk_pixbuf_get_pixels (ctx->source);
stride = gdk_pixbuf_get_rowstride (ctx->source);
x = ctx->ctx->bbox.x0;
y = ctx->ctx->bbox.y0;
width = ctx->ctx->bbox.x1 - ctx->ctx->bbox.x0;
height = ctx->ctx->bbox.y1 - ctx->ctx->bbox.y0;
x = bbox.x0;
y = bbox.y0;
width = bbox.x1 - bbox.x0;
height = bbox.y1 -bbox.y0;
ctx->width = gdk_pixbuf_get_width (ctx->source);
ctx->height = gdk_pixbuf_get_height (ctx->source);
......@@ -306,6 +307,7 @@ rsvg_filter_render (RsvgFilter * self, GdkPixbuf * source, GdkPixbuf * output,
GdkPixbuf * bg, RsvgDrawingCtx * context)
{
RsvgFilterContext *ctx;
RsvgArtRender * render = ((RsvgArtRender *)context->render);
RsvgFilterPrimitive *current;
guint i;
FPBox bounds;
......@@ -338,15 +340,15 @@ rsvg_filter_render (RsvgFilter * self, GdkPixbuf * source, GdkPixbuf * output,
bounds = rsvg_filter_primitive_get_bounds (NULL, ctx);
if (rsvg_state_current (context)->clippath)
rsvg_art_clip_image(ctx->lastresult.result, rsvg_state_current (context)->clippath);
if (render->clippath)
rsvg_art_clip_image(ctx->lastresult.result, render->clippath);
rsvg_art_alpha_blt (ctx->lastresult.result, bounds.x1, bounds.y1, bounds.x2 - bounds.x1,
bounds.y2 - bounds.y1, output, bounds.x1, bounds.y1);
context->bbox.x0 = bounds.x1;
context->bbox.y0 = bounds.y1;
context->bbox.x1 = bounds.x2;
context->bbox.y1 = bounds.y2;
render->bbox.x0 = bounds.x1;
render->bbox.y0 = bounds.y1;
render->bbox.x1 = bounds.x2;
render->bbox.y1 = bounds.y2;
g_object_unref (G_OBJECT (ctx->lastresult.result));
g_free(ctx);
}
......@@ -826,10 +828,10 @@ void rsvg_filter_adobe_blend(gint modenum, GdkPixbuf *in, GdkPixbuf *bg, GdkPixb
FPBox boundarys;
RsvgFilterPrimitiveBlendMode mode;
boundarys.x1 = ctx->bbox.x0;
boundarys.y1 = ctx->bbox.y0;
boundarys.x2 = ctx->bbox.x1;
boundarys.y2 = ctx->bbox.y1;
boundarys.x1 = ((RsvgArtRender *)ctx->render)->bbox.x0;
boundarys.y1 = ((RsvgArtRender *)ctx->render)->bbox.y0;
boundarys.x2 = ((RsvgArtRender *)ctx->render)->bbox.x1;
boundarys.y2 = ((RsvgArtRender *)ctx->render)->bbox.y1;
mode = normal;
......
......@@ -30,14 +30,8 @@
#include <string.h>
#include <math.h>
#include <errno.h>
#include "rsvg-filter.h"
#include <libart_lgpl/art_affine.h>
#include <libart_lgpl/art_rgb_svp.h>
#include "rsvg-css.h"
#include "rsvg-mask.h"
/*very art dependant at the moment*/
#include "rsvg-art-composite.h"
#include "rsvg-art-render.h"
static const char s_UTF8_B64Alphabet[64] = {
0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
......@@ -509,25 +503,19 @@ rsvg_defs_drawable_image_draw (RsvgDefsDrawable * self, RsvgDrawingCtx *ctx,
double x = z->x, y = z->y, w = z->w, h = z->h;
unsigned int aspect_ratio = z->preserve_aspect_ratio;
GdkPixbuf *img = z->img;
RsvgState *state = rsvg_state_current(ctx);
ArtSVP * temppath;
/*this will have to change*/
rsvg_state_reinherit_top(ctx, &self->state, dominate);
rsvg_push_discrete_layer(ctx);
if (!z->overflow && (aspect_ratio & RSVG_ASPECT_RATIO_SLICE)){
temppath = rsvg_rect_clip_path(x, y, w, h, ctx);
state->clip_path_loaded = TRUE;
state->clippath = rsvg_clip_path_merge(temppath,
state->clippath, 'i');
rsvg_add_clipping_rect(ctx, x, y, w, h);
}
rsvg_preserve_aspect_ratio(aspect_ratio, (double)gdk_pixbuf_get_width(img),
(double)gdk_pixbuf_get_height(img), &w, &h,
&x, &y);
rsvg_push_discrete_layer(ctx);
rsvg_render_image(ctx, img, x, y, w, h);
rsvg_pop_discrete_layer(ctx);
......
......@@ -298,12 +298,14 @@ rsvg_clip_path_render (RsvgClipPath * self, RsvgDrawingCtx *ctx)
if (self->units == objectBoundingBox)
{
state->affine[0] = ctx->bbox.x1 - ctx->bbox.x0;
state->affine[0] = ((RsvgArtRender *)ctx->render)->bbox.x1
- ((RsvgArtRender *)ctx->render)->bbox.x0;
state->affine[1] = 0;
state->affine[2] = 0;
state->affine[3] = ctx->bbox.y1 - ctx->bbox.y0;
state->affine[4] = ctx->bbox.x0;
state->affine[5] = ctx->bbox.y0;
state->affine[3] = ((RsvgArtRender *)ctx->render)->bbox.y1 -
((RsvgArtRender *)ctx->render)->bbox.y0;
state->affine[4] = ((RsvgArtRender *)ctx->render)->bbox.x0;
state->affine[5] = ((RsvgArtRender *)ctx->render)->bbox.y0;
}
for (i = 0; i < group->children->len; i++)
......@@ -485,7 +487,6 @@ rsvg_clip_path_merge(ArtSVP * first, ArtSVP * second, char operation)
tmppath = art_svp_intersect(first, second);
else
tmppath = art_svp_union(first, second);
art_free(first);
art_free(second);
return tmppath;
}
......
......@@ -31,8 +31,6 @@
#include <libxml/SAX.h>
#include <libxml/xmlmemory.h>
#include <pango/pango.h>
#include <libart_lgpl/art_rect.h>
#include <libart_lgpl/art_svp.h>
#include <glib/gslist.h>
G_BEGIN_DECLS
......@@ -69,7 +67,6 @@ struct RsvgHandle {
RsvgSizeFunc size_func;
gpointer user_data;
GDestroyNotify user_data_destroy;
ArtIRect bbox;
/* stack; there is a state for each element */
......@@ -130,7 +127,6 @@ struct RsvgHandle {
struct RsvgDrawingCtx {
RsvgRender *render;
ArtIRect bbox;
GSList * state;
GError **error;
RsvgDefs *defs;
......@@ -149,6 +145,8 @@ struct RsvgRender {
double x, double y, double w, double h);
void (* pop_discrete_layer) (RsvgDrawingCtx *ctx);
void (* push_discrete_layer) (RsvgDrawingCtx *ctx);
void (* add_clipping_rect) (RsvgDrawingCtx *ctx,
double x, double y, double w, double h);
};
struct RsvgDimensionData {
......@@ -244,6 +242,9 @@ void rsvg_push_discrete_layer (RsvgDrawingCtx *ctx);
void rsvg_render_path (RsvgDrawingCtx *ctx, const char *d);
void rsvg_render_image (RsvgDrawingCtx *ctx, GdkPixbuf * pb,
double x, double y, double w, double h);
void rsvg_add_clipping_rect (RsvgDrawingCtx *ctx, double x, double y,
double w, double h);
G_END_DECLS
......
......@@ -34,10 +34,6 @@
#include "rsvg-shapes.h"
#include "rsvg-css.h"
#include "rsvg-defs.h"
#include "rsvg-filter.h"
#include "rsvg-mask.h"
#include "rsvg-image.h"
#include "rsvg-art-draw.h"
#include <libart_lgpl/art_affine.h>
......
......@@ -28,9 +28,7 @@
#include "rsvg-structure.h"
#include "rsvg-image.h"
#include "rsvg-mask.h"
#include "rsvg-css.h"
#include "rsvg-art-composite.h"
#include <libart_lgpl/art_affine.h>
......@@ -169,7 +167,8 @@ rsvg_defs_drawable_use_resolve(RsvgDefsDrawableUse * self, RsvgDrawingCtx *ctx,
width = self->w;
height = self->h;
RsvgDefVal * parent = rsvg_defs_lookup (ctx->defs, self->href->str);
RsvgDefVal * parent = self->link;
if (parent != NULL)
switch(parent->type)
{
......@@ -226,6 +225,10 @@ rsvg_defs_drawable_use_draw (RsvgDefsDrawable * self, RsvgDrawingCtx *ctx,
child = rsvg_defs_drawable_use_resolve(use, ctx, rsvg_state_current(ctx)->affine);
/* If it can find nothing to draw... draw nothing */
if (!use->link)
return;
rsvg_push_discrete_layer (ctx);
rsvg_state_push(ctx);
......@@ -251,28 +254,19 @@ rsvg_defs_drawable_svg_draw (RsvgDefsDrawable * self, RsvgDrawingCtx *ctx,
{
RsvgDefsDrawableSvg * sself;
RsvgState *state;
ArtSVP * temppath = NULL;
RsvgDefsDrawableGroup *group = (RsvgDefsDrawableGroup*)self;
guint i;
sself = (RsvgDefsDrawableSvg *)self;
if (!sself->overflow)
temppath = rsvg_rect_clip_path(sself->x,
sself->y,
sself->w,
sself->h,
ctx);
rsvg_push_discrete_layer (ctx);
rsvg_state_reinherit_top(ctx, &self->state, dominate);