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

📄 swf_shape.c

📁 一个用于智能手机的多媒体库适合S60 WinCE的跨平台开发库
💻 C
📖 第 1 页 / 共 2 页
字号:
/* *			GPAC - Multimedia Framework C SDK * *			Copyright (c) Jean Le Feuvre 2000-2005 *					All rights reserved * *  This file is part of GPAC / Scene Management 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_mpeg4.h>#include <gpac/utf.h>#include <gpac/internal/swf_dev.h>#ifndef GPAC_READ_ONLYSFColor get_bifs_col(u32 ARGB){	SFColor val;	val.red = INT2FIX((ARGB>>16)&0xFF) / 255;	val.green = INT2FIX((ARGB>>8)&0xFF) / 255;	val.blue = INT2FIX((ARGB)&0xFF) / 255;	return val;}Fixed get_bifs_alpha(u32 ARGB){	return INT2FIX((ARGB>>24)&0xFF) / 255;}void SWF_InsertAppearance(SWFReader *read, GF_Node *app){	M_Shape *s = (M_Shape *) SWF_NewNode(read, TAG_MPEG4_Shape);	s->appearance = app;	gf_node_register(app, (GF_Node *) s);	SWF_InsertNode(read, (GF_Node *)s);}Bool col_equal(SFColor c1, SFColor c2){	if (c1.red != c2.red) return 0;	if (c1.green != c2.green) return 0;	if (c1.blue != c2.blue) return 0;	return 1;}GF_Node *SWF_GetAppearance(SWFReader *read, GF_Node *parent, u32 fill_col, Fixed line_width, u32 l_col){	char szDEF[1024];	u32 ID, i;	SFColor fc, lc;	Fixed fill_transp, line_transp;	M_Appearance *app;	M_Material2D *mat;	fc = get_bifs_col(fill_col);	fill_transp = FIX_ONE - get_bifs_alpha(fill_col);	if (fill_transp<0) fill_transp=0;	lc = get_bifs_col(l_col);	line_transp = FIX_ONE - get_bifs_alpha(l_col);	if (line_transp<0) line_transp=0;	i=0;	while ((app = (M_Appearance*)gf_list_enum(read->apps, &i))) {		mat = (M_Material2D *)app->material;		if (!line_width) {			if (mat->lineProps || !mat->filled) continue;		} else {			if (!mat->lineProps) continue;			if (!col_equal(((M_LineProperties *)mat->lineProps)->lineColor, lc)) continue;			if (((M_LineProperties *)mat->lineProps)->width != line_width) continue;		}		if (!mat->filled && fill_col) continue;		if (mat->filled) {			if (!fill_col) continue;			if (mat->transparency != fill_transp) continue;			if (!col_equal(mat->emissiveColor, fc)) continue;		}		/*OK same appearance let's go*/		gf_node_register((GF_Node *)app, parent);		return (GF_Node *)app;	}	app = (M_Appearance *) SWF_NewNode(read, TAG_MPEG4_Appearance);	app->material = SWF_NewNode(read, TAG_MPEG4_Material2D);	gf_node_register(app->material, (GF_Node *)app);	((M_Material2D *)app->material)->filled = 0;	if (fill_col) {		((M_Material2D *)app->material)->filled = 1;		((M_Material2D *)app->material)->emissiveColor = fc;		((M_Material2D *)app->material)->transparency = fill_transp;	}	if (line_width && l_col) {		if (read->flags & GF_SM_SWF_SCALABLE_LINE) {			M_XLineProperties *lp = (M_XLineProperties *) SWF_NewNode(read, TAG_MPEG4_XLineProperties);			((M_Material2D *)app->material)->lineProps = (GF_Node *) lp;			lp->width = line_width;			lp->lineColor = lc;			lp->isScalable = 1;			lp->transparency = line_transp;			gf_node_register((GF_Node *)lp, app->material);		} else {			M_LineProperties *lp = (M_LineProperties *) SWF_NewNode(read, TAG_MPEG4_LineProperties);			((M_Material2D *)app->material)->lineProps = (GF_Node *) lp;			lp->width = line_width;			lp->lineColor = lc;			gf_node_register((GF_Node *)lp, app->material);		}	}	gf_node_register((GF_Node *)app, parent);	if (read->load->swf_import_flags & GF_SM_SWF_REUSE_APPEARANCE) {		sprintf(szDEF, "FILLAPP_%d", gf_list_count(read->apps));		read->load->ctx->max_node_id++;		ID = read->load->ctx->max_node_id;		gf_node_set_id((GF_Node *)app, ID, szDEF);		SWF_InsertAppearance(read, (GF_Node *)app);		gf_list_add(read->apps, app);	}	return (GF_Node *) app;}GF_Rect SWF_GetCenteredBounds(SWFShapeRec *srec){	GF_Rect rc;	u32 i;	Fixed xm, ym, xM, yM;	xM = yM = FIX_MIN;	xm = ym = FIX_MAX;	for (i=0; i<srec->path->nbPts; i++) {		if (srec->path->pts[i].x<=xm) xm = srec->path->pts[i].x;		if (srec->path->pts[i].x>=xM) xM = srec->path->pts[i].x;		if (srec->path->pts[i].y<=ym) ym = srec->path->pts[i].y;		if (srec->path->pts[i].y>=yM) yM = srec->path->pts[i].y;	}	rc.width = xM-xm;	rc.height = yM-ym;	rc.x = xm + rc.width/2;	rc.y = ym + rc.height/2;	return rc;}GF_Node *SWF_GetGradient(SWFReader *read, GF_Node *parent, SWFShapeRec *srec){	Bool is_radial, has_alpha;	GF_Rect rc;	GF_Matrix2D mx;	u32 i;	MFFloat *keys;	MFColor *values;	GF_FieldInfo info;	M_Appearance *app = (M_Appearance *) SWF_NewNode(read, TAG_MPEG4_Appearance);	gf_node_register((GF_Node *)app, parent);	app->material = SWF_NewNode(read, TAG_MPEG4_Material2D);	gf_node_register(app->material, (GF_Node *)app);	((M_Material2D *)app->material)->filled = 1;	is_radial = (srec->type==0x12) ? 1 : 0;	app->texture = SWF_NewNode(read, is_radial ? TAG_MPEG4_RadialGradient : TAG_MPEG4_LinearGradient);	gf_node_register((GF_Node *) app->texture, (GF_Node *) app);	/*set keys*/	gf_node_get_field_by_name(app->texture, "key", &info);	gf_sg_vrml_mf_alloc(info.far_ptr, info.fieldType, srec->nbGrad);	keys = (MFFloat *)info.far_ptr;	for (i=0; i<srec->nbGrad; i++) {		keys->vals[i] = srec->grad_ratio[i];		keys->vals[i] /= 255;	}	/*set colors*/	gf_node_get_field_by_name(app->texture, "keyValue", &info);	gf_sg_vrml_mf_alloc(info.far_ptr, info.fieldType, srec->nbGrad);	values = (MFColor *)info.far_ptr;	has_alpha = 0;	for (i=0; i<srec->nbGrad; i++) {		values->vals[i] = get_bifs_col(srec->grad_col[i]);		if (get_bifs_alpha(srec->grad_col[i]) != FIX_ONE) has_alpha = 1;	}	/*set opacity*/	if (has_alpha) {		gf_node_get_field_by_name(app->texture, "opacity", &info);		gf_sg_vrml_mf_alloc(info.far_ptr, info.fieldType, srec->nbGrad);		keys = (MFFloat *)info.far_ptr;		for (i=0; i<srec->nbGrad; i++) {			keys->vals[i] = get_bifs_alpha(srec->grad_col[i]);		}		/*and remove material !!*/		((M_Material2D *)app->material)->filled = 0;		((M_Material2D *)app->material)->lineProps = SWF_NewNode(read, TAG_MPEG4_LineProperties);;		((M_LineProperties *)((M_Material2D *)app->material)->lineProps)->width = 0;		gf_node_register(((M_Material2D *)app->material)->lineProps, app->material);	}	/*		FIXME - THIS IS WRONG, don't have time to investigate how to map gradients into (u, v) space	*/	/*get bounds in local coord system*/	rc = SWF_GetCenteredBounds(srec);	/*remove positioning*/	srec->mat.m[2] -= rc.x;	srec->mat.m[5] -= rc.y;	/*set positioning in TEX coords (0,1) and not shape coords*/	srec->mat.m[2] = gf_divfix(srec->mat.m[2] , rc.width);	srec->mat.m[5] = gf_divfix(srec->mat.m[5], rc.height);	/*remove gradient square to local shape scaling*/	gf_mx2d_init(mx);	gf_mx2d_add_scale(&mx, gf_divfix(INT2FIX(32768), rc.width), gf_divfix(INT2FIX(32768), rc.height) );	gf_mx2d_add_matrix(&mx, &srec->mat);	/*adjust center for radial gradient*/	if (rc.width > rc.height) {		Fixed ar = gf_divfix(rc.width, rc.height);		mx.m[5] += (FIX_ONE-ar)/2;	} else {		Fixed ar = gf_divfix(rc.height,rc.width);		mx.m[2] += (FIX_ONE-ar)/2;	}	gf_node_get_field_by_name(app->texture, "spreadMethod", &info);	*((SFInt32*)info.far_ptr) = 1;	gf_node_get_field_by_name(app->texture, "transform", &info);	*((GF_Node **)info.far_ptr) = SWF_GetBIFSMatrix(read, &mx);	gf_node_register(*((GF_Node **)info.far_ptr), app->texture);	return (GF_Node *) app;}void SWFShape_SetAppearance(SWFReader *read, SWFShape *shape, M_Shape *n, SWFShapeRec *srec, Bool is_fill){	/*get regular appearance reuse*/	if (is_fill) {		switch (srec->type) {		/*solid/alpha fill*/		case 0x00:			n->appearance = SWF_GetAppearance(read, (GF_Node *) n, srec->solid_col, 0, 0);			break;		case 0x10:		case 0x12:			if (read->flags & GF_SM_SWF_NO_GRADIENT) {				u32 col = srec->grad_col[srec->nbGrad/2];				col |= 0xFF000000;				n->appearance = SWF_GetAppearance(read, (GF_Node *) n, col, 0, 0);			} else {				n->appearance = SWF_GetGradient(read, (GF_Node *) n, srec);			}			break;		default:			swf_report(read, GF_NOT_SUPPORTED, "Bitmap fill_style not supported");			break;		}	} else {		n->appearance = SWF_GetAppearance(read, (GF_Node *) n, 0, srec->width, srec->solid_col);	}}/*translate a flash sub shape with only one path (eg one looking style) to a BIFS Shape node*/GF_Node *SWFShapeToCurve2D(SWFReader *read, SWFShape *shape, SWFShapeRec *srec, Bool is_fill){	u32 pt_idx, i;	Bool use_xcurve;	void *fptr;	SFVec2f ct1, ct2, ct, pt, move_orig;	M_Curve2D *curve;	M_Coordinate2D *points;	M_Shape *n = (M_Shape *) SWF_NewNode(read, TAG_MPEG4_Shape);	SWFShape_SetAppearance(read, shape, n, srec, is_fill);	use_xcurve = (read->flags & GF_SM_SWF_QUAD_CURVE) ? 1 : 0;	if (use_xcurve) {		curve = (M_Curve2D *) SWF_NewNode(read, TAG_MPEG4_XCurve2D);	} else {		curve = (M_Curve2D *) SWF_NewNode(read, TAG_MPEG4_Curve2D);	}	points = (M_Coordinate2D *) SWF_NewNode(read, TAG_MPEG4_Coordinate2D);	n->geometry = (GF_Node *) curve;	gf_node_register((GF_Node *) curve, (GF_Node *)n);	curve->point = (GF_Node *) points;	gf_node_register((GF_Node *) points, (GF_Node *) curve);	curve->fineness = FIX_ONE;	assert(srec->path->nbType);	pt_idx = 0;	for (i=0; i<srec->path->nbType; i++) {		switch (srec->path->types[i]) {		/*moveTo*/		case 0:			/*first moveTo implicit in BIFS*/			if (i) {				gf_sg_vrml_mf_append(&curve->type, GF_SG_VRML_MFINT32, &fptr);				*((SFInt32 *)fptr) = 0;			}			gf_sg_vrml_mf_append(&points->point, GF_SG_VRML_MFVEC2F, &fptr);			((SFVec2f *)fptr)->x = srec->path->pts[pt_idx].x;			((SFVec2f *)fptr)->y = srec->path->pts[pt_idx].y;			move_orig = srec->path->pts[pt_idx];			pt_idx++;			break;		/*lineTo*/		case 1:			gf_sg_vrml_mf_append(&curve->type, GF_SG_VRML_MFINT32, &fptr);			*((SFInt32 *)fptr) = 1;			gf_sg_vrml_mf_append(&points->point, GF_SG_VRML_MFVEC2F, &fptr);			((SFVec2f *)fptr)->x = srec->path->pts[pt_idx].x;			((SFVec2f *)fptr)->y = srec->path->pts[pt_idx].y;			pt_idx++;			break;		/*curveTo*/		case 2:			/*XCurve2D has quad arcs*/			if (use_xcurve) {				gf_sg_vrml_mf_append(&curve->type, GF_SG_VRML_MFINT32, &fptr);				*((SFInt32 *)fptr) = 7;				gf_sg_vrml_mf_append(&points->point, GF_SG_VRML_MFVEC2F, &fptr);				((SFVec2f *)fptr)->x = srec->path->pts[pt_idx].x;				((SFVec2f *)fptr)->y = srec->path->pts[pt_idx].y;				gf_sg_vrml_mf_append(&points->point, GF_SG_VRML_MFVEC2F, &fptr);				((SFVec2f *)fptr)->x = srec->path->pts[pt_idx+1].x;				((SFVec2f *)fptr)->y = srec->path->pts[pt_idx+1].y;				pt_idx+=2;			} else {				gf_sg_vrml_mf_append(&curve->type, GF_SG_VRML_MFINT32, &fptr);				*((SFInt32 *)fptr) = 2;				/*recompute cubic from quad*/				ct.x = srec->path->pts[pt_idx].x;				ct.y = srec->path->pts[pt_idx].y;				pt.x = srec->path->pts[pt_idx-1].x;				pt.y = srec->path->pts[pt_idx-1].y;				ct1.x = pt.x + 2*(ct.x - pt.x)/3;				ct1.y = pt.y + 2*(ct.y - pt.y)/3;				ct.x = srec->path->pts[pt_idx+1].x;				ct.y = srec->path->pts[pt_idx+1].y;				ct2.x = ct1.x + (ct.x - pt.x) / 3;				ct2.y = ct1.y + (ct.y - pt.y) / 3;				gf_sg_vrml_mf_append(&points->point, GF_SG_VRML_MFVEC2F, &fptr);				((SFVec2f *)fptr)->x = ct1.x;				((SFVec2f *)fptr)->y = ct1.y;				gf_sg_vrml_mf_append(&points->point, GF_SG_VRML_MFVEC2F, &fptr);

⌨️ 快捷键说明

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