Index: pango/pango-attributes.c
===================================================================
RCS file: /cvs/gnome/pango/pango/pango-attributes.c,v
retrieving revision 1.62
diff -u -p -d -r1.62 pango-attributes.c
--- pango/pango-attributes.c	29 Apr 2006 19:41:23 -0000	1.62
+++ pango/pango-attributes.c	30 Apr 2006 00:19:42 -0000
@@ -1691,8 +1691,7 @@ pango_attr_iterator_get_font (PangoAttrI
 
   PangoFontMask mask = 0;
   gboolean have_language = FALSE;
-  gdouble scale = 0;
-  gboolean have_scale = FALSE;
+  gdouble scale = 1.0;
 
   g_return_if_fail (iterator != NULL);
   g_return_if_fail (desc != NULL);
@@ -1770,10 +1769,9 @@ pango_attr_iterator_get_font (PangoAttrI
 	    }
 	  break;
         case PANGO_ATTR_SCALE:
-	  if (!have_scale)
+	  if (!(mask & PANGO_FONT_MASK_SIZE))
 	    {
-	      have_scale = TRUE;
-	      scale = ((PangoAttrFloat *)attr)->value;
+	      scale *= ((PangoAttrFloat *)attr)->value;
 	    }
 	  break;
 	case PANGO_ATTR_LANGUAGE:
@@ -1810,7 +1808,7 @@ pango_attr_iterator_get_font (PangoAttrI
 	}
     }
 
-  if (have_scale)
+  if (scale != 1.0)
     pango_font_description_set_size (desc, scale * pango_font_description_get_size (desc));
 
 }
Index: pango/pango-markup.c
===================================================================
RCS file: /cvs/gnome/pango/pango/pango-markup.c,v
retrieving revision 1.30
diff -u -p -d -r1.30 pango-markup.c
--- pango/pango-markup.c	11 Apr 2006 08:31:43 -0000	1.30
+++ pango/pango-markup.c	30 Apr 2006 00:19:42 -0000
@@ -62,15 +62,19 @@ struct _OpenTag
 {
   GSList *attrs;
   gsize start_index;
-  /* Current total scale level; reset whenever
+  /* Our impact on scale_factor, so we know whether we
+   * need to create an attribute ourselves on close
+   */
+  gboolean has_scale;
+  /* Current scale level; reset whenever
    * an absolute size is set.
    * Each "larger" ups it 1, each "smaller" decrements it 1
    */
   gint scale_level;
-  /* Our impact on scale_level, so we know whether we
-   * need to create an attribute ourselves on close
+  /* Current scale factor; reset whenever
+   * an absolute size is set.
    */
-  gint scale_level_delta;
+  gint scale_factor;
   /* Base scale factor currently in effect
    * or size that this tag
    * forces, or parent's scale factor or size.
@@ -201,7 +205,8 @@ open_tag_set_absolute_font_size (OpenTag
   ot->base_font_size = font_size;
   ot->has_base_font_size = TRUE;
   ot->scale_level = 0;
-  ot->scale_level_delta = 0;
+  ot->scale_factor = 1.0;
+  ot->has_scale = FALSE;
 }
 
 static void
@@ -211,7 +216,8 @@ open_tag_set_absolute_font_scale (OpenTa
   ot->base_scale_factor = scale;
   ot->has_base_font_size = FALSE;
   ot->scale_level = 0;
-  ot->scale_level_delta = 0;
+  ot->scale_factor = 1.0;
+  ot->has_scale = FALSE;
 }
      
 static OpenTag*
@@ -229,7 +235,7 @@ markup_data_open_tag (MarkupData   *md)
   ot = g_slice_new (OpenTag);
   ot->attrs = NULL;
   ot->start_index = md->index;
-  ot->scale_level_delta = 0;
+  ot->has_scale = FALSE;
   
   if (parent == NULL)
     {
@@ -237,6 +243,7 @@ markup_data_open_tag (MarkupData   *md)
       ot->base_font_size = 0;
       ot->has_base_font_size = FALSE;
       ot->scale_level = 0;
+      ot->scale_factor = 1.0;
     }
   else
     {
@@ -244,6 +251,7 @@ markup_data_open_tag (MarkupData   *md)
       ot->base_font_size = parent->base_font_size;
       ot->has_base_font_size = parent->has_base_font_size;
       ot->scale_level = parent->scale_level;
+      ot->scale_factor = parent->scale_factor;
     }
   
   md->tag_stack = g_slist_prepend (md->tag_stack, ot);
@@ -283,7 +291,7 @@ markup_data_close_tag (MarkupData *md)
       tmp_list = g_slist_next (tmp_list);
     }
 
-  if (ot->scale_level_delta != 0)
+  if (ot->has_scale != 0)
     {
       /* We affected relative font size; create an appropriate
        * attribute and reverse our effects on the current level
@@ -296,7 +304,7 @@ markup_data_close_tag (MarkupData *md)
            * as the base size to be scaled from
            */
           a = pango_attr_size_new (scale_factor (ot->scale_level,
-                                                 1.0) *
+                                                 ot->scale_factor) *
                                    ot->base_font_size);
         }
       else
@@ -305,7 +313,8 @@ markup_data_close_tag (MarkupData *md)
            * as the base size to be scaled from
            */
           a = pango_attr_scale_new (scale_factor (ot->scale_level,
-                                                  ot->base_scale_factor));
+                                                  ot->scale_factor *
+						  ot->base_scale_factor));
         }
 
       a->start_index = ot->start_index;
@@ -768,7 +777,7 @@ big_parse_func      (MarkupData         
   /* Grow text one level */
   if (tag)
     {
-      tag->scale_level_delta += 1;
+      tag->has_scale = TRUE;
       tag->scale_level += 1;
     }
 
@@ -997,27 +1006,37 @@ span_parse_func     (MarkupData         
 
           n = strtoul (size, &end, 10);
 
-          if (*end != '\0')
+          if (*end == '\0')
+	    {
+	      add_attribute (tag, pango_attr_size_new (n));
+	      if (tag)
+		open_tag_set_absolute_font_size (tag, n);
+	    }
+	  else if (*end == '%' && *(end+1) == '\0')
+	    {
+	      if (tag)
+	        {
+		  tag->has_scale = TRUE;
+		  tag->scale_factor *= n / 100.;
+		}
+	    }
+	  else
             {
               g_set_error (error,
                            G_MARKUP_ERROR,
                            G_MARKUP_ERROR_INVALID_CONTENT,
-                           _("Value of 'size' attribute on <span> tag on line %d"
-                             "could not be parsed; should be an integer, or a "
-                             "string such as 'small', not '%s'"),
+                           _("Value of 'size' attribute on <span> tag on line %d "
+                             "could not be parsed; should be an integer, a "
+                             "percentage, or a string such as 'small', not '%s'"),
                            line_number, size);
               goto error;
             }
-
-          add_attribute (tag, pango_attr_size_new (n));
-	  if (tag)
-	    open_tag_set_absolute_font_size (tag, n);
         }
       else if (strcmp (size, "smaller") == 0)
         {
 	  if (tag)
 	    {
-	      tag->scale_level_delta -= 1;
+	      tag->has_scale = TRUE;
 	      tag->scale_level -= 1;
 	    }
         }
@@ -1025,7 +1044,7 @@ span_parse_func     (MarkupData         
         {
 	  if (tag)
 	    {
-	      tag->scale_level_delta += 1;
+	      tag->has_scale = TRUE;
 	      tag->scale_level += 1;
 	    }
         }
@@ -1036,9 +1055,9 @@ span_parse_func     (MarkupData         
           g_set_error (error,
                        G_MARKUP_ERROR,
                        G_MARKUP_ERROR_INVALID_CONTENT,
-                       _("Value of 'size' attribute on <span> tag on line %d"
-                         "could not be parsed; should be an integer, or a "
-                         "string such as 'small', not '%s'"),
+		       _("Value of 'size' attribute on <span> tag on line %d "
+			 "could not be parsed; should be an integer, a "
+			 "percentage, or a string such as 'small', not '%s'"),
                        line_number, size);
           goto error;
         }
@@ -1375,7 +1394,7 @@ sub_parse_func      (MarkupData         
   /* Shrink font, and set a negative rise */
   if (tag)
     {
-      tag->scale_level_delta -= 1;
+      tag->has_scale = TRUE;
       tag->scale_level -= 1;
     }
 
@@ -1397,7 +1416,7 @@ sup_parse_func      (MarkupData         
   /* Shrink font, and set a positive rise */
   if (tag)
     {
-      tag->scale_level_delta -= 1;
+      tag->has_scale = TRUE;
       tag->scale_level -= 1;
     }
 
@@ -1419,7 +1438,7 @@ small_parse_func    (MarkupData         
   /* Shrink text one level */
   if (tag)
     {
-      tag->scale_level_delta -= 1;
+      tag->has_scale = TRUE;
       tag->scale_level -= 1;
     }
 
