⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 svg_parser.c

📁 一个用于智能手机的多媒体库适合S60 WinCE的跨平台开发库
💻 C
📖 第 1 页 / 共 3 页
字号:
				}			} else if (!stricmp(attributes->name, "href")) {				if (tag == TAG_SVG_set ||						tag == TAG_SVG_animate ||						tag == TAG_SVG_animateColor ||						tag == TAG_SVG_animateTransform ||						tag == TAG_SVG_animateMotion || 						tag == TAG_SVG_discard) {					/* we don't parse the animation element attributes here */				} else {					GF_FieldInfo info;					if (!gf_node_get_field_by_name((GF_Node *)elt, "xlink:href", &info)) {						gf_svg_parse_attribute((GF_Node *)elt, &info, attributes->children->content, 0, 0);						/*try to store base-coded data*/						gf_svg_store_embedded_data(info.far_ptr, parser->temp_dir, parser->file_name);					}				}			} else if (strcmp(attributes->name, "style")) {				GF_FieldInfo info;				u32 evtType = gf_dom_event_type_by_name((char *) attributes->name + 2);				if (evtType != GF_EVENT_UNKNOWN) {					SVG_SA_handlerElement *handler;					handler = gf_dom_listener_build((GF_Node *) elt, evtType, 0, NULL);					handler->textContent = strdup(attributes->children->content);					gf_node_init((GF_Node *)handler);				} else if (!gf_node_get_field_by_name((GF_Node *)elt, (char *)attributes->name, &info)) {					gf_svg_parse_attribute((GF_Node *)elt, &info, attributes->children->content, anim_value_type, anim_transform_type);				} else {					GF_LOG(GF_LOG_WARNING, GF_LOG_PARSER, ("[SVG] Unknown attribute %s on element %s\n", attributes->name, gf_node_get_class_name((GF_Node *)elt) ));				}			}		} 		attributes = attributes->next;	}}void svg_parse_dom_children(SVGParser *parser, xmlNodePtr node, SVG_SA_Element *elt){	xmlNodePtr children;	u32 tag;	tag = gf_node_get_tag((GF_Node*)elt);	/* Parsing the children of the current element, with a special case for text nodes.*/	children = node->xmlChildrenNode;	while(children) {		SVG_SA_Element *child;		if (children->type == XML_ELEMENT_NODE) {			child = svg_parse_dom_element(parser, children, elt);			if (child) gf_node_list_add_child(&elt->children, (GF_Node*)child);		} else if ((children->type == XML_TEXT_NODE) && (tag == TAG_SVG_text)) {			SVG_SA_textElement *text = (SVG_SA_textElement *)elt;			if (text->core->space && text->core->space == XML_SPACE_PRESERVE) {				text->textContent = strdup(children->content);			} else {				char *tmp = children->content;				u32 len;				while (*tmp == ' ' || *tmp=='\n') tmp++;				text->textContent = strdup(tmp);				len = strlen(tmp);				tmp = &(text->textContent[len - 1]);				while (*tmp == ' ' || *tmp=='\n') tmp--;				tmp++;				*tmp = 0;			}		} else if ((children->type == XML_CDATA_SECTION_NODE) && (tag == TAG_SVG_script)) {			SVG_SA_scriptElement *script = (SVG_SA_scriptElement *)elt;			script->textContent = strdup(children->content);		}		children = children->next;	}}/* Should be called after xlink:href of the animation element has been resolved */static void parse_attributename(SVG_SA_Element *animation_element, char *value_string){	GF_FieldInfo xlink_href;	GF_FieldInfo attribute_name;	SVG_SA_Element *targetElement = NULL;	GF_FieldInfo targetAttribute;	gf_node_get_field_by_name((GF_Node *)animation_element, "xlink:href", &xlink_href);	gf_node_get_field_by_name((GF_Node *)animation_element, "attributeName", &attribute_name);	targetElement = ((SVG_IRI *)xlink_href.far_ptr)->target;	if (!targetElement) {#ifdef PRINT_WARNING		fprintf(stderr, "Warning: element only forward references supported.\n");#endif		return;	}	if (!gf_node_get_field_by_name((GF_Node *)targetElement, value_string, &targetAttribute)) {		SMIL_AttributeName *attributename_value = (SMIL_AttributeName *)attribute_name.far_ptr;		attributename_value->name = value_string;		attributename_value->type = targetAttribute.fieldType;		attributename_value->field_ptr = targetAttribute.far_ptr;	} else {#ifdef PRINT_WARNING		fprintf(stderr, "Error: Attribute %s does not belong to target element %s of type %s.\n", value_string, gf_node_get_class_name((GF_Node *)targetElement), gf_node_get_class_name((GF_Node *)targetElement) );#endif	}}void svg_parse_dom_defered_animations(SVGParser *parser, xmlNodePtr node, SVG_SA_Element *elt, SVG_SA_Element *parent){	GF_FieldInfo xlink_href;	u8 anim_value_type = 0;	u8 anim_transform_type = 0;	u32 tag;	tag = gf_node_get_tag((GF_Node*)elt);	/* Resolve the target element*/	if (!gf_node_get_field_by_name((GF_Node *)elt, "xlink:href", &xlink_href)) {		char *href;		if ((href = xmlGetProp(node, "href"))) {			gf_svg_parse_attribute((GF_Node *)elt,&xlink_href,  href, 0, 0);		} else {			/* default is the parent element */			elt->xlink->href.type = SVG_IRI_ELEMENTID;			elt->xlink->href.target = parent;			gf_svg_register_iri(parser->graph, &elt->xlink->href);		}	}	/* Resolve the target field */	if (tag == TAG_SVG_animateMotion) {		/* use of a special type for animation motion values (x,y) */		anim_value_type = SVG_Motion_datatype;	} else {		char *attributeName;		if (tag == TAG_SVG_animateTransform) {			char *type;			if ((type = xmlGetProp(node, "type"))) {				GF_FieldInfo type_info;				if (!gf_node_get_field_by_name((GF_Node *)elt, "type", &type_info)) {					/* parsing the type attribute of the animateTransform node,					   so we set the value of anim_transform_type to be able to parse 					   the animation values appropriately */					gf_svg_parse_attribute((GF_Node *)elt, &type_info, type, 0, 0);					anim_value_type		= SVG_Matrix_datatype;					anim_transform_type = *(SVG_TransformType*)type_info.far_ptr;				} else {					GF_LOG(GF_LOG_WARNING, GF_LOG_PARSER, ("[SVG] type attribute not found.\n"));				}			} else {				GF_LOG(GF_LOG_WARNING, GF_LOG_PARSER, ("[SVG] type attribute not specified in animateTransform.\n"));			} 		} else if ((attributeName = xmlGetProp(node, "attributeName"))) {			GF_FieldInfo attributeName_info;			if (!gf_node_get_field_by_name((GF_Node *)elt, "attributeName", &attributeName_info)) {				parse_attributename(elt, attributeName);				anim_value_type = ((SMIL_AttributeName *)attributeName_info.far_ptr)->type;			} else {				GF_LOG(GF_LOG_WARNING, GF_LOG_PARSER, ("[SVG] attributeName attribute not found.\n"));			}		} else {			if (tag != TAG_SVG_discard) {				GF_LOG(GF_LOG_WARNING, GF_LOG_PARSER, ("[SVG] target attribute not specified.\n"));			}		}	}	svg_parse_dom_attributes(parser, node, elt, anim_value_type, anim_transform_type);	svg_parse_dom_children(parser, node, elt);	/* We need to init the node at the end of the parsing, after parsing all attributes */	if (elt) {		GF_DOM_Event evt;		gf_node_init((GF_Node *)elt);		memset(&evt, 0, sizeof(GF_DOM_Event));		evt.type = GF_EVENT_LOAD;		gf_dom_event_fire((GF_Node*)elt, NULL, &evt);	}}/* Parse and Create and SVG element 	TODO: handle xml:id attribute 	TODO: find a way to handle mixed content*/SVG_SA_Element *svg_parse_dom_element(SVGParser *parser, xmlNodePtr node, SVG_SA_Element *parent){	u32 tag;	SVG_SA_Element *elt;	char *id = NULL;	/* Translates the node type (called name) from a String into a unique numeric identifier in GPAC */	tag = gf_svg_sa_node_type_by_class_name(node->name);	if (tag == TAG_UndefinedNode) {		parser->last_error = GF_SG_UNKNOWN_NODE;		return NULL;	}	/* Creates a node in the current scene graph */	elt = (SVG_SA_Element*)gf_node_new(parser->graph, tag);	if (!elt) {		parser->last_error = GF_SG_UNKNOWN_NODE;		return NULL;	}	gf_node_register((GF_Node *)elt, (GF_Node *)parent);	if ( (id = xmlGetProp(node, "id")) ) svg_parse_element_id(parser, elt, id);	/* For animation elements, we defer parsing until the all the node are parsed,	   then we first need to resolve the target element, 	   then to determine the target field using 'attributeName' attribute,	   and based on this attribute we can know how to parse the animation values 	   (anim_value_type, anim_transform_type) */	if (tag == TAG_SVG_set ||		tag == TAG_SVG_animate ||		tag == TAG_SVG_animateColor ||		tag == TAG_SVG_animateTransform ||		tag == TAG_SVG_animateMotion || 		tag == TAG_SVG_discard) {		defered_element *de = malloc(sizeof(defered_element));		de->node = node;		de->animation_elt = elt;		de->parent = parent;		gf_list_add(parser->defered_animation_elements, de);		return elt;	}	svg_parse_dom_attributes(parser, node, elt, 0, 0);	svg_parse_dom_children(parser, node, elt);	/* We need to init the node at the end of the parsing, after parsing all attributes */	if (elt) {		GF_DOM_Event evt;		gf_node_init((GF_Node *)elt);		memset(&evt, 0, sizeof(GF_DOM_Event));		evt.type = GF_EVENT_LOAD;		gf_dom_event_fire((GF_Node *)elt, NULL, &evt);	}	return elt;}/* DOM end *//* SAX functions */void svg_parse_sax_defered_anchor(SVGParser *parser, SVG_SA_Element *anchor_elt, defered_element local_de){	GF_FieldInfo xlink_href_info;	gf_node_get_field_by_name((GF_Node *)anchor_elt, "xlink:href", &xlink_href_info);	if (local_de.target_id) 		gf_svg_parse_attribute((GF_Node *)anchor_elt, &xlink_href_info, local_de.target_id, 0, 0);	else {		/* default is the parent element */		local_de.animation_elt->xlink->href.type = SVG_IRI_ELEMENTID;		local_de.animation_elt->xlink->href.target = local_de.parent;		gf_svg_register_iri(parser->graph, &local_de.animation_elt->xlink->href);	}}void svg_parse_sax_defered_animation(SVGParser *parser, SVG_SA_Element *animation_elt, defered_element local_de){	GF_FieldInfo info;	u8 anim_value_type = 0, anim_transform_type = 0;	GF_FieldInfo xlink_href_info;	gf_node_get_field_by_name((GF_Node *)animation_elt, "xlink:href", &xlink_href_info);	if (local_de.target_id) {		gf_svg_parse_attribute((GF_Node *)animation_elt, &xlink_href_info, local_de.target_id, 0, 0);		free(local_de.target_id);	} else {		/* default is the parent element */		local_de.animation_elt->xlink->href.type = SVG_IRI_ELEMENTID;		local_de.animation_elt->xlink->href.target = local_de.parent;		gf_svg_register_iri(parser->graph, &local_de.animation_elt->xlink->href);	}	if (local_de.attributeName) {		/* get the type of the target attribute to determine type of the from/to/by ... */		parse_attributename(animation_elt, local_de.attributeName);		gf_node_get_field_by_name((GF_Node *)animation_elt, "attributeName", &info);		anim_value_type = ((SMIL_AttributeName *)info.far_ptr)->type;	} else {		switch (gf_node_get_tag((GF_Node *)animation_elt) ) {		case TAG_SVG_animateMotion:			anim_value_type = SVG_Motion_datatype;			break;		case TAG_SVG_discard:			break;		default:			GF_LOG(GF_LOG_ERROR, GF_LOG_PARSER, ("[SVG] No attributeName specified.\n"));			break;		}	}	if (gf_node_get_tag((GF_Node *)animation_elt) == TAG_SVG_animateTransform && local_de.type) {		/* determine the transform_type in case of animateTransform attribute */		GF_FieldInfo type_info;		gf_node_get_field_by_name((GF_Node *)animation_elt, "type", &type_info);		gf_svg_parse_attribute((GF_Node *)animation_elt, &type_info, local_de.type, 0, 0);		anim_value_type = SVG_Matrix_datatype;		anim_transform_type = *(SVG_TransformType*)type_info.far_ptr;	} 	/* Parsing of to / from / by / values */	if (local_de.to) {		gf_node_get_field_by_name((GF_Node *)animation_elt, "to", &info);		gf_svg_parse_attribute((GF_Node *)animation_elt, &info, local_de.to, anim_value_type, anim_transform_type);		free(local_de.to);	} 	if (local_de.from) {		gf_node_get_field_by_name((GF_Node *)animation_elt, "from", &info);		gf_svg_parse_attribute((GF_Node *)animation_elt, &info, local_de.from, anim_value_type, anim_transform_type);		free(local_de.from);	} 	if (local_de.by) {		gf_node_get_field_by_name((GF_Node *)animation_elt, "by", &info);		gf_svg_parse_attribute((GF_Node *)animation_elt, &info, local_de.by, anim_value_type, anim_transform_type);		free(local_de.by);	} 	if (local_de.values) {		gf_node_get_field_by_name((GF_Node *)animation_elt, "values", &info);		gf_svg_parse_attribute((GF_Node *)animation_elt, &info, local_de.values, anim_value_type, anim_transform_type);		free(local_de.values);	} 	/*OK init the anim*/	gf_node_init((GF_Node *)animation_elt);	/*free attributeName after init since it is used in the SMIL anim setup*/	if (local_de.attributeName) free(local_de.attributeName);}SVG_SA_Element *svg_parse_sax_element(SVGParser *parser, const xmlChar *name, const xmlChar **attrs, SVG_SA_Element *parent){	u32			tag;	SVG_SA_Element *elt;	s32			attribute_index = 0;	Bool		ided = 0;	/* animation element to be defered after the target element is resolved */	defered_element *de = NULL;	/* variable required for parsing of animation attributes in a certain order 	   if the target is already resolved */	defered_element local_de;	/* Translates the node type (called name) from a String into a unique numeric identifier in GPAC */	tag = gf_svg_sa_node_type_by_class_name(name);	if (tag == TAG_UndefinedNode) {		parser->last_error = GF_SG_UNKNOWN_NODE;		return NULL;	}	/* Creates a node in the current scene graph */	elt = (SVG_SA_Element*)gf_node_new(parser->graph, tag);	if (!elt) {		parser->last_error = GF_SG_UNKNOWN_NODE;		return NULL;	}	gf_node_register((GF_Node *)elt, (GF_Node *)parent);	if (parent && elt) gf_node_list_add_child(&parent->children, (GF_Node*)elt);	/* Parsing the style attribute */	attribute_index=0;	if (attrs)	while (attrs[attribute_index]!=NULL)	{		if (stricmp(attrs[attribute_index],"style")==0) {			xmlChar *style= svg_expand_entities(parser, (xmlChar *)attrs[attribute_index+1]);			if (style)			{				gf_svg_parse_style((GF_Node *)elt, style);				free(style);			}			break;		}		attribute_index+=2;	}	/* For animation elements, we try to resolve the target element;	if we are able to determine the target,	then we have to determine the target field using 'attributeName' attribute,	and based on this attribute we can know how to parse the animation values 	(anim_value_type, anim_transform_type) 	if are not able to determine the target, we put the element in a list for future processing	(each time a new id is defined, we try to resolve the defered elements)	*/	if (is_svg_animation_tag(tag)) {		/* Parsing the xlink:href attribute */		Bool xlink_href_found = 0;		attribute_index=0;		memset(&local_de, 0, sizeof(defered_element));		local_de.parent = parent;		if (attrs)		while (attrs[attribute_index]!=NULL)		{			if (stricmp(attrs[attribute_index],"xlink:href")==0) {				GF_Node *node;				xlink_href_found = 1;				/* check if the target is known */				node = gf_sg_find_node_by_name(parser->graph, (char *)&(attrs[attribute_index+1][1]));				if (node) { 					/* target found; we can resolve all the attributes */					local_de.target = (SVG_SA_Element *)node;					local_de.target_id = strdup(attrs[attribute_index+1]);				} else /* target unresolved */				{					s32	position;					GF_SAFEALLOC(de, defered_element)					// de->node = node; we need to save some attributes for future parsing					// and not parse these attributes below					de->target_id = strdup(attrs[attribute_index+1]);					de->animation_elt = elt;					de->parent = parent;					/* this list must be sorted on target_id key */					list_dichotomic_search(parser->defered_animation_elements, &(de->target_id[1]), &position);					if (position <= 0) gf_list_add(parser->defered_animation_elements, de);					else gf_list_insert(parser->defered_animation_elements, de, position);				}				break;			} 			attribute_index+=2;		}		if (!xlink_href_found) {			local_de.target = parent;			

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -