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

📄 text.c

📁 一个用于智能手机的多媒体库适合S60 WinCE的跨平台开发库
💻 C
📖 第 1 页 / 共 3 页
字号:
/* *			GPAC - Multimedia Framework C SDK * *			Copyright (c) Jean Le Feuvre 2000-2005 *					All rights reserved * *  This file is part of GPAC / 3D 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 "render3d_nodes.h"#include "grouping.h"#include <gpac/utf.h>typedef struct{	GF_Node *owner;	GF_Renderer *compositor;	GF_Mesh *mesh;	Bool (*IntersectWithRay)(GF_Node *owner, GF_Ray *ray, SFVec3f *outPoint);	Bool (*ClosestFace)(GF_Node *owner, SFVec3f user_pos, Fixed min_dist, SFVec3f *outPoint);	GF_Path *path;	GF_List *strike_list;	Fixed ascent, descent;	GF_List *text_lines;	GF_Rect bounds;	Bool texture_text_flag;} TextStack;/*default value when no fontStyle*/#define FSFAMILY	(fs && fs->family.count) ? (const char *)fs->family.vals[0]	: ""/*here it's tricky since it depends on our metric system...*/#define FSSIZE		(fs ? fs->size : FIX_ONE)#define FSSTYLE		(fs && fs->style.buffer) ? (const char *)fs->style.buffer : ""#define FSMAJOR		( (fs && fs->justify.count && fs->justify.vals[0]) ? (const char *)fs->justify.vals[0] : "FIRST")#define FSMINOR		( (fs && (fs->justify.count>1) && fs->justify.vals[1]) ? (const char *)fs->justify.vals[1] : "FIRST")#define FSHORIZ		(fs ? fs->horizontal : 1)#define FSLTR		(fs ? fs->leftToRight : 1)#define FSTTB		(fs ? fs->topToBottom : 1)#define FSLANG		(fs ? fs->language : "")#define FSSPACE		(fs ? fs->spacing : FIX_ONE)typedef struct{	GF_Path *path;	GF_Path *outline;	GF_Mesh *mesh;	GF_Mesh *outline_mesh;	GF_Rect bounds;	/*for text texturing*/	GF_TextureHandler txh;	Render3D *sr;	/*RGBA data*/	char *tx_data;	/*a simple rectangle*/	GF_Mesh *tx_mesh;	Bool tx_ready;	u32 tx_width, tx_height;	Bool failed;	GF_Rect tx_bounds;} CachedTextLine;static CachedTextLine *new_text_line(Render3D *sr, GF_List *lines_register){	CachedTextLine *tl;	GF_SAFEALLOC(tl, CachedTextLine);	tl->path = gf_path_new();	/*text texturing enabled*/	tl->sr = sr;	memset(&tl->txh, 0, sizeof(GF_TextureHandler));	tl->txh.compositor = sr->compositor;	tl->txh.transparent = 1;	gf_list_add(lines_register, tl);	return tl;}static void delete_text_line(CachedTextLine *tl){	gf_path_del(tl->path);	if (tl->outline) gf_path_del(tl->outline);	if (tl->mesh) { mesh_free(tl->mesh); tl->mesh = NULL; }	if (tl->outline_mesh) { mesh_free(tl->outline_mesh); tl->outline_mesh = NULL; }	tx_delete(&tl->txh);	if (tl->tx_data) free(tl->tx_data);	if (tl->tx_mesh) mesh_free(tl->tx_mesh);	free(tl);}/*don't build too large textures*/#define MAX_TX_SIZE		512/*and don't build too small ones otherwise result is as crap as non-textured*/#define MIN_TX_SIZE		16Bool TextLine_TextureIsReady(CachedTextLine *tl){	GF_Matrix2D mx;	GF_STENCIL stenc;	GF_SURFACE surf;	Fixed cx, cy, sx, sy, max, min;	u32 tw, th;	GF_Err e;	Fixed scale;	GF_STENCIL texture2D;	GF_Raster2D *r2d = tl->sr->compositor->r2d;	if (tl->failed) return 0;	if (tl->tx_ready) {		if (!tl->sr->compositor->reset_graphics) goto exit;		tx_delete(&tl->txh);		if (tl->tx_mesh) mesh_free(tl->tx_mesh);		tl->tx_mesh = NULL;		if (tl->tx_data) free(tl->tx_data);		tl->tx_data = NULL;		tl->failed = 0;		tl->tx_ready = 0;	}	gf_path_get_bounds(tl->path, &tl->tx_bounds);	/*check not too big, but also not really small (meter metrics)*/	max = INT2FIX(MAX_TX_SIZE);	min = INT2FIX(MIN_TX_SIZE);	scale = FIX_ONE;	if ((gf_mulfix(scale, tl->tx_bounds.width)>max) || (gf_mulfix(scale, tl->tx_bounds.height)>max)) {		scale = MIN(gf_divfix(max, tl->tx_bounds.width), gf_divfix(max, tl->tx_bounds.height));	} 	else if ((gf_mulfix(scale, tl->tx_bounds.width)<min) || (gf_mulfix(scale, tl->tx_bounds.height)<min)) {		scale = MAX(gf_divfix(min, tl->tx_bounds.width), gf_divfix(min, tl->tx_bounds.height));	}	if (scale<FIX_ONE) scale = FIX_ONE;	/*get closest pow2 sizes*/	tw = FIX2INT( gf_ceil(gf_mulfix(scale,tl->tx_bounds.width)) );	tl->tx_width = MIN_TX_SIZE;	while (tl->tx_width<tw) {		if (tl->tx_width>=MAX_TX_SIZE) break;		tl->tx_width*=2;	}	th = FIX2INT( gf_ceil(gf_mulfix(scale, tl->tx_bounds.height)) );	tl->tx_height = MIN_TX_SIZE;	while (tl->tx_height<th) {		tl->tx_height*=2;		if (tl->tx_height>=MAX_TX_SIZE) break;	}	/*and get scaling*/	sx = gf_divfix( INT2FIX(tl->tx_width), tl->tx_bounds.width);	sy = gf_divfix( INT2FIX(tl->tx_height), tl->tx_bounds.height);	texture2D = r2d->stencil_new(r2d, GF_STENCIL_TEXTURE);	if (!texture2D) {		tl->failed = 1;		return 0;	}	surf = r2d->surface_new(r2d, 1);	if (!surf) {		r2d->stencil_delete(texture2D);		return 0;	}	tl->tx_data = (char *) malloc(sizeof(char)*tl->tx_width*tl->tx_height*4);	memset(tl->tx_data, 0, sizeof(char)*tl->tx_width*tl->tx_height*4);	/*FIXME - make it work with alphagrey...*/	e = r2d->stencil_set_texture(texture2D, tl->tx_data, tl->tx_width, tl->tx_height, 4*tl->tx_width, GF_PIXEL_ARGB, GF_PIXEL_ARGB, 1);	if (!e) e = r2d->surface_attach_to_texture(surf, texture2D);	stenc = r2d->stencil_new(r2d, GF_STENCIL_SOLID);	r2d->stencil_set_brush_color(stenc, 0xFF000000);	cx = tl->tx_bounds.x + tl->tx_bounds.width/2;	cy = tl->tx_bounds.y - tl->tx_bounds.height/2;	gf_mx2d_init(mx);	gf_mx2d_add_translation(&mx, -cx, -cy);//	gf_mx2d_add_scale(&mx, scale, -scale);	gf_mx2d_add_scale(&mx, sx, -sy);	r2d->surface_set_matrix(surf, &mx);	r2d->surface_set_raster_level(surf, GF_RASTER_HIGH_QUALITY);	r2d->surface_set_path(surf, tl->path);	r2d->surface_fill(surf, stenc);	r2d->stencil_delete(stenc);	r2d->surface_delete(surf);	r2d->stencil_delete(texture2D);	tl->tx_mesh = new_mesh();	mesh_set_vertex(tl->tx_mesh, tl->tx_bounds.x, tl->tx_bounds.y-tl->tx_bounds.height, 0, 0, 0, FIX_ONE, 0, 0);	mesh_set_vertex(tl->tx_mesh, tl->tx_bounds.x+tl->tx_bounds.width, tl->tx_bounds.y-tl->tx_bounds.height, 0, 0, 0, FIX_ONE, FIX_ONE, 0);	mesh_set_vertex(tl->tx_mesh, tl->tx_bounds.x+tl->tx_bounds.width, tl->tx_bounds.y, 0, 0, 0, FIX_ONE, FIX_ONE, FIX_ONE);	mesh_set_vertex(tl->tx_mesh, tl->tx_bounds.x, tl->tx_bounds.y, 0, 0, 0, FIX_ONE, 0, FIX_ONE);	mesh_set_triangle(tl->tx_mesh, 0, 1, 2);	mesh_set_triangle(tl->tx_mesh, 0, 2, 3);	tl->tx_mesh->flags |= MESH_IS_2D;	tl->tx_mesh->mesh_type = MESH_TRIANGLES;	mesh_update_bounds(tl->tx_mesh);	/*and setup the texture*/	tl->txh.width = tl->tx_width;	tl->txh.height = tl->tx_height;	tl->txh.stride = 4*tl->tx_width;	/*back to RGBA texturing*/	{		u32 i, j;		for (i=0; i<tl->tx_height; i++) {			char *data = tl->tx_data + i*tl->txh.stride;			for (j=0; j<tl->txh.width; j++) {				u32 val = *(u32 *) &data[4*j];				data[4*j] = (val>>16) & 0xFF;				data[4*j+1] = (val>>8) & 0xFF;				data[4*j+2] = (val) & 0xFF;				data[4*j+3] = (val>>24) & 0xFF;			}		}	}		tl->txh.data = tl->tx_data;	tl->txh.pixelformat = GF_PIXEL_RGBA;	if (!e) e = tx_allocate(&tl->txh);	if (e) {		tl->failed = 1;		mesh_free(tl->tx_mesh);		tl->tx_mesh = NULL;		free(tl->tx_data);		tl->tx_data = NULL;		return 0;	}	tx_set_blend_mode(&tl->txh, TX_BLEND);	tl->tx_ready = 1;exit:	R3D_SetTextureData(&tl->txh);	return 1;}static void clean_paths(TextStack *stack){	CachedTextLine *tl;	/*delete all path objects*/	while (gf_list_count(stack->text_lines)) {		tl = (CachedTextLine *)gf_list_get(stack->text_lines, 0);		gf_list_rem(stack->text_lines, 0);		delete_text_line(tl);	}	stack->bounds.width = stack->bounds.height = 0;}static Fixed get_font_size(M_FontStyle *fs, RenderEffect3D *eff){	Fixed fontSize = FSSIZE;	if (fontSize <= 0) {		fontSize = INT2FIX(12);		if (!eff->is_pixel_metrics) {			Fixed w, h;			R3D_GetSurfaceSizeInfo(eff, &w, &h);			fontSize = gf_divfix(fontSize, w);		}    }	return fontSize;}static void split_text_letters(TextStack *st, M_Text *txt, RenderEffect3D *eff){	CachedTextLine *tl;	unsigned short wcTemp[5000];	unsigned short letter[2];	u32 i, j, len;	Fixed fontSize, start_y, font_height, line_spacing;	GF_FontRaster *ft_r = st->compositor->font_engine;	M_FontStyle *fs = (M_FontStyle *)txt->fontStyle;	fontSize = get_font_size(fs, eff);	line_spacing = gf_mulfix(FSSPACE, fontSize);	if (ft_r->set_font(ft_r, FSFAMILY, FSSTYLE) != GF_OK) {		if (ft_r->set_font(ft_r, NULL, NULL) != GF_OK) {			return;		}	}	ft_r->set_font_size(ft_r, fontSize);	ft_r->get_font_metrics(ft_r, &st->ascent, &st->descent, &font_height);				if (!strcmp(FSMINOR, "MIDDLE")) {		start_y = (st->descent + st->ascent)/2;	}	else if (!strcmp(FSMINOR, "BEGIN")) {		start_y = st->descent;	}	else if (!strcmp(FSMINOR, "END")) {		start_y = st->descent + st->ascent;	}	else {		start_y = st->ascent;	}		st->bounds.width = st->bounds.height = 0;	for (i=0; i < txt->string.count; i++) {		char *str = txt->string.vals[i];		if (!str) continue;		len = gf_utf8_mbstowcs(wcTemp, 5000, (const char **) &str);		if (len == (size_t) (-1)) continue;		letter[1] = (unsigned short) 0;		for (j=0; j<len; j++) {			if (FSLTR) {				letter[0] = wcTemp[j];			} else {				letter[0] = wcTemp[len - j - 1];			}			tl = new_text_line(eff->surface->render, st->text_lines);			ft_r->add_text_to_path(ft_r, tl->path, 1, letter, 0, start_y, FIX_ONE, FIX_ONE, st->ascent, &tl->bounds);			tl->bounds.height = MAX(st->ascent + st->descent, tl->bounds.height);		}	}}static void split_text_words(TextStack *st, M_Text *txt, RenderEffect3D *eff){	CachedTextLine *tl;	unsigned short wcTemp[5000];	unsigned short letter[5000];	u32 i, j, len, k, first_char;	Fixed fontSize, font_height, line_spacing;	GF_Rect rc;	GF_FontRaster *ft_r = st->compositor->font_engine;	M_FontStyle *fs = (M_FontStyle *)txt->fontStyle;	fontSize = get_font_size(fs, eff);	line_spacing = gf_mulfix(FSSPACE, fontSize);	if (ft_r->set_font(ft_r, FSFAMILY, FSSTYLE) != GF_OK) {		if (ft_r->set_font(ft_r, NULL, NULL) != GF_OK) {			return;		}	}

⌨️ 快捷键说明

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