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

📄 ft_font.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 / FreeType font engine 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 <gpac/modules/font.h>#include <gpac/list.h>#include <gpac/utf.h>#include <gpac/tools.h>#include <ft2build.h>#include FT_FREETYPE_H#include FT_GLYPH_H#include FT_OUTLINE_H/*TrueType tables*/#include FT_TRUETYPE_TABLES_H typedef struct{	FT_Library library;	FT_Face active_face;	char *font_dir;	Fixed pixel_size;	GF_List *loaded_fonts;	/*0: no line, 1: underlined, 2: strikeout*/	u32 strike_style;	Bool register_font;	/*temp storage for enum - may be NULL*/	const char *tmp_font_name;	const char *tmp_font_style;	/*default fonts*/	char font_serif[1024];	char font_sans[1024];	char font_fixed[1024];} FTBuilder;static GF_Err ft_init_font_engine(GF_FontRaster *dr){	const char *sOpt;	FTBuilder *ftpriv = (FTBuilder *)dr->priv;	sOpt = gf_modules_get_option((GF_BaseInterface *)dr, "FontEngine", "FontDirectory");	if (!sOpt) return GF_BAD_PARAM;	/*inits freetype*/	if (FT_Init_FreeType(&ftpriv->library) ) {		GF_LOG(GF_LOG_ERROR, GF_LOG_PARSER, ("[FreeType] Cannot initialize FreeType\n"));		return GF_IO_ERR;	}	/*remove the final delimiter*/    ftpriv->font_dir = strdup(sOpt);	while ( (ftpriv->font_dir[strlen(ftpriv->font_dir)-1] == '\n') || (ftpriv->font_dir[strlen(ftpriv->font_dir)-1] == '\r') )		ftpriv->font_dir[strlen(ftpriv->font_dir)-1] = 0;	/*store font path*/	if (ftpriv->font_dir[strlen(ftpriv->font_dir)-1] != GF_PATH_SEPARATOR) {		char ext[2], *temp;		ext[0] = GF_PATH_SEPARATOR;		ext[1] = 0;		temp = malloc(sizeof(char) * (strlen(ftpriv->font_dir) + 2));		strcpy(temp, ftpriv->font_dir);		strcat(temp, ext);		free(ftpriv->font_dir);		ftpriv->font_dir = temp;	}	sOpt = gf_modules_get_option((GF_BaseInterface *)dr, "FontEngine", "FontSerif");	if (sOpt) strcpy(ftpriv->font_serif, sOpt);	sOpt = gf_modules_get_option((GF_BaseInterface *)dr, "FontEngine", "FontSans");	if (sOpt) strcpy(ftpriv->font_sans, sOpt);		sOpt = gf_modules_get_option((GF_BaseInterface *)dr, "FontEngine", "FontFixed");	if (sOpt) strcpy(ftpriv->font_fixed, sOpt);	GF_LOG(GF_LOG_DEBUG, GF_LOG_PARSER, ("[FreeType] Init OK - font directory %s\n", ftpriv->font_dir));		return GF_OK;}GF_Err ft_shutdown_font_engine(GF_FontRaster *dr){	FTBuilder *ftpriv = (FTBuilder *)dr->priv;	ftpriv->active_face = NULL;	/*reset loaded fonts*/	while (gf_list_count(ftpriv->loaded_fonts)) {		FT_Face face = gf_list_get(ftpriv->loaded_fonts, 0);		gf_list_rem(ftpriv->loaded_fonts, 0);		FT_Done_Face(face);	}	/*exit FT*/	if (ftpriv->library) FT_Done_FreeType(ftpriv->library);	ftpriv->library = NULL;	return GF_OK;}static Bool ft_check_face(FT_Face font, const char *fontName, const char *styles){	Bool ret;	char *ft_name;	char *ft_style;	if (fontName && stricmp(font->family_name, fontName)) return 0;	ft_style = strdup(font->style_name);	strupr(ft_style);	if (!styles) {		ret = 1;		if (strstr(ft_style, "BOLD") || strstr(ft_style, "ITALIC") ) ret = 0;		free(ft_style);		return ret;	}	ft_name = strdup(font->family_name);	strupr(ft_name);	if (strstr(styles, "BOLDITALIC") ) {		if (!strstr(ft_name, "BOLD") && !strstr(ft_style, "BOLD") ) {			free(ft_name);			free(ft_style);			return 0;		}		if (!strstr(ft_name, "ITALIC") && !strstr(ft_style, "ITALIC") ) {			free(ft_name);			free(ft_style);			return 0;		}	}	else if (strstr(styles, "BOLD")) {		if (!strstr(ft_name, "BOLD") && !strstr(ft_style, "BOLD") ) {			free(ft_name);			free(ft_style);			return 0;		}		if (strstr(ft_style, "ITALIC")) {			free(ft_name);			free(ft_style);			return 0;		}	}	else if (strstr(styles, "ITALIC")) {		if (!strstr(ft_name, "ITALIC") && !strstr(ft_style, "ITALIC")) {			free(ft_name);			free(ft_style);			return 0;		}		if (strstr(ft_style, "BOLD")) {			free(ft_name);			free(ft_style);			return 0;		}	}	else if (strstr(ft_name, "ITALIC") || strstr(ft_style, "ITALIC") || strstr(ft_name, "BOLD") || strstr(ft_style, "BOLD") ) {		free(ft_name);		free(ft_style);		return 0;	}	/*looks good, let's use this one*/	free(ft_name);	free(ft_style);	return 1;}static FT_Face ft_font_in_cache(FTBuilder *ft, const char *fontName, const char *styles){	u32 i=0;	FT_Face font;	while ((font = gf_list_enum(ft->loaded_fonts, &i))) {		if (ft_check_face(font, fontName, styles)) return font;	}	return NULL;}static Bool ft_enum_fonts(void *cbck, char *file_name, char *file_path){	FT_Face face;	u32 num_faces, i;	GF_FontRaster *dr = cbck;	FTBuilder *ftpriv = dr->priv;	GF_LOG(GF_LOG_DEBUG, GF_LOG_PARSER, ("[FreeType] Enumerating font %s (%s)\n", file_name, file_path));	if (FT_New_Face(ftpriv->library, file_path, 0, & face )) return 0;	if (!face) return 0;	num_faces = face->num_faces;	/*locate right font in collection if several*/	for (i=0; i<num_faces; i++) {		if (ft_check_face(face, ftpriv->tmp_font_name ? ftpriv->tmp_font_name : face->family_name, ftpriv->tmp_font_style)) 			break;				FT_Done_Face(face);		if (i+1==num_faces) return 0;		/*load next font in collection*/		if (FT_New_Face(ftpriv->library, file_path, i+1, & face )) return 0;		if (!face) return 0;	}	/*reject font if not scalablebitmap glyphs*/	if (! (face->face_flags & FT_FACE_FLAG_SCALABLE)) {		FT_Done_Face(face);		return 0;	}	/*OK store in cache*/	gf_list_add(ftpriv->loaded_fonts, face);	ftpriv->active_face = face;	GF_LOG(GF_LOG_DEBUG, GF_LOG_PARSER, ("[FreeType] Found font %s in directory %s\n", file_name, file_path));	/*and store entry in cfg file*/	if (ftpriv->register_font) {		char szFont[GF_MAX_PATH];		strcpy(szFont, face->family_name);		if (ftpriv->tmp_font_style && strstr(ftpriv->tmp_font_style, "BOLD") && strstr(ftpriv->tmp_font_style, "ITALIC")) {			strcat(szFont, " Bold Italic");		} else if (ftpriv->tmp_font_style && strstr(ftpriv->tmp_font_style, "BOLD") ) {			strcat(szFont, " Bold");		} else if (ftpriv->tmp_font_style && strstr(ftpriv->tmp_font_style, "ITALIC") ) {			strcat(szFont, " Italic");		}		gf_modules_set_option((GF_BaseInterface *)dr, "FontEngine", szFont, file_path);	}	return 1;}static Bool ft_enum_fonts_dir(void *cbck, char *file_name, char *file_path){	Bool ret = gf_enum_directory(file_path, 0, ft_enum_fonts, cbck, "ttf;ttc");	if (ret) return 1;	return gf_enum_directory(file_path, 1, ft_enum_fonts_dir, cbck, NULL);}static GF_Err ft_set_font(GF_FontRaster *dr, const char *OrigFontName, const char *styles){	char fname[1024];	char *fontName;	Bool check_def_fonts = 0;	FTBuilder *ftpriv = (FTBuilder *)dr->priv;	fontName = (char *) OrigFontName;	ftpriv->active_face = NULL;	ftpriv->strike_style = 0;	if (styles && strstr(styles, "UNDERLINE")) ftpriv->strike_style = 1;	else if (styles && strstr(styles, "STRIKE")) ftpriv->strike_style = 2;	if (!fontName || !strlen(fontName) || !stricmp(fontName, "SERIF")) {		fontName = ftpriv->font_serif;		check_def_fonts = 1;	}	else if (!stricmp(fontName, "SANS") || !stricmp(fontName, "sans-serif")) {		fontName = ftpriv->font_sans;		check_def_fonts = 1;	}	else if (!stricmp(fontName, "TYPEWRITER") || !stricmp(fontName, "monospace")) {		fontName = ftpriv->font_fixed;		check_def_fonts = 1;	}	if (styles && (!stricmp(styles, "PLAIN") || !stricmp(styles, "REGULAR"))) styles = NULL;	GF_LOG(GF_LOG_DEBUG, GF_LOG_PARSER, ("[FreeType] Setting current font to %s (styles %s)\n", fontName, styles));	/*first look in loaded fonts*/	ftpriv->active_face = ft_font_in_cache(ftpriv, fontName, styles);	if (ftpriv->active_face) return GF_OK;	ftpriv->tmp_font_name = fontName;	ftpriv->tmp_font_style = styles;	ftpriv->register_font = 0;	/*check cfg file - freetype is slow at loading fonts so we keep the (font name + styles)=fontfile associations	in the cfg file*/	if (fontName && strlen(fontName)) {		const char *opt;		strcpy(fname, fontName);		if (styles && strstr(styles, "BOLD") && strstr(styles, "ITALIC")) {			strcat(fname, " Bold Italic");		}		else if (styles && strstr(styles, "BOLD")) {			strcat(fname, " Bold");		}		else if (styles && strstr(styles, "ITALIC")) {			strcat(fname, " Italic");		}		opt = gf_modules_get_option((GF_BaseInterface *)dr, "FontEngine", fname);		if (opt) {			char *font_name;			if (!stricmp(opt, "UNKNOWN")) return GF_NOT_SUPPORTED;			font_name = strrchr(opt, '/');			if (!font_name) font_name = strrchr(opt, '\\');			if (font_name && ft_enum_fonts(dr, font_name+1, (char *)opt)) return GF_OK;		}	}	GF_LOG(GF_LOG_DEBUG, GF_LOG_PARSER, ("[FreeType] Looking for fonts in %s\n", ftpriv->font_dir));	/*not found, browse all fonts*/	ftpriv->register_font = 1;	if (!strlen(ftpriv->tmp_font_name)) ftpriv->tmp_font_name = NULL;	gf_enum_directory(ftpriv->font_dir, 0, ft_enum_fonts, dr, "ttf;ttc");	if (!ftpriv->active_face) 		gf_enum_directory(ftpriv->font_dir, 1, ft_enum_fonts_dir, dr, NULL);	ftpriv->register_font = 0;	if (ftpriv->active_face) {		if (check_def_fonts) {			/*reassign default - they may be wrong, but this will avoid future browsing*/			if (!ftpriv->font_serif[0] && (!OrigFontName || !stricmp(OrigFontName, "SERIF")) ) {				gf_modules_set_option((GF_BaseInterface *)dr, "FontEngine", "FontSerif", ftpriv->active_face->family_name);				strcpy(ftpriv->font_serif, ftpriv->active_face->family_name);			}			else if (!ftpriv->font_sans[0] && OrigFontName && !stricmp(OrigFontName, "SANS")) {				gf_modules_set_option((GF_BaseInterface *)dr, "FontEngine", "FontSans", ftpriv->active_face->family_name);				strcpy(ftpriv->font_sans, ftpriv->active_face->family_name);			}			else if (!ftpriv->font_fixed[0] && OrigFontName && !stricmp(OrigFontName, "TYPEWRITTER")) {				gf_modules_set_option((GF_BaseInterface *)dr, "FontEngine", "FontFixed", ftpriv->active_face->family_name);				strcpy(ftpriv->font_fixed, ftpriv->active_face->family_name);			}		}

⌨️ 快捷键说明

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