diff options
-rw-r--r-- | ChangeLog | 7 | ||||
-rw-r--r-- | Makefile.am | 6 | ||||
-rw-r--r-- | rsvg-art-composite.c | 247 | ||||
-rw-r--r-- | rsvg-art-composite.h | 7 | ||||
-rw-r--r-- | rsvg-art-draw.c | 17 | ||||
-rw-r--r-- | rsvg-art-render.c | 1 | ||||
-rw-r--r-- | rsvg-art-render.h | 2 | ||||
-rw-r--r-- | rsvg-base.c | 8 | ||||
-rw-r--r-- | rsvg-css.c | 11 | ||||
-rw-r--r-- | rsvg-css.h | 2 | ||||
-rw-r--r-- | rsvg-filter.c | 623 | ||||
-rw-r--r-- | rsvg-filter.h | 14 | ||||
-rw-r--r-- | rsvg-image.c | 5 | ||||
-rw-r--r-- | rsvg-image.h | 1 | ||||
-rw-r--r-- | rsvg-marker.c | 3 | ||||
-rw-r--r-- | rsvg-marker.h | 2 | ||||
-rw-r--r-- | rsvg-private.h | 9 | ||||
-rw-r--r-- | rsvg-structure.c | 18 | ||||
-rw-r--r-- | rsvg-structure.h | 4 | ||||
-rw-r--r-- | rsvg-styles.c | 14 | ||||
-rw-r--r-- | rsvg-styles.h | 3 |
21 files changed, 523 insertions, 481 deletions
@@ -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) { @@ -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; } + @@ -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 */ |