diff --git a/rsvg-text.c b/rsvg-text.c
index 89720de..cad5d7f 100644
--- a/rsvg-text.c
+++ b/rsvg-text.c
@@ -150,84 +150,111 @@ _rsvg_node_text_set_atts (RsvgNode * self, RsvgHandle * ctx, RsvgPropertyBag * a
 }
 
 void
  rsvg_text_render_text (RsvgDrawingCtx * ctx, const char *text, gdouble * x, gdouble * y);
 
 
 static void
  _rsvg_node_text_type_tspan (RsvgNodeText * self, RsvgDrawingCtx * ctx,
-                             gdouble * x, gdouble * y, gboolean * lastwasspace);
+                             gdouble * x, gdouble * y, gboolean * lastwasspace,
+                             gboolean usetextonly);
 
 static void
  _rsvg_node_text_type_tref (RsvgNodeTref * self, RsvgDrawingCtx * ctx,
-                            gdouble * x, gdouble * y, gboolean * lastwasspace);
+                            gdouble * x, gdouble * y, gboolean * lastwasspace,
+                            gboolean usetextonly);
 
 static void
 _rsvg_node_text_type_children (RsvgNode * self, RsvgDrawingCtx * ctx,
-                               gdouble * x, gdouble * y, gboolean * lastwasspace)
+                               gdouble * x, gdouble * y, gboolean * lastwasspace,
+                               gboolean usetextonly)
 {
     guint i;
 
     rsvg_push_discrete_layer (ctx);
     for (i = 0; i < self->children->len; i++) {
         RsvgNode *node = g_ptr_array_index (self->children, i);
         RsvgNodeType type = RSVG_NODE_TYPE (node);
 
         if (type == RSVG_NODE_TYPE_CHARS) {
             RsvgNodeChars *chars = (RsvgNodeChars *) node;
             GString *str = _rsvg_text_chomp (rsvg_current_state (ctx), chars->contents, lastwasspace);
             rsvg_text_render_text (ctx, str->str, x, y);
             g_string_free (str, TRUE);
-        } else if (type == RSVG_NODE_TYPE_TSPAN) {
-            RsvgNodeText *tspan = (RsvgNodeText *) node;
-            rsvg_state_push (ctx);
-            _rsvg_node_text_type_tspan (tspan, ctx, x, y, lastwasspace);
-            rsvg_state_pop (ctx);
-        } else if (type == RSVG_NODE_TYPE_TREF) {
-            RsvgNodeTref *tref = (RsvgNodeTref *) node;
-            _rsvg_node_text_type_tref (tref, ctx, x, y, lastwasspace);
+        } else {
+            if (usetextonly) {
+                _rsvg_node_text_type_children (node, ctx, x, y, lastwasspace,
+                                               usetextonly);
+            } else {
+                if (type == RSVG_NODE_TYPE_TSPAN) {
+                    RsvgNodeText *tspan = (RsvgNodeText *) node;
+                    rsvg_state_push (ctx);
+                    _rsvg_node_text_type_tspan (tspan, ctx, x, y, lastwasspace,
+                                                usetextonly);
+                    rsvg_state_pop (ctx);
+                } else if (type == RSVG_NODE_TYPE_TREF) {
+                    RsvgNodeTref *tref = (RsvgNodeTref *) node;
+                    _rsvg_node_text_type_tref (tref, ctx, x, y, lastwasspace,
+                                               usetextonly);
+                }
+            }
         }
     }
     rsvg_pop_discrete_layer (ctx);
 }
 
 static int
  _rsvg_node_text_length_tref (RsvgNodeTref * self, RsvgDrawingCtx * ctx,
-                              gdouble * x, gboolean * lastwasspace);
+                              gdouble * x, gboolean * lastwasspace,
+                              gboolean usetextonly);
 
 static int
  _rsvg_node_text_length_tspan (RsvgNodeText * self, RsvgDrawingCtx * ctx,
-                               gdouble * x, gboolean * lastwasspace);
+                               gdouble * x, gboolean * lastwasspace,
+                               gboolean usetextonly);
 
 static gdouble rsvg_text_length_text_as_string (RsvgDrawingCtx * ctx, const char *text);
 
 static int
 _rsvg_node_text_length_children (RsvgNode * self, RsvgDrawingCtx * ctx,
-                                 gdouble * x, gboolean * lastwasspace)
+                                 gdouble * x, gboolean * lastwasspace,
+                                 gboolean usetextonly)
 {
     guint i;
     int out = FALSE;
     for (i = 0; i < self->children->len; i++) {
         RsvgNode *node = g_ptr_array_index (self->children, i);
         RsvgNodeType type = RSVG_NODE_TYPE (node);
 
         rsvg_state_push (ctx);
         rsvg_state_reinherit_top (ctx, node->state, 0);
         if (type == RSVG_NODE_TYPE_CHARS) {
             RsvgNodeChars *chars = (RsvgNodeChars *) node;
             GString *str = _rsvg_text_chomp (rsvg_current_state (ctx), chars->contents, lastwasspace);
             *x += rsvg_text_length_text_as_string (ctx, str->str);
             g_string_free (str, TRUE);
-        } else if (type == RSVG_NODE_TYPE_TSPAN) {
-            RsvgNodeText *tspan = (RsvgNodeText *) node;
-            out = _rsvg_node_text_length_tspan (tspan, ctx, x, lastwasspace);
-        } else if (type == RSVG_NODE_TYPE_TREF) {
-            RsvgNodeTref *tref = (RsvgNodeTref *) node;
-            out = _rsvg_node_text_length_tref (tref, ctx, x, lastwasspace);
+        } else {
+            if (usetextonly) {
+                out = _rsvg_node_text_length_children(node, ctx, x,
+                                                      lastwasspace,
+                                                      usetextonly);
+            } else {
+                if (type == RSVG_NODE_TYPE_TSPAN) {
+                    RsvgNodeText *tspan = (RsvgNodeText *) node;
+                    out = _rsvg_node_text_length_tspan (tspan, ctx, x,
+                                                        lastwasspace,
+                                                        usetextonly);
+                } else if (type == RSVG_NODE_TYPE_TREF) {
+                    RsvgNodeTref *tref = (RsvgNodeTref *) node;
+                    out = _rsvg_node_text_length_tref (tref, ctx, x,
+                                                       lastwasspace,
+                                                       usetextonly);
+                }
+            }
         }
         rsvg_state_pop (ctx);
         if (out)
             break;
     }
     return out;
 }
 
@@ -242,71 +269,75 @@ _rsvg_node_text_draw (RsvgNode * self, RsvgDrawingCtx * ctx, int dominate)
 
     x = _rsvg_css_normalize_length (&text->x, ctx, 'h');
     y = _rsvg_css_normalize_length (&text->y, ctx, 'v');
     x += _rsvg_css_normalize_length (&text->dx, ctx, 'h');
     y += _rsvg_css_normalize_length (&text->dy, ctx, 'v');
 
     if (rsvg_current_state (ctx)->text_anchor != TEXT_ANCHOR_START) {
         double length = 0;
-        _rsvg_node_text_length_children (self, ctx, &length, &lastwasspace);
+        _rsvg_node_text_length_children (self, ctx, &length, &lastwasspace, FALSE);
         if (rsvg_current_state (ctx)->text_anchor == TEXT_ANCHOR_END)
             x -= length;
         if (rsvg_current_state (ctx)->text_anchor == TEXT_ANCHOR_MIDDLE)
             x -= length / 2;
     }
 
     lastwasspace = TRUE;
-    _rsvg_node_text_type_children (self, ctx, &x, &y, &lastwasspace);
+    _rsvg_node_text_type_children (self, ctx, &x, &y, &lastwasspace, FALSE);
 }
 
 RsvgNode *
 rsvg_new_text (void)
 {
     RsvgNodeText *text;
     text = g_new (RsvgNodeText, 1);
     _rsvg_node_init (&text->super, RSVG_NODE_TYPE_TEXT);
     text->super.draw = _rsvg_node_text_draw;
     text->super.set_atts = _rsvg_node_text_set_atts;
     text->x = text->y = text->dx = text->dy = _rsvg_css_parse_length ("0");
     return &text->super;
 }
 
 static void
 _rsvg_node_text_type_tspan (RsvgNodeText * self, RsvgDrawingCtx * ctx,
-                            gdouble * x, gdouble * y, gboolean * lastwasspace)
+                            gdouble * x, gdouble * y, gboolean * lastwasspace,
+                            gboolean usetextonly)
 {
     rsvg_state_reinherit_top (ctx, self->super.state, 0);
 
     if (self->x.factor != 'n') {
         *x = _rsvg_css_normalize_length (&self->x, ctx, 'h');
         if (rsvg_current_state (ctx)->text_anchor != TEXT_ANCHOR_START) {
             double length = 0;
             gboolean lws = *lastwasspace;
-            _rsvg_node_text_length_children (&self->super, ctx, &length, &lws);
+            _rsvg_node_text_length_children (&self->super, ctx, &length, &lws,
+                                             usetextonly);
             if (rsvg_current_state (ctx)->text_anchor == TEXT_ANCHOR_END)
                 *x -= length;
             if (rsvg_current_state (ctx)->text_anchor == TEXT_ANCHOR_MIDDLE)
                 *x -= length / 2;
         }
     }
     if (self->y.factor != 'n')
         *y = _rsvg_css_normalize_length (&self->y, ctx, 'v');
     *x += _rsvg_css_normalize_length (&self->dx, ctx, 'h');
     *y += _rsvg_css_normalize_length (&self->dy, ctx, 'v');
-    _rsvg_node_text_type_children (&self->super, ctx, x, y, lastwasspace);
+    _rsvg_node_text_type_children (&self->super, ctx, x, y, lastwasspace,
+                                   usetextonly);
 }
 
 static int
 _rsvg_node_text_length_tspan (RsvgNodeText * self, RsvgDrawingCtx * ctx, gdouble * x,
-                              gboolean * lastwasspace)
+                              gboolean * lastwasspace, gboolean usetextonly)
 {
     if (self->x.factor != 'n' || self->y.factor != 'n')
         return TRUE;
-    return _rsvg_node_text_length_children (&self->super, ctx, x, lastwasspace);
+    return _rsvg_node_text_length_children (&self->super, ctx, x, lastwasspace,
+                                            usetextonly);
 }
 
 static void
 _rsvg_node_tspan_set_atts (RsvgNode * self, RsvgHandle * ctx, RsvgPropertyBag * atts)
 {
     const char *klazz = NULL, *id = NULL, *value;
     RsvgNodeText *text = (RsvgNodeText *) self;
 
@@ -339,28 +370,30 @@ rsvg_new_tspan (void)
     text->super.set_atts = _rsvg_node_tspan_set_atts;
     text->x.factor = text->y.factor = 'n';
     text->dx = text->dy = _rsvg_css_parse_length ("0");
     return &text->super;
 }
 
 static void
 _rsvg_node_text_type_tref (RsvgNodeTref * self, RsvgDrawingCtx * ctx,
-                           gdouble * x, gdouble * y, gboolean * lastwasspace)
+                           gdouble * x, gdouble * y, gboolean * lastwasspace,
+                           gboolean usetextonly)
 {
     if (self->link)
-        _rsvg_node_text_type_children (self->link, ctx, x, y, lastwasspace);
+        _rsvg_node_text_type_children (self->link, ctx, x, y, lastwasspace,
+                                                              TRUE);
 }
 
 static int
 _rsvg_node_text_length_tref (RsvgNodeTref * self, RsvgDrawingCtx * ctx, gdouble * x,
-                             gboolean * lastwasspace)
+                             gboolean * lastwasspace, gboolean usetextonly)
 {
     if (self->link)
-        return _rsvg_node_text_length_children (self->link, ctx, x, lastwasspace);
+        return _rsvg_node_text_length_children (self->link, ctx, x, lastwasspace, TRUE);
     return FALSE;
 }
 
 static void
 _rsvg_node_tref_set_atts (RsvgNode * self, RsvgHandle * ctx, RsvgPropertyBag * atts)
 {
     const char *value;
     RsvgNodeTref *text = (RsvgNodeTref *) self;
