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

📄 grouping_stacks.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 / 2D rendering module * *  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 "stacks2d.h"#include "visualsurface2d.h"/*for anchor processing, which needs to be filtered at the inline scene level*/#include <gpac/internal/terminal_dev.h>typedef struct{	s32 last_switch;} SwitchStack;static void RenderSwitch(GF_Node *node, void *rs, Bool is_destroy){	GF_ChildNodeItem *l;	u32 i, count;	Bool prev_switch;	GF_ChildNodeItem *children;	s32 whichChoice;	GF_Node *child;	SwitchStack *st = (SwitchStack *)gf_node_get_private(node);	RenderEffect2D *eff; 	eff = (RenderEffect2D *)rs;	if (is_destroy) {		free(st);		return;	}		if (gf_node_get_name(node)) {		node = node;	}	/*WARNING: X3D/MPEG4 NOT COMPATIBLE*/	if (gf_node_get_tag(node)==TAG_MPEG4_Switch) {		children = ((M_Switch *)node)->choice;		whichChoice = ((M_Switch *)node)->whichChoice;	} else {		children = ((X_Switch *)node)->children;		whichChoice = ((X_Switch *)node)->whichChoice;	}	count = gf_node_list_get_count(children);	prev_switch = eff->trav_flags;	/*check changes in choice field*/	if ((gf_node_dirty_get(node) & GF_SG_NODE_DIRTY) || (st->last_switch != whichChoice) ) {		eff->trav_flags |= GF_SR_TRAV_SWITCHED_OFF;		i=0;		l = children;		while (l) {//			if ((s32) i!=whichChoice) gf_node_render(l->node, eff);			if ((s32) i == st->last_switch) gf_node_render(l->node, eff);			l = l->next;			i++;		}		eff->trav_flags &= ~GF_SR_TRAV_SWITCHED_OFF;		st->last_switch = whichChoice;	}	gf_node_dirty_clear(node, 0);	/*no need to check for sensors since a sensor is active for the whole parent group, that is for switch itself	CSQ: switch cannot be used to switch sensors, too bad...*/	eff->trav_flags = prev_switch;	if (whichChoice>=0) {		child = (GF_Node*)gf_node_list_get_child(children, whichChoice);		gf_node_render(child, eff);	}}void R2D_InitSwitch(Render2D *sr, GF_Node *node){	SwitchStack *st = (SwitchStack *)malloc(sizeof(SwitchStack));	st->last_switch = -1;	gf_node_set_private(node, st);	gf_node_set_callback_function(node, RenderSwitch);}/*transform2D*/static void RenderTransform2D(GF_Node *node, void *rs, Bool is_destroy){	GF_Matrix2D bckup;	M_Transform2D *tr = (M_Transform2D *)node;	Transform2DStack *ptr = (Transform2DStack *)gf_node_get_private(node);	RenderEffect2D *eff;		if (is_destroy) {		DeleteGroupingNode2D((GroupingNode2D *)ptr);		free(ptr);		return;	}	eff = (RenderEffect2D *) rs;	if (gf_node_dirty_get(node) & GF_SG_NODE_DIRTY) {		gf_mx2d_init(ptr->mat);		ptr->is_identity = 1;		if ((tr->scale.x != FIX_ONE) || (tr->scale.y != FIX_ONE)) {			gf_mx2d_add_scale_at(&ptr->mat, tr->scale.x, tr->scale.y, 0, 0, tr->scaleOrientation);			ptr->is_identity = 0;		}		if (tr->rotationAngle) {			gf_mx2d_add_rotation(&ptr->mat, tr->center.x, tr->center.y, tr->rotationAngle);			ptr->is_identity = 0;		}		if (tr->translation.x || tr->translation.y) {			ptr->is_identity = 0;			gf_mx2d_add_translation(&ptr->mat, tr->translation.x, tr->translation.y);		}	}	/*note we don't clear dirty flag, this is done in traversing*/	if (ptr->is_identity) {		group2d_traverse((GroupingNode2D *)ptr, tr->children, eff);	} else {		gf_mx2d_copy(bckup, eff->transform);		gf_mx2d_copy(eff->transform, ptr->mat);		gf_mx2d_add_matrix(&eff->transform, &bckup);		group2d_traverse((GroupingNode2D *)ptr, tr->children, eff);		gf_mx2d_copy(eff->transform, bckup);	}}void R2D_InitTransform2D(Render2D *sr, GF_Node *node){	Transform2DStack *stack = (Transform2DStack *)malloc(sizeof(Transform2DStack));	SetupGroupingNode2D((GroupingNode2D *)stack, sr, node);	gf_mx2d_init(stack->mat);	stack->is_identity = 1;	gf_node_set_private(node, stack);	gf_node_set_callback_function(node, RenderTransform2D);}void TM2D_GetMatrix(GF_Node *n, GF_Matrix2D *mat){	M_TransformMatrix2D *tr = (M_TransformMatrix2D*)n;	gf_mx2d_init(*mat);	mat->m[0] = tr->mxx;	mat->m[1] = tr->mxy;	mat->m[2] = tr->tx;	mat->m[3] = tr->myx;	mat->m[4] = tr->myy;	mat->m[5] = tr->ty;}/*TransformMatrix2D*/static void RenderTransformMatrix2D(GF_Node *node, void *rs, Bool is_destroy){	GF_Matrix2D bckup;	M_TransformMatrix2D *tr = (M_TransformMatrix2D*)node;	Transform2DStack *ptr = (Transform2DStack *) gf_node_get_private(node);	RenderEffect2D *eff = (RenderEffect2D *)rs;	if (is_destroy) {		DeleteGroupingNode2D((GroupingNode2D *)ptr);		free(ptr);		return;	}	if (gf_node_dirty_get(node) & GF_SG_NODE_DIRTY) {		TM2D_GetMatrix(node, &ptr->mat);		if ((tr->mxx==FIX_ONE) && (tr->mxy==0) && (tr->tx==0)			&& (tr->myx==0) && (tr->myy==FIX_ONE) && (tr->ty==0) )			ptr->is_identity = 1;		else			ptr->is_identity = 0;	}	/*note we don't clear dirty flag, this is done in traversing*/	if (ptr->is_identity) {		group2d_traverse((GroupingNode2D *)ptr, tr->children, eff);	} else {		gf_mx2d_copy(bckup, eff->transform);		gf_mx2d_copy(eff->transform, ptr->mat);		gf_mx2d_add_matrix(&eff->transform, &bckup);		group2d_traverse((GroupingNode2D *)ptr, tr->children, eff);		gf_mx2d_copy(eff->transform, bckup);	}}void R2D_InitTransformMatrix2D(Render2D *sr, GF_Node *node){	Transform2DStack *stack = (Transform2DStack *)malloc(sizeof(Transform2DStack));	SetupGroupingNode2D((GroupingNode2D *)stack, sr, node);	gf_mx2d_init(stack->mat);	gf_node_set_private(node, stack);	gf_node_set_callback_function(node, RenderTransformMatrix2D);}typedef struct{	GF_Node *owner;	GF_Renderer *compositor;	GROUPINGNODESTACK2D	GF_ColorMatrix cmat;} ColorTransformStack;/*ColorTransform*/static void RenderColorTransform(GF_Node *node, void *rs, Bool is_destroy){	Bool c_changed;	M_ColorTransform *tr = (M_ColorTransform *)node;	ColorTransformStack *ptr = (ColorTransformStack  *)gf_node_get_private(node);	RenderEffect2D *eff;	eff = (RenderEffect2D *) rs;	if (is_destroy) {		DeleteGroupingNode2D((GroupingNode2D *)ptr);		free(ptr);		return;	}	c_changed = 0;	if (gf_node_dirty_get(node) & GF_SG_NODE_DIRTY) {		gf_cmx_set(&ptr->cmat, 			tr->mrr , tr->mrg, tr->mrb, tr->mra, tr->tr, 			tr->mgr , tr->mgg, tr->mgb, tr->mga, tr->tg, 			tr->mbr, tr->mbg, tr->mbb, tr->mba, tr->tb, 			tr->mar, tr->mag, tr->mab, tr->maa, tr->ta); 		c_changed = 1;	}	/*note we don't clear dirty flag, this is done in traversing*/	if (ptr->cmat.identity) {		group2d_traverse((GroupingNode2D *) ptr, tr->children, eff);	} else {		GF_ColorMatrix gf_cmx_bck;		Bool prev_inv = eff->invalidate_all;		/*if modified redraw all nodes*/		if (c_changed) eff->invalidate_all = 1;		gf_cmx_copy(&gf_cmx_bck, &eff->color_mat);		gf_cmx_multiply(&eff->color_mat, &ptr->cmat);		group2d_traverse((GroupingNode2D *) ptr, tr->children, eff);		/*restore effects*/		gf_cmx_copy(&eff->color_mat, &gf_cmx_bck);		eff->invalidate_all = prev_inv;	}}void R2D_InitColorTransform(Render2D *sr, GF_Node *node){	ColorTransformStack *stack = (ColorTransformStack *)malloc(sizeof(ColorTransformStack));	SetupGroupingNode2D((GroupingNode2D *)stack, sr, node);	gf_cmx_init(&stack->cmat);	gf_node_set_private(node, stack);	gf_node_set_callback_function(node, RenderColorTransform);}static void RenderGroup(GF_Node *node, void *rs, Bool is_destroy){	GroupingNode2D *group = (GroupingNode2D *) gf_node_get_private(node);	if (is_destroy) {		DeleteGroupingNode2D(group);		free(group);		return;	}	group2d_traverse(group, ((M_Group *)node)->children, (RenderEffect2D*)rs);}void R2D_InitGroup(Render2D *sr, GF_Node *node){	GroupingNode2D *stack = (GroupingNode2D *)malloc(sizeof(GroupingNode2D));	SetupGroupingNode2D(stack, sr, node);	gf_node_set_private(node, stack);	gf_node_set_callback_function(node, RenderGroup);}typedef struct{	GF_Node *owner;	GF_Renderer *compositor;	GROUPINGNODESTACK2D	Bool enabled, is_over;	SensorHandler hdl;} AnchorStack;static void RenderAnchor(GF_Node *node, void *rs, Bool is_destroy){	AnchorStack *st = (AnchorStack *) gf_node_get_private(node);	M_Anchor *an = (M_Anchor *) node;	RenderEffect2D *eff = (RenderEffect2D *)rs;	if (is_destroy) {		R2D_UnregisterSensor(st->compositor, &st->hdl);		if (st->compositor->interaction_sensors) st->compositor->interaction_sensors--;		DeleteGroupingNode2D((GroupingNode2D *)st);		free(st);		return;	}	/*update enabled state*/	if (gf_node_dirty_get(node) & GF_SG_NODE_DIRTY) {		st->enabled = 0;		if (an->url.count && an->url.vals[0].url && strlen(an->url.vals[0].url) )			st->enabled = 1;	}	/*note we don't clear dirty flag, this is done in traversing*/	group2d_traverse((GroupingNode2D*)st, an->children, eff);}static Bool anchor_is_enabled(SensorHandler *sh){	AnchorStack *st = (AnchorStack *) gf_node_get_private(sh->owner);	return st->enabled;}static Bool OnAnchor(SensorHandler *sh, GF_Event *evt, DrawableContext *ctx, GF_Matrix2D *sensor_matrix){	u32 i;	GF_Event event;	AnchorStack *st = (AnchorStack *) gf_node_get_private(sh->owner);	M_Anchor *an = (M_Anchor *) sh->owner;	if (ctx==NULL) {		event.type = GF_EVENT_NAVIGATE_INFO;		event.navigate.to_url = "";		st->compositor->user->EventProc(st->compositor->user->opaque, &event);		st->is_over = 0;		return 0;	}	if (evt->type == GF_EVENT_MOUSEMOVE) {		if (!st->is_over && st->compositor->user->EventProc) {			event.type = GF_EVENT_NAVIGATE_INFO;			event.navigate.to_url = an->description.buffer;			if (!event.navigate.to_url || !strlen(event.navigate.to_url)) event.navigate.to_url = an->url.vals[0].url;			st->compositor->user->EventProc(st->compositor->user->opaque, &event);		}		st->is_over = 1;		return 0;	}	if ((evt->type != GF_EVENT_MOUSEUP) || (evt->mouse.button != GF_MOUSE_LEFT)) return 0;	event.type = GF_EVENT_NAVIGATE;	event.navigate.param_count = an->parameter.count;	event.navigate.parameters = (const char **) an->parameter.vals;

⌨️ 快捷键说明

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