[goffice] Fixed the without gtk build and add skeleton WMF and EMF parsers



commit 3ec359eca0e99cf0720daa51af2b81da6bfbf4d9
Author: Jean Brefort <jean brefort normalesup org>
Date:   Sat Oct 29 17:33:26 2011 +0200

    Fixed the without gtk build and add skeleton WMF and EMF parsers

 ChangeLog                        |   39 +
 goffice/Makefile.am              |    4 +-
 goffice/canvas/Makefile.am       |    8 +-
 goffice/canvas/goc-arc.h         |    1 +
 goffice/canvas/goc-canvas.c      |   28 +-
 goffice/canvas/goc-canvas.h      |   15 +
 goffice/canvas/goc-circle.h      |    1 +
 goffice/canvas/goc-component.c   |    4 +-
 goffice/canvas/goc-ellipse.h     |    1 +
 goffice/canvas/goc-graph.c       |    4 +
 goffice/canvas/goc-graph.h       |    1 +
 goffice/canvas/goc-group.h       |    5 +
 goffice/canvas/goc-image.h       |    1 +
 goffice/canvas/goc-item.c        |   19 +-
 goffice/canvas/goc-item.h        |   11 +-
 goffice/canvas/goc-line.h        |    1 +
 goffice/canvas/goc-path.h        |    1 +
 goffice/canvas/goc-pixbuf.h      |    1 +
 goffice/canvas/goc-polygon.h     |    1 +
 goffice/canvas/goc-polyline.h    |    1 +
 goffice/canvas/goc-rectangle.h   |    1 +
 goffice/canvas/goc-styled-item.h |    5 +
 goffice/canvas/goc-text.c        |    3 +
 goffice/canvas/goc-text.h        |    1 +
 goffice/canvas/goc-widget.h      |    1 +
 goffice/canvas/goffice-canvas.h  |    4 +-
 goffice/component/go-component.c |   50 +-
 goffice/component/go-component.h |   13 +-
 goffice/goffice.h                |    2 +-
 goffice/graph/gog-object.c       |    2 +-
 goffice/gtk/goffice-gtk.c        |    2 +
 goffice/utils/go-emf.c           | 2678 +++++++++++++++++++++++++++++++++++++-
 goffice/utils/go-image.h         |    5 +-
 goffice/utils/go-pango-extras.c  |    2 +
 goffice/utils/go-pango-extras.h  |    5 +
 plugins/plot_radar/gog-radar.c   |    2 +-
 36 files changed, 2860 insertions(+), 63 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index a0c8c03..c928f81 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,42 @@
+2011-10-29  Jean Brefort  <jean brefort normalesup org>
+
+	* goffice/Makefile.am: allow the canvas in the without gtk build.
+	* goffice/canvas/Makefile.am: ditto.
+	* goffice/canvas/goc-arc.h: add placeholders for extensions.
+	* goffice/canvas/goc-canvas.c: ditto.
+	* goffice/canvas/goc-canvas.h: ditto.
+	* goffice/canvas/goc-circle.h: ditto.
+	* goffice/canvas/goc-component.c: ditto.
+	* goffice/canvas/goc-ellipse.h: ditto.
+	* goffice/canvas/goc-graph.c: ditto.
+	* goffice/canvas/goc-graph.h: ditto.
+	* goffice/canvas/goc-group.h: ditto.
+	* goffice/canvas/goc-image.h: ditto.
+	* goffice/canvas/goc-item.c: ditto.
+	* goffice/canvas/goc-item.h: ditto.
+	* goffice/canvas/goc-line.h: ditto.
+	* goffice/canvas/goc-path.h: ditto.
+	* goffice/canvas/goc-pixbuf.h: ditto.
+	* goffice/canvas/goc-polygon.h: ditto.
+	* goffice/canvas/goc-polyline.h: ditto.
+	* goffice/canvas/goc-rectangle.h: ditto.
+	* goffice/canvas/goc-styled-item.h: ditto.
+	* goffice/canvas/goc-text.c: ditto.
+	* goffice/canvas/goc-text.h: ditto.
+	* goffice/canvas/goc-widget.h: ditto.
+	* goffice/canvas/goffice-canvas.h: ditto.
+	* goffice/component/go-component.c: remove support for windowed components.
+	* goffice/component/go-component.h: ditto.
+	* goffice/goffice.h: fix the without gtk build.
+	* goffice/graph/gog-object.c: ditto.
+	* goffice/gtk/goffice-gtk.c: ditto.
+	* goffice/utils/go-emf.c: imported Valek's WMF parser and started an EMF
+	parser.
+	* goffice/utils/go-image.h: fix the without gtk build.
+	* goffice/utils/go-pango-extras.c: ditto.
+	* goffice/utils/go-pango-extras.h: ditto.
+	* plugins/plot_radar/gog-radar.c: ditto.
+
 2011-10-28  Jean Brefort  <jean brefort normalesup org>
 
 	* goffice/graph/goffice-graph.h: some work on manual labels size.
diff --git a/goffice/Makefile.am b/goffice/Makefile.am
index bfc576c..9b041dc 100644
--- a/goffice/Makefile.am
+++ b/goffice/Makefile.am
@@ -1,4 +1,4 @@
-SUBDIRS = utils data app graph math
+SUBDIRS = utils data app graph math canvas
 
 lib_LTLIBRARIES = libgoffice- GOFFICE_API_VER@.la
 
@@ -12,7 +12,7 @@ libgoffice_ GOFFICE_API_VER@_la_LIBADD = 			\
 	$(GTK_MAC_LIBS)
 
 if WITH_GTK
-SUBDIRS += gtk component canvas
+SUBDIRS += gtk component
 libgoffice_ GOFFICE_API_VER@_la_LIBADD += 			\
 	gtk/libgoffice-gtk.la			\
 	component/libgoffice-component.la	\
diff --git a/goffice/canvas/Makefile.am b/goffice/canvas/Makefile.am
index 6fdc5c6..907973b 100644
--- a/goffice/canvas/Makefile.am
+++ b/goffice/canvas/Makefile.am
@@ -4,7 +4,6 @@ libgoffice_canvas_la_SOURCES =	\
 	goc-arc.c		\
 	goc-canvas.c		\
 	goc-circle.c		\
-	goc-component.c		\
 	goc-ellipse.c		\
 	goc-graph.c		\
 	goc-group.c		\
@@ -18,8 +17,13 @@ libgoffice_canvas_la_SOURCES =	\
 	goc-rectangle.c		\
 	goc-styled-item.c	\
 	goc-text.c		\
-	goc-utils.c		\
+	goc-utils.c
+
+if  WITH_GTK
+libgoffice_canvas_la_SOURCES += \
+	goc-component.c	\
 	goc-widget.c
+endif
 
 libgoffice_canvas_ladir = $(goffice_include_dir)/canvas
 libgoffice_canvas_la_HEADERS =	\
diff --git a/goffice/canvas/goc-arc.h b/goffice/canvas/goc-arc.h
index 4422031..f69e6e5 100644
--- a/goffice/canvas/goc-arc.h
+++ b/goffice/canvas/goc-arc.h
@@ -36,6 +36,7 @@ struct _GocArc {
 	int type;
 
 	GOArrow start_arrow, end_arrow;
+	gpointer priv;
 };
 
 typedef GocStyledItemClass GocArcClass;
diff --git a/goffice/canvas/goc-canvas.c b/goffice/canvas/goc-canvas.c
index 7691be7..4dbcb88 100644
--- a/goffice/canvas/goc-canvas.c
+++ b/goffice/canvas/goc-canvas.c
@@ -42,6 +42,8 @@
 
 static GObjectClass *parent_klass;
 
+#ifdef GOFFICE_WITH_GTK
+
 static gboolean
 goc_canvas_draw (GtkWidget *widget, cairo_t *cr)
 {
@@ -249,6 +251,8 @@ unrealize_cb (GocCanvas *canvas, G_GNUC_UNUSED gpointer data)
 	klass->unrealize (GOC_ITEM (canvas->root));
 }
 
+#endif
+
 static void
 goc_canvas_finalize (GObject *obj)
 {
@@ -268,25 +272,32 @@ goc_canvas_dispose (GObject *obj)
 static void
 goc_canvas_class_init (GObjectClass *klass)
 {
+#ifdef GOFFICE_WITH_GTK
 	GtkWidgetClass *widget_klass = (GtkWidgetClass *) klass;
+#endif
 
 	parent_klass = g_type_class_peek_parent (klass);
 	klass->finalize = goc_canvas_finalize;
 	klass->dispose = goc_canvas_dispose;
 
+#ifdef GOFFICE_WITH_GTK
 	widget_klass->draw = goc_canvas_draw;
+#endif
 }
 
 static void
 goc_canvas_init (GocCanvas *canvas)
 {
+#ifdef GOFFICE_WITH_GTK
 	GtkWidget *w = GTK_WIDGET (canvas);
-
+#endif
+	
 	canvas->root = GOC_GROUP (g_object_new (GOC_TYPE_GROUP, NULL));
 	canvas->root->base.canvas = canvas;
 	canvas->pixels_per_unit = 1.;
+#ifdef GOFFICE_WITH_GTK
 	gtk_widget_add_events (w,
-			   GDK_POINTER_MOTION_MASK |
+	                       GDK_POINTER_MOTION_MASK |
 			   GDK_BUTTON_MOTION_MASK |
 			   GDK_BUTTON_PRESS_MASK |
 			   GDK_2BUTTON_PRESS |
@@ -305,11 +316,16 @@ goc_canvas_init (GocCanvas *canvas)
 	g_signal_connect (G_OBJECT (w), "leave-notify-event", G_CALLBACK (leave_notify_cb), NULL);
 	g_signal_connect (G_OBJECT (w), "realize", G_CALLBACK (realize_cb), NULL);
 	g_signal_connect (G_OBJECT (w), "unrealize", G_CALLBACK (unrealize_cb), NULL);
+#endif
 }
 
 GSF_CLASS (GocCanvas, goc_canvas,
 	   goc_canvas_class_init, goc_canvas_init,
+#ifdef GOFFICE_WITH_GTK
 	   GTK_TYPE_LAYOUT)
+#else
+	   G_TYPE_OBJECT)
+#endif
 
 /**
  * goc_canvas_get_root :
@@ -370,8 +386,10 @@ goc_canvas_scroll_to (GocCanvas *canvas, double x, double y)
 	canvas->scroll_x1 = x;
 	canvas->scroll_y1 = y;
 	klass->notify_scrolled (GOC_ITEM (canvas->root));
+#ifdef GOFFICE_WITH_GTK
 	gtk_widget_queue_draw_area (GTK_WIDGET (canvas),
 					    0, 0, G_MAXINT, G_MAXINT);
+#endif
 }
 
 /**
@@ -410,8 +428,10 @@ goc_canvas_set_pixels_per_unit (GocCanvas *canvas, double pixels_per_unit)
 	klass = GOC_ITEM_GET_CLASS (canvas->root);
 	canvas->pixels_per_unit = pixels_per_unit;
 	klass->notify_scrolled (GOC_ITEM (canvas->root));
+#ifdef GOFFICE_WITH_GTK
 	gtk_widget_queue_draw_area (GTK_WIDGET (canvas),
 					    0, 0, G_MAXINT, G_MAXINT);
+#endif
 }
 
 /**
@@ -441,6 +461,7 @@ goc_canvas_get_pixels_per_unit (GocCanvas *canvas)
 void
 goc_canvas_invalidate (GocCanvas *canvas, double x0, double y0, double x1, double y1)
 {
+#ifdef GOFFICE_WITH_GTK
 	if (!gtk_widget_get_realized (GTK_WIDGET (canvas)))
 		return;
 	x0 = (x0 - canvas->scroll_x1) * canvas->pixels_per_unit;
@@ -465,6 +486,7 @@ goc_canvas_invalidate (GocCanvas *canvas, double x0, double y0, double x1, doubl
 					    (int) floor (x0) - 1, (int) floor (y0) - 1,
 					    (int) ceil (x1) - (int) floor (x0) + 2,
 		                            (int) ceil (y1) - (int) floor (y0) + 2);
+#endif
 }
 
 /**
@@ -553,6 +575,7 @@ goc_canvas_get_document (GocCanvas *canvas)
 	return canvas->document;
 }
 
+#ifdef GOFFICE_WITH_GTK
 /**
  * goc_canvas_get_cur_event :
  * @canvas : #GocCanvas
@@ -565,6 +588,7 @@ goc_canvas_get_cur_event (GocCanvas *canvas)
 	g_return_val_if_fail (GOC_IS_CANVAS (canvas), NULL);
 	return canvas->cur_event;
 }
+#endif
 
 /**
  * goc_canvas_ :
diff --git a/goffice/canvas/goc-canvas.h b/goffice/canvas/goc-canvas.h
index ca892a6..482e98b 100644
--- a/goffice/canvas/goc-canvas.h
+++ b/goffice/canvas/goc-canvas.h
@@ -24,7 +24,9 @@
 #define GOC_CANVAS_H
 
 #include <goffice/goffice.h>
+#ifdef GOFFICE_WITH_GTK
 #include <gdk/gdk.h>
+#endif
 
 G_BEGIN_DECLS
 
@@ -35,7 +37,11 @@ typedef enum {
 } GocDirection;
 
 struct _GocCanvas {
+#ifdef GOFFICE_WITH_GTK
 	GtkLayout base;
+#else
+	GObject base;
+#endif
 	double scroll_x1, scroll_y1;
 	double pixels_per_unit;
 	int width, height;
@@ -43,11 +49,18 @@ struct _GocCanvas {
 	GocItem *grabbed_item;
 	GocItem	*last_item;
 	GODoc *document;
+#ifdef GOFFICE_WITH_GTK
 	GdkEvent *cur_event;
+#endif
 	GocDirection direction;
+	gpointer priv;
 };
 
+#ifdef GOFFICE_WITH_GTK
 typedef GtkLayoutClass GocCanvasClass;
+#else
+typedef GObjectClass GocCanvasClass;
+#endif
 
 #define GOC_TYPE_CANVAS	(goc_canvas_get_type ())
 #define GOC_CANVAS(o)	(G_TYPE_CHECK_INSTANCE_CAST ((o), GOC_TYPE_CANVAS, GocCanvas))
@@ -69,7 +82,9 @@ void		 goc_canvas_ungrab_item (GocCanvas *canvas);
 GocItem		*goc_canvas_get_grabbed_item (GocCanvas *canvas);
 void		 goc_canvas_set_document (GocCanvas *canvas, GODoc *document);
 GODoc		*goc_canvas_get_document (GocCanvas *canvas);
+#ifdef GOFFICE_WITH_GTK
 GdkEvent	*goc_canvas_get_cur_event (GocCanvas *canvas);
+#endif
 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_);
diff --git a/goffice/canvas/goc-circle.h b/goffice/canvas/goc-circle.h
index 9f63acd..8395f6f 100644
--- a/goffice/canvas/goc-circle.h
+++ b/goffice/canvas/goc-circle.h
@@ -31,6 +31,7 @@ struct _GocCircle {
 	GocStyledItem base;
 
 	double x, y, radius;
+	gpointer priv;
 };
 
 typedef GocStyledItemClass GocCircleClass;
diff --git a/goffice/canvas/goc-component.c b/goffice/canvas/goc-component.c
index ebfad44..daac1ae 100644
--- a/goffice/canvas/goc-component.c
+++ b/goffice/canvas/goc-component.c
@@ -95,7 +95,7 @@ goc_component_set_property (GObject *obj, guint param_id,
 	}
 	case COMPONENT_PROP_ROTATION: {
 		double r = g_value_get_double (value) / 180. * M_PI;
-		if (!component->component || go_component_needs_window (component->component) || r == component->rotation)
+		if (!component->component || r == component->rotation)
 			return;
 		component->rotation = r;
 		break;
@@ -291,7 +291,7 @@ goc_component_class_init (GocItemClass *item_klass)
 	g_object_class_install_property (obj_klass, COMPONENT_PROP_ROTATION,
 		g_param_spec_double ("rotation",
 			_("Rotation"),
-			_("The rotation around center, only available for windowless components"),
+			_("The rotation around center"),
 			0., 360., 0.,
 			GSF_PARAM_STATIC | G_PARAM_READWRITE));
 	g_object_class_install_property (obj_klass, COMPONENT_PROP_OBJECT,
diff --git a/goffice/canvas/goc-ellipse.h b/goffice/canvas/goc-ellipse.h
index 13c40bb..21de21c 100644
--- a/goffice/canvas/goc-ellipse.h
+++ b/goffice/canvas/goc-ellipse.h
@@ -32,6 +32,7 @@ struct _GocEllipse {
 
 	double rotation; /* rotation around the center in radians */
 	double x, y, width, height;
+	gpointer priv;
 };
 
 typedef GocStyledItemClass GocEllipseClass;
diff --git a/goffice/canvas/goc-graph.c b/goffice/canvas/goc-graph.c
index 4ab9ef6..97187eb 100644
--- a/goffice/canvas/goc-graph.c
+++ b/goffice/canvas/goc-graph.c
@@ -245,6 +245,7 @@ format_coordinate (GogAxis *axis, GOFormat *fmt, double x)
 	return g_string_free (res, FALSE);
 }
 
+#ifdef GOFFICE_WITH_GTK
 static void
 goc_graph_do_tooltip (GocGraph *graph)
 {
@@ -422,6 +423,7 @@ goc_graph_leave_notify (GocItem *item, double x, double y)
 	gtk_widget_set_tooltip_text (GTK_WIDGET (item->canvas), NULL);
 	return ((GocItemClass*) parent_klass)->leave_notify (item, x, y);
 }
+#endif
 
 static void
 goc_graph_class_init (GocItemClass *item_klass)
@@ -474,8 +476,10 @@ goc_graph_class_init (GocItemClass *item_klass)
 	item_klass->draw = goc_graph_draw;
 	item_klass->update_bounds = goc_graph_update_bounds;
 	item_klass->distance = goc_graph_distance;
+#ifdef GOFFICE_WITH_GTK
 	item_klass->leave_notify = goc_graph_leave_notify;
 	item_klass->motion = goc_graph_motion;
+#endif
 }
 
 GSF_CLASS (GocGraph, goc_graph,
diff --git a/goffice/canvas/goc-graph.h b/goffice/canvas/goc-graph.h
index 1d1db62..b93efdd 100644
--- a/goffice/canvas/goc-graph.h
+++ b/goffice/canvas/goc-graph.h
@@ -36,6 +36,7 @@ struct _GocGraph {
 		guint timer_id;
 		double x, y;
 	} coords;
+	gpointer priv;
 };
 
 typedef GocItemClass GocGraphClass;
diff --git a/goffice/canvas/goc-group.h b/goffice/canvas/goc-group.h
index c1fc5a7..20b51ac 100644
--- a/goffice/canvas/goc-group.h
+++ b/goffice/canvas/goc-group.h
@@ -34,12 +34,17 @@ struct _GocGroup {
 	GList			*children;
 	GOPath			*clip_path;
 	cairo_fill_rule_t       clip_rule;
+	gpointer		priv;
 };
 
 typedef struct _GocGroupClass GocGroupClass;
 struct _GocGroupClass
 {
 	GocItemClass base;
+	void (*reserved1) (void);
+	void (*reserved2) (void);
+	void (*reserved3) (void);
+	void (*reserved4) (void);
 };
 
 #define GOC_TYPE_GROUP	(goc_group_get_type ())
diff --git a/goffice/canvas/goc-image.h b/goffice/canvas/goc-image.h
index d3c8c7d..7a94f1a 100644
--- a/goffice/canvas/goc-image.h
+++ b/goffice/canvas/goc-image.h
@@ -33,6 +33,7 @@ struct _GocImage {
 	double x, y, width, height, rotation;
 	double crop_left, crop_right, crop_top, crop_bottom;
 	GOImage *image;
+	gpointer priv;
 };
 typedef GocItemClass GocImageClass;
 
diff --git a/goffice/canvas/goc-item.c b/goffice/canvas/goc-item.c
index 8606c07..4811816 100644
--- a/goffice/canvas/goc-item.c
+++ b/goffice/canvas/goc-item.c
@@ -22,7 +22,9 @@
 
 #include <goffice/goffice-config.h>
 #include <goffice/goffice.h>
-#include <gtk/gtk.h>
+#ifdef GOFFICE_WITH_GTK
+#       include <gtk/gtk.h>
+#endif
 #include <gsf/gsf-impl-utils.h>
 #include <glib/gi18n-lib.h>
 
@@ -162,6 +164,7 @@ goc_item_leave_notify (GocItem *item, double x, double y)
 		FALSE;
 }
 
+#ifdef GOFFICE_WITH_GTK
 static gboolean
 goc_item_key_pressed (GocItem *item, GdkEventKey* ev)
 {
@@ -177,6 +180,7 @@ goc_item_key_released (GocItem *item, GdkEventKey* ev)
 		GOC_ITEM_GET_CLASS (item->parent)->key_released (GOC_ITEM (item->parent), ev):
 		FALSE;
 }
+#endif
 
 static void
 goc_item_realize (GocItem *item)
@@ -209,12 +213,14 @@ goc_item_dispose (GObject *object)
 			item->canvas->last_item = NULL;
 		if (item->canvas->grabbed_item == item)
 			item->canvas->grabbed_item = NULL;
+#ifdef GOFFICE_WITH_GTK
 		if (gtk_widget_get_realized (GTK_WIDGET (item->canvas))) {
 			item->cached_bounds = TRUE; /* avoids a call to update_bounds */
 			goc_item_invalidate (item);
 		}
+#endif
 	}
-
+	
 	if (item->parent != NULL)
 		goc_group_remove_child (item->parent, item);
 
@@ -271,8 +277,10 @@ goc_item_class_init (GocItemClass *item_klass)
 	item_klass->motion = goc_item_motion;
 	item_klass->enter_notify = goc_item_enter_notify;
 	item_klass->leave_notify = goc_item_leave_notify;
+#ifdef GOFFICE_WITH_GTK
 	item_klass->key_pressed = goc_item_key_pressed;
 	item_klass->key_released = goc_item_key_released;
+#endif
 }
 
 static void
@@ -442,9 +450,10 @@ goc_item_maybe_invalidate (GocItem *item, gboolean ignore_visibility)
 	if (!parent)
 		return;
 
+#ifdef GOFFICE_WITH_GTK
 	if (!gtk_widget_get_realized (GTK_WIDGET (item->canvas)))
 		return;
-
+#endif
 	if (!ignore_visibility && !item->visible)
 		return;
 
@@ -602,6 +611,7 @@ goc_item_ungrab	(GocItem *item)
 static void
 goc_item_reordered (GocItem *item, int n)
 {
+#ifdef GOFFICE_WITH_GTK
 	GocGroup *group = item->parent;
 	GList *cur = g_list_find (group->children, item);
 	GdkWindow *window;
@@ -620,6 +630,7 @@ goc_item_reordered (GocItem *item, int n)
 			cur = cur->prev;
 		}
 	}
+#endif
 }
 
 /**
@@ -726,9 +737,11 @@ goc_item_get_parent (GocItem *item)
 	return item->parent;
 }
 
+#ifdef GOFFICE_WITH_GTK
 GdkWindow *
 goc_item_get_window (GocItem *item)
 {
 	GocItemClass *klass = GOC_ITEM_GET_CLASS (item);
 	return (klass->get_window)? klass->get_window (item): NULL;
 }
+#endif
diff --git a/goffice/canvas/goc-item.h b/goffice/canvas/goc-item.h
index 9da18e1..7aab5b4 100644
--- a/goffice/canvas/goc-item.h
+++ b/goffice/canvas/goc-item.h
@@ -35,6 +35,7 @@ struct _GocItem {
 	gboolean		 visible;
 	gboolean		 realized;
 	double			 x0, y0, x1, y1; /* the bounds */
+	gpointer		 priv;
 };
 
 typedef struct _GocItemClass GocItemClass;
@@ -56,10 +57,16 @@ struct _GocItemClass {
 	gboolean		(*leave_notify) (GocItem *item, double x, double y);
 	void			(*realize) (GocItem *item);
 	void			(*unrealize) (GocItem *item);
+	void			(*notify_scrolled) (GocItem *item);
+#ifdef GOFFICE_WITH_GTK
 	gboolean		(*key_pressed) (GocItem *item, GdkEventKey* ev);
 	gboolean		(*key_released) (GocItem *item, GdkEventKey* ev);
-	void			(*notify_scrolled) (GocItem *item);
 	GdkWindow*		(*get_window) (GocItem *item);
+#endif
+	void (*reserved1) (void);
+	void (*reserved2) (void);
+	void (*reserved3) (void);
+	void (*reserved4) (void);
 };
 
 #define GOC_TYPE_ITEM	(goc_item_get_type ())
@@ -87,7 +94,9 @@ void		 goc_item_get_bounds	(GocItem const *item,
 					 double *x0, double *y0,
 					 double *x1, double *y1);
 GocGroup	*goc_item_get_parent    (GocItem *item);
+#ifdef GOFFICE_WITH_GTK
 GdkWindow       *goc_item_get_window    (GocItem *item);
+#endif
 void		 goc_item_bounds_changed (GocItem *item);
 void		 goc_item_grab		(GocItem *item);
 void		 goc_item_ungrab	(GocItem *item);
diff --git a/goffice/canvas/goc-line.h b/goffice/canvas/goc-line.h
index 395dc4f..7209c17 100644
--- a/goffice/canvas/goc-line.h
+++ b/goffice/canvas/goc-line.h
@@ -34,6 +34,7 @@ struct _GocLine {
 	double startx, starty, endx, endy;
 
 	GOArrow start_arrow, end_arrow;
+	gpointer priv;
 };
 
 typedef GocStyledItemClass GocLineClass;
diff --git a/goffice/canvas/goc-path.h b/goffice/canvas/goc-path.h
index bc0090e..0df6175 100644
--- a/goffice/canvas/goc-path.h
+++ b/goffice/canvas/goc-path.h
@@ -33,6 +33,7 @@ struct _GocPath {
 	double rotation, x, y;
 	gboolean closed;
 	GOPath *path;
+	gpointer priv;
 };
 
 typedef GocStyledItemClass GocPathClass;
diff --git a/goffice/canvas/goc-pixbuf.h b/goffice/canvas/goc-pixbuf.h
index 83ab00c..7faba64 100644
--- a/goffice/canvas/goc-pixbuf.h
+++ b/goffice/canvas/goc-pixbuf.h
@@ -32,6 +32,7 @@ struct _GocPixbuf {
 
 	double x, y, width, height, rotation;
 	GdkPixbuf *pixbuf;
+	gpointer priv;
 };
 typedef GocItemClass GocPixbufClass;
 
diff --git a/goffice/canvas/goc-polygon.h b/goffice/canvas/goc-polygon.h
index 8a94394..0054daf 100644
--- a/goffice/canvas/goc-polygon.h
+++ b/goffice/canvas/goc-polygon.h
@@ -38,6 +38,7 @@ struct _GocPolygon {
 	gboolean fill_rule;
 	unsigned nb_sizes;
 	int *sizes;
+	gpointer priv;
 };
 
 #define GOC_TYPE_POLYGON	(goc_polygon_get_type ())
diff --git a/goffice/canvas/goc-polyline.h b/goffice/canvas/goc-polyline.h
index ce7c352..e2a041e 100644
--- a/goffice/canvas/goc-polyline.h
+++ b/goffice/canvas/goc-polyline.h
@@ -35,6 +35,7 @@ struct _GocPolyline {
 	GocPoint *points;
 	unsigned nb_points;
 	gboolean use_spline;
+	gpointer priv;
 };
 
 #define GOC_TYPE_POLYLINE	(goc_polyline_get_type ())
diff --git a/goffice/canvas/goc-rectangle.h b/goffice/canvas/goc-rectangle.h
index 95b8f8e..c5927ef 100644
--- a/goffice/canvas/goc-rectangle.h
+++ b/goffice/canvas/goc-rectangle.h
@@ -43,6 +43,7 @@ struct _GocRectangle {
 	double x, y, width, height;
 	int type;
 	double rx, ry;
+	gpointer priv;
 };
 
 typedef GocStyledItemClass GocRectangleClass;
diff --git a/goffice/canvas/goc-styled-item.h b/goffice/canvas/goc-styled-item.h
index 1d66876..c00fda5 100644
--- a/goffice/canvas/goc-styled-item.h
+++ b/goffice/canvas/goc-styled-item.h
@@ -32,6 +32,7 @@ struct _GocStyledItem {
 
 	GOStyle	*style;
 	gboolean scale_line_width;
+	gpointer priv;
 };
 
 typedef struct _GocStyledItemClass GocStyledItemClass;
@@ -42,10 +43,14 @@ struct _GocStyledItemClass {
 	/*< public >*/
 	/* virtual */
 	void	  (*init_style)     	(GocStyledItem *item, GOStyle *style);
+	void (*reserved1) (void);
+	void (*reserved2) (void);
 
 	/*< private >*/
 	/* signal */
 	void (*style_changed) (GocStyledItem *item, GOStyle const *new_style);
+	void (*reserved_signal1) (void);
+	void (*reserved_signal2) (void);
 };
 
 #define GOC_TYPE_STYLED_ITEM	(goc_styled_item_get_type ())
diff --git a/goffice/canvas/goc-text.c b/goffice/canvas/goc-text.c
index 18e8808..2f1985e 100644
--- a/goffice/canvas/goc-text.c
+++ b/goffice/canvas/goc-text.c
@@ -24,6 +24,7 @@
 #include <goffice/goffice.h>
 #include <gsf/gsf-impl-utils.h>
 #include <glib/gi18n-lib.h>
+#include <pango/pangocairo.h>
 
 /**
  * SECTION:goc-text
@@ -207,6 +208,7 @@ goc_text_get_property (GObject *gobject, guint param_id,
 static void
 goc_text_realize (GocItem *item)
 {
+#ifdef GOFFICE_WITH_GTK
 	GocText *text = GOC_TEXT (item);
 	GOStyle *style = go_styled_object_get_style (GO_STYLED_OBJECT (item));
 
@@ -225,6 +227,7 @@ goc_text_realize (GocItem *item)
 	} else
 		pango_layout_set_width (text->layout, -1);
 	goc_item_bounds_changed (item);
+#endif
 }
 
 static void
diff --git a/goffice/canvas/goc-text.h b/goffice/canvas/goc-text.h
index 4110842..215a615 100644
--- a/goffice/canvas/goc-text.h
+++ b/goffice/canvas/goc-text.h
@@ -39,6 +39,7 @@ struct _GocText {
 	GOAnchorType anchor;
 	PangoAttrList *attributes;
 	PangoLayout *layout;
+	gpointer priv;
 };
 
 typedef GocStyledItemClass GocTextClass;
diff --git a/goffice/canvas/goc-widget.h b/goffice/canvas/goc-widget.h
index e3bde76..8dd378b 100644
--- a/goffice/canvas/goc-widget.h
+++ b/goffice/canvas/goc-widget.h
@@ -33,6 +33,7 @@ struct _GocWidget {
 	double x, y, w, h;
 	GtkWidget *widget, *ofbox;
 	double scale, rotation; /* rotation is not in use for now */
+	gpointer priv;
 };
 
 typedef GocItemClass GocWidgetClass;
diff --git a/goffice/canvas/goffice-canvas.h b/goffice/canvas/goffice-canvas.h
index 0de7e95..dd2f228 100644
--- a/goffice/canvas/goffice-canvas.h
+++ b/goffice/canvas/goffice-canvas.h
@@ -58,7 +58,6 @@ G_END_DECLS
 #include <goffice/canvas/goc-utils.h>
 
 #include <goffice/canvas/goc-circle.h>
-#include <goffice/canvas/goc-component.h>
 #include <goffice/canvas/goc-ellipse.h>
 #include <goffice/canvas/goc-graph.h>
 #include <goffice/canvas/goc-group.h>
@@ -71,6 +70,9 @@ G_END_DECLS
 #include <goffice/canvas/goc-polygon.h>
 #include <goffice/canvas/goc-rectangle.h>
 #include <goffice/canvas/goc-text.h>
+#ifdef GOFFICE_WITH_GTK
+#include <goffice/canvas/goc-component.h>
 #include <goffice/canvas/goc-widget.h>
+#endif
 
 #endif  /* GOFFICE_CANVAS_H */
diff --git a/goffice/component/go-component.c b/goffice/component/go-component.c
index 3b93371..6e9ca42 100644
--- a/goffice/component/go-component.c
+++ b/goffice/component/go-component.c
@@ -217,10 +217,8 @@ static void
 go_component_init (GOComponent *component)
 {
 	component->mime_type = NULL;
-	component->needs_window = FALSE;
 	component->editable = FALSE;
 	component->resizable = FALSE;
-	component->window = NULL;
 }
 
 GSF_CLASS_ABSTRACT (GOComponent, go_component,
@@ -361,33 +359,6 @@ go_component_set_default_size (GOComponent *component, double width, double asce
 		klass->set_default_size (component);
 }
 
-/**
- * go_component_needs_window:
- * @component: #GOComponent
- *
- * Returns: TRUE  if the component uses its own #GtkWindow.
- **/
-
-gboolean
-go_component_needs_window (GOComponent *component)
-{
-	g_return_val_if_fail (GO_IS_COMPONENT (component), FALSE);
-	return component->needs_window;
-}
-
-void
-go_component_set_window (GOComponent *component, GdkWindow *window)
-{
-	GOComponentClass *klass;
-
-	g_return_if_fail (GO_IS_COMPONENT (component));
-
-	klass = GO_COMPONENT_GET_CLASS(component);
-	component->window = window;
-	if (klass->set_window)
-		klass->set_window (component);
-}
-
 void
 go_component_set_data (GOComponent *component, char const *data, int length)
 {
@@ -439,6 +410,10 @@ go_component_set_size (GOComponent *component, double width, double height)
 	klass = GO_COMPONENT_GET_CLASS(component);
 	component->width = width;
 	component->height = height;
+	/* clear the snapshot */
+	g_free (component->snapshot_data);
+	component->snapshot_data = NULL;
+	component->snapshot_length = 0;
 	if (klass->set_size)
 		klass->set_size (component);
 }
@@ -518,7 +493,7 @@ go_component_get_size (GOComponent *component, double *width, double *height)
 {
 	*width = component->width;
 	if (component->height == 0.)
-		component->height = component->ascent >+ component->descent;
+		component->height = component->ascent + component->descent;
 	*height = component->height;
 }
 
@@ -731,8 +706,7 @@ go_component_build_snapshot (GOComponent *component)
 	default:
 		return GO_SNAPSHOT_NONE;
 	}
-	if (cairo_surface_status (surface) == CAIRO_STATUS_SUCCESS) {
-	} else
+	if (cairo_surface_status (surface) != CAIRO_STATUS_SUCCESS)
 		res = GO_SNAPSHOT_NONE;
 
 	cairo_surface_destroy (surface);
@@ -776,3 +750,15 @@ go_component_new_from_uri (char const *uri)
 	component->destroy_notify = g_free;
 	return component;
 }
+
+void const *
+go_component_get_snapshot (GOComponent *component, GOSnapshotType *type, size_t *length)
+{
+	if (component->snapshot_data == NULL)
+		go_component_build_snapshot (component);
+	if (type)
+		*type = component->snapshot_type;
+	if (length)
+		*length = component->snapshot_length;
+	return component->snapshot_data;
+}
diff --git a/goffice/component/go-component.h b/goffice/component/go-component.h
index 6444362..bacdbda 100644
--- a/goffice/component/go-component.h
+++ b/goffice/component/go-component.h
@@ -49,10 +49,10 @@ struct _GOComponent {
 	GDestroyNotify destroy_notify;
 	gpointer destroy_data;
 	int length;
-	GdkWindow *window;
 	GOSnapshotType snapshot_type;
 	void *snapshot_data;
 	size_t snapshot_length;
+	gpointer priv;
 };
 
 struct _GOComponentClass {
@@ -65,12 +65,19 @@ struct _GOComponentClass {
 	void (*set_data) (GOComponent *component);
 	void (*set_default_size) (GOComponent* component);
 	void (*set_size) (GOComponent *component);
-	void (*set_window) (GOComponent *component);
 	void (*render) (GOComponent *component, cairo_t *cr,
 			    double width, double height);
+	void (*reserved1) (void);
+	void (*reserved2) (void);
+	void (*reserved3) (void);
+	void (*reserved4) (void);
 
 	/* signals */
 	void (*changed) (GOComponent* component);
+	void (*reserved_signal1) (void);
+	void (*reserved_signal2) (void);
+	void (*reserved_signal3) (void);
+	void (*reserved_signal4) (void);
 };
 
 typedef struct _GOComponentClass GOComponentClass;
@@ -87,7 +94,6 @@ GOComponent  *go_component_new_from_uri	(char const *uri);
 
 void go_component_set_default_size (GOComponent *component,
 				    double width, double ascent, double descent);
-gboolean go_component_needs_window (GOComponent *component);
 void go_component_set_window (GOComponent *component, GdkWindow *window);
 void go_component_set_data (GOComponent *component,
 			    char const *data, int length);
@@ -110,6 +116,7 @@ void go_component_sax_push_parser (GsfXMLIn *xin, xmlChar const **attrs,
 				       GOComponentSaxHandler handler, gpointer user_data);
 
 GOSnapshotType go_component_build_snapshot (GOComponent *component);
+void const *go_component_get_snapshot (GOComponent *component, GOSnapshotType *type, size_t *length);
 
 G_END_DECLS
 
diff --git a/goffice/goffice.h b/goffice/goffice.h
index c288bbe..f3a6f31 100644
--- a/goffice/goffice.h
+++ b/goffice/goffice.h
@@ -54,9 +54,9 @@
 #include <goffice/data/goffice-data.h>
 #include <goffice/math/goffice-math.h>
 #include <goffice/graph/goffice-graph.h>
+#include <goffice/canvas/goffice-canvas.h>
 #ifdef GOFFICE_WITH_GTK
 #include <goffice/gtk/goffice-gtk.h>
-#include <goffice/canvas/goffice-canvas.h>
 #endif
 
 G_BEGIN_DECLS
diff --git a/goffice/graph/gog-object.c b/goffice/graph/gog-object.c
index 7c41062..5c0ddff 100644
--- a/goffice/graph/gog-object.c
+++ b/goffice/graph/gog-object.c
@@ -519,7 +519,7 @@ gog_object_populate_editor (GogObject *gobj,
 		w = go_gtk_builder_get_widget (gui, "size-select-box");
 		gtk_widget_destroy (w);
 	} else {
-		gboolean manual_size = flags & GOG_POSITION_ANY_MANUAL_SIZE;
+		gboolean manual_size = (flags = gog_object_get_position_flags (gobj, GOG_POSITION_ANY_MANUAL_SIZE)) != 0;
 		w = go_gtk_builder_get_widget (gui, "object-size-combo");
 		gtk_combo_box_set_active (GTK_COMBO_BOX (w),
 		                          manual_size? 1: 0);
diff --git a/goffice/gtk/goffice-gtk.c b/goffice/gtk/goffice-gtk.c
index 4015b33..26139f1 100644
--- a/goffice/gtk/goffice-gtk.c
+++ b/goffice/gtk/goffice-gtk.c
@@ -863,6 +863,8 @@ go_gui_get_image_save_info (GtkWindow *toplevel, GSList *supported_formats,
 			for (l = supported_formats, i = 0; l != NULL; l = l->next, i++) {
 				format = GPOINTER_TO_UINT (l->data);
 				format_info = go_image_get_format_info (format);
+				if (format_info == NULL)
+					continue;
 				go_gtk_combo_box_append_text (format_combo, _(format_info->desc));
 				if (format == state->format)
 					gtk_combo_box_set_active (format_combo, i);
diff --git a/goffice/utils/go-emf.c b/goffice/utils/go-emf.c
index 90c8f05..485996e 100644
--- a/goffice/utils/go-emf.c
+++ b/goffice/utils/go-emf.c
@@ -153,8 +153,14 @@ go_emf_class_init (GObjectClass *klass)
 	image_klass->differ = go_emf_differ;
 }
 
+static void
+go_emf_init (GOEmf *emf)
+{
+	emf->canvas = g_object_ref_sink (g_object_new (GOC_TYPE_CANVAS, NULL));
+}
+
 GSF_CLASS (GOEmf, go_emf,
-	   go_emf_class_init, NULL,
+	   go_emf_class_init, go_emf_init,
 	   GO_TYPE_IMAGE)
 
 GOImage *
@@ -174,7 +180,7 @@ go_emf_new_from_file (char const *filename, GError **error)
 		g_free (data);
 		if (error)
 			*error = g_error_new (go_error_invalid (), 0,
-			                      _("Could not load the image data"));
+			                      _("Could not load the image data\n"));
 		return NULL;
 	}
 	g_object_unref (input);
@@ -191,6 +197,13 @@ go_emf_new_from_file (char const *filename, GError **error)
 	}
 	g_object_unref (input);
 
+	if (emf) {
+		double x0, y0, x1, y1;
+		goc_canvas_get_bounds (emf->canvas, &x0, &y0, &x1, &y1);
+		image->width = x1;
+		image->height = y1;
+	}
+
 	return image;
 #else
 	return NULL;
@@ -208,7 +221,7 @@ go_emf_new_from_data (char const *data, size_t length, GError **error)
 	if (input == NULL) {
 		if (error)
 			*error = g_error_new (go_error_invalid (), 0,
-			                      _("Could not input the image data"));
+			                      _("Could not input the image data\n"));
 		return NULL;
 	}
 	emf = g_object_new (GO_TYPE_EMF, NULL);
@@ -217,9 +230,13 @@ go_emf_new_from_data (char const *data, size_t length, GError **error)
 		g_object_unref (emf);
 		image = NULL;
 	} else {
-		*image = GO_IMAGE (emf);
+		double x0, y0, x1, y1;
+		image = GO_IMAGE (emf);
 		image->data = g_malloc (length);
 		memcpy (image->data, data, length);
+		goc_canvas_get_bounds (emf->canvas, &x0, &y0, &x1, &y1);
+		image->width = x1;
+		image->height = y1;
 	}
 	g_object_unref (input);
 	return image;
@@ -228,14 +245,2659 @@ go_emf_new_from_data (char const *data, size_t length, GError **error)
 #endif
 }
 
+
+#ifdef GOFFICE_EMF_SUPPORT
 /******************************************************************************
- * Parsing code                                                               *
+ * Parsing code                                                               
+ *
+ * Parse WMF file
+ *
+ *  Copyright (C) 2010 Valek Filippov (frob gnome 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 Library 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.
  * ****************************************************************************/
 
-#ifdef GOFFICE_EMF_SUPPORT
-static gboolean go_emf_parse (GOEmf *emf, GsfInput *input, GError **error)
+#ifdef DEBUG_EMF_SUPPORT
+#       define d_(x)     g_print x
+#else
+#       define d_(x)
+#endif
+
+/*****************************************************************************
+ * First WMF parsing code
+ *****************************************************************************/
+
+typedef struct {
+	guint8 b;
+	guint8 g;
+	guint8 r;
+	guint8 a;
+} GOWmfColor;
+
+typedef struct {
+	double VPx;
+	double VPy;
+	double VPOx;
+	double VPOy;
+	double Wx;
+	double Wy;
+	double x;
+	double y;
+	double curx;
+	double cury;
+	gint curfg;
+	gint curbg;
+	gint curfnt;
+	gint curpal;
+	gint curreg;
+	guint txtalign;
+	guint bkmode;
+	guint pfm;
+	GOWmfColor bkclr;
+	GOWmfColor txtclr;
+} GOWmfDC;
+
+typedef struct {
+	guint type; /* 1 pen, 2 brush, 3 font, 4 region, 5 palette */
+	gpointer values;
+} GOWmfMFobj;
+
+typedef struct {
+	guint16 style;
+	gint16 width;
+	gint16 height;
+	GOWmfColor clr;
+	guint16 flag;
+} GOWmfPen;
+
+typedef struct {
+	guint width;
+	guint height;
+	gpointer data;
+} GOWmfBrushData;
+
+typedef struct {
+	guint16 style;
+	GOWmfColor clr;
+	guint16 hatch;
+	GOWmfBrushData bdata;
+} GOWmfBrush;
+
+typedef struct {
+	double b;
+	double r;
+	double t;
+	double l;
+	double xs;
+	double ys;
+	double xe;
+	double ye;
+} GOWmfArc;
+
+
+typedef struct {
+	gpointer name;
+	gint16 size;
+	gint16 weight;
+	gint16 escape;
+	gint16 orient;
+	gint italic;
+	gint under;
+	gint strike;
+	gchar *charset;
+} GOWmfFont;
+
+typedef struct {
+	int maxobj;
+	guint curobj;
+	guint curdc;
+	GHashTable *mfobjs;
+	GArray *dcs;
+	double zoom;
+	double w;
+	double h;
+	int type;
+} GOWmfPage;
+
+typedef struct {
+	gint32 left, right, top, bottom;
+} GOWmfRectL;
+
+static void
+go_wmf_read_rectl (GOWmfRectL *rect, guint8 const *data)
+{
+	rect->left = GSF_LE_GET_GINT32 (data);
+	rect->top = GSF_LE_GET_GINT32 (data + 4);
+	rect->right = GSF_LE_GET_GINT32 (data + 8);
+	rect->bottom = GSF_LE_GET_GINT32 (data + 12);
+}
+
+typedef struct {
+	GocCanvas *canvas;
+	GError **error;
+	guint8 const *data;
+	unsigned length;
+	GOWmfRectL dubounds; /* bounds in device units */
+	GOWmfRectL mmbounds; /* bounds in mm/100 */
+	gboolean is_emf;	/* FIXME: might be EPS or WMF */
+} GOEmfState;
+
+
+static char *
+go_wmf_mtextra_to_utf (char *txt)
+{
+	const guint16 mte[256] = {
+	0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
+	0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+	0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x300,
+	0x302, 0x303, 0x2d9, 0x27, 0x2322, 0x2323, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
+	0x30, 0xe13d, 0xe141, 0xe13e, 0x23af, 0x35, 0xe13b, 0xe140, 0xe13c, 0x39, 0x3a, 0x3b,
+	0x25c3, 0x3d, 0x25b9, 0x3f, 0x40, 0x41, 0x42, 0x2210, 0x19b, 0x45, 0x46,
+	0x47, 0x48, 0x2229, 0x4a, 0x2026, 0x22ef, 0x22ee, 0x22f0, 0x22f1, 0x50,
+	0x2235, 0x52, 0x53, 0x54, 0x222a, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x5c,
+	0x5d, 0x5e, 0x5f, 0x2035, 0x21a6, 0x2195, 0x21d5, 0x64, 0x65, 0x227b, 0x67,
+	0x210f, 0x69, 0x6a, 0x6b, 0x2113, 0x2213, 0x6e, 0x2218, 0x227a, 0x71, 0x20d7,
+	0x20d6, 0x20e1, 0x20d6, 0x20d1, 0x20d0, 0x78, 0x79, 0x7a, 0x23de, 0x7c,
+	0x23df, 0x7e,0x7f, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88,
+	0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x90, 0x91, 0x92, 0x93, 0x94,
+	0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xa0,
+	0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac,
+	0xad, 0xae, 0xaf, 0xb0, 0xa1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8,
+	0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, 0xc0, 0xc1, 0xc2, 0xc3, 0xc4,
+	0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 0xd0,
+	0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xdb, 0xdc,
+	0xdd, 0xde, 0xdf, 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8,
+	0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, 0xf0, 0xf1, 0xf2, 0xf3, 0xf4,
+	0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff};
+	guint16  *data = {0};
+	char* utxt;
+	guint i;
+
+	data = malloc (strlen (txt) * 2);
+	for (i = 0; i < strlen (txt); i++)
+		data[i] = mte[(guint8) txt[i]];
+	utxt =  g_utf16_to_utf8 (data, strlen (txt), NULL, NULL, NULL);
+	return utxt;
+}
+
+static char *
+go_wmf_symbol_to_utf (char* txt)
+{
+	const guint16 utf[256] = {
+	0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
+	0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+	0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x2200, 0x23,
+	0x2203, 0x25, 0x26, 0x220d, 0x28, 0x29, 0x2217, 0x2b, 0x2c, 0x2212, 0x2e,
+	0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a,
+	0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x2245, 0x391, 0x392, 0x3a7, 0x394, 0x395,
+	0x3a6, 0x393, 0x397, 0x399, 0x3d1, 0x39a, 0x39b, 0x39c, 0x39d, 0x39f,
+	0x3a0, 0x398, 0x3a1, 0x3a3, 0x3a4, 0x3a5, 0x3c2, 0x3a9, 0x39e, 0x3a8,
+	0x396, 0x5b, 0x2234, 0x5d, 0x22a5, 0x5f, 0xf8e5, 0x3b1, 0x3b2, 0x3c7,
+	0x3b4, 0x3b5, 0x3c6, 0x3b3, 0x3b7, 0x3b9, 0x3d5, 0x3ba, 0x3bb, 0x3bc,
+	0x3bd, 0x3bf, 0x3c0, 0x3b8, 0x3c1, 0x3c3, 0x3c4, 0x3c5, 0x3d6, 0x3c9,
+	0x3be, 0x3c8, 0x3b6, 0x7b, 0x7c, 0x7d, 0x223c, 0x7f, 0x80, 0x81, 0x82,
+	0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e,
+	0x8f, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a,
+	0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0x3d2, 0x2032, 0x2264, 0x2044, 0x201e,
+	0x192, 0x2663, 0x2666, 0x2665, 0x2660, 0x2194, 0x2190, 0x2191, 0x2192,
+	0x2193, 0xb0, 0xb1, 0x2033, 0x2265, 0xd7, 0x221d, 0x2202, 0x2022, 0xf7,
+	0x2260, 0x2261, 0x2248, 0x2026, 0xf8e6, 0xf8e7, 0x21b5, 0x2135, 0x2111,
+	0x211c, 0x2118, 0x2297, 0x2295, 0x2205, 0x2229, 0x222a, 0x2283, 0x2287,
+	0x2284, 0x2282, 0x2286, 0x2208, 0x2209, 0x2220, 0x2207, 0xae, 0xa9, 0x2122,
+	0x220f, 0x221a, 0x22c5, 0xac, 0x2227, 0x2228, 0x21d4, 0x21d0, 0x21d1,
+	0x21d2, 0x21d3, 0x22c4, 0x2329, 0xf8e8, 0xf8e9, 0xf8ea, 0x2211, 0xf8eb,
+	0xf8ec, 0xf8ed, 0xf8ee, 0xf8ef, 0xf8f0, 0xf8f1, 0xf8f2, 0xf8f3, 0xf8f4,
+	0xf8ff, 0x232a, 0x222b, 0x2320, 0xf8f5, 0x2321, 0xf8f6, 0xf8f7, 0xf8f8,
+	0xf8f9, 0xf8fa, 0xf8fb, 0xf8fc, 0xf8fd, 0xf8fe, 0x2c7};
+	guint16  *data = {0};
+	char* utxt;
+	guint i;
+
+	data = malloc (strlen (txt) * 2);
+	for (i = 0; i < strlen (txt); i++)
+		data[i] = utf[(guint8) txt[i]];
+	utxt =  g_utf16_to_utf8 (data, strlen (txt), NULL, NULL, NULL);
+	return utxt;
+}
+
+static void
+go_wmf_set_font (GOWmfPage *pg, GocItem *item)
+{
+	GOWmfMFobj *mfo;
+	GOWmfFont *font;
+	double rot;
+	PangoAttrList *pattl = pango_attr_list_new ();
+	GOWmfDC *dc;
+
+	dc = &g_array_index (pg->dcs, GOWmfDC, pg->curdc);
+	if (-1 == dc->curfnt)
+		return;
+
+	mfo = g_hash_table_lookup (pg->mfobjs, GINT_TO_POINTER (dc->curfnt));
+	font = mfo->values;
+	/* convert font values to PangoAttrList */
+	if (font->escape > 0) {
+		rot = (double) (font->escape % 3600) * M_PI / 1800.;
+		goc_item_set (item, "rotation", M_PI * 2 - rot, NULL);
+	}
+	if (font->size < 0)
+		font->size = -font->size;
+	if (font->size == 0)
+		font->size = 12;
+	pango_attr_list_insert (pattl, pango_attr_size_new (font->size * 1024. * pg->zoom / 1.5));
+	pango_attr_list_insert (pattl, pango_attr_foreground_new (dc->txtclr.r * 256, dc->txtclr.g * 256, dc->txtclr.b * 256));
+
+	if (2 == dc->bkmode)
+		pango_attr_list_insert (pattl, pango_attr_background_new (dc->bkclr.r * 256, dc->bkclr.g * 256, dc->bkclr.b * 256));
+	pango_attr_list_insert (pattl, pango_attr_weight_new (font->weight));
+	pango_attr_list_insert (pattl, pango_attr_family_new (font->name));
+	if (0 != font->italic)
+		pango_attr_list_insert (pattl, pango_attr_style_new (PANGO_STYLE_ITALIC));
+	if (0 != font->under)
+		pango_attr_list_insert (pattl, pango_attr_underline_new (PANGO_UNDERLINE_SINGLE));
+	if (0 != font->strike)
+		pango_attr_list_insert (pattl, pango_attr_strikethrough_new (TRUE));
+	goc_item_set(item, "attributes", pattl, NULL);
+}
+
+static void
+go_wmf_init_dc (GOWmfDC *dc)
+{
+	dc->VPx = 1;
+	dc->VPy = 1;
+	dc-> VPOx = 0;
+	dc->VPOy = 0;
+	dc->Wx = 1.;
+	dc->Wy = 1.;
+	dc->x = 0;
+	dc->y = 0;
+	dc->curx = 0;
+	dc->cury = 0;
+	dc->curfg = -1;
+	dc->curbg = -1;
+	dc->curfnt = -1;
+	dc->curpal = -1;
+	dc->curreg = -1;
+	dc->txtalign = 0;
+	dc->bkmode = 0;
+	dc->pfm = 1;
+	dc->bkclr = (GOWmfColor) {255, 255, 255, 255};
+	dc->txtclr = (GOWmfColor) {0, 0, 0, 255};
+}
+
+static void
+go_wmf_init_page (GOWmfPage* pg)
+{
+	GOWmfDC mydc;
+
+	go_wmf_init_dc (&mydc);
+	pg->maxobj = 0;
+	pg->curobj = 0;
+	pg->curdc = 0;
+	pg->w = 320;
+	pg->h = 200;
+	pg->zoom = 1.;
+	pg->type = 0;
+	pg->mfobjs = g_hash_table_new (g_direct_hash, g_direct_equal);
+	pg->dcs = g_array_new (FALSE, FALSE, sizeof (GOWmfDC));
+	g_array_append_vals (pg->dcs, &mydc, 1);
+}
+
+static void
+go_wmf_mr_convcoord (double* x, double* y, GOWmfPage* pg)
+{
+	GOWmfDC *dc;
+
+	dc = &g_array_index (pg->dcs, GOWmfDC, pg->curdc);
+	*x = (*x - dc->x) * dc->VPx / dc->Wx + dc->VPOx;
+	*y = (*y - dc->y) * dc->VPy / dc->Wy + dc->VPOy;
+}
+
+static void
+go_wmf_read_point (GsfInput* input, double* y, double* x)
+{
+	const guint8  *data = {0};
+
+	data = gsf_input_read (input, 2, NULL);
+	*y = GSF_LE_GET_GINT16 (data);
+	data = gsf_input_read (input, 2, NULL);
+	*x = GSF_LE_GET_GINT16 (data);
+}
+
+static void
+go_wmf_set_anchor (GOWmfPage* pg, GOAnchorType* anchor)
+{
+	GOWmfDC *dc;
+
+	dc = &g_array_index (pg->dcs, GOWmfDC, pg->curdc);
+
+	switch(dc->txtalign & 6) {
+	case 0: /* right */
+		switch(dc->txtalign & 24) {
+			case 0: /* top */
+				*anchor = GO_ANCHOR_SOUTH_WEST;
+				break;
+			case 8: /* bottom */
+				*anchor = GO_ANCHOR_NORTH_WEST;
+				break;
+			case 24: /* baseline */
+				*anchor = GO_ANCHOR_WEST;
+				break;
+		}
+		break;
+	case 2: /* left */
+		switch(dc->txtalign & 24) {
+			case 0: /* top */
+				*anchor = GO_ANCHOR_SOUTH_EAST;
+				break;
+			case 8: /* bottom */
+				*anchor = GO_ANCHOR_NORTH_EAST;
+				break;
+			case 24: /* baseline */
+				*anchor = GO_ANCHOR_EAST;
+				break;
+		}
+		break;
+	case 6: /* center */
+		switch(dc->txtalign & 24) {
+			case 0: /* top */
+				*anchor = GO_ANCHOR_SOUTH;
+				break;
+			case 8: /* bottom */
+				*anchor = GO_ANCHOR_NORTH;
+				break;
+			case 24: /* baseline */
+				*anchor = GO_ANCHOR_CENTER;
+				break;
+		}
+	}
+}
+
+static void
+go_wmf_set_align (GsfInput* input, GOWmfPage* pg, double* x, double* y)
+{
+	GOWmfDC *dc;
+
+	dc = &g_array_index (pg->dcs, GOWmfDC, pg->curdc);
+	if (dc->txtalign % 2) {
+		/* cpupdate */
+		/* FIXME: have to update pg->curx, pg->cury with layout size*/
+		*x = dc->curx;
+		*y = dc->cury;
+		gsf_input_seek (input, 4, G_SEEK_CUR);
+	} else {
+		go_wmf_read_point (input, y, x);
+		go_wmf_mr_convcoord (x, y, pg);
+	}
+}
+
+static void
+go_wmf_set_text (GOWmfPage* pg, GocCanvas* canvas, char* txt, int len, GOAnchorType* anchor, double* x, double* y)
+{
+	GocItem *gocitem;
+	char *utxt;
+	GOWmfMFobj *mfo;
+	GOWmfFont *font;
+	GOWmfDC *dc;
+
+	dc = &g_array_index (pg->dcs, GOWmfDC, pg->curdc);
+	txt[len] = 0;
+	if (-1 != dc->curfnt) {
+		mfo = g_hash_table_lookup (pg->mfobjs, GINT_TO_POINTER (dc->curfnt));
+		font = mfo->values;
+
+		if (!g_ascii_strcasecmp ("MT Extra", font->name)) {
+			utxt = go_wmf_mtextra_to_utf (txt);
+		} else if (!g_ascii_strcasecmp ("SYMBOL", font->name)) {
+			utxt = go_wmf_symbol_to_utf (txt);
+		} else {
+			utxt = g_convert (txt, len, "utf8", font->charset, NULL, NULL, NULL);
+		}
+
+	} else {
+		utxt = g_convert (txt, len, "utf8", "ASCII", NULL, NULL, NULL);
+	}
+	gocitem = goc_item_new (goc_canvas_get_root (canvas), GOC_TYPE_TEXT,
+					"x", *x, "y", *y, "text", utxt, "anchor", *anchor, NULL);
+	go_wmf_set_font (pg, gocitem);
+}
+
+static void
+go_wmf_read_color (GsfInput* input, GOWmfColor* clr)
+{
+	const guint8  *data = {0};
+
+	data = gsf_input_read (input, 1, NULL);
+	clr->r = *data;
+	data = gsf_input_read (input, 1, NULL);
+	clr->g = *data;
+	data = gsf_input_read (input, 1, NULL);
+	clr->b = *data;
+}
+
+static int
+go_wmf_find_obj (GOWmfPage* pg)
+{
+	int i = 0;
+
+	while (i <= pg->maxobj) {
+		if(NULL == g_hash_table_lookup (pg->mfobjs, GINT_TO_POINTER (i)))
+			break;
+		else
+			i++;
+	}
+	if (i == pg->maxobj)
+		pg->maxobj++;
+	return i;
+}
+
+/*
+ * MF: 0 - solid, 1 - dash, 2 - dot,  3 - dashdot,  4 - dashdotdot
+ * GO: 1 - solid, 8 - dash, 6 - dot, 10 - dashdot, 11 - dashdotdot
+  */
+
+/*
+MF2cairo: capjoin = {0:1,1:2,2:0}
+MF: cap = {0:'Flat',1:'Round',2:'Square'}
+MF: join = {0:'Miter',1:'Round',2:'Bevel'}
+*/
+
+static void
+go_wmf_stroke (GOWmfPage *pg, GocItem *item)
+{
+	GOWmfPen *p;
+	GOWmfMFobj *mfo;
+	GOStyle *style;
+	int dashes[5] = {1, 8, 6, 10, 11};
+	int capjoin[3] = {1, 2, 0};
+	int pstyle = 0;
+	GOWmfDC *dc;
+
+	dc = &g_array_index (pg->dcs, GOWmfDC, pg->curdc);
+	if (-1 == dc->curfg)
+		return;
+
+	style = go_styled_object_get_style (GO_STYLED_OBJECT (item));
+
+	mfo = g_hash_table_lookup (pg->mfobjs, GINT_TO_POINTER (dc->curfg));
+	p = mfo->values;
+	pstyle = p->style;
+	if (p->style == 5) {
+		style->line.dash_type = GO_LINE_NONE;
+		style->line.auto_dash = FALSE;
+	} else {
+		style->line.color = GO_COLOR_FROM_RGB (p->clr.r, p->clr.g, p->clr.b);
+		style->line.dash_type = GO_LINE_SOLID;
+		if (p->width > 1) {
+			style->line.width = (double) p->width * pg->zoom;
+		} else {
+			style->line.width = 0.;
+		}
+		if (3 > (pstyle & 0xF00) >> 8) {
+			style->line.cap = capjoin[(pstyle & 0xF00) >> 8];
+		}
+		if (3 > (pstyle & 0xF000) >> 12) {
+			style->line.join = capjoin[(pstyle & 0xF000) >> 12];
+		}
+
+		if (pstyle > 5)
+			pstyle = 0;
+		style->line.dash_type = dashes[pstyle];
+		if (1 == dc->bkmode) {
+			style->line.fore = GO_COLOR_FROM_RGBA (0, 0, 0, 0);
+		} else {
+			style->line.color = GO_COLOR_FROM_RGB (p->clr.r, p->clr.g, p->clr.b);
+		}
+	}
+}
+
+/*
+ * MF: 0 HS_HORIZONTAL, 1 HS_VERTICAL, 2 HS_FDIAGONAL, 3 HS_BDIAGONAL, 4 HS_CROSS, 5 HS_DIAGCROSS
+ * GO: 12	       13	       14	       15	       16	       17
+ */
+static void
+go_wmf_fill (GOWmfPage *pg, GocItem *item)
+{
+	GOWmfBrush *b;
+	GOWmfMFobj *mfo;
+	GOStyle *style;
+	GOWmfDC *dc;
+
+	dc = &g_array_index (pg->dcs, GOWmfDC, pg->curdc);
+	if (-1 == dc->curbg)
+		return;
+
+	style = go_styled_object_get_style (GO_STYLED_OBJECT (item));
+	mfo = g_hash_table_lookup (pg->mfobjs, GINT_TO_POINTER (dc->curbg));
+	b = mfo->values;
+	switch (b->style) {
+	case 1:
+		style->fill.type = GO_STYLE_FILL_NONE;
+		break;
+	case 2:
+		style->fill.pattern.pattern = b->hatch + 12;
+		if (1 == dc->bkmode) {
+			style->fill.pattern.back = GO_COLOR_FROM_RGBA (0, 0, 0, 0);
+		} else {
+			style->fill.pattern.back = GO_COLOR_FROM_RGB (dc->bkclr.r, dc->bkclr.g, dc->bkclr.b);
+		}
+		style->fill.type = GO_STYLE_FILL_PATTERN;
+		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 (go_pixbuf_new_from_pixbuf (b->bdata.data));
+		style->fill.image.type = GO_IMAGE_WALLPAPER;
+		style->fill.type = GO_STYLE_FILL_IMAGE;
+		break;
+	default:
+		style->fill.type = GO_STYLE_FILL_PATTERN;
+		style->fill.pattern.back = GO_COLOR_FROM_RGB (b->clr.r, b->clr.g, b->clr.b);
+	}
+}
+
+
+static void
+go_wmf_mr0 (GsfInput* input, guint rsize, GOWmfPage* pg, GHashTable* objs, GocCanvas *canvas)
 {
-	/* FIXME: implement */
+	d_ (("!EOF\n"));
+}
+
+/* -------------- SaveDC ---------------- */
+static void
+go_wmf_mr1 (GsfInput* input, guint rsize, GOWmfPage* pg, GHashTable* objs, GocCanvas *canvas)
+{
+	GOWmfDC mydc;
+
+	d_ (("SaveDC\n"));
+	mydc = g_array_index (pg->dcs, GOWmfDC, pg->curdc);
+	g_array_append_vals (pg->dcs, &mydc, 1);
+	pg->curdc = pg->dcs->len - 1;
+}
+
+static void
+go_wmf_mr2 (GsfInput* input, guint rsize, GOWmfPage* pg, GHashTable* objs, GocCanvas *canvas)
+{
+	d_ (("RealizePalette: unimplemeted\n"));
+}
+
+static void
+go_wmf_mr3 (GsfInput* input, guint rsize, GOWmfPage* pg, GHashTable* objs, GocCanvas *canvas)
+{
+	d_ (("SetPalEntries: unimplemented\n"));
+}
+
+/* ------------- CreatePalette ------------ */
+static void
+go_wmf_mr4 (GsfInput* input, guint rsize, GOWmfPage* pg, GHashTable* objs, GocCanvas *canvas)
+{
+	/* FIXME: do actual parsing */
+	GOWmfMFobj *mf;
+
+	d_ (("CreatePalette\n"));
+	mf = malloc (sizeof (GOWmfMFobj));
+	mf->type = 5;
+	g_hash_table_insert ((*pg).mfobjs, GINT_TO_POINTER (go_wmf_find_obj (pg)), mf);
+}
+
+/* ------------- SetBKMode ----------------- */
+static void
+go_wmf_mr5 (GsfInput* input, guint rsize, GOWmfPage* pg, GHashTable* objs, GocCanvas *canvas)
+{
+	const guint8  *data = {0};
+	GOWmfDC *dc;
+
+	d_ (("SetBkMode\n"));
+	dc = &g_array_index (pg->dcs, GOWmfDC, pg->curdc);
+	data = gsf_input_read (input, 2, NULL);
+	dc->bkmode = GSF_LE_GET_GUINT16 (data);
+	gsf_input_seek (input, -2, G_SEEK_CUR);
+}
+
+static void
+go_wmf_mr6 (GsfInput* input, guint rsize, GOWmfPage* pg, GHashTable* objs, GocCanvas *canvas)
+{
+	d_ (("SetMapMode: unimplemeted\n"));
+}
+
+static void
+go_wmf_mr7 (GsfInput* input, guint rsize, GOWmfPage* pg, GHashTable* objs, GocCanvas *canvas)
+{
+/*	g_print("SetROP2 "));*/
+}
+
+/* ------------- SetReLabs ------------- */
+static void
+go_wmf_mr8 (GsfInput* input, guint rsize, GOWmfPage* pg, GHashTable* objs, GocCanvas *canvas)
+{
+	/* FIXME: Exclude, should never be used */
+}
+
+/* ----------------- SetPolyfillMode ----------------- */
+static void
+go_wmf_mr9 (GsfInput* input, guint rsize, GOWmfPage* pg, GHashTable* objs, GocCanvas *canvas)
+{
+	const guint8  *data = {0};
+	GOWmfDC *dc;
+
+	dc = &g_array_index (pg->dcs, GOWmfDC, pg->curdc);
+	data = gsf_input_read (input, 2, NULL);
+	if (GSF_LE_GET_GUINT16 (data) > 1)
+		dc->pfm = 0;
+	else
+		dc->pfm = 1;
+	gsf_input_seek (input, -2, G_SEEK_CUR);
+}
+
+static void
+go_wmf_mr10 (GsfInput* input, guint rsize, GOWmfPage* pg, GHashTable* objs, GocCanvas *canvas)
+{
+/*	g_print("SetStrechBLTMode "));*/
+}
+
+static void
+go_wmf_mr11 (GsfInput* input, guint rsize, GOWmfPage* pg, GHashTable* objs, GocCanvas *canvas)
+{
+/*	g_print("SetTextCharExtra "));*/
+}
+
+/* ---------------- RestoreDC ----------------------- */
+static void
+go_wmf_mr12 (GsfInput* input, guint rsize, GOWmfPage* pg, GHashTable* objs, GocCanvas *canvas)
+{
+	const guint8  *data = {0};
+	gint16 idx;
+
+	data = gsf_input_read (input, 2, NULL);
+	idx = GSF_LE_GET_GINT16 (data);
+	if (idx > 0)
+		pg->curdc = idx;
+	else
+		pg->curdc -= idx;
+	gsf_input_seek (input, -2, G_SEEK_CUR);
+}
+
+static void
+go_wmf_mr13 (GsfInput* input, guint rsize, GOWmfPage* pg, GHashTable* objs, GocCanvas *canvas)
+{
+/*	g_print("InvertRegion "));*/
+}
+
+static void
+go_wmf_mr14 (GsfInput* input, guint rsize, GOWmfPage* pg, GHashTable* objs, GocCanvas *canvas)
+{
+/*	g_print("PaintRegion "));*/
+}
+
+static void
+go_wmf_mr15 (GsfInput* input, guint rsize, GOWmfPage* pg, GHashTable* objs, GocCanvas *canvas)
+{
+/*	g_print("SelectClipRegion "));*/
+}
+
+/* -------------------- Select Object ----------------- */
+static void
+go_wmf_mr16 (GsfInput* input, guint rsize, GOWmfPage* pg, GHashTable* objs, GocCanvas* canvas)
+{
+	const guint8  *data = {0};
+	int idx;
+	GOWmfMFobj *mf;
+	GOWmfDC *dc;
+
+	dc = &g_array_index (pg->dcs, GOWmfDC, pg->curdc);
+	data = gsf_input_read (input, 2, NULL);
+	idx = GSF_LE_GET_GUINT16 (data);
+
+	mf = g_hash_table_lookup (pg->mfobjs, GINT_TO_POINTER (idx));
+	switch (mf->type) {
+	case 1:
+		dc->curfg = idx; /* pen */
+		break;
+	case 2:
+		dc->curbg = idx; /* brush */
+		break;
+	case 3:
+		dc->curfnt = idx; /* font */
+		break;
+	case 4:
+		dc->curreg = idx; /* region */
+		break;
+	case 5:
+		/* palette, shouldn't happen "SelectPalette" have to be used to select palette */
+		break;
+	default:
+		break;
+	}
+	gsf_input_seek (input, -2, G_SEEK_CUR);
+}
+
+/* ---------------- SetTextAlign ----------------------- */
+static void
+go_wmf_mr17 (GsfInput* input, guint rsize, GOWmfPage* pg, GHashTable* objs, GocCanvas* canvas)
+{
+	const guint8  *data = {0};
+	GOWmfDC *dc;
+
+	dc = &g_array_index (pg->dcs, GOWmfDC, pg->curdc);
+	data = gsf_input_read (input, 2, NULL);
+	dc->txtalign = GSF_LE_GET_GUINT16 (data);
+	gsf_input_seek(input, -2, G_SEEK_CUR);
+}
+
+static void
+go_wmf_mr18 (GsfInput* input, guint rsize, GOWmfPage* pg, GHashTable* objs, GocCanvas* canvas)
+{
+/*	g_print("ResizePalette "));*/
+}
+
+/* --------------- DIBCreatePatternBrush -------------- */
+static void
+go_wmf_mr19 (GsfInput* input, guint rsize, GOWmfPage* pg, GHashTable* objs, GocCanvas* canvas)
+{
+	const guint8  *data = {0};
+	GOWmfBrush *brush;
+	GOWmfMFobj *mf;
+	guint32 w, h, bmpsize, bmpshift = 54;
+	guint16 biDepth;
+	GdkPixbufLoader *gpbloader = gdk_pixbuf_loader_new ();
+	GdkPixbuf *gpb;
+	GError **error = NULL;
+	guint8 *tmp;
+	gint32 rollback = 6 - rsize * 2;
+
+	brush = malloc (sizeof (GOWmfBrush));
+	brush->style = 3; /* DibPattern brush */
+	gsf_input_seek(input, 8, G_SEEK_CUR);
+	data = gsf_input_read (input, 4, NULL);
+	w = GSF_LE_GET_GUINT32 (data);
+	data = gsf_input_read (input, 4, NULL);
+	h = GSF_LE_GET_GUINT32 (data);
+	gsf_input_seek (input, 2, G_SEEK_CUR);
+	data = gsf_input_read (input, 2, NULL);
+	biDepth = GSF_LE_GET_GUINT32 (data);
+	gsf_input_seek(input, -16, G_SEEK_CUR);
+	data = gsf_input_read (input, rsize * 2 - 6 - 4, NULL);
+	bmpsize = rsize * 2 - 6 + 10;
+
+	gsf_input_seek (input, rollback, G_SEEK_CUR);
+	switch (biDepth) {
+	case 1:
+		bmpshift = 62;
+		break;
+	case 2:
+		bmpshift = 70;
+		break;
+	case 4:
+		bmpshift = 118;
+		break;
+	case 8:
+		bmpshift = 1078;
+		break;
+	}
+
+	tmp = malloc (bmpsize);
+	tmp[0] = 0x42;
+	tmp[1] = 0x4d;
+	memcpy(tmp + 2, &bmpsize, 4);
+	tmp[6] = 0;
+	tmp[7] = 0;
+	tmp[8] = 0;
+	tmp[9] = 0;
+	memcpy(tmp + 10, &bmpshift, 4);
+	memcpy(tmp + 14, data, bmpsize - 14);
+
+	gdk_pixbuf_loader_write (gpbloader, tmp, bmpsize, error);
+	gdk_pixbuf_loader_close (gpbloader, error);
+	gpb = gdk_pixbuf_loader_get_pixbuf (gpbloader);
+
+	brush->bdata.width = w;
+	brush->bdata.height = h;
+	brush->bdata.data = gpb;
+
+	mf = malloc (sizeof (GOWmfMFobj));
+	mf->type = 2;
+	mf->values = brush;
+	g_hash_table_insert ((*pg).mfobjs, GINT_TO_POINTER (go_wmf_find_obj (pg)), mf);
+
+}
+
+/* -------------- SetLayout -------------------- */
+static void
+go_wmf_mr20 (GsfInput* input, guint rsize, GOWmfPage* pg, GHashTable* objs, GocCanvas* canvas)
+{
+
+}
+
+/* -------------- DeleteObject -------------------- */
+static void
+go_wmf_mr21 (GsfInput* input, guint rsize, GOWmfPage* pg, GHashTable* objs, GocCanvas* canvas)
+{
+	const guint8  *data = {0};
+	int idx;
+
+	data = gsf_input_read (input, 2, NULL);
+	idx = GSF_LE_GET_GUINT16 (data);
+	g_hash_table_remove (pg->mfobjs, GINT_TO_POINTER (idx));
+	gsf_input_seek (input, -2, G_SEEK_CUR);
+}
+
+/*  -------------- CreatePatternBrush -------------------- */
+static void
+go_wmf_mr22 (GsfInput* input, guint rsize, GOWmfPage* pg, GHashTable* objs, GocCanvas* canvas)
+{
+	/* FIXME: add pixbufloader */
+	GOWmfMFobj *mf;
+
+	mf = malloc (sizeof (GOWmfMFobj));
+	mf->type = 2; /* brush */
+	g_hash_table_insert ((*pg).mfobjs, GINT_TO_POINTER (go_wmf_find_obj (pg)), mf);
+}
+
+/*  -------------- SetBKColor -------------------- */
+static void
+go_wmf_mr23 (GsfInput* input, guint rsize, GOWmfPage* pg, GHashTable* objs, GocCanvas* canvas)
+{
+	GOWmfDC *dc;
+
+	dc = &g_array_index (pg->dcs, GOWmfDC, pg->curdc);
+	go_wmf_read_color (input, &dc->bkclr);
+	gsf_input_seek (input, -3, G_SEEK_CUR);
+}
+
+/*  -------------- SetTextColor -------------------- */
+static void
+go_wmf_mr24 (GsfInput* input, guint rsize, GOWmfPage* pg, GHashTable* objs, GocCanvas* canvas)
+{
+	GOWmfDC *dc;
+
+	dc = &g_array_index (pg->dcs, GOWmfDC, pg->curdc);
+	go_wmf_read_color (input, &dc->txtclr);
+	gsf_input_seek (input, -3, G_SEEK_CUR);
+}
+
+static void
+go_wmf_mr25 (GsfInput* input, guint rsize, GOWmfPage* pg, GHashTable* objs, GocCanvas* canvas)
+{
+/*	g_print("SetTextJustification "));*/
+}
+
+/* ---------------- SetWindowOrg ----------------- */
+static void
+go_wmf_mr26 (GsfInput* input, guint rsize, GOWmfPage* pg, GHashTable* objs, GocCanvas* canvas)
+{
+	GOWmfDC *dc;
+
+	dc = &g_array_index (pg->dcs, GOWmfDC, pg->curdc);
+	go_wmf_read_point (input, &dc->y, &dc->x);
+	gsf_input_seek (input, -4, G_SEEK_CUR);
+}
+
+/*  ---------------- SetWindowExt ------------------- */
+static void
+go_wmf_mr27 (GsfInput* input, guint rsize, GOWmfPage* pg, GHashTable* objs, GocCanvas* canvas)
+{
+	GOWmfDC *dc;
+
+	dc = &g_array_index (pg->dcs, GOWmfDC, pg->curdc);
+	go_wmf_read_point (input, &dc->Wy, &dc->Wx);
+	gsf_input_seek (input, -4, G_SEEK_CUR);
+	if (2 == pg->type) {
+		if(pg->w*dc->Wy / dc->Wx > pg->h) {
+			dc->VPy = pg->h;
+			dc->VPx = pg->h * dc->Wx / dc->Wy;
+		} else {
+			dc->VPx = pg->w;
+			dc->VPy = pg->w * dc->Wy / dc->Wx;
+		}
+		pg->zoom = dc->VPx / dc->Wx;
+	}
+}
+
+/*  ----------------- SetViewportOrg ------------------- */
+static void
+go_wmf_mr28 (GsfInput* input, guint rsize, GOWmfPage* pg, GHashTable* objs, GocCanvas* canvas)
+{
+	GOWmfDC *dc;
+
+	dc = &g_array_index (pg->dcs, GOWmfDC, pg->curdc);
+	go_wmf_read_point (input, &dc->VPOy, &dc->VPOx);
+	gsf_input_seek (input, -4, G_SEEK_CUR);
+}
+
+/*  ----------------- SetViewportExt -------------------- */
+static void
+go_wmf_mr29 (GsfInput* input, guint rsize, GOWmfPage* pg, GHashTable* objs, GocCanvas* canvas)
+{
+	GOWmfDC *dc;
+
+	dc = &g_array_index (pg->dcs, GOWmfDC, pg->curdc);
+	go_wmf_read_point (input, &dc->VPy, &dc->VPx);
+	gsf_input_seek (input, -4, G_SEEK_CUR);
+}
+
+/* ------------------- OffsetWindowOrg ------------------ */
+static void
+go_wmf_mr30 (GsfInput* input, guint rsize, GOWmfPage* pg, GHashTable* objs, GocCanvas* canvas)
+{
+	GOWmfDC *dc;
+	double x,y;
+
+	dc = &g_array_index (pg->dcs, GOWmfDC, pg->curdc);
+	go_wmf_read_point (input, &x, &y);
+	dc->x += x;
+	dc->y += y;
+	gsf_input_seek (input, -4, G_SEEK_CUR);
+}
+
+/* ------------------- OffsetViewportOrg ---------------- */
+static void
+go_wmf_mr31 (GsfInput* input, guint rsize, GOWmfPage* pg, GHashTable* objs, GocCanvas* canvas)
+{
+	GOWmfDC *dc;
+	double x,y;
+
+	dc = &g_array_index (pg->dcs, GOWmfDC, pg->curdc);
+	go_wmf_read_point (input, &x, &y);
+	dc->VPx += x;
+	dc->VPy += y;
+	gsf_input_seek (input, -4, G_SEEK_CUR);
+}
+
+/*  ------------------ LineTo -------------------- */
+static void
+go_wmf_mr32 (GsfInput* input, guint rsize, GOWmfPage* pg, GHashTable* objs, GocCanvas* canvas)
+{
+	double x,y;
+	GocItem *gocitem;
+	GOWmfDC *dc;
+
+	dc = &g_array_index (pg->dcs, GOWmfDC, pg->curdc);
+	go_wmf_read_point (input, &y, &x);
+	gsf_input_seek (input, -4, G_SEEK_CUR);
+	go_wmf_mr_convcoord (&x, &y, pg);
+	gocitem = goc_item_new (goc_canvas_get_root (canvas), GOC_TYPE_LINE,
+		"x0", dc->curx, "y0", dc->cury, "x1", x, "y1", y, NULL);
+	dc->curx = x;
+	dc->cury = y;
+	go_wmf_stroke (pg, gocitem);
+}
+
+/*  ------------------ MoveTo -------------------- */
+static void
+go_wmf_mr33 (GsfInput* input, guint rsize, GOWmfPage* pg, GHashTable* objs, GocCanvas* canvas)
+{
+	double x,y;
+	GOWmfDC *dc;
+
+	dc = &g_array_index (pg->dcs, GOWmfDC, pg->curdc);
+	go_wmf_read_point (input, &y, &x);
+	gsf_input_seek (input, -4, G_SEEK_CUR);
+	go_wmf_mr_convcoord (&x, &y, pg);
+	dc->curx = x;
+	dc->cury = y;
+}
+
+static void
+go_wmf_mr34 (GsfInput* input, guint rsize, GOWmfPage* pg, GHashTable* objs, GocCanvas* canvas)
+{
+/*	g_print("OffsetClipRgn "));*/
+}
+
+static void
+go_wmf_mr35 (GsfInput* input, guint rsize, GOWmfPage* pg, GHashTable* objs, GocCanvas* canvas)
+{
+/*	g_print("FillRegion "));*/
+}
+
+static void
+go_wmf_mr36 (GsfInput* input, guint rsize, GOWmfPage* pg, GHashTable* objs, GocCanvas* canvas)
+{
+/*	g_print("SetMapperFlags "));*/
+}
+
+static void
+go_wmf_mr37 (GsfInput* input, guint rsize, GOWmfPage* pg, GHashTable* objs, GocCanvas* canvas)
+{
+/*	g_print("SelectPalette "));*/
+}
+
+/*  ------------------ CreatePenIndirect ------------------- */
+static void
+go_wmf_mr38 (GsfInput* input, guint rsize, GOWmfPage* pg, GHashTable* objs, GocCanvas* canvas)
+{
+	const guint8  *data = {0};
+	GOWmfPen *pen;
+	GOWmfMFobj *mf;
+
+	pen = malloc (sizeof (GOWmfPen));
+	data = gsf_input_read (input, 2, NULL);
+	pen->style = GSF_LE_GET_GUINT16 (data);
+	data = gsf_input_read (input, 2, NULL);
+	pen->width = GSF_LE_GET_GINT16 (data);
+	gsf_input_seek (input, 2, G_SEEK_CUR); /* skip "height" */
+	go_wmf_read_color (input, &pen->clr);
+	gsf_input_seek (input, 1, G_SEEK_CUR);
+	data = gsf_input_read (input, 2, NULL);
+	pen->flag = GSF_LE_GET_GUINT16 (data);
+	gsf_input_seek (input, -12, G_SEEK_CUR);
+	mf = malloc (sizeof (GOWmfMFobj));
+	mf->type = 1;
+	mf->values = pen;
+	g_hash_table_insert ((*pg).mfobjs, GINT_TO_POINTER (go_wmf_find_obj (pg)), mf);
+}
+
+
+/* ----------------- CreateFontIndirect ------------- */
+static void
+go_wmf_mr39 (GsfInput* input, guint rsize, GOWmfPage* pg, GHashTable* objs, GocCanvas* canvas)
+{
+	const guint8  *data = {0};
+	GOWmfFont *font;
+	GOWmfMFobj *mf;
+	int i = 0;
+
+	font = malloc (sizeof (GOWmfFont));
+	data = gsf_input_read (input, 2, NULL);
+	font->size = GSF_LE_GET_GINT16 (data);
+	gsf_input_seek (input, 2, G_SEEK_CUR); /* skip 'width' */
+	data = gsf_input_read (input, 2, NULL);
+	font->escape = GSF_LE_GET_GINT16 (data);
+	data = gsf_input_read (input, 2, NULL);
+	font->orient = GSF_LE_GET_GINT16 (data);
+	data = gsf_input_read (input, 2, NULL);
+	font->weight = GSF_LE_GET_GINT16 (data);
+	data = gsf_input_read (input, 1, NULL);
+	font->italic = GSF_LE_GET_GUINT8 (data);
+	data = gsf_input_read (input, 1, NULL);
+	font->under = GSF_LE_GET_GUINT8 (data);
+	data = gsf_input_read (input, 1, NULL);
+	font->strike = GSF_LE_GET_GUINT8 (data);
+	data = gsf_input_read (input, 1, NULL);
+/*
+77:'MAC_CHARSET',
+*/
+	switch (GSF_LE_GET_GUINT8(data)) {
+	case 0:
+	case 1:
+		font->charset = g_strdup ("iso8859-1");
+		break;
+	case 2:
+		font->charset = g_strdup ("Symbol");
+		break;
+	case 128:
+		font->charset = g_strdup ("Shift_JIS");
+		break;
+	case 129:
+		font->charset = g_strdup ("cp949");
+		break;
+	case 134:
+		font->charset = g_strdup ("gb2312");
+		break;
+	case 136:
+		font->charset = g_strdup ("Big5");
+		break;
+	case 161:
+		font->charset = g_strdup ("cp1253");
+		break;
+	case 162:
+		font->charset = g_strdup ("cp1254");
+		break;
+	case 163:
+		font->charset = g_strdup ("cp1258");
+		break;
+	case 177:
+		font->charset = g_strdup ("cp1255");
+		break;
+	case 178:
+		font->charset = g_strdup ("cp1256");
+		break;
+	case 186:
+		font->charset = g_strdup ("cp1257");
+		break;
+	case 204:
+		font->charset = g_strdup ("cp1251");
+		break;
+	case 222:
+		font->charset = g_strdup ("cp874");
+		break;
+	case 238:
+		font->charset = g_strdup ("cp1250");
+		break;
+	case 255:
+		font->charset = g_strdup ("cp437");
+		break;
+	default:
+		font->charset = g_strdup ("cp437");
+	}
+
+	gsf_input_seek (input, 4, G_SEEK_CUR);
+	data = gsf_input_read (input, 1, NULL);
+	while (0 != data[0] && (guint) i < rsize * 2 - 6) {
+		i++;
+		data = gsf_input_read (input, 1, NULL);
+	}
+	gsf_input_seek (input, -i - 1, G_SEEK_CUR);
+	font->name = malloc (i + 1);
+	gsf_input_read (input, i + 1, font->name);
+	gsf_input_seek (input, -19 - i, G_SEEK_CUR);
+	mf = malloc (sizeof (GOWmfMFobj));
+	mf->type = 3;
+	mf->values = font;
+	g_hash_table_insert ((*pg).mfobjs, GINT_TO_POINTER (go_wmf_find_obj (pg)), mf);
+}
+
+/* ---------------- CreateBrushIndirect --------------- */
+static void
+go_wmf_mr40 (GsfInput* input, guint rsize, GOWmfPage* pg, GHashTable* objs, GocCanvas* canvas)
+{
+	const guint8 *data = {0};
+	GOWmfBrush *brush;
+	GOWmfMFobj *mf;
+
+	brush = malloc (sizeof (GOWmfBrush));
+	data = gsf_input_read (input, 2, NULL);
+	brush->style = GSF_LE_GET_GUINT16 (data);
+	go_wmf_read_color (input, &brush->clr);
+	gsf_input_seek (input, 1, G_SEEK_CUR); /* skip "clr.a" */
+	data = gsf_input_read (input, 2, NULL);
+	brush->hatch = GSF_LE_GET_GUINT16 (data);
+	gsf_input_seek (input, -8, G_SEEK_CUR);
+	mf = malloc (sizeof (GOWmfMFobj));
+	mf->type = 2;
+	mf->values = brush;
+	g_hash_table_insert ((*pg). mfobjs, GINT_TO_POINTER (go_wmf_find_obj (pg)), mf);
+}
+
+static void
+go_wmf_mr_poly (GsfInput* input, GOWmfPage* pg, GocCanvas* canvas, int type)
+{
+	const guint8  *data = {0};
+	double len;
+	guint i;
+	GocItem *gocitem;
+	GocPoints *points;
+	GOWmfDC *dc;
+
+	dc = &g_array_index (pg->dcs, GOWmfDC, pg->curdc);
+	data = gsf_input_read (input, 2, NULL);
+	len = GSF_LE_GET_GINT16 (data);
+	points = goc_points_new (len);
+	for (i = 0; i < len; i++) {
+		go_wmf_read_point (input, &points->points[i].x, &points->points[i].y);
+		go_wmf_mr_convcoord (&points->points[i].x, &points->points[i].y, pg);
+	}
+
+	if (0 == type)
+		gocitem = goc_item_new (goc_canvas_get_root (canvas), GOC_TYPE_POLYGON, "points", points, "fill-rule", dc->pfm, NULL);
+	else
+		gocitem = goc_item_new (goc_canvas_get_root (canvas), GOC_TYPE_POLYLINE, "points", points, NULL);
+	go_wmf_fill (pg,gocitem);
+	go_wmf_stroke (pg,gocitem);
+	gsf_input_seek (input, -len * 4 - 2, G_SEEK_CUR);
+}
+
+/*  ---------- Polygon ---------------- */
+static void
+go_wmf_mr41 (GsfInput* input, guint rsize, GOWmfPage* pg, GHashTable* objs, GocCanvas* canvas)
+{
+	go_wmf_mr_poly (input, pg, canvas, 0);
+}
+
+/*  ---------- Polyline ---------------- */
+static void
+go_wmf_mr42 (GsfInput* input, guint rsize, GOWmfPage* pg, GHashTable* objs, GocCanvas* canvas)
+{
+	go_wmf_mr_poly (input, pg, canvas, 1);
+}
+
+static void
+go_wmf_mr43 (GsfInput* input, guint rsize, GOWmfPage* pg, GHashTable* objs, GocCanvas* canvas)
+{
+/*	g_print("ScaleWindowExtEx "));*/
+}
+
+static void
+go_wmf_mr44 (GsfInput* input, guint rsize, GOWmfPage* pg, GHashTable* objs, GocCanvas* canvas)
+{
+/*	g_print("ScaleViewportExt "));*/
+}
+
+static void
+go_wmf_mr45 (GsfInput* input, guint rsize, GOWmfPage* pg, GHashTable* objs, GocCanvas* canvas)
+{
+/*	g_print("ExcludeClipRect "));*/
+}
+
+static void
+go_wmf_mr46 (GsfInput* input, guint rsize, GOWmfPage* pg, GHashTable* objs, GocCanvas* canvas)
+{
+/*	g_print("IntersectClipRect "));*/
+}
+
+static void
+go_wmf_mr_rect (GsfInput* input, GOWmfPage* pg, GocCanvas* canvas, int type)
+{
+	double x1, x2, y1, y2, tx, ty, rx = 0, ry = 0;
+	GocItem *gocitem;
+
+	if (15 == type) {
+		go_wmf_read_point (input, &ry, &rx);
+		ry = abs (ry / 2);
+		rx = abs (rx / 2);
+		go_wmf_mr_convcoord (&rx, &ry, pg);
+	}
+	go_wmf_read_point (input, &y2, &x2);
+	go_wmf_read_point (input, &y1, &x1);
+	go_wmf_mr_convcoord (&x1, &y1, pg);
+	go_wmf_mr_convcoord (&x2, &y2, pg);
+
+	tx = x2 - x1;
+	if (x1 > x2) {
+		tx = x1;	x1 = x2;	tx -= x1;
+	}
+	ty = y2 - y1;
+	if (y1 > y2 ) {
+		ty = y1; y1 = y2; ty -= y1;
+	}
+
+	if (1 == type)
+		gocitem = goc_item_new (goc_canvas_get_root (canvas), GOC_TYPE_ELLIPSE,
+			"height", (double) ty, "x", (double) x1, "y", (double) y1, "width", (double) tx, NULL);
+	else
+		gocitem = goc_item_new (goc_canvas_get_root (canvas), GOC_TYPE_RECTANGLE,
+			"height", (double) ty, "x", (double) x1, "y", (double) y1, "width",
+			(double) tx, "rx", (double) rx, "ry", (double) ry, "type", type, NULL);
+	go_wmf_fill (pg, gocitem);
+	go_wmf_stroke (pg, gocitem);
+	gsf_input_seek (input, -8, G_SEEK_CUR);
+}
+
+/* ----------------- Ellipse --------------- */
+static void
+go_wmf_mr47 (GsfInput* input, guint rsize, GOWmfPage* pg, GHashTable* objs, GocCanvas* canvas)
+{
+	go_wmf_mr_rect (input, pg, canvas, 1);
+}
+
+static void
+go_wmf_mr48 (GsfInput* input, guint rsize, GOWmfPage* pg, GHashTable* objs, GocCanvas* canvas)
+{
+/*	g_print("FloodFill "));*/
+}
+
+/*  ---------------- Rectangle -------------- */
+static void
+go_wmf_mr49 (GsfInput* input, guint rsize, GOWmfPage* pg, GHashTable* objs, GocCanvas* canvas)
+{
+	go_wmf_mr_rect (input, pg, canvas, 0);
+}
+
+static void
+go_wmf_mr50 (GsfInput* input, guint rsize, GOWmfPage* pg, GHashTable* objs, GocCanvas* canvas)
+{
+/*	g_print("SetPixel "));*/
+}
+
+static void
+go_wmf_mr51 (GsfInput* input, guint rsize, GOWmfPage* pg, GHashTable* objs, GocCanvas* canvas)
+{
+/*	g_print("FrameRegion "));*/
+}
+
+static void
+go_wmf_mr52 (GsfInput* input, guint rsize, GOWmfPage* pg, GHashTable* objs, GocCanvas* canvas)
+{
+/*	g_print("AnimatePalette "));*/
+}
+
+/*---------------- TextOut -------------------- */
+static void
+go_wmf_mr53 (GsfInput* input, guint rsize, GOWmfPage* pg, GHashTable* objs, GocCanvas* canvas)
+{
+	const guint8  *data = {0};
+	char *txt;
+	double x, y;
+	int len, shift = 0;
+	GOAnchorType anchor = GO_ANCHOR_NORTH_WEST;
+
+	go_wmf_set_anchor (pg, &anchor);
+	data = gsf_input_read (input, 2, NULL);
+	len = GSF_LE_GET_GINT16 (data);
+	txt = malloc (sizeof (char) * len + 1);
+	gsf_input_read (input, len, txt);
+	if (len % 2) {
+		gsf_input_seek (input, 1, G_SEEK_CUR);
+		shift = 1;
+	}
+	go_wmf_set_align (input, pg, &x, &y);
+	gsf_input_seek (input, -6 - len - shift, G_SEEK_CUR);
+	go_wmf_set_text (pg, canvas, txt, len, &anchor, &x, &y);
+}
+
+/*  ------------ PolyPolygon ------------ */
+static void
+go_wmf_mr54 (GsfInput* input, guint rsize, GOWmfPage* pg, GHashTable* objs, GocCanvas* canvas)
+{
+	const guint8  *data = {0};
+	double x, y;
+	int npoly, len, curpos, sumlen = 0;
+	int i, j;
+	GocItem *gocitem;
+	GocIntArray *array;
+	GocPoints *points;
+	GOWmfDC *dc;
+
+	dc = &g_array_index (pg->dcs, GOWmfDC, pg->curdc);
+	data = gsf_input_read (input, 2, NULL);
+	npoly = GSF_LE_GET_GINT16 (data);
+	curpos = gsf_input_tell (input);
+	array = goc_int_array_new (npoly);
+
+	for (j = 0; j < npoly; j++) {
+		gsf_input_seek (input, curpos + j * 2, G_SEEK_SET);
+		data = gsf_input_read (input, 2, NULL);
+		len = GSF_LE_GET_GINT16 (data);
+		array->vals[j] = len;
+		sumlen += len;
+	}
+	points = goc_points_new (sumlen);
+
+	for ( i = 0; i < sumlen; i++) {
+			go_wmf_read_point (input, &x, &y);
+			go_wmf_mr_convcoord (&x, &y, pg);
+			points->points[i].x = x;
+			points->points[i].y = y;
+	}
+
+	gocitem = goc_item_new (goc_canvas_get_root (canvas), GOC_TYPE_POLYGON,
+		"points", points, "sizes", array, "fill-rule", dc->pfm, NULL);
+	go_wmf_fill (pg, gocitem);
+	go_wmf_stroke (pg, gocitem);
+	gsf_input_seek (input, curpos - 2, G_SEEK_SET);
+}
+
+static void
+go_wmf_mr55 (GsfInput* input, guint rsize, GOWmfPage* pg, GHashTable* objs, GocCanvas* canvas)
+{
+/*	g_print("ExtFloodFill "));*/
+}
+
+/*  ---------------- RoundRect ---------------------- */
+static void
+go_wmf_mr56 (GsfInput* input, guint rsize, GOWmfPage* pg, GHashTable* objs, GocCanvas* canvas)
+{
+	go_wmf_mr_rect (input, pg, canvas, 15);
+	gsf_input_seek (input, -4, G_SEEK_CUR);
+}
+
+static void
+go_wmf_mr57 (GsfInput* input, guint rsize, GOWmfPage* pg, GHashTable* objs, GocCanvas* canvas)
+{
+/*	g_print("PatBLT "));*/
+}
+
+/* ------------------ Escape ------------------------ */
+static void
+go_wmf_mr58 (GsfInput* input, guint rsize, GOWmfPage* pg, GHashTable* objs, GocCanvas* canvas)
+{
+
+}
+
+/* ------------------ CreateRegion ------------------ */
+static void
+go_wmf_mr59 (GsfInput* input, guint rsize, GOWmfPage* pg, GHashTable* objs, GocCanvas* canvas)
+{
+	/* FIXME: do actual parsing */
+	GOWmfMFobj *mf;
+
+	mf = malloc (sizeof (GOWmfMFobj));
+	mf->type = 4;
+	g_hash_table_insert ((*pg).mfobjs, GINT_TO_POINTER (go_wmf_find_obj (pg)), mf);
+}
+
+static void
+go_wmf_mr_arc (GsfInput* input, GOWmfPage* pg, GocCanvas* canvas, int type)
+{
+	GOWmfArc *arc;
+	GocItem *gocitem;
+	double a1, a2, xc, yc, rx, ry;
+
+	arc = malloc (sizeof (GOWmfArc));
+	go_wmf_read_point (input, &arc->ye, &arc->xe);
+	go_wmf_read_point (input, &arc->ys, &arc->xs);
+	go_wmf_read_point (input, &arc->b, &arc->r);
+	go_wmf_read_point (input, &arc->t, &arc->l);
+	gsf_input_seek (input, -16, G_SEEK_CUR);
+	go_wmf_mr_convcoord (&arc->xe, &arc->ye, pg);
+	go_wmf_mr_convcoord (&arc->xs, &arc->ys, pg);
+	go_wmf_mr_convcoord (&arc->r, &arc->b, pg);
+	go_wmf_mr_convcoord (&arc->l, &arc->t, pg);
+
+	xc = (arc->l + arc->r) * 0.5;
+	yc = (arc->b + arc->t) * 0.5;
+	rx = abs ((arc->l - arc->r) * 0.5);
+	ry = abs ((arc->b - arc->t) * 0.5);
+	a2 = atan2 (arc->xs - xc, arc->ys - yc);
+	a1 = atan2 (xc - arc->xe, yc - arc->ye);
+	arc->xs = xc;
+	arc->ys = yc;
+	arc->r = rx;
+	arc->t = ry;
+	arc->l = a1;
+	arc->b = a2;
+	gocitem = goc_item_new (goc_canvas_get_root (canvas), GOC_TYPE_ARC,
+	 "xc", arc->xs, "yc", arc->ys, "xr",arc->r, "yr", arc->t,
+	 "ang1",arc->l, "ang2", arc->b,"type", type, NULL);
+	go_wmf_stroke (pg, gocitem);
+	if (type > 0)
+		go_wmf_fill (pg, gocitem);
+}
+
+/*  ---------------- Arc ---------------- */
+static void
+go_wmf_mr60 (GsfInput* input, guint rsize, GOWmfPage* pg, GHashTable* objs, GocCanvas* canvas)
+{
+	go_wmf_mr_arc (input, pg, canvas, 0);
+}
+
+/*  ----------------- Pie ----------------- */
+static void
+go_wmf_mr61 (GsfInput* input, guint rsize, GOWmfPage* pg, GHashTable* objs, GocCanvas* canvas)
+{
+	go_wmf_mr_arc (input, pg, canvas, 2);
+}
+
+/*  ---------------- Chord ------------------ */
+static void
+go_wmf_mr62 (GsfInput* input, guint rsize, GOWmfPage* pg, GHashTable* objs, GocCanvas* canvas)
+{
+	go_wmf_mr_arc (input, pg, canvas, 1);
+}
+
+static void
+go_wmf_mr63 (GsfInput* input, guint rsize, GOWmfPage* pg, GHashTable* objs, GocCanvas* canvas)
+{
+/*	g_print("BitBLT "));*/
+}
+
+static void
+go_wmf_mr64 (GsfInput* input, guint rsize, GOWmfPage* pg, GHashTable* objs, GocCanvas* canvas)
+{
+/*	g_print("DIBBitBLT "));*/
+}
+
+/* ----------------- ExtTextOut ---------------- */
+static void
+go_wmf_mr65 (GsfInput* input, guint rsize, GOWmfPage* pg, GHashTable* objs, GocCanvas* canvas)
+{
+	const guint8  *data = {0};
+	char *txt;
+	double x, y;
+	int len/*, flag*/;
+	GOAnchorType anchor = GO_ANCHOR_SOUTH_WEST;
+
+	go_wmf_set_anchor (pg, &anchor);
+	go_wmf_set_align (input, pg, &x, &y);
+	data = gsf_input_read (input, 2, NULL);
+	len = GSF_LE_GET_GINT16 (data);
+	data = gsf_input_read (input, 2, NULL);
+	/*flag = GSF_LE_GET_GINT16 (data);*/
+	txt = malloc (sizeof (char) * len + 1);
+	gsf_input_read (input, len, txt);
+	gsf_input_seek (input, -8 - len, G_SEEK_CUR);
+	go_wmf_set_text (pg, canvas, txt, len, &anchor, &x, &y);
+}
+
+static void
+go_wmf_mr66 (GsfInput* input, guint rsize, GOWmfPage* pg, GHashTable* objs, GocCanvas* canvas)
+{
+/*	g_print("StretchBlt "));*/
+}
+
+/* ----------------- DIBStretchBlt ----------------------- */
+static void
+go_wmf_mr67 (GsfInput* input, guint rsize, GOWmfPage* pg, GHashTable* objs, GocCanvas* canvas)
+{
+/*	g_print("DIBStretchBlt "));*/
+}
+
+static void
+go_wmf_mr68 (GsfInput* input, guint rsize, GOWmfPage* pg, GHashTable* objs, GocCanvas* canvas)
+{
+/*	g_print("SetDIBtoDEV "));*/
+}
+
+/* ---------------- StretchDIB -------------------- */
+static void
+go_wmf_mr69 (GsfInput* input, guint rsize, GOWmfPage* pg, GHashTable* objs, GocCanvas* canvas)
+{
+	const guint8  *data = {0};
+	double x, y, xe, ye, w, h;
+	guint32 bmpsize, bmpshift = 54/*, dwROP*/;
+	guint16 biDepth;
+	GdkPixbufLoader *gpbloader = gdk_pixbuf_loader_new ();
+	GdkPixbuf *gpb;
+	GError **error = NULL;
+	guint8 *tmp;
+	gint32 rollback = 6 - rsize * 2;
+
+	data = gsf_input_read (input, 4, NULL);
+	/*dwROP = GSF_LE_GET_GUINT32 (data);*/
+	gsf_input_seek(input, 10, G_SEEK_CUR); /* src x,y,w,h */
+	go_wmf_read_point (input, &h, &w);
+	go_wmf_read_point (input, &y, &x);
+	gsf_input_seek(input, 14, G_SEEK_CUR);
+	data = gsf_input_read (input, 2, NULL);
+	biDepth = GSF_LE_GET_GUINT32 (data);
+	gsf_input_seek(input, -16, G_SEEK_CUR);
+	data = gsf_input_read (input, rsize * 2 - 6 - 22, NULL);
+	bmpsize = rsize * 2 - 6 - 12;
+
+	gsf_input_seek (input, rollback, G_SEEK_CUR);
+
+	switch (biDepth) {
+	case 1:
+		bmpshift = 62;
+		break;
+	case 2:
+		bmpshift = 70;
+		break;
+	case 4:
+		bmpshift = 118;
+		break;
+	case 8:
+		bmpshift = 1078;
+		break;
+	}
+
+	tmp = malloc (bmpsize);
+	tmp[0] = 0x42;
+	tmp[1] = 0x4d;
+	memcpy (tmp + 2, &bmpsize, 4);
+	tmp[6] = 0;
+	tmp[7] = 0;
+	tmp[8] = 0;
+	tmp[9] = 0;
+	memcpy (tmp + 10, &bmpshift, 4);
+	memcpy (tmp + 14, data, bmpsize - 14);
+
+	gdk_pixbuf_loader_write (gpbloader, tmp, bmpsize, error);
+	gdk_pixbuf_loader_close (gpbloader, error);
+	gpb = gdk_pixbuf_loader_get_pixbuf (gpbloader);
+
+	xe = w - x;
+	ye = h -y;
+	go_wmf_mr_convcoord (&x, &y, pg);
+	go_wmf_mr_convcoord (&xe, &ye, pg);
+	w = xe - x;
+	h = ye - y;
+
+	goc_item_new (goc_canvas_get_root (canvas), GOC_TYPE_PIXBUF,
+	 "height", (double) h, "x", (double) x, "y", (double) y, "width",(double) w, "pixbuf", gpb, NULL);
+}
+
+typedef void
+(*GOWmfHandler) (GsfInput* input, guint rsize, GOWmfPage* pg, GHashTable* objs, GocCanvas* canvas);
+
+static GOWmfHandler go_wmf_mfrec_dump[70] =
+{
+	go_wmf_mr0, go_wmf_mr1, go_wmf_mr2, go_wmf_mr3, go_wmf_mr4,
+	go_wmf_mr5, go_wmf_mr6, go_wmf_mr7, go_wmf_mr8, go_wmf_mr9,
+	go_wmf_mr10, go_wmf_mr11, go_wmf_mr12, go_wmf_mr13, go_wmf_mr14,
+	go_wmf_mr15, go_wmf_mr16, go_wmf_mr17, go_wmf_mr18, go_wmf_mr19,
+	go_wmf_mr20, go_wmf_mr21, go_wmf_mr22, go_wmf_mr23, go_wmf_mr24,
+	go_wmf_mr25, go_wmf_mr26, go_wmf_mr27, go_wmf_mr28, go_wmf_mr29,
+	go_wmf_mr30, go_wmf_mr31, go_wmf_mr32, go_wmf_mr33, go_wmf_mr34,
+	go_wmf_mr35, go_wmf_mr36, go_wmf_mr37, go_wmf_mr38, go_wmf_mr39,
+	go_wmf_mr40, go_wmf_mr41, go_wmf_mr42, go_wmf_mr43, go_wmf_mr44,
+	go_wmf_mr45, go_wmf_mr46, go_wmf_mr47, go_wmf_mr48, go_wmf_mr49,
+	go_wmf_mr50, go_wmf_mr51, go_wmf_mr52, go_wmf_mr53, go_wmf_mr54,
+	go_wmf_mr55, go_wmf_mr56, go_wmf_mr57, go_wmf_mr58, go_wmf_mr59,
+	go_wmf_mr60, go_wmf_mr61, go_wmf_mr62, go_wmf_mr63, go_wmf_mr64,
+	go_wmf_mr65, go_wmf_mr66, go_wmf_mr67, go_wmf_mr68, go_wmf_mr69
+};
+
+static GHashTable *
+go_wmf_init_recs (void)
+{
+	GHashTable	*mrecords;
+	gint i =0;
+	const gint ridarray[70] =
+	{	0, 0x001e, 0x0035, 0x0037, 0x00F7, 0x0102, 0x0103, 0x0104, 0x0105, 0x0106,
+		0x0107, 0x0108, 0x0127, 0x012a, 0x012b, 0x012c, 0x012d, 0x012e, 0x0139, 0x0142,
+		0x0149, 0x01f0, 0x01f9, 0x0201, 0x0209, 0x020a, 0x020b, 0x020c, 0x020d, 0x020e,
+		0x020f, 0x0211, 0x0213, 0x0214, 0x0220, 0x0228, 0x0231, 0x0234, 0x02fa, 0x02fb,
+		0x02fc, 0x0324, 0x0325, 0x0410, 0x0412, 0x0415, 0x0416, 0x0418, 0x0419, 0x041b,
+		0x041f, 0x0429, 0x0436, 0x0521, 0x0538, 0x0548, 0x061c, 0x061d, 0x0626, 0x06ff,
+		0x0817, 0x081a, 0x0830, 0x0922, 0x0940, 0x0a32, 0x0b23, 0x0b41, 0x0d33, 0x0f43};
+
+	mrecords = g_hash_table_new (g_direct_hash, g_direct_equal);
+	for (i = 0; i < 70; i++)
+		g_hash_table_insert (mrecords, GINT_TO_POINTER (ridarray[i]), GINT_TO_POINTER (i));
+	return mrecords;
+}
+
+static GHashTable *
+go_wmf_init_esc (void)
+{
+	GHashTable	*escrecords;
+	gint i =0;
+	const char* escarray[60] = {
+		"NEWFRAME", "ABORTDOC", "NEXTBAND", "SETCOLORTABLE", "GETCOLORTABLE",
+		"FLUSHOUT", "DRAFTMODE", "QUERYESCSUPPORT", "SETABORTPROC", "STARTDOC",
+		"ENDDOC", "GETPHYSPAGESIZE", "GETPRINTINGOFFSET", "GETSCALINGFACTOR",
+		"META_ESCAPE_ENHANCED_METAFILE", "SETPENWIDTH", "SETCOPYCOUNT",
+		"SETPAPERSOURCE", "PASSTHROUGH", "GETTECHNOLOGY", "SETLINECAP", "SETLINEJOIN",
+		"SETMITERLIMIT", "BANDINFO", "DRAWPATTERNRECT","GETVECTORPENSIZE",
+		"GETVECTORBRUSHSIZE", "ENABLEDUPLEX", "GETSETPAPERBINS", "GETSETPRINTORIENT",
+		"ENUMPAPERBINS", "SETDIBSCALING", "EPSPRINTING", "ENUMPAPERMETRICS",
+		"GETSETPAPERMETRICS", "POSTSCRIPT_DATA", "POSTSCRIPT_IGNORE", "GETDEVICEUNITS",
+		"GETEXTENDEDTEXTMETRICS", "GETPAIRKERNTABLE", "EXTTEXTOUT", "GETFACENAME",
+		"DOWNLOADFACE", "METAFILE_DRIVER", "QUERYDIBSUPPORT", "BEGIN_PATH",
+		"CLIP_TO_PATH", "END_PATH", "OPEN_CHANNEL", "DOWNLOADHEADER", "CLOSE_CHANNEL",
+		"POSTSCRIPT_PASSTHROUGH", "ENCAPSULATED_POSTSCRIPT", "POSTSCRIPT_IDENTIFY",
+		"POSTSCRIPT_INJECTION", "CHECKJPEGFORMAT", "CHECKPNGFORMAT",
+		"GET_PS_FEATURESETTING", "MXDC_ESCAPE", "SPCLPASSTHROUGH2"};
+	const guint16 escid[60] = {
+		0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000A,
+		0x000B, 0x000C, 0x000D, 0x000E, 0x000F, 0x0010, 0x0011, 0x0012, 0x0013, 0x0014,
+		0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E,
+		0x001F, 0x0020, 0x0021, 0x0022, 0x0023, 0x0025, 0x0026, 0x002A, 0x0100, 0x0102,
+		0x0200, 0x0201, 0x0202, 0x0801, 0x0C01, 0x1000, 0x1001, 0x1002, 0x100E, 0x100F,
+		0x1010, 0x1013, 0x1014, 0x1015, 0x1016, 0x1017, 0x1018, 0x1019, 0x101A, 0x11D8};
+
+	escrecords = g_hash_table_new (g_direct_hash, g_direct_equal);
+	for (i = 0; i < 60; i++)
+		g_hash_table_insert (escrecords, GINT_TO_POINTER (escid[i]), GINT_TO_POINTER (escarray[i]));
+	return escrecords;
+}
+
+/*****************************************************************************
+ * EMF parsing code
+ *****************************************************************************/
+
+static gboolean
+go_emf_header (GOEmfState *state)
+{
+	guint32 signature = GSF_LE_GET_GINT32 (state->data + 32);
+	switch (signature) {
+	case 0x464D4520:
+		state->is_emf = TRUE;
+		d_(("Enhanced Metafile\n"));
+		break;
+	default:
+		state->is_emf = FALSE;
+		d_(("Unknown type, crossing fingers\n"));
+		break;
+	}
+	
+	d_(("header with %u bytes\n", state->length));
+	go_wmf_read_rectl (&state->dubounds, state->data);
+	go_wmf_read_rectl (&state->mmbounds, state->data + 16);
+	d_(("bounds are (mm): left=%g top=%g right=%g bottom=%g\n",
+	    (double) state->mmbounds.left / 100., (double) state->mmbounds.top / 100.,
+	    (double) state->mmbounds.right / 100., (double) state->mmbounds.bottom / 100.));
+
+	return TRUE;
+}
+
+static gboolean
+go_emf_polybezier (GOEmfState *state)
+{
+	d_(("polybezier\n"));
+	return TRUE;
+}
+
+static gboolean
+go_emf_polygon (GOEmfState *state)
+{
+	d_(("polygon\n"));
+	return TRUE;
+}
+
+static gboolean
+go_emf_polyline (GOEmfState *state)
+{
+	d_(("polyline\n"));
+	return TRUE;
+}
+
+static gboolean
+go_emf_polybezierto (GOEmfState *state)
+{
+	d_(("polybezierto\n"));
+	return TRUE;
+}
+
+static gboolean
+go_emf_polylineto (GOEmfState *state)
+{
+	d_(("polylineto\n"));
+	return TRUE;
+}
+
+static gboolean
+go_emf_polypolyline (GOEmfState *state)
+{
+	d_(("polypolyline\n"));
+	return TRUE;
+}
+
+static gboolean
+go_emf_polypolygon (GOEmfState *state)
+{
+	d_(("polypolygon\n"));
+	return TRUE;
+}
+
+static gboolean
+go_emf_setwindowextex (GOEmfState *state)
+{
+	d_(("setwindowextex\n"));
+	return TRUE;
+}
+
+static gboolean
+go_emf_setwindoworgex (GOEmfState *state)
+{
+	d_(("setwindoworgex\n"));
+	return TRUE;
+}
+
+static gboolean
+go_emf_setviewportextex (GOEmfState *state)
+{
+	d_(("setviewportextex\n"));
+	return TRUE;
+}
+
+static gboolean
+go_emf_setviewportorgex (GOEmfState *state)
+{
+	d_(("setviewportorgex\n"));
+	return TRUE;
+}
+
+static gboolean
+go_emf_setbrushorgex (GOEmfState *state)
+{
+	d_(("setbrushorgex\n"));
+	return TRUE;
+}
+
+static gboolean
+go_emf_eof (GOEmfState *state)
+{
+	d_(("eof\n"));
+	return TRUE;
+}
+
+static gboolean
+go_emf_setpixelv (GOEmfState *state)
+{
+	d_(("setpixelv\n"));
+	return TRUE;
+}
+
+static gboolean
+go_emf_setmapperflags (GOEmfState *state)
+{
+	d_(("setmapperflags\n"));
+	return TRUE;
+}
+
+static gboolean
+go_emf_setmapmode (GOEmfState *state)
+{
+	d_(("setmapmode\n"));
+	return TRUE;
+}
+
+static gboolean
+go_emf_setbkmode (GOEmfState *state)
+{
+	d_(("setbkmode\n"));
+	return TRUE;
+}
+
+static gboolean
+go_emf_setpolyfillmode (GOEmfState *state)
+{
+	d_(("setpolyfillmode\n"));
+	return TRUE;
+}
+
+static gboolean
+go_emf_setrop2 (GOEmfState *state)
+{
+	d_(("setrop2\n"));
+	return TRUE;
+}
+
+static gboolean
+go_emf_setstretchbltmode (GOEmfState *state)
+{
+	d_(("setstretchbltmode\n"));
+	return TRUE;
+}
+
+static gboolean
+go_emf_settextalign (GOEmfState *state)
+{
+	d_(("settextalign\n"));
+	return TRUE;
+}
+
+static gboolean
+go_emf_setcoloradjustment (GOEmfState *state)
+{
+	d_(("setcoloradjustment\n"));
+	return TRUE;
+}
+
+static gboolean
+go_emf_settextcolor (GOEmfState *state)
+{
+	d_(("settextcolor\n"));
+	return TRUE;
+}
+
+static gboolean
+go_emf_setbkcolor (GOEmfState *state)
+{
+	d_(("setbkcolor\n"));
+	return TRUE;
+}
+
+static gboolean
+go_emf_offsetcliprgn (GOEmfState *state)
+{
+	d_(("offsetcliprgn\n"));
+	return TRUE;
+}
+
+static gboolean
+go_emf_movetoex (GOEmfState *state)
+{
+	d_(("movetoex\n"));
+	return TRUE;
+}
+
+static gboolean
+go_emf_setmetargn (GOEmfState *state)
+{
+	d_(("setmetargn\n"));
+	return TRUE;
+}
+
+static gboolean
+go_emf_excludecliprect (GOEmfState *state)
+{
+	d_(("excludecliprect\n"));
+	return TRUE;
+}
+
+static gboolean
+go_emf_intersectcliprect (GOEmfState *state)
+{
+	d_(("intersectcliprect\n"));
+	return TRUE;
+}
+
+static gboolean
+go_emf_scaleviewportextex (GOEmfState *state)
+{
+	d_(("scaleviewportextex\n"));
+	return TRUE;
+}
+
+static gboolean
+go_emf_scalewindowextex (GOEmfState *state)
+{
+	d_(("scalewindowextex\n"));
+	return TRUE;
+}
+
+static gboolean
+go_emf_savedc (GOEmfState *state)
+{
+	d_(("savedc\n"));
+	return TRUE;
+}
+
+static gboolean
+go_emf_restoredc (GOEmfState *state)
+{
+	d_(("restoredc\n"));
+	return TRUE;
+}
+
+static gboolean
+go_emf_setworldtransform (GOEmfState *state)
+{
+	d_(("setworldtransform\n"));
+	return TRUE;
+}
+
+static gboolean
+go_emf_modifyworldtransform (GOEmfState *state)
+{
+	d_(("modifyworldtransfor\n"));
+	return TRUE;
+}
+
+static gboolean
+go_emf_selectobject (GOEmfState *state)
+{
+	d_(("selectobject\n"));
+	return TRUE;
+}
+
+static gboolean
+go_emf_createpen (GOEmfState *state)
+{
+	d_(("createpen\n"));
+	return TRUE;
+}
+
+static gboolean
+go_emf_createbrushindirect (GOEmfState *state)
+{
+	d_(("createbrushindirect\n"));
+	return TRUE;
+}
+
+static gboolean
+go_emf_deleteobject (GOEmfState *state)
+{
+	d_(("deleteobject\n"));
+	return TRUE;
+}
+
+static gboolean
+go_emf_anglearc (GOEmfState *state)
+{
+	d_(("anglearc\n"));
+	return TRUE;
+}
+
+static gboolean
+go_emf_ellipse (GOEmfState *state)
+{
+	d_(("ellipse\n"));
+	return TRUE;
+}
+
+static gboolean
+go_emf_rectangle (GOEmfState *state)
+{
+	d_(("rectangle\n"));
+	return TRUE;
+}
+
+static gboolean
+go_emf_roundrect (GOEmfState *state)
+{
+	d_(("roundrect\n"));
+	return TRUE;
+}
+
+static gboolean
+go_emf_arc (GOEmfState *state)
+{
+	d_(("arc\n"));
+	return TRUE;
+}
+
+static gboolean
+go_emf_chord (GOEmfState *state)
+{
+	d_(("chord\n"));
+	return TRUE;
+}
+
+static gboolean
+go_emf_pie (GOEmfState *state)
+{
+	d_(("pie\n"));
+	return TRUE;
+}
+
+static gboolean
+go_emf_selectpalette (GOEmfState *state)
+{
+	d_(("selectpalette\n"));
+	return TRUE;
+}
+
+static gboolean
+go_emf_createpalette (GOEmfState *state)
+{
+	d_(("createpalette\n"));
+	return TRUE;
+}
+
+static gboolean
+go_emf_setpaletteentries (GOEmfState *state)
+{
+	d_(("setpaletteentries\n"));
+	return TRUE;
+}
+
+static gboolean
+go_emf_resizepalette (GOEmfState *state)
+{
+	d_(("resizepalette\n"));
+	return TRUE;
+}
+
+static gboolean
+go_emf_realizepalette (GOEmfState *state)
+{
+	d_(("realizepalette\n"));
+	return TRUE;
+}
+
+static gboolean
+go_emf_extfloodfill (GOEmfState *state)
+{
+	d_(("extfloodfill\n"));
+	return TRUE;
+}
+
+static gboolean
+go_emf_lineto (GOEmfState *state)
+{
+	d_(("lineto\n"));
+	return TRUE;
+}
+
+static gboolean
+go_emf_arcto (GOEmfState *state)
+{
+	d_(("arcto\n"));
+	return TRUE;
+}
+
+static gboolean
+go_emf_polydraw (GOEmfState *state)
+{
+	d_(("polydraw\n"));
+	return TRUE;
+}
+
+static gboolean
+go_emf_setarcdirection (GOEmfState *state)
+{
+	d_(("setarcdirection\n"));
+	return TRUE;
+}
+
+static gboolean
+go_emf_setmiterlimit (GOEmfState *state)
+{
+	d_(("setmiterlimit\n"));
+	return TRUE;
+}
+
+static gboolean
+go_emf_beginpath (GOEmfState *state)
+{
+	d_(("beginpath\n"));
+	return TRUE;
+}
+
+static gboolean
+go_emf_endpath (GOEmfState *state)
+{
+	d_(("endpath\n"));
+	return TRUE;
+}
+
+static gboolean
+go_emf_closefigure (GOEmfState *state)
+{
+	d_(("closefigure\n"));
+	return TRUE;
+}
+
+static gboolean
+go_emf_fillpath (GOEmfState *state)
+{
+	d_(("fillpath\n"));
+	return TRUE;
+}
+
+static gboolean
+go_emf_strokeandfillpath (GOEmfState *state)
+{
+	d_(("strokeandfillpath\n"));
+	return TRUE;
+}
+
+static gboolean
+go_emf_strokepath (GOEmfState *state)
+{
+	d_(("strokepath\n"));
+	return TRUE;
+}
+
+static gboolean
+go_emf_flattenpath (GOEmfState *state)
+{
+	d_(("flattenpath\n"));
+	return TRUE;
+}
+
+static gboolean
+go_emf_widenpath (GOEmfState *state)
+{
+	d_(("widenpath\n"));
+	return TRUE;
+}
+
+static gboolean
+go_emf_selectclippath (GOEmfState *state)
+{
+	d_(("selectclippath\n"));
+	return TRUE;
+}
+
+static gboolean
+go_emf_abortpath (GOEmfState *state)
+{
+	d_(("abortpath\n"));
+	return TRUE;
+}
+
+static gboolean
+go_emf_comment (GOEmfState *state)
+{
+	d_(("comment\n"));
+	return TRUE;
+}
+
+static gboolean
+go_emf_fillrgn (GOEmfState *state)
+{
+	d_(("fillrgn\n"));
+	return TRUE;
+}
+
+static gboolean
+go_emf_framergn (GOEmfState *state)
+{
+	d_(("framergn\n"));
+	return TRUE;
+}
+
+static gboolean
+go_emf_invertrgn (GOEmfState *state)
+{
+	d_(("invertrgn\n"));
+	return TRUE;
+}
+
+static gboolean
+go_emf_paintrgn (GOEmfState *state)
+{
+	d_(("paintrgn\n"));
+	return TRUE;
+}
+
+static gboolean
+go_emf_extselectcliprgn (GOEmfState *state)
+{
+	d_(("extselectcliprgn\n"));
+	return TRUE;
+}
+
+static gboolean
+go_emf_bitblt (GOEmfState *state)
+{
+	d_(("bitblt\n"));
+	return TRUE;
+}
+
+static gboolean
+go_emf_stretchblt (GOEmfState *state)
+{
+	d_(("stretchblt\n"));
+	return TRUE;
+}
+
+static gboolean
+go_emf_maskblt (GOEmfState *state)
+{
+	d_(("maskblt\n"));
+	return TRUE;
+}
+
+static gboolean
+go_emf_plgblt (GOEmfState *state)
+{
+	d_(("plgblt\n"));
+	return TRUE;
+}
+
+static gboolean
+go_emf_setdibitstodevice (GOEmfState *state)
+{
+	d_(("setdibitstodevice\n"));
+	return TRUE;
+}
+
+static gboolean
+go_emf_stretchdibits (GOEmfState *state)
+{
+	GOEmfRectL rect;
+	gint32 x, y, cx, cy;
+	d_(("stretchdibits\n"));
+	go_wmf_read_rectl (&rect, state->data);
+	x = GSF_LE_GET_GINT32 (data + 16);
+	y = GSF_LE_GET_GINT32 (data + 20);
+	cx = GSF_LE_GET_GINT32 (data + 24);
+	cy = GSF_LE_GET_GINT32 (data + 28);
+	return TRUE;
+}
+
+static gboolean
+go_emf_extcreatefontindirectw (GOEmfState *state)
+{
+	d_(("extcreatefontindirectw\n"));
+	return TRUE;
+}
+
+static gboolean
+go_emf_exttextouta (GOEmfState *state)
+{
+	d_(("exttextouta\n"));
+	return TRUE;
+}
+
+static gboolean
+go_emf_exttextoutw (GOEmfState *state)
+{
+	d_(("exttextoutw\n"));
+	return TRUE;
+}
+
+static gboolean
+go_emf_polybezier16 (GOEmfState *state)
+{
+	d_(("polybezier16\n"));
+	return TRUE;
+}
+
+static gboolean
+go_emf_polygon16 (GOEmfState *state)
+{
+	d_(("polygon16\n"));
+	return TRUE;
+}
+
+static gboolean
+go_emf_polyline16 (GOEmfState *state)
+{
+	d_(("polyline16\n"));
+	return TRUE;
+}
+
+static gboolean
+go_emf_polybezierto16 (GOEmfState *state)
+{
+	d_(("polybezierto16\n"));
+	return TRUE;
+}
+
+static gboolean
+go_emf_polylineto16 (GOEmfState *state)
+{
+	d_(("polylineto16\n"));
+	return TRUE;
+}
+
+static gboolean
+go_emf_polypolyline16 (GOEmfState *state)
+{
+	d_(("polypolyline16\n"));
+	return TRUE;
+}
+
+static gboolean
+go_emf_polypolygon16 (GOEmfState *state)
+{
+	d_(("polypolygon16\n"));
+	return TRUE;
+}
+
+static gboolean
+go_emf_polydraw16 (GOEmfState *state)
+{
+	d_(("polydraw16 \n"));
+	return TRUE;
+}
+
+static gboolean
+go_emf_createmonobrush (GOEmfState *state)
+{
+	d_(("createmonobrush\n"));
+	return TRUE;
+}
+
+static gboolean
+go_emf_createdibpatternbrushpt (GOEmfState *state)
+{
+	d_(("createdibpatternbrushpt\n"));
+	return TRUE;
+}
+
+static gboolean
+go_emf_extcreatepen (GOEmfState *state)
+{
+	d_(("extcreatepen\n"));
+	return TRUE;
+}
+
+static gboolean
+go_emf_polytextouta (GOEmfState *state)
+{
+	d_(("polytextouta\n"));
+	return TRUE;
+}
+
+static gboolean
+go_emf_polytextoutw (GOEmfState *state)
+{
+	d_(("polytextoutw\n"));
+	return TRUE;
+}
+
+static gboolean
+go_emf_seticmmode (GOEmfState *state)
+{
+	d_(("seticmmode\n"));
+	return TRUE;
+}
+
+static gboolean
+go_emf_createcolorspace (GOEmfState *state)
+{
+	d_(("createcolorspace\n"));
+	return TRUE;
+}
+
+static gboolean
+go_emf_setcolorspace (GOEmfState *state)
+{
+	d_(("setcolorspace\n"));
+	return TRUE;
+}
+
+static gboolean
+go_emf_deletecolorspace (GOEmfState *state)
+{
+	d_(("deletecolorspace\n"));
+	return TRUE;
+}
+
+typedef gboolean (*GOEmfHandler) (GOEmfState* state);
+
+static  GOEmfHandler go_emf_handlers[] = {
+	NULL,
+	go_emf_header,			/* 0x0001 */
+	go_emf_polybezier,		/* 0x0002 */
+	go_emf_polygon,			/* 0x0003 */
+	go_emf_polyline,		/* 0x0004 */
+	go_emf_polybezierto,		/* 0x0005 */
+	go_emf_polylineto,		/* 0x0006 */
+	go_emf_polypolyline,		/* 0x0007 */
+	go_emf_polypolygon,		/* 0x0008 */
+	go_emf_setwindowextex,		/* 0x0009 */
+	go_emf_setwindoworgex,		/* 0x000A */
+	go_emf_setviewportextex,	/* 0x000B */
+	go_emf_setviewportorgex,	/* 0x000C */
+	go_emf_setbrushorgex,		/* 0x000D */
+	go_emf_eof,			/* 0x000E */
+	go_emf_setpixelv,		/* 0x000F */
+	go_emf_setmapperflags,		/* 0x0010 */
+	go_emf_setmapmode,		/* 0x0011 */
+	go_emf_setbkmode,		/* 0x0012 */
+	go_emf_setpolyfillmode,		/* 0x0013 */
+	go_emf_setrop2,			/* 0x0014 */
+	go_emf_setstretchbltmode,       /* 0x0015 */
+	go_emf_settextalign,		/* 0x0016 */
+	go_emf_setcoloradjustment,	/* 0x0017 */
+	go_emf_settextcolor,		/* 0x0018 */
+	go_emf_setbkcolor,		/* 0x0019 */
+	go_emf_offsetcliprgn,		/* 0x001A */
+	go_emf_movetoex,		/* 0x001B */
+	go_emf_setmetargn,		/* 0x001C */
+	go_emf_excludecliprect,		/* 0x001D */
+	go_emf_intersectcliprect,	/* 0x001E */
+	go_emf_scaleviewportextex,	/* 0x001F */
+	go_emf_scalewindowextex,	/* 0x0020 */
+	go_emf_savedc,			/* 0x0021 */
+	go_emf_restoredc,		/* 0x0022 */
+	go_emf_setworldtransform,	/* 0x0023 */
+	go_emf_modifyworldtransform,	/* 0x0024 */
+	go_emf_selectobject,		/* 0x0025 */
+	go_emf_createpen,		/* 0x0026 */
+	go_emf_createbrushindirect,	/* 0x0027 */
+	go_emf_deleteobject,		/* 0x0028 */
+	go_emf_anglearc,		/* 0x0029 */
+	go_emf_ellipse,			/* 0x002A */
+	go_emf_rectangle,		/* 0x002B */
+	go_emf_roundrect,		/* 0x002C */
+	go_emf_arc,			/* 0x002D */
+	go_emf_chord,			/* 0x002E */
+	go_emf_pie,			/* 0x002F */
+	go_emf_selectpalette,		/* 0x0030 */
+	go_emf_createpalette,		/* 0x0031 */
+	go_emf_setpaletteentries,	/* 0x0032 */
+	go_emf_resizepalette,		/* 0x0033 */
+	go_emf_realizepalette,		/* 0x0034 */
+	go_emf_extfloodfill,		/* 0x0035 */
+	go_emf_lineto,			/* 0x0036 */
+	go_emf_arcto,			/* 0x0037 */
+	go_emf_polydraw,		/* 0x0038 */
+	go_emf_setarcdirection,		/* 0x0039 */
+	go_emf_setmiterlimit,		/* 0x003A */
+	go_emf_beginpath,		/* 0x003B */
+	go_emf_endpath,			/* 0x003C */
+	go_emf_closefigure,		/* 0x003D */
+	go_emf_fillpath,		/* 0x003E */
+	go_emf_strokeandfillpath,	/* 0x003F */
+	go_emf_strokepath,		/* 0x0040 */
+	go_emf_flattenpath,		/* 0x0041 */
+	go_emf_widenpath,		/* 0x0042 */
+	go_emf_selectclippath,		/* 0x0043 */
+	go_emf_abortpath,		/* 0x0044 */
+	NULL,
+	go_emf_comment,			/* 0x0046 */
+	go_emf_fillrgn,			/* 0x0047 */
+	go_emf_framergn,		/* 0x0048 */
+	go_emf_invertrgn,		/* 0x0049 */
+	go_emf_paintrgn,		/* 0x004A */
+	go_emf_extselectcliprgn,	/* 0x004B */
+	go_emf_bitblt,			/* 0x004C */
+	go_emf_stretchblt,		/* 0x004D */
+	go_emf_maskblt,			/* 0x004E */
+	go_emf_plgblt,			/* 0x004F */
+	go_emf_setdibitstodevice,	/* 0x0050 */
+	go_emf_stretchdibits,		/* 0x0051 */
+	go_emf_extcreatefontindirectw,	/* 0x0052 */
+	go_emf_exttextouta,		/* 0x0053 */
+	go_emf_exttextoutw,		/* 0x0054 */
+	go_emf_polybezier16,		/* 0x0055 */
+	go_emf_polygon16,		/* 0x0056 */
+	go_emf_polyline16,		/* 0x0057 */
+	go_emf_polybezierto16,		/* 0x0058 */
+	go_emf_polylineto16,		/* 0x0059 */
+	go_emf_polypolyline16,		/* 0x005A */
+	go_emf_polypolygon16,		/* 0x005B */
+	go_emf_polydraw16,		/* 0x005C */
+	go_emf_createmonobrush,		/* 0x005D */
+	go_emf_createdibpatternbrushpt,	/* 0x005E */
+	go_emf_extcreatepen,		/* 0x005F */
+	go_emf_polytextouta,		/* 0x0060 */
+	go_emf_polytextoutw,		/* 0x0051 */
+	go_emf_seticmmode,		/* 0x0062 */
+	go_emf_createcolorspace,	/* 0x0063 */
+	go_emf_setcolorspace,		/* 0x0064 */
+	go_emf_deletecolorspace		/* 0x0065 */
+};
+
+/*****************************************************************************
+ * EMF parsing code
+ *****************************************************************************/
+
+static gboolean
+go_emf_parse (GOEmf *emf, GsfInput *input, GError **error)
+{
+	GHashTable	*mrecords, *escrecords;
+	GHashTable	*objs;
+	GOWmfPage *mypg;
+	guint32 rsize = 3;
+	int rid = 0, escfunc;
+	gint mr = 0;
+	const guint8  *data = {0};
+	guint32 type = 0; /* wmf, apm or emf */
+	guint32 offset = 0;
+	guint64 fsize = 0;
+	double x1, y1, x2, y2, w, h;
+	GOWmfDC *dc;
+
+	fsize = gsf_input_size (input);
+	data = gsf_input_read (input, 4, NULL);
+	switch (GSF_LE_GET_GUINT32 (data)) {
+	case 0x9ac6cdd7:
+		d_ (("Aldus Placeable Metafile\n"));
+		type = 1;
+		offset = 40;
+		break;
+	case 0x090001:
+		d_ (("Standard metafile\n"));
+		type = 2 ;
+		offset = 18;
+		break;
+	case 1:
+		type = 3;
+		rid = 1;
+#if 0
+		gsf_input_seek (input, 40, G_SEEK_SET);  /* 40 -- offset to EMF signature */
+			data = gsf_input_read (input, 4, NULL);
+		if (0x464D4520 == GSF_LE_GET_GUINT32 (data)) {
+			type = 3;
+			d_ (("EMF file\n"));
+		} else {
+			d_ (("Unknown type"));
+		}
+#endif
+		break;
+	default:
+		d_ (("Unknown type\n"));
+	}
+
+	if (1 == type || 2 == type) {
+		mypg = malloc (sizeof (GOWmfPage));
+		mrecords = go_wmf_init_recs ();
+		escrecords = go_wmf_init_esc ();
+		go_wmf_init_page (mypg);
+		objs = g_hash_table_new (g_direct_hash, g_direct_equal);
+		dc = &g_array_index (mypg->dcs, GOWmfDC, mypg->curdc);
+		if (1 == type) {
+			gsf_input_seek (input, 6, G_SEEK_SET);
+			go_wmf_read_point (input, &x1, &y1);
+			go_wmf_read_point (input, &x2, &y2);
+			w = abs (x2 - x1);
+			h = abs (y2 - y1);
+			dc->VPx = mypg->w;
+			dc->VPy = mypg->w * h / w;
+			if (mypg->w * h / w > mypg->h) {
+				dc->VPy = mypg->h;
+				dc->VPx = mypg->h * w / h;
+			}
+			mypg->zoom = dc->VPx / w;
+			mypg->type = 1;
+			dc->Wx = w;
+			dc->Wy = h;
+		} else {
+			mypg->type = 2;
+		}
+
+		gsf_input_seek (input, offset, G_SEEK_SET);
+		while (offset < fsize - 6) {  /* check if it's end of file already */
+			data = gsf_input_read (input, 4, NULL);
+			rsize = GSF_LE_GET_GUINT32 (data);
+			data = gsf_input_read (input, 2, NULL);
+			rid = GSF_LE_GET_GINT16 (data);
+			if (0 == rid || offset + rsize * 2 > fsize)
+				break;
+			if (0x626 != rid) {
+				mr = GPOINTER_TO_INT (g_hash_table_lookup (mrecords, GINT_TO_POINTER (rid)));
+				d_ (("Offset: %d, Rid: %x, MR: %d, RSize: %d\n", offset, rid, mr, rsize));
+				go_wmf_mfrec_dump[mr] (input, rsize, mypg, objs, emf->canvas);
+			} else {
+				data = gsf_input_read (input, 2, NULL);
+				escfunc = GSF_LE_GET_GINT16 (data);
+				d_ (("ESCAPE! Function is %04x -- %s. Size: %d bytes.\n", escfunc, (char*) g_hash_table_lookup (escrecords, GINT_TO_POINTER (escfunc)), rsize * 2 - 6));
+				if (0xf == escfunc)
+					go_wmf_mr58 (input, rsize, mypg, objs, emf->canvas);
+				gsf_input_seek (input, -2, G_SEEK_CUR);
+			}
+			gsf_input_seek (input, rsize * 2 - 6, G_SEEK_CUR);
+			offset += rsize * 2;
+		}
+		g_free (mypg);
+		g_hash_table_destroy (mrecords);
+		g_hash_table_destroy (escrecords);
+		return TRUE;
+	} else if (type == 3) {
+		GOEmfState state;
+		state.canvas = emf->canvas;
+		state.error = error;
+		offset = 4;
+		while ((offset += 4) < fsize && rid != 0xe) { /* EOF */
+			data = gsf_input_read (input, 4, NULL);
+			if (!data)
+				break;
+			rsize = GSF_LE_GET_GUINT32 (data) - 8;
+			if ((offset += rsize) > fsize)
+				break;
+			state.length = rsize;
+			state.data = gsf_input_read (input, rsize, NULL);
+			if (!go_emf_handlers[rid] (&state))
+				break;
+			if (offset + 4 >= fsize)
+				break;
+			data = gsf_input_read (input, 4, NULL);
+			if (!data)
+				break;
+			rid = GSF_LE_GET_GUINT32 (data);
+		}
+		if (rid != 0xe) {
+			if (error) {
+				if (*error == NULL)
+					*error = g_error_new (go_error_invalid (), 0,
+					                      _("Invalid image data\n"));
+			}
+			return FALSE;
+		} else {
+			go_emf_handlers[rid] (&state); /* just for debugging */
+			return TRUE;
+		}
+	}
 	return FALSE;
 }
 #endif
diff --git a/goffice/utils/go-image.h b/goffice/utils/go-image.h
index cdf42e1..54bed31 100644
--- a/goffice/utils/go-image.h
+++ b/goffice/utils/go-image.h
@@ -22,10 +22,7 @@
 #include <goffice/goffice.h>
 #include <gsf/gsf-libxml.h>
 #include <cairo.h>
-
-#ifdef GOFFICE_WITH_GTK
-#	include <gdk-pixbuf/gdk-pixbuf.h>
-#endif
+#include <gdk-pixbuf/gdk-pixbuf.h>
 
 G_BEGIN_DECLS
 
diff --git a/goffice/utils/go-pango-extras.c b/goffice/utils/go-pango-extras.c
index 8cd82a9..b080997 100644
--- a/goffice/utils/go-pango-extras.c
+++ b/goffice/utils/go-pango-extras.c
@@ -252,6 +252,7 @@ go_pango_attr_list_is_empty (const PangoAttrList *attrs)
 	return empty;
 }
 
+#ifdef GOFFICE_WITH_GTK
 static gboolean
 go_load_pango_attributes_into_buffer_filter (PangoAttribute *attribute,
 					  G_GNUC_UNUSED gpointer data)
@@ -481,6 +482,7 @@ go_load_pango_attributes_into_buffer (PangoAttrList  *markup, GtkTextBuffer *buf
 		pango_attr_list_unref (our_markup);
 	}
 }
+#endif
 
 static gboolean
 filter_func (PangoAttribute *attribute, G_GNUC_UNUSED gpointer data)
diff --git a/goffice/utils/go-pango-extras.h b/goffice/utils/go-pango-extras.h
index c660fd2..987b50a 100644
--- a/goffice/utils/go-pango-extras.h
+++ b/goffice/utils/go-pango-extras.h
@@ -3,7 +3,10 @@
 #define GO_PANGO_EXTRAS_H
 
 #include <pango/pango.h>
+
+#ifdef GOFFICE_WITH_GTK
 #include <gtk/gtk.h>
+#endif
 
 G_BEGIN_DECLS
 
@@ -25,10 +28,12 @@ void go_pango_attr_list_unset (PangoAttrList  *list,
 			       PangoAttrType type);
 gboolean go_pango_attr_list_is_empty (const PangoAttrList *attrs);
 
+#ifdef GOFFICE_WITH_GTK
 void go_load_pango_attributes_into_buffer (PangoAttrList *markup,
 					   GtkTextBuffer *buffer,
 					   gchar const *str);
 void go_create_std_tags_for_buffer (GtkTextBuffer *buffer);
+#endif
 
 PangoAttrList *go_pango_translate_attributes (PangoAttrList *attrs);
 void go_pango_translate_layout (PangoLayout *layout);
diff --git a/plugins/plot_radar/gog-radar.c b/plugins/plot_radar/gog-radar.c
index 59a48fa..8a34f59 100644
--- a/plugins/plot_radar/gog-radar.c
+++ b/plugins/plot_radar/gog-radar.c
@@ -412,8 +412,8 @@ gog_polar_area_populate_editor (GogObject *obj,
 		g_object_unref (gui);
 	}
 
-#endif
 	gog_class->populate_editor (obj, editor, dalloc, cc);
+#endif
 };
 
 /*****************************************************************************/



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