[librsvg/rustification] Make RsvgLength carry its own direction for normalization



commit 5a85e7cf2ecc90486346debc9a5a426163348f52
Author: Federico Mena Quintero <federico gnome org>
Date:   Tue Nov 8 20:34:31 2016 -0600

    Make RsvgLength carry its own direction for normalization
    
    This is the pattern that was there before:
    
      foo.some_len = _rsvg_css_parse_length (str);   /* at creation time */
    
      ...
    
      double real_len = _rsvg_css_normalize_length (&foo.some_len, ctx, LENGTH_DIR_HORIZONTAL); /* at 
rendering time */
    
    This led to a few inconsistencies in the way directions got used -
    sometimes cut&paste errors could creep in and a vertical direction
    would be used for a horizontal length, for example.
    
    This change makes the pattern be
    
      foo.some_len = _rsvg_css_parse_length (str, LENGTH_DIR_HORIZONTAL);   /* at creation time */
    
      ...
    
      double real_len = _rsvg_css_normalize_length (&foo.some_len, ctx); /* at rendering time */
    
    I.e. lengths get their direction-to-be-resolved-as at creation time,
    during parse_length(); this gets stored in a new field length.dir.
    Later, normalize_length() knows which direction to use.

 rsvg-base.c         |    2 +-
 rsvg-cairo-draw.c   |   36 +++++++++++-----------
 rsvg-css.c          |   20 +++++++++---
 rsvg-filter.c       |   82 +++++++++++++++++++++++++-------------------------
 rsvg-image.c        |   18 +++++-----
 rsvg-marker.c       |   24 +++++++-------
 rsvg-mask.c         |   16 +++++-----
 rsvg-paint-server.c |   37 ++++++++++++-----------
 rsvg-private.h      |   15 +++++----
 rsvg-shapes.c       |   76 +++++++++++++++++++++++-----------------------
 rsvg-structure.c    |   48 +++++++++++++++---------------
 rsvg-styles.c       |   14 ++++----
 rsvg-text.c         |   35 ++++++++++-----------
 13 files changed, 217 insertions(+), 206 deletions(-)
---
diff --git a/rsvg-base.c b/rsvg-base.c
index 961f53a..d0a6783 100644
--- a/rsvg-base.c
+++ b/rsvg-base.c
@@ -2170,7 +2170,7 @@ rsvg_get_normalized_stroke_width (RsvgDrawingCtx *ctx)
 {
     RsvgState *state = rsvg_current_state (ctx);
 
-    return _rsvg_css_normalize_length (&state->stroke_width, ctx, LENGTH_DIR_BOTH);
+    return _rsvg_css_normalize_length (&state->stroke_width, ctx);
 }
 
 
diff --git a/rsvg-cairo-draw.c b/rsvg-cairo-draw.c
index 2425074..d1352ef 100644
--- a/rsvg-cairo-draw.c
+++ b/rsvg-cairo-draw.c
@@ -85,10 +85,10 @@ _set_source_rsvg_linear_gradient (RsvgDrawingCtx * ctx,
 
     if (linear->obj_bbox)
         _rsvg_push_view_box (ctx, 1., 1.);
-    pattern = cairo_pattern_create_linear (_rsvg_css_normalize_length (&linear->x1, ctx, 
LENGTH_DIR_HORIZONTAL),
-                                           _rsvg_css_normalize_length (&linear->y1, ctx, 
LENGTH_DIR_VERTICAL),
-                                           _rsvg_css_normalize_length (&linear->x2, ctx, 
LENGTH_DIR_HORIZONTAL),
-                                           _rsvg_css_normalize_length (&linear->y2, ctx, 
LENGTH_DIR_VERTICAL));
+    pattern = cairo_pattern_create_linear (_rsvg_css_normalize_length (&linear->x1, ctx),
+                                           _rsvg_css_normalize_length (&linear->y1, ctx),
+                                           _rsvg_css_normalize_length (&linear->x2, ctx),
+                                           _rsvg_css_normalize_length (&linear->y2, ctx));
 
     if (linear->obj_bbox)
         _rsvg_pop_view_box (ctx);
@@ -130,11 +130,11 @@ _set_source_rsvg_radial_gradient (RsvgDrawingCtx * ctx,
     if (radial->obj_bbox)
         _rsvg_push_view_box (ctx, 1., 1.);
 
-    pattern = cairo_pattern_create_radial (_rsvg_css_normalize_length (&radial->fx, ctx, 
LENGTH_DIR_HORIZONTAL),
-                                           _rsvg_css_normalize_length (&radial->fy, ctx, 
LENGTH_DIR_VERTICAL), 0.0,
-                                           _rsvg_css_normalize_length (&radial->cx, ctx, 
LENGTH_DIR_HORIZONTAL),
-                                           _rsvg_css_normalize_length (&radial->cy, ctx, 
LENGTH_DIR_VERTICAL),
-                                           _rsvg_css_normalize_length (&radial->r, ctx, LENGTH_DIR_BOTH));
+    pattern = cairo_pattern_create_radial (_rsvg_css_normalize_length (&radial->fx, ctx),
+                                           _rsvg_css_normalize_length (&radial->fy, ctx), 0.0,
+                                           _rsvg_css_normalize_length (&radial->cx, ctx),
+                                           _rsvg_css_normalize_length (&radial->cy, ctx),
+                                           _rsvg_css_normalize_length (&radial->r, ctx));
     if (radial->obj_bbox)
         _rsvg_pop_view_box (ctx);
 
@@ -198,10 +198,10 @@ _set_source_rsvg_pattern (RsvgDrawingCtx * ctx,
     if (rsvg_pattern->obj_bbox)
         _rsvg_push_view_box (ctx, 1., 1.);
 
-    patternx = _rsvg_css_normalize_length (&rsvg_pattern->x, ctx, LENGTH_DIR_HORIZONTAL);
-    patterny = _rsvg_css_normalize_length (&rsvg_pattern->y, ctx, LENGTH_DIR_VERTICAL);
-    patternw = _rsvg_css_normalize_length (&rsvg_pattern->width, ctx, LENGTH_DIR_HORIZONTAL);
-    patternh = _rsvg_css_normalize_length (&rsvg_pattern->height, ctx, LENGTH_DIR_VERTICAL);
+    patternx = _rsvg_css_normalize_length (&rsvg_pattern->x, ctx);
+    patterny = _rsvg_css_normalize_length (&rsvg_pattern->y, ctx);
+    patternw = _rsvg_css_normalize_length (&rsvg_pattern->width, ctx);
+    patternh = _rsvg_css_normalize_length (&rsvg_pattern->height, ctx);
 
     if (rsvg_pattern->obj_bbox)
         _rsvg_pop_view_box (ctx);
@@ -389,7 +389,7 @@ setup_cr_for_stroke (cairo_t *cr, RsvgDrawingCtx *ctx, RsvgState *state)
     cairo_set_line_cap (cr, (cairo_line_cap_t) state->cap);
     cairo_set_line_join (cr, (cairo_line_join_t) state->join);
     cairo_set_dash (cr, state->dash.dash, state->dash.n_dash,
-                    _rsvg_css_normalize_length (&state->dash.offset, ctx, LENGTH_DIR_BOTH));
+                    _rsvg_css_normalize_length (&state->dash.offset, ctx));
 }
 
 void
@@ -645,10 +645,10 @@ rsvg_cairo_generate_mask (cairo_t * cr, RsvgMask * self, RsvgDrawingCtx * ctx, R
     if (self->maskunits == objectBoundingBox)
         _rsvg_push_view_box (ctx, 1, 1);
 
-    sx = _rsvg_css_normalize_length (&self->x, ctx, LENGTH_DIR_HORIZONTAL);
-    sy = _rsvg_css_normalize_length (&self->y, ctx, LENGTH_DIR_VERTICAL);
-    sw = _rsvg_css_normalize_length (&self->width, ctx, LENGTH_DIR_HORIZONTAL);
-    sh = _rsvg_css_normalize_length (&self->height, ctx, LENGTH_DIR_VERTICAL);
+    sx = _rsvg_css_normalize_length (&self->x, ctx);
+    sy = _rsvg_css_normalize_length (&self->y, ctx);
+    sw = _rsvg_css_normalize_length (&self->width, ctx);
+    sh = _rsvg_css_normalize_length (&self->height, ctx);
 
     if (self->maskunits == objectBoundingBox)
         _rsvg_pop_view_box (ctx);
diff --git a/rsvg-css.c b/rsvg-css.c
index 8e108b0..2280776 100644
--- a/rsvg-css.c
+++ b/rsvg-css.c
@@ -180,9 +180,17 @@ rsvg_css_parse_raw_length (const char *str, gboolean * in,
 
 /* https://www.w3.org/TR/SVG/types.html#DataTypeLength
  * https://www.w3.org/TR/2008/REC-CSS2-20080411/syndata.html#length-units
+ *
+ * Lengths have units.  When they need to be need resolved to
+ * units in the user's coordinate system, some unit types
+ * need to know if they are horizontal/vertical/both.  For example,
+ * a some_object.width="50%" is 50% with respect to the current
+ * viewport's width.  In this case, the @dir argument is used
+ * when _rsvg_css_normalize_length() needs to know to what the
+ * length refers.
  */
 RsvgLength
-_rsvg_css_parse_length (const char *str)
+_rsvg_css_parse_length (const char *str, LengthDir dir)
 {
     RsvgLength out;
     gboolean percent, em, ex, in;
@@ -205,6 +213,8 @@ _rsvg_css_parse_length (const char *str)
     else
         out.unit = LENGTH_UNIT_DEFAULT;
 
+    out.dir = dir;
+
     return out;
 }
 
@@ -226,7 +236,7 @@ _rsvg_css_normalize_font_size (RsvgState * state, RsvgDrawingCtx * ctx)
         }
         break;
     default:
-        return _rsvg_css_normalize_length (&state->font_size, ctx, LENGTH_DIR_VERTICAL);
+        return _rsvg_css_normalize_length (&state->font_size, ctx);
         break;
     }
 
@@ -234,12 +244,12 @@ _rsvg_css_normalize_font_size (RsvgState * state, RsvgDrawingCtx * ctx)
 }
 
 double
-_rsvg_css_normalize_length (const RsvgLength * in, RsvgDrawingCtx * ctx, LengthDir dir)
+_rsvg_css_normalize_length (const RsvgLength * in, RsvgDrawingCtx * ctx)
 {
     if (in->unit == LENGTH_UNIT_DEFAULT)
         return in->length;
     else if (in->unit == LENGTH_UNIT_PERCENT) {
-        switch (dir) {
+        switch (in->dir) {
         case LENGTH_DIR_HORIZONTAL:
             return in->length * ctx->vb.rect.width;
 
@@ -257,7 +267,7 @@ _rsvg_css_normalize_length (const RsvgLength * in, RsvgDrawingCtx * ctx, LengthD
         else
             return in->length * font / 2.;
     } else if (in->unit == LENGTH_UNIT_INCH) {
-        switch (dir) {
+        switch (in->dir) {
         case LENGTH_DIR_HORIZONTAL:
             return in->length * ctx->dpi_x;
 
diff --git a/rsvg-filter.c b/rsvg-filter.c
index 73c6a33..27d7a04 100644
--- a/rsvg-filter.c
+++ b/rsvg-filter.c
@@ -126,19 +126,19 @@ filter_primitive_set_x_y_width_height_atts (RsvgFilterPrimitive *prim, RsvgPrope
     const char *value;
 
     if ((value = rsvg_property_bag_lookup (atts, "x"))) {
-        prim->x = _rsvg_css_parse_length (value);
+        prim->x = _rsvg_css_parse_length (value, LENGTH_DIR_HORIZONTAL);
         prim->x_specified = TRUE;
     }
     if ((value = rsvg_property_bag_lookup (atts, "y"))) {
-        prim->y = _rsvg_css_parse_length (value);
+        prim->y = _rsvg_css_parse_length (value, LENGTH_DIR_VERTICAL);
         prim->y_specified = TRUE;
     }
     if ((value = rsvg_property_bag_lookup (atts, "width"))) {
-        prim->width = _rsvg_css_parse_length (value);
+        prim->width = _rsvg_css_parse_length (value, LENGTH_DIR_HORIZONTAL);
         prim->width_specified = TRUE;
     }
     if ((value = rsvg_property_bag_lookup (atts, "height"))) {
-        prim->height = _rsvg_css_parse_length (value);
+        prim->height = _rsvg_css_parse_length (value, LENGTH_DIR_VERTICAL);
         prim->height_specified = TRUE;
     }
 }
@@ -161,10 +161,10 @@ rsvg_filter_primitive_get_bounds (RsvgFilterPrimitive * self, RsvgFilterContext
     otherbox.virgin = 0;
     if (ctx->filter->filterunits == objectBoundingBox)
         _rsvg_push_view_box (ctx->ctx, 1., 1.);
-    otherbox.rect.x = _rsvg_css_normalize_length (&ctx->filter->x, ctx->ctx, LENGTH_DIR_HORIZONTAL);
-    otherbox.rect.y = _rsvg_css_normalize_length (&ctx->filter->y, ctx->ctx, LENGTH_DIR_VERTICAL);
-    otherbox.rect.width = _rsvg_css_normalize_length (&ctx->filter->width, ctx->ctx, LENGTH_DIR_HORIZONTAL);
-    otherbox.rect.height = _rsvg_css_normalize_length (&ctx->filter->height, ctx->ctx, LENGTH_DIR_VERTICAL);
+    otherbox.rect.x = _rsvg_css_normalize_length (&ctx->filter->x, ctx->ctx);
+    otherbox.rect.y = _rsvg_css_normalize_length (&ctx->filter->y, ctx->ctx);
+    otherbox.rect.width = _rsvg_css_normalize_length (&ctx->filter->width, ctx->ctx);
+    otherbox.rect.height = _rsvg_css_normalize_length (&ctx->filter->height, ctx->ctx);
     if (ctx->filter->filterunits == objectBoundingBox)
         _rsvg_pop_view_box (ctx->ctx);
 
@@ -179,19 +179,19 @@ rsvg_filter_primitive_get_bounds (RsvgFilterPrimitive * self, RsvgFilterContext
             if (ctx->filter->primitiveunits == objectBoundingBox)
                 _rsvg_push_view_box (ctx->ctx, 1., 1.);
             if (self->x_specified)
-                otherbox.rect.x = _rsvg_css_normalize_length (&self->x, ctx->ctx, LENGTH_DIR_HORIZONTAL);
+                otherbox.rect.x = _rsvg_css_normalize_length (&self->x, ctx->ctx);
             else
                 otherbox.rect.x = 0;
             if (self->y_specified)
-                otherbox.rect.y = _rsvg_css_normalize_length (&self->y, ctx->ctx, LENGTH_DIR_VERTICAL);
+                otherbox.rect.y = _rsvg_css_normalize_length (&self->y, ctx->ctx);
             else
                 otherbox.rect.y = 0;
             if (self->width_specified)
-                otherbox.rect.width = _rsvg_css_normalize_length (&self->width, ctx->ctx, 
LENGTH_DIR_HORIZONTAL);
+                otherbox.rect.width = _rsvg_css_normalize_length (&self->width, ctx->ctx);
             else
                 otherbox.rect.width = ctx->ctx->vb.rect.width;
             if (self->height_specified)
-                otherbox.rect.height = _rsvg_css_normalize_length (&self->height, ctx->ctx, 
LENGTH_DIR_VERTICAL);
+                otherbox.rect.height = _rsvg_css_normalize_length (&self->height, ctx->ctx);
             else
                 otherbox.rect.height = ctx->ctx->vb.rect.height;
             if (ctx->filter->primitiveunits == objectBoundingBox)
@@ -791,13 +791,13 @@ rsvg_filter_set_args (RsvgNode * self, RsvgHandle * ctx, RsvgPropertyBag * atts)
                 filter->primitiveunits = userSpaceOnUse;
         }
         if ((value = rsvg_property_bag_lookup (atts, "x")))
-            filter->x = _rsvg_css_parse_length (value);
+            filter->x = _rsvg_css_parse_length (value, LENGTH_DIR_HORIZONTAL);
         if ((value = rsvg_property_bag_lookup (atts, "y")))
-            filter->y = _rsvg_css_parse_length (value);
+            filter->y = _rsvg_css_parse_length (value, LENGTH_DIR_VERTICAL);
         if ((value = rsvg_property_bag_lookup (atts, "width")))
-            filter->width = _rsvg_css_parse_length (value);
+            filter->width = _rsvg_css_parse_length (value, LENGTH_DIR_HORIZONTAL);
         if ((value = rsvg_property_bag_lookup (atts, "height")))
-            filter->height = _rsvg_css_parse_length (value);
+            filter->height = _rsvg_css_parse_length (value, LENGTH_DIR_VERTICAL);
         if ((value = rsvg_property_bag_lookup (atts, "id")))
             rsvg_defs_register_name (ctx->priv->defs, value, &filter->super);
     }
@@ -817,10 +817,10 @@ rsvg_new_filter (void)
     _rsvg_node_init (&filter->super, RSVG_NODE_TYPE_FILTER);
     filter->filterunits = objectBoundingBox;
     filter->primitiveunits = userSpaceOnUse;
-    filter->x = _rsvg_css_parse_length ("-10%");
-    filter->y = _rsvg_css_parse_length ("-10%");
-    filter->width = _rsvg_css_parse_length ("120%");
-    filter->height = _rsvg_css_parse_length ("120%");
+    filter->x = _rsvg_css_parse_length ("-10%", LENGTH_DIR_HORIZONTAL);
+    filter->y = _rsvg_css_parse_length ("-10%", LENGTH_DIR_VERTICAL);
+    filter->width = _rsvg_css_parse_length ("120%", LENGTH_DIR_HORIZONTAL);
+    filter->height = _rsvg_css_parse_length ("120%", LENGTH_DIR_VERTICAL);
     filter->super.set_atts = rsvg_filter_set_args;
     return (RsvgNode *) filter;
 }
@@ -2019,8 +2019,8 @@ rsvg_filter_primitive_offset_render (RsvgFilterPrimitive * self, RsvgFilterConte
 
     output_pixels = cairo_image_surface_get_data (output);
 
-    dx = _rsvg_css_normalize_length (&upself->dx, ctx->ctx, LENGTH_DIR_HORIZONTAL);
-    dy = _rsvg_css_normalize_length (&upself->dy, ctx->ctx, LENGTH_DIR_VERTICAL);
+    dx = _rsvg_css_normalize_length (&upself->dx, ctx->ctx);
+    dy = _rsvg_css_normalize_length (&upself->dy, ctx->ctx);
 
     ox = ctx->paffine.xx * dx + ctx->paffine.xy * dy;
     oy = ctx->paffine.yx * dx + ctx->paffine.yy * dy;
@@ -2066,9 +2066,9 @@ rsvg_filter_primitive_offset_set_atts (RsvgNode * self, RsvgHandle * ctx, RsvgPr
         filter_primitive_set_x_y_width_height_atts ((RsvgFilterPrimitive *) filter, atts);
 
         if ((value = rsvg_property_bag_lookup (atts, "dx")))
-            filter->dx = _rsvg_css_parse_length (value);
+            filter->dx = _rsvg_css_parse_length (value, LENGTH_DIR_HORIZONTAL);
         if ((value = rsvg_property_bag_lookup (atts, "dy")))
-            filter->dy = _rsvg_css_parse_length (value);
+            filter->dy = _rsvg_css_parse_length (value, LENGTH_DIR_VERTICAL);
         if ((value = rsvg_property_bag_lookup (atts, "id")))
             rsvg_defs_register_name (ctx->priv->defs, value, &filter->super.super);
     }
@@ -2082,8 +2082,8 @@ rsvg_new_filter_primitive_offset (void)
     _rsvg_node_init (&filter->super.super, RSVG_NODE_TYPE_FILTER_PRIMITIVE_OFFSET);
     filter->super.in = g_string_new ("none");
     filter->super.result = g_string_new ("none");
-    filter->dy = _rsvg_css_parse_length ("0");
-    filter->dx = _rsvg_css_parse_length ("0");
+    filter->dx = _rsvg_css_parse_length ("0", LENGTH_DIR_HORIZONTAL);
+    filter->dy = _rsvg_css_parse_length ("0", LENGTH_DIR_VERTICAL);
     filter->super.render = rsvg_filter_primitive_offset_render;
     filter->super.super.free = rsvg_filter_primitive_free;
     filter->super.super.set_atts = rsvg_filter_primitive_offset_set_atts;
@@ -4284,9 +4284,9 @@ get_light_direction (RsvgNodeLightSource * source, gdouble x1, gdouble y1, gdoub
             double x, y;
             x = affine->xx * x1 + affine->xy * y1 + affine->x0;
             y = affine->yx * x1 + affine->yy * y1 + affine->y0;
-            output.x = _rsvg_css_normalize_length (&source->x, ctx, LENGTH_DIR_HORIZONTAL) - x;
-            output.y = _rsvg_css_normalize_length (&source->y, ctx, LENGTH_DIR_VERTICAL) - y;
-            output.z = _rsvg_css_normalize_length (&source->z, ctx, LENGTH_DIR_BOTH) - z;
+            output.x = _rsvg_css_normalize_length (&source->x, ctx) - x;
+            output.y = _rsvg_css_normalize_length (&source->y, ctx) - y;
+            output.z = _rsvg_css_normalize_length (&source->z, ctx) - z;
             output = normalise (output);
         }
         break;
@@ -4307,12 +4307,12 @@ get_light_color (RsvgNodeLightSource * source, vector3 color,
     if (source->type != SPOTLIGHT)
         return color;
 
-    sx = _rsvg_css_normalize_length (&source->x, ctx, LENGTH_DIR_HORIZONTAL);
-    sy = _rsvg_css_normalize_length (&source->y, ctx, LENGTH_DIR_VERTICAL);
-    sz = _rsvg_css_normalize_length (&source->z, ctx, LENGTH_DIR_BOTH);
-    spx = _rsvg_css_normalize_length (&source->pointsAtX, ctx, LENGTH_DIR_HORIZONTAL);
-    spy = _rsvg_css_normalize_length (&source->pointsAtY, ctx, LENGTH_DIR_VERTICAL);
-    spz = _rsvg_css_normalize_length (&source->pointsAtZ, ctx, LENGTH_DIR_BOTH);
+    sx = _rsvg_css_normalize_length (&source->x, ctx);
+    sy = _rsvg_css_normalize_length (&source->y, ctx);
+    sz = _rsvg_css_normalize_length (&source->z, ctx);
+    spx = _rsvg_css_normalize_length (&source->pointsAtX, ctx);
+    spy = _rsvg_css_normalize_length (&source->pointsAtY, ctx);
+    spz = _rsvg_css_normalize_length (&source->pointsAtZ, ctx);
 
     x = affine->xx * x1 + affine->xy * y1 + affine->x0;
     y = affine->yx * x1 + affine->yy * y1 + affine->y0;
@@ -4363,17 +4363,17 @@ rsvg_node_light_source_set_atts (RsvgNode * self,
         if ((value = rsvg_property_bag_lookup (atts, "limitingConeAngle")))
             data->limitingconeAngle = rsvg_css_parse_angle (value) / 180.0 * M_PI;
         if ((value = rsvg_property_bag_lookup (atts, "x")))
-            data->x = data->pointsAtX = _rsvg_css_parse_length (value);
+            data->x = data->pointsAtX = _rsvg_css_parse_length (value, LENGTH_DIR_HORIZONTAL);
         if ((value = rsvg_property_bag_lookup (atts, "y")))
-            data->y = data->pointsAtX = _rsvg_css_parse_length (value);
+            data->y = data->pointsAtX = _rsvg_css_parse_length (value, LENGTH_DIR_VERTICAL);
         if ((value = rsvg_property_bag_lookup (atts, "z")))
-            data->z = data->pointsAtX = _rsvg_css_parse_length (value);
+            data->z = data->pointsAtX = _rsvg_css_parse_length (value, LENGTH_DIR_BOTH);
         if ((value = rsvg_property_bag_lookup (atts, "pointsAtX")))
-            data->pointsAtX = _rsvg_css_parse_length (value);
+            data->pointsAtX = _rsvg_css_parse_length (value, LENGTH_DIR_HORIZONTAL);
         if ((value = rsvg_property_bag_lookup (atts, "pointsAtY")))
-            data->pointsAtY = _rsvg_css_parse_length (value);
+            data->pointsAtY = _rsvg_css_parse_length (value, LENGTH_DIR_VERTICAL);
         if ((value = rsvg_property_bag_lookup (atts, "pointsAtZ")))
-            data->pointsAtZ = _rsvg_css_parse_length (value);
+            data->pointsAtZ = _rsvg_css_parse_length (value, LENGTH_DIR_BOTH);
         if ((value = rsvg_property_bag_lookup (atts, "specularExponent")))
             data->specularExponent = g_ascii_strtod (value, NULL);
     }
diff --git a/rsvg-image.c b/rsvg-image.c
index 7f9289c..595acdd 100644
--- a/rsvg-image.c
+++ b/rsvg-image.c
@@ -174,10 +174,10 @@ rsvg_node_image_draw (RsvgNode * self, RsvgDrawingCtx * ctx, int dominate)
     if (surface == NULL)
         return;
 
-    x = _rsvg_css_normalize_length (&z->x, ctx, LENGTH_DIR_HORIZONTAL);
-    y = _rsvg_css_normalize_length (&z->y, ctx, LENGTH_DIR_VERTICAL);
-    w = _rsvg_css_normalize_length (&z->w, ctx, LENGTH_DIR_HORIZONTAL);
-    h = _rsvg_css_normalize_length (&z->h, ctx, LENGTH_DIR_VERTICAL);
+    x = _rsvg_css_normalize_length (&z->x, ctx);
+    y = _rsvg_css_normalize_length (&z->y, ctx);
+    w = _rsvg_css_normalize_length (&z->w, ctx);
+    h = _rsvg_css_normalize_length (&z->h, ctx);
 
     rsvg_state_reinherit_top (ctx, z->super.state, dominate);
 
@@ -205,13 +205,13 @@ rsvg_node_image_set_atts (RsvgNode * self, RsvgHandle * ctx, RsvgPropertyBag * a
 
     if (rsvg_property_bag_size (atts)) {
         if ((value = rsvg_property_bag_lookup (atts, "x")))
-            image->x = _rsvg_css_parse_length (value);
+            image->x = _rsvg_css_parse_length (value, LENGTH_DIR_HORIZONTAL);
         if ((value = rsvg_property_bag_lookup (atts, "y")))
-            image->y = _rsvg_css_parse_length (value);
+            image->y = _rsvg_css_parse_length (value, LENGTH_DIR_VERTICAL);
         if ((value = rsvg_property_bag_lookup (atts, "width")))
-            image->w = _rsvg_css_parse_length (value);
+            image->w = _rsvg_css_parse_length (value, LENGTH_DIR_HORIZONTAL);
         if ((value = rsvg_property_bag_lookup (atts, "height")))
-            image->h = _rsvg_css_parse_length (value);
+            image->h = _rsvg_css_parse_length (value, LENGTH_DIR_VERTICAL);
         /* path is used by some older adobe illustrator versions */
         if ((value = rsvg_property_bag_lookup (atts, "path"))
             || (value = rsvg_property_bag_lookup (atts, "xlink:href"))) {
@@ -247,7 +247,7 @@ rsvg_new_image (void)
     g_assert (image->super.state);
     image->surface = NULL;
     image->preserve_aspect_ratio = RSVG_ASPECT_RATIO_XMID_YMID;
-    image->x = image->y = image->w = image->h = _rsvg_css_parse_length ("0");
+    image->x = image->y = image->w = image->h = _rsvg_css_parse_length ("0", LENGTH_DIR_BOTH);
     image->super.free = rsvg_node_image_free;
     image->super.draw = rsvg_node_image_draw;
     image->super.set_atts = rsvg_node_image_set_atts;
diff --git a/rsvg-marker.c b/rsvg-marker.c
index 62d4e70..af93107 100644
--- a/rsvg-marker.c
+++ b/rsvg-marker.c
@@ -69,13 +69,13 @@ rsvg_node_marker_set_atts (RsvgNode * self, RsvgHandle * ctx, RsvgPropertyBag *
         if ((value = rsvg_property_bag_lookup (atts, "viewBox")))
             marker->vbox = rsvg_css_parse_vbox (value);
         if ((value = rsvg_property_bag_lookup (atts, "refX")))
-            marker->refX = _rsvg_css_parse_length (value);
+            marker->refX = _rsvg_css_parse_length (value, LENGTH_DIR_HORIZONTAL);
         if ((value = rsvg_property_bag_lookup (atts, "refY")))
-            marker->refY = _rsvg_css_parse_length (value);
+            marker->refY = _rsvg_css_parse_length (value, LENGTH_DIR_VERTICAL);
         if ((value = rsvg_property_bag_lookup (atts, "markerWidth")))
-            marker->width = _rsvg_css_parse_length (value);
+            marker->width = _rsvg_css_parse_length (value, LENGTH_DIR_HORIZONTAL);
         if ((value = rsvg_property_bag_lookup (atts, "markerHeight")))
-            marker->height = _rsvg_css_parse_length (value);
+            marker->height = _rsvg_css_parse_length (value, LENGTH_DIR_VERTICAL);
         if ((value = rsvg_property_bag_lookup (atts, "orient"))) {
             if (!strcmp (value, "auto"))
                 marker->orientAuto = TRUE;
@@ -103,8 +103,8 @@ rsvg_new_marker (void)
     marker->orient = 0;
     marker->orientAuto = FALSE;
     marker->preserve_aspect_ratio = RSVG_ASPECT_RATIO_XMID_YMID;
-    marker->refX = marker->refY = _rsvg_css_parse_length ("0");
-    marker->width = marker->height = _rsvg_css_parse_length ("3");
+    marker->refX = marker->refY = _rsvg_css_parse_length ("0", LENGTH_DIR_BOTH);
+    marker->width = marker->height = _rsvg_css_parse_length ("3", LENGTH_DIR_BOTH);
     marker->bbox = TRUE;
     marker->vbox.active = FALSE;
     marker->super.set_atts = rsvg_node_marker_set_atts;
@@ -143,8 +143,8 @@ rsvg_marker_render (const char * marker_name, gdouble xpos, gdouble ypos, gdoubl
 
     if (self->vbox.active) {
         double w, h, x, y;
-        w = _rsvg_css_normalize_length (&self->width, ctx, LENGTH_DIR_HORIZONTAL);
-        h = _rsvg_css_normalize_length (&self->height, ctx, LENGTH_DIR_VERTICAL);
+        w = _rsvg_css_normalize_length (&self->width, ctx);
+        h = _rsvg_css_normalize_length (&self->height, ctx);
         x = 0;
         y = 0;
 
@@ -160,8 +160,8 @@ rsvg_marker_render (const char * marker_name, gdouble xpos, gdouble ypos, gdoubl
     }
 
     cairo_matrix_init_translate (&taffine,
-                                 -_rsvg_css_normalize_length (&self->refX, ctx, LENGTH_DIR_HORIZONTAL),
-                                 -_rsvg_css_normalize_length (&self->refY, ctx, LENGTH_DIR_VERTICAL));
+                                 -_rsvg_css_normalize_length (&self->refX, ctx),
+                                 -_rsvg_css_normalize_length (&self->refY, ctx));
     cairo_matrix_multiply (&affine, &taffine, &affine);
 
     rsvg_state_push (ctx);
@@ -183,8 +183,8 @@ rsvg_marker_render (const char * marker_name, gdouble xpos, gdouble ypos, gdoubl
                                     self->vbox.rect.width, self->vbox.rect.height);
         else
             rsvg_add_clipping_rect (ctx, 0, 0,
-                                    _rsvg_css_normalize_length (&self->width, ctx, LENGTH_DIR_HORIZONTAL),
-                                    _rsvg_css_normalize_length (&self->height, ctx, LENGTH_DIR_VERTICAL));
+                                    _rsvg_css_normalize_length (&self->width, ctx),
+                                    _rsvg_css_normalize_length (&self->height, ctx));
     }
 
     for (i = 0; i < self->super.children->len; i++) {
diff --git a/rsvg-mask.c b/rsvg-mask.c
index 44dd100..9ef4893 100644
--- a/rsvg-mask.c
+++ b/rsvg-mask.c
@@ -50,13 +50,13 @@ rsvg_mask_set_atts (RsvgNode * self, RsvgHandle * ctx, RsvgPropertyBag * atts)
                 mask->contentunits = userSpaceOnUse;
         }
         if ((value = rsvg_property_bag_lookup (atts, "x")))
-            mask->x = _rsvg_css_parse_length (value);
+            mask->x = _rsvg_css_parse_length (value, LENGTH_DIR_HORIZONTAL);
         if ((value = rsvg_property_bag_lookup (atts, "y")))
-            mask->y = _rsvg_css_parse_length (value);
+            mask->y = _rsvg_css_parse_length (value, LENGTH_DIR_VERTICAL);
         if ((value = rsvg_property_bag_lookup (atts, "width")))
-            mask->width = _rsvg_css_parse_length (value);
+            mask->width = _rsvg_css_parse_length (value, LENGTH_DIR_HORIZONTAL);
         if ((value = rsvg_property_bag_lookup (atts, "height")))
-            mask->height = _rsvg_css_parse_length (value);
+            mask->height = _rsvg_css_parse_length (value, LENGTH_DIR_VERTICAL);
         if ((value = rsvg_property_bag_lookup (atts, "id"))) {
             id = value;
             rsvg_defs_register_name (ctx->priv->defs, id, &mask->super);
@@ -77,10 +77,10 @@ rsvg_new_mask (void)
     _rsvg_node_init (&mask->super, RSVG_NODE_TYPE_MASK);
     mask->maskunits = objectBoundingBox;
     mask->contentunits = userSpaceOnUse;
-    mask->x = _rsvg_css_parse_length ("0");
-    mask->y = _rsvg_css_parse_length ("0");
-    mask->width = _rsvg_css_parse_length ("1");
-    mask->height = _rsvg_css_parse_length ("1");
+    mask->x = _rsvg_css_parse_length ("0", LENGTH_DIR_HORIZONTAL);
+    mask->y = _rsvg_css_parse_length ("0", LENGTH_DIR_VERTICAL);
+    mask->width = _rsvg_css_parse_length ("1", LENGTH_DIR_HORIZONTAL);
+    mask->height = _rsvg_css_parse_length ("1", LENGTH_DIR_VERTICAL);
     mask->super.set_atts = rsvg_mask_set_atts;
     return &mask->super;
 }
diff --git a/rsvg-paint-server.c b/rsvg-paint-server.c
index 3519467..76b678a 100644
--- a/rsvg-paint-server.c
+++ b/rsvg-paint-server.c
@@ -160,7 +160,7 @@ rsvg_stop_set_atts (RsvgNode * self, RsvgHandle * ctx, RsvgPropertyBag * atts)
     if (rsvg_property_bag_size (atts)) {
         if ((value = rsvg_property_bag_lookup (atts, "offset"))) {
             /* either a number [0,1] or a percentage */
-            RsvgLength length = _rsvg_css_parse_length (value);
+            RsvgLength length = _rsvg_css_parse_length (value, LENGTH_DIR_BOTH);
             offset = _rsvg_css_hand_normalize_length (&length, rsvg_dpi_percentage (ctx), 1., 0.);
 
             if (offset < 0.)
@@ -208,19 +208,19 @@ rsvg_linear_gradient_set_atts (RsvgNode * self, RsvgHandle * ctx, RsvgPropertyBa
         if ((value = rsvg_property_bag_lookup (atts, "id")))
             rsvg_defs_register_name (ctx->priv->defs, value, self);
         if ((value = rsvg_property_bag_lookup (atts, "x1"))) {
-            grad->x1 = _rsvg_css_parse_length (value);
+            grad->x1 = _rsvg_css_parse_length (value, LENGTH_DIR_HORIZONTAL);
             grad->hasx1 = TRUE;
         }
         if ((value = rsvg_property_bag_lookup (atts, "y1"))) {
-            grad->y1 = _rsvg_css_parse_length (value);
+            grad->y1 = _rsvg_css_parse_length (value, LENGTH_DIR_VERTICAL);
             grad->hasy1 = TRUE;
         }
         if ((value = rsvg_property_bag_lookup (atts, "x2"))) {
-            grad->x2 = _rsvg_css_parse_length (value);
+            grad->x2 = _rsvg_css_parse_length (value, LENGTH_DIR_HORIZONTAL);
             grad->hasx2 = TRUE;
         }
         if ((value = rsvg_property_bag_lookup (atts, "y2"))) {
-            grad->y2 = _rsvg_css_parse_length (value);
+            grad->y2 = _rsvg_css_parse_length (value, LENGTH_DIR_VERTICAL);
             grad->hasy2 = TRUE;
         }
         if ((value = rsvg_property_bag_lookup (atts, "spreadMethod"))) {
@@ -268,8 +268,9 @@ rsvg_new_linear_gradient (void)
     _rsvg_node_init (&grad->super, RSVG_NODE_TYPE_LINEAR_GRADIENT);
     cairo_matrix_init_identity (&grad->affine);
     grad->has_current_color = FALSE;
-    grad->x1 = grad->y1 = grad->y2 = _rsvg_css_parse_length ("0");
-    grad->x2 = _rsvg_css_parse_length ("1");
+    grad->x1 = _rsvg_css_parse_length ("0", LENGTH_DIR_HORIZONTAL);
+    grad->y1 = grad->y2 = _rsvg_css_parse_length ("0", LENGTH_DIR_VERTICAL);
+    grad->x2 = _rsvg_css_parse_length ("1", LENGTH_DIR_HORIZONTAL);
     grad->fallback = NULL;
     grad->obj_bbox = TRUE;
     grad->spread = CAIRO_EXTEND_PAD;
@@ -290,27 +291,27 @@ rsvg_radial_gradient_set_atts (RsvgNode * self, RsvgHandle * ctx, RsvgPropertyBa
         if ((value = rsvg_property_bag_lookup (atts, "id")))
             rsvg_defs_register_name (ctx->priv->defs, value, self);
         if ((value = rsvg_property_bag_lookup (atts, "cx"))) {
-            grad->cx = _rsvg_css_parse_length (value);
+            grad->cx = _rsvg_css_parse_length (value, LENGTH_DIR_HORIZONTAL);
             grad->hascx = TRUE;
             if (!grad->hasfx)
                 grad->fx = grad->cx;
         }
         if ((value = rsvg_property_bag_lookup (atts, "cy"))) {
-            grad->cy = _rsvg_css_parse_length (value);
+            grad->cy = _rsvg_css_parse_length (value, LENGTH_DIR_VERTICAL);
             grad->hascy = TRUE;
             if (!grad->hasfy)
                 grad->fy = grad->cy;
         }
         if ((value = rsvg_property_bag_lookup (atts, "r"))) {
-            grad->r = _rsvg_css_parse_length (value);
+            grad->r = _rsvg_css_parse_length (value, LENGTH_DIR_BOTH);
             grad->hasr = TRUE;
         }
         if ((value = rsvg_property_bag_lookup (atts, "fx"))) {
-            grad->fx = _rsvg_css_parse_length (value);
+            grad->fx = _rsvg_css_parse_length (value, LENGTH_DIR_HORIZONTAL);
             grad->hasfx = TRUE;
         }
         if ((value = rsvg_property_bag_lookup (atts, "fy"))) {
-            grad->fy = _rsvg_css_parse_length (value);
+            grad->fy = _rsvg_css_parse_length (value, LENGTH_DIR_VERTICAL);
             grad->hasfy = TRUE;
         }
         g_free (grad->fallback);
@@ -361,7 +362,7 @@ rsvg_new_radial_gradient (void)
     grad->obj_bbox = TRUE;
     grad->spread = CAIRO_EXTEND_PAD;
     grad->fallback = NULL;
-    grad->cx = grad->cy = grad->r = grad->fx = grad->fy = _rsvg_css_parse_length ("0.5");
+    grad->cx = grad->cy = grad->r = grad->fx = grad->fy = _rsvg_css_parse_length ("0.5", LENGTH_DIR_BOTH);
     grad->super.free = rsvg_radial_gradient_free;
     grad->super.set_atts = rsvg_radial_gradient_set_atts;
     grad->hascx = grad->hascy = grad->hasfx = grad->hasfy = grad->hasr = grad->hasbbox =
@@ -383,19 +384,19 @@ rsvg_pattern_set_atts (RsvgNode * self, RsvgHandle * ctx, RsvgPropertyBag * atts
             pattern->hasvbox = TRUE;
         }
         if ((value = rsvg_property_bag_lookup (atts, "x"))) {
-            pattern->x = _rsvg_css_parse_length (value);
+            pattern->x = _rsvg_css_parse_length (value, LENGTH_DIR_HORIZONTAL);
             pattern->hasx = TRUE;
         }
         if ((value = rsvg_property_bag_lookup (atts, "y"))) {
-            pattern->y = _rsvg_css_parse_length (value);
+            pattern->y = _rsvg_css_parse_length (value, LENGTH_DIR_VERTICAL);
             pattern->hasy = TRUE;
         }
         if ((value = rsvg_property_bag_lookup (atts, "width"))) {
-            pattern->width = _rsvg_css_parse_length (value);
+            pattern->width = _rsvg_css_parse_length (value, LENGTH_DIR_HORIZONTAL);
             pattern->haswidth = TRUE;
         }
         if ((value = rsvg_property_bag_lookup (atts, "height"))) {
-            pattern->height = _rsvg_css_parse_length (value);
+            pattern->height = _rsvg_css_parse_length (value, LENGTH_DIR_VERTICAL);
             pattern->hasheight = TRUE;
         }
         g_free (pattern->fallback);
@@ -442,7 +443,7 @@ rsvg_new_pattern (void)
     cairo_matrix_init_identity (&pattern->affine);
     pattern->obj_bbox = TRUE;
     pattern->obj_cbbox = FALSE;
-    pattern->x = pattern->y = pattern->width = pattern->height = _rsvg_css_parse_length ("0");
+    pattern->x = pattern->y = pattern->width = pattern->height = _rsvg_css_parse_length ("0", 
LENGTH_DIR_BOTH);
     pattern->fallback = NULL;
     pattern->preserve_aspect_ratio = RSVG_ASPECT_RATIO_XMID_YMID;
     pattern->vbox.active = FALSE;
diff --git a/rsvg-private.h b/rsvg-private.h
index 078f696..68a01fb 100644
--- a/rsvg-private.h
+++ b/rsvg-private.h
@@ -253,11 +253,6 @@ typedef enum {
     LENGTH_UNIT_RELATIVE_SMALLER
 } LengthUnit;
 
-typedef struct {
-    double length;
-    LengthUnit unit;
-} RsvgLength;
-
 typedef enum {
     LENGTH_DIR_HORIZONTAL,
     LENGTH_DIR_VERTICAL,
@@ -265,6 +260,12 @@ typedef enum {
 } LengthDir;
 
 typedef struct {
+    double length;
+    LengthUnit unit;
+    LengthDir dir;
+} RsvgLength;
+
+typedef struct {
     cairo_rectangle_t rect;
     cairo_matrix_t affine;
     gboolean virgin;
@@ -418,7 +419,7 @@ void rsvg_bbox_insert   (RsvgBbox * dst, RsvgBbox * src);
 G_GNUC_INTERNAL
 void rsvg_bbox_clip     (RsvgBbox * dst, RsvgBbox * src);
 G_GNUC_INTERNAL
-double _rsvg_css_normalize_length       (const RsvgLength * in, RsvgDrawingCtx * ctx, LengthDir dir);
+double _rsvg_css_normalize_length       (const RsvgLength * in, RsvgDrawingCtx * ctx);
 G_GNUC_INTERNAL
 double _rsvg_css_hand_normalize_length  (const RsvgLength * in, gdouble pixels_per_inch,
                                          gdouble width_or_height, gdouble font_size);
@@ -426,7 +427,7 @@ double _rsvg_css_normalize_font_size    (RsvgState * state, RsvgDrawingCtx * ctx
 G_GNUC_INTERNAL
 double _rsvg_css_accumulate_baseline_shift (RsvgState * state, RsvgDrawingCtx * ctx);
 G_GNUC_INTERNAL
-RsvgLength _rsvg_css_parse_length (const char *str);
+RsvgLength _rsvg_css_parse_length (const char *str, LengthDir dir);
 G_GNUC_INTERNAL
 void _rsvg_push_view_box    (RsvgDrawingCtx * ctx, double w, double h);
 G_GNUC_INTERNAL
diff --git a/rsvg-shapes.c b/rsvg-shapes.c
index 0ac27c1..22a28b0 100644
--- a/rsvg-shapes.c
+++ b/rsvg-shapes.c
@@ -257,13 +257,13 @@ _rsvg_node_line_set_atts (RsvgNode * self, RsvgHandle * ctx, RsvgPropertyBag * a
 
     if (rsvg_property_bag_size (atts)) {
         if ((value = rsvg_property_bag_lookup (atts, "x1")))
-            line->x1 = _rsvg_css_parse_length (value);
+            line->x1 = _rsvg_css_parse_length (value, LENGTH_DIR_HORIZONTAL);
         if ((value = rsvg_property_bag_lookup (atts, "y1")))
-            line->y1 = _rsvg_css_parse_length (value);
+            line->y1 = _rsvg_css_parse_length (value, LENGTH_DIR_VERTICAL);
         if ((value = rsvg_property_bag_lookup (atts, "x2")))
-            line->x2 = _rsvg_css_parse_length (value);
+            line->x2 = _rsvg_css_parse_length (value, LENGTH_DIR_HORIZONTAL);
         if ((value = rsvg_property_bag_lookup (atts, "y2")))
-            line->y2 = _rsvg_css_parse_length (value);
+            line->y2 = _rsvg_css_parse_length (value, LENGTH_DIR_VERTICAL);
         if ((value = rsvg_property_bag_lookup (atts, "class")))
             klazz = value;
         if ((value = rsvg_property_bag_lookup (atts, "id"))) {
@@ -284,10 +284,10 @@ _rsvg_node_line_draw (RsvgNode * overself, RsvgDrawingCtx * ctx, int dominate)
 
     builder = rsvg_path_builder_new ();
 
-    x1 = _rsvg_css_normalize_length (&self->x1, ctx, LENGTH_DIR_HORIZONTAL);
-    y1 = _rsvg_css_normalize_length (&self->y1, ctx, LENGTH_DIR_VERTICAL);
-    x2 = _rsvg_css_normalize_length (&self->x2, ctx, LENGTH_DIR_HORIZONTAL);
-    y2 = _rsvg_css_normalize_length (&self->y2, ctx, LENGTH_DIR_VERTICAL);
+    x1 = _rsvg_css_normalize_length (&self->x1, ctx);
+    y1 = _rsvg_css_normalize_length (&self->y1, ctx);
+    x2 = _rsvg_css_normalize_length (&self->x2, ctx);
+    y2 = _rsvg_css_normalize_length (&self->y2, ctx);
 
     rsvg_path_builder_move_to (builder, x1, y1);
     rsvg_path_builder_line_to (builder, x2, y2);
@@ -307,7 +307,7 @@ rsvg_new_line (void)
     _rsvg_node_init (&line->super, RSVG_NODE_TYPE_LINE);
     line->super.draw = _rsvg_node_line_draw;
     line->super.set_atts = _rsvg_node_line_set_atts;
-    line->x1 = line->x2 = line->y1 = line->y2 = _rsvg_css_parse_length ("0");
+    line->x1 = line->x2 = line->y1 = line->y2 = _rsvg_css_parse_length ("0", LENGTH_DIR_BOTH);
     return &line->super;
 }
 
@@ -328,19 +328,19 @@ _rsvg_node_rect_set_atts (RsvgNode * self, RsvgHandle * ctx, RsvgPropertyBag * a
     /* FIXME: negative w/h/rx/ry is an error, per http://www.w3.org/TR/SVG11/shapes.html#RectElement */
     if (rsvg_property_bag_size (atts)) {
         if ((value = rsvg_property_bag_lookup (atts, "x")))
-            rect->x = _rsvg_css_parse_length (value);
+            rect->x = _rsvg_css_parse_length (value, LENGTH_DIR_HORIZONTAL);
         if ((value = rsvg_property_bag_lookup (atts, "y")))
-            rect->y = _rsvg_css_parse_length (value);
+            rect->y = _rsvg_css_parse_length (value, LENGTH_DIR_VERTICAL);
         if ((value = rsvg_property_bag_lookup (atts, "width")))
-            rect->w = _rsvg_css_parse_length (value);
+            rect->w = _rsvg_css_parse_length (value, LENGTH_DIR_HORIZONTAL);
         if ((value = rsvg_property_bag_lookup (atts, "height")))
-            rect->h = _rsvg_css_parse_length (value);
+            rect->h = _rsvg_css_parse_length (value, LENGTH_DIR_VERTICAL);
         if ((value = rsvg_property_bag_lookup (atts, "rx"))) {
-            rect->rx = _rsvg_css_parse_length (value);
+            rect->rx = _rsvg_css_parse_length (value, LENGTH_DIR_HORIZONTAL);
             rect->got_rx = TRUE;
         }
         if ((value = rsvg_property_bag_lookup (atts, "ry"))) {
-            rect->ry = _rsvg_css_parse_length (value);
+            rect->ry = _rsvg_css_parse_length (value, LENGTH_DIR_VERTICAL);
             rect->got_ry = TRUE;
         }
         if ((value = rsvg_property_bag_lookup (atts, "class")))
@@ -362,16 +362,16 @@ _rsvg_node_rect_draw (RsvgNode * self, RsvgDrawingCtx * ctx, int dominate)
     RsvgPathBuilder *builder;
     RsvgNodeRect *rect = (RsvgNodeRect *) self;
 
-    x = _rsvg_css_normalize_length (&rect->x, ctx, LENGTH_DIR_HORIZONTAL);
-    y = _rsvg_css_normalize_length (&rect->y, ctx, LENGTH_DIR_VERTICAL);
+    x = _rsvg_css_normalize_length (&rect->x, ctx);
+    y = _rsvg_css_normalize_length (&rect->y, ctx);
 
     /* FIXME: negative w/h/rx/ry is an error, per http://www.w3.org/TR/SVG11/shapes.html#RectElement
      * For now we'll just take the absolute value.
      */
-    w = fabs (_rsvg_css_normalize_length (&rect->w, ctx, LENGTH_DIR_HORIZONTAL));
-    h = fabs (_rsvg_css_normalize_length (&rect->h, ctx, LENGTH_DIR_VERTICAL));
-    rx = fabs (_rsvg_css_normalize_length (&rect->rx, ctx, LENGTH_DIR_HORIZONTAL));
-    ry = fabs (_rsvg_css_normalize_length (&rect->ry, ctx, LENGTH_DIR_VERTICAL));
+    w = fabs (_rsvg_css_normalize_length (&rect->w, ctx));
+    h = fabs (_rsvg_css_normalize_length (&rect->h, ctx));
+    rx = fabs (_rsvg_css_normalize_length (&rect->rx, ctx));
+    ry = fabs (_rsvg_css_normalize_length (&rect->ry, ctx));
 
     if (w == 0. || h == 0.)
         return;
@@ -501,7 +501,7 @@ rsvg_new_rect (void)
     _rsvg_node_init (&rect->super, RSVG_NODE_TYPE_RECT);
     rect->super.draw = _rsvg_node_rect_draw;
     rect->super.set_atts = _rsvg_node_rect_set_atts;
-    rect->x = rect->y = rect->w = rect->h = rect->rx = rect->ry = _rsvg_css_parse_length ("0");
+    rect->x = rect->y = rect->w = rect->h = rect->rx = rect->ry = _rsvg_css_parse_length ("0", 
LENGTH_DIR_BOTH);
     rect->got_rx = rect->got_ry = FALSE;
     return &rect->super;
 }
@@ -521,11 +521,11 @@ _rsvg_node_circle_set_atts (RsvgNode * self, RsvgHandle * ctx, RsvgPropertyBag *
 
     if (rsvg_property_bag_size (atts)) {
         if ((value = rsvg_property_bag_lookup (atts, "cx")))
-            circle->cx = _rsvg_css_parse_length (value);
+            circle->cx = _rsvg_css_parse_length (value, LENGTH_DIR_HORIZONTAL);
         if ((value = rsvg_property_bag_lookup (atts, "cy")))
-            circle->cy = _rsvg_css_parse_length (value);
+            circle->cy = _rsvg_css_parse_length (value, LENGTH_DIR_VERTICAL);
         if ((value = rsvg_property_bag_lookup (atts, "r")))
-            circle->r = _rsvg_css_parse_length (value);
+            circle->r = _rsvg_css_parse_length (value, LENGTH_DIR_BOTH);
         if ((value = rsvg_property_bag_lookup (atts, "class")))
             klazz = value;
         if ((value = rsvg_property_bag_lookup (atts, "id"))) {
@@ -544,9 +544,9 @@ _rsvg_node_circle_draw (RsvgNode * self, RsvgDrawingCtx * ctx, int dominate)
     double cx, cy, r;
     RsvgPathBuilder *builder;
 
-    cx = _rsvg_css_normalize_length (&circle->cx, ctx, LENGTH_DIR_HORIZONTAL);
-    cy = _rsvg_css_normalize_length (&circle->cy, ctx, LENGTH_DIR_VERTICAL);
-    r = _rsvg_css_normalize_length (&circle->r, ctx, LENGTH_DIR_BOTH);
+    cx = _rsvg_css_normalize_length (&circle->cx, ctx);
+    cy = _rsvg_css_normalize_length (&circle->cy, ctx);
+    r = _rsvg_css_normalize_length (&circle->r, ctx);
 
     if (r <= 0)
         return;
@@ -594,7 +594,7 @@ rsvg_new_circle (void)
     _rsvg_node_init (&circle->super, RSVG_NODE_TYPE_CIRCLE);
     circle->super.draw = _rsvg_node_circle_draw;
     circle->super.set_atts = _rsvg_node_circle_set_atts;
-    circle->cx = circle->cy = circle->r = _rsvg_css_parse_length ("0");
+    circle->cx = circle->cy = circle->r = _rsvg_css_parse_length ("0", LENGTH_DIR_BOTH);
     return &circle->super;
 }
 
@@ -613,13 +613,13 @@ _rsvg_node_ellipse_set_atts (RsvgNode * self, RsvgHandle * ctx, RsvgPropertyBag
 
     if (rsvg_property_bag_size (atts)) {
         if ((value = rsvg_property_bag_lookup (atts, "cx")))
-            ellipse->cx = _rsvg_css_parse_length (value);
+            ellipse->cx = _rsvg_css_parse_length (value, LENGTH_DIR_HORIZONTAL);
         if ((value = rsvg_property_bag_lookup (atts, "cy")))
-            ellipse->cy = _rsvg_css_parse_length (value);
+            ellipse->cy = _rsvg_css_parse_length (value, LENGTH_DIR_VERTICAL);
         if ((value = rsvg_property_bag_lookup (atts, "rx")))
-            ellipse->rx = _rsvg_css_parse_length (value);
+            ellipse->rx = _rsvg_css_parse_length (value, LENGTH_DIR_HORIZONTAL);
         if ((value = rsvg_property_bag_lookup (atts, "ry")))
-            ellipse->ry = _rsvg_css_parse_length (value);
+            ellipse->ry = _rsvg_css_parse_length (value, LENGTH_DIR_VERTICAL);
         if ((value = rsvg_property_bag_lookup (atts, "class")))
             klazz = value;
         if ((value = rsvg_property_bag_lookup (atts, "id"))) {
@@ -638,10 +638,10 @@ _rsvg_node_ellipse_draw (RsvgNode * self, RsvgDrawingCtx * ctx, int dominate)
     double cx, cy, rx, ry;
     RsvgPathBuilder *builder;
 
-    cx = _rsvg_css_normalize_length (&ellipse->cx, ctx, LENGTH_DIR_HORIZONTAL);
-    cy = _rsvg_css_normalize_length (&ellipse->cy, ctx, LENGTH_DIR_VERTICAL);
-    rx = _rsvg_css_normalize_length (&ellipse->rx, ctx, LENGTH_DIR_HORIZONTAL);
-    ry = _rsvg_css_normalize_length (&ellipse->ry, ctx, LENGTH_DIR_VERTICAL);
+    cx = _rsvg_css_normalize_length (&ellipse->cx, ctx);
+    cy = _rsvg_css_normalize_length (&ellipse->cy, ctx);
+    rx = _rsvg_css_normalize_length (&ellipse->rx, ctx);
+    ry = _rsvg_css_normalize_length (&ellipse->ry, ctx);
 
     if (rx <= 0 || ry <= 0)
         return;
@@ -689,6 +689,6 @@ rsvg_new_ellipse (void)
     _rsvg_node_init (&ellipse->super, RSVG_NODE_TYPE_ELLIPSE);
     ellipse->super.draw = _rsvg_node_ellipse_draw;
     ellipse->super.set_atts = _rsvg_node_ellipse_set_atts;
-    ellipse->cx = ellipse->cy = ellipse->rx = ellipse->ry = _rsvg_css_parse_length ("0");
+    ellipse->cx = ellipse->cy = ellipse->rx = ellipse->ry = _rsvg_css_parse_length ("0", LENGTH_DIR_BOTH);
     return &ellipse->super;
 }
diff --git a/rsvg-structure.c b/rsvg-structure.c
index 41dc8d3..569aba7 100644
--- a/rsvg-structure.c
+++ b/rsvg-structure.c
@@ -184,10 +184,10 @@ rsvg_node_use_draw (RsvgNode * self, RsvgDrawingCtx * ctx, int dominate)
     RsvgState *state;
     cairo_matrix_t affine;
     double x, y, w, h;
-    x = _rsvg_css_normalize_length (&use->x, ctx, LENGTH_DIR_HORIZONTAL);
-    y = _rsvg_css_normalize_length (&use->y, ctx, LENGTH_DIR_VERTICAL);
-    w = _rsvg_css_normalize_length (&use->w, ctx, LENGTH_DIR_HORIZONTAL);
-    h = _rsvg_css_normalize_length (&use->h, ctx, LENGTH_DIR_VERTICAL);
+    x = _rsvg_css_normalize_length (&use->x, ctx);
+    y = _rsvg_css_normalize_length (&use->y, ctx);
+    w = _rsvg_css_normalize_length (&use->w, ctx);
+    h = _rsvg_css_normalize_length (&use->h, ctx);
 
     rsvg_state_reinherit_top (ctx, self->state, dominate);
 
@@ -261,10 +261,10 @@ rsvg_node_svg_draw (RsvgNode * self, RsvgDrawingCtx * ctx, int dominate)
     double nx, ny, nw, nh;
     sself = (RsvgNodeSvg *) self;
 
-    nx = _rsvg_css_normalize_length (&sself->x, ctx, LENGTH_DIR_HORIZONTAL);
-    ny = _rsvg_css_normalize_length (&sself->y, ctx, LENGTH_DIR_VERTICAL);
-    nw = _rsvg_css_normalize_length (&sself->w, ctx, LENGTH_DIR_HORIZONTAL);
-    nh = _rsvg_css_normalize_length (&sself->h, ctx, LENGTH_DIR_VERTICAL);
+    nx = _rsvg_css_normalize_length (&sself->x, ctx);
+    ny = _rsvg_css_normalize_length (&sself->y, ctx);
+    nw = _rsvg_css_normalize_length (&sself->w, ctx);
+    nh = _rsvg_css_normalize_length (&sself->h, ctx);
 
     rsvg_state_reinherit_top (ctx, self->state, dominate);
 
@@ -327,17 +327,17 @@ rsvg_node_svg_set_atts (RsvgNode * self, RsvgHandle * ctx, RsvgPropertyBag * att
         if ((value = rsvg_property_bag_lookup (atts, "preserveAspectRatio")))
             svg->preserve_aspect_ratio = rsvg_css_parse_aspect_ratio (value);
         if ((value = rsvg_property_bag_lookup (atts, "width")))
-            svg->w = _rsvg_css_parse_length (value);
+            svg->w = _rsvg_css_parse_length (value, LENGTH_DIR_HORIZONTAL);
         if ((value = rsvg_property_bag_lookup (atts, "height")))
-            svg->h = _rsvg_css_parse_length (value);
+            svg->h = _rsvg_css_parse_length (value, LENGTH_DIR_VERTICAL);
         /* 
          * x & y attributes have no effect on outermost svg
          * http://www.w3.org/TR/SVG/struct.html#SVGElement 
          */
         if (self->parent && (value = rsvg_property_bag_lookup (atts, "x")))
-            svg->x = _rsvg_css_parse_length (value);
+            svg->x = _rsvg_css_parse_length (value, LENGTH_DIR_HORIZONTAL);
         if (self->parent && (value = rsvg_property_bag_lookup (atts, "y")))
-            svg->y = _rsvg_css_parse_length (value);
+            svg->y = _rsvg_css_parse_length (value, LENGTH_DIR_VERTICAL);
         if ((value = rsvg_property_bag_lookup (atts, "id"))) {
             rsvg_defs_register_name (ctx->priv->defs, value, &svg->super);
         }
@@ -383,10 +383,10 @@ rsvg_new_svg (void)
     _rsvg_node_init (&svg->super, RSVG_NODE_TYPE_SVG);
     svg->vbox.active = FALSE;
     svg->preserve_aspect_ratio = RSVG_ASPECT_RATIO_XMID_YMID;
-    svg->x = _rsvg_css_parse_length ("0");
-    svg->y = _rsvg_css_parse_length ("0");
-    svg->w = _rsvg_css_parse_length ("100%");
-    svg->h = _rsvg_css_parse_length ("100%");
+    svg->x = _rsvg_css_parse_length ("0", LENGTH_DIR_HORIZONTAL);
+    svg->y = _rsvg_css_parse_length ("0", LENGTH_DIR_VERTICAL);
+    svg->w = _rsvg_css_parse_length ("100%", LENGTH_DIR_HORIZONTAL);
+    svg->h = _rsvg_css_parse_length ("100%", LENGTH_DIR_VERTICAL);
     svg->super.draw = rsvg_node_svg_draw;
     svg->super.free = _rsvg_svg_free;
     svg->super.set_atts = rsvg_node_svg_set_atts;
@@ -411,13 +411,13 @@ rsvg_node_use_set_atts (RsvgNode * self, RsvgHandle * ctx, RsvgPropertyBag * att
     use = (RsvgNodeUse *) self;
     if (rsvg_property_bag_size (atts)) {
         if ((value = rsvg_property_bag_lookup (atts, "x")))
-            use->x = _rsvg_css_parse_length (value);
+            use->x = _rsvg_css_parse_length (value, LENGTH_DIR_HORIZONTAL);
         if ((value = rsvg_property_bag_lookup (atts, "y")))
-            use->y = _rsvg_css_parse_length (value);
+            use->y = _rsvg_css_parse_length (value, LENGTH_DIR_VERTICAL);
         if ((value = rsvg_property_bag_lookup (atts, "width")))
-            use->w = _rsvg_css_parse_length (value);
+            use->w = _rsvg_css_parse_length (value, LENGTH_DIR_HORIZONTAL);
         if ((value = rsvg_property_bag_lookup (atts, "height")))
-            use->h = _rsvg_css_parse_length (value);
+            use->h = _rsvg_css_parse_length (value, LENGTH_DIR_VERTICAL);
         if ((value = rsvg_property_bag_lookup (atts, "class")))
             klazz = value;
         if ((value = rsvg_property_bag_lookup (atts, "id"))) {
@@ -442,10 +442,10 @@ rsvg_new_use (void)
     use->super.draw = rsvg_node_use_draw;
     use->super.free = rsvg_node_use_free;
     use->super.set_atts = rsvg_node_use_set_atts;
-    use->x = _rsvg_css_parse_length ("0");
-    use->y = _rsvg_css_parse_length ("0");
-    use->w = _rsvg_css_parse_length ("0");
-    use->h = _rsvg_css_parse_length ("0");
+    use->x = _rsvg_css_parse_length ("0", LENGTH_DIR_HORIZONTAL);
+    use->y = _rsvg_css_parse_length ("0", LENGTH_DIR_VERTICAL);
+    use->w = _rsvg_css_parse_length ("0", LENGTH_DIR_HORIZONTAL);
+    use->h = _rsvg_css_parse_length ("0", LENGTH_DIR_VERTICAL);
     use->link = NULL;
     return (RsvgNode *) use;
 }
diff --git a/rsvg-styles.c b/rsvg-styles.c
index de5eb00..a95c6b0 100644
--- a/rsvg-styles.c
+++ b/rsvg-styles.c
@@ -132,7 +132,7 @@ rsvg_state_init (RsvgState * state)
     state->fill = rsvg_paint_server_parse (NULL, "#000");
     state->fill_opacity = 0xff;
     state->stroke_opacity = 0xff;
-    state->stroke_width = _rsvg_css_parse_length ("1");
+    state->stroke_width = _rsvg_css_parse_length ("1", LENGTH_DIR_BOTH);
     state->miter_limit = 4;
     state->cap = CAIRO_LINE_CAP_BUTT;
     state->join = CAIRO_LINE_JOIN_MITER;
@@ -146,7 +146,7 @@ rsvg_state_init (RsvgState * state)
     state->flood_opacity = 255;
 
     state->font_family = g_strdup (RSVG_DEFAULT_FONT);
-    state->font_size = _rsvg_css_parse_length ("12.0");
+    state->font_size = _rsvg_css_parse_length ("12.0", LENGTH_DIR_BOTH);
     state->font_style = PANGO_STYLE_NORMAL;
     state->font_variant = PANGO_VARIANT_NORMAL;
     state->font_weight = PANGO_WEIGHT_NORMAL;
@@ -155,7 +155,7 @@ rsvg_state_init (RsvgState * state)
     state->text_gravity = PANGO_GRAVITY_SOUTH;
     state->unicode_bidi = UNICODE_BIDI_NORMAL;
     state->text_anchor = TEXT_ANCHOR_START;
-    state->letter_spacing = _rsvg_css_parse_length ("0.0");
+    state->letter_spacing = _rsvg_css_parse_length ("0.0", LENGTH_DIR_HORIZONTAL);
     state->visible = TRUE;
     state->cond_true = TRUE;
     state->filter = NULL;
@@ -662,7 +662,7 @@ rsvg_parse_style_pair (RsvgHandle * ctx,
 
         rsvg_paint_server_unref (stroke);
     } else if (g_str_equal (name, "stroke-width")) {
-        state->stroke_width = _rsvg_css_parse_length (value);
+        state->stroke_width = _rsvg_css_parse_length (value, LENGTH_DIR_BOTH);
         state->has_stroke_width = TRUE;
     } else if (g_str_equal (name, "stroke-linecap")) {
         state->has_cap = TRUE;
@@ -688,7 +688,7 @@ rsvg_parse_style_pair (RsvgHandle * ctx,
         else
             g_warning (_("unknown line join style %s\n"), value);
     } else if (g_str_equal (name, "font-size")) {
-        state->font_size = _rsvg_css_parse_length (value);
+        state->font_size = _rsvg_css_parse_length (value, LENGTH_DIR_BOTH);
         state->has_font_size = TRUE;
     } else if (g_str_equal (name, "font-family")) {
         char *save = g_strdup (rsvg_css_parse_font_family (value, &state->has_font_family));
@@ -775,7 +775,7 @@ rsvg_parse_style_pair (RsvgHandle * ctx,
         }
     } else if (g_str_equal (name, "letter-spacing")) {
        state->has_letter_spacing = TRUE;
-       state->letter_spacing = _rsvg_css_parse_length (value);
+       state->letter_spacing = _rsvg_css_parse_length (value, LENGTH_DIR_HORIZONTAL);
     } else if (g_str_equal (name, "stop-color")) {
         if (!g_str_equal (value, "inherit")) {
             state->stop_color = rsvg_css_parse_color (value, &state->has_stop_color);
@@ -802,7 +802,7 @@ rsvg_parse_style_pair (RsvgHandle * ctx,
         state->miter_limit = g_ascii_strtod (value, NULL);
     } else if (g_str_equal (name, "stroke-dashoffset")) {
         state->has_dashoffset = TRUE;
-        state->dash.offset = _rsvg_css_parse_length (value);
+        state->dash.offset = _rsvg_css_parse_length (value, LENGTH_DIR_BOTH);
         if (state->dash.offset.length < 0.)
             state->dash.offset.length = 0.;
     } else if (g_str_equal (name, "shape-rendering")) {
diff --git a/rsvg-text.c b/rsvg-text.c
index 1ac6db0..9b22961 100644
--- a/rsvg-text.c
+++ b/rsvg-text.c
@@ -131,17 +131,17 @@ set_text_common_atts (RsvgNodeText *text, RsvgPropertyBag * atts)
     const char *value;
 
     if ((value = rsvg_property_bag_lookup (atts, "x"))) {
-        text->x = _rsvg_css_parse_length (value);
+        text->x = _rsvg_css_parse_length (value, LENGTH_DIR_HORIZONTAL);
         text->x_specified = TRUE;
     }
     if ((value = rsvg_property_bag_lookup (atts, "y"))) {
-        text->y = _rsvg_css_parse_length (value);
+        text->y = _rsvg_css_parse_length (value, LENGTH_DIR_VERTICAL);
         text->y_specified = TRUE;
     }
     if ((value = rsvg_property_bag_lookup (atts, "dx")))
-        text->dx = _rsvg_css_parse_length (value);
+        text->dx = _rsvg_css_parse_length (value, LENGTH_DIR_HORIZONTAL);
     if ((value = rsvg_property_bag_lookup (atts, "dy")))
-        text->dy = _rsvg_css_parse_length (value);
+        text->dy = _rsvg_css_parse_length (value, LENGTH_DIR_VERTICAL);
 }
 
 
@@ -284,10 +284,10 @@ _rsvg_node_text_draw (RsvgNode * self, RsvgDrawingCtx * ctx, int dominate)
     RsvgNodeText *text = (RsvgNodeText *) self;
     rsvg_state_reinherit_top (ctx, self->state, dominate);
 
-    x = _rsvg_css_normalize_length (&text->x, ctx, LENGTH_DIR_HORIZONTAL);
-    y = _rsvg_css_normalize_length (&text->y, ctx, LENGTH_DIR_VERTICAL);
-    dx = _rsvg_css_normalize_length (&text->dx, ctx, LENGTH_DIR_HORIZONTAL);
-    dy = _rsvg_css_normalize_length (&text->dy, ctx, LENGTH_DIR_VERTICAL);
+    x = _rsvg_css_normalize_length (&text->x, ctx);
+    y = _rsvg_css_normalize_length (&text->y, ctx);
+    dx = _rsvg_css_normalize_length (&text->dx, ctx);
+    dy = _rsvg_css_normalize_length (&text->dy, ctx);
 
     if (rsvg_current_state (ctx)->text_anchor != TEXT_ANCHOR_START) {
         _rsvg_node_text_length_children (self, ctx, &length, &lastwasspace, FALSE);
@@ -322,7 +322,7 @@ rsvg_new_text (void)
     _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");
+    text->x = text->y = text->dx = text->dy = _rsvg_css_parse_length ("0", LENGTH_DIR_BOTH);
     return &text->super;
 }
 
@@ -334,8 +334,8 @@ _rsvg_node_text_type_tspan (RsvgNodeText * self, RsvgDrawingCtx * ctx,
     double dx, dy, length = 0;
     rsvg_state_reinherit_top (ctx, self->super.state, 0);
 
-    dx = _rsvg_css_normalize_length (&self->dx, ctx, LENGTH_DIR_HORIZONTAL);
-    dy = _rsvg_css_normalize_length (&self->dy, ctx, LENGTH_DIR_VERTICAL);
+    dx = _rsvg_css_normalize_length (&self->dx, ctx);
+    dy = _rsvg_css_normalize_length (&self->dy, ctx);
 
     if (rsvg_current_state (ctx)->text_anchor != TEXT_ANCHOR_START) {
         gboolean lws = *lastwasspace;
@@ -346,7 +346,7 @@ _rsvg_node_text_type_tspan (RsvgNodeText * self, RsvgDrawingCtx * ctx,
     }
 
     if (self->x_specified) {
-        *x = _rsvg_css_normalize_length (&self->x, ctx, LENGTH_DIR_HORIZONTAL);
+        *x = _rsvg_css_normalize_length (&self->x, ctx);
         if (!PANGO_GRAVITY_IS_VERTICAL (rsvg_current_state (ctx)->text_gravity)) {
             *x -= length;
             if (rsvg_current_state (ctx)->text_anchor == TEXT_ANCHOR_MIDDLE)
@@ -358,7 +358,7 @@ _rsvg_node_text_type_tspan (RsvgNodeText * self, RsvgDrawingCtx * ctx,
     *x += dx;
 
     if (self->y_specified) {
-        *y = _rsvg_css_normalize_length (&self->y, ctx, LENGTH_DIR_VERTICAL);
+        *y = _rsvg_css_normalize_length (&self->y, ctx);
         if (PANGO_GRAVITY_IS_VERTICAL (rsvg_current_state (ctx)->text_gravity)) {
             *y -= length;
             if (rsvg_current_state (ctx)->text_anchor == TEXT_ANCHOR_MIDDLE)
@@ -381,9 +381,9 @@ _rsvg_node_text_length_tspan (RsvgNodeText * self,
         return TRUE;
 
     if (PANGO_GRAVITY_IS_VERTICAL (rsvg_current_state (ctx)->text_gravity))
-        *length += _rsvg_css_normalize_length (&self->dy, ctx, LENGTH_DIR_VERTICAL);
+        *length += _rsvg_css_normalize_length (&self->dy, ctx);
     else
-        *length += _rsvg_css_normalize_length (&self->dx, ctx, LENGTH_DIR_HORIZONTAL);
+        *length += _rsvg_css_normalize_length (&self->dx, ctx);
 
     return _rsvg_node_text_length_children (&self->super, ctx, length,
                                              lastwasspace, usetextonly);
@@ -416,7 +416,7 @@ rsvg_new_tspan (void)
     text = g_new0 (RsvgNodeText, 1);
     _rsvg_node_init (&text->super, RSVG_NODE_TYPE_TSPAN);
     text->super.set_atts = _rsvg_node_tspan_set_atts;
-    text->dx = text->dy = _rsvg_css_parse_length ("0");
+    text->dx = text->dy = _rsvg_css_parse_length ("0", LENGTH_DIR_BOTH);
     return &text->super;
 }
 
@@ -547,8 +547,7 @@ rsvg_text_create_layout (RsvgDrawingCtx * ctx,
     pango_font_description_free (font_desc);
 
     attr_list = pango_attr_list_new ();
-    attribute = pango_attr_letter_spacing_new (_rsvg_css_normalize_length (&state->letter_spacing,
-                                                                           ctx, LENGTH_DIR_HORIZONTAL) * 
PANGO_SCALE);
+    attribute = pango_attr_letter_spacing_new (_rsvg_css_normalize_length (&state->letter_spacing, ctx) * 
PANGO_SCALE);
     attribute->start_index = 0;
     attribute->end_index = G_MAXINT;
     pango_attr_list_insert (attr_list, attribute); 


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