[goffice] Add a GOImage item to the canvas.



commit e34110e664489ef056cb93b63334c936d6486aa9
Author: Jean Brefort <jean brefort normalesup org>
Date:   Wed Oct 26 13:34:55 2011 +0200

    Add a GOImage item to the canvas.

 ChangeLog                       |   11 ++
 NEWS                            |    1 +
 goffice/canvas/Makefile.am      |    2 +
 goffice/canvas/goc-image.c      |  262 +++++++++++++++++++++++++++++++++++++++
 goffice/canvas/goc-image.h      |   46 +++++++
 goffice/canvas/goffice-canvas.h |    2 +
 goffice/utils/go-image.c        |   14 ++-
 goffice/utils/go-image.h        |    5 +-
 goffice/utils/go-style.c        |    3 +-
 9 files changed, 343 insertions(+), 3 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 44f890b..9ba4ebc 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,16 @@
 2011-10-26  Jean Brefort  <jean brefort normalesup org>
 
+	* goffice/canvas/goc-image.c (goc_image_set_property),
+	(goc_image_get_property), (goc_image_finalize),
+	(goc_image_update_bounds), (goc_image_distance), (goc_image_draw),
+	(goc_image_class_init): new canvas item displaying a GOImage.
+	* goffice/canvas/goc-image.h: ditto.
+	* goffice/canvas/goffice-canvas.h: ditto.
+	* goffice/canvas/Makefile.am: ditto.
+	* goffice/utils/go-style.c: fixed loading of image without type.
+
+2011-10-26  Jean Brefort  <jean brefort normalesup org>
+
 	* all files: add support for svg images using librsvg.
 
 2011-10-25  Morten Welinder  <terra gnome org>
diff --git a/NEWS b/NEWS
index 670e89d..8db837c 100644
--- a/NEWS
+++ b/NEWS
@@ -36,6 +36,7 @@ Jean:
 	* Update series labels when needed. [658527]
 	* Fix background images issues in graphs. [#660917]
 	* Make GSettings the default configuration backend.
+	* Add support for SVG images.
 
 Morten:
 	* Recognize scientific formats with longer exponents.
diff --git a/goffice/canvas/Makefile.am b/goffice/canvas/Makefile.am
index 47b44bf..6fdc5c6 100644
--- a/goffice/canvas/Makefile.am
+++ b/goffice/canvas/Makefile.am
@@ -9,6 +9,7 @@ libgoffice_canvas_la_SOURCES =	\
 	goc-graph.c		\
 	goc-group.c		\
 	goc-item.c		\
+	goc-image.c		\
 	goc-line.c		\
 	goc-path.c		\
 	goc-pixbuf.c		\
@@ -30,6 +31,7 @@ libgoffice_canvas_la_HEADERS =	\
 	goc-graph.h		\
 	goc-group.h		\
 	goc-item.h		\
+	goc-image.h		\
 	goc-line.h		\
 	goc-path.h		\
 	goc-pixbuf.h		\
diff --git a/goffice/canvas/goc-image.c b/goffice/canvas/goc-image.c
new file mode 100644
index 0000000..2629207
--- /dev/null
+++ b/goffice/canvas/goc-image.c
@@ -0,0 +1,262 @@
+/* vim: set sw=8: -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * goc-image.c:
+ *
+ * Copyright (C) 2011 Jean Brefort (jean brefort normalesup org)
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301
+ * USA
+ */
+
+#include <goffice/goffice-config.h>
+#include <goffice/goffice.h>
+#include <gsf/gsf-impl-utils.h>
+#include <glib/gi18n-lib.h>
+
+/**
+ * SECTION:goc-image
+ * @short_description: Image.
+ *
+ * #GocImage implements image drawing in the canvas.
+**/
+
+enum {
+	IMAGE_PROP_0,
+	IMAGE_PROP_X,
+	IMAGE_PROP_Y,
+	IMAGE_PROP_W,
+	IMAGE_PROP_H,
+	IMAGE_PROP_ROTATION,
+	IMAGE_PROP_IMAGE
+};
+
+static GocItemClass *parent_class;
+
+static void
+goc_image_set_property (GObject *gobject, guint param_id,
+				    GValue const *value, GParamSpec *pspec)
+{
+	GocImage *image = GOC_IMAGE (gobject);
+
+	switch (param_id) {
+	case IMAGE_PROP_X:
+		image->x = g_value_get_double (value);
+		break;
+
+	case IMAGE_PROP_Y:
+		image->y = g_value_get_double (value);
+		break;
+
+	case IMAGE_PROP_W:
+		image->width = g_value_get_double (value);
+		break;
+
+	case IMAGE_PROP_H:
+		image->height = g_value_get_double (value);
+		break;
+
+	case IMAGE_PROP_ROTATION:
+		image->rotation = g_value_get_double (value);
+		break;
+
+	case IMAGE_PROP_IMAGE:
+		if (image->image)
+			g_object_unref (image);
+		image->image = GO_IMAGE (g_object_ref (g_value_get_object (value)));
+		break;
+
+	default: G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, param_id, pspec);
+		return; /* NOTE : RETURN */
+	}
+	goc_item_bounds_changed (GOC_ITEM (gobject));
+
+}
+
+static void
+goc_image_get_property (GObject *gobject, guint param_id,
+				    GValue *value, GParamSpec *pspec)
+{
+	GocImage *image = GOC_IMAGE (gobject);
+
+	switch (param_id) {
+	case IMAGE_PROP_X:
+		g_value_set_double (value, image->x);
+		break;
+
+	case IMAGE_PROP_Y:
+		g_value_set_double (value, image->y);
+		break;
+
+	case IMAGE_PROP_W:
+		g_value_set_double (value, image->width);
+		break;
+
+	case IMAGE_PROP_H:
+		g_value_set_double (value, image->height);
+		break;
+
+	case IMAGE_PROP_ROTATION:
+		g_value_set_double (value, image->rotation);
+		break;
+
+	case IMAGE_PROP_IMAGE:
+		if (image->image)
+			g_value_set_object (value, G_OBJECT (image->image));
+		break;
+
+	default: G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, param_id, pspec);
+		return; /* NOTE : RETURN */
+	}
+}
+
+static void
+goc_image_finalize (GObject *gobject)
+{
+	GocImage *image = GOC_IMAGE (gobject);
+
+	if (image->image)
+		g_object_unref (image->image);
+	((GObjectClass *) parent_class)->finalize (gobject);
+}
+
+static void
+goc_image_update_bounds (GocItem *item)
+{
+	GocImage *image = GOC_IMAGE (item);
+	if (!image->image)
+		return;
+	/* FIXME: take rotation into account */
+	item->x0 = floor (image->x);
+	item->y0 = floor (image->y);
+	item->x1 = ceil (image->x + ((image->width > 0.)? image->width: go_image_get_width (image->image)));
+	item->y1 = ceil (image->y + ((image->height > 0.)? image->height: go_image_get_height (image->image)));
+}
+
+static double
+goc_image_distance (GocItem *item, double x, double y, GocItem **near_item)
+{
+	GocImage *image = GOC_IMAGE (item);
+	/* FIXME: take rotation into account */
+	double dx, dy, w, h;
+	if (image->image == NULL)
+		return G_MAXDOUBLE;
+	w = (image->width >= 0.)? image->width: go_image_get_width (image->image);
+	h = (image->height >= 0.)? image->height: go_image_get_height (image->image);
+	if (x < image->x) {
+		dx = image->x - x;
+	} else if (x < image->x + w) {
+		dx = 0;
+	} else {
+		dx = x - image->x - w;
+	}
+	if (y < image->y) {
+		dy = image->y - y;
+	} else if (y < image->y + h) {
+		dy = 0;
+	} else {
+		dy = y - image->y - h;
+	}
+	*near_item = item;
+	return hypot (dx, dy);
+}
+
+static void
+goc_image_draw (GocItem const *item, cairo_t *cr)
+{
+	GocImage *image = GOC_IMAGE (item);
+	double height, width;
+	double scalex = 1., scaley = 1.;
+	int x;
+
+	if (image->image == NULL || image->width == 0. || image->height == 0.)
+		return;
+
+	if (image->width < 0.)
+		width = go_image_get_width (image->image);
+	else {
+		width = image->width;
+		scalex = width / go_image_get_width (image->image);
+	}
+	if (image->height < 0.)
+		height = go_image_get_height (image->image);
+	else {
+		height = image->height;
+		scaley = height / go_image_get_height (image->image);
+	}
+	cairo_save (cr);
+	x = (goc_canvas_get_direction (item->canvas) == GOC_DIRECTION_RTL)?
+		image->x + image->width: image->x;
+	goc_group_cairo_transform (item->parent, cr, x, (int) image->y);
+	cairo_rotate (cr, image->rotation);
+	if (scalex != 1. || scaley != 1.)
+		cairo_scale (cr, scalex, scaley);
+	cairo_move_to (cr, 0, 0);
+	go_image_draw (image->image, cr);
+	cairo_restore (cr);
+}
+
+static void
+goc_image_class_init (GocItemClass *item_klass)
+{
+	GObjectClass *obj_klass = (GObjectClass *) item_klass;
+	parent_class = g_type_class_peek_parent (item_klass);
+
+	obj_klass->finalize = goc_image_finalize;
+	obj_klass->get_property = goc_image_get_property;
+	obj_klass->set_property = goc_image_set_property;
+	g_object_class_install_property (obj_klass, IMAGE_PROP_X,
+		g_param_spec_double ("x",
+			_("x"),
+			_("The image left position"),
+			-G_MAXDOUBLE, G_MAXDOUBLE, 0.,
+			GSF_PARAM_STATIC | G_PARAM_READWRITE));
+	g_object_class_install_property (obj_klass, IMAGE_PROP_Y,
+		g_param_spec_double ("y",
+			_("y"),
+			_("The image top position"),
+			-G_MAXDOUBLE, G_MAXDOUBLE, 0.,
+			GSF_PARAM_STATIC | G_PARAM_READWRITE));
+	g_object_class_install_property (obj_klass, IMAGE_PROP_W,
+		g_param_spec_double ("width",
+			_("Width"),
+			_("The image width or -1 to use the image width"),
+			-G_MAXDOUBLE, G_MAXDOUBLE, 0.,
+			GSF_PARAM_STATIC | G_PARAM_READWRITE));
+	g_object_class_install_property (obj_klass, IMAGE_PROP_H,
+		g_param_spec_double ("height",
+			_("Height"),
+			_("The image height or -1 to use the image height"),
+			-G_MAXDOUBLE, G_MAXDOUBLE, 0.,
+			GSF_PARAM_STATIC | G_PARAM_READWRITE));
+/*	g_object_class_install_property (obj_klass, IMAGE_PROP_ROTATION,
+		g_param_spec_double ("rotation",
+			_("Rotation"),
+			_("The rotation around top left position"),
+			0., 2 * M_PI, 0.,
+			GSF_PARAM_STATIC | G_PARAM_READWRITE));*/
+	g_object_class_install_property (obj_klass, IMAGE_PROP_IMAGE,
+	        g_param_spec_object ("image", _("Image"),
+	                _("The GOImage to display"),
+	                GO_TYPE_IMAGE,
+			GSF_PARAM_STATIC | G_PARAM_READWRITE));
+
+	item_klass->update_bounds = goc_image_update_bounds;
+	item_klass->distance = goc_image_distance;
+	item_klass->draw = goc_image_draw;
+}
+
+GSF_CLASS (GocImage, goc_image,
+	   goc_image_class_init, NULL,
+	   GOC_TYPE_ITEM)
diff --git a/goffice/canvas/goc-image.h b/goffice/canvas/goc-image.h
new file mode 100644
index 0000000..d1859a4
--- /dev/null
+++ b/goffice/canvas/goc-image.h
@@ -0,0 +1,46 @@
+/* vim: set sw=8: -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * goc-image.h:
+ *
+ * Copyright (C) 2011 Jean Brefort (jean brefort normalesup org)
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301
+ * USA
+ */
+
+#ifndef GOC_IMAGE_H
+#define GOC_IMAGE_H
+
+#include <goffice/goffice.h>
+
+G_BEGIN_DECLS
+
+struct _GocImage {
+	GocItem base;
+
+	double x, y, width, height, rotation;
+	GOImage *image;
+};
+typedef GocItemClass GocImageClass;
+
+#define GOC_TYPE_IMAGE	(goc_image_get_type ())
+#define GOC_IMAGE(o)	(G_TYPE_CHECK_INSTANCE_CAST ((o), GOC_TYPE_IMAGE, GocImage))
+#define GOC_IS_IMAGE(o)	(G_TYPE_CHECK_INSTANCE_TYPE ((o), GOC_TYPE_IMAGE))
+
+GType goc_image_get_type (void);
+
+G_END_DECLS
+
+#endif  /* GOC_IMAGE_H */
diff --git a/goffice/canvas/goffice-canvas.h b/goffice/canvas/goffice-canvas.h
index c5034bc..0de7e95 100644
--- a/goffice/canvas/goffice-canvas.h
+++ b/goffice/canvas/goffice-canvas.h
@@ -32,6 +32,7 @@ typedef struct _GocCanvas	GocCanvas;
 typedef struct _GocItem		GocItem;
 typedef struct _GocGroup	GocGroup;
 typedef struct _GocArc		GocArc;
+typedef struct _GocImage	GocImage;
 typedef struct _GocLine		GocLine;
 typedef struct _GocPath		GocPath;
 typedef struct _GocPixbuf	GocPixbuf;
@@ -62,6 +63,7 @@ G_END_DECLS
 #include <goffice/canvas/goc-graph.h>
 #include <goffice/canvas/goc-group.h>
 #include <goffice/canvas/goc-arc.h>
+#include <goffice/canvas/goc-image.h>
 #include <goffice/canvas/goc-line.h>
 #include <goffice/canvas/goc-path.h>
 #include <goffice/canvas/goc-pixbuf.h>
diff --git a/goffice/utils/go-image.c b/goffice/utils/go-image.c
index 929a7e4..5be0fba 100644
--- a/goffice/utils/go-image.c
+++ b/goffice/utils/go-image.c
@@ -462,7 +462,7 @@ go_image_set_name (GOImage *image, char const *name)
 }
 
 char const *
-go_image_get_name (GOImage *image)
+go_image_get_name (GOImage const *image)
 {
 	g_return_val_if_fail (GO_IS_IMAGE (image), NULL);
 	return image->name;
@@ -523,3 +523,15 @@ _go_image_changed (GOImage *image, double width, double height)
 		image->thumbnail = NULL;
 	}
 }
+
+double
+go_image_get_width (GOImage const *image)
+{
+	return image->width;
+}
+
+double
+go_image_get_height (GOImage const *image)
+{
+	return image->height;
+}
diff --git a/goffice/utils/go-image.h b/goffice/utils/go-image.h
index b44619b..6c1f7e1 100644
--- a/goffice/utils/go-image.h
+++ b/goffice/utils/go-image.h
@@ -100,7 +100,7 @@ guint8 		*go_image_get_pixels 		(GOImage *image);
 void 		 go_image_fill 			(GOImage *image, GOColor color);
 
 void		 go_image_set_name		(GOImage *image, char const *name);
-char const	*go_image_get_name 		(GOImage *image);
+char const	*go_image_get_name 		(GOImage const *image);
 
 gboolean	 go_image_differ		(GOImage *first, GOImage *second);
 
@@ -108,6 +108,9 @@ void		 go_image_save			(GOImage *image, GsfXMLOut *output);
 void		 go_image_load_attrs		(GOImage *image, GsfXMLIn *xin, xmlChar const **attrs);
 void		 go_image_load_data		(GOImage *image, GsfXMLIn *xin);
 
+double		 go_image_get_width		(GOImage const *image);
+double		 go_image_get_height		(GOImage const *image);
+
 /* Protected */
 void		 _go_image_changed		(GOImage *image, double width, double height);
 
diff --git a/goffice/utils/go-style.c b/goffice/utils/go-style.c
index dc7b109..e5beadc 100644
--- a/goffice/utils/go-style.c
+++ b/goffice/utils/go-style.c
@@ -1522,8 +1522,9 @@ go_style_sax_load_fill_image (GsfXMLIn *xin, xmlChar const **attrs)
 		else if (0 == strcmp (attrs[0], "type-name"))
 			type_name = attrs[1];
 	type = type_name? g_type_from_name (type_name): GO_TYPE_PIXBUF;
-	if (name && type_name)
+	if (name && type)
 		style->fill.image.image = g_object_ref (go_doc_image_fetch (doc, name, type));
+printf("image=%p\n",style->fill.image.image);
 	if (style->fill.image.image != NULL)
 		style->fill.type = GO_STYLE_FILL_IMAGE;
 }



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