[goffice] Use a fallback image when the actual image type is not supported.



commit 239ae3dae8a22458f2a99c1b6f3c98675fa8b4b2
Author: Jean Brefort <jean brefort normalesup org>
Date:   Mon Mar 26 16:07:30 2012 +0200

    Use a fallback image when the actual image type is not supported.

 ChangeLog                  |   12 ++++++
 goffice/utils/go-emf.c     |    7 +++-
 goffice/utils/go-image.c   |   85 ++++++++++++++++++++++++++++++++++++++++---
 goffice/utils/go-spectre.c |   12 ++----
 4 files changed, 101 insertions(+), 15 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 2a6696c..c517b3b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,17 @@
 2012-03-26  Jean Brefort  <jean brefort normalesup org>
 
+	* goffice/utils/go-emf.c (go_emf_load_data), (go_emf_get_pixbuf),
+	(go_emf_class_init): use a fallback image when the actual image type is
+	not supported.
+	* goffice/utils/go-image.c (go_image_draw_fb),
+	(go_image_get_pixbuf_fb), (go_image_get_scaled_pixbuf_fb),
+	(go_image_class_init): ditto.
+	* goffice/utils/go-spectre.c (go_spectre_build_surface),
+	(go_spectre_draw), (go_spectre_get_pixbuf),
+	(go_spectre_get_scaled_pixbuf), (go_spectre_class_init): ditto.
+
+2012-03-26  Jean Brefort  <jean brefort normalesup org>
+
 	* goffice/canvas/goc-image.c (goc_image_draw),
 	(goc_image_class_init): fixed cropped images rendering.
 
diff --git a/goffice/utils/go-emf.c b/goffice/utils/go-emf.c
index fea0c38..7215d52 100644
--- a/goffice/utils/go-emf.c
+++ b/goffice/utils/go-emf.c
@@ -59,9 +59,11 @@ go_emf_load_attr (G_GNUC_UNUSED GOImage *image, G_GNUC_UNUSED xmlChar const *att
 static void
 go_emf_load_data (GOImage *image, GsfXMLIn *xin)
 {
+#ifdef GOFFICE_EMF_SUPPORT
 	GOEmf *emf = GO_EMF (image);
 	GError *error = NULL;
 	GsfInput *input;
+#endif
 	image->data_length = gsf_base64_decode_simple (xin->content->str, strlen(xin->content->str));
 	image->data = g_malloc (image->data_length);
 	memcpy (image->data, xin->content->str, image->data_length);
@@ -76,6 +78,7 @@ go_emf_load_data (GOImage *image, GsfXMLIn *xin)
 #endif
 }
 
+#ifdef GOFFICE_EMF_SUPPORT
 static void
 go_emf_draw (GOImage *image, cairo_t *cr)
 {
@@ -102,7 +105,6 @@ go_emf_get_pixbuf (GOImage *image)
 	                                   image->width, image->height,
 	                                   cairo_image_surface_get_stride (surface));
 	return res;
-	return NULL; /* FIXME */
 }
 
 static GdkPixbuf *
@@ -125,6 +127,7 @@ go_emf_get_scaled_pixbuf (GOImage *image, int width, int height)
 	                                   cairo_image_surface_get_stride (surface));
 	return res;
 }
+#endif
 
 static gboolean
 go_emf_differ (GOImage *first, GOImage *second)
@@ -154,9 +157,11 @@ go_emf_class_init (GObjectClass *klass)
 	image_klass->save = go_emf_save;
 	image_klass->load_attr = go_emf_load_attr;
 	image_klass->load_data = go_emf_load_data;
+#ifdef GOFFICE_EMF_SUPPORT
 	image_klass->get_pixbuf = go_emf_get_pixbuf;
 	image_klass->get_scaled_pixbuf = go_emf_get_scaled_pixbuf;
 	image_klass->draw = go_emf_draw;
+#endif
 	image_klass->differ = go_emf_differ;
 }
 
diff --git a/goffice/utils/go-image.c b/goffice/utils/go-image.c
index fa2c873..a71b284 100644
--- a/goffice/utils/go-image.c
+++ b/goffice/utils/go-image.c
@@ -352,21 +352,93 @@ go_image_finalize (GObject *obj)
 	(parent_klass->finalize) (obj);
 }
 
+/* default implementation for unsupported images */
 static void
-go_image_class_init (GObjectClass *klass)
+go_image_draw_fb (GOImage *image, cairo_t *cr)
 {
-	klass->finalize = go_image_finalize;
-	klass->set_property = go_image_set_property;
-	klass->get_property = go_image_get_property;
+	GdkPixbuf *placeholder = gtk_icon_theme_load_icon
+		(gtk_icon_theme_get_default (),
+		 "unknown_image", 100, 0, NULL);
+	double dx, dy;
+	int n;
+	n = go_fake_floor (image->width / gdk_pixbuf_get_width (placeholder));
+	dx = (image->width - n * gdk_pixbuf_get_width (placeholder)) / 2.;
+	n = go_fake_floor (image->height / gdk_pixbuf_get_height (placeholder));
+	dy = (image->height - n * gdk_pixbuf_get_height (placeholder)) / 2.;
+	cairo_save (cr);
+	cairo_rectangle (cr, 0., 0., image->width, image->height);
+	cairo_clip (cr);
+	cairo_rectangle (cr, -dx, -dy, image->width + dx, image->height + dy);
+	gdk_cairo_set_source_pixbuf (cr, placeholder, 0, 0);
+	cairo_pattern_set_extend (cairo_get_source (cr), CAIRO_EXTEND_REPEAT);
+	cairo_fill (cr);
+	cairo_restore (cr);
+}
+
+static GdkPixbuf *
+go_image_get_pixbuf_fb (GOImage *image)
+{
+	cairo_surface_t *surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
+		                                                    image->width,
+		                                                    image->height);
+	cairo_t *cr = cairo_create (surface);
+	GdkPixbuf *ret, *placeholder = gtk_icon_theme_load_icon
+		(gtk_icon_theme_get_default (),
+		 "unknown_image", 100, 0, NULL);
+	double dx, dy;
+	int n;
+	n = go_fake_floor (image->width / gdk_pixbuf_get_width (placeholder));
+	dx = (image->width - n * gdk_pixbuf_get_width (placeholder)) / 2.;
+	n = go_fake_floor (image->height / gdk_pixbuf_get_height (placeholder));
+	dy = (image->height - n * gdk_pixbuf_get_height (placeholder)) / 2.;
+	cairo_rectangle (cr, 0., 0., image->width, image->height);
+	cairo_clip (cr);
+	cairo_rectangle (cr, -dx, -dy, image->width + dx, image->height + dy);
+	gdk_cairo_set_source_pixbuf (cr, placeholder, 0, 0);
+	cairo_pattern_set_extend (cairo_get_source (cr), CAIRO_EXTEND_REPEAT);
+	cairo_fill (cr);
+	cairo_destroy (cr);
+	ret = gdk_pixbuf_new (GDK_COLORSPACE_RGB, TRUE, 8, image->width, image->height);
+	if (cairo_image_surface_get_stride (surface) != gdk_pixbuf_get_rowstride (ret)) {
+		g_object_unref (ret);
+		ret = NULL;
+	} else
+		go_cairo_convert_data_from_pixbuf (gdk_pixbuf_get_pixels (ret),
+			                               cairo_image_surface_get_data (surface),
+			                               image->width, image->height,
+			                               gdk_pixbuf_get_rowstride (ret));
+	cairo_surface_destroy (surface);
+	return ret;
+}
+
+static GdkPixbuf *
+go_image_get_scaled_pixbuf_fb (GOImage *image, int width, int height)
+{
+	if (image->pixbuf == NULL)
+		image->pixbuf = go_image_get_pixbuf_fb (image);
+	return gdk_pixbuf_scale_simple (image->pixbuf, width, height, GDK_INTERP_BILINEAR);
+}
+
+static void
+go_image_class_init (GOImageClass *klass)
+{
+	GObjectClass *obj_klass = (GObjectClass *) klass;
+	obj_klass->finalize = go_image_finalize;
+	obj_klass->set_property = go_image_set_property;
+	obj_klass->get_property = go_image_get_property;
 	parent_klass = g_type_class_peek_parent (klass);
-	g_object_class_install_property (klass, IMAGE_PROP_WIDTH,
+	g_object_class_install_property (obj_klass, IMAGE_PROP_WIDTH,
 					 g_param_spec_uint ("width", _("Width"),
 							    _("Image width in pixels"),
 							    0, G_MAXUINT16, 0, G_PARAM_READWRITE));
-	g_object_class_install_property (klass, IMAGE_PROP_HEIGHT,
+	g_object_class_install_property (obj_klass, IMAGE_PROP_HEIGHT,
 					 g_param_spec_uint ("height", _("Height"),
 							    _("Image height in pixels"),
 							    0, G_MAXUINT16, 0, G_PARAM_READWRITE));
+
+	klass->draw = go_image_draw_fb;
+	klass->get_pixbuf = go_image_get_pixbuf_fb;
+	klass->get_scaled_pixbuf = go_image_get_scaled_pixbuf_fb;
 }
 
 GSF_CLASS_ABSTRACT (GOImage, go_image,
@@ -390,6 +462,7 @@ go_image_get_thumbnail (GOImage *image)
 		image->thumbnail = go_image_get_scaled_pixbuf (image, GO_THUMBNAIL_SIZE, GO_THUMBNAIL_SIZE);
 	return image->thumbnail;
 }
+
 GdkPixbuf *
 go_image_get_pixbuf (GOImage *image)
 {
diff --git a/goffice/utils/go-spectre.c b/goffice/utils/go-spectre.c
index 77c26c6..f5feb57 100644
--- a/goffice/utils/go-spectre.c
+++ b/goffice/utils/go-spectre.c
@@ -114,12 +114,10 @@ go_spectre_build_surface (GOSpectre *spectre)
 	cairo_surface_set_user_data (spectre->surface, &key,
 				     data, (cairo_destroy_func_t) g_free);
 }
-#endif
 
-static void
+Sstatic void
 go_spectre_draw (GOImage *image, cairo_t *cr)
 {
-#ifdef GOFFICE_WITH_EPS
 	GOSpectre *spectre = GO_SPECTRE (image);
 	if (spectre->surface == NULL)
 		go_spectre_build_surface (spectre);
@@ -128,14 +126,12 @@ go_spectre_draw (GOImage *image, cairo_t *cr)
 	cairo_rectangle (cr, 0., 0., image->width, image->height);
 	cairo_fill (cr);
 	cairo_restore (cr);
-#endif
 }
 
 static GdkPixbuf *
 go_spectre_get_pixbuf (GOImage *image)
 {
 	GdkPixbuf *res = NULL;
-#ifdef GOFFICE_WITH_EPS
 	GOSpectre *spectre = GO_SPECTRE (image);
 	cairo_surface_t *surface;
 	cairo_t *cr;
@@ -153,7 +149,6 @@ go_spectre_get_pixbuf (GOImage *image)
 	                                   image->width, image->height,
 	                                   cairo_image_surface_get_stride (surface));
 	cairo_surface_destroy (surface);
-#endif
 	return res;
 }
 
@@ -161,7 +156,6 @@ static GdkPixbuf *
 go_spectre_get_scaled_pixbuf (GOImage *image, int width, int height)
 {
 	GdkPixbuf *res = NULL;
-#ifdef GOFFICE_WITH_EPS
 	GOSpectre *spectre = GO_SPECTRE (image);
 	cairo_surface_t *surface;
 	cairo_t *cr;
@@ -180,9 +174,9 @@ go_spectre_get_scaled_pixbuf (GOImage *image, int width, int height)
 	                                   width, height,
 	                                   cairo_image_surface_get_stride (surface));
 	cairo_surface_destroy (surface);
-#endif
 	return res;
 }
+#endif
 
 static gboolean
 go_spectre_differ (GOImage *first, GOImage *second)
@@ -216,9 +210,11 @@ go_spectre_class_init (GObjectClass *klass)
 	image_klass->save = go_spectre_save;
 	image_klass->load_attr = go_spectre_load_attr;
 	image_klass->load_data = go_spectre_load_data;
+#ifdef GOFFICE_WITH_EPS
 	image_klass->get_pixbuf = go_spectre_get_pixbuf;
 	image_klass->get_scaled_pixbuf = go_spectre_get_scaled_pixbuf;
 	image_klass->draw = go_spectre_draw;
+#endif
 	image_klass->differ = go_spectre_differ;
 }
 



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