From 627be678d2d05ff2b85747f878ea014f6314100f Mon Sep 17 00:00:00 2001 From: tavmjong Date: Sun, 3 Feb 2008 18:32:59 +0000 Subject: [PATCH] Allow relative paths to be used for images. Fix missing left and top pixel rows in image. --- src/display/nr-filter-image.cpp | 36 ++++++++++++++++++++++++++------- src/display/nr-filter-image.h | 2 ++ src/sp-feimage.cpp | 7 ++++++- src/sp-feimage.h | 1 + 4 files changed, 38 insertions(+), 8 deletions(-) diff --git a/src/display/nr-filter-image.cpp b/src/display/nr-filter-image.cpp index f570d363a..cc42e5e4c 100644 --- a/src/display/nr-filter-image.cpp +++ b/src/display/nr-filter-image.cpp @@ -8,6 +8,7 @@ * * Released under GNU GPL, read the file 'COPYING' for more information */ +#include "document.h" #include "display/nr-arena-item.h" #include "display/nr-filter.h" #include "display/nr-filter-image.h" @@ -19,6 +20,7 @@ FilterImage::FilterImage() { feImageHref=NULL; image_pixbuf=NULL; + document=NULL; } FilterPrimitive * FilterImage::create() { @@ -35,16 +37,28 @@ int FilterImage::render(FilterSlot &slot, FilterUnits const &units) { if (!image_pixbuf){ try { - image = Gdk::Pixbuf::create_from_file(feImageHref); + gchar *fullname = feImageHref; + if ( !g_file_test( fullname, G_FILE_TEST_EXISTS ) ) { + // Try to load from relative postion combined with document base + if( document ) { + fullname = g_build_filename( document->base, feImageHref, NULL ); + } + } + if ( !g_file_test( fullname, G_FILE_TEST_EXISTS ) ) { + // Should display Broken Image png. + g_warning("FilterImage::render: Can not find: %s", feImageHref ); + } + image = Gdk::Pixbuf::create_from_file(fullname); + if( fullname != feImageHref ) g_free( fullname ); } catch (const Glib::FileError & e) { - g_warning("caught Glib::FileError in FilterImage::render"); + g_warning("caught Glib::FileError in FilterImage::render %i", e.code() ); return 0; } catch (const Gdk::PixbufError & e) { - g_warning("Gdk::PixbufError in FilterImage::render"); + g_warning("Gdk::PixbufError in FilterImage::render: %i", e.code() ); return 0; } if ( !image ) return 0; @@ -78,10 +92,14 @@ int FilterImage::render(FilterSlot &slot, FilterUnits const &units) { for (x=x0; x < x1; x++){ for (y=y0; y < y1; y++){ //TODO: use interpolation - coordx = int(scaleX * ((x * unit_trans[0] + unit_trans[4]) - feImageX)); - coordy = int(scaleY * ((y * unit_trans[3] + unit_trans[5]) - feImageY)); - - if (coordx > 0 && coordx < width && coordy > 0 && coordy < height){ + // Temporarily add 0.5 so we sample center of "cell" + double indexX = scaleX * (((x+0.5) * unit_trans[0] + unit_trans[4]) - feImageX); + double indexY = scaleY * (((y+0.5) * unit_trans[3] + unit_trans[5]) - feImageY); + // coordx == 0 and coordy == 0 must be included, but we must protect + // against negative numbers which round up to 0 with (int). + coordx = ( indexX >= 0 ? int( indexX ) : -1 ); + coordy = ( indexY >= 0 ? int( indexY ) : -1 ); + if (coordx >= 0 && coordx < width && coordy >= 0 && coordy < height){ out_data[4*((x - x0)+w*(y - y0))] = (unsigned char) image_pixbuf[3*coordx + rowstride*coordy]; //Red out_data[4*((x - x0)+w*(y - y0)) + 1] = (unsigned char) image_pixbuf[3*coordx + rowstride*coordy + 1]; //Green out_data[4*((x - x0)+w*(y - y0)) + 2] = (unsigned char) image_pixbuf[3*coordx + rowstride*coordy + 2]; //Blue @@ -100,6 +118,10 @@ void FilterImage::set_href(const gchar *href){ feImageHref = (href) ? g_strdup (href) : NULL; } +void FilterImage::set_document(SPDocument *doc){ + document = doc; +} + void FilterImage::set_region(SVGLength x, SVGLength y, SVGLength width, SVGLength height){ feImageX=x.computed; feImageY=y.computed; diff --git a/src/display/nr-filter-image.h b/src/display/nr-filter-image.h index 47bfe157b..afa9f798c 100644 --- a/src/display/nr-filter-image.h +++ b/src/display/nr-filter-image.h @@ -27,9 +27,11 @@ public: virtual int render(FilterSlot &slot, FilterUnits const &units); virtual FilterTraits get_input_traits(); + void set_document( SPDocument *document ); void set_href(const gchar *href); void set_region(SVGLength x, SVGLength y, SVGLength width, SVGLength height); private: + SPDocument *document; gchar *feImageHref; guint8* image_pixbuf; Glib::RefPtr image; diff --git a/src/sp-feimage.cpp b/src/sp-feimage.cpp index 7387d2a80..271baa591 100644 --- a/src/sp-feimage.cpp +++ b/src/sp-feimage.cpp @@ -1,4 +1,4 @@ - #define __SP_FEIMAGE_CPP__ +#define __SP_FEIMAGE_CPP__ /** \file * SVG implementation. @@ -93,6 +93,10 @@ sp_feImage_init(SPFeImage */*feImage*/) static void sp_feImage_build(SPObject *object, SPDocument *document, Inkscape::XML::Node *repr) { + // Save document reference so we can load images with relative paths. + SPFeImage *feImage = SP_FEIMAGE(object); + feImage->document = document; + if (((SPObjectClass *) feImage_parent_class)->build) { ((SPObjectClass *) feImage_parent_class)->build(object, document, repr); } @@ -213,6 +217,7 @@ static void sp_feImage_build_renderer(SPFilterPrimitive *primitive, NR::Filter * sp_filter_primitive_renderer_common(primitive, nr_primitive); nr_image->set_region(sp_image->x, sp_image->y, sp_image->width, sp_image->height); nr_image->set_href(sp_image->href); + nr_image->set_document(sp_image->document); } /* diff --git a/src/sp-feimage.h b/src/sp-feimage.h index 0c0289d6e..cf80a3166 100644 --- a/src/sp-feimage.h +++ b/src/sp-feimage.h @@ -25,6 +25,7 @@ struct SPFeImage : public SPFilterPrimitive { /** IMAGE ATTRIBUTES HERE */ gchar *href; SVGLength x, y, height, width; + SPDocument *document; }; struct SPFeImageClass { -- 2.30.2