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

📄 geometry_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"/*		Shape */static void RenderShape(GF_Node *node, void *rs, Bool is_destroy){	RenderEffect2D *eff;	M_Shape *shape = (M_Shape *) node;	if (is_destroy ) return;	gf_node_dirty_clear(node, 0);	if (!shape->geometry) return;	eff = (RenderEffect2D *)rs;	if (eff->trav_flags & GF_SR_TRAV_SWITCHED_OFF) return;	eff->appear = (GF_Node *) shape->appearance;	gf_node_render((GF_Node *) shape->geometry, eff);	eff->appear = NULL;}void R2D_InitShape(Render2D *sr, GF_Node *node){	gf_node_set_callback_function(node, RenderShape);}static void RenderCircle(GF_Node *node, void *rs, Bool is_destroy){	DrawableContext *ctx;	Drawable *cs = (Drawable *)gf_node_get_private(node);	RenderEffect2D *eff = (RenderEffect2D *)rs;	if (is_destroy) {		DestroyDrawableNode(node);		return;	}	if (eff->traversing_mode==TRAVERSE_DRAW) {		drawable_draw(eff);		return;	}	else if (eff->traversing_mode==TRAVERSE_PICK) {		drawable_pick(eff);		return;	}		if (gf_node_dirty_get(node)) {		drawable_reset_path(cs);		gf_path_add_ellipse(cs->path, 0, 0, ((M_Circle *) node)->radius * 2, ((M_Circle *) node)->radius * 2);		gf_node_dirty_clear(node, 0);		cs->flags |= DRAWABLE_HAS_CHANGED;	}	ctx = drawable_init_context(cs, eff);	if (!ctx) return;		drawable_finalize_render(ctx, eff, NULL);}void R2D_InitCircle(Render2D *sr, GF_Node *node){	drawable_stack_new(sr, node);	gf_node_set_callback_function(node, RenderCircle);}static void RenderEllipse(GF_Node *node, void *rs, Bool is_destroy){	DrawableContext *ctx;	Drawable *cs = (Drawable *)gf_node_get_private(node);	RenderEffect2D *eff = (RenderEffect2D *)rs;	if (is_destroy) {		DestroyDrawableNode(node);		return;	}	if (eff->traversing_mode==TRAVERSE_DRAW) {		drawable_draw(eff);		return;	}	else if (eff->traversing_mode==TRAVERSE_PICK) {		drawable_pick(eff);		return;	}	if (gf_node_dirty_get(node)) {		drawable_reset_path(cs);		gf_path_add_ellipse(cs->path, 0, 0, ((M_Ellipse *) node)->radius.x, ((M_Ellipse *) node)->radius.y);		gf_node_dirty_clear(node, 0);		cs->flags |= DRAWABLE_HAS_CHANGED;	}	ctx = drawable_init_context(cs, eff);	if (!ctx) return;		drawable_finalize_render(ctx, eff, NULL);}void R2D_InitEllipse(Render2D  *sr, GF_Node *node){	drawable_stack_new(sr, node);	gf_node_set_callback_function(node, RenderEllipse);}static Bool txtrans_identity(GF_Node *appear){	if (!appear || !((M_Appearance*)appear)->textureTransform) return 1;	/*we could optimize, but let's assume that if a transform is used, it is not identity...*/	return 0;}void R2D_DrawRectangle(RenderEffect2D *eff){	DrawableContext *ctx = eff->ctx;	if (!ctx->h_texture || !ctx->h_texture->stream || ctx->transform.m[1] || ctx->transform.m[3] || !txtrans_identity(ctx->appear) ) {		VS2D_TexturePath(eff->surface, ctx->drawable->path, ctx);		VS2D_DrawPath(eff->surface, ctx->drawable->path, ctx, NULL, NULL);	} else {		GF_Rect unclip;		GF_IRect clip, unclip_pix;		u8 alpha = GF_COL_A(ctx->aspect.fill_color);		/*THIS IS A HACK, will not work when setting filled=0, transparency and XLineProps*/		if (!alpha) alpha = GF_COL_A(ctx->aspect.line_color);		/*get image size WITHOUT line size*/		gf_path_get_bounds(ctx->drawable->path, &unclip);		gf_mx2d_apply_rect(&ctx->transform, &unclip);		unclip_pix = clip = gf_rect_pixelize(&unclip);		gf_irect_intersect(&clip, &ctx->bi->clip);		/*direct rendering, render without clippers */		if (eff->surface->render->top_effect->trav_flags & TF_RENDER_DIRECT) {			eff->surface->DrawBitmap(eff->surface, ctx->h_texture, &clip, &unclip, alpha, NULL, ctx->col_mat);		}		/*render bitmap for all dirty rects*/		else {			u32 i;			GF_IRect a_clip;			for (i=0; i<eff->surface->to_redraw.count; i++) {				/*there's an opaque region above, don't draw*/#ifdef TRACK_OPAQUE_REGIONS				if (eff->surface->draw_node_index < eff->surface->to_redraw.opaque_node_index[i]) continue;#endif				a_clip = clip;				gf_irect_intersect(&a_clip, &eff->surface->to_redraw.list[i]);				if (a_clip.width && a_clip.height) {					eff->surface->DrawBitmap(eff->surface, ctx->h_texture, &a_clip, &unclip, alpha, NULL, ctx->col_mat);				}			}		}		ctx->flags |= CTX_PATH_FILLED;		VS2D_DrawPath(eff->surface, ctx->drawable->path, ctx, NULL, NULL);	}}static void RenderRectangle(GF_Node *node, void *reff, Bool is_destroy){	DrawableContext *ctx;	Drawable *rs = (Drawable *)gf_node_get_private(node);	RenderEffect2D *eff = (RenderEffect2D *)reff;	if (is_destroy) {		DestroyDrawableNode(node);		return;	}	if (eff->traversing_mode==TRAVERSE_DRAW) {		R2D_DrawRectangle(eff);		return;	}	else if (eff->traversing_mode==TRAVERSE_PICK) {		drawable_pick(eff);		return;	}	if (gf_node_dirty_get(node)) {		drawable_reset_path(rs);		gf_path_add_rect_center(rs->path, 0, 0, ((M_Rectangle *) node)->size.x, ((M_Rectangle *) node)->size.y);		gf_node_dirty_clear(node, 0);		rs->flags |= DRAWABLE_HAS_CHANGED;	}	ctx = drawable_init_context(rs, eff);	if (!ctx) return;		/*if alpha or not filled, transparent*/	if (GF_COL_A(ctx->aspect.fill_color) != 0xFF) {	} 	/*if texture transparent, transparent*/	else if (ctx->h_texture && ctx->h_texture->transparent) {	} 	/*if rotated, transparent (doesn't fill bounds)*/	else if (ctx->transform.m[1] || ctx->transform.m[3]) {	}	/*TODO check matrix for alpha*/	else if (!eff->color_mat.identity) {	}	/*otherwsie, not transparent*/	else {		ctx->flags &= ~CTX_IS_TRANSPARENT;		}	drawable_finalize_render(ctx, eff, NULL);}void R2D_InitRectangle(Render2D  *sr, GF_Node *node){	drawable_stack_new(sr, node);	gf_node_set_callback_function(node, RenderRectangle);}//#define CHECK_VALID_C2D(nbPts) if (cur_index+nbPts>=pt_count) { gd->path_reset(cs->path); return; }#define CHECK_VALID_C2D(nbPts)static void build_curve2D(Drawable *cs, M_Curve2D *c2D){	SFVec2f orig, ct_orig, ct_end, end;	u32 cur_index, i, remain, type_count, pt_count;	SFVec2f *pts;	M_Coordinate2D *coord = (M_Coordinate2D *)c2D->point;	pts = coord->point.vals;	if (!pts) 		return;	cur_index = c2D->type.count ? 1 : 0;	/*if the first type is a moveTo skip initial moveTo*/	i=0;	i=0;	if (cur_index) {		while (c2D->type.vals[i]==0) i++;	}	ct_orig = orig = pts[i];	gf_path_add_move_to(cs->path, orig.x, orig.y);	pt_count = coord->point.count;	type_count = c2D->type.count;	for (; i<type_count; i++) {		switch (c2D->type.vals[i]) {		/*moveTo, 1 point*/		case 0:			CHECK_VALID_C2D(0);			orig = pts[cur_index];			if (i) gf_path_add_move_to(cs->path, orig.x, orig.y);			cur_index += 1;			break;		/*lineTo, 1 point*/		case 1:			CHECK_VALID_C2D(0);			end = pts[cur_index];			gf_path_add_line_to(cs->path, end.x, end.y);			orig = end;			cur_index += 1;			break;		/*curveTo, 3 points*/		case 2:			CHECK_VALID_C2D(2);			ct_orig = pts[cur_index];			ct_end = pts[cur_index+1];			end = pts[cur_index+2];			gf_path_add_cubic_to(cs->path, ct_orig.x, ct_orig.y, ct_end.x, ct_end.y, end.x, end.y);			cur_index += 3;			ct_orig = ct_end;			orig = end;			break;		/*nextCurveTo, 2 points (cf spec)*/		case 3:			CHECK_VALID_C2D(1);			ct_orig.x = 2*orig.x - ct_orig.x;			ct_orig.y = 2*orig.y - ct_orig.y;			ct_end = pts[cur_index];			end = pts[cur_index+1];			gf_path_add_cubic_to(cs->path, ct_orig.x, ct_orig.y, ct_end.x, ct_end.y, end.x, end.y);			cur_index += 2;			ct_orig = ct_end;			orig = end;			break;				/*all XCurve2D specific*/		/*CW and CCW ArcTo*/		case 4:		case 5:			CHECK_VALID_C2D(2);			ct_orig = pts[cur_index];			ct_end = pts[cur_index+1];			end = pts[cur_index+2];			gf_path_add_arc_to(cs->path, end.x, end.y, ct_orig.x, ct_orig.y, ct_end.x, ct_end.y, (c2D->type.vals[i]==5) ? 1 : 0);			cur_index += 3;			ct_orig = ct_end;			orig = end;			break;		/*ClosePath*/		case 6:			gf_path_close(cs->path);			break;		/*quadratic CurveTo, 2 points*/		case 7:			CHECK_VALID_C2D(1);			ct_end = pts[cur_index];			end = pts[cur_index+1];			gf_path_add_quadratic_to(cs->path, ct_end.x, ct_end.y, end.x, end.y);			cur_index += 2;			ct_orig = ct_end;			orig = end;			break;		}	}	/*what's left is an N-bezier spline*/	if (pt_count > cur_index) {		/*first moveto*/		if (!cur_index) cur_index++;		remain = pt_count - cur_index;		if (remain>1)			gf_path_add_bezier(cs->path, &pts[cur_index], remain);	}}static void RenderCurve2D(GF_Node *node, void *rs, Bool is_destroy){

⌨️ 快捷键说明

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