diff --git a/goffice/canvas/goc-graph.c b/goffice/canvas/goc-graph.c
index ed84eb6..f7abec4 100644
--- a/goffice/canvas/goc-graph.c
+++ b/goffice/canvas/goc-graph.c
@@ -236,7 +236,6 @@ format_coordinate (GogAxis *axis, GOFormat *fmt, double x)
 		 go_font_metrics_unit,
 		 fmt,
 		 x, 'F', NULL,
-		 NULL,
 		 width, date_conv, TRUE);
 	if (err) {
 		/* Invalid number for format.  */
diff --git a/goffice/graph/gog-axis-line.c b/goffice/graph/gog-axis-line.c
index da30abc..8fad0e6 100644
--- a/goffice/graph/gog-axis-line.c
+++ b/goffice/graph/gog-axis-line.c
@@ -1054,9 +1054,9 @@ axis_line_get_bbox (GogAxisBase *axis_base, GogRenderer *renderer,
 
 	obrs = g_new0 (GOGeometryOBR, tick_nbr);
 	for (i = 0; i < tick_nbr; i++) {
-		if (ticks[i].label != NULL) {
+		if (ticks[i].layout != NULL) {
 			GOGeometryOBR *obr = obrs + i;
-			gog_renderer_get_text_OBR (renderer, ticks[i].label, TRUE, obr);
+			gog_renderer_get_layout_OBR (renderer, ticks[i].layout, obr);
 			if (obr->w > label_size_max
 			    || obr->h > label_size_max) {
 				label_size_max = MAX (obr->w, obr->h);
@@ -1066,7 +1066,7 @@ axis_line_get_bbox (GogAxisBase *axis_base, GogRenderer *renderer,
 	}
 
 	for (i = 0; i < tick_nbr; i++) {
-		if (ticks[i].label != NULL) {
+		if (ticks[i].layout != NULL) {
 			GOGeometryOBR *obr = obrs + i;
 			pos = gog_axis_map_to_view (map, ticks[i].position);
 			obr->w += label_padding;
@@ -1166,9 +1166,9 @@ axis_line_render (GogAxisBase *axis_base,
 		obrs = g_new0 (GOGeometryOBR, tick_nbr);
 		indexmap = g_new0 (unsigned int, tick_nbr);
 		for (i = 0; i < tick_nbr; i++) {
-			if (ticks[i].label != NULL) {
+			if (ticks[i].layout != NULL) {
 				GOGeometryOBR *obr = obrs + i;
-				gog_renderer_get_text_OBR (renderer, ticks[i].label, TRUE, obr);
+				gog_renderer_get_layout_OBR (renderer, ticks[i].layout, obr);
 				if (obr->w > label_size_max
 				    || obr->h > label_size_max) {
 					label_size_max = MAX (obr->w, obr->h);
@@ -1216,7 +1216,7 @@ axis_line_render (GogAxisBase *axis_base,
 			}
 		}
 
-		if (ticks[i].label != NULL && draw_labels) {
+		if (ticks[i].layout != NULL && draw_labels) {
 			GOGeometryOBR *obr = obrs + i;
 			obr->w += label_padding;
 			go_geometry_calc_label_position (obr, axis_angle, tick_len,
@@ -1267,9 +1267,8 @@ axis_line_render (GogAxisBase *axis_base,
 			GogViewAllocation label_pos;
 			label_pos.x = obrs[j].x;
 			label_pos.y = obrs[j].y;
-			gog_renderer_draw_text (renderer, ticks[j].label,
-						&label_pos, GTK_ANCHOR_CENTER,
-						TRUE);
+			gog_renderer_draw_layout (renderer, ticks[j].layout,
+						&label_pos, GTK_ANCHOR_CENTER);
 		}
 	}
 	g_free (obrs);
@@ -1338,8 +1337,8 @@ axis_circle_get_bbox (GogAxisBase *axis_base, GogRenderer *renderer,
 		angle = gog_axis_map_to_view (map, ticks[i].position);
 		gog_chart_map_2D_to_view (c_map, ticks[i].position, position, &x, &y);
 
-		if (ticks[i].label != NULL && draw_labels) {
-			gog_renderer_get_text_OBR (renderer, ticks[i].label, TRUE, &txt_obr);
+		if (ticks[i].layout != NULL && draw_labels) {
+			gog_renderer_get_layout_OBR (renderer, ticks[i].layout, &txt_obr);
 			txt_obr.w += label_padding;
 			go_geometry_calc_label_position (&txt_obr, angle + M_PI / 2.0, tick_len,
 							 GO_SIDE_LEFT, GO_SIDE_AUTO);
@@ -1460,10 +1459,10 @@ axis_circle_render (GogAxisBase *axis_base, GogRenderer *renderer,
 			}
 		}
 
-		if (ticks[i].label != NULL && draw_labels) {
+		if (ticks[i].layout != NULL && draw_labels) {
 			gog_chart_map_2D_to_view (c_map, ticks[i].position, position,
 						  &label_pos.x, &label_pos.y);
-			gog_renderer_get_text_OBR (renderer, ticks[i].label, TRUE, &txt_obr);
+			gog_renderer_get_layout_OBR (renderer, ticks[i].layout, &txt_obr);
 			txt_obr.w += label_padding;
 			go_geometry_calc_label_position (&txt_obr, angle + M_PI / 2.0, tick_len,
 							 GO_SIDE_LEFT, GO_SIDE_AUTO);
@@ -1474,8 +1473,9 @@ axis_circle_render (GogAxisBase *axis_base, GogRenderer *renderer,
 			if (!first_label_done ||
 			    (!go_geometry_test_OBR_overlap (&txt_obr, &txt_obr_old) &&
 			     !go_geometry_test_OBR_overlap (&txt_obr, &txt_obr_first))) {
-				gog_renderer_draw_text (renderer, ticks[i].label,
-							&label_pos, GTK_ANCHOR_CENTER, TRUE);
+				gog_renderer_draw_layout 
+					(renderer, ticks[i].layout,
+					 &label_pos, GTK_ANCHOR_CENTER);
 				txt_obr_old = txt_obr;
 			}
 			if (!first_label_done) {
@@ -2061,10 +2061,13 @@ xyz_process (GogAxisBaseAction action, GogView *view, GogViewPadding *padding,
 			if (axis_base->major_tick_labeled) {
 				label_w = label_h = 0;
 				for (i = 0; i < tick_nbr; i++) {
-					if (ticks[i].label == NULL)
+					if (ticks[i].layout == NULL)
 						continue;
-					gog_renderer_get_text_OBR (view->renderer,
-						ticks[i].label, TRUE, &obr);
+#warning FIXME: we should use the ticks[i].layout itself
+					gog_renderer_get_text_OBR 
+						(view->renderer,
+						 pango_layout_get_text (ticks[i].layout), 
+						 FALSE, &obr);
 					if (obr.w > label_w)
 						label_w = obr.w;
 					if (obr.h > label_h)
diff --git a/goffice/graph/gog-axis.c b/goffice/graph/gog-axis.c
index 4762c67..e94ae1d 100644
--- a/goffice/graph/gog-axis.c
+++ b/goffice/graph/gog-axis.c
@@ -105,6 +105,26 @@ struct _GogAxis {
 
 static void gog_axis_set_ticks (GogAxis *axis,int tick_nbr, GogAxisTick *ticks);
 
+static PangoLayout *
+gog_get_layout (void)
+{
+	PangoContext *context = pango_context_new ();
+	PangoLayout *layout = pango_layout_new (context);
+	g_object_unref (context);
+	return layout;
+}
+
+static void
+gog_axis_ticks_set_text (GogAxisTick *ticks, char const *str)
+{
+	if (ticks->layout == NULL)
+		ticks->layout = gog_get_layout ();
+
+	pango_layout_set_attributes (ticks->layout, NULL);
+	pango_layout_set_text (ticks->layout, str, -1);
+
+}
+
 static GogAxisTick *
 create_invalid_axis_ticks (double min, double max)
 {
@@ -114,8 +134,9 @@ create_invalid_axis_ticks (double min, double max)
 	ticks[0].position = min;
 	ticks[1].position = max;
 	ticks[0].type = ticks[1].type = GOG_AXIS_TICK_MAJOR;
-	ticks[0].label = g_strdup ("##");
-	ticks[1].label = g_strdup ("##");
+	ticks[0].layout = ticks[1].layout = NULL;
+	gog_axis_ticks_set_text (&ticks[0], "##");
+	gog_axis_ticks_set_text (&ticks[1], "##");
 
 	return ticks;
 }
@@ -139,26 +160,30 @@ gog_axis_get_effective_format (GogAxis const *axis)
 	return axis->format;
 }
 
-static char *
-axis_format_value (GogAxis *axis, double val)
+static void
+axis_format_value (GogAxis *axis, double val, PangoLayout **layout)
 {
 	GOFormat *fmt = gog_axis_get_effective_format (axis);
-	GString *res = g_string_sized_new (20);
 	const GODateConventions *date_conv = axis->date_conv;
-	GOFormatNumberError err = go_format_value_gstring
-		(NULL, res,
+	GOFormatNumberError err;
+
+	g_return_if_fail (layout != NULL);
+
+	if (*layout == NULL)
+		*layout = gog_get_layout ();
+
+	err = go_format_value_gstring
+		(*layout, NULL,
 		 go_format_measure_strlen,
 		 go_font_metrics_unit,
 		 fmt,
 		 val, 'F', NULL,
-		 NULL,
 		 -1, date_conv, TRUE);
-	if (err) {
+	if (err){
 		/* Invalid number for format.  */
-		g_string_assign (res, "#####");
+		pango_layout_set_text (*layout, "#####", -1);
+		pango_layout_set_attributes (*layout, NULL);
 	}
-
-	return g_string_free (res, FALSE);
 }
 
 static gboolean
@@ -345,22 +370,25 @@ map_discrete_calc_ticks (GogAxis *axis)
 	for (i = 0; i < tick_nbr; i++) {
 		ticks[i].position = tick_start + (double) (i) * major_tick;
 		ticks[i].type = GOG_AXIS_TICK_MAJOR;
-		ticks[i].label = NULL;
+		ticks[i].layout = NULL;
 	}
 	for (i = 0, j = tick_nbr; i < label_nbr; i++, j++) {
+		char *label;
 		ticks[j].position = go_rint (label_start + (double) (i) * major_label);
 		index = ticks[j].position - 1;
 		ticks[j].type = GOG_AXIS_TICK_NONE;
+		ticks[j].layout = NULL;
 		if (axis->labels != NULL) {
 			if (index < (int) go_data_get_vector_size (axis->labels) && index >= 0) {
-				char *label = go_data_get_vector_string (axis->labels, index);
-				ticks[j].label = g_markup_escape_text (label, -1);
+				label = go_data_get_vector_string (axis->labels, index);
+				gog_axis_ticks_set_text(&ticks[j], label);
 				g_free (label);
-			} else
-				ticks[j].label = NULL;
+			}
+		} else {
+			label = g_strdup_printf ("%d", index + 1);
+			gog_axis_ticks_set_text (&ticks[j], label);
+			g_free (label);
 		}
-		else
-			ticks[j].label = g_strdup_printf ("%d", index + 1);
 	}
 
 	gog_axis_set_ticks (axis, tick_nbr + label_nbr, ticks);
@@ -761,7 +789,7 @@ map_linear_calc_ticks (GogAxis *axis)
 			g_assert (t < N);
 			ticks[t].position = maj_pos;
 			ticks[t].type = GOG_AXIS_TICK_MAJOR;
-			ticks[t].label = axis_format_value (axis, maj_pos);
+			axis_format_value (axis, maj_pos, &ticks[t].layout);
 			t++;
 		}
 
@@ -775,7 +803,7 @@ map_linear_calc_ticks (GogAxis *axis)
 			g_assert (t < N);
 			ticks[t].position = min_pos;
 			ticks[t].type = GOG_AXIS_TICK_MINOR;
-			ticks[t].label = NULL;
+			ticks[t].layout = NULL;
 			t++;
 		}
 	}
@@ -985,7 +1013,7 @@ map_date_calc_ticks (GogAxis *axis)
 
 		ticks[t].position = maj_pos;
 		ticks[t].type = GOG_AXIS_TICK_MAJOR;
-		ticks[t].label = axis_format_value (axis, maj_pos);
+		axis_format_value (axis, maj_pos, &ticks[t].layout);
 		t++;
 
 		/* Calculate next major so we know when to stop minors.  */
@@ -1007,7 +1035,7 @@ map_date_calc_ticks (GogAxis *axis)
 
 			ticks[t].position = min_pos;
 			ticks[t].type = GOG_AXIS_TICK_MINOR;
-			ticks[t].label = NULL;
+			ticks[t].layout = NULL;
 			t++;
 		}
 	}
@@ -1035,6 +1063,7 @@ map_date_get_dim_format (GogAxis *axis, unsigned dim)
 {
 	switch (dim) {
 	case GOG_AXIS_ELEM_MIN:
+
 	case GOG_AXIS_ELEM_MAX: {
 		GOFormat *fmt = gog_axis_get_effective_format (axis);
 		/*
@@ -1349,7 +1378,7 @@ map_log_calc_ticks (GogAxis *axis)
 			g_assert (t < N);
 			ticks[t].position = maj_pos;
 			ticks[t].type = GOG_AXIS_TICK_MAJOR;
-			ticks[t].label = axis_format_value (axis, maj_pos);
+		        axis_format_value (axis, maj_pos, &ticks[t].layout);
 			t++;
 		}
 
@@ -1373,7 +1402,7 @@ map_log_calc_ticks (GogAxis *axis)
 			g_assert (t < N);
 			ticks[t].position = min_pos;
 			ticks[t].type = GOG_AXIS_TICK_MINOR;
-			ticks[t].label = NULL;
+			ticks[t].layout = NULL;
 			t++;
 		}
 	}
@@ -1778,7 +1807,8 @@ gog_axis_set_ticks (GogAxis *axis, int tick_nbr, GogAxisTick *ticks)
 
 	if (axis->ticks != NULL) {
 		for (i = 0; i < axis->tick_nbr; i++)
-			g_free (axis->ticks[i].label);
+			if (axis->ticks[i].layout)
+				g_object_unref (axis->ticks[i].layout);
 
 		g_free (axis->ticks);
 	}
diff --git a/goffice/graph/gog-axis.h b/goffice/graph/gog-axis.h
index 75c5b6e..42cec29 100644
--- a/goffice/graph/gog-axis.h
+++ b/goffice/graph/gog-axis.h
@@ -45,7 +45,7 @@ typedef enum {
 typedef struct {
 	double		 position;
 	GogAxisTickTypes	 type;
-	char 		*label;
+	PangoLayout      *layout;
 } GogAxisTick;
 
 typedef struct _GogAxisMap GogAxisMap;
diff --git a/goffice/graph/gog-renderer.c b/goffice/graph/gog-renderer.c
index 17a32ee..d2929e1 100644
--- a/goffice/graph/gog-renderer.c
+++ b/goffice/graph/gog-renderer.c
@@ -776,52 +776,60 @@ gog_renderer_draw_marker (GogRenderer *rend, double x, double y)
 	cairo_paint (rend->cairo);
 }
 
+static void
+gog_renderer_copy_layout_info (PangoLayout *from_layout, PangoLayout *to_layout)
+{
+	pango_layout_set_text (to_layout,
+			       pango_layout_get_text (from_layout),
+			       -1);
+	pango_layout_set_attributes 
+		(to_layout,
+		 pango_layout_get_attributes 
+				      (from_layout));
+}
+
 /**
- * gog_renderer_draw_text :
+ * gog_renderer_draw_layout :
  * @rend   : #GogRenderer
- * @text   : the string to draw
+ * @layout : the layout to draw
  * @pos    : #GogViewAllocation
  * @anchor : #GtkAnchorType how to draw relative to @pos
- * @use_markup: wether to use pango markup
  *
- * Have @rend draw @text in the at @pos.{x,y} anchored by the @anchor corner.
+ * Have @rend draw @layout in the at @pos.{x,y} anchored by the @anchor corner.
  * If @pos.w or @pos.h are >= 0 then clip the results to less than that size.
  **/
 
 void
-gog_renderer_draw_text (GogRenderer *rend, char const *text,
-			GogViewAllocation const *pos, GtkAnchorType anchor,
-			gboolean use_markup)
+gog_renderer_draw_layout (GogRenderer *rend, PangoLayout *orig_layout,
+			GogViewAllocation const *pos, GtkAnchorType anchor)
 {
 	PangoLayout *layout;
 	PangoContext *context;
-	cairo_t *cairo = rend->cairo;
+	cairo_t *cairo;
 	GOGeometryOBR obr;
 	GOGeometryAABR aabr;
 	GOStyle const *style;
 	int iw, ih;
 
+	g_return_if_fail (orig_layout != NULL);
 	g_return_if_fail (GOG_IS_RENDERER (rend));
 	g_return_if_fail (rend->cur_style != NULL);
-	g_return_if_fail (text != NULL);
-
-	if (*text == '\0')
-		return;
 
+	cairo = rend->cairo;
 	style = rend->cur_style;
 
+	/* Note: orig layout may not have been created using cairo! */
 	layout = pango_cairo_create_layout (cairo);
 	context = pango_layout_get_context (layout);
+	gog_renderer_copy_layout_info (orig_layout, layout);
 	pango_cairo_context_set_resolution (context, 72.0);
-	if (use_markup)
-		pango_layout_set_markup (layout, text, -1);
-	else
-		pango_layout_set_text (layout, text, -1);
 	pango_layout_set_font_description (layout, style->font.font->desc);
 	pango_layout_get_size (layout, &iw, &ih);
 
-	obr.w = rend->scale * ((double) iw + (double) PANGO_SCALE / 2.0) / (double) PANGO_SCALE;
-	obr.h = rend->scale * ((double) ih + (double) PANGO_SCALE / 2.0) /(double) PANGO_SCALE;
+	obr.w = rend->scale * ((double) iw + (double) PANGO_SCALE / 2.0) 
+		/ (double) PANGO_SCALE;
+	obr.h = rend->scale * ((double) ih + (double) PANGO_SCALE / 2.0) 
+		/(double) PANGO_SCALE;
 	obr.alpha = -style->text_layout.angle * M_PI / 180.0;
 	obr.x = pos->x;
 	obr.y = pos->y;
@@ -849,8 +857,10 @@ gog_renderer_draw_text (GogRenderer *rend, char const *text,
 
 	cairo_save (cairo);
 	cairo_set_source_rgba (cairo, GO_COLOR_TO_CAIRO (style->font.color));
-	cairo_move_to (cairo, obr.x - (obr.w / 2.0) * cos (obr.alpha) + (obr.h / 2.0) * sin (obr.alpha),
-		       obr.y - (obr.w / 2.0) * sin (obr.alpha) - (obr.h / 2.0) * cos (obr.alpha));
+	cairo_move_to (cairo, obr.x - (obr.w / 2.0) * cos (obr.alpha) + 
+		       (obr.h / 2.0) * sin (obr.alpha),
+		       obr.y - (obr.w / 2.0) * sin (obr.alpha) - 
+		       (obr.h / 2.0) * cos (obr.alpha));
 	cairo_rotate (cairo, obr.alpha);
 	cairo_scale (cairo, rend->scale, rend->scale);
 	pango_cairo_show_layout (cairo, layout);
@@ -858,6 +868,45 @@ gog_renderer_draw_text (GogRenderer *rend, char const *text,
 	g_object_unref (layout);
 }
 
+
+/**
+ * gog_renderer_draw_text :
+ * @rend   : #GogRenderer
+ * @text   : the string to draw
+ * @pos    : #GogViewAllocation
+ * @anchor : #GtkAnchorType how to draw relative to @pos
+ * @use_markup: wether to use pango markup
+ *
+ * Have @rend draw @text in the at @pos.{x,y} anchored by the @anchor corner.
+ * If @pos.w or @pos.h are >= 0 then clip the results to less than that size.
+ **/
+
+void
+gog_renderer_draw_text (GogRenderer *rend, char const *text,
+			GogViewAllocation const *pos, GtkAnchorType anchor,
+			gboolean use_markup)
+{
+	PangoLayout *layout;
+	cairo_t *cairo;
+
+	g_return_if_fail (GOG_IS_RENDERER (rend));
+	g_return_if_fail (text != NULL);
+
+	if (*text == '\0')
+		return;
+
+	cairo = rend->cairo;
+	layout = pango_cairo_create_layout (cairo);
+	if (use_markup)
+		pango_layout_set_markup (layout, text, -1);
+	else
+		pango_layout_set_text (layout, text, -1);
+
+	gog_renderer_draw_layout (rend, layout, pos, anchor);
+
+	g_object_unref (layout);
+}
+
 /**
  * gog_renderer_get_text_OBR :
  * @rend: #GogRenderer
@@ -866,22 +915,22 @@ gog_renderer_draw_text (GogRenderer *rend, char const *text,
  * @obr: #GOGeometryOBR to store the Object Bounding Rectangle of @text.
  **/
 void
-gog_renderer_get_text_OBR (GogRenderer *rend, char const *text,
-			   gboolean use_markup, GOGeometryOBR *obr)
+gog_renderer_get_layout_OBR (GogRenderer *rend, PangoLayout *orig_layout, GOGeometryOBR *obr)
 {
 	GOStyle const *style;
 	PangoLayout *layout;
 	PangoContext *context;
 	PangoRectangle logical;
-	cairo_t *cairo = rend->cairo;
+	cairo_t *cairo;
+	char const *text = pango_layout_get_text (orig_layout);
 
 	g_return_if_fail (GOG_IS_RENDERER (rend));
 	g_return_if_fail (rend->cur_style != NULL);
-	g_return_if_fail (text != NULL);
 	g_return_if_fail (obr != NULL);
 
+	cairo = rend->cairo;
 	obr->x = obr->y = 0;
-	if (*text == '\0') {
+	if (text == NULL || *text == '\0') {
 		/* Make sure invisible things don't skew size */
 		obr->w = obr->h = 0;
 		obr->alpha = 0;
@@ -889,20 +938,18 @@ gog_renderer_get_text_OBR (GogRenderer *rend, char const *text,
 	}
 
 	style = rend->cur_style;
-
 	layout = pango_cairo_create_layout (cairo);
 	context = pango_layout_get_context (layout);
+	gog_renderer_copy_layout_info (orig_layout, layout);
 	pango_cairo_context_set_resolution (context, 72.0);
-	if (use_markup)
-		pango_layout_set_markup (layout, text, -1);
-	else
-		pango_layout_set_text (layout, text, -1);
 	pango_layout_set_font_description (layout, style->font.font->desc);
 	pango_layout_get_extents (layout, NULL, &logical);
 	g_object_unref (layout);
 
-	obr->w = rend->scale * ((double) logical.width + (double) PANGO_SCALE / 2.0) / (double) PANGO_SCALE;
-	obr->h = rend->scale * ((double) logical.height + (double) PANGO_SCALE / 2.0) /(double) PANGO_SCALE;
+	obr->w = rend->scale * ((double) logical.width + (double) PANGO_SCALE / 2.0) 
+		/ (double) PANGO_SCALE;
+	obr->h = rend->scale * ((double) logical.height + (double) PANGO_SCALE / 2.0) 
+		/(double) PANGO_SCALE;
 
 	/* Make sure invisible things don't skew size */
 	if (obr->w == 0)
@@ -913,6 +960,33 @@ gog_renderer_get_text_OBR (GogRenderer *rend, char const *text,
 	obr->alpha = - style->text_layout.angle * M_PI / 180.0;
 }
 
+
+/**
+ * gog_renderer_get_text_OBR :
+ * @rend: #GogRenderer
+ * @text: the string to draw
+ * @use_markup: wether to use pango markup
+ * @obr: #GOGeometryOBR to store the Object Bounding Rectangle of @text.
+ **/
+void
+gog_renderer_get_text_OBR (GogRenderer *rend, char const *text,
+			   gboolean use_markup, GOGeometryOBR *obr)
+{
+	PangoLayout *layout;
+	cairo_t *cairo = rend->cairo;
+
+	g_return_if_fail (GOG_IS_RENDERER (rend));
+	g_return_if_fail (text != NULL);
+
+	layout = pango_cairo_create_layout (cairo);
+	if (use_markup)
+		pango_layout_set_markup (layout, text, -1);
+	else
+		pango_layout_set_text (layout, text, -1);
+	gog_renderer_get_layout_OBR (rend, layout, obr);
+	g_object_unref (layout);
+}
+
 /**
  * gog_renderer_get_text_AABR :
  * @rend: #GogRenderer
diff --git a/goffice/graph/gog-renderer.h b/goffice/graph/gog-renderer.h
index 3c0dc5e..88e6d68 100644
--- a/goffice/graph/gog-renderer.h
+++ b/goffice/graph/gog-renderer.h
@@ -115,9 +115,17 @@ void  gog_renderer_draw_selection_rectangle	(GogRenderer *renderer, GogViewAlloc
 void  gog_renderer_draw_marker	  (GogRenderer *rend, double x, double y);
 
 void  gog_renderer_draw_text	  (GogRenderer *rend, char const *text,
-				   GogViewAllocation const *pos, GtkAnchorType anchor,
+				   GogViewAllocation const *pos, 
+				   GtkAnchorType anchor,
 				   gboolean use_markup);
 
+void  gog_renderer_draw_layout	  (GogRenderer *rend,
+				   PangoLayout *layout,
+				   GogViewAllocation const *pos, 
+				   GtkAnchorType anchor);
+
+void  gog_renderer_get_layout_OBR   (GogRenderer *rend, PangoLayout *layout,
+				     GOGeometryOBR *obr);
 void  gog_renderer_get_text_OBR   (GogRenderer *rend, char const *text,
 				   gboolean use_markup, GOGeometryOBR *obr);
 void  gog_renderer_get_text_AABR  (GogRenderer *rend, char const *text,
diff --git a/goffice/gtk/go-format-sel.c b/goffice/gtk/go-format-sel.c
index c0c4224..2b7b9d7 100644
--- a/goffice/gtk/go-format-sel.c
+++ b/goffice/gtk/go-format-sel.c
@@ -160,12 +160,12 @@ static guint go_format_sel_signals [LAST_SIGNAL] = { 0 };
 static void format_entry_set_text (GOFormatSel *gfs, const gchar *text);
 
 static char *
-generate_preview (GOFormatSel *gfs, GOColor *c)
+generate_preview (GOFormatSel *gfs, PangoAttrList **attrs)
 {
 	char *res = NULL;
 	g_signal_emit (G_OBJECT (gfs),
 		       go_format_sel_signals [GENERATE_PREVIEW], 0,
-		       c, &res);
+		       attrs, &res);
 	return res;
 }
 
@@ -174,8 +174,7 @@ draw_format_preview (GOFormatSel *gfs, gboolean regen_format)
 {
 	char *preview;
 	GOFormat const *sf = NULL;
-	GOColor c = 0;
-	GdkColor gdk_color;
+	PangoAttrList *attrs = NULL;
 	gsize len;
 
 	if (regen_format) {
@@ -196,22 +195,23 @@ draw_format_preview (GOFormatSel *gfs, gboolean regen_format)
 	if (NULL == (sf = gfs->format.spec))
 		return;
 
-	if (NULL == (preview = generate_preview (gfs, &c)))
+	if (NULL == (preview = generate_preview (gfs, &attrs)))
 		return;
 
 	len = g_utf8_strlen (preview, -1);
 	if (len > FORMAT_PREVIEW_MAX)
-		strcpy (g_utf8_offset_to_pointer (preview, FORMAT_PREVIEW_MAX - 5),
+		strcpy (g_utf8_offset_to_pointer (preview, 
+						  FORMAT_PREVIEW_MAX - 5),
 			"...");
 
 	gtk_text_buffer_set_text (gfs->format.preview_buffer, preview, -1);
-	if (c != 0)
-		go_color_to_gdk (c, &gdk_color);
-	else
-		gdk_color_parse ("black", &gdk_color);
 
-	gtk_widget_modify_text (GTK_WIDGET (gfs->format.preview),
-				GTK_STATE_NORMAL, &gdk_color);
+	go_load_pango_attributes_into_buffer (attrs, 
+					      gfs->format.preview_buffer,
+					      preview);
+
+	pango_attr_list_unref (attrs);
+
 	g_free (preview);
 }
 
@@ -999,6 +999,7 @@ nfs_init (GOFormatSel *gfs)
 		pango_font_metrics_unref (metrics);
 	}
 	gfs->format.preview_buffer = gtk_text_view_get_buffer (gfs->format.preview);
+	go_create_std_tags_for_buffer (gfs->format.preview_buffer);
 
 	gfs->format.menu = go_gtk_builder_get_widget (gfs->gui, "format_menu");
 	populate_menu (gfs);
diff --git a/goffice/utils/go-format.c b/goffice/utils/go-format.c
index 6c62419..48ae59d 100644
--- a/goffice/utils/go-format.c
+++ b/goffice/utils/go-format.c
@@ -179,6 +179,8 @@ typedef enum {
 	OP_NUM_MARK_MANTISSA,
 	OP_NUM_SIMPLIFY_MANTISSA,
 	OP_NUM_SIMPLIFY_EXPONENT,
+	OP_MARKUP_SUPERSCRIPT_START,
+	OP_MARKUP_SUPERSCRIPT_END,
 #endif
 	OP_NUM_FRACTION,	/* wholep explicitp (digits|denominator) */
 	OP_NUM_FRACTION_WHOLE,
@@ -1769,11 +1771,7 @@ go_format_parse_number_E (GOFormatParseState *pstate)
 			ADD_OP (OP_NUM_SIMPLIFY_MANTISSA);
 		ADD_OP2 (OP_CHAR, '1');
 		ADD_OP2 (OP_CHAR, '0');
-		ADD_OP2 (OP_CHAR, '<');
-		ADD_OP2 (OP_CHAR, 's');
-		ADD_OP2 (OP_CHAR, 'u');
-		ADD_OP2 (OP_CHAR, 'p');
-		ADD_OP2 (OP_CHAR, '>');
+		ADD_OP  (OP_MARKUP_SUPERSCRIPT_START);
 	} else
 #endif
 		ADD_OP2 (OP_CHAR, 'E');
@@ -1785,14 +1783,9 @@ go_format_parse_number_E (GOFormatParseState *pstate)
 
 #ifdef ALLOW_EE_MARKUP
 	if (use_markup) {
-		ADD_OP2 (OP_CHAR, '<');
-		ADD_OP2 (OP_CHAR, '/');
-		ADD_OP2 (OP_CHAR, 's');
-		ADD_OP2 (OP_CHAR, 'u');
-		ADD_OP2 (OP_CHAR, 'p');
-		ADD_OP2 (OP_CHAR, '>');
 		if (simplify_mantissa)
 			ADD_OP (OP_NUM_SIMPLIFY_EXPONENT);
+		ADD_OP  (OP_MARKUP_SUPERSCRIPT_END);
 	}
 #endif
 
@@ -2315,6 +2308,8 @@ go_format_dump_program (const guchar *prg)
 		REGULAR(OP_NUM_MARK_MANTISSA);
 		REGULAR(OP_NUM_SIMPLIFY_MANTISSA);
 		REGULAR(OP_NUM_SIMPLIFY_EXPONENT);
+		REGULAR(OP_MARKUP_SUPERSCRIPT_START);
+		REGULAR(OP_MARKUP_SUPERSCRIPT_END);
 #endif
 		REGULAR(OP_NUM_FRACTION_WHOLE);
 		REGULAR(OP_NUM_FRACTION_NOMINATOR);
@@ -2497,11 +2492,19 @@ SUFFIX(go_format_execute) (PangoLayout *layout, GString *dst,
 		DOUBLE w, n, d;
 		gsize nominator_start, denominator_start;
 	} fraction;
+	char *oldlocale = NULL;
 #ifdef ALLOW_EE_MARKUP
 	int mantissa_start = -1;
 	int special_mantissa = INT_MAX;
+	PangoAttrList *attrs = NULL;
+	GSList *markup_stack = NULL;
+
+	if (layout) {
+		attrs = pango_attr_list_copy (pango_layout_get_attributes (layout));
+		if (attrs == NULL)
+			attrs = pango_attr_list_new ();
+	}
 #endif
-	char *oldlocale = NULL;
 
 	memset (&fraction, 0, sizeof (fraction));
 
@@ -2510,8 +2513,15 @@ SUFFIX(go_format_execute) (PangoLayout *layout, GString *dst,
 
 		switch (op) {
 		case OP_END:
-			if (layout)
+			if (layout) {
 				pango_layout_set_text (layout, dst->str, -1);
+#ifdef ALLOW_EE_MARKUP
+
+				pango_layout_set_attributes (layout, attrs);
+				pango_attr_list_unref (attrs);
+				g_slist_free (markup_stack);
+#endif
+			}
 			if (numtxt)
 				g_string_free (numtxt, TRUE);
 			if (oldlocale) {
@@ -3062,6 +3072,33 @@ SUFFIX(go_format_execute) (PangoLayout *layout, GString *dst,
 				g_string_append_c (dst, '0');
 			}
 			break;
+
+		case OP_MARKUP_SUPERSCRIPT_START:
+			if (layout)
+				markup_stack = g_slist_prepend 
+					(markup_stack, GSIZE_TO_POINTER (dst->len));
+			break;
+
+		case OP_MARKUP_SUPERSCRIPT_END: 
+			if (layout) {
+				guint start = 0, 
+					end = (guint)dst->len;
+				PangoAttribute *attr;
+				if (markup_stack) {
+					start = (guint)GPOINTER_TO_SIZE (markup_stack->data);
+					markup_stack = g_slist_delete_link (markup_stack, markup_stack);
+				}
+				 /* FIXME: we need to calculate the right rise value */
+				attr = pango_attr_rise_new (5000);
+				attr->start_index = start;
+				attr->end_index = end;
+				pango_attr_list_insert (attrs, attr);
+				attr = pango_attr_scale_new (PANGO_SCALE_SMALL);
+				attr->start_index = start;
+				attr->end_index = end;
+				pango_attr_list_insert (attrs, attr);
+			}
+			break;
 #endif
 
 		case OP_NUM_FRACTION: {
@@ -3451,6 +3488,7 @@ SUFFIX(go_render_general) (PangoLayout *layout, GString *str,
 	return;
 }
 
+#define FREE_NEW_STR do { if (new_str) (void)g_string_free (new_str, TRUE); } while (0)
 
 GOFormatNumberError
 SUFFIX(go_format_value_gstring) (PangoLayout *layout, GString *str,
@@ -3458,25 +3496,40 @@ SUFFIX(go_format_value_gstring) (PangoLayout *layout, GString *str,
 				 const GOFontMetrics *metrics,
 				 GOFormat const *fmt,
 				 DOUBLE val, char type, const char *sval,
-				 GOColor *go_color,
 				 int col_width,
 				 GODateConventions const *date_conv,
 				 gboolean unicode_minus)
 {
 	gboolean inhibit = FALSE;
+	GString *new_str =  NULL;
+	GOFormatNumberError err;
 
 	g_return_val_if_fail (type == 'F' || sval != NULL,
 			      (GOFormatNumberError)-1);
 
-	g_string_truncate (str, 0);
+	if (str == NULL)
+		new_str = str = g_string_new (NULL);
+	else
+		g_string_truncate (str, 0);
 
 	if (fmt)
 		fmt = SUFFIX(go_format_specialize) (fmt, val, type, &inhibit);
 	if (!fmt)
 		fmt = go_format_general ();
 
-	if (go_color)
-		*go_color = fmt->color;
+	if (layout && fmt->color != 0) {
+		PangoAttrList *attrs;
+		PangoAttribute *attr;
+		attrs = pango_attr_list_ref (pango_layout_get_attributes (layout));
+		if (attrs == NULL)
+			attrs = pango_attr_list_new ();
+		attr = go_color_to_pango (fmt->color, TRUE);
+		attr->start_index = 0;
+		attr->end_index = G_MAXUINT;
+		pango_attr_list_insert (attrs, attr);
+		pango_layout_set_attributes (layout, attrs);
+		pango_attr_list_unref (attrs);
+	}
 
 	if (type == 'F') {
 		switch (fmt->typ) {
@@ -3487,14 +3540,17 @@ SUFFIX(go_format_value_gstring) (PangoLayout *layout, GString *str,
 				(layout, str, measure, metrics,
 				 val,
 				 col_width, unicode_minus);
+			FREE_NEW_STR;
 			return GO_FORMAT_NUMBER_OK;
 
 		case GO_FMT_NUMBER:
 			if (val < 0) {
 #ifndef ALLOW_NEGATIVE_TIMES
 				if (fmt->u.number.has_date ||
-				    fmt->u.number.has_time)
+				    fmt->u.number.has_time) {
+					FREE_NEW_STR;
 					return GO_FORMAT_NUMBER_DATE_ERROR;
+				}
 #endif
 				if (inhibit)
 					val = SUFFIX(fabs)(val);
@@ -3503,16 +3559,20 @@ SUFFIX(go_format_value_gstring) (PangoLayout *layout, GString *str,
 			g_printerr ("Executing %s\n", fmt->format);
 			go_format_dump_program (fmt->u.number.program);
 #endif
-			return SUFFIX(go_format_execute)
+
+			err = SUFFIX(go_format_execute)
 				(layout, str,
 				 measure, metrics,
 				 fmt->u.number.program,
 				 col_width,
 				 val, sval, date_conv,
 				 unicode_minus);
-
+			FREE_NEW_STR;
+			return err;
+			
 		case GO_FMT_EMPTY:
 			SETUP_LAYOUT;
+			FREE_NEW_STR;
 			return GO_FORMAT_NUMBER_OK;
 
 		default:
@@ -3520,26 +3580,30 @@ SUFFIX(go_format_value_gstring) (PangoLayout *layout, GString *str,
 		case GO_FMT_MARKUP:
 		case GO_FMT_COND:
 			SETUP_LAYOUT;
+			FREE_NEW_STR;
 			return GO_FORMAT_NUMBER_INVALID_FORMAT;
 		}
 	} else {
 		switch (fmt->typ) {
 		case GO_FMT_TEXT:
-			return SUFFIX(go_format_execute)
+			err = SUFFIX(go_format_execute)
 				(layout, str,
 				 measure, metrics,
 				 fmt->u.text.program,
 				 col_width,
 				 val, sval, date_conv,
 				 unicode_minus);
-
+			FREE_NEW_STR;
+			return err;
 		case GO_FMT_NUMBER:
 			g_string_assign (str, sval);
 			SETUP_LAYOUT;
+			FREE_NEW_STR;
 			return GO_FORMAT_NUMBER_OK;
 
 		case GO_FMT_EMPTY:
 			SETUP_LAYOUT;
+			FREE_NEW_STR;
 			return GO_FORMAT_NUMBER_OK;
 
 		default:
@@ -3547,11 +3611,14 @@ SUFFIX(go_format_value_gstring) (PangoLayout *layout, GString *str,
 		case GO_FMT_MARKUP:
 		case GO_FMT_COND:
 			SETUP_LAYOUT;
+			FREE_NEW_STR;
 			return GO_FORMAT_NUMBER_INVALID_FORMAT;
 		}
 	}
 }
 
+#undef FREE_NEW_STR
+
 /**
  * go_format_value:
  * @fmt: a #GOFormat
@@ -3572,7 +3639,6 @@ SUFFIX(go_format_value) (GOFormat const *fmt, DOUBLE val)
 		 go_font_metrics_unit,
 		 fmt,
 		 val, 'F', NULL,
-		 NULL,
 		 -1, NULL, FALSE);
 	if (err) {
 		/* Invalid number for format.  */
diff --git a/goffice/utils/go-format.h b/goffice/utils/go-format.h
index b82e3b3..f3d2e78 100644
--- a/goffice/utils/go-format.h
+++ b/goffice/utils/go-format.h
@@ -195,7 +195,6 @@ go_format_value_gstring (PangoLayout *layout, GString *str,
 			 const GOFontMetrics *metrics,
 			 GOFormat const *fmt,
 			 double val, char type, const char *sval,
-			 GOColor *go_color,
 			 int col_width,
 			 GODateConventions const *date_conv,
 			 gboolean unicode_minus);
@@ -207,7 +206,6 @@ go_format_value_gstringl (PangoLayout *layout, GString *str,
 			  const GOFontMetrics *metrics,
 			  GOFormat const *fmt,
 			  long double val, char type, const char *sval,
-			  GOColor *go_color,
 			  int col_width,
 			  GODateConventions const *date_conv,
 			  gboolean unicode_minus);
diff --git a/goffice/utils/go-pango-extras.c b/goffice/utils/go-pango-extras.c
index 9b6e677..0097cf9 100644
--- a/goffice/utils/go-pango-extras.c
+++ b/goffice/utils/go-pango-extras.c
@@ -1,3 +1,4 @@
+/* vim: set sw=8: -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
 /*
  * go-pango-extras.c: Various utility routines that should have been in pango.
  *
@@ -7,6 +8,8 @@
 
 #include <goffice/goffice-config.h>
 #include "go-pango-extras.h"
+#include "go-glib-extras.h"
+#include <string.h>
 
 struct cb_splice {
 	guint pos, len;
@@ -244,3 +247,233 @@ go_pango_attr_list_is_empty (const PangoAttrList *attrs)
 					      cb_empty, &empty);
 	return empty;
 }
+
+static gboolean
+go_load_pango_attributes_into_buffer_filter (PangoAttribute *attribute,
+					  G_GNUC_UNUSED gpointer data)
+{
+	return ((PANGO_ATTR_FOREGROUND == attribute->klass->type) ||
+		(PANGO_ATTR_UNDERLINE == attribute->klass->type) ||
+		(PANGO_ATTR_RISE == attribute->klass->type));
+}
+
+static gboolean
+go_load_pango_attributes_into_buffer_named_filter (PangoAttribute *attribute,
+						    G_GNUC_UNUSED gpointer data)
+{
+	return ((PANGO_ATTR_STYLE == attribute->klass->type) ||
+		(PANGO_ATTR_WEIGHT == attribute->klass->type) ||
+		(PANGO_ATTR_STRIKETHROUGH == attribute->klass->type));
+}
+
+void
+go_create_std_tags_for_buffer (GtkTextBuffer *buffer)
+{
+	gtk_text_buffer_create_tag (buffer, "PANGO_STYLE_NORMAL", "style", PANGO_STYLE_NORMAL,
+				    "style-set", TRUE, NULL);
+	gtk_text_buffer_create_tag (buffer, "PANGO_STYLE_ITALIC", "style", PANGO_STYLE_ITALIC,
+				    "style-set", TRUE, NULL);
+	gtk_text_buffer_create_tag (buffer, "PANGO_STRIKETHROUGH_TRUE", "strikethrough", TRUE,
+				    "strikethrough-set", TRUE, NULL);
+	gtk_text_buffer_create_tag (buffer, "PANGO_STRIKETHROUGH_FALSE", "strikethrough", FALSE,
+				    "strikethrough-set", TRUE, NULL);
+	gtk_text_buffer_create_tag (buffer, "PANGO_WEIGHT_THIN", "weight", 100,
+				    "weight-set", TRUE, NULL);
+	gtk_text_buffer_create_tag (buffer, "PANGO_WEIGHT_ULTRALIGHT", "weight", PANGO_WEIGHT_ULTRALIGHT,
+				    "weight-set", TRUE, NULL);
+	gtk_text_buffer_create_tag (buffer, "PANGO_WEIGHT_LIGHT", "weight", PANGO_WEIGHT_LIGHT,
+				    "weight-set", TRUE, NULL);
+	gtk_text_buffer_create_tag (buffer, "PANGO_WEIGHT_BOOK", "weight", 380,
+				    "weight-set", TRUE, NULL);
+	gtk_text_buffer_create_tag (buffer, "PANGO_WEIGHT_NORMAL", "weight", PANGO_WEIGHT_NORMAL,
+				    "weight-set", TRUE, NULL);
+	gtk_text_buffer_create_tag (buffer, "PANGO_WEIGHT_MEDIUM", "weight", 500,
+				    "weight-set", TRUE, NULL);
+	gtk_text_buffer_create_tag (buffer, "PANGO_WEIGHT_SEMIBOLD", "weight", PANGO_WEIGHT_SEMIBOLD,
+				    "weight-set", TRUE, NULL);
+	gtk_text_buffer_create_tag (buffer, "PANGO_WEIGHT_BOLD", "weight", PANGO_WEIGHT_BOLD,
+				    "weight-set", TRUE, NULL);
+	gtk_text_buffer_create_tag (buffer, "PANGO_WEIGHT_ULTRABOLD", "weight", PANGO_WEIGHT_ULTRABOLD,
+				    "weight-set", TRUE, NULL);
+	gtk_text_buffer_create_tag (buffer, "PANGO_WEIGHT_HEAVY", "weight", PANGO_WEIGHT_HEAVY,
+				    "weight-set", TRUE, NULL);
+	gtk_text_buffer_create_tag (buffer, "PANGO_WEIGHT_ULTRAHEAVY", "weight", 1000,
+				    "weight-set", TRUE, NULL);
+}
+
+static gint
+go_load_pango_byte_to_char (gchar const *str, gint byte)
+{
+	if (byte >= (gint)strlen (str))
+		return g_utf8_strlen (str, -1);
+	return g_utf8_pointer_to_offset (str, g_utf8_prev_char (str + byte + 1));
+}
+
+void
+go_load_pango_attributes_into_buffer (PangoAttrList  *markup, GtkTextBuffer *buffer, gchar const *str)
+{
+	PangoAttrIterator * iter;
+	PangoAttrList  *copied_markup;
+	PangoAttrList  *our_markup;
+
+	if (markup == NULL)
+		return;
+
+/* For some styles we create named tags. The names are taken from the Pango enums */
+
+	copied_markup = pango_attr_list_copy (markup);
+	our_markup = pango_attr_list_filter (copied_markup,
+					     go_load_pango_attributes_into_buffer_named_filter,
+					     NULL);
+	pango_attr_list_unref (copied_markup);
+	if (our_markup != NULL) {
+		iter = pango_attr_list_get_iterator (our_markup);
+
+		do {
+			GSList *attr = pango_attr_iterator_get_attrs (iter);
+			if (attr != NULL) {
+				GSList *ptr;
+				gint start, end;
+				GtkTextIter start_iter, end_iter;
+				char const *name;
+
+				pango_attr_iterator_range (iter, &start, &end);
+				start = go_load_pango_byte_to_char (str, start);
+				end = go_load_pango_byte_to_char (str, end);
+				gtk_text_buffer_get_iter_at_offset (buffer, &start_iter, start);
+				gtk_text_buffer_get_iter_at_offset (buffer, &end_iter, end);
+
+				for (ptr = attr; ptr != NULL; ptr = ptr->next) {
+					PangoAttribute *attribute = ptr->data;
+					GtkTextTag *tag;
+					int val;
+
+					switch (attribute->klass->type) {
+					case PANGO_ATTR_STYLE:
+						name = (((PangoAttrInt *)attribute)->value
+							== PANGO_STYLE_NORMAL)
+							? "PANGO_STYLE_NORMAL" :
+							"PANGO_STYLE_ITALIC";
+						tag = gtk_text_tag_table_lookup
+							(gtk_text_buffer_get_tag_table (buffer),
+							 name);
+						gtk_text_buffer_apply_tag (buffer, tag,
+									   &start_iter, &end_iter);
+						break;
+					case PANGO_ATTR_STRIKETHROUGH:
+						name = (((PangoAttrInt *)attribute)->value) ?
+							"PANGO_STRIKETHROUGH_TRUE" :
+							"PANGO_STRIKETHROUGH_FALSE";
+						tag = gtk_text_tag_table_lookup
+							(gtk_text_buffer_get_tag_table (buffer),
+							 name);
+						gtk_text_buffer_apply_tag (buffer, tag,
+									   &start_iter, &end_iter);
+						break;
+					case PANGO_ATTR_WEIGHT:
+						val = ((PangoAttrInt *)attribute)->value;
+						if (val < (PANGO_WEIGHT_THIN + PANGO_WEIGHT_ULTRALIGHT)/2)
+							gtk_text_buffer_apply_tag_by_name (buffer,"PANGO_WEIGHT_THIN",
+											   &start_iter, &end_iter);
+						else if (val < (PANGO_WEIGHT_ULTRALIGHT + PANGO_WEIGHT_LIGHT)/2)
+							gtk_text_buffer_apply_tag_by_name (buffer,"PANGO_WEIGHT_ULTRALIGHT",
+											   &start_iter, &end_iter);
+						else if (val < (PANGO_WEIGHT_LIGHT + PANGO_WEIGHT_BOOK)/2)
+							gtk_text_buffer_apply_tag_by_name (buffer,"PANGO_WEIGHT_LIGHT",
+											   &start_iter, &end_iter);
+						else if (val < (PANGO_WEIGHT_BOOK + PANGO_WEIGHT_NORMAL)/2)
+							gtk_text_buffer_apply_tag_by_name (buffer,"PANGO_WEIGHT_BOOK",
+											   &start_iter, &end_iter);
+						else if (val < (PANGO_WEIGHT_NORMAL + PANGO_WEIGHT_MEDIUM)/2)
+							gtk_text_buffer_apply_tag_by_name (buffer,"PANGO_WEIGHT_NORMAL",
+											   &start_iter, &end_iter);
+						else if (val < (PANGO_WEIGHT_MEDIUM + PANGO_WEIGHT_SEMIBOLD)/2)
+							gtk_text_buffer_apply_tag_by_name (buffer,"PANGO_WEIGHT_MEDIUM",
+											   &start_iter, &end_iter);
+						else if (val < (PANGO_WEIGHT_SEMIBOLD + PANGO_WEIGHT_BOLD)/2)
+							gtk_text_buffer_apply_tag_by_name (buffer,"PANGO_WEIGHT_SEMIBOLD",
+											   &start_iter, &end_iter);
+						else if (val < (PANGO_WEIGHT_BOLD + PANGO_WEIGHT_ULTRABOLD)/2)
+							gtk_text_buffer_apply_tag_by_name (buffer,"PANGO_WEIGHT_BOLD",
+											   &start_iter, &end_iter);
+						else if (val < (PANGO_WEIGHT_ULTRABOLD + PANGO_WEIGHT_HEAVY)/2)
+							gtk_text_buffer_apply_tag_by_name (buffer,"PANGO_WEIGHT_ULTRABOLD",
+											   &start_iter, &end_iter);
+						else if (val < (PANGO_WEIGHT_HEAVY + PANGO_WEIGHT_ULTRAHEAVY)/2)
+							gtk_text_buffer_apply_tag_by_name (buffer,"PANGO_WEIGHT_HEAVY",
+											   &start_iter, &end_iter);
+						else gtk_text_buffer_apply_tag_by_name (buffer,"PANGO_WEIGHT_ULTRAHEAVY",
+											&start_iter, &end_iter);
+						break;
+					default:
+						break;
+					}
+				}
+				go_slist_free_custom (attr, (GFreeFunc)pango_attribute_destroy);
+			}
+		} while (pango_attr_iterator_next (iter));
+		pango_attr_iterator_destroy (iter);
+		pango_attr_list_unref (our_markup);
+	}
+
+/* For other styles (that are not at true/false type styles) we use unnamed styles */
+
+	copied_markup = pango_attr_list_copy (markup);
+	our_markup = pango_attr_list_filter (copied_markup,
+					     go_load_pango_attributes_into_buffer_filter,
+					     NULL);
+	pango_attr_list_unref (copied_markup);
+	if (our_markup != NULL) {
+		iter = pango_attr_list_get_iterator (our_markup);
+
+		do {
+			GSList *attr = pango_attr_iterator_get_attrs (iter);
+			if (attr != NULL) {
+				char *string;
+				GSList *ptr;
+				gint start, end;
+				GtkTextIter start_iter, end_iter;
+				GtkTextTag *tag = gtk_text_buffer_create_tag (buffer, NULL, NULL);
+				for (ptr = attr; ptr != NULL; ptr = ptr->next) {
+					PangoAttribute *attribute = ptr->data;
+					switch (attribute->klass->type) {
+					case PANGO_ATTR_FOREGROUND:
+						string = pango_color_to_string
+							(&((PangoAttrColor *)attribute)->color);
+						g_object_set (G_OBJECT (tag),
+							      "foreground", string,
+							      "foreground-set", TRUE,
+							      NULL);
+						g_free (string);
+						break;
+					case PANGO_ATTR_UNDERLINE:
+						g_object_set (G_OBJECT (tag),
+							      "underline",
+							      ((PangoAttrInt *)attribute)->value,
+							      "underline-set", TRUE,
+							      NULL);
+						break;
+					case PANGO_ATTR_RISE:
+						g_object_set (G_OBJECT (tag),
+							      "rise",
+							      ((PangoAttrInt *)attribute)->value,
+							      "rise-set", TRUE,
+							      NULL);
+						break;
+					default:
+						break;
+					}
+				}
+				pango_attr_iterator_range (iter, &start, &end);
+				start = go_load_pango_byte_to_char (str, start);
+				end = go_load_pango_byte_to_char (str, end);
+				gtk_text_buffer_get_iter_at_offset (buffer, &start_iter, start);
+				gtk_text_buffer_get_iter_at_offset (buffer, &end_iter, end);
+				gtk_text_buffer_apply_tag (buffer, tag, &start_iter, &end_iter);
+				go_slist_free_custom (attr, (GFreeFunc)pango_attribute_destroy);
+			}
+		} while (pango_attr_iterator_next (iter));
+		pango_attr_iterator_destroy (iter);
+		pango_attr_list_unref (our_markup);
+	}
+}
diff --git a/goffice/utils/go-pango-extras.h b/goffice/utils/go-pango-extras.h
index 18fd95a..33c7339 100644
--- a/goffice/utils/go-pango-extras.h
+++ b/goffice/utils/go-pango-extras.h
@@ -2,6 +2,7 @@
 #define GO_PANGO_EXTRAS_H
 
 #include <pango/pango.h>
+#include <gtk/gtk.h>
 
 G_BEGIN_DECLS
 
@@ -12,6 +13,11 @@ void go_pango_attr_list_unset (PangoAttrList  *list,
 			       PangoAttrType type);
 gboolean go_pango_attr_list_is_empty (const PangoAttrList *attrs);
 
+void go_load_pango_attributes_into_buffer (PangoAttrList *markup, 
+					   GtkTextBuffer *buffer, 
+					   gchar const *str);
+void go_create_std_tags_for_buffer (GtkTextBuffer *buffer);
+
 G_END_DECLS
 
 #endif /* GO_PANGO_EXTRAS_H */
