summaryrefslogtreecommitdiff
path: root/rsvg-art-composite.c
diff options
context:
space:
mode:
Diffstat (limited to 'rsvg-art-composite.c')
-rw-r--r--rsvg-art-composite.c247
1 files changed, 42 insertions, 205 deletions
diff --git a/rsvg-art-composite.c b/rsvg-art-composite.c
index 5d27dd6c..49c5a6f4 100644
--- a/rsvg-art-composite.c
+++ b/rsvg-art-composite.c
@@ -50,7 +50,7 @@ typedef struct _RsvgArtDiscreteLayer RsvgArtDiscreteLayer;
struct _RsvgArtDiscreteLayer
{
GdkPixbuf *save_pixbuf;
- ArtIRect underbbox;
+ RsvgIRect underbbox;
RsvgState * state;
ArtSVP * clippath_save;
gboolean clippath_loaded;
@@ -215,7 +215,7 @@ rsvg_compile_bg(RsvgDrawingCtx *ctx)
int i;
GdkPixbuf *intermediate, *lastintermediate;
RsvgArtDiscreteLayer *state;
- ArtIRect save;
+ RsvgIRect save;
RsvgArtRender *render = (RsvgArtRender *)ctx->render;
lastintermediate = gdk_pixbuf_copy(((RsvgArtDiscreteLayer *)render->layers->data)->save_pixbuf);
@@ -254,6 +254,7 @@ rsvg_composite_layer(RsvgDrawingCtx *ctx, RsvgState *state, GdkPixbuf *tos, GdkP
GdkPixbuf *in, *out, *insidebg;
int operationsleft;
gint adobe_blend = state->adobe_blend;
+ RsvgArtRender * render = (RsvgArtRender *)ctx->render;
intermediate = NULL;
@@ -289,8 +290,17 @@ rsvg_composite_layer(RsvgDrawingCtx *ctx, RsvgState *state, GdkPixbuf *tos, GdkP
if (filter != NULL)
{
+ GdkPixbuf * temp;
out = get_next_out(&operationsleft, in, tos, nos, intermediate);
- rsvg_filter_render (filter, in, out, insidebg, ctx);
+ temp = rsvg_filter_render (filter, in, insidebg, ctx,
+ (RsvgIRect *)&render->bbox);
+ if (render->clippath)
+ rsvg_art_clip_image(temp, render->clippath);
+ rsvg_alpha_blt (temp, render->bbox.x0, render->bbox.y0,
+ render->bbox.x1 - render->bbox.x0,
+ render->bbox.y1 - render->bbox.y0,
+ out, render->bbox.x0, render->bbox.y0);
+ g_object_unref (G_OBJECT (temp));
in = out;
}
if (opacity != 0xFF)
@@ -308,7 +318,8 @@ rsvg_composite_layer(RsvgDrawingCtx *ctx, RsvgState *state, GdkPixbuf *tos, GdkP
if (adobe_blend)
{
out = get_next_out(&operationsleft, in, tos, nos, intermediate);
- rsvg_filter_adobe_blend (adobe_blend, in, insidebg, out, ctx);
+ rsvg_filter_adobe_blend (adobe_blend, in, insidebg, out,
+ render->bbox, ctx);
in = out;
}
@@ -354,7 +365,9 @@ rsvg_art_pop_discrete_layer(RsvgDrawingCtx *ctx)
g_object_unref (tos);
render->pixbuf = nos;
- art_irect_union(&render->bbox, &render->bbox, &layer->underbbox);
+ art_irect_union((ArtIRect*)&render->bbox,
+ (ArtIRect*)&render->bbox,
+ (ArtIRect*)&layer->underbbox);
}
if (layer->clippath_loaded)
{
@@ -372,206 +385,6 @@ rsvg_art_needs_discrete_layer(RsvgState *state)
}
void
-rsvg_art_alpha_blt (GdkPixbuf * src, gint srcx, gint srcy, gint srcwidth,
- gint srcheight, GdkPixbuf * dst, gint dstx, gint dsty)
-{
- gint rightx;
- gint bottomy;
- gint dstwidth;
- gint dstheight;
-
- gint srcoffsetx;
- gint srcoffsety;
- gint dstoffsetx;
- gint dstoffsety;
-
- gint x, y, srcrowstride, dstrowstride, sx, sy, dx, dy;
- guchar *src_pixels, *dst_pixels;
-
- dstheight = srcheight;
- dstwidth = srcwidth;
-
- rightx = srcx + srcwidth;
- bottomy = srcy + srcheight;
-
- if (rightx > gdk_pixbuf_get_width (src))
- rightx = gdk_pixbuf_get_width (src);
- if (bottomy > gdk_pixbuf_get_height (src))
- bottomy = gdk_pixbuf_get_height (src);
- srcwidth = rightx - srcx;
- srcheight = bottomy - srcy;
-
- rightx = dstx + dstwidth;
- bottomy = dsty + dstheight;
- if (rightx > gdk_pixbuf_get_width (dst))
- rightx = gdk_pixbuf_get_width (dst);
- if (bottomy > gdk_pixbuf_get_height (dst))
- bottomy = gdk_pixbuf_get_height (dst);
- dstwidth = rightx - dstx;
- dstheight = bottomy - dsty;
-
- if (dstwidth < srcwidth)
- srcwidth = dstwidth;
- if (dstheight < srcheight)
- srcheight = dstheight;
-
- if (srcx < 0)
- srcoffsetx = 0 - srcx;
- else
- srcoffsetx = 0;
-
- if (srcy < 0)
- srcoffsety = 0 - srcy;
- else
- srcoffsety = 0;
-
- if (dstx < 0)
- dstoffsetx = 0 - dstx;
- else
- dstoffsetx = 0;
-
- if (dsty < 0)
- dstoffsety = 0 - dsty;
- else
- dstoffsety = 0;
-
- if (dstoffsetx > srcoffsetx)
- srcoffsetx = dstoffsetx;
- if (dstoffsety > srcoffsety)
- srcoffsety = dstoffsety;
-
- srcrowstride = gdk_pixbuf_get_rowstride (src);
- dstrowstride = gdk_pixbuf_get_rowstride (dst);
-
- src_pixels = gdk_pixbuf_get_pixels (src);
- dst_pixels = gdk_pixbuf_get_pixels (dst);
-
- for (y = srcoffsety; y < srcheight; y++)
- for (x = srcoffsetx; x < srcwidth; x++)
- {
- guchar r, g, b, a;
-
- sx = x + srcx;
- sy = y + srcy;
- dx = x + dstx;
- dy = y + dsty;
- a = src_pixels[4 * sx + sy * srcrowstride + 3];
- if (a)
- {
- r = src_pixels[4 * sx + sy * srcrowstride];
- g = src_pixels[4 * sx + 1 + sy * srcrowstride];
- b = src_pixels[4 * sx + 2 + sy * srcrowstride];
- art_rgba_run_alpha (dst_pixels + 4 * dx +
- dy * dstrowstride, r, g, b, a, 1);
- }
- }
-}
-
-void
-rsvg_art_affine_image(const GdkPixbuf *img, GdkPixbuf *intermediate,
- double * affine, double w, double h)
-{
- gdouble tmp_affine[6];
- gdouble inv_affine[6];
- gdouble raw_inv_affine[6];
- gint intstride;
- gint basestride;
- gint basex, basey;
- gdouble fbasex, fbasey;
- gdouble rawx, rawy;
- guchar * intpix;
- guchar * basepix;
- gint i, j, k, basebpp, ii, jj;
- gboolean has_alpha;
- gdouble pixsum[4];
- gboolean xrunnoff, yrunnoff;
- gint iwidth, iheight;
- gint width, height;
-
- width = gdk_pixbuf_get_width (img);
- height = gdk_pixbuf_get_height (img);
- iwidth = gdk_pixbuf_get_width (intermediate);
- iheight = gdk_pixbuf_get_height (intermediate);
-
- has_alpha = gdk_pixbuf_get_has_alpha (img);
-
- basestride = gdk_pixbuf_get_rowstride (img);
- intstride = gdk_pixbuf_get_rowstride (intermediate);
- basepix = gdk_pixbuf_get_pixels (img);
- intpix = gdk_pixbuf_get_pixels (intermediate);
- basebpp = has_alpha ? 4 : 3;
-
- _rsvg_affine_invert(raw_inv_affine, affine);
-
- /*scale to w and h*/
- tmp_affine[0] = (double)w;
- tmp_affine[3] = (double)h;
- tmp_affine[1] = tmp_affine[2] = tmp_affine[4] = tmp_affine[5] = 0;
- _rsvg_affine_multiply(tmp_affine, tmp_affine, affine);
-
- _rsvg_affine_invert(inv_affine, tmp_affine);
-
-
- /*apply the transformation*/
- for (i = 0; i < iwidth; i++)
- for (j = 0; j < iheight; j++)
- {
- fbasex = (inv_affine[0] * (double)i + inv_affine[2] * (double)j +
- inv_affine[4]) * (double)width;
- fbasey = (inv_affine[1] * (double)i + inv_affine[3] * (double)j +
- inv_affine[5]) * (double)height;
- basex = floor(fbasex);
- basey = floor(fbasey);
- rawx = raw_inv_affine[0] * i + raw_inv_affine[2] * j +
- raw_inv_affine[4];
- rawy = raw_inv_affine[1] * i + raw_inv_affine[3] * j +
- raw_inv_affine[5];
- if (rawx < 0 || rawy < 0 || rawx >= w ||
- rawy >= h || basex < 0 || basey < 0
- || basex >= width || basey >= height)
- {
- for (k = 0; k < 4; k++)
- intpix[i * 4 + j * intstride + k] = 0;
- }
- else
- {
- if (basex < 0 || basex + 1 >= width)
- xrunnoff = TRUE;
- else
- xrunnoff = FALSE;
- if (basey < 0 || basey + 1 >= height)
- yrunnoff = TRUE;
- else
- yrunnoff = FALSE;
- for (k = 0; k < basebpp; k++)
- pixsum[k] = 0;
- for (ii = 0; ii < 2; ii++)
- for (jj = 0; jj < 2; jj++)
- {
- if (basex + ii < 0 || basey + jj< 0
- || basex + ii >= width || basey + jj >= height)
- ;
- else
- {
- for (k = 0; k < basebpp; k++)
- {
- pixsum[k] +=
- (double)basepix[basebpp * (basex + ii) + (basey + jj) * basestride + k]
- * (xrunnoff ? 1 : fabs(fbasex - (double)(basex + (1 - ii))))
- * (yrunnoff ? 1 : fabs(fbasey - (double)(basey + (1 - jj))));
- }
- }
- }
- for (k = 0; k < basebpp; k++)
- intpix[i * 4 + j * intstride + k] = pixsum[k];
- if (!has_alpha)
- intpix[i * 4 + j * intstride + 3] = 255;
- }
-
- }
-}
-
-void
rsvg_art_clip_image(GdkPixbuf *intermediate, ArtSVP *path)
{
gint intstride;
@@ -617,3 +430,27 @@ rsvg_art_add_clipping_rect(RsvgDrawingCtx *ctx, double x, double y, double w, do
else
data->clippath_loaded = FALSE;
}
+
+void *
+rsvg_art_get_image_of_node(RsvgDrawingCtx *ctx, RsvgNode * drawable,
+ double w, double h)
+{
+ GdkPixbuf *img, *save;
+
+
+ img = _rsvg_pixbuf_new_cleared (GDK_COLORSPACE_RGB, 1, 8, w, h);
+
+ save = ((RsvgArtRender *)ctx->render)->pixbuf;
+ ((RsvgArtRender *)ctx->render)->pixbuf = img;
+
+
+ rsvg_state_push(ctx);
+
+ rsvg_node_draw (drawable, ctx, 0);
+
+ rsvg_state_pop(ctx);
+
+ ((RsvgArtRender *)ctx->render)->pixbuf = save;
+
+ return img;
+}