[dia] New std-prop 'pixbuf': preparation of embedding image data
- From: Hans Breuer <hans src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [dia] New std-prop 'pixbuf': preparation of embedding image data
- Date: Sat, 14 Aug 2010 17:47:49 +0000 (UTC)
commit ca269a01119195b204db4974fe6eb4add5001f62
Author: Hans Breuer <hans breuer org>
Date: Sat Aug 14 19:42:00 2010 +0200
New std-prop 'pixbuf': preparation of embedding image data
A bitmap editor is not yet built in but may come later;)
Also it is not yet used anywhere, but that's coming with
the next commit.
lib/Makefile.am | 2 +
lib/dia_xml.c | 2 +
lib/dia_xml.h | 6 +-
lib/libdia.def | 4 +
lib/makefile.msc | 1 +
lib/prop_pixbuf.c | 268 +++++++++++++++++++++++++++++++++++++++++++++++++++
lib/prop_pixbuf.h | 41 ++++++++
lib/properties.c | 1 +
lib/properties.h | 1 +
lib/propinternals.h | 1 +
10 files changed, 326 insertions(+), 1 deletions(-)
---
diff --git a/lib/Makefile.am b/lib/Makefile.am
index 0cf7bf2..424735d 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -14,6 +14,8 @@ stdprop_files = \
prop_basic.h \
prop_dict.c \
prop_dict.h \
+ prop_pixbuf.c \
+ prop_pixbuf.h \
prop_inttypes.c \
prop_inttypes.h \
prop_geomtypes.c \
diff --git a/lib/dia_xml.c b/lib/dia_xml.c
index 096e9e3..9cef604 100644
--- a/lib/dia_xml.c
+++ b/lib/dia_xml.c
@@ -424,6 +424,8 @@ data_type(DataNode data)
return DATATYPE_BEZPOINT;
} else if (strcmp(name, "dict")==0) {
return DATATYPE_DICT;
+ } else if (strcmp(name, "pixbuf")==0) {
+ return DATATYPE_PIXBUF;
}
message_error("Unknown type of DataNode");
diff --git a/lib/dia_xml.h b/lib/dia_xml.h
index f6082e0..faff1cb 100644
--- a/lib/dia_xml.h
+++ b/lib/dia_xml.h
@@ -58,7 +58,8 @@ typedef enum{
DATATYPE_STRING,
DATATYPE_FONT,
DATATYPE_BEZPOINT,
- DATATYPE_DICT
+ DATATYPE_DICT,
+ DATATYPE_PIXBUF
} DataType;
AttributeNode object_find_attribute(ObjectNode obj_node,
@@ -101,5 +102,8 @@ DataNode data_add_composite(AttributeNode attr,
GHashTable *data_dict (DataNode data);
void data_add_dict (AttributeNode attr, GHashTable *data);
+GdkPixbuf *data_pixbuf (DataNode data);
+void data_add_pixbuf (AttributeNode attr, GdkPixbuf *pixbuf);
+
#endif /* DIA_XML_H */
diff --git a/lib/libdia.def b/lib/libdia.def
index f344af1..454d546 100644
--- a/lib/libdia.def
+++ b/lib/libdia.def
@@ -130,11 +130,13 @@ EXPORTS
data_add_color
data_add_composite
data_add_enum
+ data_add_dict
data_add_filename
data_add_font
data_add_int
data_add_layer
data_add_layer_at
+ data_add_pixbuf
data_add_point
data_add_bezpoint
data_add_real
@@ -143,6 +145,7 @@ EXPORTS
data_boolean
data_color
data_delete_layer
+ data_dict
data_emit
data_enum
data_filename
@@ -159,6 +162,7 @@ EXPORTS
data_layer_get_nth
data_lower_layer
data_next
+ data_pixbuf
data_point
data_bezpoint
data_raise_layer
diff --git a/lib/makefile.msc b/lib/makefile.msc
index 6a863f7..1103d8b 100644
--- a/lib/makefile.msc
+++ b/lib/makefile.msc
@@ -95,6 +95,7 @@ OBJECTS = \
prop_dict.obj \
prop_geomtypes.obj \
prop_inttypes.obj \
+ prop_pixbuf.obj \
prop_sdarray.obj \
prop_text.obj \
prop_widgets.obj \
diff --git a/lib/prop_pixbuf.c b/lib/prop_pixbuf.c
new file mode 100644
index 0000000..9d174b6
--- /dev/null
+++ b/lib/prop_pixbuf.c
@@ -0,0 +1,268 @@
+/* Dia -- a diagram creation/manipulation program -*- c -*-
+ * Copyright (C) 1998 Alexander Larsson
+ *
+ * Property system for dia objects/shapes.
+ * Copyright (C) 2000 James Henstridge
+ * Copyright (C) 2001 Cyrille Chepelov
+ *
+ * Copyright (C) 2010 Hans Breuer
+ * Property types for pixbuf.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#include <config.h>
+
+#include <gtk/gtk.h>
+#define WIDGET GtkWidget
+#include "widgets.h"
+#include "properties.h"
+#include "propinternals.h"
+#include "message.h"
+
+static PixbufProperty *
+pixbufprop_new(const PropDescription *pdesc, PropDescToPropPredicate reason)
+{
+ PixbufProperty *prop = g_new0(PixbufProperty,1);
+
+ initialize_property(&prop->common, pdesc, reason);
+ /* empty by default */
+ prop->pixbuf = NULL;
+
+ return prop;
+}
+
+static void
+pixbufprop_free(PixbufProperty *prop)
+{
+ if (prop->pixbuf)
+ g_object_unref(prop->pixbuf);
+ g_free(prop);
+}
+
+static PixbufProperty *
+pixbufprop_copy(PixbufProperty *src)
+{
+ PixbufProperty *prop =
+ (PixbufProperty *)src->common.ops->new_prop(src->common.descr,
+ src->common.reason);
+ if (src->pixbuf) /* TODO: rething on edit - gdk_pixbuf_copy() ? */
+ prop->pixbuf = g_object_ref (src->pixbuf);
+
+ return prop;
+}
+
+GdkPixbuf *
+data_pixbuf (DataNode data)
+{
+ GdkPixbuf *pixbuf = NULL;
+ GdkPixbufLoader *loader;
+ GError *error = NULL;
+ AttributeNode attr = composite_find_attribute(data, "data");
+
+ loader = gdk_pixbuf_loader_new ();
+ if (loader) {
+ xmlNode *node = attribute_first_data (attr);
+ gint state = 0;
+ guint save = 0;
+# define BUF_SIZE 4096
+ guchar buf[BUF_SIZE];
+ guchar *in = NULL; /* direct access, not involving another xmlStrDup/xmlFree */
+ gssize len = 0;
+
+ if (node->children && xmlStrcmp (node->children->name, "text") == 0) {
+ in = node->children->content;
+ len = strlen (in);
+ }
+
+ do {
+ gsize step = g_base64_decode_step (in,
+ len > BUF_SIZE ? BUF_SIZE : len,
+ buf, &state, &save);
+
+ if (!gdk_pixbuf_loader_write (loader, buf, step, &error))
+ break;
+
+ in += BUF_SIZE;
+ len -= BUF_SIZE;
+ } while (len > 0);
+ if (gdk_pixbuf_loader_close (loader, error ? NULL : &error)) {
+ pixbuf = g_object_ref (gdk_pixbuf_loader_get_pixbuf (loader));
+ } else {
+ message_warning ("%s", error->message);
+ g_error_free (error);
+ }
+
+ g_object_unref (loader);
+ }
+# undef BUF_SIZE
+ return pixbuf;
+}
+
+static void
+pixbufprop_load(PixbufProperty *prop, AttributeNode attr, DataNode data)
+{
+ prop->pixbuf = data_pixbuf (data);
+}
+
+typedef struct _EncodeData {
+ GByteArray *array;
+
+ gsize size;
+
+ gint state;
+ gint save;
+} EncodeData;
+static gboolean
+_pixbuf_encode (const gchar *buf,
+ gsize count,
+ GError **error,
+ gpointer data)
+{
+ EncodeData *ed = data;
+ gsize size;
+ guint old_len;
+ gsize growth = (count / 3 + 1) * 4 + 4 + ((count / 3 + 1) * 4 + 4) / 72 + 1;
+ guchar *out;
+
+ old_len = ed->array->len;
+ g_byte_array_set_size (ed->array, ed->size + growth);
+ out = &ed->array->data[ed->size];
+ ed->size += g_base64_encode_step (buf, count, TRUE, out, &ed->state, &ed->save);
+
+ return TRUE;
+}
+void
+data_add_pixbuf (AttributeNode attr, GdkPixbuf *pixbuf)
+{
+ ObjectNode composite = data_add_composite(attr, "pixbuf");
+ AttributeNode comp_attr = composite_add_attribute (composite, "data");
+ GError *error = NULL;
+ EncodeData ed = { 0, };
+
+ ed.array = g_byte_array_new ();
+
+ if (!gdk_pixbuf_save_to_callback (pixbuf, _pixbuf_encode, &ed, "png", &error, NULL)) {
+ message_error (_("Saving inline pixbuf failed:\n%s"), error->message);
+ g_error_free (error);
+ return;
+ }
+ /* FIXME: is there enough space for the rest? */
+ ed.size += g_base64_encode_close (TRUE, &ed.array->data[ed.size], &ed.state, &ed.save);
+ /* is the array 0-terminated? */
+ if (ed.array->data[ed.size] != 0) {
+ g_byte_array_append (ed.array, "\0", 1);
+ ed.array->data[ed.size] = '\0';
+ }
+ (void)xmlNewChild (comp_attr, NULL, "data", ed.array->data);
+
+ g_byte_array_free (ed.array, TRUE);
+}
+
+static void
+pixbufprop_save(PixbufProperty *prop, AttributeNode attr)
+{
+ if (prop->pixbuf) {
+ data_add_pixbuf (attr, prop->pixbuf);
+ }
+}
+
+static void
+pixbufprop_get_from_offset(PixbufProperty *prop,
+ void *base, guint offset, guint offset2)
+{
+ /* before we start editing a simple refernce should be enough */
+ GdkPixbuf *pixbuf = struct_member(base,offset,GdkPixbuf *);
+
+ if (pixbuf)
+ prop->pixbuf = g_object_ref (pixbuf);
+ else
+ prop->pixbuf = NULL;
+}
+
+static void
+pixbufprop_set_from_offset(PixbufProperty *prop,
+ void *base, guint offset, guint offset2)
+{
+ GdkPixbuf *dest = struct_member(base,offset,GdkPixbuf *);
+ if (dest)
+ g_object_unref (dest);
+ if (prop->pixbuf)
+ struct_member(base,offset, GdkPixbuf *) = g_object_ref (prop->pixbuf);
+ else
+ struct_member(base,offset, GdkPixbuf *) = NULL;
+}
+
+/* GUI stuff - not yet
+ - allow to crop
+ - maybe scale
+ */
+static void
+_pixbuf_toggled(GtkWidget *wid)
+{
+ if (GTK_TOGGLE_BUTTON(wid)->active)
+ gtk_label_set_text(GTK_LABEL(GTK_BIN(wid)->child), _("Yes"));
+ else
+ gtk_label_set_text(GTK_LABEL(GTK_BIN(wid)->child), _("No"));
+}
+
+static GtkWidget *
+pixbufprop_get_widget (PixbufProperty *prop, PropDialog *dialog)
+{
+ GtkWidget *ret = gtk_toggle_button_new_with_label(_("No"));
+ g_signal_connect(G_OBJECT(ret), "toggled",
+ G_CALLBACK (_pixbuf_toggled), NULL);
+ prophandler_connect(&prop->common, G_OBJECT(ret), "toggled");
+ return ret;
+}
+
+static void
+pixbufprop_reset_widget(PixbufProperty *prop, GtkWidget *widget)
+{
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget),prop->pixbuf != NULL);
+}
+
+static void
+pixbufprop_set_from_widget(PixbufProperty *prop, GtkWidget *widget)
+{
+ if (GTK_TOGGLE_BUTTON(widget)->active) {
+ if (!prop->pixbuf)
+ message_warning (_("Cant create image data from scratch!"));
+ } else {
+ if (prop->pixbuf)
+ g_object_unref (prop->pixbuf);
+ prop->pixbuf = NULL;
+ }
+}
+
+static const PropertyOps pixbufprop_ops = {
+ (PropertyType_New) pixbufprop_new,
+ (PropertyType_Free) pixbufprop_free,
+ (PropertyType_Copy) pixbufprop_copy,
+ (PropertyType_Load) pixbufprop_load,
+ (PropertyType_Save) pixbufprop_save,
+ (PropertyType_GetWidget) pixbufprop_get_widget,
+ (PropertyType_ResetWidget) pixbufprop_reset_widget,
+ (PropertyType_SetFromWidget) pixbufprop_set_from_widget,
+
+ (PropertyType_CanMerge) noopprop_can_merge,
+ (PropertyType_GetFromOffset) pixbufprop_get_from_offset,
+ (PropertyType_SetFromOffset) pixbufprop_set_from_offset
+};
+
+void
+prop_pixbuftypes_register(void)
+{
+ prop_type_register(PROP_TYPE_PIXBUF, &pixbufprop_ops);
+}
diff --git a/lib/prop_pixbuf.h b/lib/prop_pixbuf.h
new file mode 100644
index 0000000..e82daaf
--- /dev/null
+++ b/lib/prop_pixbuf.h
@@ -0,0 +1,41 @@
+/* Dia -- a diagram creation/manipulation program -*- c -*-
+ * Copyright (C) 1998 Alexander Larsson
+ *
+ * Property system for dia objects/shapes.
+ * Copyright (C) 2000 James Henstridge
+ * Copyright (C) 2001 Cyrille Chepelov
+ * Major restructuration done in August 2001 by C. Chepelov
+ *
+ * Copyright (C) 2010 Hans Breuer
+ * Property types for pixbuf.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#ifndef PROP_PIXBUF_H
+#define PROP_PIXBUF_H
+
+#include <gdk-pixbuf/gdk-pixbuf.h>
+
+#include "properties.h"
+#include "dia_xml.h"
+
+typedef struct {
+ Property common;
+ GdkPixbuf *pixbuf; /* just the reference */
+} PixbufProperty;
+
+void prop_pixbuftypes_register(void);
+
+#endif /* PROP_PIXBUF_H */
diff --git a/lib/properties.c b/lib/properties.c
index 8f8c5b2..ce568ba 100644
--- a/lib/properties.c
+++ b/lib/properties.c
@@ -51,6 +51,7 @@ stdprops_init(void)
prop_widgets_register();
prop_sdarray_register();
prop_dicttypes_register();
+ prop_pixbuftypes_register();
}
/* --------------------------------------- */
diff --git a/lib/properties.h b/lib/properties.h
index 7e2071d..fcf89c6 100644
--- a/lib/properties.h
+++ b/lib/properties.h
@@ -198,6 +198,7 @@ typedef const gchar *PropertyType;
#define PROP_TYPE_SARRAY "sarray" /* ArrayProperty */
#define PROP_TYPE_DARRAY "darray" /* ArrayProperty */
#define PROP_TYPE_DICT "dict" /* DictProperty */
+#define PROP_TYPE_PIXBUF "pixbuf" /* PixbufProperty */
/* **************************************************************** */
diff --git a/lib/propinternals.h b/lib/propinternals.h
index c20fccf..728e7e1 100644
--- a/lib/propinternals.h
+++ b/lib/propinternals.h
@@ -86,6 +86,7 @@ void do_get_props_from_offsets(void *base, GPtrArray *props,
#include "prop_widgets.h"
#include "prop_sdarray.h"
#include "prop_dict.h"
+#include "prop_pixbuf.h"
#endif /* PROPINTERNALS_H */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]