Code

Allow relative paths to be used for images.
authortavmjong <tavmjong@users.sourceforge.net>
Sun, 3 Feb 2008 18:32:59 +0000 (18:32 +0000)
committertavmjong <tavmjong@users.sourceforge.net>
Sun, 3 Feb 2008 18:32:59 +0000 (18:32 +0000)
Fix missing left and top pixel rows in image.

src/display/nr-filter-image.cpp
src/display/nr-filter-image.h
src/sp-feimage.cpp
src/sp-feimage.h

index f570d363a762b5b344447d6d390d870312792ef0..cc42e5e4c579c077e29521cfdb2525d008c6f6d8 100644 (file)
@@ -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;
index 47bfe157b8f4acce6f8540858f22623c17e96a2c..afa9f798c87b3d8b5a9d92e9a8cb72ffffad8a83 100644 (file)
@@ -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<Gdk::Pixbuf> image;
index 7387d2a80579d2b36766e87f8e2b556908aa21f1..271baa5914a9a978a33b4307541aa013812e5050 100644 (file)
@@ -1,4 +1,4 @@
-       #define __SP_FEIMAGE_CPP__
+#define __SP_FEIMAGE_CPP__
 
 /** \file
  * SVG <feImage> 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);
 }
 
 /*
index 0c0289d6e5196da77f2639d421ee3b8bc380a975..cf80a31666fd15ef60fde8f9703004ec60da0b80 100644 (file)
@@ -25,6 +25,7 @@ struct SPFeImage : public SPFilterPrimitive {
     /** IMAGE ATTRIBUTES HERE */
     gchar *href;
     SVGLength x, y, height, width;
+    SPDocument *document;
 };
 
 struct SPFeImageClass {