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

📄 ft_font.c

📁 一个用于智能手机的多媒体库适合S60 WinCE的跨平台开发库
💻 C
📖 第 1 页 / 共 2 页
字号:
		return GF_OK;	}	if (fontName) {		/*font not on system...*/		gf_modules_set_option((GF_BaseInterface *)dr, "FontEngine", fname, "UNKNOWN");		if (!styles) {			/*remove cache if default fonts not found*/			if (!OrigFontName || !stricmp(OrigFontName, "SERIF")) {				gf_modules_set_option((GF_BaseInterface *)dr, "FontEngine", "FontSerif", NULL);				strcpy(ftpriv->font_serif, "");			}			else if (!stricmp(OrigFontName, "SANS")) {				gf_modules_set_option((GF_BaseInterface *)dr, "FontEngine", "FontSans", NULL);				strcpy(ftpriv->font_sans, "");			}			else if (!stricmp(OrigFontName, "TYPEWRITTER")) {				gf_modules_set_option((GF_BaseInterface *)dr, "FontEngine", "FontFixed", NULL);				strcpy(ftpriv->font_fixed, "");			}		}	}	GF_LOG(GF_LOG_WARNING, GF_LOG_PARSER, ("[FreeType] Font not found\n"));	return GF_NOT_SUPPORTED;}static GF_Err ft_set_font_size(GF_FontRaster *dr, Fixed pixel_size){	FTBuilder *ftpriv = (FTBuilder *)dr->priv;	if (!ftpriv->active_face || !pixel_size) return GF_BAD_PARAM;	ftpriv->pixel_size = pixel_size;	return GF_OK;}static GF_Err ft_get_font_metrics(GF_FontRaster *dr, Fixed *ascent, Fixed *descent, Fixed *lineSpacing){	FTBuilder *ftpriv = (FTBuilder *)dr->priv;	if (!ftpriv->active_face || !ftpriv->pixel_size) return GF_BAD_PARAM;	*ascent = (ftpriv->pixel_size / ftpriv->active_face->units_per_EM) * ftpriv->active_face->ascender;	*descent = - (ftpriv->pixel_size / ftpriv->active_face->units_per_EM) * ftpriv->active_face->descender;	*lineSpacing = (ftpriv->pixel_size / ftpriv->active_face->units_per_EM) * ftpriv->active_face->height;	return GF_OK;}static GF_Err ft_get_text_size(GF_FontRaster *dr, const unsigned short *string, Fixed *width, Fixed *height){	u32 i, count, glyph_idx, w, h;	FT_Glyph glyph;	FT_BBox bbox;	FTBuilder *ftpriv = (FTBuilder *)dr->priv;	if (!ftpriv->active_face || !ftpriv->pixel_size) return GF_BAD_PARAM;	FT_Select_Charmap(ftpriv->active_face, FT_ENCODING_UNICODE);	count = gf_utf8_wcslen(string);	if (count == (size_t) (-1)) return GF_BAD_PARAM;	w = h = 0;	for (i=0; i<count; i++) {		glyph_idx = FT_Get_Char_Index(ftpriv->active_face, string[i]);		/*missing glyph*/		if (!glyph_idx) continue;		/*work in design units*/		FT_Load_Glyph(ftpriv->active_face, glyph_idx, FT_LOAD_NO_SCALE | FT_LOAD_NO_BITMAP);		FT_Get_Glyph(ftpriv->active_face->glyph, &glyph);		FT_Glyph_Get_CBox(glyph, ft_glyph_bbox_unscaled, &bbox);				if (h < (u32) (bbox.yMax - bbox.yMin)) h = (bbox.yMax - bbox.yMin);		if (!i) w = -1 * bbox.xMin;		if (i+1<count) {			w += ftpriv->active_face->glyph->metrics.horiAdvance;		} else {			w += bbox.xMax;		}		FT_Done_Glyph(glyph);	}	/*convert to font size*/	*width = (ftpriv->pixel_size / ftpriv->active_face->units_per_EM) * w;	*height = (ftpriv->pixel_size / ftpriv->active_face->units_per_EM) * h;	return GF_OK;}typedef struct{//	Fixed font_scale;	Fixed top;	Fixed pos_x;	FTBuilder *ftpriv;	GF_Path *path;	Fixed x_scale, y_scale;	Fixed last_x, last_y;} ft_outliner;#define GETX(_x) (ftol->pos_x + gf_mulfix(ftol->x_scale, INT2FIX(_x)))#define GETY(_y) (ftol->top + gf_mulfix(ftol->y_scale, INT2FIX(_y)))/*	this is not explicit in FreeType doc, i assume each line/curve ending at last moveTo	shall be closed*/int ft_move_to(FT_Vector *to, void *user){	Fixed x, y;	ft_outliner *ftol = (ft_outliner *)user;	x = GETX(to->x);	y = GETY(to->y);	gf_path_add_move_to(ftol->path, x, y);	ftol->last_x = x;	ftol->last_y = y;	return 0;}int ft_line_to(FT_Vector *to, void *user){	Fixed x, y;	ft_outliner *ftol = (ft_outliner *)user;	x = GETX(to->x);	y = GETY(to->y);	if ( (ftol->last_x == x) && (ftol->last_y == y)) {		gf_path_close(ftol->path);	} else {		gf_path_add_line_to(ftol->path, x, y);	}	return 0;}int ft_conic_to(FT_Vector * control, FT_Vector *to, void *user){	Fixed x, y, cx, cy;	ft_outliner *ftol = (ft_outliner *)user;	cx = GETX(control->x);	cy = GETY(control->y);	x = GETX(to->x);	y = GETY(to->y);	gf_path_add_quadratic_to(ftol->path, cx, cy, x, y);	if ( (ftol->last_x == x) && (ftol->last_y == y)) gf_path_close(ftol->path);	return 0;}int ft_cubic_to(FT_Vector *control1, FT_Vector *control2, FT_Vector *to, void *user){	Fixed x, y, c1x, c1y, c2x, c2y;	ft_outliner *ftol = (ft_outliner *)user;	c1x = GETX(control1->x);	c1y = GETY(control1->y);	c2x = GETX(control2->x);	c2y = GETY(control2->y);	x = GETX(to->x);	y = GETY(to->y);	gf_path_add_cubic_to(ftol->path, c1x, c1y, c1x, c1y, x, y);	if ( (ftol->last_x == x) && (ftol->last_y == y)) gf_path_close(ftol->path);	return 0;}static GF_Err ft_add_text_to_path(GF_FontRaster *dr, GF_Path *path, Bool flipText,					const unsigned short *string, Fixed left, Fixed top, Fixed x_scaling, Fixed y_scaling, 					Fixed ascent, GF_Rect *bounds){	u32 i, count, glyph_idx;	Fixed def_inc_x, font_scale;	s32 ymin, ymax;	FT_BBox bbox;	FT_OutlineGlyph outline;	ft_outliner outl;	FT_Outline_Funcs ft_outl_funcs;	FTBuilder *ftpriv = (FTBuilder *)dr->priv;	if (!ftpriv->active_face || !ftpriv->pixel_size) return GF_BAD_PARAM;	FT_Select_Charmap(ftpriv->active_face, FT_ENCODING_UNICODE);	/*setup outliner*/	ft_outl_funcs.shift = 0;	ft_outl_funcs.delta = 0;	ft_outl_funcs.move_to = ft_move_to;	ft_outl_funcs.line_to = ft_line_to;	ft_outl_funcs.conic_to = ft_conic_to;	ft_outl_funcs.cubic_to = ft_cubic_to;	/*units per EM are 24.6 fixed point in freetype, consider them as integers (no risk of overflow)*/	font_scale = ftpriv->pixel_size / ftpriv->active_face->units_per_EM;	outl.path = path;	outl.ftpriv = ftpriv;		outl.x_scale = gf_mulfix(x_scaling, font_scale);	outl.y_scale = gf_mulfix(y_scaling, font_scale);	if (!flipText) outl.y_scale *= -1;		bounds->x = outl.pos_x = gf_mulfix(left, x_scaling);	if (flipText) 		bounds->y = outl.top = gf_mulfix(top - ascent, y_scaling);	else 		bounds->y = outl.top = gf_mulfix(top, y_scaling);	/*same remark as above*/	def_inc_x = ftpriv->active_face->max_advance_width * outl.x_scale;	/*TODO: reverse layout (for arabic fonts) and glyph substitution / ligature once openType is in place in freetype*/	bounds->height = 0;	count = gf_utf8_wcslen(string);	if (count == (size_t) (-1)) return GF_BAD_PARAM;	ymin = ymax	= 0;	for (i=0; i<count; i++) {		glyph_idx = FT_Get_Char_Index(ftpriv->active_face, string[i]);		/*missing glyph*/		if (!glyph_idx) continue;		/*work in design units*/		FT_Load_Glyph(ftpriv->active_face, glyph_idx, FT_LOAD_NO_SCALE | FT_LOAD_NO_BITMAP);		FT_Get_Glyph(ftpriv->active_face->glyph, (FT_Glyph*)&outline);#ifdef FT_GLYPH_FORMAT_OUTLINE		/*oops not vectorial...*/		if (outline->root.format != FT_GLYPH_FORMAT_OUTLINE) {			outl.pos_x += def_inc_x;			FT_Done_Glyph((FT_Glyph) outline);			continue;		}#endif		/*freeType is marvelous and gives back the right advance on space char !!!*/	    FT_Outline_Decompose(&outline->outline, &ft_outl_funcs, &outl);		FT_Glyph_Get_CBox((FT_Glyph) outline, ft_glyph_bbox_unscaled, &bbox);				if (ymax < bbox.yMax ) ymax = bbox.yMax ;		if (ymin > bbox.yMin) ymin = bbox.yMin;		/*update start of bounding box on first char*/		if (!i) bounds->x += bbox.xMin * outl.x_scale;		/*take care of last char (may be AFTER last horiz_advanced with certain glyphs)*/		if ((i+1==count) && (bbox.xMax)) {			outl.pos_x += bbox.xMax * outl.x_scale;		} else {			outl.pos_x += ftpriv->active_face->glyph->metrics.horiAdvance * outl.x_scale;		}		FT_Done_Glyph((FT_Glyph) outline);	}	bounds->width = outl.pos_x - bounds->x;	bounds->height = (ymax - ymin) * outl.y_scale;	bounds->y = ymax * outl.y_scale;	if (!bounds->height && count) bounds->height = FIX_ONE/1000;	/*add underline/strikeout*/	if (ftpriv->strike_style) {		Fixed sy;		if (ftpriv->strike_style==1) {			sy = top - ascent + ftpriv->active_face->underline_position * font_scale;		} else {			sy = top - 3 * ascent / 4;		}		gf_path_add_rect_center(path, bounds->x + bounds->width / 2, sy, bounds->width, ftpriv->active_face->underline_thickness * font_scale);	}	return GF_OK;}GF_FontRaster *FT_Load(){	GF_FontRaster *dr;	FTBuilder *ftpriv;	dr = malloc(sizeof(GF_FontRaster));	memset(dr, 0, sizeof(GF_FontRaster));	GF_REGISTER_MODULE_INTERFACE(dr, GF_FONT_RASTER_INTERFACE, "FreeType Font Engine", "gpac distribution");	ftpriv = malloc(sizeof(FTBuilder));	memset(ftpriv, 0, sizeof(FTBuilder));	ftpriv->loaded_fonts = gf_list_new();	dr->priv = ftpriv;		dr->init_font_engine = ft_init_font_engine;	dr->shutdown_font_engine = ft_shutdown_font_engine;	dr->set_font = ft_set_font;	dr->set_font_size = ft_set_font_size;	dr->get_font_metrics = ft_get_font_metrics;	dr->get_text_size = ft_get_text_size;	dr->add_text_to_path = ft_add_text_to_path;	return dr;}void FT_Delete(GF_BaseInterface *ifce){	GF_FontRaster *dr = (GF_FontRaster *) ifce;	FTBuilder *ftpriv = dr->priv;	if (ftpriv->font_dir) free(ftpriv->font_dir);	assert(!gf_list_count(ftpriv->loaded_fonts) );	gf_list_del(ftpriv->loaded_fonts);	free(dr->priv);	free(dr);}#ifndef GPAC_STANDALONE_RENDER_2DGF_EXPORTBool QueryInterface(u32 InterfaceType) {	if (InterfaceType == GF_FONT_RASTER_INTERFACE) return 1;	return 0;}GF_EXPORTGF_BaseInterface *LoadInterface(u32 InterfaceType) {	if (InterfaceType == GF_FONT_RASTER_INTERFACE) return (GF_BaseInterface *)FT_Load();	return NULL;}GF_EXPORTvoid ShutdownInterface(GF_BaseInterface *ifce){	switch (ifce->InterfaceType) {	case GF_FONT_RASTER_INTERFACE:		FT_Delete(ifce);		break;	}}#endif

⌨️ 快捷键说明

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