Bug#268831: librsvg2: x, y, dx, dy properties bogus on tspan element

Nick Lewycky Nick Lewycky <nicholas@mxc.ca>, 268831@bugs.debian.org
Sun, 29 Aug 2004 08:06:59 -0400


This is a multi-part MIME message sent by reportbug.

--===============1399983408==
Content-Type: text/plain; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: inline

Package: librsvg2
Severity: normal
Tags: patch

librsvg2 doesn't handle the following fragment:

    <text x="0" y="256">
        <tspan>H</tspan>
        <tspan y="261">2</tspan>
        <tspan>SO</tspan>
        <tspan dy="5">4</tspan>
    </text>

This should be rendered as if it were H_2SO_4 in TeX. Instead, the "2"
and "4" are displayed on the same line as the H and SO.

My attached patch, librsvg2-tspan.diff implements the correct
behaviour, but the patch was made against a tree with the patch from
bug 264484 already in it.

A unified patch, librsvg2-tspan+baseline.diff includes both changes.

-- System Information:
Debian Release: 3.1
  APT prefers unstable
  APT policy: (500, 'unstable')
Architecture: i386 (i686)
Kernel: Linux 2.6.7
Locale: LANG=C, LC_CTYPE=C

--===============1399983408==
Content-Type: text/x-c; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment; filename="librsvg2-tspan.diff"

diff -u librsvg2-2.7.2/rsvg-text.c librsvg2-2.7.2/rsvg-text.c
--- librsvg2-2.7.2/rsvg-text.c
+++ librsvg2-2.7.2/rsvg-text.c
@@ -322,16 +322,19 @@
 
 			rsvg_parse_style_attrs (ctx, state, "tspan", klazz, id, atts);
 		}
-	
-	/* todo: transform() is illegal here */
-	x += dx ;
-	y += dy ;
-	
-	if (x > 0 && y > 0)
+
+	if (x || y)
 		{
 			art_affine_translate (affine, x, y);
-			art_affine_multiply (state->affine, affine, state->affine);
+			state->affine[5] = 0, state->affine[6] = 0;
+			art_affine_multiply (state->affine, state->affine, affine);
+		}
+
+	if (dx || dy)
+		{
+			art_affine_translate (affine, dx, dy);
+			art_affine_multiply (state->affine, state->affine, affine);
 		}
 }
 
diff -u librsvg2-2.7.2/debian/changelog librsvg2-2.7.2/debian/changelog
--- librsvg2-2.7.2/debian/changelog
+++ librsvg2-2.7.2/debian/changelog
@@ -1,4 +1,10 @@
+librsvg2 (2.7.2-5.2) unstable; urgency=low
+
+  * Fix bug with translations on tspan tag.
+
+ -- Nicholas Lewycky <nicholas@spi-inc.org>  Sun, 29 Aug 2004 00:51:42 -0400
+
 librsvg2 (2.7.2-5.1) unstable; urgency=low
 
   * Add support for baseline-shift.

--===============1399983408==
Content-Type: text/x-c; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment; filename="librsvg2-tspan+baseline.diff"

diff -u librsvg2-2.7.2/debian/changelog librsvg2-2.7.2/debian/changelog
--- librsvg2-2.7.2/debian/changelog
+++ librsvg2-2.7.2/debian/changelog
@@ -1,3 +1,15 @@
+librsvg2 (2.7.2-5.2) unstable; urgency=low
+
+  * Fix bug with translations on tspan tag.
+
+ -- Nicholas Lewycky <nicholas@spi-inc.org>  Sun, 29 Aug 2004 00:51:42 -0400
+
+librsvg2 (2.7.2-5.1) unstable; urgency=low
+
+  * Add support for baseline-shift.
+
+ -- Nicholas Lewycky <nicholas@spi-inc.org>  Sun,  8 Aug 2004 20:20:06 -0500
+
 librsvg2 (2.7.2-5) unstable; urgency=medium
 
   * Rebuild with libgnutls11 (closes: #263682).
only in patch2:
unchanged:
--- librsvg2-2.7.2.orig/rsvg-css.c
+++ librsvg2-2.7.2/rsvg-css.c
@@ -693,6 +693,26 @@
 		return str;
 }
 
+gint
+rsvg_css_parse_baseline_shift (const char * str, gdouble pixels_per_inch,
+                               gdouble width_or_height, gdouble font_size,
+                               gint inherit)
+{
+	if (!str)
+		return 0;
+	else if (!strcmp (str, "inherit"))
+		return inherit;
+	else if (!strcmp (str, "baseline"))
+		return 0;
+	else if (!strcmp (str, "sub"))
+		return font_size * -0.54;        /* not quite spec */
+	else if (!strcmp (str, "super"))
+		return font_size * 0.54;
+	else
+		return rsvg_css_parse_normalized_length (str, pixels_per_inch,
+												 width_or_height, font_size);
+}
+
 #if !defined(HAVE_STRTOK_R) && !GLIB_CHECK_VERSION(2, 3, 2)
 
 static char *
only in patch2:
unchanged:
--- librsvg2-2.7.2.orig/rsvg-styles.c
+++ librsvg2-2.7.2/rsvg-styles.c
@@ -51,6 +51,20 @@
 	return 0;
 }
 
+static gint
+rsvg_state_baseline_shift (RsvgState * cur_state, RsvgState * parent_state)
+{
+	if (cur_state)
+		{
+			if (cur_state->has_baseline_shift)
+				return cur_state->baseline_shift;
+			else if (parent_state)
+				return parent_state->baseline_shift;
+		}
+	
+	return 0;
+}
+
 gdouble
 rsvg_viewport_percentage (gdouble width, gdouble height)
 {
@@ -645,6 +659,13 @@
 						}
 				}
 		}
+	else if (rsvg_css_param_match (str, "baseline-shift"))
+		{
+			gint current_baseline_shift = rsvg_state_baseline_shift (state, parent_state);
+			state->has_baseline_shift = TRUE;
+			state->baseline_shift = rsvg_css_parse_baseline_shift (str + arg_off, ctx->dpi,
+																   (gdouble)ctx->height, state->font_size, current_baseline_shift);
+		}
 }
 
 void rsvg_parse_style_pair (RsvgHandle *ctx, RsvgState *state, 
only in patch2:
unchanged:
--- librsvg2-2.7.2.orig/rsvg-styles.h
+++ librsvg2-2.7.2/rsvg-styles.h
@@ -125,6 +125,9 @@
 	guint32 current_color;
 	gboolean has_current_color;
 
+	gint baseline_shift;
+	gboolean has_baseline_shift;
+
 	GdkPixbuf *save_pixbuf;
 };
 
only in patch2:
unchanged:
--- librsvg2-2.7.2.orig/rsvg-text.c
+++ librsvg2-2.7.2/rsvg-text.c
@@ -156,7 +156,10 @@
 		line_ink_rect = ink_rect; /* nothing to draw anyway */
 	else
 		pango_layout_line_get_pixel_extents (line, &line_ink_rect, NULL);
-	
+
+	if (state->has_baseline_shift)
+		line_ink_rect.y -= state->baseline_shift;
+
 	bitmap.rows       = ink_rect.height;
 	bitmap.width      = ink_rect.width;
 	bitmap.pitch      = bitmap.width;
@@ -211,7 +214,7 @@
 	gradctx.y1 = line_ink_rect.y + logical_rect.height;
 	for (i = 0; i < 6; i++)
 		gradctx.affine[i] = state->affine[i];
-	
+
 	rsvg_render_paint_server (render, state->fill, &gradctx);
 
 	opacity = state->fill_opacity * state->opacity;
@@ -319,15 +322,18 @@
 
 			rsvg_parse_style_attrs (ctx, state, "tspan", klazz, id, atts);
 		}
-	
-	/* todo: transform() is illegal here */
-	x += dx ;
-	y += dy ;
-	
-	if (x > 0 && y > 0)
+
+	if (x || y)
 		{
 			art_affine_translate (affine, x, y);
-			art_affine_multiply (state->affine, affine, state->affine);
+			state->affine[5] = 0, state->affine[6] = 0;
+			art_affine_multiply (state->affine, state->affine, affine);
+		}
+
+	if (dx || dy)
+		{
+			art_affine_translate (affine, dx, dy);
+			art_affine_multiply (state->affine, state->affine, affine);
 		}
 }
 
only in patch2:
unchanged:
--- librsvg2-2.7.2.orig/rsvg-text-vectors.c
+++ librsvg2-2.7.2/rsvg-text-vectors.c
@@ -135,7 +135,7 @@
 {
 	RsvgTextLayout * layout;
 	PangoFontDescription *font_desc;
-	
+
 	if (ctx->pango_context == NULL)
 		ctx->pango_context = rsvg_text_get_pango_context (ctx);
 	
@@ -506,11 +506,16 @@
 			PangoRectangle   rect;
 			PangoLayoutLine *line;
 			gint             baseline;
+			RsvgState       *state;
 			
 			line = pango_layout_iter_get_line (iter);
 			
 			pango_layout_iter_get_line_extents (iter, NULL, &rect);
 			baseline = pango_layout_iter_get_baseline (iter);
+
+			state = rsvg_state_current(layout->ctx);
+			if (state && state->has_baseline_shift)
+				baseline -= state->baseline_shift;
 			
 			rsvg_text_layout_render_line (layout, line,
 										  render_func,

--===============1399983408==--