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

📄 svg_smjs.c

📁 一个用于智能手机的多媒体库适合S60 WinCE的跨平台开发库
💻 C
📖 第 1 页 / 共 4 页
字号:
	}	return JS_FALSE;}static u32 svg_path_realloc_pts(pathCI *p, u32 nb_pts){	u32 i, orig_pts;	orig_pts = 0;	for (i=0; i<p->nb_coms; i++) {		switch (p->tags[i]) {		case 0: orig_pts++; break;		case 1: orig_pts++; break;		case 2: orig_pts+=3; break;		case 3: orig_pts+=2; break;		case 4: orig_pts+=2; break;		case 5: orig_pts+=1; break;		}	}	p->pts = realloc(p->pts, sizeof(ptCI)*(nb_pts+orig_pts));	return orig_pts;}static JSBool svg_path_move_to(JSContext *c, JSObject *obj, uintN argc, jsval *argv, jsval *vp){	pathCI *p;	jsdouble x, y;	u32 nb_pts;	if (!JS_InstanceOf(c, obj, &svg_rt->pathClass, NULL) ) return JS_FALSE;	p = JS_GetPrivate(c, obj);	if (!p) return JS_FALSE;	if ((argc!=2) || !JSVAL_IS_NUMBER(argv[0]) || !JSVAL_IS_NUMBER(argv[1])) return JS_FALSE;	JS_ValueToNumber(c, argv[0], &x);	JS_ValueToNumber(c, argv[1], &y);	nb_pts = svg_path_realloc_pts(p, 1);	p->pts[nb_pts].x = (Float) x;	p->pts[nb_pts].y = (Float) y;	p->tags = realloc(p->tags, sizeof(u8)*(p->nb_coms+1) );	p->tags[p->nb_coms] = 0;	p->nb_coms++;	return JS_TRUE;}static JSBool svg_path_line_to(JSContext *c, JSObject *obj, uintN argc, jsval *argv, jsval *vp){	pathCI *p;	jsdouble x, y;	u32 nb_pts;	if (!JS_InstanceOf(c, obj, &svg_rt->pathClass, NULL) ) return JS_FALSE;	p = JS_GetPrivate(c, obj);	if (!p) return JS_FALSE;	if ((argc!=2) || !JSVAL_IS_NUMBER(argv[0]) || !JSVAL_IS_NUMBER(argv[1])) return JS_FALSE;	JS_ValueToNumber(c, argv[0], &x);	JS_ValueToNumber(c, argv[1], &y);	nb_pts = svg_path_realloc_pts(p, 1);	p->pts[nb_pts].x = (Float) x;	p->pts[nb_pts].y = (Float) y;	p->tags = realloc(p->tags, sizeof(u8)*(p->nb_coms+1) );	p->tags[p->nb_coms] = 1;	p->nb_coms++;	return JS_TRUE;}static JSBool svg_path_quad_to(JSContext *c, JSObject *obj, uintN argc, jsval *argv, jsval *vp){	pathCI *p;	jsdouble x1, y1, x2, y2;	u32 nb_pts;	if (!JS_InstanceOf(c, obj, &svg_rt->pathClass, NULL) ) return JS_FALSE;	p = JS_GetPrivate(c, obj);	if (!p) return JS_FALSE;	if ((argc!=4) || !JSVAL_IS_NUMBER(argv[0]) || !JSVAL_IS_NUMBER(argv[1]) || !JSVAL_IS_NUMBER(argv[2]) || !JSVAL_IS_NUMBER(argv[3])) return JS_FALSE;	JS_ValueToNumber(c, argv[0], &x1);	JS_ValueToNumber(c, argv[1], &y1);	JS_ValueToNumber(c, argv[2], &x2);	JS_ValueToNumber(c, argv[3], &y2);	nb_pts = svg_path_realloc_pts(p, 2);	p->pts[nb_pts].x = (Float) x1; p->pts[nb_pts].y = (Float) y1;	p->pts[nb_pts+1].x = (Float) x2; p->pts[nb_pts+1].y = (Float) y2;	p->tags = realloc(p->tags, sizeof(u8)*(p->nb_coms+1) );	p->tags[p->nb_coms] = 4;	p->nb_coms++;	return JS_TRUE;}static JSBool svg_path_curve_to(JSContext *c, JSObject *obj, uintN argc, jsval *argv, jsval *vp){	pathCI *p;	jsdouble x1, y1, x2, y2, x, y;	u32 nb_pts;	if (!JS_InstanceOf(c, obj, &svg_rt->pathClass, NULL) ) return JS_FALSE;	p = JS_GetPrivate(c, obj);	if (!p) return JS_FALSE;	if ((argc!=6) || !JSVAL_IS_NUMBER(argv[0]) || !JSVAL_IS_NUMBER(argv[1]) || !JSVAL_IS_NUMBER(argv[2]) || !JSVAL_IS_NUMBER(argv[3]) || !JSVAL_IS_NUMBER(argv[4]) || !JSVAL_IS_NUMBER(argv[5])) return JS_FALSE;	JS_ValueToNumber(c, argv[0], &x1);	JS_ValueToNumber(c, argv[1], &y1);	JS_ValueToNumber(c, argv[2], &x2);	JS_ValueToNumber(c, argv[3], &y2);	JS_ValueToNumber(c, argv[4], &x);	JS_ValueToNumber(c, argv[5], &y);	nb_pts = svg_path_realloc_pts(p, 3);	p->pts[nb_pts].x = (Float) x1; p->pts[nb_pts].y = (Float) y1;	p->pts[nb_pts+1].x = (Float) x2; p->pts[nb_pts+1].y = (Float) y2;	p->pts[nb_pts+2].x = (Float) x; p->pts[nb_pts+2].y = (Float) y;	p->tags = realloc(p->tags, sizeof(u8)*(p->nb_coms+1) );	p->tags[p->nb_coms] = 2;	p->nb_coms++;	return JS_TRUE;}static JSBool svg_path_close(JSContext *c, JSObject *obj, uintN argc, jsval *argv, jsval *vp){	pathCI *p;	if (!JS_InstanceOf(c, obj, &svg_rt->pathClass, NULL) ) return JS_FALSE;	p = JS_GetPrivate(c, obj);	if (!p) return JS_FALSE;	if (argc) return JS_FALSE;	p->tags = realloc(p->tags, sizeof(u8)*(p->nb_coms+1) );	p->tags[p->nb_coms] = 6;	p->nb_coms++;	return JS_TRUE;}static JSBool svg_mx2d_constructor(JSContext *c, JSObject *obj, uintN argc, jsval *argv, jsval *rval){	GF_Matrix2D *mx = malloc(sizeof(GF_Matrix2D));	gf_mx2d_init(*mx);	JS_SetPrivate(c, obj, mx);	*rval = OBJECT_TO_JSVAL(obj);	return JS_TRUE;}static JSBool svg_mx2d_get_component(JSContext *c, JSObject *obj, uintN argc, jsval *argv, jsval *vp){	jsdouble *d;	GF_Matrix2D *mx;	if (!JS_InstanceOf(c, obj, &svg_rt->matrixClass, NULL) ) return JS_FALSE;	mx = JS_GetPrivate(c, obj);	if (!mx || (argc!=1)) return JS_FALSE;	if (!JSVAL_IS_INT(argv[0])) return JS_FALSE;	switch (JSVAL_TO_INT(argv[0])) {	case 0: d = JS_NewDouble(c, FIX2FLT(mx->m[0])); *vp = DOUBLE_TO_JSVAL(d); return JS_TRUE;	case 1: d = JS_NewDouble(c, FIX2FLT(mx->m[3])); *vp = DOUBLE_TO_JSVAL(d); return JS_TRUE;	case 2: d = JS_NewDouble(c, FIX2FLT(mx->m[1])); *vp = DOUBLE_TO_JSVAL(d); return JS_TRUE;	case 3: d = JS_NewDouble(c, FIX2FLT(mx->m[4])); *vp = DOUBLE_TO_JSVAL(d); return JS_TRUE;	case 4: d = JS_NewDouble(c, FIX2FLT(mx->m[2])); *vp = DOUBLE_TO_JSVAL(d); return JS_TRUE;	case 5: d = JS_NewDouble(c, FIX2FLT(mx->m[5])); *vp = DOUBLE_TO_JSVAL(d); return JS_TRUE;	}	return JS_FALSE;}static JSBool svg_mx2d_multiply(JSContext *c, JSObject *obj, uintN argc, jsval *argv, jsval *vp){	JSObject *mat;	GF_Matrix2D *mx1, *mx2;	if (!JS_InstanceOf(c, obj, &svg_rt->matrixClass, NULL) ) return JS_FALSE;	mx1 = JS_GetPrivate(c, obj);	if (!mx1 || (argc!=1)) return JS_FALSE;	if (!JSVAL_IS_OBJECT(argv[0])) return JS_FALSE;	mat = JSVAL_TO_OBJECT(argv[0]);	if (!JS_InstanceOf(c, mat, &svg_rt->matrixClass, NULL) ) return JS_FALSE;	mx2 = JS_GetPrivate(c, mat);	if (!mx2) return JS_FALSE;	gf_mx2d_add_matrix(mx1, mx2);	*vp = OBJECT_TO_JSVAL(obj);	return JS_TRUE;}static JSBool svg_mx2d_inverse(JSContext *c, JSObject *obj, uintN argc, jsval *argv, jsval *vp){	GF_Matrix2D *mx1;	if (!JS_InstanceOf(c, obj, &svg_rt->matrixClass, NULL) ) return JS_FALSE;	mx1 = JS_GetPrivate(c, obj);	if (!mx1) return JS_FALSE;	gf_mx2d_inverse(mx1);	*vp = OBJECT_TO_JSVAL(obj);	return JS_TRUE;}static JSBool svg_mx2d_translate(JSContext *c, JSObject *obj, uintN argc, jsval *argv, jsval *vp){	jsdouble x, y;	GF_Matrix2D *mx1;	if (!JS_InstanceOf(c, obj, &svg_rt->matrixClass, NULL) ) return JS_FALSE;	mx1 = JS_GetPrivate(c, obj);	if (!mx1 || (argc!=2)) return JS_FALSE;	JS_ValueToNumber(c, argv[0], &x);	JS_ValueToNumber(c, argv[1], &y);	gf_mx2d_add_translation(mx1, FLT2FIX(x), FLT2FIX(y));	*vp = OBJECT_TO_JSVAL(obj);	return JS_TRUE;}static JSBool svg_mx2d_scale(JSContext *c, JSObject *obj, uintN argc, jsval *argv, jsval *vp){	jsdouble scale;	GF_Matrix2D *mx1;	if (!JS_InstanceOf(c, obj, &svg_rt->matrixClass, NULL) ) return JS_FALSE;	mx1 = JS_GetPrivate(c, obj);	if (!mx1 || (argc!=2)) return JS_FALSE;	JS_ValueToNumber(c, argv[0], &scale);	gf_mx2d_add_scale(mx1, FLT2FIX(scale), FLT2FIX(scale));	*vp = OBJECT_TO_JSVAL(obj);	return JS_TRUE;}static JSBool svg_mx2d_rotate(JSContext *c, JSObject *obj, uintN argc, jsval *argv, jsval *vp){	jsdouble angle;	GF_Matrix2D *mx1;	if (!JS_InstanceOf(c, obj, &svg_rt->matrixClass, NULL) ) return JS_FALSE;	mx1 = JS_GetPrivate(c, obj);	if (!mx1 || (argc!=2)) return JS_FALSE;	JS_ValueToNumber(c, argv[0], &angle);	gf_mx2d_add_rotation(mx1, 0, 0, FLT2FIX(angle));	*vp = OBJECT_TO_JSVAL(obj);	return JS_TRUE;}jsval svg_udom_new_rect(JSContext *c, Fixed x, Fixed y, Fixed width, Fixed height){	JSObject *r = JS_NewObject(c, &svg_rt->rectClass, 0, 0);	rectCI *rc = malloc(sizeof(rectCI));	rc->x = FIX2FLT(x);	rc->y = FIX2FLT(y);	rc->w = FIX2FLT(width);	rc->h = FIX2FLT(height);	rc->sg = NULL;	JS_SetPrivate(c, r, rc);	return OBJECT_TO_JSVAL(r);}jsval svg_udom_new_point(JSContext *c, Fixed x, Fixed y){	JSObject *p = JS_NewObject(c, &svg_rt->pointClass, 0, 0);	pointCI *pt = malloc(sizeof(pointCI));	pt->x = FIX2FLT(x);	pt->y = FIX2FLT(y);	pt->sg = NULL;	JS_SetPrivate(c, p, pt);	return OBJECT_TO_JSVAL(p);}static void svg_init_js_api(GF_SceneGraph *scene){	JS_SetContextPrivate(scene->svg_js->js_ctx, scene);	JS_SetErrorReporter(scene->svg_js->js_ctx, svg_script_error);	/*init global object*/	scene->svg_js->global = JS_NewObject(scene->svg_js->js_ctx, &svg_rt->globalClass, 0, 0 );	JS_InitStandardClasses(scene->svg_js->js_ctx, scene->svg_js->global);	/*remember pointer to scene graph!!*/	JS_SetPrivate(scene->svg_js->js_ctx, scene->svg_js->global, scene);	{		JSPropertySpec globalClassProps[] = {			{"connected",	0,       JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY},			{"parent",		1,       JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY},			{0}		};		JSFunctionSpec globalClassFuncs[] = {			{"createConnection", svg_connection_create, 0},			{"gotoLocation", svg_nav_to_location, 1},			{"alert",           svg_echo,          0},			/*technically, this is part of Implementation interface, not global, but let's try not to complicate things too much*/			{"hasFeature", dom_imp_has_feature, 2},			{0}		};		JS_DefineFunctions(scene->svg_js->js_ctx, scene->svg_js->global, globalClassFuncs);		JS_DefineProperties(scene->svg_js->js_ctx, scene->svg_js->global, globalClassProps);	}	/*initialize DOM core */	dom_js_load(scene->svg_js->js_ctx, scene->svg_js->global);	/*create document object, and remember it*/	dom_js_define_document(scene->svg_js->js_ctx, scene->svg_js->global, scene);	/*create event object, and remember it*/	scene->svg_js->event = dom_js_define_event(scene->svg_js->js_ctx, scene->svg_js->global);	/*RGBColor class*/	{		JSPropertySpec rgbClassProps[] = {			{"red",		0,       JSPROP_ENUMERATE | JSPROP_PERMANENT },			{"green",	1,       JSPROP_ENUMERATE | JSPROP_PERMANENT },			{"blue",	2,       JSPROP_ENUMERATE | JSPROP_PERMANENT },			{0}		};		JS_InitClass(scene->svg_js->js_ctx, scene->svg_js->global, 0, &svg_rt->rgbClass, rgb_constructor, 0, rgbClassProps, 0, 0, 0);	}	/*SVGRect class*/	{		JSPropertySpec rectClassProps[] = {			{"x",		0,       JSPROP_ENUMERATE | JSPROP_PERMANENT },			{"y",		1,       JSPROP_ENUMERATE | JSPROP_PERMANENT },			{"width",	2,       JSPROP_ENUMERATE | JSPROP_PERMANENT },			{"height",	3,       JSPROP_ENUMERATE | JSPROP_PERMANENT },			{0}		};		JS_InitClass(scene->svg_js->js_ctx, scene->svg_js->global, 0, &svg_rt->rectClass, rect_constructor, 0, rectClassProps, 0, 0, 0);	}	/*SVGPoint class*/	{		JSPropertySpec pointClassProps[] = {			{"x",	0,       JSPROP_ENUMERATE | JSPROP_PERMANENT },			{"y",	1,       JSPROP_ENUMERATE | JSPROP_PERMANENT },			{0}		};		JS_InitClass(scene->svg_js->js_ctx, scene->svg_js->global, 0, &svg_rt->pointClass, point_constructor, 0, pointClassProps, 0, 0, 0);	}	/*SVGMatrix class*/	{		JSFunctionSpec matrixClassFuncs[] = {			{"getComponent", svg_mx2d_get_component, 1},			{"mMultiply", svg_mx2d_multiply, 1},			{"inverse", svg_mx2d_inverse, 0},			{"mTranslate", svg_mx2d_translate, 2},			{"mScale", svg_mx2d_scale, 1},			{"mRotate", svg_mx2d_rotate, 1},			{0}		};		JS_InitClass(scene->svg_js->js_ctx, scene->svg_js->global, 0, &svg_rt->matrixClass, svg_mx2d_constructor, 0, 0, matrixClassFuncs, 0, 0);	}	/*SVGPath class*/	{		JSFunctionSpec pathClassFuncs[] = {			{"getSegment", svg_path_get_segment, 1},			{"getSegmentParam", svg_path_get_segment_param, 2},			{"moveTo", svg_path_move_to, 2},			{"lineTo", svg_path_line_to, 2},			{"quadTo", svg_path_quad_to, 4},			{"curveTo", svg_path_curve_to, 6},			{"close", svg_path_close, 0},			{0}		};		JSPropertySpec pathClassProps[] = {			{"numberOfSegments",	0,       JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY},			{0}		};		JS_InitClass(scene->svg_js->js_ctx, scene->svg_js->global, 0, &svg_rt->pathClass, pathCI_constructor, 0, pathClassProps, pathClassFuncs, 0, 0);	}}Bool svg_script_execute(GF_SceneGraph *sg, char *utf8_script, GF_DOM_Event *event){	char szFuncName[1024];	JSBool ret;	jsval rval;	GF_DOM_Event *prev_event = NULL;	char *sep = strchr(utf8_script, '(');	if (!sep) {		strcpy(szFuncName, utf8_script);		strcat(szFuncName, "(evt)");		utf8_script = szFuncName;	}	prev_event = JS_GetPrivate(sg->svg_js->js_ctx, sg->svg_js->event);	JS_SetPrivate(sg->svg_js->js_ctx, sg->svg_js->event, event);	ret = JS_EvaluateScript(sg->svg_js->js_ctx, sg->svg_js->global, utf8_script, strlen(utf8_script), 0, 0, &rval);	JS_SetPrivate(sg->svg_js->js_ctx, sg->svg_js->event, prev_event);	/*clean-up*/	JS_GC(sg->svg_js->js_ctx);	if (ret==JS_FALSE) {		char *sep = strchr(utf8_script, '(');		if (!sep) return 0;		sep[0] = 0;		JS_LookupProperty(sg->svg_js->js_ctx, sg->svg_js->global, utf8_script, &rval);		sep[0] = '(';		if (JSVAL_IS_VOID(rval)) return 0;	}	return 1;}static void svg_script_predestroy(GF_Node *n, void *eff, Bool is_destroy){	if (is_destroy) {		GF_SVGJS *svg_js = n->sgprivate->scenegraph->svg_js;		/*unregister script from parent scene (cf base_scenegraph::sg_reset) */		gf_list_del_item(n->sgprivate->scenegraph->scripts, n);		if (svg_js->nb_scripts) {			svg_js->nb_scripts--;			if (!svg_js->nb_scripts) {				gf_sg_ecmascript_del(svg_js->js_ctx);				dom_js_unload(svg_js->js_ctx, svg_js->global);				free(svg_js);				n->sgprivate->scenegraph->svg_js = NULL;				assert(svg_rt);				svg_rt->nb_inst--;				if (!svg_rt->nb_inst) {					free(svg_rt);					svg_rt = NULL;				}			}		}	}}static GF_Err JSScript_CreateSVGContext(GF_SceneGraph *sg){	GF_SVGJS *svg_js;	GF_SAFEALLOC(svg_js, GF_SVGJS);	/*create new ecmascript context*/	svg_js->js_ctx = gf_sg_ecmascript_new();	if (!svg_js->js_ctx) {		free(svg_js);		return GF_SCRIPT_ERROR;	}	if (!svg_rt) {		GF_SAFEALLOC(svg_rt, GF_SVGuDOM);		uDOM_SETUP_CLASS(svg_rt->globalClass, "global", JSCLASS_HAS_PRIVATE, global_getProperty, JS_PropertyStub, JS_FinalizeStub);		uDOM_SETUP_CLASS(svg_rt->rgbClass, "SVGRGBColor", JSCLASS_HAS_PRIVATE, rgb_getProperty, rgb_setProperty, baseCI_finalize);		uDOM_SETUP_CLASS(svg_rt->rectClass, "SVGRect", JSCLASS_HAS_PRIVATE, rect_getProperty, rect_setProperty, baseCI_finalize);		uDOM_SETUP_CLASS(svg_rt->pointClass, "SVGPoint", JSCLASS_HAS_PRIVATE, point_getProperty, point_setProperty, baseCI_finalize);		uDOM_SETUP_CLASS(svg_rt->matrixClass, "SVGMatrix", JSCLASS_HAS_PRIVATE, JS_PropertyStub, JS_PropertyStub, baseCI_finalize);		uDOM_SETUP_CLASS(svg_rt->pathClass, "SVGPath", JSCLASS_HAS_PRIVATE, path_getProperty, JS_PropertyStub, pathCI_finalize);	}	svg_rt->nb_inst++;	svg_js->script_execute = svg_script_execute;	svg_js->handler_execute = svg_script_execute_handler;	sg->svg_js = svg_js;	/*load SVG & DOM APIs*/	svg_init_js_api(sg);	return GF_OK;}GF_DOMText *svg_get_text_child(GF_Node *node){	GF_ChildNodeItem *child;	GF_DOMText *txt;	txt = NULL;	child = ((SVG_Element*)node)->children;	if (! child) return NULL;	while (child) {		txt = (GF_DOMText*)child->node;		if ((txt->sgprivate->tag==TAG_DOMText) && txt->textContent) return txt;		txt = NULL;		child = child->next;	}	return NULL;}void JSScript_LoadSVG(GF_Node *node){	GF_DOMText *txt;	GF_SVGJS *svg_js;	JSBool ret;	jsval rval;	txt = svg_get_text_child(node);	if (!txt) return;	if (!node->sgprivate->scenegraph->svg_js) {		if (JSScript_CreateSVGContext(node->sgprivate->scenegraph) != GF_OK) return;	}	/*register script width parent scene (cf base_scenegraph::sg_reset) */	gf_list_add(node->sgprivate->scenegraph->scripts, node);	svg_js = node->sgprivate->scenegraph->svg_js;	if (!node->sgprivate->UserCallback) {		svg_js->nb_scripts++;		node->sgprivate->UserCallback = svg_script_predestroy;	}	if (node->sgprivate->tag == TAG_SVG_handler) return;	ret = JS_EvaluateScript(svg_js->js_ctx, svg_js->global, txt->textContent, strlen(txt->textContent), 0, 0, &rval);	if (ret==JS_FALSE) {		_ScriptMessage(node->sgprivate->scenegraph, GF_SCRIPT_ERROR, "SVG: Invalid script");		return;	}	return;}Bool svg_script_execute_handler(GF_Node *node, GF_DOM_Event *event){	GF_DOMText *txt;	GF_SVGJS *svg_js;	JSBool ret = JS_FALSE;	GF_DOM_Event *prev_event = NULL;	jsval fval, rval;	txt = svg_get_text_child(node);	if (!txt) return 0;	GF_LOG(GF_LOG_DEBUG, GF_LOG_COMPOSE, ("[DOM Events] Executing script code from handler\n"));	svg_js = node->sgprivate->scenegraph->svg_js;	prev_event = JS_GetPrivate(svg_js->js_ctx, svg_js->event);	JS_SetPrivate(svg_js->js_ctx, svg_js->event, event);	if (JS_LookupProperty(svg_js->js_ctx, svg_js->global, txt->textContent, &fval) && !JSVAL_IS_VOID(fval) ) {		if (svg_script_execute(node->sgprivate->scenegraph, txt->textContent, event)) 			ret = JS_TRUE;	} else {		ret = JS_EvaluateScript(svg_js->js_ctx, svg_js->global, txt->textContent, strlen(txt->textContent), 0, 0, &rval);	}	JS_SetPrivate(svg_js->js_ctx, svg_js->event, prev_event);	if (ret==JS_FALSE) {		_ScriptMessage(node->sgprivate->scenegraph, GF_SCRIPT_ERROR, "SVG: Invalid handler textContent");		return 0;	}	return 1;}#endif#endif

⌨️ 快捷键说明

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