[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