summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Silverstone <dsilvers@digital-scurf.org>2012-11-03 16:46:39 +0000
committerDaniel Silverstone <dsilvers@digital-scurf.org>2012-11-03 16:46:39 +0000
commit60ce406e8b18627c6aab42c434830cc3dfbd67f3 (patch)
tree54a8711b0c8458de727e4ffc30f9ce3028ca95c1
parent1e37287ed69ca5c9828cb156dd567d0f3b9fea20 (diff)
downloadlibsvgtiny-60ce406e8b18627c6aab42c434830cc3dfbd67f3.tar.gz
libsvgtiny-60ce406e8b18627c6aab42c434830cc3dfbd67f3.tar.bz2
More work towards libdom conversion
-rw-r--r--src/svgtiny.c179
-rw-r--r--src/svgtiny_gradient.c89
-rw-r--r--src/svgtiny_internal.h7
-rw-r--r--src/svgtiny_strings.h16
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 <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;
-}
-
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 <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