From 61856750e7a0419d24e834f5d912511fab6244a3 Mon Sep 17 00:00:00 2001 From: Daniel Silverstone Date: Sat, 3 Nov 2012 10:32:06 +0000 Subject: Add an example SVG and a gitignore --- .gitignore | 1 + examples/tiger.svg | 730 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 731 insertions(+) create mode 100644 .gitignore create mode 100644 examples/tiger.svg diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..dd07bff --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +build-* diff --git a/examples/tiger.svg b/examples/tiger.svg new file mode 100644 index 0000000..983e570 --- /dev/null +++ b/examples/tiger.svg @@ -0,0 +1,730 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -- cgit v1.2.1 From d03a7471001c4701e1fea976aee162b0de375f52 Mon Sep 17 00:00:00 2001 From: Daniel Silverstone Date: Sat, 3 Nov 2012 12:05:13 +0000 Subject: Begin conversion to libdom --- Makefile | 13 ++--- include/svgtiny.h | 4 +- src/svgtiny.c | 140 ++++++++++++++++++++++++++++++++++--------------- src/svgtiny_internal.h | 6 ++- 4 files changed, 108 insertions(+), 55 deletions(-) diff --git a/Makefile b/Makefile index fe4cfe7..cb393a7 100644 --- a/Makefile +++ b/Makefile @@ -31,18 +31,15 @@ else CFLAGS := $(CFLAGS) -Dinline="__inline__" endif -# LibXML2 +# libdom ifneq ($(PKGCONFIG),) CFLAGS := $(CFLAGS) \ - $(shell $(PKGCONFIG) $(PKGCONFIGFLAGS) --cflags libxml-2.0) + $(shell $(PKGCONFIG) $(PKGCONFIGFLAGS) --cflags libdom) LDFLAGS := $(LDFLAGS) \ - $(shell $(PKGCONFIG) $(PKGCONFIGFLAGS) --libs libxml-2.0) + $(shell $(PKGCONFIG) $(PKGCONFIGFLAGS) --libs libdom) else - ifeq ($(TARGET),beos) - CFLAGS := $(CFLAGS) -I/boot/home/config/include/libxml2 - endif - CFLAGS := $(CFLAGS) -I$(PREFIX)/include/libxml2 - LDFLAGS := $(CFLAGS) -lxml2 + CFLAGS := $(CFLAGS) -I$(PREFIX)/include + LDFLAGS := $(CFLAGS) -ldom endif include $(NSBUILD)/Makefile.top diff --git a/include/svgtiny.h b/include/svgtiny.h index 9d685e9..85f146f 100644 --- a/include/svgtiny.h +++ b/include/svgtiny.h @@ -8,8 +8,6 @@ #ifndef SVGTINY_H #define SVGTINY_H -#include - typedef int svgtiny_colour; #define svgtiny_TRANSPARENT 0x1000000 #ifdef __riscos__ @@ -47,7 +45,7 @@ struct svgtiny_diagram { typedef enum { svgtiny_OK, svgtiny_OUT_OF_MEMORY, - svgtiny_LIBXML_ERROR, + svgtiny_LIBDOM_ERROR, svgtiny_NOT_SVG, svgtiny_SVG_ERROR } svgtiny_code; diff --git a/src/svgtiny.c b/src/svgtiny.c index 8fa09a5..ac13d7a 100644 --- a/src/svgtiny.c +++ b/src/svgtiny.c @@ -3,6 +3,7 @@ * Licensed under the MIT License, * http://opensource.org/licenses/mit-license.php * Copyright 2008-2009 James Bursa + * Copyright 2012 Daniel Silverstone */ #include @@ -12,8 +13,10 @@ #include #include #include -#include -#include + +#include +#include + #include "svgtiny.h" #include "svgtiny_internal.h" @@ -23,30 +26,30 @@ #define KAPPA 0.5522847498 -static svgtiny_code svgtiny_parse_svg(xmlNode *svg, +static svgtiny_code svgtiny_parse_svg(dom_node *svg, struct svgtiny_parse_state state); -static svgtiny_code svgtiny_parse_path(xmlNode *path, +static svgtiny_code svgtiny_parse_path(dom_node *path, struct svgtiny_parse_state state); -static svgtiny_code svgtiny_parse_rect(xmlNode *rect, +static svgtiny_code svgtiny_parse_rect(dom_node *rect, struct svgtiny_parse_state state); -static svgtiny_code svgtiny_parse_circle(xmlNode *circle, +static svgtiny_code svgtiny_parse_circle(dom_node *circle, struct svgtiny_parse_state state); -static svgtiny_code svgtiny_parse_ellipse(xmlNode *ellipse, +static svgtiny_code svgtiny_parse_ellipse(dom_node *ellipse, struct svgtiny_parse_state state); -static svgtiny_code svgtiny_parse_line(xmlNode *line, +static svgtiny_code svgtiny_parse_line(dom_node *line, struct svgtiny_parse_state state); -static svgtiny_code svgtiny_parse_poly(xmlNode *poly, +static svgtiny_code svgtiny_parse_poly(dom_node *poly, struct svgtiny_parse_state state, bool polygon); -static svgtiny_code svgtiny_parse_text(xmlNode *text, +static svgtiny_code svgtiny_parse_text(dom_node *text, struct svgtiny_parse_state state); -static void svgtiny_parse_position_attributes(const xmlNode *node, +static void svgtiny_parse_position_attributes(const dom_node *node, const struct svgtiny_parse_state state, float *x, float *y, float *width, float *height); -static void svgtiny_parse_paint_attributes(const xmlNode *node, +static void svgtiny_parse_paint_attributes(const dom_node *node, struct svgtiny_parse_state *state); -static void svgtiny_parse_font_attributes(const xmlNode *node, +static void svgtiny_parse_font_attributes(const dom_node *node, struct svgtiny_parse_state *state); -static void svgtiny_parse_transform_attributes(xmlNode *node, +static void svgtiny_parse_transform_attributes(dom_node *node, struct svgtiny_parse_state *state); static svgtiny_code svgtiny_add_path(float *p, unsigned int n, struct svgtiny_parse_state *state); @@ -72,6 +75,12 @@ struct svgtiny_diagram *svgtiny_create(void) return diagram; } +static void ignore_msg(uint32_t severity, void *ctx, const char *msg, ...) +{ + UNUSED(severity); + UNUSED(ctx); + UNUSED(msg); +} /** * Parse a block of memory into a svgtiny_diagram. @@ -81,8 +90,13 @@ svgtiny_code svgtiny_parse(struct svgtiny_diagram *diagram, const char *buffer, size_t size, const char *url, int viewport_width, int viewport_height) { - xmlDoc *document; - xmlNode *svg; + dom_document *document; + dom_exception exc; + dom_xml_parser *parser; + dom_xml_error err; + dom_node *svg; + dom_string *svg_name; + lwc_string *svg_name_lwc; struct svgtiny_parse_state state; float x, y, width, height; svgtiny_code code; @@ -91,20 +105,62 @@ svgtiny_code svgtiny_parse(struct svgtiny_diagram *diagram, assert(buffer); assert(url); - /* parse XML to tree */ - document = xmlReadMemory(buffer, size, url, 0, - XML_PARSE_NONET | XML_PARSE_COMPACT); - if (!document) - return svgtiny_LIBXML_ERROR; + UNUSED(url); + + parser = dom_xml_parser_create(NULL, NULL, + ignore_msg, NULL, &document); + + if (parser == NULL) + return svgtiny_LIBDOM_ERROR; + + err = dom_xml_parser_parse_chunk(parser, (uint8_t *)buffer, size); + if (err != DOM_XML_OK) { + dom_node_unref(document); + dom_xml_parser_destroy(parser); + return svgtiny_LIBDOM_ERROR; + } + + err = dom_xml_parser_completed(parser); + if (err != DOM_XML_OK) { + dom_node_unref(document); + dom_xml_parser_destroy(parser); + return svgtiny_LIBDOM_ERROR; + } - /*xmlDebugDumpDocument(stderr, document);*/ + /* We're done parsing, drop the parser. + * We now own the document entirely. + */ + dom_xml_parser_destroy(parser); /* find root element */ - svg = xmlDocGetRootElement(document); - if (!svg) - return svgtiny_NOT_SVG; - if (strcmp((const char *) svg->name, "svg") != 0) + exc = dom_document_get_document_element(document, &svg); + if (exc != DOM_NO_ERR) { + dom_node_unref(document); + return svgtiny_LIBDOM_ERROR; + } + exc = dom_node_get_node_name(svg, &svg_name); + if (exc != DOM_NO_ERR) { + dom_node_unref(svg); + dom_node_unref(document); + return svgtiny_LIBDOM_ERROR; + } + if (lwc_intern_string("svg", 3 /* SLEN("svg") */, + &svg_name_lwc) != lwc_error_ok) { + dom_string_unref(svg_name); + dom_node_unref(svg); + dom_node_unref(document); + return svgtiny_LIBDOM_ERROR; + } + if (!dom_string_caseless_lwc_isequal(svg_name, svg_name_lwc)) { + lwc_string_unref(svg_name_lwc); + dom_string_unref(svg_name); + dom_node_unref(svg); + dom_node_unref(document); return svgtiny_NOT_SVG; + } + + lwc_string_unref(svg_name_lwc); + dom_string_unref(svg_name); /* get graphic dimensions */ state.diagram = diagram; @@ -134,8 +190,8 @@ svgtiny_code svgtiny_parse(struct svgtiny_diagram *diagram, /* parse tree */ code = svgtiny_parse_svg(svg, state); - /* free XML tree */ - xmlFreeDoc(document); + dom_node_unref(svg); + dom_node_unref(document); return code; } @@ -145,12 +201,12 @@ svgtiny_code svgtiny_parse(struct svgtiny_diagram *diagram, * Parse a or element node. */ -svgtiny_code svgtiny_parse_svg(xmlNode *svg, +svgtiny_code svgtiny_parse_svg(dom_node *svg, struct svgtiny_parse_state state) { float x, y, width, height; xmlAttr *view_box; - xmlNode *child; + dom_node *child; svgtiny_parse_position_attributes(svg, state, &x, &y, &width, &height); svgtiny_parse_paint_attributes(svg, &state); @@ -218,7 +274,7 @@ svgtiny_code svgtiny_parse_svg(xmlNode *svg, * http://www.w3.org/TR/SVG11/paths#PathElement */ -svgtiny_code svgtiny_parse_path(xmlNode *path, +svgtiny_code svgtiny_parse_path(dom_node *path, struct svgtiny_parse_state state) { char *s, *path_d; @@ -450,7 +506,7 @@ svgtiny_code svgtiny_parse_path(xmlNode *path, * http://www.w3.org/TR/SVG11/shapes#RectElement */ -svgtiny_code svgtiny_parse_rect(xmlNode *rect, +svgtiny_code svgtiny_parse_rect(dom_node *rect, struct svgtiny_parse_state state) { float x, y, width, height; @@ -487,7 +543,7 @@ svgtiny_code svgtiny_parse_rect(xmlNode *rect, * Parse a element node. */ -svgtiny_code svgtiny_parse_circle(xmlNode *circle, +svgtiny_code svgtiny_parse_circle(dom_node *circle, struct svgtiny_parse_state state) { float x = 0, y = 0, r = -1; @@ -563,7 +619,7 @@ svgtiny_code svgtiny_parse_circle(xmlNode *circle, * Parse an element node. */ -svgtiny_code svgtiny_parse_ellipse(xmlNode *ellipse, +svgtiny_code svgtiny_parse_ellipse(dom_node *ellipse, struct svgtiny_parse_state state) { float x = 0, y = 0, rx = -1, ry = -1; @@ -643,7 +699,7 @@ svgtiny_code svgtiny_parse_ellipse(xmlNode *ellipse, * Parse a element node. */ -svgtiny_code svgtiny_parse_line(xmlNode *line, +svgtiny_code svgtiny_parse_line(dom_node *line, struct svgtiny_parse_state state) { float x1 = 0, y1 = 0, x2 = 0, y2 = 0; @@ -692,7 +748,7 @@ svgtiny_code svgtiny_parse_line(xmlNode *line, * http://www.w3.org/TR/SVG11/shapes#PolygonElement */ -svgtiny_code svgtiny_parse_poly(xmlNode *poly, +svgtiny_code svgtiny_parse_poly(dom_node *poly, struct svgtiny_parse_state state, bool polygon) { char *s, *points; @@ -752,12 +808,12 @@ svgtiny_code svgtiny_parse_poly(xmlNode *poly, * Parse a or element node. */ -svgtiny_code svgtiny_parse_text(xmlNode *text, +svgtiny_code svgtiny_parse_text(dom_node *text, struct svgtiny_parse_state state) { float x, y, width, height; float px, py; - xmlNode *child; + dom_node *child; svgtiny_parse_position_attributes(text, state, &x, &y, &width, &height); @@ -802,7 +858,7 @@ svgtiny_code svgtiny_parse_text(xmlNode *text, * Parse x, y, width, and height attributes, if present. */ -void svgtiny_parse_position_attributes(const xmlNode *node, +void svgtiny_parse_position_attributes(const dom_node *node, const struct svgtiny_parse_state state, float *x, float *y, float *width, float *height) { @@ -876,7 +932,7 @@ float svgtiny_parse_length(const char *s, int viewport_size, * Parse paint attributes, if present. */ -void svgtiny_parse_paint_attributes(const xmlNode *node, +void svgtiny_parse_paint_attributes(const dom_node *node, struct svgtiny_parse_state *state) { const xmlAttr *attr; @@ -994,7 +1050,7 @@ void svgtiny_parse_color(const char *s, svgtiny_colour *c, * Parse font attributes, if present. */ -void svgtiny_parse_font_attributes(const xmlNode *node, +void svgtiny_parse_font_attributes(const dom_node *node, struct svgtiny_parse_state *state) { const xmlAttr *attr; @@ -1021,7 +1077,7 @@ void svgtiny_parse_font_attributes(const xmlNode *node, * http://www.w3.org/TR/SVG11/coords#TransformAttribute */ -void svgtiny_parse_transform_attributes(xmlNode *node, +void svgtiny_parse_transform_attributes(dom_node *node, struct svgtiny_parse_state *state) { char *transform; diff --git a/src/svgtiny_internal.h b/src/svgtiny_internal.h index eb90c5b..789651a 100644 --- a/src/svgtiny_internal.h +++ b/src/svgtiny_internal.h @@ -10,6 +10,8 @@ #include +#include + #ifndef UNUSED #define UNUSED(x) ((void) (x)) #endif @@ -24,7 +26,7 @@ struct svgtiny_gradient_stop { struct svgtiny_parse_state { struct svgtiny_diagram *diagram; - xmlDoc *document; + dom_document *document; float viewport_width; float viewport_height; @@ -75,7 +77,7 @@ char *svgtiny_strndup(const char *s, size_t n); void svgtiny_find_gradient(const char *id, struct svgtiny_parse_state *state); svgtiny_code svgtiny_add_path_linear_gradient(float *p, unsigned int n, struct svgtiny_parse_state *state); -xmlNode *svgtiny_find_element_by_id(xmlNode *node, const char *id); +dom_node *svgtiny_find_element_by_id(dom_node *node, const char *id); /* svgtiny_list.c */ struct svgtiny_list *svgtiny_list_create(size_t item_size); -- cgit v1.2.1 From 3ac494551acba0e966aea4dd0aad624578b8256c Mon Sep 17 00:00:00 2001 From: Daniel Silverstone Date: Sat, 3 Nov 2012 14:13:41 +0000 Subject: Ignore ~ files --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index dd07bff..015f2f7 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ build-* +*~ -- cgit v1.2.1 From ccc89083064d413c6785e1b740cf8e23c2eb4cfa Mon Sep 17 00:00:00 2001 From: Daniel Silverstone Date: Sat, 3 Nov 2012 14:13:47 +0000 Subject: More work to bring svgtiny into the libdom era --- src/svgtiny.c | 163 +++++++++++++++++++++++++++++++++---------------- src/svgtiny_internal.h | 6 ++ src/svgtiny_strings.h | 22 +++++++ 3 files changed, 138 insertions(+), 53 deletions(-) create mode 100644 src/svgtiny_strings.h diff --git a/src/svgtiny.c b/src/svgtiny.c index ac13d7a..63c7cc2 100644 --- a/src/svgtiny.c +++ b/src/svgtiny.c @@ -26,30 +26,30 @@ #define KAPPA 0.5522847498 -static svgtiny_code svgtiny_parse_svg(dom_node *svg, +static svgtiny_code svgtiny_parse_svg(dom_element *svg, struct svgtiny_parse_state state); -static svgtiny_code svgtiny_parse_path(dom_node *path, +static svgtiny_code svgtiny_parse_path(dom_element *path, struct svgtiny_parse_state state); -static svgtiny_code svgtiny_parse_rect(dom_node *rect, +static svgtiny_code svgtiny_parse_rect(dom_element *rect, struct svgtiny_parse_state state); -static svgtiny_code svgtiny_parse_circle(dom_node *circle, +static svgtiny_code svgtiny_parse_circle(dom_element *circle, struct svgtiny_parse_state state); -static svgtiny_code svgtiny_parse_ellipse(dom_node *ellipse, +static svgtiny_code svgtiny_parse_ellipse(dom_element *ellipse, struct svgtiny_parse_state state); -static svgtiny_code svgtiny_parse_line(dom_node *line, +static svgtiny_code svgtiny_parse_line(dom_element *line, struct svgtiny_parse_state state); -static svgtiny_code svgtiny_parse_poly(dom_node *poly, +static svgtiny_code svgtiny_parse_poly(dom_element *poly, struct svgtiny_parse_state state, bool polygon); -static svgtiny_code svgtiny_parse_text(dom_node *text, +static svgtiny_code svgtiny_parse_text(dom_element *text, struct svgtiny_parse_state state); -static void svgtiny_parse_position_attributes(const dom_node *node, +static void svgtiny_parse_position_attributes(const dom_element *node, const struct svgtiny_parse_state state, float *x, float *y, float *width, float *height); -static void svgtiny_parse_paint_attributes(const dom_node *node, +static void svgtiny_parse_paint_attributes(const dom_element *node, struct svgtiny_parse_state *state); -static void svgtiny_parse_font_attributes(const dom_node *node, +static void svgtiny_parse_font_attributes(const dom_element *node, struct svgtiny_parse_state *state); -static void svgtiny_parse_transform_attributes(dom_node *node, +static void svgtiny_parse_transform_attributes(dom_element *node, struct svgtiny_parse_state *state); static svgtiny_code svgtiny_add_path(float *p, unsigned int n, struct svgtiny_parse_state *state); @@ -63,16 +63,13 @@ struct svgtiny_diagram *svgtiny_create(void) { struct svgtiny_diagram *diagram; - diagram = malloc(sizeof *diagram); + diagram = calloc(sizeof(*diagram), 1); if (!diagram) return 0; - diagram->shape = 0; - diagram->shape_count = 0; - diagram->error_line = 0; - diagram->error_message = 0; - return diagram; + free(diagram); + return NULL; } static void ignore_msg(uint32_t severity, void *ctx, const char *msg, ...) @@ -94,7 +91,7 @@ svgtiny_code svgtiny_parse(struct svgtiny_diagram *diagram, dom_exception exc; dom_xml_parser *parser; dom_xml_error err; - dom_node *svg; + dom_element *svg; dom_string *svg_name; lwc_string *svg_name_lwc; struct svgtiny_parse_state state; @@ -167,6 +164,17 @@ svgtiny_code svgtiny_parse(struct svgtiny_diagram *diagram, state.document = document; state.viewport_width = viewport_width; state.viewport_height = viewport_height; + +#define SVGTINY_STRING_ACTION(s) \ + if (dom_string_create_interned((const uint8_t *) #s, \ + strlen(#s), &state.interned_##s) \ + != DOM_NO_ERR) { \ + code = svgtiny_LIBDOM_ERROR; \ + goto cleanup; \ + } +#include "svgtiny_strings.h" +#undef SVGTINY_STRING_ACTION + svgtiny_parse_position_attributes(svg, state, &x, &y, &width, &height); diagram->width = width; diagram->height = height; @@ -193,6 +201,12 @@ svgtiny_code svgtiny_parse(struct svgtiny_diagram *diagram, dom_node_unref(svg); dom_node_unref(document); +cleanup: +#define SVGTINY_STRING_ACTION(s) \ + if (state.interned_##s != NULL) \ + dom_string_unref(state.interned_##s); +//#include "svgtiny_strings.h" +#undef SVGTINY_STRING_ACTION return code; } @@ -201,21 +215,27 @@ svgtiny_code svgtiny_parse(struct svgtiny_diagram *diagram, * Parse a or element node. */ -svgtiny_code svgtiny_parse_svg(dom_node *svg, +svgtiny_code svgtiny_parse_svg(dom_element *svg, struct svgtiny_parse_state state) { float x, y, width, height; - xmlAttr *view_box; - dom_node *child; + dom_string *view_box; + dom_element *child; + dom_exception exc; svgtiny_parse_position_attributes(svg, state, &x, &y, &width, &height); svgtiny_parse_paint_attributes(svg, &state); svgtiny_parse_font_attributes(svg, &state); - /* parse viewBox */ - view_box = xmlHasProp(svg, (const xmlChar *) "viewBox"); + exc = dom_element_get_attribute(svg, state.interned_viewBox, + &view_box); + if (exc != DOM_NO_ERR) { + return svgtiny_LIBDOM_ERROR; + } + if (view_box) { - const char *s = (const char *) view_box->children->content; + char *s = strndup(dom_string_data(view_box), + dom_string_length(view_box)); float min_x, min_y, vwidth, vheight; if (sscanf(s, "%f,%f,%f,%f", &min_x, &min_y, &vwidth, &vheight) == 4 || @@ -226,41 +246,78 @@ svgtiny_code svgtiny_parse_svg(dom_node *svg, state.ctm.e += -min_x * state.ctm.a; state.ctm.f += -min_y * state.ctm.d; } + free(s); + dom_string_unref(view_box); } svgtiny_parse_transform_attributes(svg, &state); - for (child = svg->children; child; child = child->next) { + exc = dom_node_get_first_child(svg, &child); + if (exc != DOM_NO_ERR) { + return svgtiny_LIBDOM_ERROR; + } + while (child != NULL) { + dom_element *next; + dom_node_type nodetype; svgtiny_code code = svgtiny_OK; - if (child->type == XML_ELEMENT_NODE) { - const char *name = (const char *) child->name; - if (strcmp(name, "svg") == 0) + exc = dom_node_get_node_type(child, &nodetype); + if (exc != DOM_NO_ERR) { + dom_node_unref(child); + return svgtiny_LIBDOM_ERROR; + } + if (nodetype == DOM_ELEMENT_NODE) { + dom_string *nodename; + exc = dom_node_get_node_name(child, &nodename); + if (exc != DOM_NO_ERR) { + dom_node_unref(child); + return svgtiny_LIBDOM_ERROR; + } + if (dom_string_caseless_isequal(state.interned_svg, + nodename)) code = svgtiny_parse_svg(child, state); - else if (strcmp(name, "g") == 0) + else if (dom_string_caseless_isequal(state.interned_g, + nodename)) code = svgtiny_parse_svg(child, state); - else if (strcmp(name, "a") == 0) + else if (dom_string_caseless_isequal(state.interned_a, + nodename)) code = svgtiny_parse_svg(child, state); - else if (strcmp(name, "path") == 0) + else if (dom_string_caseless_isequal(state.interned_path, + nodename)) code = svgtiny_parse_path(child, state); - else if (strcmp(name, "rect") == 0) + else if (dom_string_caseless_isequal(state.interned_rect, + nodename)) code = svgtiny_parse_rect(child, state); - else if (strcmp(name, "circle") == 0) + else if (dom_string_caseless_isequal(state.interned_circle, + nodename)) code = svgtiny_parse_circle(child, state); - else if (strcmp(name, "ellipse") == 0) + else if (dom_string_caseless_isequal(state.interned_ellipse, + nodename)) code = svgtiny_parse_ellipse(child, state); - else if (strcmp(name, "line") == 0) + else if (dom_string_caseless_isequal(state.interned_line, + nodename)) code = svgtiny_parse_line(child, state); - else if (strcmp(name, "polyline") == 0) + else if (dom_string_caseless_isequal(state.interned_polyline, + nodename)) code = svgtiny_parse_poly(child, state, false); - else if (strcmp(name, "polygon") == 0) + else if (dom_string_caseless_isequal(state.interned_polygon, + nodename)) code = svgtiny_parse_poly(child, state, true); - else if (strcmp(name, "text") == 0) + else if (dom_string_caseless_isequal(state.interned_text, + nodename)) code = svgtiny_parse_text(child, state); + dom_string_unref(nodename); } - - if (code != svgtiny_OK) + if (code != svgtiny_OK) { + dom_node_unref(child); return code; + } + exc = dom_node_get_next_sibling(child, &next); + dom_node_unref(child); + if (exc != DOM_NO_ERR) { + return svgtiny_LIBDOM_ERROR; + } + child = next; } return svgtiny_OK; @@ -274,7 +331,7 @@ svgtiny_code svgtiny_parse_svg(dom_node *svg, * http://www.w3.org/TR/SVG11/paths#PathElement */ -svgtiny_code svgtiny_parse_path(dom_node *path, +svgtiny_code svgtiny_parse_path(dom_element *path, struct svgtiny_parse_state state) { char *s, *path_d; @@ -506,7 +563,7 @@ svgtiny_code svgtiny_parse_path(dom_node *path, * http://www.w3.org/TR/SVG11/shapes#RectElement */ -svgtiny_code svgtiny_parse_rect(dom_node *rect, +svgtiny_code svgtiny_parse_rect(dom_element *rect, struct svgtiny_parse_state state) { float x, y, width, height; @@ -543,7 +600,7 @@ svgtiny_code svgtiny_parse_rect(dom_node *rect, * Parse a element node. */ -svgtiny_code svgtiny_parse_circle(dom_node *circle, +svgtiny_code svgtiny_parse_circle(dom_element *circle, struct svgtiny_parse_state state) { float x = 0, y = 0, r = -1; @@ -619,7 +676,7 @@ svgtiny_code svgtiny_parse_circle(dom_node *circle, * Parse an element node. */ -svgtiny_code svgtiny_parse_ellipse(dom_node *ellipse, +svgtiny_code svgtiny_parse_ellipse(dom_element *ellipse, struct svgtiny_parse_state state) { float x = 0, y = 0, rx = -1, ry = -1; @@ -699,7 +756,7 @@ svgtiny_code svgtiny_parse_ellipse(dom_node *ellipse, * Parse a element node. */ -svgtiny_code svgtiny_parse_line(dom_node *line, +svgtiny_code svgtiny_parse_line(dom_element *line, struct svgtiny_parse_state state) { float x1 = 0, y1 = 0, x2 = 0, y2 = 0; @@ -748,7 +805,7 @@ svgtiny_code svgtiny_parse_line(dom_node *line, * http://www.w3.org/TR/SVG11/shapes#PolygonElement */ -svgtiny_code svgtiny_parse_poly(dom_node *poly, +svgtiny_code svgtiny_parse_poly(dom_element *poly, struct svgtiny_parse_state state, bool polygon) { char *s, *points; @@ -808,12 +865,12 @@ svgtiny_code svgtiny_parse_poly(dom_node *poly, * Parse a or element node. */ -svgtiny_code svgtiny_parse_text(dom_node *text, +svgtiny_code svgtiny_parse_text(dom_element *text, struct svgtiny_parse_state state) { float x, y, width, height; float px, py; - dom_node *child; + dom_element *child; svgtiny_parse_position_attributes(text, state, &x, &y, &width, &height); @@ -858,7 +915,7 @@ svgtiny_code svgtiny_parse_text(dom_node *text, * Parse x, y, width, and height attributes, if present. */ -void svgtiny_parse_position_attributes(const dom_node *node, +void svgtiny_parse_position_attributes(const dom_element *node, const struct svgtiny_parse_state state, float *x, float *y, float *width, float *height) { @@ -932,7 +989,7 @@ float svgtiny_parse_length(const char *s, int viewport_size, * Parse paint attributes, if present. */ -void svgtiny_parse_paint_attributes(const dom_node *node, +void svgtiny_parse_paint_attributes(const dom_element *node, struct svgtiny_parse_state *state) { const xmlAttr *attr; @@ -1050,7 +1107,7 @@ void svgtiny_parse_color(const char *s, svgtiny_colour *c, * Parse font attributes, if present. */ -void svgtiny_parse_font_attributes(const dom_node *node, +void svgtiny_parse_font_attributes(const dom_element *node, struct svgtiny_parse_state *state) { const xmlAttr *attr; @@ -1077,7 +1134,7 @@ void svgtiny_parse_font_attributes(const dom_node *node, * http://www.w3.org/TR/SVG11/coords#TransformAttribute */ -void svgtiny_parse_transform_attributes(dom_node *node, +void svgtiny_parse_transform_attributes(dom_element *node, struct svgtiny_parse_state *state) { char *transform; diff --git a/src/svgtiny_internal.h b/src/svgtiny_internal.h index 789651a..77a6698 100644 --- a/src/svgtiny_internal.h +++ b/src/svgtiny_internal.h @@ -51,6 +51,12 @@ struct svgtiny_parse_state { struct { float a, b, c, d, e, f; } gradient_transform; + + /* Interned strings */ +#define SVGTINY_STRING_ACTION(n) dom_string *interned_##n; +#include "svgtiny_strings.h" +#undef SVGTINY_STRING_ACTION + }; struct svgtiny_list; diff --git a/src/svgtiny_strings.h b/src/svgtiny_strings.h new file mode 100644 index 0000000..265ab62 --- /dev/null +++ b/src/svgtiny_strings.h @@ -0,0 +1,22 @@ +/* This file is part of Libsvgtiny + * Licensed under the MIT License, + * http://opensource.org/licenses/mit-license.php + * Copyright 2012 Daniel Silverstone + */ + +#ifndef SVGTINY_STRING_ACTION +#error No action defined +#endif + +SVGTINY_STRING_ACTION(svg) +SVGTINY_STRING_ACTION(viewBox) +SVGTINY_STRING_ACTION(g) +SVGTINY_STRING_ACTION(a) +SVGTINY_STRING_ACTION(path) +SVGTINY_STRING_ACTION(rect) +SVGTINY_STRING_ACTION(circle) +SVGTINY_STRING_ACTION(ellipse) +SVGTINY_STRING_ACTION(line) +SVGTINY_STRING_ACTION(polyline) +SVGTINY_STRING_ACTION(polygon) +SVGTINY_STRING_ACTION(text) -- cgit v1.2.1 From 7edb291dd90bfac6736abca08f5549ad0961d3f8 Mon Sep 17 00:00:00 2001 From: Daniel Silverstone Date: Sat, 3 Nov 2012 14:35:11 +0000 Subject: Make more svg elements parse again --- src/svgtiny.c | 184 ++++++++++++++++++++++++++++++++++--------------- src/svgtiny_internal.h | 2 +- src/svgtiny_strings.h | 12 +++- 3 files changed, 139 insertions(+), 59 deletions(-) diff --git a/src/svgtiny.c b/src/svgtiny.c index 63c7cc2..9b2af32 100644 --- a/src/svgtiny.c +++ b/src/svgtiny.c @@ -334,6 +334,8 @@ svgtiny_code svgtiny_parse_svg(dom_element *svg, svgtiny_code svgtiny_parse_path(dom_element *path, struct svgtiny_parse_state state) { + dom_string *path_d_str; + dom_exception exc; char *s, *path_d; float *p; unsigned int i; @@ -345,17 +347,31 @@ svgtiny_code svgtiny_parse_path(dom_element *path, svgtiny_parse_transform_attributes(path, &state); /* read d attribute */ - s = path_d = (char *) xmlGetProp(path, (const xmlChar *) "d"); - if (!s) { - state.diagram->error_line = path->line; + exc = dom_element_get_attribute(path, state.interned_d, &path_d_str); + if (exc != DOM_NO_ERR) { + state.diagram->error_line = -1; /* path->line; */ + state.diagram->error_message = "path: error retrieving d attribute"; + return svgtiny_SVG_ERROR; + } + + if (path_d_str == NULL) { + state.diagram->error_line = -1; /* path->line; */ state.diagram->error_message = "path: missing d attribute"; return svgtiny_SVG_ERROR; } + s = path_d = strndup(dom_string_data(path_d_str), + dom_string_length(path_d_str)); + dom_string_unref(path_d_str); + if (s == NULL) { + return svgtiny_OUT_OF_MEMORY; + } /* allocate space for path: it will never have more elements than d */ p = malloc(sizeof p[0] * strlen(s)); - if (!p) + if (!p) { + free(path_d); return svgtiny_OUT_OF_MEMORY; + } /* parse d and build path */ for (i = 0; s[i]; i++) @@ -545,7 +561,7 @@ svgtiny_code svgtiny_parse_path(dom_element *path, } } - xmlFree(path_d); + free(path_d); if (i <= 4) { /* no real segments in path */ @@ -605,26 +621,38 @@ svgtiny_code svgtiny_parse_circle(dom_element *circle, { float x = 0, y = 0, r = -1; float *p; - xmlAttr *attr; + dom_string *attr; + dom_exception exc; + + exc = dom_element_get_attribute(circle, state.interned_cx, &attr); + if (exc != DOM_NO_ERR) + return svgtiny_LIBDOM_ERROR; + if (attr != NULL) { + x = svgtiny_parse_length(attr, state.viewport_width, state); + } + dom_string_unref(attr); + + exc = dom_element_get_attribute(circle, state.interned_cy, &attr); + if (exc != DOM_NO_ERR) + return svgtiny_LIBDOM_ERROR; + if (attr != NULL) { + y = svgtiny_parse_length(attr, state.viewport_height, state); + } + dom_string_unref(attr); + + exc = dom_element_get_attribute(circle, state.interned_r, &attr); + if (exc != DOM_NO_ERR) + return svgtiny_LIBDOM_ERROR; + if (attr != NULL) { + r = svgtiny_parse_length(attr, state.viewport_width, state); + } + dom_string_unref(attr); - for (attr = circle->properties; attr; attr = attr->next) { - const char *name = (const char *) attr->name; - const char *content = (const char *) attr->children->content; - if (strcmp(name, "cx") == 0) - x = svgtiny_parse_length(content, - state.viewport_width, state); - else if (strcmp(name, "cy") == 0) - y = svgtiny_parse_length(content, - state.viewport_height, state); - else if (strcmp(name, "r") == 0) - r = svgtiny_parse_length(content, - state.viewport_width, state); - } svgtiny_parse_paint_attributes(circle, &state); svgtiny_parse_transform_attributes(circle, &state); if (r < 0) { - state.diagram->error_line = circle->line; + state.diagram->error_line = -1; /* circle->line; */ state.diagram->error_message = "circle: r missing or negative"; return svgtiny_SVG_ERROR; } @@ -681,29 +709,46 @@ svgtiny_code svgtiny_parse_ellipse(dom_element *ellipse, { float x = 0, y = 0, rx = -1, ry = -1; float *p; - xmlAttr *attr; + dom_string *attr; + dom_exception exc; + + exc = dom_element_get_attribute(ellipse, state.interned_cx, &attr); + if (exc != DOM_NO_ERR) + return svgtiny_LIBDOM_ERROR; + if (attr != NULL) { + x = svgtiny_parse_length(attr, state.viewport_width, state); + } + dom_string_unref(attr); + + exc = dom_element_get_attribute(ellipse, state.interned_cy, &attr); + if (exc != DOM_NO_ERR) + return svgtiny_LIBDOM_ERROR; + if (attr != NULL) { + y = svgtiny_parse_length(attr, state.viewport_height, state); + } + dom_string_unref(attr); + + exc = dom_element_get_attribute(ellipse, state.interned_rx, &attr); + if (exc != DOM_NO_ERR) + return svgtiny_LIBDOM_ERROR; + if (attr != NULL) { + rx = svgtiny_parse_length(attr, state.viewport_width, state); + } + dom_string_unref(attr); + + exc = dom_element_get_attribute(ellipse, state.interned_ry, &attr); + if (exc != DOM_NO_ERR) + return svgtiny_LIBDOM_ERROR; + if (attr != NULL) { + ry = svgtiny_parse_length(attr, state.viewport_width, state); + } + dom_string_unref(attr); - for (attr = ellipse->properties; attr; attr = attr->next) { - const char *name = (const char *) attr->name; - const char *content = (const char *) attr->children->content; - if (strcmp(name, "cx") == 0) - x = svgtiny_parse_length(content, - state.viewport_width, state); - else if (strcmp(name, "cy") == 0) - y = svgtiny_parse_length(content, - state.viewport_height, state); - else if (strcmp(name, "rx") == 0) - rx = svgtiny_parse_length(content, - state.viewport_width, state); - else if (strcmp(name, "ry") == 0) - ry = svgtiny_parse_length(content, - state.viewport_width, state); - } svgtiny_parse_paint_attributes(ellipse, &state); svgtiny_parse_transform_attributes(ellipse, &state); if (rx < 0 || ry < 0) { - state.diagram->error_line = ellipse->line; + state.diagram->error_line = -1; /* ellipse->line; */ state.diagram->error_message = "ellipse: rx or ry missing " "or negative"; return svgtiny_SVG_ERROR; @@ -761,24 +806,41 @@ svgtiny_code svgtiny_parse_line(dom_element *line, { float x1 = 0, y1 = 0, x2 = 0, y2 = 0; float *p; - xmlAttr *attr; + dom_string *attr; + dom_exception exc; + + exc = dom_element_get_attribute(line, state.interned_x1, &attr); + if (exc != DOM_NO_ERR) + return svgtiny_LIBDOM_ERROR; + if (attr != NULL) { + x1 = svgtiny_parse_length(attr, state.viewport_width, state); + } + dom_string_unref(attr); + + exc = dom_element_get_attribute(line, state.interned_y1, &attr); + if (exc != DOM_NO_ERR) + return svgtiny_LIBDOM_ERROR; + if (attr != NULL) { + y1 = svgtiny_parse_length(attr, state.viewport_height, state); + } + dom_string_unref(attr); + + exc = dom_element_get_attribute(line, state.interned_x2, &attr); + if (exc != DOM_NO_ERR) + return svgtiny_LIBDOM_ERROR; + if (attr != NULL) { + x2 = svgtiny_parse_length(attr, state.viewport_width, state); + } + dom_string_unref(attr); + + exc = dom_element_get_attribute(line, state.interned_y2, &attr); + if (exc != DOM_NO_ERR) + return svgtiny_LIBDOM_ERROR; + if (attr != NULL) { + y2 = svgtiny_parse_length(attr, state.viewport_height, state); + } + dom_string_unref(attr); - for (attr = line->properties; attr; attr = attr->next) { - const char *name = (const char *) attr->name; - const char *content = (const char *) attr->children->content; - if (strcmp(name, "x1") == 0) - x1 = svgtiny_parse_length(content, - state.viewport_width, state); - else if (strcmp(name, "y1") == 0) - y1 = svgtiny_parse_length(content, - state.viewport_height, state); - else if (strcmp(name, "x2") == 0) - x2 = svgtiny_parse_length(content, - state.viewport_width, state); - else if (strcmp(name, "y2") == 0) - y2 = svgtiny_parse_length(content, - state.viewport_height, state); - } svgtiny_parse_paint_attributes(line, &state); svgtiny_parse_transform_attributes(line, &state); @@ -949,8 +1011,8 @@ void svgtiny_parse_position_attributes(const dom_element *node, * Parse a length as a number of pixels. */ -float svgtiny_parse_length(const char *s, int viewport_size, - const struct svgtiny_parse_state state) +static float _svgtiny_parse_length(const char *s, int viewport_size, + const struct svgtiny_parse_state state) { int num_length = strspn(s, "0123456789+-."); const char *unit = s + num_length; @@ -984,6 +1046,14 @@ float svgtiny_parse_length(const char *s, int viewport_size, return 0; } +float svgtiny_parse_length(dom_string *s, int viewport_size, + const struct svgtiny_parse_state state) +{ + const char *ss = strndup(dom_string_data(s), dom_string_length(s)); + float ret = _svgtiny_parse_length(ss, viewport_size, state); + free(ss); + return ret; +} /** * Parse paint attributes, if present. diff --git a/src/svgtiny_internal.h b/src/svgtiny_internal.h index 77a6698..403805a 100644 --- a/src/svgtiny_internal.h +++ b/src/svgtiny_internal.h @@ -62,7 +62,7 @@ struct svgtiny_parse_state { struct svgtiny_list; /* svgtiny.c */ -float svgtiny_parse_length(const char *s, int viewport_size, +float svgtiny_parse_length(dom_string *s, int viewport_size, const struct svgtiny_parse_state state); void svgtiny_parse_color(const char *s, svgtiny_colour *c, struct svgtiny_parse_state *state); diff --git a/src/svgtiny_strings.h b/src/svgtiny_strings.h index 265ab62..d30562e 100644 --- a/src/svgtiny_strings.h +++ b/src/svgtiny_strings.h @@ -10,8 +10,18 @@ SVGTINY_STRING_ACTION(svg) SVGTINY_STRING_ACTION(viewBox) -SVGTINY_STRING_ACTION(g) SVGTINY_STRING_ACTION(a) +SVGTINY_STRING_ACTION(d) +SVGTINY_STRING_ACTION(g) +SVGTINY_STRING_ACTION(r) +SVGTINY_STRING_ACTION(cx) +SVGTINY_STRING_ACTION(cy) +SVGTINY_STRING_ACTION(rx) +SVGTINY_STRING_ACTION(ry) +SVGTINY_STRING_ACTION(x1) +SVGTINY_STRING_ACTION(y1) +SVGTINY_STRING_ACTION(x2) +SVGTINY_STRING_ACTION(y2) SVGTINY_STRING_ACTION(path) SVGTINY_STRING_ACTION(rect) SVGTINY_STRING_ACTION(circle) -- cgit v1.2.1 From 1e37287ed69ca5c9828cb156dd567d0f3b9fea20 Mon Sep 17 00:00:00 2001 From: Daniel Silverstone Date: Sat, 3 Nov 2012 15:00:36 +0000 Subject: Parse text --- src/svgtiny.c | 84 +++++++++++++++++++++++++++++++++++++++------------ src/svgtiny_strings.h | 2 ++ 2 files changed, 67 insertions(+), 19 deletions(-) diff --git a/src/svgtiny.c b/src/svgtiny.c index 9b2af32..79a87d7 100644 --- a/src/svgtiny.c +++ b/src/svgtiny.c @@ -870,26 +870,37 @@ svgtiny_code svgtiny_parse_line(dom_element *line, svgtiny_code svgtiny_parse_poly(dom_element *poly, struct svgtiny_parse_state state, bool polygon) { + dom_string *points_str; + dom_exception exc; char *s, *points; float *p; unsigned int i; svgtiny_parse_paint_attributes(poly, &state); svgtiny_parse_transform_attributes(poly, &state); - - /* read points attribute */ - s = points = (char *) xmlGetProp(poly, (const xmlChar *) "points"); - if (!s) { - state.diagram->error_line = poly->line; + + exc = dom_element_get_attribute(poly, state.interned_points, + &points_str); + if (exc != DOM_NO_ERR) + return svgtiny_LIBDOM_ERROR; + + if (points_str == NULL) { + state.diagram->error_line = -1; /* poly->line; */ state.diagram->error_message = "polyline/polygon: missing points attribute"; return svgtiny_SVG_ERROR; } + s = points = strndup(dom_string_data(points_str), + dom_string_length(points_str)); + dom_string_unref(points_str); + /* read points attribute */ + if (s == NULL) + return svgtiny_OUT_OF_MEMORY; /* allocate space for path: it will never have more elements than s */ p = malloc(sizeof p[0] * strlen(s)); if (!p) { - xmlFree(points); + free(points); return svgtiny_OUT_OF_MEMORY; } @@ -917,7 +928,7 @@ svgtiny_code svgtiny_parse_poly(dom_element *poly, if (polygon) p[i++] = svgtiny_PATH_CLOSE; - xmlFree(points); + free(points); return svgtiny_add_path(p, i, &state); } @@ -932,7 +943,8 @@ svgtiny_code svgtiny_parse_text(dom_element *text, { float x, y, width, height; float px, py; - dom_element *child; + dom_node *child; + dom_exception exc; svgtiny_parse_position_attributes(text, state, &x, &y, &width, &height); @@ -946,27 +958,61 @@ svgtiny_code svgtiny_parse_text(dom_element *text, /*struct css_style style = state.style; style.font_size.value.length.value *= state.ctm.a;*/ - - for (child = text->children; child; child = child->next) { + + exc = dom_node_get_first_child(text, &child); + if (exc != DOM_NO_ERR) + return svgtiny_LIBDOM_ERROR; + while (child != NULL) { + dom_node *next; + dom_node_type nodetype; svgtiny_code code = svgtiny_OK; - if (child->type == XML_TEXT_NODE) { + exc = dom_node_get_node_type(child, &nodetype); + if (exc != DOM_NO_ERR) { + dom_node_unref(child); + return svgtiny_LIBDOM_ERROR; + } + if (nodetype == DOM_ELEMENT_NODE) { + dom_string *nodename; + exc = dom_node_get_node_name(child, &nodename); + if (exc != DOM_NO_ERR) { + dom_node_unref(child); + return svgtiny_LIBDOM_ERROR; + } + if (dom_string_caseless_isequal(nodename, + state.interned_tspan)) + code = svgtiny_parse_text((dom_element *)child, + state); + dom_string_unref(nodename); + } else if (nodetype == DOM_TEXT_NODE) { struct svgtiny_shape *shape = svgtiny_add_shape(&state); - if (!shape) + dom_string *content; + if (shape == NULL) { + dom_node_unref(child); return svgtiny_OUT_OF_MEMORY; - shape->text = strdup((const char *) child->content); + } + exc = dom_text_get_whole_text(child, &content); + if (exc != DOM_NO_ERR) { + dom_node_unref(child); + return svgtiny_LIBDOM_ERROR; + } + shape->text = strndup(dom_string_data(content), + dom_string_length(content)); + dom_string_unref(content); shape->text_x = px; shape->text_y = py; state.diagram->shape_count++; - - } else if (child->type == XML_ELEMENT_NODE && - strcmp((const char *) child->name, - "tspan") == 0) { - code = svgtiny_parse_text(child, state); } - if (!code != svgtiny_OK) + if (code != svgtiny_OK) { + dom_node_unref(child); return code; + } + exc = dom_node_get_next_sibling(child, &next); + dom_node_unref(child); + if (exc != DOM_NO_ERR) + return svgtiny_LIBDOM_ERROR; + child = next; } return svgtiny_OK; diff --git a/src/svgtiny_strings.h b/src/svgtiny_strings.h index d30562e..69026ae 100644 --- a/src/svgtiny_strings.h +++ b/src/svgtiny_strings.h @@ -23,6 +23,7 @@ SVGTINY_STRING_ACTION(y1) SVGTINY_STRING_ACTION(x2) SVGTINY_STRING_ACTION(y2) SVGTINY_STRING_ACTION(path) +SVGTINY_STRING_ACTION(points) SVGTINY_STRING_ACTION(rect) SVGTINY_STRING_ACTION(circle) SVGTINY_STRING_ACTION(ellipse) @@ -30,3 +31,4 @@ SVGTINY_STRING_ACTION(line) SVGTINY_STRING_ACTION(polyline) SVGTINY_STRING_ACTION(polygon) SVGTINY_STRING_ACTION(text) +SVGTINY_STRING_ACTION(tspan) -- cgit v1.2.1 From 60ce406e8b18627c6aab42c434830cc3dfbd67f3 Mon Sep 17 00:00:00 2001 From: Daniel Silverstone Date: Sat, 3 Nov 2012 16:46:39 +0000 Subject: More work towards libdom conversion --- src/svgtiny.c | 179 ++++++++++++++++++++++++++++++------------------- src/svgtiny_gradient.c | 89 ++++++++++++------------ src/svgtiny_internal.h | 7 +- src/svgtiny_strings.h | 16 ++++- 4 files changed, 173 insertions(+), 118 deletions(-) diff --git a/src/svgtiny.c b/src/svgtiny.c index 79a87d7..635974f 100644 --- a/src/svgtiny.c +++ b/src/svgtiny.c @@ -53,6 +53,8 @@ static void svgtiny_parse_transform_attributes(dom_element *node, struct svgtiny_parse_state *state); static svgtiny_code svgtiny_add_path(float *p, unsigned int n, struct svgtiny_parse_state *state); +static void _svgtiny_parse_color(const char *s, svgtiny_colour *c, + struct svgtiny_parse_state *state); /** @@ -165,15 +167,15 @@ svgtiny_code svgtiny_parse(struct svgtiny_diagram *diagram, state.viewport_width = viewport_width; state.viewport_height = viewport_height; -#define SVGTINY_STRING_ACTION(s) \ - if (dom_string_create_interned((const uint8_t *) #s, \ - strlen(#s), &state.interned_##s) \ +#define SVGTINY_STRING_ACTION2(s,n) \ + if (dom_string_create_interned((const uint8_t *) #n, \ + strlen(#n), &state.interned_##s) \ != DOM_NO_ERR) { \ code = svgtiny_LIBDOM_ERROR; \ goto cleanup; \ } #include "svgtiny_strings.h" -#undef SVGTINY_STRING_ACTION +#undef SVGTINY_STRING_ACTION2 svgtiny_parse_position_attributes(svg, state, &x, &y, &width, &height); diagram->width = width; @@ -202,11 +204,11 @@ svgtiny_code svgtiny_parse(struct svgtiny_diagram *diagram, dom_node_unref(document); cleanup: -#define SVGTINY_STRING_ACTION(s) \ +#define SVGTINY_STRING_ACTION2(s,n) \ if (state.interned_##s != NULL) \ dom_string_unref(state.interned_##s); //#include "svgtiny_strings.h" -#undef SVGTINY_STRING_ACTION +#undef SVGTINY_STRING_ACTION2 return code; } @@ -1027,28 +1029,38 @@ void svgtiny_parse_position_attributes(const dom_element *node, const struct svgtiny_parse_state state, float *x, float *y, float *width, float *height) { - xmlAttr *attr; + dom_string *attr; + dom_exception exc; *x = 0; *y = 0; *width = state.viewport_width; *height = state.viewport_height; - for (attr = node->properties; attr; attr = attr->next) { - const char *name = (const char *) attr->name; - const char *content = (const char *) attr->children->content; - if (strcmp(name, "x") == 0) - *x = svgtiny_parse_length(content, - state.viewport_width, state); - else if (strcmp(name, "y") == 0) - *y = svgtiny_parse_length(content, - state.viewport_height, state); - else if (strcmp(name, "width") == 0) - *width = svgtiny_parse_length(content, - state.viewport_width, state); - else if (strcmp(name, "height") == 0) - *height = svgtiny_parse_length(content, - state.viewport_height, state); + exc = dom_element_get_attribute(node, state.interned_x, &attr); + if (exc == DOM_NO_ERR && attr != NULL) { + *x = svgtiny_parse_length(attr, state.viewport_width, state); + dom_string_unref(attr); + } + + exc = dom_element_get_attribute(node, state.interned_y, &attr); + if (exc == DOM_NO_ERR && attr != NULL) { + *y = svgtiny_parse_length(attr, state.viewport_height, state); + dom_string_unref(attr); + } + + exc = dom_element_get_attribute(node, state.interned_width, &attr); + if (exc == DOM_NO_ERR && attr != NULL) { + *width = svgtiny_parse_length(attr, state.viewport_width, + state); + dom_string_unref(attr); + } + + exc = dom_element_get_attribute(node, state.interned_height, &attr); + if (exc == DOM_NO_ERR && attr != NULL) { + *height = svgtiny_parse_length(attr, state.viewport_height, + state); + dom_string_unref(attr); } } @@ -1095,7 +1107,7 @@ static float _svgtiny_parse_length(const char *s, int viewport_size, float svgtiny_parse_length(dom_string *s, int viewport_size, const struct svgtiny_parse_state state) { - const char *ss = strndup(dom_string_data(s), dom_string_length(s)); + char *ss = strndup(dom_string_data(s), dom_string_length(s)); float ret = _svgtiny_parse_length(ss, viewport_size, state); free(ss); return ret; @@ -1108,49 +1120,61 @@ float svgtiny_parse_length(dom_string *s, int viewport_size, void svgtiny_parse_paint_attributes(const dom_element *node, struct svgtiny_parse_state *state) { - const xmlAttr *attr; + dom_string *attr; + dom_exception exc; + + exc = dom_element_get_attribute(node, state->interned_fill, &attr); + if (exc == DOM_NO_ERR && attr != NULL) { + svgtiny_parse_color(attr, &state->fill, state); + dom_string_unref(attr); + } - for (attr = node->properties; attr; attr = attr->next) { - const char *name = (const char *) attr->name; - const char *content = (const char *) attr->children->content; - if (strcmp(name, "fill") == 0) - svgtiny_parse_color(content, &state->fill, state); - else if (strcmp(name, "stroke") == 0) - svgtiny_parse_color(content, &state->stroke, state); - else if (strcmp(name, "stroke-width") == 0) - state->stroke_width = svgtiny_parse_length(content, - state->viewport_width, *state); - else if (strcmp(name, "style") == 0) { - const char *style = (const char *) - attr->children->content; - const char *s; - char *value; - if ((s = strstr(style, "fill:"))) { - s += 5; - while (*s == ' ') - s++; - value = strndup(s, strcspn(s, "; ")); - svgtiny_parse_color(value, &state->fill, state); - free(value); - } - if ((s = strstr(style, "stroke:"))) { - s += 7; - while (*s == ' ') - s++; - value = strndup(s, strcspn(s, "; ")); - svgtiny_parse_color(value, &state->stroke, state); - free(value); - } - if ((s = strstr(style, "stroke-width:"))) { - s += 13; - while (*s == ' ') - s++; - value = strndup(s, strcspn(s, "; ")); - state->stroke_width = svgtiny_parse_length(value, + exc = dom_element_get_attribute(node, state->interned_stroke, &attr); + if (exc == DOM_NO_ERR && attr != NULL) { + svgtiny_parse_color(attr, &state->stroke, state); + dom_string_unref(attr); + } + + exc = dom_element_get_attribute(node, state->interned_stroke_width, &attr); + if (exc == DOM_NO_ERR && attr != NULL) { + state->stroke_width = svgtiny_parse_length(attr, state->viewport_width, *state); - free(value); - } + dom_string_unref(attr); + } + + exc = dom_element_get_attribute(node, state->interned_style, &attr); + if (exc == DOM_NO_ERR && attr != NULL) { + char *style = strndup(dom_string_data(attr), + dom_string_length(attr)); + const char *s; + char *value; + if ((s = strstr(style, "fill:"))) { + s += 5; + while (*s == ' ') + s++; + value = strndup(s, strcspn(s, "; ")); + _svgtiny_parse_color(value, &state->fill, state); + free(value); } + if ((s = strstr(style, "stroke:"))) { + s += 7; + while (*s == ' ') + s++; + value = strndup(s, strcspn(s, "; ")); + _svgtiny_parse_color(value, &state->stroke, state); + free(value); + } + if ((s = strstr(style, "stroke-width:"))) { + s += 13; + while (*s == ' ') + s++; + value = strndup(s, strcspn(s, "; ")); + state->stroke_width = _svgtiny_parse_length(value, + state->viewport_width, *state); + free(value); + } + free(style); + dom_string_unref(attr); } } @@ -1159,7 +1183,7 @@ void svgtiny_parse_paint_attributes(const dom_element *node, * Parse a colour. */ -void svgtiny_parse_color(const char *s, svgtiny_colour *c, +static void _svgtiny_parse_color(const char *s, svgtiny_colour *c, struct svgtiny_parse_state *state) { unsigned int r, g, b; @@ -1218,6 +1242,13 @@ void svgtiny_parse_color(const char *s, svgtiny_colour *c, } } +void svgtiny_parse_color(dom_string *s, svgtiny_colour *c, + struct svgtiny_parse_state *state) +{ + char *ss = strndup(dom_string_data(s), dom_string_length(s)); + _svgtiny_parse_color(ss, c, state); + free(ss); +} /** * Parse font attributes, if present. @@ -1226,6 +1257,10 @@ void svgtiny_parse_color(const char *s, svgtiny_colour *c, void svgtiny_parse_font_attributes(const dom_element *node, struct svgtiny_parse_state *state) { + /* TODO: Implement this, it never used to be */ + UNUSED(node); + UNUSED(state); +#ifdef WRITTEN_THIS_PROPERLY const xmlAttr *attr; UNUSED(state); @@ -1241,6 +1276,7 @@ void svgtiny_parse_font_attributes(const dom_element *node, }*/ } } +#endif } @@ -1254,14 +1290,19 @@ void svgtiny_parse_transform_attributes(dom_element *node, struct svgtiny_parse_state *state) { char *transform; - - /* parse transform */ - transform = (char *) xmlGetProp(node, (const xmlChar *) "transform"); - if (transform) { + dom_string *attr; + dom_exception exc; + + exc = dom_element_get_attribute(node, state->interned_transform, + &attr); + if (exc == DOM_NO_ERR && attr != NULL) { + transform = strndup(dom_string_data(attr), + dom_string_length(attr)); svgtiny_parse_transform(transform, &state->ctm.a, &state->ctm.b, &state->ctm.c, &state->ctm.d, &state->ctm.e, &state->ctm.f); - xmlFree(transform); + free(transform); + dom_string_unref(attr); } } diff --git a/src/svgtiny_gradient.c b/src/svgtiny_gradient.c index 3a8db73..3544f1d 100644 --- a/src/svgtiny_gradient.c +++ b/src/svgtiny_gradient.c @@ -8,12 +8,14 @@ #include #include #include +#include + #include "svgtiny.h" #include "svgtiny_internal.h" #undef GRADIENT_DEBUG -static svgtiny_code svgtiny_parse_linear_gradient(xmlNode *linear, +static svgtiny_code svgtiny_parse_linear_gradient(dom_element *linear, struct svgtiny_parse_state *state); static float svgtiny_parse_gradient_offset(const char *s); static void svgtiny_path_bbox(float *p, unsigned int n, @@ -27,7 +29,9 @@ static void svgtiny_invert_matrix(float *m, float *inv); void svgtiny_find_gradient(const char *id, struct svgtiny_parse_state *state) { - xmlNode *gradient; + dom_element *gradient; + dom_string *id_str; + dom_exception exc; fprintf(stderr, "svgtiny_find_gradient: id \"%s\"\n", id); @@ -43,19 +47,34 @@ void svgtiny_find_gradient(const char *id, struct svgtiny_parse_state *state) state->gradient_transform.d = 1; state->gradient_transform.e = 0; state->gradient_transform.f = 0; + + exc = dom_string_create_interned((const uint8_t *) id, strlen(id), + &id_str); + if (exc != DOM_NO_ERR) + return; + + exc = dom_document_get_element_by_id(state->document, id_str, + &gradient); + dom_string_unref(id_str); + if (exc != DOM_NO_ERR) + return; - gradient = svgtiny_find_element_by_id( - (xmlNode *) state->document, id); - fprintf(stderr, "gradient %p\n", (void *) gradient); - if (!gradient) { + if (gradient == NULL) { fprintf(stderr, "gradient \"%s\" not found\n", id); return; } - - fprintf(stderr, "gradient name \"%s\"\n", gradient->name); - if (strcmp((const char *) gradient->name, "linearGradient") == 0) { - svgtiny_parse_linear_gradient(gradient, state); + + exc = dom_node_get_node_name(gradient, &id_str); + if (exc != DOM_NO_ERR) { + dom_node_unref(gradient); + return; } + + if (dom_string_isequal(id_str, state->interned_linearGradient)) + svgtiny_parse_linear_gradient(gradient, state); + + dom_string_unref(id_str); + dom_node_unref(gradient); } @@ -65,17 +84,25 @@ void svgtiny_find_gradient(const char *id, struct svgtiny_parse_state *state) * http://www.w3.org/TR/SVG11/pservers#LinearGradients */ -svgtiny_code svgtiny_parse_linear_gradient(xmlNode *linear, +svgtiny_code svgtiny_parse_linear_gradient(dom_element *linear, struct svgtiny_parse_state *state) { unsigned int i = 0; - xmlNode *stop; - xmlAttr *attr; - xmlAttr *href = xmlHasProp(linear, (const xmlChar *) "href"); - if (href && href->children->content[0] == '#') - svgtiny_find_gradient((const char *) href->children->content - + 1, state); - + dom_element *stop; + dom_string *attr; + dom_exception exc; + + exc = dom_element_get_attribute(linear, state->interned_href, &attr); + if (exc == DOM_NO_ERR && attr != NULL) { + if (dom_string_data(attr)[0] == (uint8_t) '#') { + char *s = strndup(dom_string_data(attr) + 1, + dom_string_length(attr) - 1); + svgtiny_find_gradient(s, state); + free(s); + } + dom_string_unref(attr); + } + for (attr = linear->properties; attr; attr = attr->next) { const char *name = (const char *) attr->name; const char *content = (const char *) attr->children->content; @@ -642,29 +669,3 @@ void svgtiny_invert_matrix(float *m, float *inv) inv[5] = (m[1]*m[4] - m[0]*m[5]) / determinant; } - -/** - * Find an element in the document by id. - */ - -xmlNode *svgtiny_find_element_by_id(xmlNode *node, const char *id) -{ - xmlNode *child; - xmlNode *found; - - for (child = node->children; child; child = child->next) { - xmlAttr *attr; - if (child->type != XML_ELEMENT_NODE) - continue; - attr = xmlHasProp(child, (const xmlChar *) "id"); - if (attr && strcmp(id, (const char *) attr->children->content) - == 0) - return child; - found = svgtiny_find_element_by_id(child, id); - if (found) - return found; - } - - return 0; -} - diff --git a/src/svgtiny_internal.h b/src/svgtiny_internal.h index 403805a..5ff1370 100644 --- a/src/svgtiny_internal.h +++ b/src/svgtiny_internal.h @@ -53,9 +53,9 @@ struct svgtiny_parse_state { } gradient_transform; /* Interned strings */ -#define SVGTINY_STRING_ACTION(n) dom_string *interned_##n; +#define SVGTINY_STRING_ACTION2(n,nn) dom_string *interned_##n; #include "svgtiny_strings.h" -#undef SVGTINY_STRING_ACTION +#undef SVGTINY_STRING_ACTION2 }; @@ -64,7 +64,7 @@ struct svgtiny_list; /* svgtiny.c */ float svgtiny_parse_length(dom_string *s, int viewport_size, const struct svgtiny_parse_state state); -void svgtiny_parse_color(const char *s, svgtiny_colour *c, +void svgtiny_parse_color(dom_string *s, svgtiny_colour *c, struct svgtiny_parse_state *state); void svgtiny_parse_transform(char *s, float *ma, float *mb, float *mc, float *md, float *me, float *mf); @@ -83,7 +83,6 @@ char *svgtiny_strndup(const char *s, size_t n); void svgtiny_find_gradient(const char *id, struct svgtiny_parse_state *state); svgtiny_code svgtiny_add_path_linear_gradient(float *p, unsigned int n, struct svgtiny_parse_state *state); -dom_node *svgtiny_find_element_by_id(dom_node *node, const char *id); /* svgtiny_list.c */ struct svgtiny_list *svgtiny_list_create(size_t item_size); diff --git a/src/svgtiny_strings.h b/src/svgtiny_strings.h index 69026ae..019bb14 100644 --- a/src/svgtiny_strings.h +++ b/src/svgtiny_strings.h @@ -4,16 +4,20 @@ * Copyright 2012 Daniel Silverstone */ -#ifndef SVGTINY_STRING_ACTION +#ifndef SVGTINY_STRING_ACTION2 #error No action defined #endif +#define SVGTINY_STRING_ACTION(s) SVGTINY_STRING_ACTION2(s,s) + SVGTINY_STRING_ACTION(svg) SVGTINY_STRING_ACTION(viewBox) SVGTINY_STRING_ACTION(a) SVGTINY_STRING_ACTION(d) SVGTINY_STRING_ACTION(g) SVGTINY_STRING_ACTION(r) +SVGTINY_STRING_ACTION(x) +SVGTINY_STRING_ACTION(y) SVGTINY_STRING_ACTION(cx) SVGTINY_STRING_ACTION(cy) SVGTINY_STRING_ACTION(rx) @@ -24,6 +28,8 @@ SVGTINY_STRING_ACTION(x2) SVGTINY_STRING_ACTION(y2) SVGTINY_STRING_ACTION(path) SVGTINY_STRING_ACTION(points) +SVGTINY_STRING_ACTION(width) +SVGTINY_STRING_ACTION(height) SVGTINY_STRING_ACTION(rect) SVGTINY_STRING_ACTION(circle) SVGTINY_STRING_ACTION(ellipse) @@ -32,3 +38,11 @@ SVGTINY_STRING_ACTION(polyline) SVGTINY_STRING_ACTION(polygon) SVGTINY_STRING_ACTION(text) SVGTINY_STRING_ACTION(tspan) +SVGTINY_STRING_ACTION(fill) +SVGTINY_STRING_ACTION(stroke) +SVGTINY_STRING_ACTION(style) +SVGTINY_STRING_ACTION(transform) +SVGTINY_STRING_ACTION(linearGradient) +SVGTINY_STRING_ACTION2(stroke_width,stroke-width) + +#undef SVGTINY_STRING_ACTION -- cgit v1.2.1 From 4f6c3034252830b3f4c0a03cbb03a661fdb1d8e8 Mon Sep 17 00:00:00 2001 From: Daniel Silverstone Date: Sat, 3 Nov 2012 17:45:07 +0000 Subject: The library now builds --- src/svgtiny.c | 1 + src/svgtiny_gradient.c | 225 +++++++++++++++++++++++++++++++++---------------- src/svgtiny_internal.h | 2 +- src/svgtiny_list.c | 1 + src/svgtiny_strings.h | 9 ++ 5 files changed, 163 insertions(+), 75 deletions(-) diff --git a/src/svgtiny.c b/src/svgtiny.c index 635974f..18884a1 100644 --- a/src/svgtiny.c +++ b/src/svgtiny.c @@ -162,6 +162,7 @@ svgtiny_code svgtiny_parse(struct svgtiny_diagram *diagram, dom_string_unref(svg_name); /* get graphic dimensions */ + memset(&state, 0, sizeof(state)); state.diagram = diagram; state.document = document; state.viewport_width = viewport_width; diff --git a/src/svgtiny_gradient.c b/src/svgtiny_gradient.c index 3544f1d..19f7f1f 100644 --- a/src/svgtiny_gradient.c +++ b/src/svgtiny_gradient.c @@ -9,6 +9,7 @@ #include #include #include +#include #include "svgtiny.h" #include "svgtiny_internal.h" @@ -36,10 +37,18 @@ void svgtiny_find_gradient(const char *id, struct svgtiny_parse_state *state) fprintf(stderr, "svgtiny_find_gradient: id \"%s\"\n", id); state->linear_gradient_stop_count = 0; - state->gradient_x1 = "0%"; - state->gradient_y1 = "0%"; - state->gradient_x2 = "100%"; - state->gradient_y2 = "0%"; + if (state->gradient_x1 != NULL) + dom_string_unref(state->gradient_x1); + if (state->gradient_y1 != NULL) + dom_string_unref(state->gradient_y1); + if (state->gradient_x2 != NULL) + dom_string_unref(state->gradient_x2); + if (state->gradient_y2 != NULL) + dom_string_unref(state->gradient_y2); + state->gradient_x1 = dom_string_ref(state->interned_zero_percent); + state->gradient_y1 = dom_string_ref(state->interned_zero_percent); + state->gradient_x2 = dom_string_ref(state->interned_hundred_percent); + state->gradient_y2 = dom_string_ref(state->interned_zero_percent); state->gradient_user_space_on_use = false; state->gradient_transform.a = 1; state->gradient_transform.b = 0; @@ -88,9 +97,9 @@ svgtiny_code svgtiny_parse_linear_gradient(dom_element *linear, struct svgtiny_parse_state *state) { unsigned int i = 0; - dom_element *stop; dom_string *attr; dom_exception exc; + dom_nodelist *stops; exc = dom_element_get_attribute(linear, state->interned_href, &attr); if (exc == DOM_NO_ERR && attr != NULL) { @@ -102,84 +111,145 @@ svgtiny_code svgtiny_parse_linear_gradient(dom_element *linear, } dom_string_unref(attr); } - - for (attr = linear->properties; attr; attr = attr->next) { - const char *name = (const char *) attr->name; - const char *content = (const char *) attr->children->content; - if (strcmp(name, "x1") == 0) - state->gradient_x1 = content; - else if (strcmp(name, "y1") == 0) - state->gradient_y1 = content; - else if (strcmp(name, "x2") == 0) - state->gradient_x2 = content; - else if (strcmp(name, "y2") == 0) - state->gradient_y2 = content; - else if (strcmp(name, "gradientUnits") == 0) - state->gradient_user_space_on_use = - strcmp(content, "userSpaceOnUse") == 0; - else if (strcmp(name, "gradientTransform") == 0) { - float a = 1, b = 0, c = 0, d = 1, e = 0, f = 0; - char *s = strdup(content); - if (!s) - return svgtiny_OUT_OF_MEMORY; - svgtiny_parse_transform(s, &a, &b, &c, &d, &e, &f); - free(s); - fprintf(stderr, "transform %g %g %g %g %g %g\n", - a, b, c, d, e, f); - state->gradient_transform.a = a; - state->gradient_transform.b = b; - state->gradient_transform.c = c; - state->gradient_transform.d = d; - state->gradient_transform.e = e; - state->gradient_transform.f = f; - } - } - for (stop = linear->children; stop; stop = stop->next) { - float offset = -1; - svgtiny_colour color = svgtiny_TRANSPARENT; + exc = dom_element_get_attribute(linear, state->interned_x1, &attr); + if (exc == DOM_NO_ERR && attr != NULL) { + dom_string_unref(state->gradient_x1); + state->gradient_x1 = attr; + attr = NULL; + } - if (stop->type != XML_ELEMENT_NODE) - continue; - if (strcmp((const char *) stop->name, "stop") != 0) - continue; + exc = dom_element_get_attribute(linear, state->interned_y1, &attr); + if (exc == DOM_NO_ERR && attr != NULL) { + dom_string_unref(state->gradient_y1); + state->gradient_y1 = attr; + attr = NULL; + } - for (attr = stop->properties; attr; - attr = attr->next) { - const char *name = (const char *) attr->name; - const char *content = - (const char *) attr->children->content; - if (strcmp(name, "offset") == 0) - offset = svgtiny_parse_gradient_offset(content); - else if (strcmp(name, "stop-color") == 0) - svgtiny_parse_color(content, &color, state); - else if (strcmp(name, "style") == 0) { + exc = dom_element_get_attribute(linear, state->interned_x2, &attr); + if (exc == DOM_NO_ERR && attr != NULL) { + dom_string_unref(state->gradient_x2); + state->gradient_x2 = attr; + attr = NULL; + } + + exc = dom_element_get_attribute(linear, state->interned_y2, &attr); + if (exc == DOM_NO_ERR && attr != NULL) { + dom_string_unref(state->gradient_y2); + state->gradient_y2 = attr; + attr = NULL; + } + + exc = dom_element_get_attribute(linear, state->interned_gradientUnits, + &attr); + if (exc == DOM_NO_ERR && attr != NULL) { + state->gradient_user_space_on_use = + dom_string_isequal(attr, + state->interned_userSpaceOnUse); + dom_string_unref(attr); + } + + exc = dom_element_get_attribute(linear, + state->interned_gradientTransform, + &attr); + if (exc == DOM_NO_ERR && attr != NULL) { + float a = 1, b = 0, c = 0, d = 1, e = 0, f = 0; + char *s = strndup(dom_string_data(attr), + dom_string_length(attr)); + if (s == NULL) { + dom_string_unref(attr); + return svgtiny_OUT_OF_MEMORY; + } + svgtiny_parse_transform(s, &a, &b, &c, &d, &e, &f); + free(s); + fprintf(stderr, "transform %g %g %g %g %g %g\n", + a, b, c, d, e, f); + state->gradient_transform.a = a; + state->gradient_transform.b = b; + state->gradient_transform.c = c; + state->gradient_transform.d = d; + state->gradient_transform.e = e; + state->gradient_transform.f = f; + dom_string_unref(attr); + } + + exc = dom_element_get_elements_by_tag_name(linear, + state->interned_stop, + &stops); + if (exc == DOM_NO_ERR && stops != NULL) { + uint32_t listlen, stopnr; + exc = dom_nodelist_get_length(stops, &listlen); + if (exc != DOM_NO_ERR) { + dom_nodelist_unref(stops); + goto no_more_stops; + } + + for (stopnr = 0; stopnr < listlen; ++stopnr) { + dom_element *stop; + float offset = -1; + svgtiny_colour color = svgtiny_TRANSPARENT; + exc = dom_nodelist_item(stops, stopnr, &stop); + if (exc != DOM_NO_ERR) + continue; + exc = dom_element_get_attribute(stop, + state->interned_offset, + &attr); + if (exc == DOM_NO_ERR && attr != NULL) { + char *s = strndup(dom_string_data(attr), + dom_string_length(attr)); + offset = svgtiny_parse_gradient_offset(s); + free(s); + dom_string_unref(attr); + } + exc = dom_element_get_attribute(stop, + state->interned_stop_color, + &attr); + if (exc == DOM_NO_ERR && attr != NULL) { + svgtiny_parse_color(attr, &color, state); + dom_string_unref(attr); + } + exc = dom_element_get_attribute(stop, + state->interned_style, + &attr); + if (exc == DOM_NO_ERR && attr != NULL) { + char *content = strndup(dom_string_data(attr), + dom_string_length(attr)); const char *s; - char *value; + dom_string *value; if ((s = strstr(content, "stop-color:"))) { s += 11; while (*s == ' ') s++; - value = strndup(s, strcspn(s, "; ")); - svgtiny_parse_color(value, &color, - state); - free(value); + exc = dom_string_create_interned( + (const uint8_t *) s, + strcspn(s, "; "), + &value); + if (exc != DOM_NO_ERR && + value != NULL) { + svgtiny_parse_color(value, + &color, + state); + dom_string_unref(value); + } } + free(content); + dom_string_unref(attr); } + if (offset != -1 && color != svgtiny_TRANSPARENT) { + fprintf(stderr, "stop %g %x\n", offset, color); + state->gradient_stop[i].offset = offset; + state->gradient_stop[i].color = color; + i++; + } + dom_node_unref(stop); + if (i == svgtiny_MAX_STOPS) + break; } - - if (offset != -1 && color != svgtiny_TRANSPARENT) { - fprintf(stderr, "stop %g %x\n", offset, color); - state->gradient_stop[i].offset = offset; - state->gradient_stop[i].color = color; - i++; - } - - if (i == svgtiny_MAX_STOPS) - break; + + dom_nodelist_unref(stops); } - - if (i) +no_more_stops: + if (i > 0) state->linear_gradient_stop_count = i; return svgtiny_OK; @@ -246,9 +316,16 @@ svgtiny_code svgtiny_add_path_linear_gradient(float *p, unsigned int n, #endif /* compute gradient vector */ - fprintf(stderr, "x1 %s, y1 %s, x2 %s, y2 %s\n", - state->gradient_x1, state->gradient_y1, - state->gradient_x2, state->gradient_y2); + fprintf(stderr, "x1 %*s, y1 %*s, x2 %*s, y2 %*s\n", + dom_string_length(state->gradient_x1), + dom_string_data(state->gradient_x1), + dom_string_length(state->gradient_y1), + dom_string_data(state->gradient_y1), + dom_string_length(state->gradient_x2), + dom_string_data(state->gradient_x2), + dom_string_length(state->gradient_y2), + dom_string_data(state->gradient_y2)); + if (!state->gradient_user_space_on_use) { gradient_x0 = object_x0 + svgtiny_parse_length(state->gradient_x1, diff --git a/src/svgtiny_internal.h b/src/svgtiny_internal.h index 5ff1370..0fd5af9 100644 --- a/src/svgtiny_internal.h +++ b/src/svgtiny_internal.h @@ -45,7 +45,7 @@ struct svgtiny_parse_state { /* gradients */ unsigned int linear_gradient_stop_count; - const char *gradient_x1, *gradient_y1, *gradient_x2, *gradient_y2; + dom_string *gradient_x1, *gradient_y1, *gradient_x2, *gradient_y2; struct svgtiny_gradient_stop gradient_stop[svgtiny_MAX_STOPS]; bool gradient_user_space_on_use; struct { diff --git a/src/svgtiny_list.c b/src/svgtiny_list.c index 53cfb34..91e2c98 100644 --- a/src/svgtiny_list.c +++ b/src/svgtiny_list.c @@ -11,6 +11,7 @@ */ #include +#include #include "svgtiny.h" #include "svgtiny_internal.h" diff --git a/src/svgtiny_strings.h b/src/svgtiny_strings.h index 019bb14..d075eb6 100644 --- a/src/svgtiny_strings.h +++ b/src/svgtiny_strings.h @@ -43,6 +43,15 @@ SVGTINY_STRING_ACTION(stroke) SVGTINY_STRING_ACTION(style) SVGTINY_STRING_ACTION(transform) SVGTINY_STRING_ACTION(linearGradient) +SVGTINY_STRING_ACTION(href) +SVGTINY_STRING_ACTION(stop) +SVGTINY_STRING_ACTION(offset) +SVGTINY_STRING_ACTION(gradientUnits) +SVGTINY_STRING_ACTION(gradientTransform) +SVGTINY_STRING_ACTION(userSpaceOnUse) SVGTINY_STRING_ACTION2(stroke_width,stroke-width) +SVGTINY_STRING_ACTION2(stop_color,stop-color) +SVGTINY_STRING_ACTION2(zero_percent,0%) +SVGTINY_STRING_ACTION2(hundred_percent,100%) #undef SVGTINY_STRING_ACTION -- cgit v1.2.1 From dc1d99abcc35fd50673ed009d9247ef976beed4f Mon Sep 17 00:00:00 2001 From: Daniel Silverstone Date: Sat, 3 Nov 2012 17:49:30 +0000 Subject: Convert the last bits for libdom --- Makefile | 8 ++++---- test/svgtiny_test.c | 5 +++-- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/Makefile b/Makefile index cb393a7..ff41860 100644 --- a/Makefile +++ b/Makefile @@ -34,12 +34,12 @@ endif # libdom ifneq ($(PKGCONFIG),) CFLAGS := $(CFLAGS) \ - $(shell $(PKGCONFIG) $(PKGCONFIGFLAGS) --cflags libdom) - LDFLAGS := $(LDFLAGS) \ - $(shell $(PKGCONFIG) $(PKGCONFIGFLAGS) --libs libdom) + $(shell $(PKGCONFIG) $(PKGCONFIGFLAGS) --cflags libdom libwapcaplet) + LDFLAGS := $(LDFLAGS) -lm \ + $(shell $(PKGCONFIG) $(PKGCONFIGFLAGS) --libs libdom libwapcaplet) else CFLAGS := $(CFLAGS) -I$(PREFIX)/include - LDFLAGS := $(CFLAGS) -ldom + LDFLAGS := $(CFLAGS) -ldom -lwapcaplet -lexpat -lm endif include $(NSBUILD)/Makefile.top diff --git a/test/svgtiny_test.c b/test/svgtiny_test.c index 2a2c862..1b507fd 100644 --- a/test/svgtiny_test.c +++ b/test/svgtiny_test.c @@ -9,6 +9,7 @@ #include #include #include +#include #include "svgtiny.h" @@ -78,8 +79,8 @@ int main(int argc, char *argv[]) case svgtiny_OUT_OF_MEMORY: fprintf(stderr, "svgtiny_OUT_OF_MEMORY"); break; - case svgtiny_LIBXML_ERROR: - fprintf(stderr, "svgtiny_LIBXML_ERROR"); + case svgtiny_LIBDOM_ERROR: + fprintf(stderr, "svgtiny_LIBDOM_ERROR"); break; case svgtiny_NOT_SVG: fprintf(stderr, "svgtiny_NOT_SVG"); -- cgit v1.2.1