static svgtiny_code svgtiny_parse_text(dom_element *text,
struct svgtiny_parse_state state);
static void svgtiny_parse_position_attributes(dom_element *node,
- const struct svgtiny_parse_state state,
+ struct svgtiny_parse_state state,
float *x, float *y, float *width, float *height);
static void svgtiny_parse_paint_attributes(dom_element *node,
struct svgtiny_parse_state *state);
svgtiny_code err;
float x = 0, y = 0, r = -1;
float *p;
- dom_string *attr;
- dom_exception exc;
+ struct svgtiny_parse_internal_operation ops[] = {
+ {
+ state.interned_cx,
+ SVGTIOP_LENGTH,
+ &state.viewport_width,
+ &x
+ }, {
+ state.interned_cy,
+ SVGTIOP_LENGTH,
+ &state.viewport_height,
+ &y
+ }, {
+ state.interned_r,
+ SVGTIOP_LENGTH,
+ &state.viewport_width,
+ &r
+ }, {
+ NULL, SVGTIOP_NONE, NULL, NULL
+ },
+ };
svgtiny_setup_state_local(&state);
- exc = dom_element_get_attribute(circle, state.interned_cx, &attr);
- if (exc != DOM_NO_ERR) {
- svgtiny_cleanup_state_local(&state);
- return svgtiny_LIBDOM_ERROR;
- }
- if (attr != NULL) {
- svgtiny_parse_length(dom_string_data(attr),
- dom_string_byte_length(attr),
- state.viewport_width,
- &x);
- }
- dom_string_unref(attr);
-
- exc = dom_element_get_attribute(circle, state.interned_cy, &attr);
- if (exc != DOM_NO_ERR) {
- svgtiny_cleanup_state_local(&state);
- return svgtiny_LIBDOM_ERROR;
- }
- if (attr != NULL) {
- svgtiny_parse_length(dom_string_data(attr),
- dom_string_byte_length(attr),
- state.viewport_height,
- &y);
- }
- dom_string_unref(attr);
-
- exc = dom_element_get_attribute(circle, state.interned_r, &attr);
- if (exc != DOM_NO_ERR) {
+ err = svgtiny_parse_attributes(circle, &state, ops);
+ if (err != svgtiny_OK) {
svgtiny_cleanup_state_local(&state);
- return svgtiny_LIBDOM_ERROR;
+ return err;
}
- if (attr != NULL) {
- svgtiny_parse_length(dom_string_data(attr),
- dom_string_byte_length(attr),
- state.viewport_width,
- &r);
- }
- dom_string_unref(attr);
svgtiny_parse_paint_attributes(circle, &state);
svgtiny_parse_transform_attributes(circle, &state);
svgtiny_code err;
float x = 0, y = 0, rx = -1, ry = -1;
float *p;
- dom_string *attr;
- dom_exception exc;
+ struct svgtiny_parse_internal_operation ops[] = {
+ {
+ state.interned_cx,
+ SVGTIOP_LENGTH,
+ &state.viewport_width,
+ &x
+ }, {
+ state.interned_cy,
+ SVGTIOP_LENGTH,
+ &state.viewport_height,
+ &y
+ }, {
+ state.interned_rx,
+ SVGTIOP_LENGTH,
+ &state.viewport_width,
+ &rx
+ }, {
+ state.interned_ry,
+ SVGTIOP_LENGTH,
+ &state.viewport_height,
+ &ry
+ }, {
+ NULL, SVGTIOP_NONE, NULL, NULL
+ },
+ };
svgtiny_setup_state_local(&state);
- exc = dom_element_get_attribute(ellipse, state.interned_cx, &attr);
- if (exc != DOM_NO_ERR) {
- svgtiny_cleanup_state_local(&state);
- return svgtiny_LIBDOM_ERROR;
- }
- if (attr != NULL) {
- svgtiny_parse_length(dom_string_data(attr),
- dom_string_byte_length(attr),
- state.viewport_width,
- &x);
- }
- dom_string_unref(attr);
-
- exc = dom_element_get_attribute(ellipse, state.interned_cy, &attr);
- if (exc != DOM_NO_ERR) {
- svgtiny_cleanup_state_local(&state);
- return svgtiny_LIBDOM_ERROR;
- }
- if (attr != NULL) {
- svgtiny_parse_length(dom_string_data(attr),
- dom_string_byte_length(attr),
- state.viewport_height,
- &y);
- }
- dom_string_unref(attr);
-
- exc = dom_element_get_attribute(ellipse, state.interned_rx, &attr);
- if (exc != DOM_NO_ERR) {
- svgtiny_cleanup_state_local(&state);
- return svgtiny_LIBDOM_ERROR;
- }
- if (attr != NULL) {
- svgtiny_parse_length(dom_string_data(attr),
- dom_string_byte_length(attr),
- state.viewport_width,
- &rx);
- }
- dom_string_unref(attr);
-
- exc = dom_element_get_attribute(ellipse, state.interned_ry, &attr);
- if (exc != DOM_NO_ERR) {
+ err = svgtiny_parse_attributes(ellipse, &state, ops);
+ if (err != svgtiny_OK) {
svgtiny_cleanup_state_local(&state);
- return svgtiny_LIBDOM_ERROR;
- }
- if (attr != NULL) {
- svgtiny_parse_length(dom_string_data(attr),
- dom_string_byte_length(attr),
- state.viewport_width,
- &ry);
+ return err;
}
- dom_string_unref(attr);
svgtiny_parse_paint_attributes(ellipse, &state);
svgtiny_parse_transform_attributes(ellipse, &state);
svgtiny_code err;
float x1 = 0, y1 = 0, x2 = 0, y2 = 0;
float *p;
- dom_string *attr;
- dom_exception exc;
+ struct svgtiny_parse_internal_operation ops[] = {
+ {
+ state.interned_x1,
+ SVGTIOP_LENGTH,
+ &state.viewport_width,
+ &x1
+ }, {
+ state.interned_y1,
+ SVGTIOP_LENGTH,
+ &state.viewport_height,
+ &y1
+ }, {
+ state.interned_x2,
+ SVGTIOP_LENGTH,
+ &state.viewport_width,
+ &x2
+ }, {
+ state.interned_y2,
+ SVGTIOP_LENGTH,
+ &state.viewport_height,
+ &y2
+ }, {
+ NULL, SVGTIOP_NONE, NULL, NULL
+ },
+ };
svgtiny_setup_state_local(&state);
- exc = dom_element_get_attribute(line, state.interned_x1, &attr);
- if (exc != DOM_NO_ERR) {
- svgtiny_cleanup_state_local(&state);
- return svgtiny_LIBDOM_ERROR;
- }
- if (attr != NULL) {
- svgtiny_parse_length(dom_string_data(attr),
- dom_string_byte_length(attr),
- state.viewport_width,
- &x1);
- }
- dom_string_unref(attr);
-
- exc = dom_element_get_attribute(line, state.interned_y1, &attr);
- if (exc != DOM_NO_ERR) {
+ err = svgtiny_parse_attributes(line, &state, ops);
+ if (err != svgtiny_OK) {
svgtiny_cleanup_state_local(&state);
- return svgtiny_LIBDOM_ERROR;
+ return err;
}
- if (attr != NULL) {
- svgtiny_parse_length(dom_string_data(attr),
- dom_string_byte_length(attr),
- state.viewport_height,
- &y1);
- }
- dom_string_unref(attr);
-
- exc = dom_element_get_attribute(line, state.interned_x2, &attr);
- if (exc != DOM_NO_ERR) {
- svgtiny_cleanup_state_local(&state);
- return svgtiny_LIBDOM_ERROR;
- }
- if (attr != NULL) {
- svgtiny_parse_length(dom_string_data(attr),
- dom_string_byte_length(attr),
- state.viewport_width,
- &x2);
- }
- dom_string_unref(attr);
-
- exc = dom_element_get_attribute(line, state.interned_y2, &attr);
- if (exc != DOM_NO_ERR) {
- svgtiny_cleanup_state_local(&state);
- return svgtiny_LIBDOM_ERROR;
- }
- if (attr != NULL) {
- svgtiny_parse_length(dom_string_data(attr),
- dom_string_byte_length(attr),
- state.viewport_height,
- &y2);
- }
- dom_string_unref(attr);
svgtiny_parse_paint_attributes(line, &state);
svgtiny_parse_transform_attributes(line, &state);
*/
void svgtiny_parse_position_attributes(dom_element *node,
- const struct svgtiny_parse_state state,
+ struct svgtiny_parse_state state,
float *x, float *y, float *width, float *height)
{
- dom_string *attr;
- dom_exception exc;
+ struct svgtiny_parse_internal_operation styles[] = {
+ {
+ /* x */
+ state.interned_x,
+ SVGTIOP_LENGTH,
+ &state.viewport_width,
+ x
+ },{
+ /* y */
+ state.interned_y,
+ SVGTIOP_LENGTH,
+ &state.viewport_height,
+ y
+ },{
+ /* width */
+ state.interned_width,
+ SVGTIOP_LENGTH,
+ &state.viewport_width,
+ width
+ },{
+ /* height */
+ state.interned_height,
+ SVGTIOP_LENGTH,
+ &state.viewport_height,
+ height
+ },{
+ NULL, SVGTIOP_NONE, NULL, NULL
+ },
+ };
*x = 0;
*y = 0;
*width = state.viewport_width;
*height = state.viewport_height;
- exc = dom_element_get_attribute(node, state.interned_x, &attr);
- if (exc == DOM_NO_ERR && attr != NULL) {
- svgtiny_parse_length(dom_string_data(attr),
- dom_string_byte_length(attr),
- state.viewport_width,
- x);
- dom_string_unref(attr);
- }
-
- exc = dom_element_get_attribute(node, state.interned_y, &attr);
- if (exc == DOM_NO_ERR && attr != NULL) {
- svgtiny_parse_length(dom_string_data(attr),
- dom_string_byte_length(attr),
- state.viewport_height,
- y);
- dom_string_unref(attr);
- }
-
- exc = dom_element_get_attribute(node, state.interned_width, &attr);
- if (exc == DOM_NO_ERR && attr != NULL) {
- svgtiny_parse_length(dom_string_data(attr),
- dom_string_byte_length(attr),
- state.viewport_width,
- width);
- dom_string_unref(attr);
- }
-
- exc = dom_element_get_attribute(node, state.interned_height, &attr);
- if (exc == DOM_NO_ERR && attr != NULL) {
- svgtiny_parse_length(dom_string_data(attr),
- dom_string_byte_length(attr),
- state.viewport_height,
- height);
- dom_string_unref(attr);
- }
+ svgtiny_parse_attributes(node, &state, styles);
}
void svgtiny_parse_paint_attributes(dom_element *node,
struct svgtiny_parse_state *state)
{
- dom_string *attr;
- dom_exception exc;
-
- /* fill color */
- exc = dom_element_get_attribute(node, state->interned_fill, &attr);
- if (exc == DOM_NO_ERR && attr != NULL) {
- svgtiny_parse_paint(dom_string_data(attr),
- dom_string_byte_length(attr),
- &state->fill_grad,
- state,
- &state->fill);
- dom_string_unref(attr);
- }
-
- /* stroke color */
- exc = dom_element_get_attribute(node, state->interned_stroke, &attr);
- if (exc == DOM_NO_ERR && attr != NULL) {
- svgtiny_parse_paint(dom_string_data(attr),
- dom_string_byte_length(attr),
- &state->stroke_grad,
- state,
- &state->stroke);
- dom_string_unref(attr);
- }
-
- /* stroke width */
- exc = dom_element_get_attribute(node, state->interned_stroke_width, &attr);
- if (exc == DOM_NO_ERR && attr != NULL) {
- float stroke_width;
- svgtiny_parse_length(dom_string_data(attr),
- dom_string_byte_length(attr),
- state->viewport_width,
- &stroke_width);
- state->stroke_width = stroke_width;
- dom_string_unref(attr);
- }
-
- /* style attribute */
- exc = dom_element_get_attribute(node, state->interned_style, &attr);
- if (exc == DOM_NO_ERR && attr != NULL) {
- struct svgtiny_parse_inline_style_op styles[]={
- {
- state->interned_fill,
- ISTYLEOP_PAINT,
- &state->fill_grad,
- &state->fill
- }, {
- state->interned_stroke,
- ISTYLEOP_PAINT,
- &state->stroke_grad,
- &state->stroke
- }, {
- state->interned_stroke_width,
- ISTYLEOP_INTLENGTH,
- &state->viewport_width,
- &state->stroke_width
- },{
- NULL, ISTYLEOP_NONE, NULL, NULL
- },
- };
- svgtiny_parse_inline_style(dom_string_data(attr),
- dom_string_byte_length(attr),
- state,
- styles);
- dom_string_unref(attr);
- }
+ struct svgtiny_parse_internal_operation ops[] = {
+ {
+ /* fill color */
+ state->interned_fill,
+ SVGTIOP_PAINT,
+ &state->fill_grad,
+ &state->fill
+ }, {
+ /* stroke color */
+ state->interned_stroke,
+ SVGTIOP_PAINT,
+ &state->stroke_grad,
+ &state->stroke
+ }, {
+ /* stroke width */
+ state->interned_stroke_width,
+ SVGTIOP_INTLENGTH,
+ &state->viewport_width,
+ &state->stroke_width
+ },{
+ NULL, SVGTIOP_NONE, NULL, NULL
+ },
+ };
+
+ svgtiny_parse_attributes(node, state, ops);
+ svgtiny_parse_inline_style(node, state, ops);
}
struct svgtiny_list;
-enum svgtiny_parse_inline_style_operation {
- ISTYLEOP_NONE,
- ISTYLEOP_PAINT,
- ISTYLEOP_COLOR,
- ISTYLEOP_LENGTH,
- ISTYLEOP_INTLENGTH,
-};
-
/**
* control structure for inline style parse
*/
-struct svgtiny_parse_inline_style_op {
+struct svgtiny_parse_internal_operation {
dom_string *key;
- enum svgtiny_parse_inline_style_operation operation;
+ enum {
+ SVGTIOP_NONE,
+ SVGTIOP_PAINT,
+ SVGTIOP_COLOR,
+ SVGTIOP_LENGTH,
+ SVGTIOP_INTLENGTH,
+ SVGTIOP_OFFSET,
+ } operation;
void *param;
void *value;
};
int viewport_size, float *length);
svgtiny_code svgtiny_parse_transform(const char *text, size_t textlen,
struct svgtiny_transformation_matrix *tm);
-svgtiny_code svgtiny_parse_paint(const char *text, size_t textlen,
- struct svgtiny_parse_state_gradient *grad,
- struct svgtiny_parse_state *state,
- svgtiny_colour *c);
svgtiny_code svgtiny_parse_color(const char *text, size_t textlen,
svgtiny_colour *c);
svgtiny_code svgtiny_parse_viewbox(const char *text, size_t textlen,
float viewport_width, float viewport_height,
struct svgtiny_transformation_matrix *tm);
-svgtiny_code svgtiny_parse_inline_style(const char *text, size_t textlen,
+svgtiny_code svgtiny_parse_inline_style(dom_element *node,
+ struct svgtiny_parse_state *state,
+ struct svgtiny_parse_internal_operation *ops);
+svgtiny_code svgtiny_parse_attributes(dom_element *node,
struct svgtiny_parse_state *state,
- struct svgtiny_parse_inline_style_op *styles);
+ struct svgtiny_parse_internal_operation *ops);
/* svgtiny_gradient.c */
svgtiny_code svgtiny_find_gradient(const char *id,
/* find and update gradient */
res = svgtiny_find_gradient(idstart, idend - idstart, grad, state);
+ if (res == svgtiny_OK) {
+ *c = svgtiny_LINEAR_GRADIENT;
+ }
+
+ return res;
+}
+
+
+/**
+ * Parse a paint.
+ *
+ * https://www.w3.org/TR/SVG11/painting.html#SpecifyingPaint
+ * https://www.w3.org/TR/SVG2/painting.html#SpecifyingPaint
+ *
+ */
+static svgtiny_code
+svgtiny_parse_paint(const char *text,
+ size_t textlen,
+ struct svgtiny_parse_state_gradient *grad,
+ struct svgtiny_parse_state *state,
+ svgtiny_colour *c)
+{
+ const char *cursor = text; /* cursor */
+ const char *textend = text+textlen;
+ svgtiny_code res;
+ advance_whitespace(&cursor, textend);
+
+ if (((textend - cursor) == 4) &&
+ cursor[0] == 'n' &&
+ cursor[1] == 'o' &&
+ cursor[2] == 'n' &&
+ cursor[3] == 'e') {
+ *c = svgtiny_TRANSPARENT;
+ return svgtiny_OK;
+ }
+
+ /* attempt to parse element as a paint url */
+ res = parse_paint_url(&cursor, textend, grad, state, c);
if (res == svgtiny_OK) {
- /* only set the color if the gradient was processed ok */
- if (grad->linear_gradient_stop_count == 0) {
- *c = svgtiny_TRANSPARENT;
- } else if (grad->linear_gradient_stop_count == 1) {
- *c = grad->gradient_stop[0].color;
- } else {
- *c = svgtiny_LINEAR_GRADIENT;
- }
+ return res;
}
+ return svgtiny_parse_color(cursor, textend - cursor, c);
+}
+
+
+/**
+ * parse an offset
+ */
+static svgtiny_code
+svgtiny_parse_offset(const char *text, size_t textlen, float *offset)
+{
+ svgtiny_code err;
+ float number;
+ const char *numend;
+
+ numend = text + textlen;
+ err = parse_number(text, &numend, &number);
+ if (err != svgtiny_OK) {
+ return err;
+ }
+ if ((numend < (text + textlen)) && (*numend == '%')) {
+ number /= 100.0;
+ }
+ /* ensure value between 0 and 1 */
+ if (number < 0) {
+ number = 0;
+ }
+ if (number > 1.0) {
+ number = 1.0;
+ }
+ *offset = number;
+ return svgtiny_OK;
+}
+
+
+/**
+ * dispatch parse operation
+ */
+static inline svgtiny_code
+dispatch_op(const char *value,
+ size_t value_len,
+ struct svgtiny_parse_state *state,
+ struct svgtiny_parse_internal_operation *styleop)
+{
+ float parse_len;
+ svgtiny_code res = svgtiny_OK;
+
+ switch (styleop->operation) {
+ case SVGTIOP_NONE:
+ res = svgtiny_SVG_ERROR;
+ break;
+
+ case SVGTIOP_PAINT:
+ res = svgtiny_parse_paint(value,
+ value_len,
+ styleop->param,
+ state,
+ styleop->value);
+ break;
+
+ case SVGTIOP_COLOR:
+ res = svgtiny_parse_color(value, value_len, styleop->value);
+ break;
+
+ case SVGTIOP_LENGTH:
+ res = svgtiny_parse_length(value,
+ value_len,
+ *((int *)styleop->param),
+ styleop->value);
+ break;
+
+ case SVGTIOP_INTLENGTH:
+ res = svgtiny_parse_length(value,
+ value_len,
+ *((int *)styleop->param),
+ &parse_len);
+ *((int *)styleop->value) = parse_len;
+ break;
+
+ case SVGTIOP_OFFSET:
+ res = svgtiny_parse_offset(value, value_len, styleop->value);
+ break;
+ }
return res;
}
+/**
+ * parse a declaration in a style
+ *
+ * https://www.w3.org/TR/CSS21/syndata.html#declaration
+ *
+ * \param declaration The declaration without any preceeding space
+ * \param end The end of the declaration string
+ * \param state parse state to pass on
+ * \param styleops The table of style operations to apply
+ *
+ * declaration is "<property name> : <property value>"
+ */
+static inline svgtiny_code
+parse_declaration(const char *declaration,
+ const char *end,
+ struct svgtiny_parse_state *state,
+ struct svgtiny_parse_internal_operation *styleops)
+{
+ const char *cursor = declaration; /* text cursor */
+ size_t key_len; /* key length */
+ struct svgtiny_parse_internal_operation *styleop;
+
+ /* declaration must be at least 3 characters long (ie "a:b") */
+ if ((end - declaration) < 3) {
+ return svgtiny_SVG_ERROR;
+ }
+
+ /* find end of key */
+ advance_property_name(&cursor, end);
+
+ if ((cursor - declaration) < 1) {
+ /* no key */
+ return svgtiny_SVG_ERROR;
+ }
+
+ key_len = cursor - declaration;
+
+ advance_whitespace(&cursor, end);
+
+ if ((cursor >= end) || (*cursor != ':')) {
+ /* no colon */
+ return svgtiny_SVG_ERROR;
+ }
+ cursor++; /* advance over colon */
+
+ advance_whitespace(&cursor, end);
+
+ /* search style operations for a match */
+ for (styleop = styleops; styleop->key != NULL; styleop++) {
+ if ((dom_string_byte_length(styleop->key) == key_len) &&
+ (memcmp(declaration, dom_string_data(styleop->key), key_len) == 0)) {
+ /* found the operation, stop iterating */
+ return dispatch_op(cursor, end - cursor, state, styleop);
+ }
+ }
+
+ return svgtiny_OK;
+}
+
+
/**
* parse text points into path points
*
}
-/**
- * Parse a paint.
- *
- * https://www.w3.org/TR/SVG11/painting.html#SpecifyingPaint
- * https://www.w3.org/TR/SVG2/painting.html#SpecifyingPaint
- *
- */
-svgtiny_code
-svgtiny_parse_paint(const char *text,
- size_t textlen,
- struct svgtiny_parse_state_gradient *grad,
- struct svgtiny_parse_state *state,
- svgtiny_colour *c)
-{
- const char *cursor = text; /* cursor */
- const char *textend = text+textlen;
- svgtiny_code res;
-
- advance_whitespace(&cursor, textend);
-
- if (((textend - cursor) == 4) &&
- cursor[0] == 'n' &&
- cursor[1] == 'o' &&
- cursor[2] == 'n' &&
- cursor[3] == 'e') {
- *c = svgtiny_TRANSPARENT;
- return svgtiny_OK;
- }
-
- /* attempt to parse element as a paint url */
- res = parse_paint_url(&cursor, textend, grad, state, c);
- if (res == svgtiny_OK) {
- return res;
- }
-
- return svgtiny_parse_color(cursor, textend - cursor, c);
-}
/**
return svgtiny_OK;
}
+
/**
- * parse a declaration in a style
- *
- * https://www.w3.org/TR/CSS21/syndata.html#declaration
- *
- * \param declaration The declaration without any preceeding space
- * \param end The end of the declaration string
- * \param state parse state to pass on
- * \param styleops The table of style operations to apply
- *
- * declaration is "<property name> : <property value>"
+ * parse an inline style
*/
-static inline svgtiny_code
-parse_declaration(const char *declaration,
- const char *end,
- struct svgtiny_parse_state *state,
- struct svgtiny_parse_inline_style_op *styleops)
+svgtiny_code
+svgtiny_parse_inline_style(dom_element *node,
+ struct svgtiny_parse_state *state,
+ struct svgtiny_parse_internal_operation *ops)
{
- const char *cursor = declaration; /* text cursor */
- size_t key_len; /* key length */
- struct svgtiny_parse_inline_style_op *styleop;
-
- /* declaration must be at least 3 characters long (ie "a:b") */
- if ((end - declaration) < 3) {
- return svgtiny_SVG_ERROR;
- }
-
- /* find end of key */
- advance_property_name(&cursor, end);
+ const char *cursor; /* text cursor */
+ const char *textend;
+ const char *declaration_start;
+ dom_string *attr;
+ dom_exception exc;
- if ((cursor - declaration) < 1) {
- /* no key */
- return svgtiny_SVG_ERROR;
+ /* style attribute */
+ exc = dom_element_get_attribute(node, state->interned_style, &attr);
+ if (exc != DOM_NO_ERR) {
+ return svgtiny_LIBDOM_ERROR;
}
-
- key_len = cursor - declaration;
-
- advance_whitespace(&cursor, end);
-
- if ((cursor >= end) || (*cursor != ':')) {
- /* no colon */
- return svgtiny_SVG_ERROR;
+ if (attr == NULL) {
+ /* no style attribute */
+ return svgtiny_OK;
}
- cursor++; /* advance over colon */
-
- advance_whitespace(&cursor, end);
-
- /* search style operations for a match */
- for (styleop = styleops; styleop->key != NULL; styleop++) {
- if ((dom_string_byte_length(styleop->key) == key_len) &&
- (memcmp(declaration, dom_string_data(styleop->key), key_len) == 0)) {
- float parse_len;
-
- switch (styleop->operation) {
- case ISTYLEOP_PAINT:
- svgtiny_parse_paint(cursor,
- end - cursor,
- styleop->param,
- state,
- styleop->value);
- break;
+ cursor = dom_string_data(attr);
+ textend = cursor + dom_string_byte_length(attr);
- case ISTYLEOP_COLOR:
- svgtiny_parse_color(cursor,
- end - cursor,
- styleop->value);
- break;
-
- case ISTYLEOP_LENGTH:
- svgtiny_parse_length(cursor,
- end - cursor,
- *((int *)styleop->param),
- styleop->value);
- break;
-
- case ISTYLEOP_INTLENGTH:
- svgtiny_parse_length(cursor,
- end - cursor,
- *((int *)styleop->param),
- &parse_len);
- *((int *)styleop->value) = parse_len;
- break;
-
- default:
+ while (cursor < textend) {
+ advance_whitespace(&cursor, textend);
+ declaration_start = cursor;
+ while (cursor < textend) {
+ if ((*cursor == ';') &&
+ (*(cursor - 1) != '\\')) {
break;
}
- break; /* found the operation, stop iterating */
+ cursor++;
}
+ parse_declaration(declaration_start, cursor, state, ops);
+ cursor++; /* skip semicolon */
}
-
+ dom_string_unref(attr);
return svgtiny_OK;
}
+
/**
- * parse an inline style
+ * parse attributes controled by operation table
*/
svgtiny_code
-svgtiny_parse_inline_style(const char *text,
- size_t textlen,
- struct svgtiny_parse_state *state,
- struct svgtiny_parse_inline_style_op *styles)
+svgtiny_parse_attributes(dom_element *node,
+ struct svgtiny_parse_state *state,
+ struct svgtiny_parse_internal_operation *styleops)
{
- const char *cursor = text; /* text cursor */
- const char *textend = text + textlen;
- const char *declaration_start;
+ struct svgtiny_parse_internal_operation *styleop;
+ dom_string *attr;
+ dom_exception exc;
- while (cursor < textend) {
- advance_whitespace(&cursor, textend);
- declaration_start = cursor;
- while (cursor < textend) {
- if ((*cursor == ';') &&
- (*(cursor - 1) != '\\')) {
- break;
- }
- cursor++;
+ for (styleop = styleops; styleop->key != NULL; styleop++) {
+ exc = dom_element_get_attribute(node, styleop->key, &attr);
+ if (exc != DOM_NO_ERR) {
+ return svgtiny_LIBDOM_ERROR;
+ }
+ if (attr != NULL) {
+ dispatch_op(dom_string_data(attr),
+ dom_string_byte_length(attr),
+ state,
+ styleop);
+ dom_string_unref(attr);
}
- parse_declaration(declaration_start, cursor, state, styles);
- cursor++;/* skip semicolon */
}
return svgtiny_OK;
}