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 + -
显示快捷键?