[cairo-commit] libsvg/src svg.h, 1.21, 1.22 svg_element.c, 1.36, 1.37 svg_parser.c, 1.35, 1.36 svg_text.c, 1.13, 1.14 svgint.h, 1.45, 1.46

Keith Packard commit at pdx.freedesktop.org
Mon Jul 18 14:55:08 PDT 2005


Committed by: keithp

Update of /cvs/cairo/libsvg/src
In directory gabe:/tmp/cvs-serv9519/src

Modified Files:
	svg.h svg_element.c svg_parser.c svg_text.c svgint.h 
Log Message:
2005-07-18  Keith Packard  <keithp at keithp.com>

reviewed by: cworth

* src/svg.h:
* src/svg_element.c: (_svg_element_init), (_svg_element_init_copy),
(_svg_element_deinit), (svg_element_render),
(_svg_element_apply_attributes):
* src/svg_parser.c: (_svg_parser_parse_text),
(_svg_parser_parse_tspan), (_svg_parser_parse_text_characters),
(_svg_parser_parse_tspan_characters):
* src/svg_text.c: (_svg_tspan_init), (_svg_tspan_init_copy),
(_svg_tspan_deinit), (_svg_tspan_append_chars),
(_svg_tspan_render), (_svg_tspan_apply_attributes),
(_svg_tspan_extents), (_svg_text_init), (_svg_text_init_copy),
(_svg_text_deinit), (_svg_text_prepare_tspan), (_svg_text_render),
(_svg_text_apply_attributes), (_svg_text_extents):
* src/svgint.h:
Add preliminary support for <tspan>. No support
for positioning tspan elements.

Index: svg.h
===================================================================
RCS file: /cvs/cairo/libsvg/src/svg.h,v
retrieving revision 1.21
retrieving revision 1.22
diff -u -d -r1.21 -r1.22
--- svg.h	11 Apr 2005 16:58:20 -0000	1.21
+++ svg.h	18 Jul 2005 21:55:06 -0000	1.22
@@ -48,7 +48,7 @@
     SVG_LENGTH_UNIT_PC,
     SVG_LENGTH_UNIT_PCT,
     SVG_LENGTH_UNIT_PT,
-    SVG_LENGTH_UNIT_PX
+    SVG_LENGTH_UNIT_PX,
 } svg_length_unit_t;
 
 typedef enum svg_length_orientation {
@@ -297,8 +297,8 @@
 				     svg_length_t *rx,
 				     svg_length_t *ry);
     svg_status_t (* render_text) (void *closure,
-				  svg_length_t *x,
-				  svg_length_t *y,
+				  double x,
+				  double y,
 				  const char   *utf8);
     svg_status_t (* render_image) (void		 *closure,
 				   unsigned char *data,
@@ -308,6 +308,15 @@
 				   svg_length_t	 *y,
 				   svg_length_t	 *width,
 				   svg_length_t	 *height);
+    svg_status_t (* text_extents) (void *closure,
+				   const char *utf8,
+				   double *width,
+				   double *height);
+    svg_status_t (*measure_position) (void	    *closure,
+				      svg_length_t  *ix,
+				      svg_length_t  *iy,
+				      double	    *ox,
+				      double	    *oy);
 } svg_render_engine_t;
 
 svg_status_t

Index: svg_element.c
===================================================================
RCS file: /cvs/cairo/libsvg/src/svg_element.c,v
retrieving revision 1.36
retrieving revision 1.37
diff -u -d -r1.36 -r1.37
--- svg_element.c	11 Apr 2005 16:20:09 -0000	1.36
+++ svg_element.c	18 Jul 2005 21:55:06 -0000	1.37
@@ -82,6 +82,9 @@
     case SVG_ELEMENT_TYPE_TEXT:
 	status = _svg_text_init (&element->e.text);
 	break;
+    case SVG_ELEMENT_TYPE_TSPAN:
+	status = _svg_tspan_init (&element->e.tspan);
+	break;
     case SVG_ELEMENT_TYPE_IMAGE:
 	status = _svg_image_init (&element->e.image);
 	break;
@@ -144,6 +147,9 @@
     case SVG_ELEMENT_TYPE_TEXT:
 	status = _svg_text_init_copy (&element->e.text, &other->e.text);
 	break;
+    case SVG_ELEMENT_TYPE_TSPAN:
+	status = _svg_tspan_init_copy (&element->e.tspan, &other->e.tspan);
+	break;
     case SVG_ELEMENT_TYPE_GRADIENT:
 	status = _svg_gradient_init_copy (&element->e.gradient, &other->e.gradient);
 	break;
@@ -199,6 +205,7 @@
 	status = SVG_STATUS_SUCCESS;
 	break;
     case SVG_ELEMENT_TYPE_TEXT:
+	status = _svg_group_deinit (&element->e.text.group);
 	status = _svg_text_deinit (&element->e.text);
 	break;
     case SVG_ELEMENT_TYPE_GRADIENT:
@@ -258,7 +265,8 @@
 	return status;
 
     if (element->type == SVG_ELEMENT_TYPE_SVG_GROUP
-	|| element->type == SVG_ELEMENT_TYPE_GROUP) {
+	|| element->type == SVG_ELEMENT_TYPE_GROUP
+	|| element->type == SVG_ELEMENT_TYPE_TEXT) {
 
 	status = (engine->begin_group) (closure, _svg_style_get_opacity(&element->style));
 	if (status)
@@ -502,6 +510,9 @@
     case SVG_ELEMENT_TYPE_TEXT:
 	status = _svg_text_apply_attributes (&element->e.text, attributes);
 	break;
+    case SVG_ELEMENT_TYPE_TSPAN:
+	status = _svg_tspan_apply_attributes (&element->e.tspan, attributes);
+	break;
     case SVG_ELEMENT_TYPE_IMAGE:
 	status = _svg_image_apply_attributes (&element->e.image, attributes);
 	break;

Index: svg_parser.c
===================================================================
RCS file: /cvs/cairo/libsvg/src/svg_parser.c,v
retrieving revision 1.35
retrieving revision 1.36
diff -u -d -r1.35 -r1.36
--- svg_parser.c	21 Apr 2005 19:29:19 -0000	1.35
+++ svg_parser.c	18 Jul 2005 21:55:06 -0000	1.36
@@ -119,6 +119,11 @@
 			svg_element_t	**text_element);
 
 static svg_status_t
+_svg_parser_parse_tspan (svg_parser_t	*parser,
+			 const char	**attributes,
+			 svg_element_t	**tspan_element);
+
+static svg_status_t
 _svg_parser_parse_image (svg_parser_t	*parser,
 			 const char	**attributes,
 			 svg_element_t	**image_element);
@@ -148,6 +153,11 @@
 				   const char	*ch,
 				   int			len);
 
+static svg_status_t
+_svg_parser_parse_tspan_characters (svg_parser_t	*parser,
+				    const char		*ch,
+				    int			len);
+
 typedef struct svg_parser_map {
     char		*name;
     svg_parser_cb_t	cb;
@@ -169,6 +179,8 @@
     {"polyline",	{_svg_parser_parse_polyline,		NULL }},
     {"text",		{_svg_parser_parse_text,
 			 _svg_parser_parse_text_characters }},
+    {"tspan",		{_svg_parser_parse_tspan,
+			 _svg_parser_parse_tspan_characters }},
     {"image",		{_svg_parser_parse_image,		NULL }},
     {"linearGradient",	{_svg_parser_parse_linear_gradient,	NULL }},
     {"radialGradient",	{_svg_parser_parse_radial_gradient,	NULL }},
@@ -627,9 +639,9 @@
 {
     svg_status_t status;
 
-    status = _svg_parser_new_leaf_element (parser,
-					   text_element,
-					   SVG_ELEMENT_TYPE_TEXT);
+    status = _svg_parser_new_group_element (parser,
+					    text_element,
+					    SVG_ELEMENT_TYPE_TEXT);
     if (status)
 	return status;
 
@@ -639,6 +651,29 @@
 }
 
 static svg_status_t
+_svg_parser_parse_tspan (svg_parser_t	*parser,
+			 const char	**attributes,
+			 svg_element_t	**tspan_element)
+{
+    svg_status_t status;
+    svg_text_t *text;
+
+    text = parser->state->text;
+    if (text == NULL)
+	return SVG_STATUS_PARSE_ERROR;
+
+    status = _svg_parser_new_leaf_element (parser,
+					   tspan_element,
+					   SVG_ELEMENT_TYPE_TSPAN);
+    if (status)
+	return status;
+
+    parser->state->tspan = &(*tspan_element)->e.tspan;
+
+    return SVG_STATUS_SUCCESS;
+}
+
+static svg_status_t
 _svg_parser_parse_image (svg_parser_t	*parser,
 			 const char	**attributes,
 			 svg_element_t	**image_element)
@@ -775,12 +810,36 @@
 {
     svg_status_t status;
     svg_text_t *text;
+    svg_element_t *tspan;
 
     text = parser->state->text;
     if (text == NULL)
 	return SVG_STATUS_PARSE_ERROR;
 
-    status = _svg_text_append_chars (text, ch, len);
+    status = _svg_parser_parse_tspan (parser, NULL, &tspan);
+    if (status)
+	return status;
+    
+    status = _svg_parser_parse_tspan_characters (parser, ch, len);
+    if (status)
+	return status;
+
+    return SVG_STATUS_SUCCESS;
+}
+
+static svg_status_t
+_svg_parser_parse_tspan_characters (svg_parser_t    *parser,
+				    const char	    *ch,
+				    int		    len)
+{
+    svg_status_t status;
+    svg_tspan_t *tspan;
+
+    tspan = parser->state->tspan;
+    if (tspan == NULL)
+	return SVG_STATUS_PARSE_ERROR;
+
+    status = _svg_tspan_append_chars (tspan, ch, len);
     if (status)
 	return status;
 

Index: svg_text.c
===================================================================
RCS file: /cvs/cairo/libsvg/src/svg_text.c,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -d -r1.13 -r1.14
--- svg_text.c	21 Apr 2005 19:29:19 -0000	1.13
+++ svg_text.c	18 Jul 2005 21:55:06 -0000	1.14
@@ -25,87 +25,231 @@
 #include "svgint.h"
 
 svg_status_t
-_svg_text_init (svg_text_t *text)
+_svg_tspan_init (svg_tspan_t *tspan)
 {
-    text->chars = NULL;
-    text->len = 0;
-    _svg_length_init_unit (&text->x, 0, SVG_LENGTH_UNIT_PX, SVG_LENGTH_ORIENTATION_HORIZONTAL);
-    _svg_length_init_unit (&text->y, 0, SVG_LENGTH_UNIT_PX, SVG_LENGTH_ORIENTATION_VERTICAL);
-
+    tspan->chars = NULL;
+    tspan->len = 0;
     return SVG_STATUS_SUCCESS;
 }
 
 svg_status_t
-_svg_text_init_copy (svg_text_t *text,
-		     svg_text_t *other)
+_svg_tspan_init_copy (svg_tspan_t *tspan,
+		     svg_tspan_t *other)
 {
-    text->x = other->x;
-    text->y = other->y;
-
-    text->len = other->len;
-    if (text->len) {
-	text->chars = malloc (text->len + 1);
-	if (text->chars == NULL)
+    tspan->len = other->len;
+    if (tspan->len) {
+	tspan->chars = malloc (tspan->len + 1);
+	if (tspan->chars == NULL)
 	    return SVG_STATUS_NO_MEMORY;
-	memcpy (text->chars, other->chars, text->len);
-	text->chars[text->len] = '\0';
+	memcpy (tspan->chars, other->chars, tspan->len);
+	tspan->chars[tspan->len] = '\0';
     } else {
-	text->chars = NULL;
+	tspan->chars = NULL;
     }
 
     return SVG_STATUS_SUCCESS;
 }
 
 svg_status_t
-_svg_text_deinit (svg_text_t *text)
+_svg_tspan_deinit (svg_tspan_t *tspan)
 {
-    free (text->chars);
-    text->len = 0;
+    free (tspan->chars);
+    tspan->len = 0;
 
     return SVG_STATUS_SUCCESS;
 }
 
 svg_status_t
-_svg_text_append_chars (svg_text_t	*text,
+_svg_tspan_append_chars (svg_tspan_t	*tspan,
 			const char	*chars,
 			int		len)
 {
     char *new_chars;
 
-    text->len += len;
+    tspan->len += len;
 
-    new_chars = realloc (text->chars, text->len + 1);
+    new_chars = realloc (tspan->chars, tspan->len + 1);
     if (new_chars == NULL) {
-	text->len -= len;
+	tspan->len -= len;
 	return SVG_STATUS_NO_MEMORY;
     }
 
-    if (text->chars == NULL)
+    if (tspan->chars == NULL)
 	new_chars[0] = '\0';
-    text->chars = new_chars;
-    strncat (text->chars, chars, len);
+    tspan->chars = new_chars;
+    strncat (tspan->chars, chars, len);
+
+    return SVG_STATUS_SUCCESS;
+}
+
+svg_status_t
+_svg_tspan_render (svg_tspan_t		*tspan,
+		   double		x,
+		   double		y,
+		   svg_render_engine_t	*engine,
+		   void			*closure)
+{
+    return (engine->render_text) (closure, x, y, tspan->chars);
+}
+
+svg_status_t
+_svg_tspan_apply_attributes (svg_tspan_t	*tspan,
+			     const char		**attributes)
+{
+#if 0
+    _svg_attribute_get_lengths (attributes, "x", &tspan->x, "");
+    _svg_attribute_get_lengths (attributes, "y", &tspan->y, "");
+    _svg_attribute_get_lengths (attributes, "dx", &tspan->dx, "");
+    _svg_attribute_get_lengths (attributes, "dy", &tspan->dy, "");
+#endif
+
+    /* XXX: What else goes here? */
+
+    return SVG_STATUS_SUCCESS;
+}
+
+svg_status_t
+_svg_tspan_extents (svg_tspan_t		*tspan,
+		    double		*width,
+		    double		*height,
+		    svg_render_engine_t	*engine,
+		    void		*closure)
+{
+    return (engine->text_extents) (closure,
+				   tspan->chars,
+				   width, height);
+}
+
+
+svg_status_t
+_svg_text_init (svg_text_t *text)
+{
+    _svg_group_init (&text->group);
+    return SVG_STATUS_SUCCESS;
+}
+
+svg_status_t
+_svg_text_init_copy (svg_text_t *text,
+		     svg_text_t *other)
+{
+    svg_status_t status;
+    
+    status = _svg_group_init_copy (&text->group, &other->group);
+    if (status)
+	return status;
 
     return SVG_STATUS_SUCCESS;
 }
 
 svg_status_t
+_svg_text_deinit (svg_text_t *text)
+{
+    _svg_group_deinit (&text->group);
+
+    return SVG_STATUS_SUCCESS;
+}
+
+static svg_status_t
+_svg_text_prepare_tspan (svg_element_t *element,
+			 svg_render_engine_t *engine,
+			 void *closure)
+{
+    svg_transform_t transform = element->transform;
+    svg_status_t status;
+    
+    status = _svg_transform_render (&transform, engine, closure);
+    if (status)
+	return status;
+
+    status = _svg_style_render (&element->style, engine, closure);
+    if (status)
+	return status;
+    return SVG_STATUS_SUCCESS;
+}
+
+svg_status_t
 _svg_text_render (svg_text_t		*text,
 		  svg_render_engine_t	*engine,
 		  void			*closure)
 {
-    return (engine->render_text) (closure,
-				  &text->x, &text->y,
-				  text->chars);
+    double		x, y;
+    int			e;
+    double		w, h;
+    svg_status_t	status = SVG_STATUS_SUCCESS;
+
+    (engine->measure_position) (closure,
+				&text->group.x, &text->group.y, &x, &y);
+    for (e = 0; e < text->group.num_elements; e++)
+    {
+	status = (engine->begin_element) (closure);
+	if (status)
+	    return status;
+	status = _svg_text_prepare_tspan (text->group.element[e],
+					  engine, closure);
+	if (status)
+	    break;
+	status = _svg_tspan_render (&text->group.element[e]->e.tspan,
+				    x, y, engine, closure);
+	if (status)
+	    break;
+	status = _svg_tspan_extents (&text->group.element[e]->e.tspan,
+				     &w, &h, engine, closure);
+	if (status)
+	    return status;
+	status = (engine->end_element) (closure);
+	if (status)
+	    break;
+	x += w;
+	y += h;
+    }
+    return status;
 }
 
 svg_status_t
 _svg_text_apply_attributes (svg_text_t		*text,
 			    const char		**attributes)
 {
-    _svg_attribute_get_length (attributes, "x", &text->x, "0");
-    _svg_attribute_get_length (attributes, "y", &text->y, "0");
+    _svg_attribute_get_length (attributes, "x", &text->group.x, "0");
+    _svg_attribute_get_length (attributes, "y", &text->group.y, "0");
 
     /* XXX: What else goes here? */
 
     return SVG_STATUS_SUCCESS;
 }
+
+svg_status_t
+_svg_text_extents (svg_text_t		*text,
+		   double		*width,
+		   double		*height,
+		   svg_render_engine_t	*engine,
+		   void			*closure)
+{
+    int		    e;
+    double	    x = 0, y = 0;
+    double	    w, h;
+    svg_status_t    status;
+
+    
+    for (e = 0; e < text->group.num_elements; e++)
+    {
+	status = (engine->begin_element) (closure);
+	if (status)
+	    return status;
+	status = _svg_text_prepare_tspan (text->group.element[e],
+					  engine, closure);
+	if (status)
+	    return status;
+	status = _svg_tspan_extents (&text->group.element[e]->e.tspan,
+				     &w, &h, engine, closure);
+	if (status)
+	    return status;
+	status = (engine->end_element) (closure);
+	if (status)
+	    return status;
+	x += w;
+	y += h;
+    }
+    *width = x;
+    *height = y;
+    return SVG_STATUS_SUCCESS;
+}

Index: svgint.h
===================================================================
RCS file: /cvs/cairo/libsvg/src/svgint.h,v
retrieving revision 1.45
retrieving revision 1.46
diff -u -d -r1.45 -r1.46
--- svgint.h	3 Jun 2005 16:23:32 -0000	1.45
+++ svgint.h	18 Jul 2005 21:55:06 -0000	1.46
@@ -234,11 +234,13 @@
     svg_length_t y;
 };
 
-typedef struct svg_text {
-    svg_length_t x;
-    svg_length_t y;
+typedef struct svg_tspan {
     char *chars;
     unsigned int len;
+} svg_tspan_t;
+
+typedef struct svg_text {
+    struct svg_group group;
 } svg_text_t;
 
 typedef struct svg_ellipse {
@@ -290,6 +292,7 @@
     SVG_ELEMENT_TYPE_LINE,
     SVG_ELEMENT_TYPE_RECT,
     SVG_ELEMENT_TYPE_TEXT,
+    SVG_ELEMENT_TYPE_TSPAN,
     SVG_ELEMENT_TYPE_GRADIENT,
     SVG_ELEMENT_TYPE_GRADIENT_STOP,
     SVG_ELEMENT_TYPE_PATTERN,
@@ -316,6 +319,7 @@
 	svg_line_t line;
 	svg_rect_element_t rect;
 	svg_text_t text;
+	svg_tspan_t tspan;
 	svg_image_t image;
 	svg_gradient_t gradient;
 	svg_gradient_stop_t gradient_stop;
@@ -342,6 +346,7 @@
     const svg_parser_cb_t	*cb;
     svg_element_t		*group_element;
     svg_text_t			*text;
+    svg_tspan_t			*tspan;
 
     struct svg_parser_state	*next;
 } svg_parser_state_t;
@@ -847,6 +852,39 @@
 /* svg_text.c */
 
 svg_status_t
+_svg_tspan_init (svg_tspan_t *tspan);
+
+svg_status_t
+_svg_tspan_init_copy (svg_tspan_t *tspan,
+		      svg_tspan_t *other);
+
+svg_status_t
+_svg_tspan_deinit (svg_tspan_t *tspan);
+
+svg_status_t
+_svg_tspan_append_chars (svg_tspan_t	*tspan,
+			 const char	*chars,
+			 int		len);
+
+svg_status_t
+_svg_tspan_render (svg_tspan_t		*text,
+		   double		x,
+		   double		y,
+		   svg_render_engine_t	*engine,
+		   void			*closure);
+
+svg_status_t
+_svg_tspan_apply_attributes (svg_tspan_t	*tspan,
+			     const char		**attributes);
+
+svg_status_t
+_svg_tspan_extents (svg_tspan_t		*text,
+		    double		*width,
+		    double		*height,
+		    svg_render_engine_t	*engine,
+		    void		*closure);
+
+svg_status_t
 _svg_text_init (svg_text_t *text);
 
 svg_status_t
@@ -870,6 +908,13 @@
 _svg_text_apply_attributes (svg_text_t		*text,
 			    const char		**attributes);
 
+svg_status_t
+_svg_text_extents (svg_text_t		*text,
+		   double		*width,
+		   double		*height,
+		   svg_render_engine_t	*engine,
+		   void			*closure);
+
 /* svg_transform.c */
 
 svg_status_t




More information about the cairo-commit mailing list