[goffice] Add support for svg images inside gnumeric sheets.
- From: Jean BrÃfort <jbrefort src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [goffice] Add support for svg images inside gnumeric sheets.
- Date: Thu, 27 Oct 2011 15:25:16 +0000 (UTC)
commit 74dc9b514983ee2af7fa232414520c9e9fb51961
Author: Jean Brefort <jean brefort normalesup org>
Date: Thu Oct 27 17:24:22 2011 +0200
Add support for svg images inside gnumeric sheets.
ChangeLog | 20 ++++
goffice/canvas/goc-canvas.c | 13 +++
goffice/canvas/goc-canvas.h | 3 +
goffice/canvas/goc-image.c | 92 ++++++++++++++---
goffice/canvas/goc-image.h | 1 +
goffice/goffice.c | 1 +
goffice/graph/gog-plot-impl.h | 1 +
goffice/graph/gog-plot.c | 9 ++
goffice/graph/gog-plot.h | 1 +
goffice/utils/Makefile.am | 2 +
goffice/utils/go-emf.c | 236 +++++++++++++++++++++++++++++++++++++++++
goffice/utils/go-emf.h | 41 +++++++
goffice/utils/go-image.c | 38 +++++--
goffice/utils/go-image.h | 5 +-
goffice/utils/go-svg.c | 29 +++++
goffice/utils/go-svg.h | 1 +
goffice/utils/goffice-utils.h | 2 +
po/ChangeLog | 4 +
po/POTFILES.in | 4 +
tests/mf-demo.c | 2 +-
20 files changed, 480 insertions(+), 25 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 3a94486..e318501 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,23 @@
+2011-10-27 Jean Brefort <jean brefort normalesup org>
+
+ * goffice/canvas/goc-canvas.c: new helper functions.
+ * goffice/canvas/goc-canvas.h: ditto.
+ * goffice/canvas/goc-image.c: add crop.
+ * goffice/canvas/goc-image.h: ditto.
+ * goffice/goffice.c: initialize new type.
+ * goffice/graph/gog-plot-impl.h: add get_percent method.
+ * goffice/graph/gog-plot.c: ditto.
+ * goffice/graph/gog-plot.h: ditto.
+ * goffice/utils/Makefile.am: new files.
+ * goffice/utils/go-emf.c: added for a future support of WMF images.
+ * goffice/utils/go-emf.h: ditto.
+ * goffice/utils/go-image.c: add go_image_from_data().
+ * goffice/utils/go-image.h: ditto.
+ * goffice/utils/go-svg.c: ditto.
+ * goffice/utils/go-svg.h: ditto.
+ * goffice/utils/goffice-utils.h: add GOEmf.
+ * tests/mf-demo.c: fixed GOImage usage.
+
2011-10-26 Andreas J. Guelzow <aguelzow pyrshep ca>
* goffice/utils/go-pango-extras.c (go_pango_translate_here): allow for
diff --git a/goffice/canvas/goc-canvas.c b/goffice/canvas/goc-canvas.c
index 5bcf781..eab614e 100644
--- a/goffice/canvas/goc-canvas.c
+++ b/goffice/canvas/goc-canvas.c
@@ -639,3 +639,16 @@ goc_canvas_c2w (GocCanvas *canvas, double x, double y, int *x_, int *y_)
if (y_)
*y_ = go_fake_round ((y - canvas->scroll_y1) * canvas->pixels_per_unit);
}
+
+void
+goc_canvas_render (GocCanvas *canvas, cairo_t *cr, double x0, double y0, double x1, double y1)
+{
+ goc_item_draw_region (GOC_ITEM (canvas->root), cr, x0, y0, x1, y1);
+}
+
+void
+goc_canvas_get_bounds (GocCanvas *canvas, double *x0, double *y0, int *x1, int *y1)
+{
+ goc_item_get_bounds (GOC_ITEM (canvas->root), x0, y0, x1, y1);
+}
+
diff --git a/goffice/canvas/goc-canvas.h b/goffice/canvas/goc-canvas.h
index c6923a3..e6ab301 100644
--- a/goffice/canvas/goc-canvas.h
+++ b/goffice/canvas/goc-canvas.h
@@ -74,6 +74,9 @@ void goc_canvas_set_direction (GocCanvas *canvas, GocDirection direction);
GocDirection goc_canvas_get_direction (GocCanvas *canvas);
void goc_canvas_w2c (GocCanvas *canvas, int x, int y, double *x_, double *y_);
void goc_canvas_c2w (GocCanvas *canvas, double x, double y, int *x_, int *y_);
+void goc_canvas_render (GocCanvas *canvas, cairo_t *cr, double x0, double y0, double x1, double y1);
+void goc_canvas_get_bounds (GocCanvas *canvas, double *x0, double *y0, int *x1, int *y1);
+
G_END_DECLS
#endif /* GOC_CANVAS_H */
diff --git a/goffice/canvas/goc-image.c b/goffice/canvas/goc-image.c
index 2629207..e0d3ba2 100644
--- a/goffice/canvas/goc-image.c
+++ b/goffice/canvas/goc-image.c
@@ -39,7 +39,11 @@ enum {
IMAGE_PROP_W,
IMAGE_PROP_H,
IMAGE_PROP_ROTATION,
- IMAGE_PROP_IMAGE
+ IMAGE_PROP_IMAGE,
+ IMAGE_PROP_CROP_BOTTOM,
+ IMAGE_PROP_CROP_LEFT,
+ IMAGE_PROP_CROP_RIGHT,
+ IMAGE_PROP_CROP_TOP
};
static GocItemClass *parent_class;
@@ -77,6 +81,19 @@ goc_image_set_property (GObject *gobject, guint param_id,
image->image = GO_IMAGE (g_object_ref (g_value_get_object (value)));
break;
+ case IMAGE_PROP_CROP_BOTTOM:
+ image->crop_bottom = g_value_get_double (value);
+ break;
+ case IMAGE_PROP_CROP_LEFT:
+ image->crop_left = g_value_get_double (value);
+ break;
+ case IMAGE_PROP_CROP_RIGHT:
+ image->crop_right = g_value_get_double (value);
+ break;
+ case IMAGE_PROP_CROP_TOP:
+ image->crop_top = g_value_get_double (value);
+ break;
+
default: G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, param_id, pspec);
return; /* NOTE : RETURN */
}
@@ -116,6 +133,22 @@ goc_image_get_property (GObject *gobject, guint param_id,
g_value_set_object (value, G_OBJECT (image->image));
break;
+ case IMAGE_PROP_CROP_BOTTOM:
+ g_value_set_double (value, image->crop_bottom);
+ break;
+
+ case IMAGE_PROP_CROP_LEFT:
+ g_value_set_double (value, image->crop_left);
+ break;
+
+ case IMAGE_PROP_CROP_RIGHT:
+ g_value_set_double (value, image->crop_right);
+ break;
+
+ case IMAGE_PROP_CROP_TOP:
+ g_value_set_double (value, image->crop_top);
+ break;
+
default: G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, param_id, pspec);
return; /* NOTE : RETURN */
}
@@ -135,13 +168,21 @@ static void
goc_image_update_bounds (GocItem *item)
{
GocImage *image = GOC_IMAGE (item);
+ double w, h;
if (!image->image)
return;
/* FIXME: take rotation into account */
+ w = go_image_get_width (image->image) - image->crop_left - image->crop_right;
+ h = go_image_get_height (image->image) - image->crop_top - image->crop_bottom;
+ if (w <= 0 || h <= 0) {
+ /* nothing visible, put it at origin */
+ item->x0 = item->x1 = image->x;
+ item->y0 = item->y1 = image->y;
+ }
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)));
+ item->x1 = ceil (image->x + ((image->width > 0.)? image->width: w));
+ item->y1 = ceil (image->y + ((image->height > 0.)? image->height: h));
}
static double
@@ -149,24 +190,22 @@ 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;
+ double dx, dy;
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) {
+ if (x < item->x0) {
+ dx = item->x0 - x;
+ } else if (x < item->x1) {
dx = 0;
} else {
- dx = x - image->x - w;
+ dx = x - item->x1;
}
- if (y < image->y) {
- dy = image->y - y;
- } else if (y < image->y + h) {
+ if (y < item->y0) {
+ dy = item->y0 - y;
+ } else if (y < item->y1) {
dy = 0;
} else {
- dy = y - image->y - h;
+ dy = y - item->y1;
}
*near_item = item;
return hypot (dx, dy);
@@ -202,6 +241,11 @@ goc_image_draw (GocItem const *item, cairo_t *cr)
cairo_rotate (cr, image->rotation);
if (scalex != 1. || scaley != 1.)
cairo_scale (cr, scalex, scaley);
+ cairo_translate (cr, -image->crop_left, -image->crop_top);
+ cairo_rectangle (cr, 0, 0,
+ go_image_get_width (image->image) - image->crop_left - image->crop_right,
+ go_image_get_height (image->image) - image->crop_top - image->crop_bottom);
+ cairo_clip (cr);
cairo_move_to (cr, 0, 0);
go_image_draw (image->image, cr);
cairo_restore (cr);
@@ -251,6 +295,26 @@ goc_image_class_init (GocItemClass *item_klass)
_("The GOImage to display"),
GO_TYPE_IMAGE,
GSF_PARAM_STATIC | G_PARAM_READWRITE));
+ g_object_class_install_property (obj_klass, IMAGE_PROP_CROP_BOTTOM,
+ g_param_spec_double ("crop-bottom", _("Cropped bottom"),
+ _("The cropped area at the image bottom"),
+ 0., G_MAXDOUBLE, 0.,
+ GSF_PARAM_STATIC | G_PARAM_READWRITE));
+ g_object_class_install_property (obj_klass, IMAGE_PROP_CROP_LEFT,
+ g_param_spec_double ("crop-left", _("Cropped left"),
+ _("The cropped area at the image left"),
+ 0., G_MAXDOUBLE, 0.,
+ GSF_PARAM_STATIC | G_PARAM_READWRITE));
+ g_object_class_install_property (obj_klass, IMAGE_PROP_CROP_RIGHT,
+ g_param_spec_double ("crop-right", _("Cropped right"),
+ _("The cropped area at the image right"),
+ 0., G_MAXDOUBLE, 0.,
+ GSF_PARAM_STATIC | G_PARAM_READWRITE));
+ g_object_class_install_property (obj_klass, IMAGE_PROP_CROP_TOP,
+ g_param_spec_double ("crop-top", _("Cropped top"),
+ _("The cropped area at the image top"),
+ 0., G_MAXDOUBLE, 0.,
+ GSF_PARAM_STATIC | G_PARAM_READWRITE));
item_klass->update_bounds = goc_image_update_bounds;
item_klass->distance = goc_image_distance;
diff --git a/goffice/canvas/goc-image.h b/goffice/canvas/goc-image.h
index d1859a4..d3c8c7d 100644
--- a/goffice/canvas/goc-image.h
+++ b/goffice/canvas/goc-image.h
@@ -31,6 +31,7 @@ struct _GocImage {
GocItem base;
double x, y, width, height, rotation;
+ double crop_left, crop_right, crop_top, crop_bottom;
GOImage *image;
};
typedef GocItemClass GocImageClass;
diff --git a/goffice/goffice.c b/goffice/goffice.c
index ccef860..83a3571 100644
--- a/goffice/goffice.c
+++ b/goffice/goffice.c
@@ -213,6 +213,7 @@ libgoffice_init (void)
(void) GO_TYPE_DATA_SCALAR_VAL;
(void) GO_TYPE_DATA_SCALAR_STR;
(void) GOG_3D_BOX_TYPE;
+ (void) GO_TYPE_EMF;
(void) GO_TYPE_PIXBUF;
(void) GO_TYPE_SVG;
_gog_themes_init ();
diff --git a/goffice/graph/gog-plot-impl.h b/goffice/graph/gog-plot-impl.h
index cf9d7e1..994b8f3 100644
--- a/goffice/graph/gog-plot-impl.h
+++ b/goffice/graph/gog-plot-impl.h
@@ -77,6 +77,7 @@ typedef struct {
void (*update_3d) (GogPlot *plot);
void (*guru_helper) (GogPlot *plot, char const *hint);
+ double (*get_percent) (GogPlot *plot, unsigned series, unsigned index);
} GogPlotClass;
#define GOG_PLOT_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), GOG_TYPE_PLOT, GogPlotClass))
diff --git a/goffice/graph/gog-plot.c b/goffice/graph/gog-plot.c
index 59f2b94..badf84e 100644
--- a/goffice/graph/gog-plot.c
+++ b/goffice/graph/gog-plot.c
@@ -942,6 +942,15 @@ void gog_plot_clear_series (GogPlot *plot)
}
}
+double
+gog_plot_get_percent_value (GogPlot *plot, unsigned series, unsigned index)
+{
+ GogPlotClass *klass;
+ g_return_val_if_fail (GOG_IS_PLOT (plot), go_nan);
+ klass = GOG_PLOT_GET_CLASS (plot);
+ return (klass->get_percent)? klass->get_percent (plot, series, index): go_nan;
+}
+
/*****************************************************************************/
#ifdef GOFFICE_WITH_GTK
diff --git a/goffice/graph/gog-plot.h b/goffice/graph/gog-plot.h
index 768f95e..6989d8c 100644
--- a/goffice/graph/gog-plot.h
+++ b/goffice/graph/gog-plot.h
@@ -73,6 +73,7 @@ void gog_plot_clear_series (GogPlot *plot);
int gog_plot_view_get_data_at_point (GogPlotView *view,
double x, double y, GogSeries **series);
+double gog_plot_get_percent_value (GogPlot *plot, unsigned series, unsigned index);
G_END_DECLS
diff --git a/goffice/utils/Makefile.am b/goffice/utils/Makefile.am
index 6142123..7b55bc6 100644
--- a/goffice/utils/Makefile.am
+++ b/goffice/utils/Makefile.am
@@ -14,6 +14,7 @@ libgoffice_utils_la_SOURCES = \
go-image.c \
go-pixbuf.c \
go-svg.c \
+ go-emf.c \
go-line.c \
go-locale.c \
go-marker.c \
@@ -48,6 +49,7 @@ libgoffice_utils_la_HEADERS = \
go-image.h \
go-pixbuf.h \
go-svg.h \
+ go-emf.h \
go-line.h \
go-locale.h \
go-marker.h \
diff --git a/goffice/utils/go-emf.c b/goffice/utils/go-emf.c
new file mode 100644
index 0000000..a157713
--- /dev/null
+++ b/goffice/utils/go-emf.c
@@ -0,0 +1,236 @@
+/* vim: set sw=8: -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * go-emf.c - EMF/WMF image support
+ *
+ * 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 "go-emf.h"
+#include <gsf/gsf-utils.h>
+#include <gsf/gsf-impl-utils.h>
+#include <gsf/gsf-input-memory.h>
+#include <gsf/gsf-input-stdio.h>
+#include <glib/gi18n-lib.h>
+#include <string.h>
+
+struct _GOEmf {
+ GOImage parent;
+ GocCanvas *canvas;
+ gsize data_length;
+};
+
+typedef GOImageClass GOEmfClass;
+
+static GObjectClass *parent_klass;
+
+static gboolean go_emf_parse (GOEmf *emf, GsfInput *input, GError **error);
+
+static void
+go_emf_save (GOImage *image, GsfXMLOut *output)
+{
+ GOEmf *emf = GO_EMF (image);
+ g_return_if_fail (emf);
+ gsf_xml_out_add_base64 (output, NULL,
+ image->data, emf->data_length);
+}
+
+static void
+go_emf_load_attr (G_GNUC_UNUSED GOImage *image, G_GNUC_UNUSED xmlChar const *attr_name, G_GNUC_UNUSED xmlChar const *attr_value)
+{
+ /* nothing to do */
+}
+
+static void
+go_emf_load_data (GOImage *image, GsfXMLIn *xin)
+{
+ GOEmf *emf = GO_EMF (image);
+ emf->data_length = gsf_base64_decode_simple (xin->content->str, strlen(xin->content->str));
+ image->data = g_malloc (emf->data_length);
+ memcpy (image->data, xin->content->str, emf->data_length);
+ /* FIXME: build the canvas */
+}
+
+static void
+go_emf_draw (GOImage *image, cairo_t *cr)
+{
+ GOEmf *emf = GO_EMF (image);
+ g_return_if_fail (emf && emf->canvas);
+ goc_canvas_render (emf->canvas, cr, 0, 0, image->width, image->height);
+}
+
+static GdkPixbuf *
+go_emf_get_pixbuf (GOImage *image)
+{
+ GOEmf *emf = GO_EMF (image);
+ cairo_surface_t *surface;
+ cairo_t *cr;
+ GdkPixbuf *res = NULL;
+ g_return_val_if_fail (emf, NULL);
+ surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, image->width, image->height);
+ cr = cairo_create (surface);
+ goc_canvas_render (emf->canvas, cr, 0, 0, image->width, image->height);
+ cairo_destroy (cr);
+ res = gdk_pixbuf_new (GDK_COLORSPACE_RGB, TRUE, 8, image->width, image->height);
+ go_cairo_convert_data_from_pixbuf (gdk_pixbuf_get_pixels (res),
+ cairo_image_surface_get_data (surface),
+ image->width, image->height,
+ cairo_image_surface_get_stride (surface));
+ return res;
+ return NULL; /* FIXME */
+}
+
+static GdkPixbuf *
+go_emf_get_scaled_pixbuf (GOImage *image, int width, int height)
+{
+ GOEmf *emf = GO_EMF (image);
+ cairo_surface_t *surface;
+ cairo_t *cr;
+ GdkPixbuf *res = NULL;
+ g_return_val_if_fail (emf, NULL);
+ surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height);
+ cr = cairo_create (surface);
+ cairo_scale (cr, width / image->width, height / image->height);
+ goc_canvas_render (emf->canvas, cr, 0, 0, image->width, image->height);
+ cairo_destroy (cr);
+ res = gdk_pixbuf_new (GDK_COLORSPACE_RGB, TRUE, 8, width, height);
+ go_cairo_convert_data_from_pixbuf (gdk_pixbuf_get_pixels (res),
+ cairo_image_surface_get_data (surface),
+ width, height,
+ cairo_image_surface_get_stride (surface));
+ return res;
+}
+
+static gboolean
+go_emf_differ (GOImage *first, GOImage *second)
+{
+ GOEmf *sfirst = GO_EMF (first), *ssecond = GO_EMF (second);
+ if (sfirst->data_length != ssecond->data_length)
+ return TRUE;
+ return memcmp (first->data, second->data, sfirst->data_length);
+}
+
+static void
+go_emf_finalize (GObject *obj)
+{
+ GOEmf *emf = GO_EMF (obj);
+ if (emf->canvas != NULL)
+ g_object_unref (emf->canvas);
+ (parent_klass->finalize) (obj);
+}
+
+static void
+go_emf_class_init (GObjectClass *klass)
+{
+ GOImageClass *image_klass = (GOImageClass *) klass;
+
+ klass->finalize = go_emf_finalize;
+ parent_klass = g_type_class_peek_parent (klass);
+
+ image_klass->save = go_emf_save;
+ image_klass->load_attr = go_emf_load_attr;
+ image_klass->load_data = go_emf_load_data;
+ image_klass->get_pixbuf = go_emf_get_pixbuf;
+ image_klass->get_scaled_pixbuf = go_emf_get_scaled_pixbuf;
+ image_klass->draw = go_emf_draw;
+ image_klass->differ = go_emf_differ;
+}
+
+GSF_CLASS (GOEmf, go_emf,
+ go_emf_class_init, NULL,
+ GO_TYPE_IMAGE)
+
+GOEmf *
+go_emf_new_from_file (char const *filename, GError **error)
+{
+#ifdef GOFFICE_EMF_SUPPORT
+ GOEmf *emf = NULL;
+ GOImage *image;
+ GsfInput *input = gsf_input_stdio_new (filename, error);
+ guint8 *data;
+
+ if (input == NULL)
+ return NULL;
+ data = g_malloc (gsf_input_size (input));
+ if (!data || !gsf_input_read (input, emf->data_length, data)) {
+ g_object_unref (emf);
+ g_free (data);
+ if (error)
+ *error = g_error_new (go_error_invalid (), 0,
+ _("Could not load the image data"));
+ return NULL;
+ }
+ g_object_unref (input);
+ emf = g_object_new (GO_TYPE_EMF, NULL);
+ emf->data_length = gsf_input_size (input);
+ g_object_unref (input);
+
+ image = GO_IMAGE (emf);
+ image->data = data;
+ input = gsf_input_memory_new (data, emf->data_length, FALSE);
+ if (!go_emf_parse (emf, input, error)) {
+ g_object_unref (emf);
+ emf = NULL;
+ }
+ g_object_unref (input);
+
+ return emf;
+#else
+ return NULL;
+#endif
+}
+
+GOEmf *
+go_emf_new_from_data (char const *data, size_t length, GError **error)
+{
+#ifdef GOFFICE_EMF_SUPPORT
+ GOEmf *emf = NULL;
+ GsfInput *input = gsf_input_memory_new (data, length, FALSE);
+
+ if (input == NULL) {
+ if (error)
+ *error = g_error_new (go_error_invalid (), 0,
+ _("Could not input the image data"));
+ return NULL;
+ }
+ emf = g_object_new (GO_TYPE_EMF, NULL);
+ emf->data_length = gsf_input_size (input);
+ if (!go_emf_parse (emf, input, error)) {
+ g_object_unref (emf);
+ emf = NULL;
+ } else {
+ GOImage *image = GO_IMAGE (emf);
+ image->data = g_malloc (length);
+ memcpy (image->data, data, length);
+ }
+ g_object_unref (input);
+ return emf;
+#else
+ return NULL;
+#endif
+}
+
+/******************************************************************************
+ * Parsing code *
+ * ****************************************************************************/
+
+static gboolean go_emf_parse (GOEmf *emf, GsfInput *input, GError **error)
+{
+ /* FIXME: implement */
+ return FALSE;
+}
diff --git a/goffice/utils/go-emf.h b/goffice/utils/go-emf.h
new file mode 100644
index 0000000..6cd3960
--- /dev/null
+++ b/goffice/utils/go-emf.h
@@ -0,0 +1,41 @@
+/* vim: set sw=8: -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * go-emf.h - EMF/WMF image support
+ *
+ * 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 GO_EMF_H
+#define GO_EMF_H
+
+#include <goffice/goffice.h>
+
+G_BEGIN_DECLS
+
+#define GO_TYPE_EMF (go_emf_get_type ())
+#define GO_EMF(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GO_TYPE_EMF, GOEmf))
+#define GO_IS_EMF(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GO_TYPE_EMF))
+
+GType go_emf_get_type (void);
+
+GOEmf *go_emf_new_from_file (char const *filename, GError **error);
+GOEmf *go_emf_new_from_data (char const *data, size_t length, GError **error);
+
+G_END_DECLS
+
+#endif /* GO_EMF_H */
diff --git a/goffice/utils/go-image.c b/goffice/utils/go-image.c
index 5be0fba..2c61d89 100644
--- a/goffice/utils/go-image.c
+++ b/goffice/utils/go-image.c
@@ -362,10 +362,9 @@ go_image_class_init (GObjectClass *klass)
0, G_MAXUINT16, 0, G_PARAM_READWRITE));
}
-GSF_CLASS_FULL (GOImage, go_image,
- NULL, NULL,
- go_image_class_init, NULL, NULL,
- G_TYPE_OBJECT, G_TYPE_FLAG_ABSTRACT, {})
+GSF_CLASS_ABSTRACT (GOImage, go_image,
+ go_image_class_init, NULL,
+ G_TYPE_OBJECT)
void
go_image_draw (GOImage *image, cairo_t *cr)
@@ -405,7 +404,7 @@ go_image_get_scaled_pixbuf (GOImage *image, int width, int height)
}
GOImage *
-go_image_new_from_file (const char *filename, GError **error)
+go_image_new_from_file (char const *filename, GError **error)
{
char *mime, *name;
GOImageFormat format;
@@ -427,12 +426,12 @@ go_image_new_from_file (const char *filename, GError **error)
switch (format) {
case GO_IMAGE_FORMAT_SVG:
return GO_IMAGE (go_svg_new_from_file (filename, error));
- case GO_IMAGE_FORMAT_PDF:
- case GO_IMAGE_FORMAT_PS:
case GO_IMAGE_FORMAT_EMF:
case GO_IMAGE_FORMAT_WMF:
+ return GO_IMAGE (go_emf_new_from_file (filename, error));
+ case GO_IMAGE_FORMAT_PDF:
+ case GO_IMAGE_FORMAT_PS:
case GO_IMAGE_FORMAT_EPS:
- break;
case GO_IMAGE_FORMAT_UNKNOWN:
break;
default: {
@@ -447,6 +446,29 @@ go_image_new_from_file (const char *filename, GError **error)
return NULL;
}
+GOImage *
+go_image_new_from_data (char const *type, guint8 const *data, gsize length, GError **error)
+{
+ char *real_type = NULL;
+ GOImage *image = NULL;
+ if (type == NULL || *type == 0) {
+ char *mime_type = go_get_mime_type_for_data (data, length);
+ real_type = go_mime_to_image_format (mime_type);
+ g_free (mime_type);
+ type = real_type;
+ }
+ g_return_val_if_fail (type != NULL, NULL);
+ if (!strcmp (type, "svg")) {
+ image = GO_IMAGE (go_svg_new_from_data (data, length, error));
+ } else if (!strcmp (type, "emf") || !strcmp (type, "wmf")) {
+ image = GO_IMAGE (go_emf_new_from_data (data, length, error));
+ } else {
+ /* FIXME: pixbuf */
+ }
+ g_free (real_type);
+ return image;
+}
+
guint8 *
go_image_get_pixels (GOImage *image)
{
diff --git a/goffice/utils/go-image.h b/goffice/utils/go-image.h
index 6c1f7e1..59a0a8f 100644
--- a/goffice/utils/go-image.h
+++ b/goffice/utils/go-image.h
@@ -89,13 +89,14 @@ typedef struct {
gboolean (*differ) (GOImage *first, GOImage *second);
} GOImageClass;
-GOImage *go_image_new_from_pixbuf (GdkPixbuf *pixbuf);
GdkPixbuf const *go_image_get_thumbnail (GOImage *image);
GdkPixbuf *go_image_get_pixbuf (GOImage *image);
GdkPixbuf *go_image_get_scaled_pixbuf (GOImage *image, int width, int height);
void go_image_draw (GOImage *image, cairo_t *cr);
-GOImage *go_image_new_from_file (const char *filename, GError **error);
+GOImage *go_image_new_from_file (char const *filename, GError **error);
+GOImage *go_image_new_from_data (char const *type, guint8 const *data, gsize length, GError **error);
+
guint8 *go_image_get_pixels (GOImage *image);
void go_image_fill (GOImage *image, GOColor color);
diff --git a/goffice/utils/go-svg.c b/goffice/utils/go-svg.c
index c2c84a3..712a0aa 100644
--- a/goffice/utils/go-svg.c
+++ b/goffice/utils/go-svg.c
@@ -166,6 +166,7 @@ go_svg_new_from_file (char const *filename, GError **error)
data = g_malloc (svg->data_length);
if (!data || !gsf_input_read (input, svg->data_length, data)) {
g_object_unref (svg);
+ g_free (data);
return NULL;
}
image = GO_IMAGE (svg);
@@ -180,3 +181,31 @@ go_svg_new_from_file (char const *filename, GError **error)
image->height = dim.height;
return svg;
}
+
+GOSvg *
+go_svg_new_from_data (char const *data, size_t length, GError **error)
+{
+ GOSvg *svg;
+ GOImage *image;
+ RsvgDimensionData dim;
+
+ g_return_val_if_fail (data != NULL && length != 0, NULL);
+ svg = g_object_new (GO_TYPE_SVG, NULL);
+ svg->data_length = length;
+ image = GO_IMAGE (svg);
+ image->data = g_malloc (length);
+ if (image->data == NULL) {
+ g_object_unref (svg);
+ return NULL;
+ }
+ memcpy (image->data, data, length);
+ svg->handle = rsvg_handle_new_from_data (image->data, svg->data_length, error);
+ if (svg->handle == NULL) {
+ g_object_unref (svg);
+ return NULL;
+ }
+ rsvg_handle_get_dimensions (svg->handle, &dim);
+ image->width = dim.width;
+ image->height = dim.height;
+ return svg;
+}
diff --git a/goffice/utils/go-svg.h b/goffice/utils/go-svg.h
index baa8395..2cadb24 100644
--- a/goffice/utils/go-svg.h
+++ b/goffice/utils/go-svg.h
@@ -34,6 +34,7 @@ G_BEGIN_DECLS
GType go_svg_get_type (void);
GOSvg *go_svg_new_from_file (char const *filename, GError **error);
+GOSvg *go_svg_new_from_data (char const *data, size_t length, GError **error);
G_END_DECLS
diff --git a/goffice/utils/goffice-utils.h b/goffice/utils/goffice-utils.h
index 58208f2..7030a16 100644
--- a/goffice/utils/goffice-utils.h
+++ b/goffice/utils/goffice-utils.h
@@ -37,6 +37,7 @@ typedef struct _GODateConventions GODateConventions;
typedef struct _GOImage GOImage;
typedef struct _GOPixbuf GOPixbuf;
typedef struct _GOSvg GOSvg;
+typedef struct _GOEmf GOEmf;
typedef struct _GOPath GOPath;
typedef struct _GOString GOString;
typedef struct _GOStyle GOStyle;
@@ -117,6 +118,7 @@ G_END_DECLS
#include <goffice/utils/go-image.h>
#include <goffice/utils/go-pixbuf.h>
#include <goffice/utils/go-svg.h>
+#include <goffice/utils/go-emf.h>
#include <goffice/utils/go-libxml-extras.h>
#include <goffice/utils/go-line.h>
#include <goffice/utils/go-locale.h>
diff --git a/po/ChangeLog b/po/ChangeLog
index 6b0e3d0..70c9a34 100644
--- a/po/ChangeLog
+++ b/po/ChangeLog
@@ -1,3 +1,7 @@
+2011-10-27 Jean Brefort <jean brefort normalesup org>
+
+ * POTFILES.in: fixed file list.
+
2011-07-31 Morten Welinder <terra gnome org>
* Release 0.8.17
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 91b55dc..4f357fc 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -43,6 +43,7 @@ goffice/canvas/goc-component.c
goffice/canvas/goc-ellipse.c
goffice/canvas/goc-graph.c
goffice/canvas/goc-group.c
+goffice/canvas/goc-image.c
goffice/canvas/goc-item.c
goffice/canvas/goc-line.c
goffice/canvas/goc-path.c
@@ -186,6 +187,7 @@ goffice/gtk/go-format-sel.c
goffice/gtk/go-format-sel.h
[type: gettext/glade]goffice/gtk/go-image-save-dialog-extra.ui
[type: gettext/glade]goffice/gtk/go-image-sel.ui
+goffice/gtk/go-image-sel.c
goffice/gtk/go-locale-sel.c
goffice/gtk/go-locale-sel.h
goffice/gtk/go-optionmenu.c
@@ -222,6 +224,7 @@ goffice/utils/datetime.h
goffice/utils/formats.c
goffice/utils/go-color.c
goffice/utils/go-color.h
+goffice/utils/go-emf.c
goffice/utils/go-file.c
goffice/utils/go-file.h
goffice/utils/go-font.c
@@ -246,6 +249,7 @@ goffice/utils/go-marker.c
goffice/utils/go-marker.h
goffice/utils/go-pattern.c
goffice/utils/go-pattern.h
+goffice/utils/go-pixbuf.c
goffice/utils/go-style.c
goffice/utils/go-style.h
[type: gettext/glade]goffice/utils/go-style-prefs.ui
diff --git a/tests/mf-demo.c b/tests/mf-demo.c
index c35bc03..ca15d81 100644
--- a/tests/mf-demo.c
+++ b/tests/mf-demo.c
@@ -644,7 +644,7 @@ fill (Page *pg, GocItem *item)
style->fill.pattern.fore = GO_COLOR_FROM_RGB (b->clr.r, b->clr.g, b->clr.b);
break;
case 3:
- style->fill.image.image = go_image_new_from_pixbuf (b->bdata.data);
+ style->fill.image.image = GO_IMAGE (go_pixbuf_new_from_pixbuf (b->bdata.data));
style->fill.image.type = GO_IMAGE_WALLPAPER;
style->fill.type = GO_STYLE_FILL_IMAGE;
break;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]