diff --git a/rsvg-cond.c b/rsvg-cond.c
index b5c02a4..25823cd 100644
--- a/rsvg-cond.c
+++ b/rsvg-cond.c
@@ -94,26 +94,38 @@ rsvg_cond_fulfills_requirement (const char *value, const char **features, guint
 
 /* http://www.w3.org/TR/SVG/struct.html#SystemLanguageAttribute */
 static gboolean
-rsvg_locale_compare (const char *a, const char *b)
+rsvg_locale_compare (const char *a, const char *b, gboolean *fallback_true)
 {
-    const char *hyphen;
+    const char *hyphen, *underscore, *dot;
+    gchar *a_dup;
+
+    /* check if a contains a dot */
+    dot = g_strstr_len(a, -1, ".");
+    a_dup = dot ? g_strndup(a, dot - a) : g_strdup(a);
+
+    /* check if there's an underscore instead of a hyphen */
+    underscore = g_strstr_len(a, -1, "_");
+    a_dup[underscore - a] = '-';
 
     /* check for an exact-ish match first */
-    if (!g_ascii_strncasecmp (a, b, strlen (b)))
+    if (strlen (a_dup) == strlen (b) && !g_ascii_strncasecmp (a_dup, b, strlen (b)))
         return TRUE;
 
     /* check to see if there's a hyphen */
     hyphen = strstr (b, "-");
-    if (!hyphen)
-        return FALSE;
 
-    /* compare up to the hyphen */
-    return !g_ascii_strncasecmp (a, b, (hyphen - b));
+    /* compare up to the hyphen to find out fallback */
+    if (hyphen && !g_ascii_strncasecmp (a_dup, b, (hyphen - b)))
+        *fallback_true = TRUE;
+
+    g_free(a_dup);
+
+    return FALSE;
 }
 
 /* http://www.w3.org/TR/SVG/struct.html#SystemLanguageAttribute */
 static gboolean
-rsvg_cond_parse_system_language (const char *value)
+rsvg_cond_parse_system_language (const char *value, gboolean *fallback_true)
 {
     guint nb_elems = 0;
     char **elems;
@@ -151,8 +163,9 @@ rsvg_cond_parse_system_language (const char *value)
 
         if (locale) {
             for (i = 0; (i < nb_elems) && !permitted; i++) {
-                if (rsvg_locale_compare (locale, elems[i]))
+                if (rsvg_locale_compare (locale, elems[i], fallback_true)) {
                     permitted = TRUE;
+                }
             }
 
             g_free (locale);
@@ -168,11 +181,13 @@ rsvg_cond_parse_system_language (const char *value)
 /* returns TRUE if this element should be processed according to <switch> semantics
    http://www.w3.org/TR/SVG/struct.html#SwitchElement */
 gboolean
-rsvg_eval_switch_attributes (RsvgPropertyBag * atts, gboolean * p_has_cond)
+rsvg_eval_switch_attributes (RsvgPropertyBag * atts, gboolean * p_has_cond, gboolean * fallback_true)
 {
     gboolean permitted = TRUE;
     gboolean has_cond = FALSE;
 
+    *fallback_true = FALSE;
+
     if (atts && rsvg_property_bag_size (atts)) {
         const char *value;
 
@@ -191,7 +206,7 @@ rsvg_eval_switch_attributes (RsvgPropertyBag * atts, gboolean * p_has_cond)
         }
 
         if (permitted && (value = rsvg_property_bag_lookup (atts, "systemLanguage"))) {
-            permitted = rsvg_cond_parse_system_language (value);
+            permitted = rsvg_cond_parse_system_language (value, fallback_true);
             has_cond = TRUE;
         }
     }
diff --git a/rsvg-private.h b/rsvg-private.h
index 6921bc3..edba2bb 100644
--- a/rsvg-private.h
+++ b/rsvg-private.h
@@ -351,7 +351,7 @@ GdkPixbuf *rsvg_pixbuf_from_data_with_size_data (const guchar * buff,
                                                  gpointer data,
                                                  const char *base_uri, GError ** error);
 G_GNUC_INTERNAL
-gboolean     rsvg_eval_switch_attributes	(RsvgPropertyBag * atts, gboolean * p_has_cond);
+gboolean     rsvg_eval_switch_attributes	(RsvgPropertyBag * atts, gboolean * p_has_cond, gboolean * fallback_true);
 G_GNUC_INTERNAL
 gchar       *rsvg_get_base_uri_from_filename    (const gchar * file_name);
 G_GNUC_INTERNAL
diff --git a/rsvg-structure.c b/rsvg-structure.c
index 4ab4473..8d86910 100644
--- a/rsvg-structure.c
+++ b/rsvg-structure.c
@@ -503,6 +503,8 @@ static void
 _rsvg_node_switch_draw (RsvgNode * self, RsvgDrawingCtx * ctx, int dominate)
 {
     guint i;
+    guint i_matched = -1;
+    guint i_fallback = -1;
 
     rsvg_state_reinherit_top (ctx, self->state, dominate);
 
@@ -511,13 +513,23 @@ _rsvg_node_switch_draw (RsvgNode * self, RsvgDrawingCtx * ctx, int dominate)
     for (i = 0; i < self->children->len; i++) {
         RsvgNode *drawable = g_ptr_array_index (self->children, i);
 
-        if (drawable->state->cond_true) {
-            rsvg_state_push (ctx);
-            rsvg_node_draw (g_ptr_array_index (self->children, i), ctx, 0);
-            rsvg_state_pop (ctx);
-
+        if (drawable->state->has_cond && drawable->state->cond_true) {
+            i_matched = i;
             break;              /* only render the 1st one */
         }
+        else if (i_fallback == -1 && (drawable->state->cond_true || drawable->state->fallback_true)) {
+            i_fallback = i;  /* only the 1st fallback get rendered */
+        }
+    }
+
+    if (i_matched == -1)
+        i_matched = i_fallback;
+
+
+    if (i_matched != -1) {
+        rsvg_state_push (ctx);
+        rsvg_node_draw (g_ptr_array_index (self->children, i_matched), ctx, 0);
+        rsvg_state_pop (ctx);
     }
 
     rsvg_pop_discrete_layer (ctx);
diff --git a/rsvg-styles.c b/rsvg-styles.c
index 4639f51..dcb617d 100644
--- a/rsvg-styles.c
+++ b/rsvg-styles.c
@@ -148,6 +148,7 @@ rsvg_state_init (RsvgState * state)
     state->letter_spacing = _rsvg_css_parse_length ("0.0");
     state->visible = TRUE;
     state->cond_true = TRUE;
+    state->fallback_true = FALSE;
     state->filter = NULL;
     state->clip_path = NULL;
     state->startMarker = NULL;
@@ -929,12 +930,13 @@ rsvg_parse_style_pairs (RsvgHandle * ctx, RsvgState * state, RsvgPropertyBag * a
 
     {
         /* TODO: this conditional behavior isn't quite correct, and i'm not sure it should reside here */
-        gboolean cond_true, has_cond;
+        gboolean cond_true, has_cond, fallback_true;
 
-        cond_true = rsvg_eval_switch_attributes (atts, &has_cond);
+        cond_true = rsvg_eval_switch_attributes (atts, &has_cond, &fallback_true);
 
         if (has_cond) {
             state->cond_true = cond_true;
+            state->fallback_true = fallback_true;
             state->has_cond = TRUE;
         }
     }
diff --git a/rsvg-styles.h b/rsvg-styles.h
index a044d3f..d7ab408 100644
--- a/rsvg-styles.h
+++ b/rsvg-styles.h
@@ -154,6 +154,7 @@ struct _RsvgState {
 
     gboolean has_cond;
     gboolean cond_true;
+    gboolean fallback_true;
 
     RsvgVpathDash dash;
     gboolean has_dash;
