svg_status_t _svg_style_apply_attributes (svg_style_t *style, const char **attributes) { unsigned int i; svg_status_t status; const char *style_str, *str; _svg_attribute_get_string (attributes, "style", &style_str, NULL); if (style_str) { status = _svg_style_parse_style_str (style, style_str); if (status) return status; } for (i=0; i < SVG_ARRAY_SIZE(SVG_STYLE_PARSE_MAP); i++) { const svg_style_parse_map_t *map; map = &SVG_STYLE_PARSE_MAP[i]; _svg_attribute_get_string (attributes, map->name, &str, NULL); if (str) { status = (map->parse) (style, str); if (status) return status; } } return SVG_STATUS_SUCCESS; }
/* Apply attributes unique to `svg' elements */ svg_status_t _svg_group_apply_svg_attributes (svg_group_t *group, const char **attributes) { const char *view_box_str, *aspect_ratio_str; _svg_attribute_get_length (attributes, "width", &group->width, "100%"); _svg_attribute_get_length (attributes, "height", &group->height, "100%"); /* XXX: What else? */ _svg_attribute_get_length (attributes, "x", &group->x, "0"); _svg_attribute_get_length (attributes, "y", &group->y, "0"); _svg_attribute_get_string (attributes, "viewBox", &view_box_str, NULL); if (view_box_str) { (void) _svg_element_parse_view_box (view_box_str, &group->view_box.box.x, &group->view_box.box.y, &group->view_box.box.width, &group->view_box.box.height); group->view_box.aspect_ratio = SVG_PRESERVE_ASPECT_RATIO_NONE; _svg_attribute_get_string (attributes, "preserveAspectRatio", &aspect_ratio_str, NULL); if (aspect_ratio_str) (void) _svg_element_parse_aspect_ratio (aspect_ratio_str, &group->view_box); } return SVG_STATUS_SUCCESS; }
svg_status_t _svg_group_apply_use_attributes (svg_element_t *group, const char **attributes) { const char *href; svg_element_t *ref; svg_element_t *clone; svgint_status_t status = SVG_STATUS_SUCCESS; _svg_attribute_get_string (attributes, "xlink:href", &href, ""); _svg_fetch_element_by_id (group->doc, href + 1, &ref); if (!ref) { /* XXX: Should we report an error here? */ return SVG_STATUS_SUCCESS; } _svg_attribute_get_length (attributes, "width", &group->e.group.width, "100%"); _svg_attribute_get_length (attributes, "height", &group->e.group.height, "100%"); clone = ref; _svg_element_reference(ref); if (status) return status; if (clone) { _svg_group_add_element (&group->e.group, clone); } return SVG_STATUS_SUCCESS; }
svg_status_t _svg_transform_apply_attributes (svg_transform_t *transform, const char **attributes) { const char *transform_str; _svg_attribute_get_string (attributes, "transform", &transform_str, NULL); if (transform_str) return _svg_transform_parse_str (transform, transform_str); return SVG_STATUS_SUCCESS; }
/* XXX: This function is a mess --- it's doing its own style/attribute handling rather than leaving that to the existing framework. Instead this should be shifted to the standard mechanism, whereby we have a new svg_gradient_stop element, etc. If we'd like to, we can collapse the gradient's child stop elements into an array when the gradient is done being parsed. */ static svg_status_t _svg_parser_parse_gradient_stop (svg_parser_t *parser, const char **attributes, svg_element_t **gradient_element) { svg_style_t style; svg_gradient_t* gradient; double offset; double opacity; svg_color_t color; const char* color_str; svg_element_t *group_element; gradient_element = NULL; if (parser->state->group_element == NULL || parser->state->group_element->type != SVG_ELEMENT_TYPE_GRADIENT) return SVG_STATUS_PARSE_ERROR; group_element = parser->state->group_element; gradient = &group_element->e.gradient; /* XXX: This ad-hoc style parsing breaks inheritance I believe. */ _svg_style_init_empty (&style, parser->svg); style.flags = SVG_STYLE_FLAG_NONE; _svg_style_apply_attributes (&style, attributes); color = style.color; opacity = style.opacity; _svg_attribute_get_double (attributes, "offset", &offset, 0); _svg_attribute_get_double (attributes, "stop-opacity", &opacity, opacity); if (_svg_attribute_get_string (attributes, "stop-color", &color_str, "#000000") == SVG_STATUS_SUCCESS) _svg_color_init_from_str (&color, color_str); if (color.is_current_color) color = group_element->style.color; /* XXX: Rather than directly storing the stop in the gradient here, it would be cleaner to just have the stop be a standard child element. */ _svg_gradient_add_stop (gradient, offset, &color, opacity); /* XXX: Obviously, this is totally bogus and needs to change. */ /* not quite unknown, just don't store the element and stop applying attributes */ return SVGINT_STATUS_UNKNOWN_ELEMENT; }
static svg_status_t _svg_parser_parse_polyline (svg_parser_t *parser, const char **attributes, svg_element_t **path_element) { svg_status_t status; const char *points; const char *p, *next; svg_path_t *path; double pt[2]; int first; _svg_attribute_get_string (attributes, "points", &points, NULL); if (points == NULL) return SVG_STATUS_PARSE_ERROR; status = _svg_parser_new_leaf_element (parser, path_element, SVG_ELEMENT_TYPE_PATH); if (status) return status; path = &(*path_element)->e.path; first = 1; p = points; while (*p) { status = _svg_str_parse_csv_doubles (p, pt, 2, &next); if (status) return SVG_STATUS_PARSE_ERROR; if (first) { _svg_path_move_to (path, pt[0], pt[1]); first = 0; } else { _svg_path_line_to (path, pt[0], pt[1]); } p = next; _svg_str_skip_space (&p); } return SVG_STATUS_SUCCESS; }