[dia] Bug 304693 - Optionally embedded images



commit bb2f22834201775ee7c88dc778fe2360170e97c7
Author: Hans Breuer <hans breuer org>
Date:   Sat Aug 14 19:47:01 2010 +0200

    Bug 304693 - Optionally embedded images
    
    There is an extra property to select the embedding of images
    into the diagram. If there are embedded images and a valid filename
    the file is still preferred during load. But if it is not available
    anymore the loading falls back to the embedded pixbuf.
    
    If there is no filename at all the image embedding is enforced
    and loading works with out complaints about missing files.

 lib/dia_image.c          |   19 ++++++++++++++++
 lib/dia_image.h          |    1 +
 lib/libdia.def           |    2 +
 objects/standard/image.c |   53 ++++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 75 insertions(+), 0 deletions(-)
---
diff --git a/lib/dia_image.c b/lib/dia_image.c
index 1e653c5..1fb19b3 100644
--- a/lib/dia_image.c
+++ b/lib/dia_image.c
@@ -177,6 +177,23 @@ dia_image_load(const gchar *filename)
   return dia_img;
 }
 
+/*!
+ * Create a Dia Image from in memory GdkPixbuf
+ *
+ * It stores only a reference, so drop your own after calling this.
+ */
+DiaImage *
+dia_image_new_from_pixbuf (GdkPixbuf *pixbuf)
+{
+  DiaImage *dia_img;
+  GdkPixbuf *image;
+
+  dia_img = DIA_IMAGE(g_object_new(DIA_TYPE_IMAGE, NULL));
+  dia_img->image = g_object_ref (pixbuf);
+  
+  return dia_img;
+}
+
 /** Reference an image.
  * @param image Image that we want a reference to.
  */
@@ -279,6 +296,8 @@ dia_image_rowstride(const DiaImage *image)
 const GdkPixbuf* 
 dia_image_pixbuf (const DiaImage *image)
 {
+  if (!image)
+    return NULL;
   return image->image;
 }
 
diff --git a/lib/dia_image.h b/lib/dia_image.h
index 6be93ce..4b2d598 100644
--- a/lib/dia_image.h
+++ b/lib/dia_image.h
@@ -30,6 +30,7 @@ void dia_image_init(void);
 DiaImage *dia_image_get_broken(void);
 
 DiaImage *dia_image_load(const gchar *filename);
+DiaImage *dia_image_new_from_pixbuf(GdkPixbuf *pixbuf);
 void dia_image_add_ref(DiaImage *image);
 void dia_image_unref(DiaImage *image);
 void dia_image_draw(DiaImage *image, GdkWindow *window, GdkGC *gc,
diff --git a/lib/libdia.def b/lib/libdia.def
index 454d546..e5e351e 100644
--- a/lib/libdia.def
+++ b/lib/libdia.def
@@ -271,6 +271,8 @@ EXPORTS
  dia_image_rgba_data
  dia_image_rowstride
  dia_image_width
+ dia_image_pixbuf
+ dia_image_new_from_pixbuf
 
  dia_interactive_renderer_interface_get_type
  
diff --git a/objects/standard/image.c b/objects/standard/image.c
index bc9a576..4cc5933 100644
--- a/objects/standard/image.c
+++ b/objects/standard/image.c
@@ -60,6 +60,11 @@ struct _Image {
   
   DiaImage *image;
   gchar *file;
+  
+  gboolean inline_data;
+  /* may contain the images pixbuf pointer */
+  GdkPixbuf *pixbuf;
+
   gboolean draw_border;
   gboolean keep_aspect;
 
@@ -137,6 +142,10 @@ static PropDescription image_props[] = {
   ELEMENT_COMMON_PROPERTIES,
   { "image_file", PROP_TYPE_FILE, PROP_FLAG_VISIBLE,
     N_("Image file"), NULL, NULL},
+  { "inline_data", PROP_TYPE_BOOL, PROP_FLAG_VISIBLE|PROP_FLAG_OPTIONAL,
+    N_("Inline data"), N_("Store image data in diagram"), NULL },
+  { "pixbuf", PROP_TYPE_PIXBUF, PROP_FLAG_OPTIONAL,
+    N_("Pixbuf"), N_("The Pixbuf reference"), NULL },
   { "show_border", PROP_TYPE_BOOL, PROP_FLAG_VISIBLE,
     N_("Draw border"), NULL, NULL},
   { "keep_aspect", PROP_TYPE_BOOL, PROP_FLAG_VISIBLE,
@@ -158,6 +167,8 @@ image_describe_props(Image *image)
 static PropOffset image_offsets[] = {
   ELEMENT_COMMON_PROPERTIES_OFFSETS,
   { "image_file", PROP_TYPE_FILE, offsetof(Image, file) },
+  { "inline_data", PROP_TYPE_BOOL, offsetof(Image, inline_data) },
+  { "pixbuf", PROP_TYPE_PIXBUF, offsetof(Image, pixbuf) },
   { "show_border", PROP_TYPE_BOOL, offsetof(Image, draw_border) },
   { "keep_aspect", PROP_TYPE_BOOL, offsetof(Image, keep_aspect) },
   { PROP_STDNAME_LINE_WIDTH, PROP_STDTYPE_LINE_WIDTH, offsetof(Image, border_width) },
@@ -170,6 +181,8 @@ static PropOffset image_offsets[] = {
 static void
 image_get_props(Image *image, GPtrArray *props)
 {
+  if (image->inline_data)
+    image->pixbuf = dia_image_pixbuf (image->image);
   object_get_props_from_offsets(&image->element.object, image_offsets, props);
 }
 
@@ -179,9 +192,23 @@ image_set_props(Image *image, GPtrArray *props)
   struct stat st;
   time_t mtime = 0;
   char *old_file = image->file ? g_strdup(image->file) : "";
+  GdkPixbuf *old_pixbuf = dia_image_pixbuf (image->image);
 
   object_set_props_from_offsets(&image->element.object, image_offsets, props);
 
+  if (old_pixbuf != image->pixbuf) {
+    if (!image->file || *image->file == '\0') {
+      image->inline_data = TRUE; /* otherwise we'll loose it */
+      if (image->image)
+        g_object_unref (image->image);
+      image->image = dia_image_new_from_pixbuf (image->pixbuf);
+      /* FIXME: reference problem? */
+      image->pixbuf = dia_image_pixbuf (image->image);  
+    } else {
+      message_warning ("FIXME: handle pixbuf change!");
+    }
+  }
+
   /* use old value on error */
   if (!image->file || g_stat (image->file, &st) != 0)
     mtime = image->mtime;
@@ -601,6 +628,18 @@ image_save(Image *image, ObjectNode obj_node, const char *filename)
     }
     
   }
+  /* only save image_data inline if told to do so */
+  if (image->inline_data) {
+    GdkPixbuf *pixbuf;
+    data_add_boolean (new_attribute(obj_node, "inline_data"), image->inline_data);
+
+    /* just to be sure to get the currently visible */
+    pixbuf = dia_image_pixbuf (image->image);
+    if (pixbuf != image->pixbuf)
+      message_warning (_("Inconsistent pixbuf during image save."));
+    if (pixbuf)
+      data_add_pixbuf (new_attribute(obj_node, "pixbuf"), pixbuf);
+  }
 }
 
 static DiaObject *
@@ -740,6 +779,20 @@ image_load(ObjectNode obj_node, int version, const char *filename)
     }
     g_free(diafile_dir);
   }
+  /* if we don't have an image yet try to recover it from inlined data */
+  if (!image->image) {
+    attr = object_find_attribute(obj_node, "pixbuf");
+    if (attr != NULL) {
+      GdkPixbuf *pixbuf = data_pixbuf (attribute_first_data(attr));
+
+      if (pixbuf) {
+	image->image = dia_image_new_from_pixbuf (pixbuf);
+	image->inline_data = TRUE; /* avoid loosing it */
+	/* FIXME: should we reset the filename? */
+	g_object_unref (pixbuf);
+      }
+    }
+  }
 
   /* update mtime */
   {



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]