font_load_ft.c

来自「君正早期ucos系统(只有早期的才不没有打包成库),MPLAYER,文件系统,图」· C语言 代码 · 共 1,172 行 · 第 1/3 页

C
1,172
字号
#else    int j;#endif    FT_UInt   gindex;    int i;    if (face->charmap==NULL || face->charmap->encoding!=ft_encoding_unicode) {	WARNING("Unicode charmap not available for this font. Very bad!");	return -1;    }#ifdef HAVE_FREETYPE21    i = 0;    charcode = FT_Get_First_Char( face, &gindex );    while (gindex != 0) {	if (charcode < 65536 && charcode >= 33) { // sanity check	    charset[i] = charcode;	    charcodes[i] = 0;	    i++;	}	charcode = FT_Get_Next_Char( face, charcode, &gindex );    }#else    // for FT < 2.1 we have to use brute force enumeration    i = 0;    for (j = 33; j < 65536; j++) {	gindex = FT_Get_Char_Index(face, j);	if (gindex > 0) {	    charset[i] = j;	    charcodes[i] = 0;	    i++;	}    }#endif    mp_msg(MSGT_OSD, MSGL_V, "Unicode font: %d glyphs.\n", i);    return i;}#endifstatic font_desc_t* init_font_desc(void){    font_desc_t *desc;    int i;    desc = malloc(sizeof(font_desc_t));    if(!desc) return NULL;    memset(desc,0,sizeof(font_desc_t));    desc->dynamic = 1;        /* setup sane defaults */    desc->name = NULL;    desc->fpath = NULL;    desc->face_cnt = 0;    desc->charspace = 0;    desc->spacewidth = 0;    desc->height = 0;    desc->max_width = 0;    desc->max_height = 0;    desc->tables.g = NULL;    desc->tables.gt2 = NULL;    desc->tables.om = NULL;    desc->tables.omt = NULL;    desc->tables.tmp = NULL;    for(i = 0; i < 65536; i++)	desc->start[i] = desc->width[i] = desc->font[i] = -1;    for(i = 0; i < 16; i++)	desc->pic_a[i] = desc->pic_b[i] = NULL;        return desc;}void free_font_desc(font_desc_t *desc){    int i;        if (!desc) return;//    if (!desc->dynamic) return; // some vo_aa crap, better leaking than crashing    if (desc->name) free(desc->name);    if (desc->fpath) free(desc->fpath);        for(i = 0; i < 16; i++) {	if (desc->pic_a[i]) {	    if (desc->pic_a[i]->bmp) free(desc->pic_a[i]->bmp);	    if (desc->pic_a[i]->pal) free(desc->pic_a[i]->pal);	    free (desc->pic_a[i]);	}	if (desc->pic_b[i]) {	    if (desc->pic_b[i]->bmp) free(desc->pic_b[i]->bmp);	    if (desc->pic_b[i]->pal) free(desc->pic_b[i]->pal);	    free (desc->pic_b[i]);	}    }    if (desc->tables.g) free(desc->tables.g);    if (desc->tables.gt2) free(desc->tables.gt2);    if (desc->tables.om) free(desc->tables.om);    if (desc->tables.omt) free(desc->tables.omt);    if (desc->tables.tmp) free(desc->tables.tmp);    for(i = 0; i < desc->face_cnt; i++) {	FT_Done_Face(desc->faces[i]);    }        free(desc);}static int load_sub_face(const char *name, FT_Face *face){    int err = -1;        if (name) err = FT_New_Face(library, name, 0, face);    if (err) {	char *font_file = get_path("subfont.ttf");	err = FT_New_Face(library, font_file, 0, face);	free(font_file);	if (err) {	    err = FT_New_Face(library, MPLAYER_DATADIR "/subfont.ttf", 0, face);	    if (err) {	        mp_msg(MSGT_OSD, MSGL_ERR, "New_Face failed. Maybe the font path is wrong.\nPlease supply the text font file (~/.mplayer/subfont.ttf).\n" );		return -1;	    }	}    }    return err;}static int load_osd_face(FT_Face *face){    if ( FT_New_Memory_Face(library, osd_font_pfb, sizeof(osd_font_pfb), 0, face) ) {	mp_msg(MSGT_OSD, MSGL_ERR, "New_Memory_Face failed..\n");	return -1;    }    return 0;}int kerning(font_desc_t *desc, int prevc, int c){    FT_Vector kern;        if (!desc->dynamic) return 0;    if (prevc < 0 || c < 0) return 0;    if (desc->font[prevc] != desc->font[c]) return 0;    if (desc->font[prevc] == -1 || desc->font[c] == -1) return 0;    FT_Get_Kerning(desc->faces[desc->font[c]], 		   desc->glyph_index[prevc], desc->glyph_index[c],		   ft_kerning_default, &kern);//    fprintf(stderr, "kern: %c %c %d\n", prevc, c, f266ToInt(kern.x));    return f266ToInt(kern.x);}font_desc_t* read_font_desc_ft(const char *fname, int movie_width, int movie_height){    font_desc_t *desc = NULL;    FT_Face face;    FT_ULong *my_charset = malloc(MAX_CHARSET_SIZE * sizeof(FT_ULong)); /* characters we want to render; Unicode */    FT_ULong *my_charcodes = malloc(MAX_CHARSET_SIZE * sizeof(FT_ULong)); /* character codes in 'encoding' */    char *charmap = "ucs-4";    int err;    int charset_size;    int i, j;    int unicode;        float movie_size;    float subtitle_font_ppem;    float osd_font_ppem;    if (my_charset == NULL || my_charcodes == NULL) {	mp_msg(MSGT_OSD, MSGL_ERR, "subtitle font: malloc failed.\n");	goto err_out;    }    switch (subtitle_autoscale) {    case 1:	movie_size = movie_height;	break;    case 2:	movie_size = movie_width;	break;    case 3:	movie_size = sqrt(movie_height*movie_height+movie_width*movie_width);	break;    default:	movie_size = 100;	break;    }    subtitle_font_ppem = movie_size*text_font_scale_factor/100.0;    osd_font_ppem = movie_size*osd_font_scale_factor/100.0;    if (subtitle_font_ppem < 5) subtitle_font_ppem = 5;    if (osd_font_ppem < 5) osd_font_ppem = 5;    if (subtitle_font_ppem > 128) subtitle_font_ppem = 128;    if (osd_font_ppem > 128) osd_font_ppem = 128;    if ((subtitle_font_encoding == NULL)	|| (strcasecmp(subtitle_font_encoding, "unicode") == 0)) {	unicode = 1;    } else {	unicode = 0;    }    desc = init_font_desc();    if(!desc) goto err_out;//    t=GetTimer();    /* generate the subtitle font */    err = load_sub_face(fname, &face);    if (err) {	mp_msg(MSGT_OSD, MSGL_WARN, "subtitle font: load_sub_face failed.\n");	goto gen_osd;    }    desc->face_cnt++;#ifdef USE_ICONV    if (unicode) {	charset_size = prepare_charset_unicode(face, my_charset, my_charcodes);    } else {	if (subtitle_font_encoding) {	    charset_size = prepare_charset(charmap, subtitle_font_encoding, my_charset, my_charcodes);	} else {	    charset_size = prepare_charset(charmap, "iso-8859-1", my_charset, my_charcodes);	}    }    if (charset_size < 0) {	mp_msg(MSGT_OSD, MSGL_ERR, "subtitle font: prepare_charset failed.\n");	goto err_out;    }#else    goto err_out;#endif//    fprintf(stderr, "fg: prepare t = %lf\n", GetTimer()-t);    err = prepare_font(desc, face, subtitle_font_ppem, desc->face_cnt-1,		       charset_size, my_charset, my_charcodes, unicode,		       subtitle_font_thickness, subtitle_font_radius);    if (err) {	mp_msg(MSGT_OSD, MSGL_ERR, "Cannot prepare subtitle font.\n");	goto err_out;    }gen_osd:    /* generate the OSD font */    err = load_osd_face(&face);    if (err) {	goto err_out;    }    desc->face_cnt++;    err = prepare_font(desc, face, osd_font_ppem, desc->face_cnt-1,		       OSD_CHARSET_SIZE, osd_charset, osd_charcodes, 0,		       subtitle_font_thickness, subtitle_font_radius);        if (err) {	mp_msg(MSGT_OSD, MSGL_ERR, "Cannot prepare OSD font.\n");	goto err_out;    }    err = generate_tables(desc, subtitle_font_thickness, subtitle_font_radius);        if (err) {	mp_msg(MSGT_OSD, MSGL_ERR, "Cannot generate tables.\n");	goto err_out;    }    // final cleanup    desc->font[' ']=-1;    desc->width[' ']=desc->spacewidth;    j = '_';    if (desc->font[j] < 0) j = '?';    if (desc->font[j] < 0) j = ' ';    render_one_glyph(desc, j);    for(i = 0; i < 65536; i++) {	if (desc->font[i] < 0 && i != ' ') {	    desc->start[i] = desc->start[j];	    desc->width[i] = desc->width[j];	    desc->font[i] = desc->font[j];	}    }    free(my_charset);    free(my_charcodes);    return desc;err_out:    if (desc)      free_font_desc(desc);    free(my_charset);    free(my_charcodes);    return NULL;}int init_freetype(void){    int err;        /* initialize freetype */    err = FT_Init_FreeType(&library);    if (err) {	mp_msg(MSGT_OSD, MSGL_ERR, "Init_FreeType failed.\n");	return -1;    }    mp_msg(MSGT_OSD, MSGL_V, "init_freetype\n");    using_freetype = 1;    return 0;}int done_freetype(void){    int err;    if (!using_freetype)	return 0;        err = FT_Done_FreeType(library);    if (err) {	mp_msg(MSGT_OSD, MSGL_ERR, "FT_Done_FreeType failed.\n");	return -1;    }    return 0;}void load_font_ft(int width, int height, font_desc_t** fontp, const char *font_name) {#ifdef HAVE_FONTCONFIG    FcPattern *fc_pattern;    FcPattern *fc_pattern2;    FcChar8 *s;    FcBool scalable;#endif    font_desc_t *vo_font = *fontp;    vo_image_width = width;    vo_image_height = height;    // protection against vo_aa font hacks    if (vo_font && !vo_font->dynamic) return;    if (vo_font) free_font_desc(vo_font);#ifdef HAVE_FONTCONFIG    if (font_fontconfig)    {	if (!font_name)	    font_name = strdup("sans-serif");	FcInit();	fc_pattern = FcNameParse(font_name);	FcConfigSubstitute(0, fc_pattern, FcMatchPattern);	FcDefaultSubstitute(fc_pattern);	fc_pattern2 = fc_pattern;	fc_pattern = FcFontMatch(0, fc_pattern, 0);	FcPatternDestroy(fc_pattern2);	FcPatternGetBool(fc_pattern, FC_SCALABLE, 0, &scalable);	if (scalable != FcTrue) {	    FcPatternDestroy(fc_pattern);    	    fc_pattern = FcNameParse("sans-serif");    	    FcConfigSubstitute(0, fc_pattern, FcMatchPattern);    	    FcDefaultSubstitute(fc_pattern);	    fc_pattern2 = fc_pattern;    	    fc_pattern = FcFontMatch(0, fc_pattern, 0);	    FcPatternDestroy(fc_pattern2);	}	// s doesn't need to be freed according to fontconfig docs	FcPatternGetString(fc_pattern, FC_FILE, 0, &s);	*fontp=read_font_desc_ft(s, width, height);	FcPatternDestroy(fc_pattern);    }    else#endif    *fontp=read_font_desc_ft(font_name, width, height);}

⌨️ 快捷键说明

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