コード例 #1
0
/* Parse a CSS2 style argument */
static svg_status_t
_svg_style_parse_nv_pair (svg_style_t	*style,
			  const char	*nv_pair)
{
    unsigned int i;
    char *name, *value;
    svg_status_t status;

    status = _svg_style_split_nv_pair_alloc (nv_pair, &name, &value);
    if (status)
	return status;

    /* guilty until proven innocent */
    /* XXX: Check SVG spec. for this error condition */
    status = SVG_STATUS_PARSE_ERROR;

    for (i=0; i < SVG_ARRAY_SIZE(SVG_STYLE_PARSE_MAP); i++)
	if (strcmp (SVG_STYLE_PARSE_MAP[i].name, name) == 0) {
	    status = (SVG_STYLE_PARSE_MAP[i].parse) (style, value);
	    break;
	}

    free (name);
    free (value);

    return status;
}
コード例 #2
0
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;
}
コード例 #3
0
ファイル: svg_parser.c プロジェクト: isvissu/SVGImageRep
void
_svg_parser_sax_start_element (void		*closure,
			       const xmlChar	*name_unsigned,
			       const xmlChar	**attributes_unsigned)
{
    unsigned int i;
    svg_parser_t *parser = closure;
    const svg_parser_cb_t *cb;
    svg_element_t *element;
    const char *name = (const char *) name_unsigned;
    const char **attributes = (const char **) attributes_unsigned;

    if (parser->unknown_element_depth) {
		parser->unknown_element_depth++;
		return;
    }

    cb = NULL;
    for (i=0; i < SVG_ARRAY_SIZE (SVG_PARSER_MAP); i++) {
		if (strcmp (SVG_PARSER_MAP[i].name, name) == 0) {
			cb = &SVG_PARSER_MAP[i].cb;
			break;
		}
    }

    if (cb == NULL) {
		parser->unknown_element_depth++;
		return;
    }

    parser->status = _svg_parser_push_state (parser, cb);
    if (parser->status)
		return;

    parser->status = (cb->parse_element) (parser, attributes, &element);
    if (parser->status) {
		if (parser->status == SVGINT_STATUS_UNKNOWN_ELEMENT)
			parser->status = SVG_STATUS_SUCCESS;
		return;
    }

    parser->status = _svg_element_apply_attributes (element, attributes);
    if (parser->status)
		return;

    if (element->id)
		_svg_store_element_by_id (parser->svg, element);

    return;
}
コード例 #4
0
svg_status_t
_svg_style_init_defaults (svg_style_t *style, svg_t *svg)
{
    int i;
    svg_status_t status;

    style->svg = svg;

    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];

	if (map->default_value) {
	    status = (map->parse) (style, map->default_value);
	    if (status)
		return status;
	}
    }

    return SVG_STATUS_SUCCESS;
}
コード例 #5
0
ファイル: svg_transform.c プロジェクト: isvissu/SVGImageRep
/* The following parse function is:

   Copyright (C) 2000 Eazel, Inc.
   Copyright (C) 2002 Dom Lachowicz <*****@*****.**>

   Author: Raph Levien <*****@*****.**>

   Parse an SVG transform string into an affine matrix. Reference: SVG
   working draft dated 1999-07-06, section 8.5.
*/
extern svg_status_t
_svg_transform_parse_str (svg_transform_t *transform, const char *str)
{
    intptr_t idx;
    svg_status_t status;
    char keyword[32];
    double args[6];
    int n_args;
    unsigned int key_len;
    svg_transform_t tmp_transform;

    status = _svg_transform_init (transform);
    if (status)
		return status;

    idx = 0;
    while (str[idx]) {
		/* skip initial whitespace */
		while (_svg_ascii_isspace (str[idx]) || str[idx] == ',')
			idx++;

		/* parse keyword */
		for (key_len = 0; key_len < sizeof (keyword); key_len++) {
			char c;

			c = str[idx];
			if (_svg_ascii_isalpha (c) || c == '-')
				keyword[key_len] = str[idx++];
			else
				break;
		}
		/* XXX: This size limitation looks bogus */
		if (key_len >= sizeof (keyword))
			return SVG_STATUS_PARSE_ERROR;
		keyword[key_len] = '\0';

		/* skip whitespace */
		while (_svg_ascii_isspace (str[idx]))
			idx++;

		if (str[idx] != '(')
			return SVG_STATUS_PARSE_ERROR;
		idx++;
		
		for (n_args = 0; ; n_args++) {
			char c;
			const char *end_ptr;

			/* skip whitespace */
			while (_svg_ascii_isspace (str[idx]))
				idx++;
			c = str[idx];
			if (_svg_ascii_isdigit (c) || c == '+' || c == '-' || c == '.') {
				if (n_args == SVG_ARRAY_SIZE (args))
					return SVG_STATUS_PARSE_ERROR;
				args[n_args] = _svg_ascii_strtod (str + idx, &end_ptr);
				idx = end_ptr - str;

				while (_svg_ascii_isspace (str[idx]))
					idx++;

				/* skip optional comma */
				if (str[idx] == ',')
					idx++;
			} else if (c == ')')
				break;
			else
				return SVG_STATUS_PARSE_ERROR;
		}
		idx++;

		/* ok, have parsed keyword and args, now modify the transform */
		if (strcmp (keyword, "matrix") == 0) {
			if (n_args != 6)
				return SVG_STATUS_PARSE_ERROR;
			_svg_transform_init_matrix (&tmp_transform,
										args[0], args[1],
										args[2], args[3],
										args[4], args[5]);
			_svg_transform_multiply_into_right (&tmp_transform, transform);
		} else if (strcmp (keyword, "translate") == 0) {
			if (n_args == 1)
				args[1] = 0;
			else if (n_args != 2)
				return SVG_STATUS_PARSE_ERROR;
			_svg_transform_add_translate (transform, args[0], args[1]);
		} else if (strcmp (keyword, "scale") == 0) {
			if (n_args == 1)
				args[1] = args[0];
			else if (n_args != 2)
				return SVG_STATUS_PARSE_ERROR;
			_svg_transform_add_scale (transform, args[0], args[1]);
		} else if (strcmp (keyword, "rotate") == 0) {
			if (n_args != 1)
				return SVG_STATUS_PARSE_ERROR;
			_svg_transform_add_rotate (transform, args[0]);
		} else if (strcmp (keyword, "skewX") == 0) {
			if (n_args != 1)
				return SVG_STATUS_PARSE_ERROR;
			_svg_transform_add_skew_x (transform, args[0]);
		} else if (strcmp (keyword, "skewY") == 0) {
			if (n_args != 1)
				return SVG_STATUS_PARSE_ERROR;
			_svg_transform_add_skew_y (transform, args[0]);
		} else
			return SVG_STATUS_PARSE_ERROR;
    }

    return SVG_STATUS_SUCCESS;
}
コード例 #6
0
ファイル: svg_parser_path.c プロジェクト: agambier/libsvg2
svgItem* svgParsePath( xmlNodePtr ptXmlNode )
{
	svgItem *ptItem = NULL;
	char *szValue, szField[ 16 ];
	const char *szFieldStart;
	svgPathCommand *ptPathCmd, *ptLastPathCmd = NULL;
	unsigned int uiCmdIdx;
	int8 iI;
	svgLength atArgs[ 12 ];

	if( ptXmlNode==NULL )
		return NULL;
	if( strcmp( ( char* )ptXmlNode->name, SVG_TAG_PATH )!=0 )
		return NULL;

	//	Read common values to all kind of item
	ptItem = svgNewItem( ptXmlNode );
	if( ptItem==NULL )
		return NULL;

	ptItem->tKind = SVG_ITEM_KIND_PATH;

	//	d
	if( ( szValue = ( char* )xmlGetProp( ptXmlNode, ( xmlChar* )"d" ) )!=NULL ) {
		ptLastPathCmd = NULL;
		szFieldStart = svgGetNextPathField( szValue, szField, 16 );
		while( szFieldStart!=NULL ) {

			ptPathCmd = NULL;

			//	What's this command ?
			if( svgIsRealNumber( szField )!= 0) {

				//	No command so use last command
				if( ptLastPathCmd!=NULL ) {

					switch( ptLastPathCmd->tId ) {
						//	MoveTo => LineTo
						case SVG_PATH_CMD_ID_MOVETO_ABS:
						case SVG_PATH_CMD_ID_MOVETO_REL:
							ptPathCmd = svgNewPathCommand( ( ptLastPathCmd->tId==SVG_PATH_CMD_ID_MOVETO_REL ) ? SVG_PATH_CMD_ID_LINETO_REL : SVG_PATH_CMD_ID_LINETO_ABS );
							break;
						//	Repeated command
						default:
							ptPathCmd = svgNewPathCommand( ptLastPathCmd->tId );
							break;
					}

					//	Search command format
					for( uiCmdIdx = 0; g_atPathCommandFormat[ uiCmdIdx ].cCommand!='\0'; uiCmdIdx ++ ) {
						if( g_atPathCommandFormat[ uiCmdIdx ].tId==ptPathCmd->tId ) {
							break;
						}
					}

					//	Since we already read the parameter of the command we don't want to skip when we'll parse the command's parameters.
					szField[ 0 ] = 0;
				}
			}
			else {
				//	Search command format
				for( uiCmdIdx = 0; g_atPathCommandFormat[ uiCmdIdx ].cCommand!='\0'; uiCmdIdx ++ ) {
					if( g_atPathCommandFormat[ uiCmdIdx ].cCommand==szField[ 0 ] ) {
						ptPathCmd = svgNewPathCommand( g_atPathCommandFormat[ uiCmdIdx ].tId );
						break;
					}
				}
			}
			
			if (ptPathCmd == NULL) {
				svgSetLastError( SVG_ERR_NOT_ENOUGH_RAM, "Unrecognized path command '%c'.", szField[ 0 ] );
				return ptItem;
			}
			
			//	Parse args
			for( iI = 0; ( iI < g_atPathCommandFormat[ uiCmdIdx ].i8NbrOfArgs ) && ( iI < ( int8 )SVG_ARRAY_SIZE( atArgs ) ); iI ++ ) {
				atArgs[ iI ].fValue = 0;
				szFieldStart += strlen( szField );
				if( ( szFieldStart = svgGetNextPathField( szFieldStart, szField, 16 ) )!=NULL ) {
					if( svgIsRealNumber( szField )!= 0)
						svgStringToCoordinate( szField, &atArgs[ iI ] );
				}
			}

			//	Parse the command parameters
			switch( ptPathCmd->tId ) {
				//	MoveTo
				case SVG_PATH_CMD_ID_MOVETO_ABS:
				case SVG_PATH_CMD_ID_MOVETO_REL:
					ptPathCmd->tParameters.tMoveTo.tX = atArgs[ 0 ];
					ptPathCmd->tParameters.tMoveTo.tY = atArgs[ 1 ];
					break;

				//	LineTo
				case SVG_PATH_CMD_ID_LINETO_ABS:
				case SVG_PATH_CMD_ID_LINETO_REL:
					ptPathCmd->tParameters.tLineTo.tX = atArgs[ 0 ];
					ptPathCmd->tParameters.tLineTo.tY = atArgs[ 1 ];
					break;

				//	Vertical LineTo
				case SVG_PATH_CMD_ID_VERTICAL_LINETO_ABS:
				case SVG_PATH_CMD_ID_VERTICAL_LINETO_REL:
					ptPathCmd->tParameters.tLineTo.tY = atArgs[ 0 ];
					break;

				//	Horizontal LineTo
				case SVG_PATH_CMD_ID_HORIZONTAL_LINETO_ABS:
				case SVG_PATH_CMD_ID_HORIZONTAL_LINETO_REL:
					ptPathCmd->tParameters.tLineTo.tX = atArgs[ 0 ];
					break;

				//	Cubic CurveTo
				case SVG_PATH_CMD_ID_CUBIC_CURVETO_ABS:
				case SVG_PATH_CMD_ID_CUBIC_CURVETO_REL:
					ptPathCmd->tParameters.tCubicCurveTo.tX1 = atArgs[ 0 ];
					ptPathCmd->tParameters.tCubicCurveTo.tY1 = atArgs[ 1 ];
					ptPathCmd->tParameters.tCubicCurveTo.tX2 = atArgs[ 2 ];
					ptPathCmd->tParameters.tCubicCurveTo.tY2 = atArgs[ 3 ];
					ptPathCmd->tParameters.tCubicCurveTo.tX = atArgs[ 4 ];
					ptPathCmd->tParameters.tCubicCurveTo.tY = atArgs[ 5 ];
					break;

				//	Smooth Cubic CurveTo
				case SVG_PATH_CMD_ID_SMOOTH_CUBIC_CURVETO_ABS:
				case SVG_PATH_CMD_ID_SMOOTH_CUBIC_CURVETO_REL:
					ptPathCmd->tParameters.tSmoothCubicCurveTo.tX2 = atArgs[ 0 ];
					ptPathCmd->tParameters.tSmoothCubicCurveTo.tY2 = atArgs[ 1 ];
					ptPathCmd->tParameters.tSmoothCubicCurveTo.tX = atArgs[ 2 ];
					ptPathCmd->tParameters.tSmoothCubicCurveTo.tY = atArgs[ 3 ];
					break;

				//	Quadratic CurveTo
				case SVG_PATH_CMD_ID_QUADRATIC_CURVETO_ABS:
				case SVG_PATH_CMD_ID_QUADRATIC_CURVETO_REL:
					ptPathCmd->tParameters.tQuadraticCurveTo.tX1 = atArgs[ 0 ];
					ptPathCmd->tParameters.tQuadraticCurveTo.tY1 = atArgs[ 1 ];
					ptPathCmd->tParameters.tQuadraticCurveTo.tX = atArgs[ 2 ];
					ptPathCmd->tParameters.tQuadraticCurveTo.tY = atArgs[ 3 ];
					break;

				//	Quadratic Cubic CurveTo
				case SVG_PATH_CMD_ID_SMOOTH_QUADRATIC_CURVETO_ABS:
				case SVG_PATH_CMD_ID_SMOOTH_QUADRATIC_CURVETO_REL:
					ptPathCmd->tParameters.tSmoothQuadraticCurveTo.tX = atArgs[ 0 ];
					ptPathCmd->tParameters.tSmoothQuadraticCurveTo.tY = atArgs[ 1 ];
					break;

				//	ArcTo
				case SVG_PATH_CMD_ID_ARCTO_ABS:
				case SVG_PATH_CMD_ID_ARCTO_REL:
					ptPathCmd->tParameters.tArcTo.tRadiusX = atArgs[ 0 ];
					ptPathCmd->tParameters.tArcTo.tRadiusY = atArgs[ 1 ];
					ptPathCmd->tParameters.tArcTo.tXAxisAngle = atArgs[ 2 ];
					ptPathCmd->tParameters.tArcTo.tLargeArcFlag = atArgs[ 3 ];
					ptPathCmd->tParameters.tArcTo.tSweepFlag = atArgs[ 4 ];
					ptPathCmd->tParameters.tArcTo.tX = atArgs[ 5 ];
					ptPathCmd->tParameters.tArcTo.tY = atArgs[ 6 ];
					break;

				//	No parameters
				case SVG_PATH_CMD_ID_CLOSEPATH:
				default:
					break;
			}

			//	Store the new command into the command list
			if( ptItem->tParameters.tPath.ptFirstCommand==NULL )
				ptItem->tParameters.tPath.ptFirstCommand = ptPathCmd;

			if( ptLastPathCmd!=NULL )
				ptLastPathCmd->ptNextCommand = ptPathCmd;

			ptLastPathCmd = ptPathCmd;

			//	Next
			szFieldStart += strlen( szField );
			szFieldStart = svgGetNextPathField( szFieldStart, szField, 16 );
		}
	}


	return ptItem;
}
コード例 #7
0
svg_status_t
_svg_color_init_from_str (svg_color_t *color, const char *str)
{
    unsigned int r=0, g=0, b=0;
    svg_status_t status;
    svg_color_map_t *map;

    /* XXX: Need to check SVG spec. for this error case */
    if (str == NULL || str[0] == '\0')
	return _svg_color_init_rgb (color, 0, 0, 0);

    if (strcmp (str, "currentColor") == 0) {
	_svg_color_init_rgb (color, 0, 0, 0);
	color->is_current_color = 1;
	return SVG_STATUS_SUCCESS;
    }

    color->is_current_color = 0;

    if (str[0] == '#') {
	str++;
	if (strlen(str) >= 6) {
	    r = _svg_color_get_two_hex_digits (str);
	    str += 2;
	    g = _svg_color_get_two_hex_digits (str);
	    str += 2;
	    b = _svg_color_get_two_hex_digits (str);
	} else if (strlen(str) >= 3) {
	    r = _svg_color_get_hex_digit (str);
	    r += (r << 4);
	    str++;
	    g = _svg_color_get_hex_digit (str);
	    g += (g << 4);
	    str++;
	    b = _svg_color_get_hex_digit (str);
	    b += (b << 4);
	}

	return _svg_color_init_rgb (color, r, g, b);
    }

    _svg_str_skip_space (&str);
    if (strncmp (str, "rgb", 3) == 0) {
	str += 3;

	_svg_str_skip_space (&str);
	_svg_str_skip_char (&str, '(');
	status = _svg_color_parse_component (&str, &r);
	if (status)
	    return status;
	_svg_str_skip_char (&str, ',');
	status = _svg_color_parse_component (&str, &g);
	if (status)
	    return status;
	_svg_str_skip_char (&str, ',');
	status = _svg_color_parse_component (&str, &b);
	if (status)
	    return status;
	_svg_str_skip_char (&str, ')');

	return _svg_color_init_rgb (color, r, g, b);
    }

    map = (svg_color_map_t *)bsearch (str, SVG_COLOR_MAP,
		   SVG_ARRAY_SIZE(SVG_COLOR_MAP),
		   sizeof (svg_color_map_t),
		   _svg_color_cmp);
    
    /* default to black on failed lookup */
    if (map == NULL)
	return _svg_color_init_rgb (color, 0, 0, 0);

    *color = map->color;

    return SVG_STATUS_SUCCESS;
}