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);
/**
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;
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;
}
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);
}
}
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;
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);
}
}
* 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;
}
}
+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.
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);
}*/
}
}
+#endif
}
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);
}
}
#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,
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);
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);
}
* 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;
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;
-}
-