Commit 37bb778b authored by Caleb Michael Moore's avatar Caleb Michael Moore

image fixes

parent 40e7c1f4
2004-07-18 Caleb Moore <c.moore@student.unsw.edu.au>
* rsvg-filter.c: made feImage work better, now it transforms it better.
* rsvg-shapes.c: fixed filters on images and bounding boxes on images
2004-07-17 Dom Lachowicz <cinamod@hotmail.com> 2004-07-17 Dom Lachowicz <cinamod@hotmail.com>
* rsvg.[ch]: Bug #147662 * rsvg.[ch]: Bug #147662
......
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
#include "rsvg-shapes.h" #include "rsvg-shapes.h"
#include "rsvg-css.h" #include "rsvg-css.h"
#include <libart_lgpl/art_rgba.h> #include <libart_lgpl/art_rgba.h>
#include <libart_lgpl/art_affine.h>
#include <string.h> #include <string.h>
#include <math.h> #include <math.h>
...@@ -4024,6 +4025,19 @@ rsvg_filter_primitive_image_render_ext (RsvgFilterPrimitive * self, ...@@ -4024,6 +4025,19 @@ rsvg_filter_primitive_image_render_ext (RsvgFilterPrimitive * self,
{ {
FPBox boundarys; FPBox boundarys;
RsvgFilterPrimitiveImage *oself; RsvgFilterPrimitiveImage *oself;
GdkPixbuf * img;
double tmp_affine[6];
double tmp_tmp_affine[6];
double inv_tmp_affine[6];
GdkPixbuf * intermediate;
int intstride;
int basestride;
int basex, basey;
guchar * intpix;
guchar * basepix;
int i, j, k, basebpp;
gboolean has_alpha;
oself = (RsvgFilterPrimitiveImage *) self; oself = (RsvgFilterPrimitiveImage *) self;
...@@ -4032,11 +4046,63 @@ rsvg_filter_primitive_image_render_ext (RsvgFilterPrimitive * self, ...@@ -4032,11 +4046,63 @@ rsvg_filter_primitive_image_render_ext (RsvgFilterPrimitive * self,
boundarys = rsvg_filter_primitive_get_bounds (self, ctx); boundarys = rsvg_filter_primitive_get_bounds (self, ctx);
return rsvg_pixbuf_new_from_href(oself->href->str, img = rsvg_pixbuf_new_from_href(oself->href->str,
rsvg_handle_get_base_uri (oself->ctx), rsvg_handle_get_base_uri (oself->ctx), NULL);
has_alpha = gdk_pixbuf_get_has_alpha (img);
for (i = 0; i < 6; i++)
tmp_affine[i] = ctx->paffine[i];
art_affine_invert(inv_tmp_affine, tmp_affine);
/*scale to w and h*/
tmp_tmp_affine[0] = (double)gdk_pixbuf_get_width (img) / (double)(boundarys.x2 - boundarys.x1);
tmp_tmp_affine[3] = (double)gdk_pixbuf_get_height (img) / (double)(boundarys.y2 - boundarys.y1);
tmp_tmp_affine[1] = tmp_tmp_affine[2] = tmp_tmp_affine[4] = tmp_tmp_affine[5] = 0;
art_affine_multiply(inv_tmp_affine, inv_tmp_affine, tmp_tmp_affine);
intermediate = gdk_pixbuf_new (GDK_COLORSPACE_RGB, 1, 8,
boundarys.x2 - boundarys.x1, boundarys.x2 - boundarys.x1,
boundarys.y2 - boundarys.y1, boundarys.y2 - boundarys.y1);
FALSE, NULL);
if (!intermediate)
{
g_object_unref (G_OBJECT (img));
return NULL;
}
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;
/*apply the transformation*/
for (i = 0; i < gdk_pixbuf_get_width (intermediate); i++)
for (j = 0; j < gdk_pixbuf_get_height (intermediate); j++)
{
basex = inv_tmp_affine[0] * i + inv_tmp_affine[2] * j + inv_tmp_affine[4];
basey = inv_tmp_affine[1] * i + inv_tmp_affine[3] * j + inv_tmp_affine[5];
if (basex < 0 || basey < 0
|| basex >= gdk_pixbuf_get_width (img)
|| basey >= gdk_pixbuf_get_height (img))
{
for (k = 0; k < 4; k++)
intpix[i * 4 + j * intstride + k] = 0;
}
else
{
for (k = 0; k < basebpp; k++)
intpix[i * 4 + j * intstride + k] = basepix[basebpp * basex + basey * basestride + k];
if (!has_alpha)
intpix[i * 4 + j * intstride + 3] = 255;
}
}
g_object_unref (G_OBJECT (img));
return intermediate;
} }
static void static void
......
...@@ -1289,9 +1289,6 @@ static gboolean utf8_base64_decode(char ** binptr, size_t * binlen, const char * ...@@ -1289,9 +1289,6 @@ static gboolean utf8_base64_decode(char ** binptr, size_t * binlen, const char *
static GdkPixbuf * static GdkPixbuf *
rsvg_pixbuf_new_from_data_at_size (const char *data, rsvg_pixbuf_new_from_data_at_size (const char *data,
int width,
int height,
gboolean keep_aspect_ratio,
GError **error) GError **error)
{ {
GdkPixbufLoader *loader; GdkPixbufLoader *loader;
...@@ -1301,7 +1298,6 @@ rsvg_pixbuf_new_from_data_at_size (const char *data, ...@@ -1301,7 +1298,6 @@ rsvg_pixbuf_new_from_data_at_size (const char *data,
size_t buffer_len, buffer_max_len, data_len; size_t buffer_len, buffer_max_len, data_len;
g_return_val_if_fail (data != NULL, NULL); g_return_val_if_fail (data != NULL, NULL);
g_return_val_if_fail (width > 0 && height > 0, NULL);
while (*data) if (*data++ == ',') break; while (*data) if (*data++ == ',') break;
...@@ -1377,9 +1373,6 @@ rsvg_get_file_path (const gchar * filename, const gchar *basedir) ...@@ -1377,9 +1373,6 @@ rsvg_get_file_path (const gchar * filename, const gchar *basedir)
static GdkPixbuf * static GdkPixbuf *
rsvg_pixbuf_new_from_file_at_size (const char *filename, rsvg_pixbuf_new_from_file_at_size (const char *filename,
const char *base_uri, const char *base_uri,
int width,
int height,
gboolean keep_aspect_ratio,
GError **error) GError **error)
{ {
GdkPixbufLoader *loader; GdkPixbufLoader *loader;
...@@ -1451,9 +1444,6 @@ rsvg_pixbuf_new_from_file_at_size (const char *filename, ...@@ -1451,9 +1444,6 @@ rsvg_pixbuf_new_from_file_at_size (const char *filename,
static GdkPixbuf * static GdkPixbuf *
rsvg_pixbuf_new_from_vfs_at_size (const char *filename, rsvg_pixbuf_new_from_vfs_at_size (const char *filename,
const char *base_uri, const char *base_uri,
int width,
int height,
gboolean keep_aspect_ratio,
GError **error) GError **error)
{ {
GdkPixbufLoader *loader; GdkPixbufLoader *loader;
...@@ -1465,7 +1455,6 @@ rsvg_pixbuf_new_from_vfs_at_size (const char *filename, ...@@ -1465,7 +1455,6 @@ rsvg_pixbuf_new_from_vfs_at_size (const char *filename,
GnomeVFSResult res; GnomeVFSResult res;
g_return_val_if_fail (filename != NULL, NULL); g_return_val_if_fail (filename != NULL, NULL);
g_return_val_if_fail (width > 0 && height > 0, NULL);
if (!gnome_vfs_initialized()) if (!gnome_vfs_initialized())
gnome_vfs_init(); gnome_vfs_init();
...@@ -1540,22 +1529,19 @@ rsvg_pixbuf_new_from_vfs_at_size (const char *filename, ...@@ -1540,22 +1529,19 @@ rsvg_pixbuf_new_from_vfs_at_size (const char *filename,
GdkPixbuf * GdkPixbuf *
rsvg_pixbuf_new_from_href (const char *href, rsvg_pixbuf_new_from_href (const char *href,
const char *base_uri, const char *base_uri,
int w,
int h,
gboolean keep_aspect_ratio,
GError **err) GError **err)
{ {
GdkPixbuf * img = NULL; GdkPixbuf * img = NULL;
if(!strncmp(href, "data:", 5)) if(!strncmp(href, "data:", 5))
img = rsvg_pixbuf_new_from_data_at_size (href, w, h, keep_aspect_ratio, err); img = rsvg_pixbuf_new_from_data_at_size (href, err);
if(!img) if(!img)
img = rsvg_pixbuf_new_from_file_at_size (href, base_uri, w, h, keep_aspect_ratio, err); img = rsvg_pixbuf_new_from_file_at_size (href, base_uri, err);
#ifdef HAVE_GNOME_VFS #ifdef HAVE_GNOME_VFS
if(!img) if(!img)
img = rsvg_pixbuf_new_from_vfs_at_size (href, base_uri, w, h, keep_aspect_ratio, err); img = rsvg_pixbuf_new_from_vfs_at_size (href, base_uri, err);
#endif #endif
return img; return img;
...@@ -1627,7 +1613,7 @@ rsvg_start_image (RsvgHandle *ctx, RsvgPropertyBag *atts) ...@@ -1627,7 +1613,7 @@ rsvg_start_image (RsvgHandle *ctx, RsvgPropertyBag *atts)
/* figure out if image is visible or not */ /* figure out if image is visible or not */
if (!state->visible || !state->cond_true) if (!state->visible || !state->cond_true)
return; return;
img = rsvg_pixbuf_new_from_href (href, rsvg_handle_get_base_uri (ctx), w, h, (aspect_ratio != RSVG_ASPECT_RATIO_NONE), &err); img = rsvg_pixbuf_new_from_href (href, rsvg_handle_get_base_uri (ctx), &err);
if (!img) if (!img)
{ {
...@@ -1727,15 +1713,27 @@ rsvg_start_image (RsvgHandle *ctx, RsvgPropertyBag *atts) ...@@ -1727,15 +1713,27 @@ rsvg_start_image (RsvgHandle *ctx, RsvgPropertyBag *atts)
ctx->pixbuf, ctx->pixbuf,
0, 0); 0, 0);
rsvg_pop_discrete_layer(ctx); temprect.x0 = gdk_pixbuf_get_width (intermediate);
temprect.y0 = gdk_pixbuf_get_height (intermediate);
temprect.x1 = 0;
temprect.y1 = 0;
for (i = 0; i < 2; i++)
for (j = 0; j < 2; j++)
{
basex = tmp_affine[0] * w * i + tmp_affine[2] * h * j + tmp_affine[4];
basey = tmp_affine[1] * w * i + tmp_affine[3] * h * j + tmp_affine[5];
temprect.x0 = MIN(basex, temprect.x0);
temprect.y0 = MIN(basey, temprect.y0);
temprect.x1 = MAX(basex, temprect.x1);
temprect.y1 = MAX(basey, temprect.y1);
}
/*fix me, this is not the propper rectangle*/
temprect.x0 = 0;;
temprect.y0 = 0;;
temprect.x1 = gdk_pixbuf_get_width (intermediate);
temprect.y1 = gdk_pixbuf_get_height (intermediate);
art_irect_union(&ctx->bbox, &ctx->bbox, &temprect); art_irect_union(&ctx->bbox, &ctx->bbox, &temprect);
rsvg_pop_discrete_layer(ctx);
g_object_unref (G_OBJECT (intermediate));
} }
void void
......
...@@ -98,9 +98,6 @@ rsvg_marker_parse (const RsvgDefs * defs, const char *str); ...@@ -98,9 +98,6 @@ rsvg_marker_parse (const RsvgDefs * defs, const char *str);
GdkPixbuf * GdkPixbuf *
rsvg_pixbuf_new_from_href (const char *href, rsvg_pixbuf_new_from_href (const char *href,
const char *base_uri, const char *base_uri,
int w,
int h,
gboolean keep_aspect_ratio,
GError **err); GError **err);
void rsvg_defs_drawable_draw (RsvgDefsDrawable * self, RsvgHandle *ctx, void rsvg_defs_drawable_draw (RsvgDefsDrawable * self, RsvgHandle *ctx,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment