]> gitweb.michael.orlitzky.com - libsvgtiny.git/commitdiff
More work towards libdom conversion
authorDaniel Silverstone <dsilvers@digital-scurf.org>
Sat, 3 Nov 2012 16:46:39 +0000 (16:46 +0000)
committerDaniel Silverstone <dsilvers@digital-scurf.org>
Sat, 3 Nov 2012 16:46:39 +0000 (16:46 +0000)
src/svgtiny.c
src/svgtiny_gradient.c
src/svgtiny_internal.h
src/svgtiny_strings.h

index 79a87d70c8b41b77195f80ee0bf8699eaeaffc53..635974f250ac9217f8dc840ec473a1cafe24a6ec 100644 (file)
@@ -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);
        }
 }
 
index 3a8db7375d7bc0e1b91b89d82975337a4ed1d6fe..3544f1d199adc9989af193329d848d040755ca36 100644 (file)
@@ -8,12 +8,14 @@
 #include <assert.h>
 #include <math.h>
 #include <string.h>
+#include <stdio.h>
+
 #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;
-}
-
index 403805aae975d1693ec2ac0c174f60ed4c8530ea..5ff1370ab4d146d65428ac5578216a46cc1ac854 100644 (file)
@@ -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);
index 69026ae1a0859db83c23fb24a9548047ef3f044b..019bb1449a6d9f077220cf78ae06602dfa6a9eee 100644 (file)
@@ -4,16 +4,20 @@
  * Copyright 2012 Daniel Silverstone <dsilvers@netsurf-browser.org>
  */
 
-#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