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

📄 svg_types.c

📁 一个用于智能手机的多媒体库适合S60 WinCE的跨平台开发库
💻 C
字号:
/* *			GPAC - Multimedia Framework C SDK * *			Copyright (c) Cyril Concolato 2004 *					All rights reserved * *  This file is part of GPAC / SVG Scene Graph sub-project * *  GPAC is free software; you can redistribute it and/or modify *  it under the terms of the GNU Lesser General Public License as published by *  the Free Software Foundation; either version 2, or (at your option) *  any later version. * *  GPAC is distributed in the hope that it will be useful, *  but WITHOUT ANY WARRANTY; without even the implied warranty of *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the *  GNU Lesser General Public License for more details.	 * *  You should have received a copy of the GNU Lesser General Public *  License along with this library; see the file COPYING.  If not, write to *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. * */#include <gpac/nodes_svg_sa.h>#ifndef GPAC_DISABLE_SVG#include <gpac/internal/scenegraph_dev.h>void gf_svg_reset_path(SVG_PathData d) {#if USE_GF_PATH	gf_path_reset(&d);#else	u32 i, count;	count = gf_list_count(d.commands);	for (i = 0; i < count; i++) {		u8 *command = (u8 *)gf_list_get(d.commands, i);		free(command);	}	gf_list_del(d.commands);	count = gf_list_count(d.points);	for (i = 0; i < count; i++) {		SVG_Point *pt = (SVG_Point *)gf_list_get(d.points, i);		free(pt);	}	gf_list_del(d.points);#endif}/* TODO: update for elliptical arcs */		GF_EXPORTvoid gf_svg_path_build(GF_Path *path, GF_List *commands, GF_List *points){	u32 i, j, command_count, points_count;	SVG_Point orig, ct_orig, ct_end, end, *tmp;	command_count = gf_list_count(commands);	points_count = gf_list_count(points);	orig.x = orig.y = ct_orig.x = ct_orig.y = 0;	for (i=0, j=0; i<command_count; i++) {		u8 *command = (u8 *)gf_list_get(commands, i);		switch (*command) {		case SVG_PATHCOMMAND_M: /* Move To */			tmp = (SVG_Point*)gf_list_get(points, j);			orig = *tmp;			gf_path_add_move_to(path, orig.x, orig.y);			j++;			/*provision for nextCurveTo when no curve is specified:				"If there is no previous command or if the previous command was not an C, c, S or s, 				assume the first control point is coincident with the current point.			*/			ct_orig = orig;			break;		case SVG_PATHCOMMAND_L: /* Line To */			tmp = (SVG_Point*)gf_list_get(points, j);			end = *tmp;			gf_path_add_line_to(path, end.x, end.y);			j++;			orig = end;			/*cf above*/			ct_orig = orig;			break;		case SVG_PATHCOMMAND_C: /* Curve To */			tmp = (SVG_Point*)gf_list_get(points, j);			ct_orig = *tmp;			tmp = (SVG_Point*)gf_list_get(points, j+1);			ct_end = *tmp;			tmp = (SVG_Point*)gf_list_get(points, j+2);			end = *tmp;			gf_path_add_cubic_to(path, ct_orig.x, ct_orig.y, ct_end.x, ct_end.y, end.x, end.y);			ct_orig = ct_end;			orig = end;			j+=3;			break;		case SVG_PATHCOMMAND_S: /* Next Curve To */			ct_orig.x = 2*orig.x - ct_orig.x;			ct_orig.y = 2*orig.y - ct_orig.y;			tmp = (SVG_Point*)gf_list_get(points, j);			ct_end = *tmp;			tmp = (SVG_Point*)gf_list_get(points, j+1);			end = *tmp;			gf_path_add_cubic_to(path, ct_orig.x, ct_orig.y, ct_end.x, ct_end.y, end.x, end.y);			ct_orig = ct_end;			orig = end;			j+=2;			break;		case SVG_PATHCOMMAND_Q: /* Quadratic Curve To */			tmp = (SVG_Point*)gf_list_get(points, j);			ct_orig = *tmp;			tmp = (SVG_Point*)gf_list_get(points, j+1);			end = *tmp;			gf_path_add_quadratic_to(path, ct_orig.x, ct_orig.y, end.x, end.y);						orig = end;			j+=2;			break;		case SVG_PATHCOMMAND_T: /* Next Quadratic Curve To */			ct_orig.x = 2*orig.x - ct_orig.x;			ct_orig.y = 2*orig.y - ct_orig.y;			tmp = (SVG_Point*)gf_list_get(points, j);			end = *tmp;			gf_path_add_quadratic_to(path, ct_orig.x, ct_orig.y, end.x, end.y);				orig = end;				j++;			break;		case SVG_PATHCOMMAND_Z: /* Close */			gf_path_close(path);			break;		}	}	}void gf_smil_delete_times(GF_List *list){	u32 i, count;	count = gf_list_count(list);	for (i = 0; i < count; i++) {		SMIL_Time *v = (SMIL_Time *)gf_list_get(list, i);		if (v->element_id) free(v->element_id);		free(v);	}	gf_list_del(list);}void gf_svg_delete_points(GF_List *list){	u32 i, count = gf_list_count(list);	for (i = 0; i < count; i++) {		SVG_Point *p = (SVG_Point *)gf_list_get(list, i);		free(p);	}	gf_list_del(list);}void gf_svg_delete_coordinates(GF_List *list){	u32 i, count = gf_list_count(list);	for (i = 0; i < count; i++) {		SVG_Coordinate *c = (SVG_Coordinate *)gf_list_get(list, i);		free(c);	}	gf_list_del(list);}void gf_svg_reset_iri(GF_SceneGraph *sg, XMLRI *iri) {	if (!iri) return;	if (iri->string) free(iri->string);	gf_svg_unregister_iri(sg, iri);}void gf_svg_delete_paint(GF_SceneGraph *sg, SVG_Paint *paint) {	if (!paint) return;	if (paint->type == SVG_PAINT_URI && sg) gf_svg_reset_iri(sg, &paint->iri);	free(paint);}static void svg_delete_one_anim_value(u8 anim_datatype, void *anim_value, GF_SceneGraph *sg){	/* TODO: handle specific animation types : Motion, else ? */	gf_svg_delete_attribute_value(anim_datatype, anim_value, sg);}void gf_svg_reset_animate_values(SMIL_AnimateValues anim_values, GF_SceneGraph *sg){	u32 i, count;	count = gf_list_count(anim_values.values);	for (i = 0; i < count; i++) {		void *value = gf_list_get(anim_values.values, i);		svg_delete_one_anim_value(anim_values.type, value, sg);	}	gf_list_del(anim_values.values);	anim_values.values = NULL;}void gf_svg_reset_animate_value(SMIL_AnimateValue anim_value, GF_SceneGraph *sg){	svg_delete_one_anim_value(anim_value.type, anim_value.value, sg);	anim_value.value = NULL;}void gf_svg_delete_attribute_value(u32 type, void *value, GF_SceneGraph *sg){	GF_List *l;	switch (type) {	case SVG_Paint_datatype:		gf_svg_delete_paint(sg, (SVG_Paint *)value);		break;	case XMLRI_datatype:	case XML_IDREF_datatype:		gf_svg_reset_iri(sg, (XMLRI *)value);		free(value);		break;	case SVG_Focus_datatype:		gf_svg_reset_iri(sg, & ((SVG_Focus*)value)->target);		free(value);		break;	case SVG_PathData_datatype:#if USE_GF_PATH		gf_path_del((GF_Path *)value);#else		free(value);#endif		break;	case SVG_String_datatype:	case SVG_ContentType_datatype:	case SVG_LanguageID_datatype:		if (*(SVG_String *)value) free(*(SVG_String *)value);		free(value);		break;	case SVG_StrokeDashArray_datatype:		if (((SVG_StrokeDashArray*)value)->array.vals) free(((SVG_StrokeDashArray*)value)->array.vals);		free(value);		break;	case SVG_Coordinates_datatype:	case SVG_Points_datatype:		l = *(GF_List**)value;		while (gf_list_count(l)) {			void *n = gf_list_last(l);			gf_list_rem_last(l);			free(n);		}		gf_list_del(l);		free(value);		break;	case SVG_FontFamily_datatype:		{			SVG_FontFamily *ff = (SVG_FontFamily *)value;			if (ff->value) free(ff->value);			free(value);		}		break;	case SMIL_AttributeName_datatype:		{			SMIL_AttributeName *an = (SMIL_AttributeName *)value;			if (an->name) free(an->name);			free(value);		}		break;	case SMIL_Times_datatype:		gf_smil_delete_times(*(SMIL_Times *)value);		free(value);		break;	case SMIL_AnimateValue_datatype:		svg_delete_one_anim_value(((SMIL_AnimateValue *)value)->type, ((SMIL_AnimateValue *)value)->value, sg);		free(value);		break;	case SMIL_AnimateValues_datatype:		gf_svg_reset_animate_values(*((SMIL_AnimateValues *)value), sg);		free(value);		break;	case SVG_FeatureList_datatype:	case SVG_ExtensionList_datatype:	case SVG_FormatList_datatype:	case SVG_LanguageIDs_datatype:		l = *(GF_List**)value;		while (gf_list_count(l)) {			char *n = gf_list_last(l);			gf_list_rem_last(l);			free(n);		}		gf_list_del(l);		free(value);		break;	case SVG_ListOfIRI_datatype:		l = *(GF_List**)value;		while (gf_list_count(l)) {			XMLRI *r = gf_list_last(l);			gf_list_rem_last(l);			if (r->string) free(r->string);			free(r);		}		gf_list_del(l);		free(value);		break;	case SMIL_RepeatCount_datatype:	case SMIL_Duration_datatype:	case SVG_Length_datatype:	case SVG_Coordinate_datatype:	case SVG_Visibility_datatype:	case SVG_Display_datatype:	default:		free(value);	} }void gf_smil_delete_key_types(GF_List *l){	while (gf_list_count(l)) {		Fixed *t = (Fixed *)gf_list_get(l, 0);		gf_list_rem(l, 0);		free(t);	}	gf_list_del(l);}GF_EXPORTvoid gf_svg_register_iri(GF_SceneGraph *sg, XMLRI *target){	if (gf_list_find(sg->xlink_hrefs, target)<0) {		gf_list_add(sg->xlink_hrefs, target);	}}void gf_svg_unregister_iri(GF_SceneGraph *sg, XMLRI *target){	gf_list_del_item(sg->xlink_hrefs, target);}/*TODO FIXME, this is ugly, add proper cache system*/#include <gpac/base_coding.h>static u32 check_existing_file(char *base_file, char *ext, char *data, u32 data_size, u32 idx){	char szFile[GF_MAX_PATH];	u32 fsize;	FILE *f;		sprintf(szFile, "%s%04X%s", base_file, idx, ext);		f = fopen(szFile, "rb");	if (!f) return 0;	fseek(f, 0, SEEK_END);	fsize = ftell(f);	if (fsize==data_size) {		u32 offset=0;		char cache[1024];		fseek(f, 0, SEEK_SET);		while (fsize) {			u32 read = fread(cache, 1, 1024, f);			fsize -= read;			if (memcmp(cache, data+offset, sizeof(char)*read)) break;			offset+=read;		}		fclose(f);		/*same file*/		if (!fsize) return 2;	}	fclose(f);	return 1;}GF_EXPORTBool gf_svg_store_embedded_data(XMLRI *iri, const char *cache_dir, const char *base_filename){	char szFile[GF_MAX_PATH], buf[20], *sep, *data, *ext;	u32 data_size, idx;	Bool existing;	FILE *f;	if (!cache_dir || !base_filename || !iri || !iri->string || strncmp(iri->string, "data:", 5)) return 0;	/*handle "data:" scheme when cache is specified*/	strcpy(szFile, cache_dir);	data_size = strlen(szFile);	if (szFile[data_size-1] != GF_PATH_SEPARATOR) {		szFile[data_size] = GF_PATH_SEPARATOR;		szFile[data_size+1] = 0;	}	if (base_filename) {		sep = strrchr(base_filename, GF_PATH_SEPARATOR);#ifdef WIN32		if (!sep) sep = strrchr(base_filename, '/');#endif		if (!sep) sep = (char *) base_filename;		else sep += 1;		strcat(szFile, sep);	}	sep = strrchr(szFile, '.');	if (sep) sep[0] = 0;	strcat(szFile, "_img_");	/*get mime type*/	sep = (char *)iri->string + 5;	if (!strncmp(sep, "image/jpg", 9) || !strncmp(sep, "image/jpeg", 10)) ext = ".jpg";	else if (!strncmp(sep, "image/png", 9)) ext = ".png";	else return 0;	data = NULL;	sep = strchr(iri->string, ';');	if (!strncmp(sep, ";base64,", 8)) {		sep += 8;		data_size = 2*strlen(sep);		data = (char*)malloc(sizeof(char)*data_size);		if (!data) return 0;		data_size = gf_base64_decode(sep, strlen(sep), data, data_size);	}	else if (!strncmp(sep, ";base16,", 8)) {		data_size = 2*strlen(sep);		data = (char*)malloc(sizeof(char)*data_size);		if (!data) return 0;		sep += 8;		data_size = gf_base16_decode(sep, strlen(sep), data, data_size);	}	if (!data_size) return 0;		iri->type = XMLRI_STRING;		existing = 0;	idx = 0;	while (1) {		u32 res = check_existing_file(szFile, ext, data, data_size, idx);		if (!res) break;		if (res==2) {			existing = 1;			break;		}		idx++;	}	sprintf(buf, "%04X", idx);	strcat(szFile, buf);	strcat(szFile, ext);	if (!existing) {		f = fopen(szFile, "wb");		if (!f) return 0;		fwrite(data, data_size, 1, f);		fclose(f);	}	free(data);	free(iri->string);	iri->string = strdup(szFile);	return 1;}#endif /*GPAC_DISABLE_SVG*/

⌨️ 快捷键说明

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