static svg_status_t
_svg_style_parse_stop_color (svg_style_t *style, const char *str)
{
    svg_status_t status;

    status = _svg_color_init_from_str (&style->color, str);
    if (status)
	return status;

    style->flags |= SVG_STYLE_FLAG_COLOR;

    return SVG_STATUS_SUCCESS;
}
svg_status_t
_svg_paint_init (svg_paint_t *paint, svg_t *svg, const char *str)
{
    svg_status_t status;

    if (strcmp (str, "none") == 0) {
	paint->type = SVG_PAINT_TYPE_NONE;
	return SVG_STATUS_SUCCESS;
    }

    /* Paint parser courtesy of Steven Kramer */
    if (strncmp (str, "url(#", 5) == 0 && strchr (str, ')')) {
    	svg_element_t	*element = NULL;
    	const char	*end = strchr (str, ')');
    	int 		length = end - (str + 5);
    	char		*id = malloc (length+1);
    	if (!id)
	    return SVG_STATUS_NO_MEMORY;

    	strncpy (id, str + 5, length);
    	id[length] = '\0';

    	_svg_fetch_element_by_id (svg, id, &element);
    	free (id);

	if (element == NULL)
	    return SVG_STATUS_PARSE_ERROR;

	switch (element->type) {
	case SVG_ELEMENT_TYPE_GRADIENT:
	    paint->type = SVG_PAINT_TYPE_GRADIENT;
	    paint->p.gradient = &element->e.gradient;
	    break;
	case SVG_ELEMENT_TYPE_PATTERN:
	    paint->type = SVG_PAINT_TYPE_PATTERN;
	    paint->p.pattern_element = element;
	    break;
	default:
	    return SVG_STATUS_PARSE_ERROR;
	}

	return SVG_STATUS_SUCCESS;
    }

    status = _svg_color_init_from_str (&paint->p.color, str);
    if (status)
	return status;
    paint->type = SVG_PAINT_TYPE_COLOR;

    return SVG_STATUS_SUCCESS;
}
Exemple #3
0
/* 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;
}