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

📄 text.c

📁 一个用于智能手机的多媒体库适合S60 WinCE的跨平台开发库
💻 C
📖 第 1 页 / 共 2 页
字号:
	} else if (!strcmp(FSMAJOR, "END")) {		int_major = 1;	} else {		int_major = 2;	}	gf_rect_reset(&final);	for (i=0; i < txt->string.count; i++) {		switch (int_major) {		case 0:			if (FSTTB) 				start_y = lines[i].height/2;			else				start_y = -lines[i].height/2 + space;			break;		case 1:			if (FSTTB)				start_y = lines[i].height;			else				start_y = -lines[i].height + space;			break;		default:			if (FSTTB)				start_y = 0;			else				start_y = space;			break;		}		if (lines[i].length) {			TextLineEntry2D *tl = NewTextLine2D(eff->surface->render);			gf_list_add(st->text_lines, tl);			/*adjust horizontal offset on first column*/			if (!i) {				max_lw = 0;				for (k=0; k<lines[i].length; k++) {					letter[0] = lines[i].wcText[k];					/*get glyph width so that all letters are centered on the same vertical line*/					ft_dr->get_text_size(ft_dr, letter, &lw, &lh);					if (max_lw < lw) max_lw = lw;				}				st->bounds.width += max_lw/2;				start_x += max_lw/2;			}						for (k=0; k<lines[i].length; k++) {				letter[0] = lines[i].wcText[k];				/*get glyph width so that all letters are centered on the same vertical line*/				ft_dr->get_text_size(ft_dr, letter, &lw, &lh);				ft_dr->add_text_to_path(ft_dr, tl->path,  1, letter, start_x - lw/2, start_y, lines[i].x_scaling, gf_mulfix(lines[i].y_scaling,max_scale), st->ascent, &rc);				if (FSTTB)					start_y -= space;				else					start_y += space;			}			gf_path_get_bounds(tl->path, &rc);			gf_rect_union(&final, &rc);			TextLine_StoreBounds(tl);		}		if (FSLTR) {			start_x += line_spacing;		} else {			start_x -= line_spacing;		}		if (! eff->parent) {			rc = final;			gf_mx2d_apply_rect(&eff->transform, &rc);			if (FSLTR && (FIX2INT(rc.x) > eff->surface->top_clipper.x + eff->surface->top_clipper.width) ) {				break;			}			else if (!FSLTR && (FIX2INT(rc.x + rc.width) < eff->surface->top_clipper.x) ) {				break;			}		}		/*free unicode buffer*/		free(lines[i].wcText);	}	/*free remaining unicode buffers*/	for (; i < txt->string.count; i++) free(lines[i].wcText);	free(lines);	st->bounds.height = final.height;	st->bounds.y = final.y;}static void BuildTextGraph(TextStack2D *st, M_Text *txt, RenderEffect2D *eff){	TextLine2D *lines;	unsigned short wcTemp[5000];	u32 i, int_major, len, k;	Fixed fontSize, start_x, start_y, font_height, line_spacing, tot_width, tot_height, max_scale, tmp;	GF_Rect rc, final;	GF_FontRaster *ft_dr = eff->surface->render->compositor->font_engine;	M_FontStyle *fs = (M_FontStyle *)txt->fontStyle;	if (!FSHORIZ) {		BuildVerticalTextGraph(st, txt, eff);		return;	}	fontSize = FSSIZE;	if (fontSize <= 0) {		fontSize = INT2FIX(12);		if (!R2D_IsPixelMetrics((GF_Node *)txt)) fontSize = gf_divfix(fontSize, eff->surface->render->cur_width);    }	if (ft_dr->set_font(ft_dr, FSFAMILY, FSSTYLE) != GF_OK) {		if (ft_dr->set_font(ft_dr, NULL, NULL) != GF_OK) {			return;		}	}	ft_dr->set_font_size(ft_dr, fontSize);	ft_dr->get_font_metrics(ft_dr, &st->ascent, &st->descent, &font_height);	/*spacing= FSSPACING * (font_height) and fontSize not adjusted */	line_spacing = gf_mulfix(FSSPACE, fontSize);		tot_width = 0;	lines = (TextLine2D *) malloc(sizeof(TextLine2D)*txt->string.count);	memset(lines, 0, sizeof(TextLine2D)*txt->string.count);		for (i=0; i < txt->string.count; i++) {		char *str = txt->string.vals[i];		if (!str) continue;		lines[i].length = 0;		len = gf_utf8_mbstowcs(wcTemp, 5000, (const char **) &str);		if (len == (size_t) (-1)) continue;		lines[i].length = len;		lines[i].wcText = (u16*)malloc(sizeof(unsigned short) * (len+1));		if (!FSLTR) {			for (k=0; k<len; k++) lines[i].wcText[k] = wcTemp[len-k-1];		} else {			memcpy(lines[i].wcText, wcTemp, sizeof(unsigned short) * len);		}		lines[i].wcText[len] = (unsigned short) '\0';		lines[i].y_scaling = lines[i].x_scaling = FIX_ONE;		ft_dr->get_text_size(ft_dr, lines[i].wcText, &lines[i].width, &lines[i].height);		if (!lines[i].width) continue;		if ((txt->length.count>i) && (txt->length.vals[i]>0)) {			lines[i].x_scaling = gf_divfix(txt->length.vals[i], lines[i].width);		}		tmp = gf_mulfix(lines[i].width, lines[i].x_scaling);		if (tot_width < tmp) tot_width = tmp;	}		max_scale = FIX_ONE;	if ((txt->maxExtent > 0) && (tot_width>txt->maxExtent)) {		max_scale = gf_divfix(txt->maxExtent, tot_width);		tot_width = txt->maxExtent;	}	tot_height = (txt->string.count-1) * line_spacing + (st->ascent + st->descent);	st->bounds.height = tot_height;		if (!strcmp(FSMINOR, "MIDDLE")) {		if (FSTTB) {			start_y = tot_height/2;			st->bounds.y = start_y;		} else {			start_y = st->descent + st->ascent - tot_height/2;			st->bounds.y = tot_height/2;		}	}	else if (!strcmp(FSMINOR, "BEGIN")) {		if (FSTTB) {			start_y = st->descent;			start_y = 0;			st->bounds.y = start_y;		} else {			st->bounds.y = st->bounds.height;			start_y = st->descent + st->ascent;		}	}	else if (!strcmp(FSMINOR, "END")) {		if (FSTTB) {			start_y = tot_height;			st->bounds.y = start_y;		} else {			start_y = -tot_height + 2*st->descent + st->ascent;			st->bounds.y = start_y - (st->descent + st->ascent) + tot_height;		}	}	else {		start_y = st->ascent;		st->bounds.y = FSTTB ? start_y : (tot_height - st->descent);	}		/*major-justification*/	if (!strcmp(FSMAJOR, "MIDDLE") ) {		int_major = 0;	} else if (!strcmp(FSMAJOR, "END") ) {		int_major = 1;	} else {		int_major = 2;	}	gf_rect_reset(&final);	for (i=0; i < txt->string.count; i++) {		switch (int_major) {		/*major-justification MIDDLE*/		case 0:			start_x = -lines[i].width/2;			break;		/*major-justification END*/		case 1:			start_x = (FSLTR) ? -lines[i].width : 0;			break;		/*BEGIN, FIRST or default*/		default:			start_x = (FSLTR) ? 0 : -lines[i].width;			break;		}		if (lines[i].length) {			TextLineEntry2D *tl = NewTextLine2D(eff->surface->render);			/*if using the font engine the font is already configured*/			ft_dr->add_text_to_path(ft_dr, tl->path, 1, lines[i].wcText, start_x, start_y, gf_mulfix(lines[i].x_scaling,max_scale), lines[i].y_scaling, st->ascent, &rc);			gf_list_add(st->text_lines, tl);			TextLine_StoreBounds(tl);			gf_rect_union(&final, &rc);		}		if (FSTTB) {			start_y -= line_spacing;		} else {			start_y += line_spacing;		}		if (! eff->parent) {			rc = final;			gf_mx2d_apply_rect(&eff->transform, &rc);			if (FSTTB && (FIX2INT(rc.y) < eff->surface->top_clipper.y - eff->surface->top_clipper.height) ) {				break;			}			else if (! FSTTB && (FIX2INT(rc.y - rc.height) > eff->surface->top_clipper.y) ) {				break;			}		}		/*free unicode buffer*/		free(lines[i].wcText);	}	/*free remaining unicode buffers*/	for (; i < txt->string.count; i++) free(lines[i].wcText);	free(lines);	st->bounds.width = final.width;	st->bounds.x = final.x;}void Text2D_Draw(GF_Node *node, RenderEffect2D *eff){	u32 i;	Bool can_texture_text;	TextLineEntry2D *tl;	const char *fs_style;	char *hlight;	u32 hl_color;	DrawableContext *ctx = eff->ctx;	TextStack2D *st = (TextStack2D *) gf_node_get_private((GF_Node *) ctx->drawable->node);	M_FontStyle *fs = (M_FontStyle *) ((M_Text *) node)->fontStyle;	if (!GF_COL_A(ctx->aspect.fill_color) && !ctx->aspect.pen_props.width) return;	hl_color = 0;	fs_style = FSSTYLE;	hlight = strstr(fs_style, "HIGHLIGHT");	if (hlight) hlight = strchr(hlight, '#');	if (hlight) {		hlight += 1;		/*reverse video: highlighting uses the text color, and text color is inverted (except alpha channel)		the ideal impl would be to use the background color for the text, but since the text may be 		displayed over anything non uniform this would require clipping the highlight rect with the text		which is too onerous (and not supported anyway) */		if (!strnicmp(hlight, "RV", 2)) {			u32 a, r, g, b;			hl_color = ctx->aspect.fill_color;						a = GF_COL_A(ctx->aspect.fill_color);			if (a) {				r = GF_COL_R(ctx->aspect.fill_color);				g = GF_COL_G(ctx->aspect.fill_color);				b = GF_COL_B(ctx->aspect.fill_color);				ctx->aspect.fill_color = GF_COL_ARGB(a, 255-r, 255-g, 255-b);			}		} else {			sscanf(hlight, "%x", &hl_color);		}		if (GF_COL_A(hl_color) == 0) hl_color = 0;	}	if (strstr(fs_style, "TEXTURED")) st->texture_text_flag = 1;	/*text has been splited*/	if (ctx->sub_path_index > 0) {		tl = (TextLineEntry2D*)gf_list_get(st->text_lines, ctx->sub_path_index - 1);		if (!tl || !tl->path) return;		if (hl_color) VS2D_FillRect(eff->surface, ctx, &tl->bounds, hl_color, 0);		VS2D_TexturePath(eff->surface, tl->path, ctx);		VS2D_DrawPath(eff->surface, tl->path, ctx, NULL, NULL);		return;	}	can_texture_text = 0;	if ((st->compositor->texture_text_mode==GF_TEXTURE_TEXT_ALWAYS) || st->texture_text_flag) {		can_texture_text = !ctx->h_texture && !ctx->aspect.pen_props.width;	}	i=0;	while ((tl = (TextLineEntry2D*)gf_list_enum(st->text_lines, &i))) {		if (hl_color) VS2D_FillRect(eff->surface, ctx, &tl->bounds, hl_color, 0);		if (can_texture_text && TextLine2D_TextureIsReady(tl)) {			VS2D_TexturePathText(eff->surface, ctx, tl->tx_path, &tl->bounds, tl->hwtx, &tl->tx_bounds);		} else {			VS2D_TexturePath(eff->surface, tl->path, ctx);			VS2D_DrawPath(eff->surface, tl->path, ctx, NULL, NULL);		}		/*reset fill/strike flags since we perform several draw per context*/		ctx->flags &= ~CTX_PATH_FILLED;		ctx->flags &= ~CTX_PATH_STROKE;	}}static Bool Text2D_PointOver(DrawableContext *ctx, Fixed x, Fixed y, u32 check_type){	GF_Matrix2D inv;	u32 i;	TextLineEntry2D *tl;	TextStack2D *st;	/*this is not documented anywhere but it speeds things up*/	if (!check_type || GF_COL_A(ctx->aspect.fill_color) ) return 1;		st = (TextStack2D *) gf_node_get_private((GF_Node *) ctx->drawable->node);		gf_mx2d_copy(inv, ctx->transform);	gf_mx2d_inverse(&inv);	gf_mx2d_apply_coords(&inv, &x, &y);	/*otherwise get all paths*/	if (ctx->sub_path_index > 0) {		tl = (TextLineEntry2D*)gf_list_get(st->text_lines, ctx->sub_path_index - 1);		if (!tl || !tl->path) return 0;		return gf_path_point_over(tl->path, x, y);	}	i=0;	while ((tl = (TextLineEntry2D*)gf_list_enum(st->text_lines, &i))) {		if (!tl->path) return 0;		if (gf_path_point_over(tl->path, x, y)) return 1;	}	return 0;}static void Text_Render(GF_Node *n, void *rs, Bool is_destroy){	DrawableContext *ctx;	M_Text *txt = (M_Text *) n;	TextStack2D *st = (TextStack2D *) gf_node_get_private(n);	RenderEffect2D *eff = (RenderEffect2D *)rs;	if (is_destroy) {		TextStack2D_clean_paths(st);		drawable_del(st->graph);		gf_list_del(st->text_lines);		free(st);		return;	}	if (eff->traversing_mode==TRAVERSE_DRAW) {		Text2D_Draw(n, eff);		return;	}	else if (eff->traversing_mode==TRAVERSE_PICK) {		eff->is_over = Text2D_PointOver(eff->ctx, eff->x, eff->y, eff->pick_type);		return;	}	if (!st->compositor->font_engine) return;	if (!txt->string.count) return;	if (eff->text_split_mode == 2) {		split_text_letters(st, txt, eff);		return;	}	else if (eff->text_split_mode == 1) {		split_text_words(st, txt, eff);		return;	}	/*check for geometry change*/	if (gf_node_dirty_get(n)) {		TextStack2D_clean_paths(st);		BuildTextGraph(st, txt, eff);		gf_node_dirty_clear(n, 0);		st->graph->flags |= DRAWABLE_HAS_CHANGED;	}	/*get the text bounds*/	ctx = drawable_init_context(st->graph, eff);	if (!ctx) return;	ctx->flags |= CTX_IS_TEXT;	if (!GF_COL_A(ctx->aspect.fill_color)) {		/*override line join*/		ctx->aspect.pen_props.join = GF_LINE_JOIN_MITER;		ctx->aspect.pen_props.cap = GF_LINE_CAP_FLAT;	}	drawable_finalize_render(ctx, eff, &st->bounds);}void R2D_InitText(Render2D *sr, GF_Node *node){	TextStack2D *stack = (TextStack2D *)malloc(sizeof(TextStack2D));	stack->graph = drawable_new();	/*override all funct*/	stack->graph->node = node;	stack->ascent = stack->descent = 0;	stack->text_lines = gf_list_new();	stack->texture_text_flag = 0;	stack->compositor = sr->compositor;	gf_node_set_private(node, stack);	gf_node_set_callback_function(node, Text_Render);}static void RenderTextureText(GF_Node *node, void *rs, Bool is_destroy){	TextStack2D *stack;	GF_Node *text;	GF_FieldInfo field;	if (is_destroy) return;	if (gf_node_get_field(node, 0, &field) != GF_OK) return;	if (field.fieldType != GF_SG_VRML_SFNODE) return;	text = *(GF_Node **)field.far_ptr;	if (!text) return;	if (gf_node_get_field(node, 1, &field) != GF_OK) return;	if (field.fieldType != GF_SG_VRML_SFBOOL) return;	if (gf_node_get_tag(text) != TAG_MPEG4_Text) return;	stack = (TextStack2D *) gf_node_get_private(text);	stack->texture_text_flag = *(SFBool*)field.far_ptr ? 1 : 0;}void R2D_InitTextureText(Render2D *sr, GF_Node *node){	gf_node_set_callback_function(node, RenderTextureText);}

⌨️ 快捷键说明

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