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

📄 grouping.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 "grouping.h"#include "visualsurface2d.h"#ifndef GPAC_DISABLE_SVG#include "svg_stacks.h"#endifstatic void child2d_compute_bounds(ChildGroup2D *cg){	u32 i, count;	Fixed a, d;	if (cg->bounds_forced) return;	cg->is_text_group = 1;	cg->ascent = cg->descent = 0;	gf_rect_reset(&cg->original);	count = gf_list_count(cg->contexts);	for (i=0; i<count; i++) {		void text2D_get_ascent_descent(DrawableContext *ctx, Fixed *a, Fixed *d);		DrawableContext *ctx = (DrawableContext *)gf_list_get(cg->contexts, i);		gf_rect_union(&cg->original, &ctx->bi->unclip);		if (!cg->is_text_group) continue;		if (! (ctx->flags & CTX_IS_TEXT) ) {			cg->is_text_group = 0;			continue;		}		text2D_get_ascent_descent(ctx, &a, &d);		if (a>cg->ascent) cg->ascent = a;		if (d>cg->descent) cg->descent = d;	}}void group2d_force_bounds(GroupingNode2D *group, GF_Rect *clip){	ChildGroup2D *cg;	if (!group || !clip) return;	cg = (ChildGroup2D *)gf_list_get(group->groups, gf_list_count(group->groups)-1);	if (!cg) return;	cg->ascent = cg->descent = 0;	cg->is_text_group = 0;	cg->original = *clip;	cg->final = cg->original;	cg->bounds_forced = 1;}void group2d_start_child(GroupingNode2D *group){	ChildGroup2D *cg;	GF_SAFEALLOC(cg, ChildGroup2D);	cg->contexts = gf_list_new();	gf_list_add(group->groups, cg);}void group2d_end_child(GroupingNode2D *group){	ChildGroup2D *cg = (ChildGroup2D *)gf_list_get(group->groups, gf_list_count(group->groups)-1);	if (!cg) return;	child2d_compute_bounds(cg);	cg->final = cg->original;}void group2d_reset_children(GroupingNode2D *group){	while (gf_list_count(group->groups)) {		ChildGroup2D *cg = (ChildGroup2D *)gf_list_get(group->groups, 0);		gf_list_rem(group->groups, 0);		gf_list_del(cg->contexts);		free(cg);	}}void group2d_add_to_context_list(GroupingNode2D *group, DrawableContext *ctx){	ChildGroup2D *cg = (ChildGroup2D *)gf_list_get(group->groups, gf_list_count(group->groups)-1);	if (!cg) return;	gf_list_add(cg->contexts, ctx);}/*	This is the generic routine for child traversing - note we are not duplicating the effect*/void group2d_traverse(GroupingNode2D *group, GF_ChildNodeItem *children, RenderEffect2D *eff){	GF_ChildNodeItem *l;	Bool split_text_backup;	u32 i, count2;	SensorHandler *hsens;	GF_List *sensors_backup = NULL;	/*rebuild sensor list */	if (gf_node_dirty_get(group->owner) & GF_SG_CHILD_DIRTY) {		/*reset*/		gf_list_reset(group->sensors);		/*special case for anchor which is a parent node acting as a sensor*/		if (gf_node_get_tag(group->owner)==TAG_MPEG4_Anchor) {			SensorHandler *r2d_anchor_get_handler(GF_Node *n);			hsens = r2d_anchor_get_handler(group->owner);			if (hsens) gf_list_add(group->sensors, hsens);		}		l = children;		while (l) {			if (l->node && is_sensor_node(l->node) ) {				hsens = get_sensor_handler(l->node);				/*only keep track of locally enabled sensors*/				if (hsens) gf_list_add(group->sensors, hsens);			}			l = l->next;		}	}	/*if we have an active sensor at this level discard all sensors in current render context (cf VRML)*/	count2 = gf_list_count(group->sensors);	if (count2) {		sensors_backup = eff->sensors;		eff->sensors = gf_list_new();			/*add sensor(s) to effects*/			for (i=0; i <count2; i++) {			SensorHandler *hsens = (SensorHandler *)gf_list_get(group->sensors, i);			effect_add_sensor(eff, hsens, &eff->transform);		}	}	gf_node_dirty_clear(group->owner, 0);	if (eff->parent == group) {		l = children;		while (l) {			group2d_start_child(group);			gf_node_render(l->node, eff);			group2d_end_child(group);			l = l->next;		}	} else {		split_text_backup = eff->text_split_mode;		l = children;		if (l && l->next) eff->text_split_mode = 0;		while (l) {			gf_node_render(l->node, eff);			l = l->next;		}		eff->text_split_mode = split_text_backup;	}	if (count2) {		/*destroy current effect list and restore previous*/		effect_reset_sensors(eff);		gf_list_del(eff->sensors);		eff->sensors = sensors_backup;	}}void gf_mx2d_apply_rect_int(GF_Matrix2D *mat, GF_IRect *rc){	GF_Rect rcft = gf_rect_ft(rc);	gf_mx2d_apply_rect(mat, &rcft);	*rc = gf_rect_pixelize(&rcft);}void child2d_render_done(ChildGroup2D *cg, RenderEffect2D *eff, GF_Rect *par_clipper){	GF_Matrix2D mat, loc_mx;	Fixed x, y, inv_min_hsize;	u32 i, count;	GF_Rect _clip;	GF_IRect clipper;	_clip = *par_clipper;	gf_mx2d_apply_rect(&eff->transform, &_clip);	clipper = gf_rect_pixelize(&_clip);	gf_mx2d_init(mat);	gf_mx2d_add_translation(&mat, cg->final.x - cg->original.x, cg->final.y - cg->original.y);	inv_min_hsize = gf_invfix(eff->min_hsize);	count = gf_list_count(cg->contexts);	for (i=0; i<count; i++) {		SensorContext *sc;		DrawableContext *ctx = (DrawableContext *)gf_list_get(cg->contexts, i);		drawable_check_bounds(ctx, eff->surface);		gf_mx2d_apply_coords(&mat, &ctx->bi->unclip.x, &ctx->bi->unclip.y);		x = INT2FIX(ctx->bi->clip.x);		y = INT2FIX(ctx->bi->clip.y);		gf_mx2d_apply_coords(&mat, &x, &y);		ctx->bi->clip.x = FIX2INT(gf_floor(x));		ctx->bi->clip.y = FIX2INT(gf_ceil(y));		gf_mx2d_add_matrix(&ctx->transform, &mat);		if (!eff->is_pixel_metrics) gf_mx2d_add_scale(&ctx->transform, inv_min_hsize, inv_min_hsize);		gf_mx2d_add_matrix(&ctx->transform, &eff->transform);		sc = ctx->sensor;		while (sc) {			if (!eff->is_pixel_metrics) gf_mx2d_add_scale(&sc->matrix, inv_min_hsize, inv_min_hsize);			gf_mx2d_add_matrix(&sc->matrix, &eff->transform);			sc = sc->next;		}		gf_mx2d_init(loc_mx);		if (!eff->is_pixel_metrics) gf_mx2d_add_scale(&loc_mx, inv_min_hsize, inv_min_hsize);		gf_mx2d_add_matrix(&loc_mx, &eff->transform);		gf_mx2d_apply_rect(&loc_mx, &ctx->bi->unclip);		gf_mx2d_apply_rect_int(&loc_mx, &ctx->bi->clip);		gf_irect_intersect(&ctx->bi->clip, &clipper);		drawable_finalize_end(ctx, eff);	}}void child2d_render_done_complex(ChildGroup2D *cg, RenderEffect2D *eff, GF_Matrix2D *mat){	u32 i, count;	count = gf_list_count(cg->contexts);	for (i=0; i<count; i++) {		SensorContext *sc;		DrawableContext *ctx = (DrawableContext *)gf_list_get(cg->contexts, i);		drawable_check_bounds(ctx, eff->surface);		if (!mat) {			gf_rect_reset(&ctx->bi->clip);			gf_rect_reset(&ctx->bi->unclip);			continue;		}		gf_mx2d_add_matrix(&ctx->transform, mat);		gf_mx2d_add_matrix(&ctx->transform, &eff->transform);		sc = ctx->sensor;		while (sc) {			gf_mx2d_add_matrix(&sc->matrix, &eff->transform);			sc = sc->next;		}		gf_mx2d_apply_rect(&ctx->transform, &ctx->bi->unclip);		gf_mx2d_apply_rect_int(&ctx->transform, &ctx->bi->clip);		drawable_finalize_end(ctx, eff);	}}void SetupGroupingNode2D(GroupingNode2D *group, Render2D *sr, GF_Node *node){	memset(group, 0, sizeof(GroupingNode2D));	gf_sr_traversable_setup(group, node, sr->compositor);	group->sensors = gf_list_new();	group->groups = gf_list_new();}void DeleteGroupingNode2D(GroupingNode2D *group){	/*just in case*/	group2d_reset_children(group);	gf_list_del(group->sensors);	group2d_reset_children(group);	gf_list_del(group->groups);}void DestroyBaseGrouping2D(GF_Node *node){	GroupingNode2D *group = (GroupingNode2D *)gf_node_get_private(node);	DeleteGroupingNode2D(group);	free(group);}

⌨️ 快捷键说明

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