summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog7
-rw-r--r--Makefile.am6
-rw-r--r--rsvg-art-composite.c247
-rw-r--r--rsvg-art-composite.h7
-rw-r--r--rsvg-art-draw.c17
-rw-r--r--rsvg-art-render.c1
-rw-r--r--rsvg-art-render.h2
-rw-r--r--rsvg-base.c8
-rw-r--r--rsvg-css.c11
-rw-r--r--rsvg-css.h2
-rw-r--r--rsvg-filter.c623
-rw-r--r--rsvg-filter.h14
-rw-r--r--rsvg-image.c5
-rw-r--r--rsvg-image.h1
-rw-r--r--rsvg-marker.c3
-rw-r--r--rsvg-marker.h2
-rw-r--r--rsvg-private.h9
-rw-r--r--rsvg-structure.c18
-rw-r--r--rsvg-structure.h4
-rw-r--r--rsvg-styles.c14
-rw-r--r--rsvg-styles.h3
21 files changed, 523 insertions, 481 deletions
diff --git a/ChangeLog b/ChangeLog
index aca93956..eef23316 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2005-07-29 Caleb Moore <c.moore@student.unsw.edu.au>
+
+ * rsvg-filter.c, et_al: Made filters work again.
+ * rsvg-private.c: made a new function for render thingies to implement,
+ something that will get a node as a pixbuf.
+ * rsvg-styles.c: made overflow into a propper CSS property
+
2005-07-21 Caleb Moore <c.moore@student.unsw.edu.au>
* Makefile.am, configure.in, rsvg.c, rsvg-base.c: further split the library into librsvg-2.so, librsvg-2-base.so and librsvg-2-libart.so. Make libart an optional dependancy.
diff --git a/Makefile.am b/Makefile.am
index 2dd86eed..0f606882 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -47,6 +47,8 @@ librsvg_2_base_la_SOURCES = \
rsvg-path.h \
rsvg-private.h \
rsvg-file-util.c \
+ rsvg-filter.c \
+ rsvg-filter.h \
rsvg-marker.c \
rsvg-marker.h \
rsvg-mask.c \
@@ -76,9 +78,7 @@ librsvg_2_libart_la_SOURCES = \
rsvg-art-paint-server.c \
rsvg-art-paint-server.h \
rsvg-art-render.c \
- rsvg-art-render.h \
- rsvg-filter.c \
- rsvg-filter.h
+ rsvg-art-render.h
librsvg_2_libart_la_LDFLAGS = -version-info @VERSION_INFO@ -no-undefined -export-dynamic
librsvg_2_libart_la_LIBADD = librsvg-2-base.la $(LIBGNOME_VFS_LIBS) $(LIBGSF_LIBS) $(LIBCROCO_LIBS) $(LIBRSVG_LIBS) $(FREETYPE_LIBS) $(LIBART_LIBS)
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;
+}
diff --git a/rsvg-art-composite.h b/rsvg-art-composite.h
index 3d13e23b..a03acad9 100644
--- a/rsvg-art-composite.h
+++ b/rsvg-art-composite.h
@@ -39,13 +39,10 @@ void rsvg_art_pop_discrete_layer(RsvgDrawingCtx *ctx);
void rsvg_art_push_discrete_layer (RsvgDrawingCtx *ctx);
gboolean 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);
void rsvg_art_clip_image (GdkPixbuf *intermediate, ArtSVP *path);
-void rsvg_art_affine_image(const 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);
+void * rsvg_art_get_image_of_node(RsvgDrawingCtx *ctx, RsvgNode * drawable, double w, double h);
+
G_END_DECLS
#endif
diff --git a/rsvg-art-draw.c b/rsvg-art-draw.c
index ff7fd5dd..b8e2f7df 100644
--- a/rsvg-art-draw.c
+++ b/rsvg-art-draw.c
@@ -44,6 +44,7 @@
#include "rsvg-styles.h"
#include "rsvg-bpath-util.h"
#include "rsvg-path.h"
+#include "rsvg-filter.h"
#include <math.h>
@@ -253,7 +254,8 @@ rsvg_render_svp (RsvgDrawingCtx *ctx, ArtSVP *svp,
art_render_mask_solid (render, (opacity << 8) + opacity + (opacity >> 7));
temptemprect = rsvg_frect_pixelspaceise(temprect, state->affine);
- art_irect_union(&arender->bbox, &arender->bbox, &temptemprect);
+ art_irect_union((ArtIRect*)&arender->bbox,
+ (ArtIRect*)&arender->bbox, (ArtIRect*)&temptemprect);
gradctx.x0 = temprect.x0;
gradctx.y0 = temprect.y0;
@@ -466,11 +468,11 @@ void rsvg_art_render_image (RsvgDrawingCtx *ctx, const GdkPixbuf * img,
}
/*slap it down*/
- rsvg_art_alpha_blt (intermediate, 0, 0,
- gdk_pixbuf_get_width (intermediate),
- gdk_pixbuf_get_height (intermediate),
- pixbuf,
- 0, 0);
+ rsvg_alpha_blt (intermediate, 0, 0,
+ gdk_pixbuf_get_width (intermediate),
+ gdk_pixbuf_get_height (intermediate),
+ pixbuf,
+ 0, 0);
temprect.x0 = gdk_pixbuf_get_width (intermediate);
temprect.y0 = gdk_pixbuf_get_height (intermediate);
@@ -488,7 +490,8 @@ void rsvg_art_render_image (RsvgDrawingCtx *ctx, const GdkPixbuf * img,
temprect.y1 = MAX(basey, temprect.y1);
}
- art_irect_union(&arender->bbox, &arender->bbox, &temprect);
+ art_irect_union((ArtIRect*)&arender->bbox,
+ (ArtIRect*)&arender->bbox, (ArtIRect*)&temprect);
g_object_unref (G_OBJECT (intermediate));
}
diff --git a/rsvg-art-render.c b/rsvg-art-render.c
index a9085325..ecf76bc0 100644
--- a/rsvg-art-render.c
+++ b/rsvg-art-render.c
@@ -77,6 +77,7 @@ rsvg_art_render_new(int new_width, int new_height)
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->super.get_image_of_node = rsvg_art_get_image_of_node;
output->pixbuf = gdk_pixbuf_new_from_data (pixels,
GDK_COLORSPACE_RGB,
diff --git a/rsvg-art-render.h b/rsvg-art-render.h
index b48a0023..8b2972de 100644
--- a/rsvg-art-render.h
+++ b/rsvg-art-render.h
@@ -38,7 +38,7 @@ struct RsvgArtRender {
RsvgRender super;
GdkPixbuf *pixbuf;
GSList * layers;
- ArtIRect bbox;
+ RsvgIRect bbox;
ArtSVP * clippath;
};
diff --git a/rsvg-base.c b/rsvg-base.c
index 9fd4a259..5cc757ba 100644
--- a/rsvg-base.c
+++ b/rsvg-base.c
@@ -207,7 +207,6 @@ rsvg_filter_handler_start (RsvgHandle *ctx, const xmlChar *name,
newnode = rsvg_new_radial_gradient ();
else if (!strcmp ((char *)name, "conicalGradient"))
newnode = rsvg_new_radial_gradient ();
- /*
else if (!strcmp ((char *)name, "filter"))
newnode = rsvg_new_filter();
else if (!strcmp ((char *)name, "feBlend"))
@@ -258,7 +257,6 @@ rsvg_filter_handler_start (RsvgHandle *ctx, const xmlChar *name,
newnode = rsvg_new_filter_primitive_light_source('s');
else if (!strcmp ((char *)name, "fePointLight"))
newnode = rsvg_new_filter_primitive_light_source('p');
- */
if (newnode)
{
rsvg_node_set_atts(newnode, ctx, atts);
@@ -1330,6 +1328,12 @@ rsvg_add_clipping_rect (RsvgDrawingCtx *ctx, double x, double y, double w, doubl
ctx->render->add_clipping_rect(ctx, x, y, w, h);
}
+void * rsvg_get_image_of_node(RsvgDrawingCtx *ctx, RsvgNode * drawable,
+ double w, double h)
+{
+ return ctx->render->get_image_of_node(ctx, drawable, w, h);
+}
+
void
rsvg_render_free (RsvgRender * render)
{
diff --git a/rsvg-css.c b/rsvg-css.c
index c55b96c2..90d55930 100644
--- a/rsvg-css.c
+++ b/rsvg-css.c
@@ -906,9 +906,14 @@ rsvg_css_parse_aspect_ratio (const char * str)
}
gboolean
-rsvg_css_parse_overflow(const char * str)
+rsvg_css_parse_overflow(const char * str, gboolean * inherit)
{
- if (!strcmp(str, "visible"))
+ SETINHERIT ();
+ if (!strcmp(str, "visible") || !strcmp(str, "auto"))
return 1;
- return 0; /* hidden, scroll */
+ if (!strcmp(str, "hidden") || !strcmp(str, "scroll"))
+ return 0;
+ UNSETINHERIT ();
+ return 0;
}
+
diff --git a/rsvg-css.h b/rsvg-css.h
index 90f0f661..ef1f1dc9 100644
--- a/rsvg-css.h
+++ b/rsvg-css.h
@@ -103,7 +103,7 @@ gdouble *
rsvg_css_parse_number_list(const char * in_str, guint * out_list_len);
gboolean
-rsvg_css_parse_overflow(const char * str);
+rsvg_css_parse_overflow(const char * str, gboolean * inherit);
G_END_DECLS
diff --git a/rsvg-filter.c b/rsvg-filter.c
index aa119900..be7bbbf7 100644
--- a/rsvg-filter.c
+++ b/rsvg-filter.c
@@ -33,27 +33,17 @@
#include <math.h>
-#include "rsvg-art-render.h"
-#include "rsvg-art-composite.h"
-#include <libart_lgpl/art_rgba.h>
-#include <libart_lgpl/art_rgb_svp.h>
-
#define PERFECTBLUR 0
/*************************************************************/
/*************************************************************/
-typedef struct
-{
- gint x1, y1, x2, y2;
-} FPBox;
-
typedef struct _RsvgFilterPrimitiveOutput RsvgFilterPrimitiveOutput;
struct _RsvgFilterPrimitiveOutput
{
GdkPixbuf *result;
- FPBox bounds;
+ RsvgIRect bounds;
gboolean Rused;
gboolean Gused;
gboolean Bused;
@@ -98,11 +88,11 @@ rsvg_filter_primitive_render (RsvgFilterPrimitive * self,
self->render (self, ctx);
}
-static FPBox
+static RsvgIRect
rsvg_filter_primitive_get_bounds (RsvgFilterPrimitive * self,
RsvgFilterContext * ctx)
{
- FPBox output;
+ RsvgIRect output;
int skip;
skip = 0;
@@ -113,53 +103,53 @@ rsvg_filter_primitive_get_bounds (RsvgFilterPrimitive * self,
if (skip)
{
- output.x1 = ctx->affine[0] * ctx->filter->x + ctx->affine[4];
- output.y1 = ctx->affine[3] * ctx->filter->y + ctx->affine[5];
- output.x2 =
+ output.x0 = ctx->affine[0] * ctx->filter->x + ctx->affine[4];
+ output.y0 = ctx->affine[3] * ctx->filter->y + ctx->affine[5];
+ output.x1 =
ctx->affine[0] * (ctx->filter->x + ctx->filter->width) +
ctx->affine[4];
- output.y2 =
+ output.y1 =
ctx->affine[3] * (ctx->filter->y + ctx->filter->height) +
ctx->affine[5];
- if (output.x1 < 0)
- output.x1 = 0;
- if (output.x2 > ctx->width)
- output.x2 = ctx->width;
- if (output.y1 < 0)
- output.y1 = 0;
- if (output.y2 > ctx->height)
- output.y2 = ctx->height;
+ if (output.x0 < 0)
+ output.x0 = 0;
+ if (output.x1 > ctx->width)
+ output.x1 = ctx->width;
+ if (output.y0 < 0)
+ output.y0 = 0;
+ if (output.y1 > ctx->height)
+ output.y1 = ctx->height;
return output;
}
- output.x1 = ctx->paffine[0] * self->x + ctx->paffine[4];
- output.y1 = ctx->paffine[3] * self->y + ctx->paffine[5];
- output.x2 = ctx->paffine[0] * (self->x + self->width) + ctx->paffine[4];
- output.y2 = ctx->paffine[3] * (self->y + self->height) + ctx->paffine[5];
+ output.x0 = ctx->paffine[0] * self->x + ctx->paffine[4];
+ output.y0 = ctx->paffine[3] * self->y + ctx->paffine[5];
+ output.x1 = ctx->paffine[0] * (self->x + self->width) + ctx->paffine[4];
+ output.y1 = ctx->paffine[3] * (self->y + self->height) + ctx->paffine[5];
- if (output.x1 < ctx->affine[0] * ctx->filter->x + ctx->affine[4])
- output.x1 = ctx->affine[0] * ctx->filter->x + ctx->affine[4];
- if (output.x2 >
+ if (output.x0 < ctx->affine[0] * ctx->filter->x + ctx->affine[4])
+ output.x0 = ctx->affine[0] * ctx->filter->x + ctx->affine[4];
+ if (output.x1 >
ctx->affine[0] * (ctx->filter->x + ctx->filter->width) + ctx->affine[4])
- output.x2 =
+ output.x1 =
ctx->affine[0] * (ctx->filter->x + ctx->filter->width) + ctx->affine[4];
- if (output.y1 < ctx->affine[3] * ctx->filter->y + ctx->affine[5])
- output.y1 = ctx->affine[3] * ctx->filter->y + ctx->affine[5];
- if (output.y2 > ctx->affine[3] * (ctx->filter->y + ctx->filter->height) +
+ if (output.y0 < ctx->affine[3] * ctx->filter->y + ctx->affine[5])
+ output.y0 = ctx->affine[3] * ctx->filter->y + ctx->affine[5];
+ if (output.y1 > ctx->affine[3] * (ctx->filter->y + ctx->filter->height) +
ctx->affine[5])
- output.y2 = ctx->affine[3] * (ctx->filter->y + ctx->filter->height) +
+ output.y1 = ctx->affine[3] * (ctx->filter->y + ctx->filter->height) +
ctx->affine[5];
- if (output.x1 < 0)
- output.x1 = 0;
- if (output.x2 > ctx->width)
- output.x2 = ctx->width;
- if (output.y1 < 0)
- output.y1 = 0;
- if (output.y2 > ctx->height)
- output.y2 = ctx->height;
+ if (output.x0 < 0)
+ output.x0 = 0;
+ if (output.x1 > ctx->width)
+ output.x1 = ctx->width;
+ if (output.y0 < 0)
+ output.y0 = 0;
+ if (output.y1 > ctx->height)
+ output.y1 = ctx->height;
return output;
}
@@ -179,7 +169,7 @@ _rsvg_pixbuf_new_cleared (GdkColorspace colorspace, gboolean has_alpha, int bits
}
static guchar
-gdk_pixbuf_get_interp_pixel(guchar * src, gdouble ox, gdouble oy, guchar ch, FPBox boundarys, guint rowstride)
+gdk_pixbuf_get_interp_pixel(guchar * src, gdouble ox, gdouble oy, guchar ch, RsvgIRect boundarys, guint rowstride)
{
double xmod, ymod;
double dist1, dist2, dist3, dist4;
@@ -193,26 +183,26 @@ gdk_pixbuf_get_interp_pixel(guchar * src, gdouble ox, gdouble oy, guchar ch, FPB
dist3 = (xmod) * (ymod);
dist4 = (1 - xmod) * (ymod);
- if (floor(ox) <= boundarys.x1 || floor(ox) >= boundarys.x2 ||
- floor(oy) <= boundarys.y1 || floor(oy) >= boundarys.y2)
+ if (floor(ox) <= boundarys.x0 || floor(ox) >= boundarys.x1 ||
+ floor(oy) <= boundarys.y0 || floor(oy) >= boundarys.y1)
c1 = 0;
else
c1 = src[(guint)floor(oy) * rowstride + (guint)floor(ox) * 4 + ch];
- if (ceil(ox) <= boundarys.x1 || ceil(ox) >= boundarys.x2 ||
- floor(oy) <= boundarys.y1 || floor(oy) >= boundarys.y2)
+ if (ceil(ox) <= boundarys.x0 || ceil(ox) >= boundarys.x1 ||
+ floor(oy) <= boundarys.y0 || floor(oy) >= boundarys.y1)
c2 = 0;
else
c2 = src[(guint)floor(oy) * rowstride + (guint)ceil(ox) * 4 + ch];
- if (ceil(ox) <= boundarys.x1 || ceil(ox) >= boundarys.x2 ||
- ceil(oy) <= boundarys.y1 || ceil(oy) >= boundarys.y2)
+ if (ceil(ox) <= boundarys.x0 || ceil(ox) >= boundarys.x1 ||
+ ceil(oy) <= boundarys.y0 || ceil(oy) >= boundarys.y1)
c3 = 0;
else
c3 = src[(guint)ceil(oy) * rowstride + (guint)ceil(ox) * 4 + ch];
- if (floor(ox) <= boundarys.x1 || floor(ox) >= boundarys.x2 ||
- ceil(oy) <= boundarys.y1 || ceil(oy) >= boundarys.y2)
+ if (floor(ox) <= boundarys.x0 || floor(ox) >= boundarys.x1 ||
+ ceil(oy) <= boundarys.y0 || ceil(oy) >= boundarys.y1)
c4 = 0;
else
c4 = src[(guint)ceil(oy) * rowstride + (guint)floor(ox) * 4 + ch];
@@ -223,11 +213,11 @@ gdk_pixbuf_get_interp_pixel(guchar * src, gdouble ox, gdouble oy, guchar ch, FPB
}
static void
-rsvg_filter_fix_coordinate_system (RsvgFilterContext * ctx, RsvgState * state)
+rsvg_filter_fix_coordinate_system (RsvgFilterContext * ctx, RsvgState * state,
+ RsvgIRect bbox)
{
int x, y, height, width;
int i;
- ArtIRect bbox = ((RsvgArtRender *)ctx->ctx->render)->bbox;
x = bbox.x0;
y = bbox.y0;
@@ -268,6 +258,212 @@ rsvg_filter_fix_coordinate_system (RsvgFilterContext * ctx, RsvgState * state)
}
}
+void
+rsvg_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++)
+ {
+ guint a, c, ad, cd, ar, cr, i;
+
+ sx = x + srcx;
+ sy = y + srcy;
+ dx = x + dstx;
+ dy = y + dsty;
+ a = src_pixels[4 * sx + sy * srcrowstride + 3];
+
+ if (a)
+ {
+ ad = dst_pixels[4 * dx + dy * dstrowstride + 3];
+ ar = a + ad * (255 - a) / 255;
+ for (i = 0; i < 3; i++)
+ {
+ c = src_pixels[4 * sx + sy * srcrowstride + i] * a / 255;
+ cd = dst_pixels[4 * dx + dy * dstrowstride + i] * ar / 255;
+ cr = (c * 255 + cd * (255 - a)) / ar;
+ dst_pixels[4 * dx + dy * dstrowstride + i] = cr;
+ }
+ dst_pixels[4 * dx + dy * dstrowstride + 3] = ar;
+ }
+ }
+}
+
+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;
+ }
+
+ }
+}
+
static void
rsvg_filter_free_pair (gpointer value)
{
@@ -288,16 +484,16 @@ rsvg_filter_free_pair (gpointer value)
* This function will create a context for itself, set up the coordinate systems
* execute all its little primatives and then clean up its own mess
**/
-void
-rsvg_filter_render (RsvgFilter * self, GdkPixbuf * source, GdkPixbuf * output,
- GdkPixbuf * bg, RsvgDrawingCtx * context)
+GdkPixbuf *
+rsvg_filter_render (RsvgFilter * self, GdkPixbuf * source,
+ GdkPixbuf * bg, RsvgDrawingCtx * context,
+ RsvgIRect * bounds)
{
RsvgFilterContext *ctx;
- RsvgArtRender * render = ((RsvgArtRender *)context->render);
RsvgFilterPrimitive *current;
guint i;
- FPBox bounds;
-
+ GdkPixbuf * out;
+
ctx = g_new (RsvgFilterContext, 1);
ctx->filter = self;
ctx->source = source;
@@ -307,7 +503,8 @@ rsvg_filter_render (RsvgFilter * self, GdkPixbuf * source, GdkPixbuf * output,
g_object_ref (G_OBJECT (source));
- rsvg_filter_fix_coordinate_system (ctx, rsvg_state_current (context));
+ rsvg_filter_fix_coordinate_system (ctx, rsvg_state_current (context),
+ *bounds);
ctx->lastresult.result = source;
ctx->lastresult.Rused = 1;
@@ -323,21 +520,15 @@ rsvg_filter_render (RsvgFilter * self, GdkPixbuf * source, GdkPixbuf * output,
rsvg_filter_primitive_render (current, ctx);
}
- g_hash_table_destroy (ctx->results);
-
- bounds = rsvg_filter_primitive_get_bounds (NULL, ctx);
+ out = ctx->lastresult.result;
+ g_object_ref (G_OBJECT (out));
+ *bounds = rsvg_filter_primitive_get_bounds (NULL, ctx);
- if (render->clippath)
- rsvg_art_clip_image(ctx->lastresult.result, render->clippath);
+ g_hash_table_destroy (ctx->results);
- rsvg_art_alpha_blt (ctx->lastresult.result, bounds.x1, bounds.y1, bounds.x2 - bounds.x1,
- bounds.y2 - bounds.y1, output, bounds.x1, bounds.y1);
- 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);
+
+ return out;
}
/**
@@ -379,10 +570,10 @@ rsvg_filter_store_result(GString * name, GdkPixbuf * result,
output.Gused = 1;
output.Bused = 1;
output.Aused = 1;
- output.bounds.x1 = 0;
- output.bounds.y1 = 0;
- output.bounds.x2 = ctx->width;
- output.bounds.y2 = ctx->height;
+ output.bounds.x0 = 0;
+ output.bounds.y0 = 0;
+ output.bounds.x1 = ctx->width;
+ output.bounds.y1 = ctx->height;
output.result = result;
rsvg_filter_store_output(name, output, ctx);
@@ -440,7 +631,7 @@ rsvg_filter_get_result (GString * name, RsvgFilterContext * ctx)
output.Rused = output.Gused = output.Bused = output.Aused = 1;
return output;
}
- else if (!strcmp (name->str, "") || !strcmp (name->str, "none"))
+ else if (!strcmp (name->str, "") || !strcmp (name->str, "none") || !name)
{
g_object_ref (G_OBJECT (ctx->lastresult.result));
output = ctx->lastresult;
@@ -621,7 +812,7 @@ struct _RsvgFilterPrimitiveBlend
GString *in2;
};
-static void rsvg_filter_blend(RsvgFilterPrimitiveBlendMode mode, GdkPixbuf *in, GdkPixbuf *in2, GdkPixbuf *output, FPBox boundarys)
+static void rsvg_filter_blend(RsvgFilterPrimitiveBlendMode mode, GdkPixbuf *in, GdkPixbuf *in2, GdkPixbuf *output, RsvgIRect boundarys)
{
guchar i;
gint x, y;
@@ -639,17 +830,17 @@ static void rsvg_filter_blend(RsvgFilterPrimitiveBlendMode mode, GdkPixbuf *in,
in_pixels = gdk_pixbuf_get_pixels (in);
in2_pixels = gdk_pixbuf_get_pixels (in2);
- if (boundarys.x1 < 0)
- boundarys.x1 = 0;
- if (boundarys.y1 < 0)
- boundarys.y2 = 0;
- if (boundarys.x2 >= width)
- boundarys.x2 = width;
- if (boundarys.y2 >= height)
- boundarys.y2 = height;
+ if (boundarys.x0 < 0)
+ boundarys.x0 = 0;
+ if (boundarys.y0 < 0)
+ boundarys.y1 = 0;
+ if (boundarys.x1 >= width)
+ boundarys.x1 = width;
+ if (boundarys.y1 >= height)
+ boundarys.y1 = height;
- for (y = boundarys.y1; y < boundarys.y2; y++)
- for (x = boundarys.x1; x < boundarys.x2; x++)
+ for (y = boundarys.y0; y < boundarys.y1; y++)
+ for (x = boundarys.x0; x < boundarys.x1; x++)
{
double qr, cr, qa, qb, ca, cb, bca, bcb;
@@ -735,7 +926,7 @@ static void
rsvg_filter_primitive_blend_render (RsvgFilterPrimitive * self,
RsvgFilterContext * ctx)
{
- FPBox boundarys;
+ RsvgIRect boundarys;
RsvgFilterPrimitiveBlend *upself;
@@ -760,16 +951,9 @@ rsvg_filter_primitive_blend_render (RsvgFilterPrimitive * self,
g_object_unref (G_OBJECT (output));
}
-void rsvg_filter_adobe_blend(gint modenum, GdkPixbuf *in, GdkPixbuf *bg, GdkPixbuf *output, RsvgDrawingCtx * ctx)
+void rsvg_filter_adobe_blend(gint modenum, GdkPixbuf *in, GdkPixbuf *bg, GdkPixbuf *output, RsvgIRect boundarys, RsvgDrawingCtx * ctx)
{
- FPBox boundarys;
RsvgFilterPrimitiveBlendMode mode;
-
- 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;
switch(modenum)
@@ -943,7 +1127,7 @@ rsvg_filter_primitive_convolve_matrix_render (RsvgFilterPrimitive * self,
gint x, y;
gint i, j;
gint rowstride, height, width;
- FPBox boundarys;
+ RsvgIRect boundarys;
guchar *in_pixels;
guchar *output_pixels;
@@ -984,8 +1168,8 @@ rsvg_filter_primitive_convolve_matrix_render (RsvgFilterPrimitive * self,
output = _rsvg_pixbuf_new_cleared (GDK_COLORSPACE_RGB, 1, 8, width, height);
output_pixels = gdk_pixbuf_get_pixels (output);
- for (y = boundarys.y1; y < boundarys.y2; y++)
- for (x = boundarys.x1; x < boundarys.x2; x++)
+ for (y = boundarys.y0; y < boundarys.y1; y++)
+ for (x = boundarys.x0; x < boundarys.x1; x++)
{
for (ch = 0; ch < 3 + !upself->preservealpha; ch++)
{
@@ -997,27 +1181,27 @@ rsvg_filter_primitive_convolve_matrix_render (RsvgFilterPrimitive * self,
sy = y - targety + i * dy;
if (upself->edgemode == 0)
{
- if (sx < boundarys.x1)
- sx = boundarys.x1;
- if (sx >= boundarys.x2)
- sx = boundarys.x2 - 1;
- if (sy < boundarys.y1)
- sy = boundarys.y1;
- if (sy >= boundarys.y2)
- sy = boundarys.y2 - 1;
+ if (sx < boundarys.x0)
+ sx = boundarys.x0;
+ if (sx >= boundarys.x1)
+ sx = boundarys.x1 - 1;
+ if (sy < boundarys.y0)
+ sy = boundarys.y0;
+ if (sy >= boundarys.y1)
+ sy = boundarys.y1 - 1;
}
else if (upself->edgemode == 1)
{
- if (sx < boundarys.x1 || (sx >= boundarys.x2))
- sx = boundarys.x1 + (sx - boundarys.x1) %
- (boundarys.x2 - boundarys.x1);
- if (sy < boundarys.y1 || (sy >= boundarys.y2))
- sy = boundarys.y1 + (sy - boundarys.y1) %
- (boundarys.y2 - boundarys.y1);
+ if (sx < boundarys.x0 || (sx >= boundarys.x1))
+ sx = boundarys.x0 + (sx - boundarys.x0) %
+ (boundarys.x1 - boundarys.x0);
+ if (sy < boundarys.y0 || (sy >= boundarys.y1))
+ sy = boundarys.y0 + (sy - boundarys.y0) %
+ (boundarys.y1 - boundarys.y0);
}
else if (upself->edgemode == 2)
- if (sx < boundarys.x1 || (sx >= boundarys.x2) ||
- sy < boundarys.y1 || (sy >= boundarys.y2))
+ if (sx < boundarys.x0 || (sx >= boundarys.x1) ||
+ sy < boundarys.y0 || (sy >= boundarys.y1))
continue;
kx = upself->orderx - j - 1;
@@ -1226,7 +1410,7 @@ struct _RsvgFilterPrimitiveGaussianBlur
static void
box_blur (GdkPixbuf *in, GdkPixbuf *output, GdkPixbuf *intermediate, gint kw,
- gint kh, FPBox boundarys, RsvgFilterPrimitiveOutput op)
+ gint kh, RsvgIRect boundarys, RsvgFilterPrimitiveOutput op)
{
gint ch;
gint x, y;
@@ -1248,11 +1432,11 @@ box_blur (GdkPixbuf *in, GdkPixbuf *output, GdkPixbuf *intermediate, gint kw,
rowstride = gdk_pixbuf_get_rowstride (in);
- if (kw > boundarys.x2 - boundarys.x1)
- kw = boundarys.x2 - boundarys.x1;
+ if (kw > boundarys.x1 - boundarys.x0)
+ kw = boundarys.x1 - boundarys.x0;
- if (kh > boundarys.y2 - boundarys.y1)
- kh = boundarys.y2 - boundarys.y1;
+ if (kh > boundarys.y1 - boundarys.y0)
+ kh = boundarys.y1 - boundarys.y0;
if (kw >= 1)
@@ -1274,11 +1458,11 @@ box_blur (GdkPixbuf *in, GdkPixbuf *output, GdkPixbuf *intermediate, gint kw,
if (!op.Aused)
continue;
}
- for (y = boundarys.y1; y < boundarys.y2; y++)
+ for (y = boundarys.y0; y < boundarys.y1; y++)
{
sum = 0;
divisor = 0;
- for (x = boundarys.x1; x < boundarys.x1 + kw; x++)
+ for (x = boundarys.x0; x < boundarys.x0 + kw; x++)
{
if (ch != 3)
{
@@ -1291,13 +1475,13 @@ box_blur (GdkPixbuf *in, GdkPixbuf *output, GdkPixbuf *intermediate, gint kw,
sum += in_pixels[4 * x + y * rowstride + ch];
}
- if (x - kw / 2 >= 0 && x - kw / 2 < boundarys.x2)
+ if (x - kw / 2 >= 0 && x - kw / 2 < boundarys.x1)
{
if (divisor > 0)
output_pixels[4 * (x - kw / 2) + y * rowstride + ch] = sum / divisor;
}
}
- for (x = boundarys.x1 + kw; x < boundarys.x2; x++)
+ for (x = boundarys.x0 + kw; x < boundarys.x1; x++)
{
if (ch != 3)
{
@@ -1316,7 +1500,7 @@ box_blur (GdkPixbuf *in, GdkPixbuf *output, GdkPixbuf *intermediate, gint kw,
if (divisor > 0)
output_pixels[4 * (x - kw / 2) + y * rowstride + ch] = sum / divisor;
}
- for (x = boundarys.x2; x < boundarys.x2 + kw; x++)
+ for (x = boundarys.x1; x < boundarys.x1 + kw; x++)
{
if (ch != 3)
{
@@ -1329,7 +1513,7 @@ box_blur (GdkPixbuf *in, GdkPixbuf *output, GdkPixbuf *intermediate, gint kw,
divisor--;
sum -= in_pixels[4 * (x - kw) + y * rowstride + ch];
}
- if (x - kw / 2 >= 0 && x - kw / 2 < boundarys.x2)
+ if (x - kw / 2 >= 0 && x - kw / 2 < boundarys.x1)
{
if (divisor > 0)
output_pixels[4 * (x - kw / 2) + y * rowstride + ch] = sum / divisor;
@@ -1365,12 +1549,12 @@ box_blur (GdkPixbuf *in, GdkPixbuf *output, GdkPixbuf *intermediate, gint kw,
}
- for (x = boundarys.x1; x < boundarys.x2; x++)
+ for (x = boundarys.x0; x < boundarys.x1; x++)
{
sum = 0;
divisor = 0;
- for (y = boundarys.y1; y < boundarys.y1 + kh; y++)
+ for (y = boundarys.y0; y < boundarys.y0 + kh; y++)
{
if (ch != 3)
{
@@ -1383,13 +1567,13 @@ box_blur (GdkPixbuf *in, GdkPixbuf *output, GdkPixbuf *intermediate, gint kw,
divisor++;
sum += in_pixels[4 * x + y * rowstride + ch];
}
- if (y - kh / 2 >= 0 && y - kh / 2 < boundarys.y2)
+ if (y - kh / 2 >= 0 && y - kh / 2 < boundarys.y1)
{
if (divisor > 0)
output_pixels[4 * x + (y - kh / 2) * rowstride + ch] = sum / divisor;
}
}
- for (; y < boundarys.y2; y++)
+ for (; y < boundarys.y1; y++)
{
if (ch != 3)
{
@@ -1408,7 +1592,7 @@ box_blur (GdkPixbuf *in, GdkPixbuf *output, GdkPixbuf *intermediate, gint kw,
if (divisor > 0)
output_pixels[4 * x + (y - kh / 2) * rowstride + ch] = sum / divisor;
}
- for (; y < boundarys.y2 + kh; y++)
+ for (; y < boundarys.y1 + kh; y++)
{
if (ch != 3)
{
@@ -1421,7 +1605,7 @@ box_blur (GdkPixbuf *in, GdkPixbuf *output, GdkPixbuf *intermediate, gint kw,
divisor--;
sum -= in_pixels[4 * x + (y - kh) * rowstride + ch];
}
- if (y - kh / 2 >= 0 && y - kh / 2 < boundarys.y2)
+ if (y - kh / 2 >= 0 && y - kh / 2 < boundarys.y1)
{
if (divisor > 0)
output_pixels[4 * x + (y - kh / 2) * rowstride + ch] = sum / divisor;
@@ -1441,7 +1625,7 @@ box_blur (GdkPixbuf *in, GdkPixbuf *output, GdkPixbuf *intermediate, gint kw,
static void
fast_blur (GdkPixbuf *in, GdkPixbuf *output, gfloat sx,
- gfloat sy, FPBox boundarys, RsvgFilterPrimitiveOutput op)
+ gfloat sy, RsvgIRect boundarys, RsvgFilterPrimitiveOutput op)
{
GdkPixbuf *intermediate1;
GdkPixbuf *intermediate2;
@@ -1476,7 +1660,7 @@ rsvg_filter_primitive_gaussian_blur_render (RsvgFilterPrimitive * self,
GdkPixbuf *output;
GdkPixbuf *in;
- FPBox boundarys;
+ RsvgIRect boundarys;
gfloat sdx, sdy;
RsvgFilterPrimitiveOutput op;
@@ -1616,7 +1800,7 @@ rsvg_filter_primitive_offset_render (RsvgFilterPrimitive * self,
guchar ch;
gint x, y;
gint rowstride, height, width;
- FPBox boundarys;
+ RsvgIRect boundarys;
guchar *in_pixels;
guchar *output_pixels;
@@ -1647,12 +1831,12 @@ rsvg_filter_primitive_offset_render (RsvgFilterPrimitive * self,
ox = ctx->paffine[0] * upself->dx + ctx->paffine[2] * upself->dy;
oy = ctx->paffine[1] * upself->dx + ctx->paffine[3] * upself->dy;
- for (y = boundarys.y1; y < boundarys.y2; y++)
- for (x = boundarys.x1; x < boundarys.x2; x++)
+ for (y = boundarys.y0; y < boundarys.y1; y++)
+ for (x = boundarys.x0; x < boundarys.x1; x++)
{
- if (x - ox < boundarys.x1 || x - ox >= boundarys.x2)
+ if (x - ox < boundarys.x0 || x - ox >= boundarys.x1)
continue;
- if (y - oy < boundarys.y1 || y - oy >= boundarys.y2)
+ if (y - oy < boundarys.y0 || y - oy >= boundarys.y1)
continue;
for (ch = 0; ch < 4; ch++)
@@ -1789,7 +1973,7 @@ rsvg_filter_primitive_merge_render (RsvgFilterPrimitive * self,
RsvgFilterContext * ctx)
{
guint i;
- FPBox boundarys;
+ RsvgIRect boundarys;
RsvgFilterPrimitiveMerge *upself;
@@ -1808,9 +1992,9 @@ rsvg_filter_primitive_merge_render (RsvgFilterPrimitive * self,
if (mn->super.type != RSVG_NODE_FILTER_PRIMITIVE_MERGE_NODE)
continue;
in = rsvg_filter_get_in (mn->in, ctx);
- rsvg_art_alpha_blt (in, boundarys.x1, boundarys.y1, boundarys.x2 - boundarys.x1,
- boundarys.y2 - boundarys.y1, output, boundarys.x1,
- boundarys.y1);
+ rsvg_alpha_blt (in, boundarys.x0, boundarys.y0, boundarys.x1 - boundarys.x0,
+ boundarys.y1 - boundarys.y0, output, boundarys.x0,
+ boundarys.y0);
g_object_unref (G_OBJECT (in));
}
@@ -1963,7 +2147,7 @@ rsvg_filter_primitive_colour_matrix_render (RsvgFilterPrimitive * self,
gint x, y;
gint i;
gint rowstride, height, width;
- FPBox boundarys;
+ RsvgIRect boundarys;
guchar *in_pixels;
guchar *output_pixels;
@@ -1991,8 +2175,8 @@ rsvg_filter_primitive_colour_matrix_render (RsvgFilterPrimitive * self,
output = _rsvg_pixbuf_new_cleared (GDK_COLORSPACE_RGB, 1, 8, width, height);
output_pixels = gdk_pixbuf_get_pixels (output);
- for (y = boundarys.y1; y < boundarys.y2; y++)
- for (x = boundarys.x1; x < boundarys.x2; x++)
+ for (y = boundarys.y0; y < boundarys.y1; y++)
+ for (x = boundarys.x0; x < boundarys.x1; x++)
{
for (ch = 0; ch < 4; ch++)
{
@@ -2315,7 +2499,7 @@ rsvg_filter_primitive_component_transfer_render (RsvgFilterPrimitive *
guint i;
gint temp;
gint rowstride, height, width;
- FPBox boundarys;
+ RsvgIRect boundarys;
RsvgNodeComponentTransferFunc * channels[4];
ComponentTransferFunc functions[4];
@@ -2361,8 +2545,8 @@ rsvg_filter_primitive_component_transfer_render (RsvgFilterPrimitive *
output_pixels = gdk_pixbuf_get_pixels (output);
- for (y = boundarys.y1; y < boundarys.y2; y++)
- for (x = boundarys.x1; x < boundarys.x2; x++)
+ for (y = boundarys.y0; y < boundarys.y1; y++)
+ for (x = boundarys.x0; x < boundarys.x1; x++)
for (c = 0; c < 4; c++)
{
temp = functions[c]((double)in_pixels[y * rowstride + x * 4 + c] / 255.0, channels[c]) * 255.0;
@@ -2552,7 +2736,7 @@ rsvg_filter_primitive_erode_render (RsvgFilterPrimitive * self,
gint x, y;
gint i, j;
gint rowstride, height, width;
- FPBox boundarys;
+ RsvgIRect boundarys;
guchar *in_pixels;
guchar *output_pixels;
@@ -2584,8 +2768,8 @@ rsvg_filter_primitive_erode_render (RsvgFilterPrimitive * self,
output_pixels = gdk_pixbuf_get_pixels (output);
- for (y = boundarys.y1; y < boundarys.y2; y++)
- for (x = boundarys.x1; x < boundarys.x2; x++)
+ for (y = boundarys.y0; y < boundarys.y1; y++)
+ for (x = boundarys.x0; x < boundarys.x1; x++)
for (ch = 0; ch < 4; ch++)
{
if (upself->mode == 0)
@@ -2752,7 +2936,7 @@ rsvg_filter_primitive_composite_render (RsvgFilterPrimitive * self,
guchar i;
gint x, y;
gint rowstride, height, width;
- FPBox boundarys;
+ RsvgIRect boundarys;
guchar *in_pixels;
guchar *in2_pixels;
@@ -2781,8 +2965,8 @@ rsvg_filter_primitive_composite_render (RsvgFilterPrimitive * self,
output_pixels = gdk_pixbuf_get_pixels (output);
if (upself->mode == COMPOSITE_MODE_ARITHMETIC)
- for (y = boundarys.y1; y < boundarys.y2; y++)
- for (x = boundarys.x1; x < boundarys.x2; x++)
+ for (y = boundarys.y0; y < boundarys.y1; y++)
+ for (x = boundarys.x0; x < boundarys.x1; x++)
{
double qr, cr, qa, qb, ca, cb;
@@ -2814,8 +2998,8 @@ rsvg_filter_primitive_composite_render (RsvgFilterPrimitive * self,
}
else
- for (y = boundarys.y1; y < boundarys.y2; y++)
- for (x = boundarys.x1; x < boundarys.x2; x++)
+ for (y = boundarys.y0; y < boundarys.y1; y++)
+ for (x = boundarys.x0; x < boundarys.x1; x++)
{
double qr, cr, qa, qb, ca, cb, Fa, Fb, Fab, Fo;
@@ -3024,7 +3208,7 @@ rsvg_filter_primitive_flood_render (RsvgFilterPrimitive * self,
guchar i;
gint x, y;
gint rowstride, height, width;
- FPBox boundarys;
+ RsvgIRect boundarys;
guchar *output_pixels;
@@ -3044,8 +3228,8 @@ rsvg_filter_primitive_flood_render (RsvgFilterPrimitive * self,
output_pixels = gdk_pixbuf_get_pixels (output);
- for (y = boundarys.y1; y < boundarys.y2; y++)
- for (x = boundarys.x1; x < boundarys.x2; x++)
+ for (y = boundarys.y0; y < boundarys.y1; y++)
+ for (x = boundarys.x0; x < boundarys.x1; x++)
{
for (i = 0; i < 3; i++)
{
@@ -3181,7 +3365,7 @@ rsvg_filter_primitive_displacement_map_render (RsvgFilterPrimitive * self,
guchar ch, xch, ych;
gint x, y;
gint rowstride, height, width;
- FPBox boundarys;
+ RsvgIRect boundarys;
guchar *in_pixels;
guchar *in2_pixels;
@@ -3249,8 +3433,8 @@ rsvg_filter_primitive_displacement_map_render (RsvgFilterPrimitive * self,
ych = 4;
};
- for (y = boundarys.y1; y < boundarys.y2; y++)
- for (x = boundarys.x1; x < boundarys.x2; x++)
+ for (y = boundarys.y0; y < boundarys.y1; y++)
+ for (x = boundarys.x0; x < boundarys.x1; x++)
{
if (xch != 4)
ox = x + upself->scale * ctx->paffine[0] *
@@ -3611,7 +3795,7 @@ rsvg_filter_primitive_turbulence_render (RsvgFilterPrimitive * self,
{
RsvgFilterPrimitiveTurbulence *upself;
gint x, y, tileWidth, tileHeight, rowstride, width, height;
- FPBox boundarys;
+ RsvgIRect boundarys;
guchar *output_pixels;
GdkPixbuf *output;
gdouble affine[6];
@@ -3625,8 +3809,8 @@ rsvg_filter_primitive_turbulence_render (RsvgFilterPrimitive * self,
upself = (RsvgFilterPrimitiveTurbulence *) self;
boundarys = rsvg_filter_primitive_get_bounds (self, ctx);
- tileWidth = (boundarys.x2 - boundarys.x1);
- tileHeight = (boundarys.y2 - boundarys.y1);
+ tileWidth = (boundarys.x1 - boundarys.x0);
+ tileHeight = (boundarys.y1 - boundarys.y0);
output = _rsvg_pixbuf_new_cleared (GDK_COLORSPACE_RGB, 1, 8, width, height);
output_pixels = gdk_pixbuf_get_pixels (output);
@@ -3639,10 +3823,10 @@ rsvg_filter_primitive_turbulence_render (RsvgFilterPrimitive * self,
{
gint i;
double point[2];
- point[0] = affine[0] * (x+boundarys.x1) +
- affine[2] * (y+boundarys.y1) + affine[4];
- point[1] = affine[1] * (x+boundarys.x1) +
- affine[3] * (y+boundarys.y1) + affine[5];
+ point[0] = affine[0] * (x+boundarys.x0) +
+ affine[2] * (y+boundarys.y0) + affine[4];
+ point[1] = affine[1] * (x+boundarys.x0) +
+ affine[3] * (y+boundarys.y0) + affine[5];
for (i = 0; i < 4; i++)
{
@@ -3657,7 +3841,7 @@ rsvg_filter_primitive_turbulence_render (RsvgFilterPrimitive * self,
cr = CLAMP(cr, 0., 255.);
- output_pixels[(4 * (x+boundarys.x1)) + ((y+boundarys.y1) * rowstride) + i] = (guchar)(cr);
+ output_pixels[(4 * (x+boundarys.x0)) + ((y+boundarys.y0) * rowstride) + i] = (guchar)(cr);
}
}
}
@@ -3787,51 +3971,33 @@ static GdkPixbuf *
rsvg_filter_primitive_image_render_in (RsvgFilterPrimitive * self,
RsvgFilterContext * context)
{
- FPBox boundarys;
RsvgDrawingCtx * ctx;
RsvgFilterPrimitiveImage *upself;
int i;
- RsvgNode * parent;
- GdkPixbuf *img, *save;
- RsvgNode *drawable;
+ RsvgNode * drawable;
ctx = context->ctx;
+
upself = (RsvgFilterPrimitiveImage *) self;
if(!upself->href)
return NULL;
- parent = rsvg_defs_lookup (ctx->defs, upself->href->str);
- if (!parent)
+ drawable = rsvg_defs_lookup (ctx->defs, upself->href->str);
+ if (!drawable)
return NULL;
- drawable = (RsvgNode*)parent;
-
- boundarys = rsvg_filter_primitive_get_bounds (self, context);
-
- img = _rsvg_pixbuf_new_cleared (GDK_COLORSPACE_RGB, 1, 8, context->width, context->height);
-
- save = ((RsvgArtRender *)ctx->render)->pixbuf;
- ((RsvgArtRender *)ctx->render)->pixbuf = img;
-
for (i = 0; i < 6; i++)
rsvg_state_current(ctx)->affine[i] = context->paffine[i];
-
- rsvg_state_push(ctx);
-
- rsvg_node_draw (drawable, ctx, 0);
- rsvg_state_pop(ctx);
-
- ((RsvgArtRender *)ctx->render)->pixbuf = save;
- return img;
+ return rsvg_get_image_of_node(ctx, drawable, context->width, context->height);
}
static GdkPixbuf *
rsvg_filter_primitive_image_render_ext (RsvgFilterPrimitive * self,
RsvgFilterContext * ctx)
{
- FPBox boundarys;
+ RsvgIRect boundarys;
RsvgFilterPrimitiveImage *upself;
GdkPixbuf * img;
@@ -3846,17 +4012,18 @@ rsvg_filter_primitive_image_render_ext (RsvgFilterPrimitive * self,
img = rsvg_pixbuf_new_from_href(upself->href->str,
rsvg_handle_get_base_uri (upself->ctx), NULL);
-
+
if(!img)
return NULL;
- intermediate = gdk_pixbuf_new (GDK_COLORSPACE_RGB, 1, 8, boundarys.x2 - boundarys.x1,
- boundarys.y2 - boundarys.y1);
+ intermediate = gdk_pixbuf_new (GDK_COLORSPACE_RGB, 1, 8, boundarys.x1 - boundarys.x0,
+ boundarys.y1 - boundarys.y0);
+
rsvg_art_affine_image(img, intermediate,
ctx->paffine,
- (boundarys.x2 - boundarys.x1) / ctx->paffine[0],
- (boundarys.y2 - boundarys.y1) / ctx->paffine[3]);
+ (boundarys.x1 - boundarys.x0) / ctx->paffine[0],
+ (boundarys.y1 - boundarys.y0) / ctx->paffine[3]);
if (!intermediate)
{
@@ -3874,7 +4041,7 @@ static void
rsvg_filter_primitive_image_render (RsvgFilterPrimitive * self,
RsvgFilterContext * ctx)
{
- FPBox boundarys;
+ RsvgIRect boundarys;
RsvgFilterPrimitiveImage *upself;
RsvgFilterPrimitiveOutput op;
@@ -3896,16 +4063,16 @@ rsvg_filter_primitive_image_render (RsvgFilterPrimitive * self,
if (img)
{
gdk_pixbuf_copy_area (img, 0, 0,
- boundarys.x2 - boundarys.x1,
- boundarys.y2 - boundarys.y1,
- output, boundarys.x1, boundarys.y1);
+ boundarys.x1 - boundarys.x0,
+ boundarys.y1 - boundarys.y0,
+ output, boundarys.x0, boundarys.y0);
g_object_unref (G_OBJECT (img));
}
}
else
{
- gdk_pixbuf_copy_area (img, boundarys.x1, boundarys.y1, boundarys.x2 - boundarys.x1, boundarys.y2 - boundarys.y1,
- output, boundarys.x1, boundarys.y1);
+ gdk_pixbuf_copy_area (img, boundarys.x0, boundarys.y0, boundarys.x1 - boundarys.x0, boundarys.y1 - boundarys.y0,
+ output, boundarys.x0, boundarys.y0);
g_object_unref (G_OBJECT (img));
}
@@ -4194,7 +4361,7 @@ get_light_normal_matrix_y (gint n)
}
static vector3
-get_surface_normal (guchar * I, FPBox boundarys, gint x, gint y,
+get_surface_normal (guchar * I, RsvgIRect boundarys, gint x, gint y,
gdouble dx, gdouble dy, gdouble rawdx, gdouble rawdy, gdouble surfaceScale, gint rowstride)
{
gint mrow, mcol;
@@ -4204,16 +4371,16 @@ get_surface_normal (guchar * I, FPBox boundarys, gint x, gint y,
gdouble Nx, Ny;
vector3 output;
- if (x + dx >= boundarys.x2 - 1)
+ if (x + dx >= boundarys.x1 - 1)
mcol = 2;
- else if (x - dx < boundarys.x1 + 1)
+ else if (x - dx < boundarys.x0 + 1)
mcol = 0;
else
mcol = 1;
- if (y + dy >= boundarys.y2 - 1)
+ if (y + dy >= boundarys.y1 - 1)
mrow = 2;
- else if (y - dy < boundarys.y1 + 1)
+ else if (y - dy < boundarys.y0 + 1)
mrow = 0;
else
mrow = 1;
@@ -4462,7 +4629,7 @@ rsvg_filter_primitive_diffuse_lighting_render (RsvgFilterPrimitive * self,
vector3 colour;
gdouble iaffine[6];
RsvgNodeLightSource * source = NULL;
- FPBox boundarys;
+ RsvgIRect boundarys;
guchar *in_pixels;
guchar *output_pixels;
@@ -4521,8 +4688,8 @@ rsvg_filter_primitive_diffuse_lighting_render (RsvgFilterPrimitive * self,
_rsvg_affine_invert(iaffine, ctx->paffine);
- for (y = boundarys.y1; y < boundarys.y2; y++)
- for (x = boundarys.x1; x < boundarys.x2; x++)
+ for (y = boundarys.y0; y < boundarys.y1; y++)
+ for (x = boundarys.x0; x < boundarys.x1; x++)
{
z = surfaceScale * (double)in_pixels[y * rowstride + x * 4 + 3];
L = get_light_direction(source, x, y, z, iaffine);
@@ -4677,7 +4844,7 @@ rsvg_filter_primitive_specular_lighting_render (RsvgFilterPrimitive * self,
vector3 colour;
vector3 L;
gdouble iaffine[6];
- FPBox boundarys;
+ RsvgIRect boundarys;
RsvgNodeLightSource *source = NULL;
guchar *in_pixels;
@@ -4723,8 +4890,8 @@ rsvg_filter_primitive_specular_lighting_render (RsvgFilterPrimitive * self,
_rsvg_affine_invert(iaffine, ctx->paffine);
- for (y = boundarys.y1; y < boundarys.y2; y++)
- for (x = boundarys.x1; x < boundarys.x2; x++)
+ for (y = boundarys.y0; y < boundarys.y1; y++)
+ for (x = boundarys.x0; x < boundarys.x1; x++)
{
z = in_pixels[y * rowstride + x * 4 + 3] * surfaceScale;
L = get_light_direction(source, x, y, z, iaffine);
@@ -4899,7 +5066,7 @@ rsvg_filter_primitive_tile_render (RsvgFilterPrimitive * self,
{
guchar i;
gint x, y, rowstride;
- FPBox boundarys, oboundarys;
+ RsvgIRect boundarys, oboundarys;
RsvgFilterPrimitiveOutput input;
@@ -4926,15 +5093,15 @@ rsvg_filter_primitive_tile_render (RsvgFilterPrimitive * self,
output_pixels = gdk_pixbuf_get_pixels (output);
- for (y = oboundarys.y1; y < oboundarys.y2; y++)
- for (x = oboundarys.x1; x < oboundarys.x2; x++)
+ for (y = oboundarys.y0; y < oboundarys.y1; y++)
+ for (x = oboundarys.x0; x < oboundarys.x1; x++)
for (i = 0; i < 4; i++)
{
output_pixels[4 * x + y * rowstride + i] =
- in_pixels[(mod((x - boundarys.x1), (boundarys.x2 - boundarys.x1)) +
- boundarys.x1) * 4 +
- (mod((y - boundarys.y1), (boundarys.y2 - boundarys.y1)) +
- boundarys.y1) * rowstride + i];
+ in_pixels[(mod((x - boundarys.x0), (boundarys.x1 - boundarys.x0)) +
+ boundarys.x0) * 4 +
+ (mod((y - boundarys.y0), (boundarys.y1 - boundarys.y0)) +
+ boundarys.y0) * rowstride + i];
}
rsvg_filter_store_result (self->result, output, ctx);
diff --git a/rsvg-filter.h b/rsvg-filter.h
index e6c03d5f..a1e2f8d1 100644
--- a/rsvg-filter.h
+++ b/rsvg-filter.h
@@ -41,8 +41,8 @@ struct _RsvgFilter {
RsvgFilterUnits primitiveunits;
};
-void
-rsvg_filter_render (RsvgFilter *self, GdkPixbuf *source, GdkPixbuf *output, GdkPixbuf *bg, RsvgDrawingCtx *context);
+GdkPixbuf *
+rsvg_filter_render (RsvgFilter *self, GdkPixbuf *source, GdkPixbuf *bg, RsvgDrawingCtx *context, RsvgIRect * dimentions);
RsvgNode *
rsvg_new_filter (void);
@@ -108,9 +108,17 @@ RsvgNode *
rsvg_new_filter_primitive_tile (void);
void
-rsvg_filter_adobe_blend(gint modenum, GdkPixbuf *in, GdkPixbuf *bg, GdkPixbuf *output,
+rsvg_filter_adobe_blend(gint modenum, GdkPixbuf *in, GdkPixbuf *bg,
+ GdkPixbuf *output, RsvgIRect boundarys,
RsvgDrawingCtx * ctx);
+void rsvg_alpha_blt (GdkPixbuf * src, gint srcx, gint srcy,
+ gint srcwidth, gint srcheight,
+ GdkPixbuf * dst, gint dstx, gint dsty);
+
+void rsvg_art_affine_image(const GdkPixbuf *img, GdkPixbuf *intermediate,
+ double * affine, double w, double h);
+
G_END_DECLS
#endif
diff --git a/rsvg-image.c b/rsvg-image.c
index 252c9125..c48dee60 100644
--- a/rsvg-image.c
+++ b/rsvg-image.c
@@ -508,7 +508,7 @@ rsvg_node_image_draw (RsvgNode * self, RsvgDrawingCtx *ctx,
rsvg_push_discrete_layer(ctx);
- if (!z->overflow && (aspect_ratio & RSVG_ASPECT_RATIO_SLICE)){
+ if (!rsvg_state_current(ctx)->overflow && (aspect_ratio & RSVG_ASPECT_RATIO_SLICE)){
rsvg_add_clipping_rect(ctx, x, y, w, h);
}
@@ -569,8 +569,6 @@ rsvg_node_image_set_atts (RsvgNode *self, RsvgHandle *ctx, RsvgPropertyBag *atts
}
if ((value = rsvg_property_bag_lookup (atts, "preserveAspectRatio")))
image->preserve_aspect_ratio = rsvg_css_parse_aspect_ratio (value);
- if ((value = rsvg_property_bag_lookup (atts, "overflow")))
- image->overflow = rsvg_css_parse_overflow(value);
rsvg_parse_style_attrs (ctx, image->super.state, "image", klazz, id, atts);
}
@@ -587,7 +585,6 @@ rsvg_new_image (void)
image->y = 0;
image->w = -1;
image->h = -1;
- image->overflow = FALSE;
image->super.state = g_new(RsvgState, 1);
rsvg_state_init(image->super.state);
image->super.type = RSVG_NODE_PATH;
diff --git a/rsvg-image.h b/rsvg-image.h
index 24db9af2..8b01efab 100644
--- a/rsvg-image.h
+++ b/rsvg-image.h
@@ -40,7 +40,6 @@ typedef struct _RsvgNodeImage RsvgNodeImage;
struct _RsvgNodeImage {
RsvgNode super;
- gboolean overflow;
gint preserve_aspect_ratio, x, y, w, h;
GdkPixbuf *img;
};
diff --git a/rsvg-marker.c b/rsvg-marker.c
index fc1551e3..34f0b0e3 100644
--- a/rsvg-marker.c
+++ b/rsvg-marker.c
@@ -86,8 +86,6 @@ rsvg_node_marker_set_atts (RsvgNode * self, RsvgHandle *ctx, RsvgPropertyBag *at
}
if ((value = rsvg_property_bag_lookup (atts, "preserveAspectRatio")))
marker->preserve_aspect_ratio = rsvg_css_parse_aspect_ratio (value);
- if ((value = rsvg_property_bag_lookup (atts, "overflow")))
- marker->overflow = rsvg_css_parse_overflow(value);
rsvg_parse_style_attrs (ctx, self->state, "marker", klazz, id, atts);
}
}
@@ -100,7 +98,6 @@ rsvg_new_marker (void)
_rsvg_node_init(&marker->super);
marker->orient = 0;
marker->orientAuto = FALSE;
- marker->overflow = FALSE;
marker->preserve_aspect_ratio = RSVG_ASPECT_RATIO_XMID_YMID;
marker->refX = 0;
marker->refY = 0;
diff --git a/rsvg-marker.h b/rsvg-marker.h
index 2c8e02ad..e4f382b0 100644
--- a/rsvg-marker.h
+++ b/rsvg-marker.h
@@ -37,7 +37,7 @@ struct _RsvgMarker {
double refX, refY, orient;
double vbx, vby, vbw, vbh, width, height;
gint preserve_aspect_ratio;
- gboolean vbox, orientAuto, overflow;
+ gboolean vbox, orientAuto;
};
RsvgNode *
diff --git a/rsvg-private.h b/rsvg-private.h
index 83dbf177..92619c64 100644
--- a/rsvg-private.h
+++ b/rsvg-private.h
@@ -47,6 +47,7 @@ typedef struct _RsvgDefs RsvgDefs;
typedef struct _RsvgNode RsvgNode;
typedef struct _RsvgFilter RsvgFilter;
typedef struct _RsvgNodeChars RsvgNodeChars;
+typedef struct _RsvgIRect RsvgIRect;
/* prepare for gettext */
#ifndef _
@@ -148,6 +149,8 @@ struct RsvgRender {
void (* push_discrete_layer) (RsvgDrawingCtx *ctx);
void (* add_clipping_rect) (RsvgDrawingCtx *ctx,
double x, double y, double w, double h);
+ void * (* get_image_of_node) (RsvgDrawingCtx *ctx, RsvgNode * drawable,
+ double w, double h);
};
struct RsvgDimensionData {
@@ -156,6 +159,10 @@ struct RsvgDimensionData {
gdouble em, ex;
};
+struct _RsvgIRect {
+ int x0, y0, x1, y1;
+};
+
typedef enum {
RSVG_SIZE_ZOOM,
RSVG_SIZE_WH,
@@ -263,6 +270,8 @@ void rsvg_render_image (RsvgDrawingCtx *ctx, GdkPixbuf * pb,
void rsvg_render_free (RsvgRender * render);
void rsvg_add_clipping_rect (RsvgDrawingCtx *ctx, double x, double y,
double w, double h);
+void * rsvg_get_image_of_node(RsvgDrawingCtx *ctx, RsvgNode * drawable,
+ double w, double h);
void
diff --git a/rsvg-structure.c b/rsvg-structure.c
index 3fc0618f..367454de 100644
--- a/rsvg-structure.c
+++ b/rsvg-structure.c
@@ -195,9 +195,6 @@ rsvg_node_use_draw (RsvgNode * self, RsvgDrawingCtx *ctx,
(symbol->preserve_aspect_ratio,
symbol->width, symbol->height,
&width, &height, &x, &y);
-
- if (!symbol->overflow)
- rsvg_add_clipping_rect (ctx, x, y, width, height);
_rsvg_affine_translate(affine, x, y);
_rsvg_affine_multiply(state->affine, affine, state->affine);
@@ -208,6 +205,10 @@ rsvg_node_use_draw (RsvgNode * self, RsvgDrawingCtx *ctx,
-symbol->y);
_rsvg_affine_multiply(state->affine, affine, state->affine);
+ if (!state->overflow ||
+ (!state->has_overflow && child->state->overflow))
+ rsvg_add_clipping_rect (ctx, symbol->x, symbol->y,
+ symbol->width, symbol->height);
} else {
_rsvg_affine_translate(affine, use->x, use->y);
_rsvg_affine_multiply(state->affine, affine, state->affine);
@@ -244,11 +245,12 @@ rsvg_node_svg_draw (RsvgNode * self, RsvgDrawingCtx *ctx,
rsvg_push_discrete_layer (ctx);
- if (!sself->overflow && self->parent)
+ state = rsvg_state_current (ctx);
+
+ if (!state->overflow && self->parent)
{
rsvg_add_clipping_rect(ctx, sself->x, sself->y, sself->w, sself->h);
}
- state = rsvg_state_current (ctx);
if (sself->has_vbox && sself->hasw && sself->hash)
{
@@ -332,8 +334,6 @@ rsvg_node_svg_set_atts (RsvgNode * self, RsvgHandle *ctx, RsvgPropertyBag *atts)
id = value;
rsvg_defs_register_name (ctx->defs, value, &svg->super);
}
- if ((value = rsvg_property_bag_lookup (atts, "overflow")))
- svg->overflow = rsvg_css_parse_overflow(value);
}
}
@@ -351,7 +351,6 @@ rsvg_new_svg (void)
svg->super.type = RSVG_NODE_PATH;
svg->super.draw = rsvg_node_svg_draw;
svg->super.set_atts = rsvg_node_svg_set_atts;
- svg->overflow = FALSE;
return &svg->super;
}
@@ -437,8 +436,6 @@ rsvg_node_symbol_set_atts(RsvgNode *self, RsvgHandle *ctx, RsvgPropertyBag *atts
}
if ((value = rsvg_property_bag_lookup (atts, "preserveAspectRatio")))
symbol->preserve_aspect_ratio = rsvg_css_parse_aspect_ratio (value);
- if ((value = rsvg_property_bag_lookup (atts, "overflow")))
- symbol->overflow = rsvg_css_parse_overflow(value);
}
rsvg_parse_style_attrs (ctx, self->state, "symbol", klazz, id, atts);
@@ -452,7 +449,6 @@ rsvg_new_symbol(void)
symbol = g_new (RsvgNodeSymbol, 1);
_rsvg_node_init(&symbol->super);
symbol->has_vbox = 0;
- symbol->overflow = 0;
symbol->preserve_aspect_ratio = RSVG_ASPECT_RATIO_XMID_YMID;
symbol->super.type = RSVG_NODE_SYMBOL;
symbol->super.draw = _rsvg_node_draw_nothing;
diff --git a/rsvg-structure.h b/rsvg-structure.h
index 8876ac7e..c6a72516 100644
--- a/rsvg-structure.h
+++ b/rsvg-structure.h
@@ -54,7 +54,7 @@ struct _RsvgNodeGroup {
struct _RsvgNodeSymbol {
RsvgNode super;
gint preserve_aspect_ratio;
- gboolean overflow, has_vbox;
+ gboolean has_vbox;
double x, y, width, height;
};
@@ -71,7 +71,7 @@ struct _RsvgNodeSvg {
int hasw :1;
int hash :1;
gdouble vbx, vby, vbw, vbh;
- gboolean overflow, has_vbox;
+ gboolean has_vbox;
GdkPixbuf *img;
};
diff --git a/rsvg-styles.c b/rsvg-styles.c
index 1e0bb57f..91e7202b 100644
--- a/rsvg-styles.c
+++ b/rsvg-styles.c
@@ -68,7 +68,8 @@ rsvg_state_init (RsvgState *state)
state->stop_opacity = 0xff;
state->fill_rule = FILL_RULE_NONZERO;
state->clip_rule = FILL_RULE_NONZERO;
- state->backgroundnew = FALSE;
+ state->backgroundnew = FALSE;
+ state->overflow = FALSE;
state->font_family = g_strdup (RSVG_DEFAULT_FONT);
state->font_size = 12.0;
@@ -117,6 +118,7 @@ rsvg_state_init (RsvgState *state)
state->has_startMarker = FALSE;
state->has_middleMarker = FALSE;
state->has_endMarker = FALSE;
+ state->has_overflow = FALSE;
}
typedef int (*InheritanceFunction) (int dst, int src);
@@ -171,6 +173,8 @@ rsvg_state_inherit_run (RsvgState *dst, const RsvgState *src,
dst->fill_rule = src->fill_rule;
if (function(dst->has_clip_rule, src->has_clip_rule))
dst->clip_rule = src->clip_rule;
+ if (function(dst->overflow, src->overflow))
+ dst->overflow = src->overflow;
if (function(dst->has_stroke_server, src->has_stroke_server))
{
rsvg_paint_server_ref (src->stroke);
@@ -392,6 +396,13 @@ rsvg_parse_style_arg (RsvgHandle *ctx, RsvgState *state, const char *str)
{
state->clip_path_ref = rsvg_clip_path_parse(ctx->defs, str + arg_off);
}
+ else if (rsvg_css_param_match (str, "overflow"))
+ {
+ if (strcmp(str + arg_off, "inherit"))
+ {
+ state->overflow = rsvg_css_parse_overflow (str + arg_off, &state->has_overflow);
+ }
+ }
else if (rsvg_css_param_match (str, "enable-background"))
{
if (!strcmp (str + arg_off, "new"))
@@ -760,6 +771,7 @@ rsvg_parse_style_pairs (RsvgHandle *ctx, RsvgState *state,
rsvg_lookup_parse_style_pair (ctx, state, "marker-mid", atts);
rsvg_lookup_parse_style_pair (ctx, state, "marker-start", atts);
rsvg_lookup_parse_style_pair (ctx, state, "opacity", atts);
+ rsvg_lookup_parse_style_pair (ctx, state, "overflow", atts);
rsvg_lookup_parse_style_pair (ctx, state, "stop-color", atts);
rsvg_lookup_parse_style_pair (ctx, state, "stop-opacity", atts);
rsvg_lookup_parse_style_pair (ctx, state, "stroke", atts);
diff --git a/rsvg-styles.h b/rsvg-styles.h
index 06e3376a..d5298cf9 100644
--- a/rsvg-styles.h
+++ b/rsvg-styles.h
@@ -104,6 +104,9 @@ struct _RsvgState {
gint clip_rule;
gboolean has_clip_rule;
+ gboolean overflow;
+ gboolean has_overflow;
+
RsvgPaintServer *stroke;
gboolean has_stroke_server;
guint8 stroke_opacity; /* 0..255 */