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

📄 viewport.c

📁 一个用于智能手机的多媒体库适合S60 WinCE的跨平台开发库
💻 C
字号:
/* *			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 default scene view*/#include <gpac/internal/terminal_dev.h>GF_Err R2D_GetViewport(GF_VisualRenderer *vr, u32 viewpoint_idx, const char **outName, Bool *is_bound){	u32 count;	GF_Node *n;	Render2D *sr = (Render2D *) vr->user_priv;	if (!sr->surface) return GF_BAD_PARAM;	count = gf_list_count(sr->surface->view_stack);	if (!viewpoint_idx) return GF_BAD_PARAM;	if (viewpoint_idx>count) return GF_EOS;	n = (GF_Node*)gf_list_get(sr->surface->view_stack, viewpoint_idx-1);	switch (gf_node_get_tag(n)) {	case TAG_MPEG4_Viewport: *outName = ((M_Viewport*)n)->description.buffer; *is_bound = ((M_Viewport*)n)->isBound; return GF_OK;	default: *outName = NULL; return GF_OK;	}}GF_Err R2D_SetViewport(GF_VisualRenderer *vr, u32 viewpoint_idx, const char *viewpoint_name){	u32 count, i;	M_Viewport *n;	Render2D *sr = (Render2D *) vr->user_priv;	if (!sr->surface) return GF_BAD_PARAM;	count = gf_list_count(sr->surface->view_stack);	if (viewpoint_idx>count) return GF_BAD_PARAM;	if (!viewpoint_idx && !viewpoint_name) return GF_BAD_PARAM;	/*note we're sure only viewport nodes are in the 2D view stack*/	if (viewpoint_idx) {		n = (M_Viewport *) gf_list_get(sr->surface->view_stack, viewpoint_idx-1);		n->set_bind = !n->set_bind;		n->on_set_bind((GF_Node *) n);		return GF_OK;	}	for (i=0; i<count;i++) {		n = (M_Viewport*) gf_list_get(sr->surface->view_stack, viewpoint_idx-1);		if (n->description.buffer && !stricmp(n->description.buffer, viewpoint_name)) {			n->set_bind = !n->set_bind;			n->on_set_bind((GF_Node *) n);			return GF_OK;		}	}	return GF_BAD_PARAM;}#define VPCHANGED(__comp) { GF_Event evt; evt.type = GF_EVENT_VIEWPOINTS; GF_USER_SENDEVENT(__comp->user, &evt); }typedef struct{	GF_Node *owner;	GF_Renderer *compositor;	GF_List *stack_list;	u32 last_sim_time;	Bool first_time;} ViewportStack;static void DestroyViewport(GF_Node *node){	s32 i;	GF_List *stack;	ViewportStack *ptr = (ViewportStack *) gf_node_get_private(node);	M_Viewport *n_vp;	while (gf_list_count(ptr->stack_list)) {		stack = (GF_List*)gf_list_get(ptr->stack_list, 0);		i = gf_list_del_item(stack, node);		if (i==0) {			n_vp = (M_Viewport *) gf_list_get(stack, 0);			/*we were bound so bind new top*/			if (n_vp) {				n_vp->isBound = 1;				n_vp->bindTime = gf_node_get_scene_time((GF_Node *)n_vp);				gf_node_event_out_str((GF_Node *)n_vp, "isBound");				gf_node_event_out_str((GF_Node *)n_vp, "bindTime");			}		}		gf_list_rem(ptr->stack_list, 0);	}	gf_list_del(ptr->stack_list);	/*notify change of vp stack*/	VPCHANGED(ptr->compositor);	free(ptr);}static void viewport_set_bind(GF_Node *node){	Bool on_top;	u32 i;	GF_List *stack;	GF_Node *a_vp;	ViewportStack *ptr = (ViewportStack *) gf_node_get_private(node);	M_Viewport *vp = (M_Viewport *) ptr->owner;	//notify all stacks using this node	i=0;	while ((stack = (GF_List*)gf_list_enum(ptr->stack_list, &i))) {		on_top = (gf_list_get(stack, 0) == node) ? 1 : 0;			if (!vp->set_bind) {			if (vp->isBound) {				vp->isBound = 0;				gf_node_event_out_str(node, "isBound");			}			if (on_top) {				a_vp = (GF_Node*)gf_list_get(stack, 0);				gf_list_rem(stack, 0);				gf_list_add(stack, a_vp);				a_vp = (GF_Node*)gf_list_get(stack, 0);				if (a_vp != node) {					((M_Viewport *) a_vp)->set_bind = 1;					gf_node_event_out_str(a_vp, "set_bind");				}			}		} else {			if (!vp->isBound) {				vp->isBound = 1;				vp->bindTime = gf_node_get_scene_time(node);				gf_node_event_out_str(node, "isBound");				gf_node_event_out_str(node, "bindTime");			}			if (!on_top) {				a_vp = (GF_Node*)gf_list_get(stack, 0);				if (a_vp != node) {					gf_list_del_item(stack, vp);					gf_list_insert(stack, vp, 0);					((M_Viewport *) a_vp)->isBound = 0;					gf_node_event_out_str(a_vp, "isBound");				}			}		}	}	gf_sr_invalidate(ptr->compositor, NULL);	/*notify change of vp stack*/	VPCHANGED(ptr->compositor);}static GF_List *vp_get_stack(ViewportStack *vp, RenderEffect2D *eff){	u32 i;		GF_List *stack;	if (!eff->view_stack) return NULL;	i=0;	while ((stack = (GF_List*)gf_list_enum(vp->stack_list, &i))) {		if (eff->view_stack == stack) return eff->view_stack;		}	gf_list_add(vp->stack_list, eff->view_stack);	gf_list_add(eff->view_stack, vp->owner);	/*need a callback to user*/	return eff->view_stack;}static void RenderViewport(GF_Node *node, void *rs, Bool is_destroy){	ViewportStack *st = (ViewportStack *) gf_node_get_private(node);	M_Viewport *vp = (M_Viewport *) st->owner;		if (is_destroy) {		DestroyViewport(node);		return;	}	if (st->first_time) {		GF_List *stack = vp_get_stack(st, (RenderEffect2D *)rs);		if (gf_list_get(stack, 0) == node) {			if (! vp->isBound) {				vp->isBound = 1;				vp->bindTime = gf_node_get_scene_time(node);				gf_node_event_out_str(node, "isBound");				gf_node_event_out_str(node, "bindTime");			}		} else {			if (gf_is_default_scene_viewpoint(node)) {				vp->set_bind = 1;				vp->on_set_bind(node);			}		}		st->first_time = 0;		VPCHANGED(st->compositor);	}}void R2D_InitViewport(Render2D *sr, GF_Node *node){	ViewportStack *ptr;	GF_SAFEALLOC(ptr, ViewportStack);	ptr->first_time = 1;	ptr->stack_list = gf_list_new();	gf_sr_traversable_setup(ptr, node, sr->compositor);	gf_node_set_private(node, ptr);	gf_node_set_callback_function(node, RenderViewport);	((M_Viewport*)node)->on_set_bind = viewport_set_bind;}void vp_setup(GF_Node *n, RenderEffect2D *eff, GF_Rect *surf_clip){	Fixed sx, sy, w, h, tx, ty;	GF_Matrix2D mat;	GF_Rect rc;	M_Viewport *vp = (M_Viewport *) n;	if (!vp->isBound || !surf_clip->width || !surf_clip->height) return;	gf_mx2d_init(mat);	gf_mx2d_add_translation(&mat, -1 * vp->position.x, -1 * vp->position.y);	gf_mx2d_add_rotation(&mat, 0, 0, -1 * vp->orientation);		gf_mx2d_add_matrix(&eff->transform, &mat);	gf_mx2d_copy(mat, eff->transform);	//compute scaling ratio	rc = gf_rect_center(vp->size.x, vp->size.y);	gf_mx2d_apply_rect(&mat, &rc);	w = surf_clip->width;	h = surf_clip->height;		surf_clip->width = rc.width;	surf_clip->height = rc.height;	switch (vp->fit) {	//covers all area and respect aspect ratio	case 2:		if (gf_divfix(rc.width, w) > gf_divfix(rc.height, h)) {			rc.width = gf_muldiv(rc.width , h, rc.height);			rc.height = h;		} else {			rc.height = gf_muldiv(rc.height , w, rc.width);			rc.width = w;		}		break;	//fits inside the area and respect AR	case 1:		if (gf_divfix(rc.width, w) > gf_divfix(rc.height, h)) {			rc.height = gf_muldiv(rc.height, w, rc.width);			rc.width = w;		} else {			rc.width = gf_muldiv(rc.width , h, rc.height);			rc.height = h;		}		break;	//fit entirely: nothing to change	case 0:		rc.width = w;		rc.height = h;		break;	default:		return;	}	sx = gf_divfix(rc.width, surf_clip->width);	sy = gf_divfix(rc.height, surf_clip->height);	surf_clip->width = rc.width;	surf_clip->height = rc.height;	surf_clip->x = - rc.width/2;	surf_clip->y = rc.height/2;	gf_mx2d_init(mat);	if (!vp->fit) {		gf_mx2d_add_scale(&mat, sx, sy);		gf_mx2d_add_matrix(&eff->transform, &mat);		return;	}	//setup x-alignment	switch (vp->alignment.vals[0]) {	//left align: 	case -1:		tx = rc.width/2 - w/2;		break;	//right align	case 1:		tx = w/2 - rc.width/2;		break;	//center	case 0:	default:		tx = 0;		break;	}	//setup y-alignment	switch (vp->alignment.vals[1]) {	//left align: 	case -1:		ty = rc.height/2 - h/2;		break;	//right align	case 1:		ty = h/2 - rc.height/2;		break;	//center	case 0:	default:		ty = 0;		break;	}	gf_mx2d_add_scale(&mat, sx, sy);	gf_mx2d_add_translation(&mat, tx, ty);	gf_mx2d_add_matrix(&eff->transform, &mat);	surf_clip->x += tx;	surf_clip->y += ty;}static void RenderNavigationInfo(GF_Node *node, void *rs, Bool is_destroy){	u32 i;	M_NavigationInfo *ni = (M_NavigationInfo *) node;	RenderEffect2D *eff = (RenderEffect2D *) rs;	if (is_destroy) return;	/*FIXME, we only deal with one node, no bind stack for the current time*/	for (i=0; i<ni->type.count; i++) {		if (ni->type.vals[i] && !stricmp(ni->type.vals[i], "NONE")) {			eff->surface->render->navigation_disabled = 1;		}	}}void R2D_InitNavigationInfo(Render2D *sr, GF_Node *node){	gf_node_set_callback_function(node, RenderNavigationInfo);}

⌨️ 快捷键说明

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