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

📄 svg_parser.c

📁 一个用于智能手机的多媒体库适合S60 WinCE的跨平台开发库
💻 C
📖 第 1 页 / 共 3 页
字号:
			local_de.animation_elt = elt;		}	}	/* For anchor elements, we try to resolve the target element;	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_anchor_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_FieldInfo xlink_href_info;				gf_node_get_field_by_name((GF_Node *)elt, "xlink:href", &xlink_href_info);				gf_svg_parse_attribute((GF_Node *)elt, &xlink_href_info, (char *)attrs[attribute_index+1], 0, 0);				break;			} 			attribute_index+=2;		}		if (!xlink_href_found) {			local_de.target = parent;					}	}		/* Parsing all the other attributes, with a special case of id */	attribute_index=0;	if (attrs)	while (attrs[attribute_index]) {		if (!stricmp(attrs[attribute_index], "id")) {			svg_parse_element_id(parser, elt, (xmlChar *)attrs[attribute_index+1]);			ided = 1;		} else if (!stricmp(attrs[attribute_index], "attributeName")) {			if (de) de->attributeName = strdup(attrs[attribute_index+1]);			else local_de.attributeName = strdup(attrs[attribute_index+1]);		} else if (!stricmp(attrs[attribute_index], "to")) {			if (de) de->to = strdup(attrs[attribute_index+1]);			else local_de.to = strdup(attrs[attribute_index+1]);		} else if (!stricmp(attrs[attribute_index], "from")) {			if (de) de->from = strdup(attrs[attribute_index+1]);			else local_de.from = strdup(attrs[attribute_index+1]);		} else if (!stricmp(attrs[attribute_index], "by")) {			if (de) de->by = strdup(attrs[attribute_index+1]);			else local_de.by = strdup(attrs[attribute_index+1]);		} else if (!stricmp(attrs[attribute_index], "values")) {			if (de) de->values = strdup(attrs[attribute_index+1]);			else local_de.values = strdup(attrs[attribute_index+1]);		} else if (!stricmp(attrs[attribute_index], "type")) {			if (tag == TAG_SVG_animateTransform) {				if (de) de->type = strdup(attrs[attribute_index+1]);				else local_de.type = strdup(attrs[attribute_index+1]);			} else {				GF_FieldInfo info;				if (!gf_node_get_field_by_name((GF_Node *)elt, "type", &info)) {					gf_svg_parse_attribute((GF_Node *)elt, &info, (xmlChar *)attrs[attribute_index+1], 0, 0);				}			}		} else if (!stricmp(attrs[attribute_index], "language")) {			// TODO process this attribute (for scripts)		} else if (!stricmp(attrs[attribute_index], "xlink:href")) {			if (is_svg_animation_tag(tag)) {				/* already dealt with above */			} 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, (xmlChar *)attrs[attribute_index+1], 0, 0);				}			}		} else {			GF_FieldInfo info;			u32 evtType = gf_dom_event_type_by_name((char *) (char *)attrs[attribute_index] + 2);			if (evtType != GF_EVENT_UNKNOWN) {				SVG_SA_handlerElement *handler;				handler = gf_dom_listener_build((GF_Node *) elt, evtType, 0, NULL);				handler->textContent = strdup((char *)attrs[attribute_index+1]);				gf_node_init((GF_Node *)handler);			} else if (!gf_node_get_field_by_name((GF_Node *)elt, (char *)attrs[attribute_index], &info)) {				gf_svg_parse_attribute((GF_Node *)elt, &info, (xmlChar *)attrs[attribute_index+1], 0, 0);			} else {				GF_LOG(GF_LOG_WARNING, GF_LOG_PARSER, ("[SVG] Unknown attribute %s on element %s\n", (char *)attrs[attribute_index], gf_node_get_class_name((GF_Node *)elt) ));			}		}		attribute_index+=2;	}	if (!de && is_svg_animation_tag(tag)) svg_parse_sax_defered_animation(parser, elt, local_de);	/* if the new element has an id, we try to resolve defered references */	if (ided) {		defered_element *previous_de;		const char *new_id = gf_node_get_name((GF_Node *)elt);		/* dichotomic search in the sorted list of defered animation elements */		previous_de = list_dichotomic_search(parser->defered_animation_elements, new_id, NULL);		if (previous_de) { /* defered element 'previous_de' can be resolved by the new elt */			svg_parse_sax_defered_animation(parser, previous_de->animation_elt, *previous_de);		}				/* defered references for anchor */		{			u32 i;			u32 count = gf_list_count(parser->unresolved_hrefs);			for (i=0; i<count; i++)			{				href_instance *hi = gf_list_get(parser->unresolved_hrefs, i);				if (hi) {					SVG_IRI *iri = hi->iri;					GF_Node *targ = gf_sg_find_node_by_name(parser->graph, &(iri->iri[1]));					if (iri->target) {						hi->elt->xlink->href.type = SVG_IRI_ELEMENTID;						hi->elt->xlink->href.target = (SVG_SA_Element *)targ;						gf_svg_register_iri(parser->graph, &hi->elt->xlink->href);						gf_node_init((GF_Node *)hi->elt);						gf_list_rem(parser->unresolved_hrefs, i);					}				}			}		}			}	/* We need to init the node at the end of the parsing, after parsing all attributes */	if (!is_svg_animation_tag(tag) && elt) {		GF_DOM_Event evt;		/*init node*/		gf_node_init((GF_Node *)elt);		/*fire initialization event*/		memset(&evt, 0, sizeof(GF_DOM_Event));		evt.type = GF_EVENT_LOAD;		gf_dom_event_fire((GF_Node *) elt, NULL, &evt);	}	return elt;}/* SAX end *//* Constructors and Desctructos of the SVG Parser */SVGParser *NewSVGParser(){	SVGParser *tmp;	GF_SAFEALLOC(tmp, SVGParser);	return tmp;}void SVGParser_Terminate(SVGParser *parser){    /* there is no more input, indicate the parsing is finished.	   Is this needed ?		xmlParseChunk(ctxt, inputbuffer, 0, 1);     */    /* destroy the SAX parser context and file. */    if (parser->sax_handler) free(parser->sax_handler);	if (parser->sax_ctx) xmlFreeParserCtxt(parser->sax_ctx);	if (parser->sax_file) fclose(parser->sax_file);	if (xmllib_is_init) xmlCleanupParser();	xmllib_is_init = 0;	gf_list_del(parser->ided_nodes);	gf_list_del(parser->unresolved_timing_elements);	gf_list_del(parser->unresolved_hrefs);	gf_list_del(parser->defered_animation_elements);	if (parser->entities) gf_list_del(parser->entities);	if (parser->svg_node_stack) gf_list_del(parser->svg_node_stack);	if (parser->file_name) free(parser->file_name);	free(parser);}static void SVGParser_InitAllParsers(SVGParser *parser){	/* Scene Graph related code */	parser->ided_nodes = gf_list_new();	/* List of elements to be resolved after parsing but before rendering */	parser->unresolved_timing_elements = gf_list_new();		/* xlink:href attributes */	parser->unresolved_hrefs = gf_list_new();	/* defered animation elements */	parser->defered_animation_elements = gf_list_new();}/* Full DOM Parsing and Progressive Parsing functions */GF_Err SVGParser_ParseFullDoc(SVGParser *parser){	xmlDocPtr doc = NULL;	xmlNodePtr root = NULL;	SVG_SA_Element *n;	//u32 d;	/* XML Related code */	if (!xmllib_is_init) {		xmlInitParser();		LIBXML_TEST_VERSION		xmllib_is_init=1;	}	doc = xmlParseFile(parser->file_name);	if (doc == NULL) return GF_BAD_PARAM;	root = xmlDocGetRootElement(doc);	SVGParser_InitAllParsers(parser);	n = svg_parse_dom_element(parser, root, NULL);	if (n) svg_init_root_element(parser, (SVG_SA_svgElement *)n);	/* Resolve time elements */	while (gf_list_count(parser->unresolved_timing_elements) > 0) {		SMIL_Time *v = gf_list_get(parser->unresolved_timing_elements, 0);		gf_list_rem(parser->unresolved_timing_elements, 0);		v->element = gf_sg_find_node_by_name(parser->graph, v->element_id);		if (v->element) {			free(v->element_id);			v->element_id = NULL;		}	}	/* Resolve hrefs */	while (gf_list_count(parser->unresolved_hrefs) > 0) {		href_instance *hi = gf_list_get(parser->unresolved_hrefs, 0);		SVG_IRI *iri = hi->iri;		GF_Node *targ =  gf_sg_find_node_by_name(parser->graph, &(iri->iri[1]));		gf_list_rem(parser->unresolved_hrefs, 0);		if (targ) {			hi->elt->xlink->href.type = SVG_IRI_ELEMENTID;			hi->elt->xlink->href.target = (SVG_SA_Element *)targ;			gf_svg_register_iri(parser->graph, &hi->elt->xlink->href);			if (iri->iri) free(iri->iri);			iri->iri = NULL;		}	}	while (gf_list_count(parser->defered_animation_elements)) {		defered_element *de = gf_list_get(parser->defered_animation_elements, 0);		gf_list_rem(parser->defered_animation_elements, 0);		svg_parse_dom_defered_animations(parser, de->node, de->animation_elt, de->parent);		free(de);	}	//scanf("%d", &d);	xmlFreeDoc(doc);	//scanf("%d", &d);	return GF_OK;}static void SVGParser_InitSaxHandler(SVGParser *parser){	GF_SAFEALLOC(parser->sax_handler, xmlSAXHandler)	parser->sax_handler->startDocument	= svg_start_document;	parser->sax_handler->endDocument	= svg_end_document;	parser->sax_handler->characters		= svg_characters;	parser->sax_handler->endElement		= svg_end_element;	parser->sax_handler->startElement	= svg_start_element;	parser->sax_handler->getEntity		= svg_get_entity;	parser->sax_handler->entityDecl 	= svg_entity_decl;	parser->sax_handler->cdataBlock 	= svg_cdata_block;}GF_Err SVGParser_InitProgressiveFileChunk(SVGParser *parser){    char inputbuffer[SAX_MAX_CHARS];    s32	len;	/* XML Related code */	if (!xmllib_is_init) {		xmlInitParser();		LIBXML_TEST_VERSION		xmllib_is_init=1;	}    parser->sax_file = fopen(parser->file_name, "rb");    if (parser->sax_file == NULL) return GF_IO_ERR;	parser->sax_state	= UNDEF;	SVGParser_InitAllParsers(parser);	SVGParser_InitSaxHandler(parser);    /* Read a few first byte to check the input used for the     * encoding detection at the parser level. */    len = fread(inputbuffer, 1, 4, parser->sax_file);    if (len != 4)  return GF_OK; 	parser->nb_bytes_read = len;	/* Create a progressive parsing context, the 2 first arguments     * are not used since we want to build a tree and not use a SAX     * parsing interface. We also pass the first bytes of the document     * to allow encoding detection when creating the parser but this     * is optional. */    parser->sax_ctx = xmlCreatePushParserCtxt(parser->sax_handler, parser, inputbuffer, len, NULL);    	/* TODO setup a better error value and verify cleanup: fclose... */	if (parser->sax_ctx == NULL)  return GF_IO_ERR; 	return GF_OK;}GF_Err SVGParser_ParseProgressiveFileChunk(SVGParser *parser){	u32 read_bytes, entry_time, diff;    char inputbuffer[SAX_MAX_CHARS];	if (!parser->sax_ctx) return GF_OK;	entry_time = gf_sys_clock();	fseek(parser->sax_file, parser->nb_bytes_read, SEEK_SET);	while (1) {		read_bytes = fread(inputbuffer, 1, SAX_MAX_CHARS, parser->sax_file);		if (read_bytes > 0) {			xmlParseChunk(parser->sax_ctx, inputbuffer, read_bytes, 0);			parser->nb_bytes_read += read_bytes;		}				if (parser->sax_state == FINISHSVG) return GF_EOS;		if (parser->sax_state == ERROR) return GF_IO_ERR;		if (parser->load_type == SVG_LOAD_SAX_PROGRESSIVE) {			diff = gf_sys_clock() - entry_time;			if (diff > parser->sax_max_duration) return GF_OK;		}	}	return GF_OK;}GF_Err SVGParser_ParseMemoryFirstChunk(SVGParser *parser, unsigned char *inBuffer, u32 inBufferLength){	/* XML Related code */	if (!xmllib_is_init) {		xmlInitParser();		LIBXML_TEST_VERSION		xmllib_is_init=1;	}	parser->sax_state	= UNDEF;	SVGParser_InitAllParsers(parser);	SVGParser_InitSaxHandler(parser);	/* Create a progressive parsing context, the 2 first arguments     * are not used since we want to build a tree and not use a SAX     * parsing interface. We also pass the first bytes of the document     * to allow encoding detection when creating the parser but this     * is optional. */    parser->sax_ctx = xmlCreatePushParserCtxt(parser->sax_handler, parser, inBuffer, 4, NULL);    	/* TODO setup a better error value and verify cleanup: fclose... */	if (parser->sax_ctx == NULL)  return GF_IO_ERR; 	if (inBufferLength > 4) 		return SVGParser_ParseMemoryNextChunk(parser, inBuffer+4, inBufferLength-4);	return GF_OK;}GF_Err SVGParser_ParseMemoryNextChunk(SVGParser *parser, unsigned char *inBuffer, u32 inBufferLength){	if (!parser->sax_ctx) return GF_OK;		xmlParseChunk(parser->sax_ctx, inBuffer, inBufferLength, 0);		if (parser->sax_state == FINISHSVG) return GF_EOS;	if (parser->sax_state == ERROR) return GF_IO_ERR;	return GF_OK;}/* The rest of the file is required for DANAE but not used in GPAC */struct danae_parser {	u32 type; // 0 = SVG, 1 = LSR	void *parser;};void *DANAE_NewSVGParser(char *filename, void *scene_graph){	struct danae_parser *dp;	char *ext;	if (!filename || !scene_graph) return NULL;	if ((ext = strrchr(filename, '.')) == NULL) return NULL;	dp = malloc(sizeof(struct danae_parser));	if (!strcmp(ext, ".svg")) {		dp->type = 0;		dp->parser = NewSVGParser();		((SVGParser *)dp->parser)->oti = SVGLOADER_OTI_SVG;		((SVGParser *)dp->parser)->file_name = strdup(filename);		((SVGParser *)dp->parser)->graph = scene_graph;	} else if (!strcmp(ext, ".xsr")) {		dp->type = 0;		dp->parser = NewSVGParser();		((SVGParser *)dp->parser)->oti = SVGLOADER_OTI_LASERML;		((SVGParser *)dp->parser)->file_name = strdup(filename);		((SVGParser *)dp->parser)->graph = scene_graph;	} else if (!strcmp(ext, ".lsr")) {		dp->type = 1;	}	return dp;}void DANAE_SVGParser_Parse(void *p){	struct danae_parser *dp = (struct danae_parser *)p;	if (!dp->type) {		if (((SVGParser *)dp->parser)->oti == SVGLOADER_OTI_SVG) {			SVGParser_ParseFullDoc(dp->parser);		} else if (((SVGParser *)dp->parser)->oti == SVGLOADER_OTI_LASERML) {			SVGParser_ParseLASeR(dp->parser);		}	} }void DANAE_SVGParser_Terminate(void *p){}#endif

⌨️ 快捷键说明

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