From 85a3a0d5bc1294f88dea42a515bb3dce16c9d951 Mon Sep 17 00:00:00 2001 From: wm4 Date: Sat, 28 Jul 2012 22:00:31 +0200 Subject: osd: remove freetype font rendering code The previous commit made libass the default OSD renderer. This commit removes the disabled freetype renderer completely. The commits were done separately to make rolling back easier, because using libass for OSD rendering is a risky choice. Also remove freetype/fontconfig/fribidi code. This is all done by libass now. If mplayer is compiled without libass, no OSD is displayed. --- sub/ass_mp.c | 26 +- sub/font_load.c | 351 ---------------- sub/font_load.h | 108 ----- sub/font_load_ft.c | 1169 ---------------------------------------------------- sub/osd_dummy.c | 43 ++ sub/osd_ft.c | 969 ------------------------------------------- sub/osd_libass.c | 1 - sub/sub.h | 1 - sub/subreader.c | 83 ---- sub/subreader.h | 4 - 10 files changed, 52 insertions(+), 2703 deletions(-) delete mode 100644 sub/font_load.c delete mode 100644 sub/font_load.h delete mode 100644 sub/font_load_ft.c create mode 100644 sub/osd_dummy.c delete mode 100644 sub/osd_ft.c (limited to 'sub') diff --git a/sub/ass_mp.c b/sub/ass_mp.c index 3dd743776d..1510e43ab5 100644 --- a/sub/ass_mp.c +++ b/sub/ass_mp.c @@ -60,10 +60,8 @@ ASS_Track *mp_ass_default_track(ASS_Library *library, struct MPOpts *opts) track->default_style = sid; ASS_Style *style = track->styles + sid; style->Name = strdup("Default"); - style->FontName = (font_fontconfig >= 0 - && sub_font_name) ? strdup(sub_font_name) - : (font_fontconfig >= 0 - && font_name) ? strdup(font_name) : strdup("Sans"); + style->FontName = sub_font_name ? strdup(sub_font_name) + : font_name ? strdup(font_name) : strdup("Sans"); style->treat_fontname_as_pattern = 1; double fs = track->PlayResY * text_font_scale_factor / 100.; @@ -250,25 +248,19 @@ void mp_ass_configure_fonts(ASS_Renderer *priv) { char *dir, *path, *family; dir = get_path("fonts"); - if (font_fontconfig < 0 && sub_font_name) - path = strdup(sub_font_name); - else if (font_fontconfig < 0 && font_name) - path = strdup(font_name); - else { - path = get_path("subfont.ttf"); - if (!mp_path_exists(path)) { - free(path); - path = NULL; - } + path = get_path("subfont.ttf"); + if (!mp_path_exists(path)) { + free(path); + path = NULL; } - if (font_fontconfig >= 0 && sub_font_name) + if (sub_font_name) family = strdup(sub_font_name); - else if (font_fontconfig >= 0 && font_name) + else if (font_name) family = strdup(font_name); else family = 0; - ass_set_fonts(priv, path, family, font_fontconfig + 1, NULL, 1); + ass_set_fonts(priv, path, family, 1, NULL, 1); free(dir); free(path); diff --git a/sub/font_load.c b/sub/font_load.c deleted file mode 100644 index d8f9eafe34..0000000000 --- a/sub/font_load.c +++ /dev/null @@ -1,351 +0,0 @@ -/* - * This file is part of MPlayer. - * - * MPlayer is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * MPlayer 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with MPlayer; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#include "config.h" - -#include -#include -#include - -#include "osdep/io.h" - -#include "font_load.h" -#include "mp_msg.h" -#include "libavutil/attributes.h" - -raw_file* load_raw(char *name,int verbose){ - int bpp; - raw_file* raw=malloc(sizeof(raw_file)); - unsigned char head[32]; - FILE *f=fopen(name,"rb"); - if(!f) goto err_out; // can't open - if(fread(head,32,1,f)<1) goto err_out; // too small - if(memcmp(head,"mhwanh",6)) goto err_out; // not raw file - raw->w=head[8]*256+head[9]; - raw->h=head[10]*256+head[11]; - raw->c=head[12]*256+head[13]; - if(raw->w == 0) // 2 bytes were not enough for the width... read 4 bytes from the end of the header - raw->w = ((head[28]*0x100 + head[29])*0x100 + head[30])*0x100 + head[31]; - if(raw->c>256) goto err_out; // too many colors!? - mp_msg(MSGT_OSD, MSGL_DBG2, "RAW: %s %d x %d, %d colors\n",name,raw->w,raw->h,raw->c); - if(raw->c){ - raw->pal=malloc(raw->c*3); - fread(raw->pal,3,raw->c,f); - bpp=1; - } else { - raw->pal=NULL; - bpp=3; - } - raw->bmp=malloc(raw->h*raw->w*bpp); - fread(raw->bmp,raw->h*raw->w*bpp,1,f); - fclose(f); - return raw; - -err_out: - if (f) - fclose(f); - free(raw); - return NULL; -} - -extern int sub_unicode; - -font_desc_t* read_font_desc(const char* fname,float factor,int verbose){ -unsigned char sor[1024]; -unsigned char sor2[1024]; -font_desc_t *desc; -FILE *f = NULL; -char *dn; -char section[64]; -int i,j; -int chardb=0; -int fontdb=-1; -int version av_unused; -int first=1; - -desc=malloc(sizeof(font_desc_t));if(!desc) goto fail_out; -memset(desc,0,sizeof(font_desc_t)); - -f=fopen(fname,"rt");if(!f){ mp_msg(MSGT_OSD, MSGL_V, "font: can't open file: %s\n",fname); goto fail_out;} - -i = strlen (fname) - 9; -if ((dn = malloc(i+1))){ - strncpy (dn, fname, i); - dn[i]='\0'; -} - -desc->fpath = dn; // search in the same dir as fonts.desc - - - -// set up some defaults, and erase table -desc->charspace=2; -desc->spacewidth=12; -desc->height=0; -for(i=0;i<65536;i++) desc->start[i]=desc->width[i]=desc->font[i]=-1; - -section[0]=0; - -while(fgets(sor,1020,f)){ - unsigned char* p[8]; - int pdb=0; - unsigned char *s=sor; - unsigned char *d=sor2; - int ec=' '; - int id=0; - sor[1020]=0; - - /* skip files that look like: TTF (0x00, 0x01), PFM (0x00, 0x01), PFB - * (0x80, 0x01), PCF (0x01, 0x66), fon ("MZ"), gzipped (0x1f, 0x8b) */ - - if (first) { - if (!sor[0] || sor[1] == 1 || (sor[0] == 'M' && sor[1] == 'Z') || (sor[0] == 0x1f && sor[1] == 0x8b) || (sor[0] == 1 && sor[1] == 0x66)) { - mp_msg(MSGT_OSD, MSGL_ERR, "%s doesn't look like a bitmap font description, ignoring.\n", fname); - goto fail_out; - } - first = 0; - } - - p[0]=d;++pdb; - while(1){ - int c=*s++; - if(c==0 || c==13 || c==10) break; - if(!id){ - if(c==39 || c==34){ id=c;continue;} // idezojel - if(c==';' || c=='#') break; - if(c==9) c=' '; - if(c==' '){ - if(ec==' ') continue; - *d=0; ++d; - p[pdb]=d;++pdb; - if(pdb>=8) break; - continue; - } - } else { - if(id==c){ id=0;continue;} // idezojel - - } - *d=c;d++; - ec=c; - } - if(d==sor2) continue; // skip empty lines - *d=0; - -// printf("params=%d sor=%s\n",pdb,sor); -// for(i=0;i=16){ mp_msg(MSGT_OSD, MSGL_ERR, "font: Too many bitmaps defined.\n");goto fail_out;} - } - continue; - } - } - - if(strcmp(section,"[fpath]")==0){ - if(pdb==1){ - free (desc->fpath); // release previously allocated memory - desc->fpath=strdup(p[0]); - continue; - } - } else - -#ifdef __AMIGAOS4__ -#define FONT_PATH_SEP "" -#else -//! path seperator for font paths, may not be more than one character -#define FONT_PATH_SEP "/" -#endif - - if(strcmp(section,"[files]")==0){ - char *default_dir=MPLAYER_DATADIR FONT_PATH_SEP "font"; - if(pdb==2 && strcmp(p[0],"alpha")==0){ - char *cp; - if (!(cp=malloc(strlen(desc->fpath)+strlen(p[1])+2))) goto fail_out; - - snprintf(cp,strlen(desc->fpath)+strlen(p[1])+2,"%s" FONT_PATH_SEP "%s", - desc->fpath,p[1]); - if(!((desc->pic_a[fontdb]=load_raw(cp,verbose)))){ - free(cp); - if (!(cp=malloc(strlen(default_dir)+strlen(p[1])+2))) - goto fail_out; - snprintf(cp,strlen(default_dir)+strlen(p[1])+2,"%s" FONT_PATH_SEP "%s", - default_dir,p[1]); - if (!((desc->pic_a[fontdb]=load_raw(cp,verbose)))){ - mp_msg(MSGT_OSD, MSGL_ERR, "Can't load font bitmap: %s\n",p[1]); - free(cp); - goto fail_out; - } - } - free(cp); - continue; - } - if(pdb==2 && strcmp(p[0],"bitmap")==0){ - char *cp; - if (!(cp=malloc(strlen(desc->fpath)+strlen(p[1])+2))) goto fail_out; - - snprintf(cp,strlen(desc->fpath)+strlen(p[1])+2,"%s" FONT_PATH_SEP "%s", - desc->fpath,p[1]); - if(!((desc->pic_b[fontdb]=load_raw(cp,verbose)))){ - free(cp); - if (!(cp=malloc(strlen(default_dir)+strlen(p[1])+2))) - goto fail_out; - snprintf(cp,strlen(default_dir)+strlen(p[1])+2,"%s" FONT_PATH_SEP "%s", - default_dir,p[1]); - if (!((desc->pic_b[fontdb]=load_raw(cp,verbose)))){ - mp_msg(MSGT_OSD, MSGL_ERR, "Can't load font bitmap: %s\n",p[1]); - free(cp); - goto fail_out; - } - } - free(cp); - continue; - } - } else - - if(strcmp(section,"[info]")==0){ - if(pdb==2 && strcmp(p[0],"name")==0){ - desc->name=strdup(p[1]); - continue; - } - if(pdb==2 && strcmp(p[0],"descversion")==0){ - version=atoi(p[1]); - continue; - } - if(pdb==2 && strcmp(p[0],"spacewidth")==0){ - desc->spacewidth=atoi(p[1]); - continue; - } - if(pdb==2 && strcmp(p[0],"charspace")==0){ - desc->charspace=atoi(p[1]); - continue; - } - if(pdb==2 && strcmp(p[0],"height")==0){ - desc->height=atoi(p[1]); - continue; - } - } else - - if(strcmp(section,"[characters]")==0){ - if(pdb==3){ - int chr=p[0][0]; - int start=atoi(p[1]); - int end=atoi(p[2]); - if(sub_unicode && (chr>=0x80)) chr=(chr<<8)+p[0][1]; - else if(strlen(p[0])!=1) chr=strtol(p[0],NULL,0); - if(endstart[chr]=start; - desc->width[chr]=end-start+1; - desc->font[chr]=fontdb; -// printf("char %d '%c' start=%d width=%d\n",chr,chr,desc->start[chr],desc->width[chr]); - ++chardb; - } - continue; - } - } - mp_msg(MSGT_OSD, MSGL_ERR, "Syntax error in font desc: %s",sor); - goto fail_out; - -} -fclose(f); -f = NULL; - - if (first == 1) { - mp_msg(MSGT_OSD, MSGL_ERR, "%s is empty or a directory, ignoring.\n", fname); - goto fail_out; - } - -//printf("font: pos of U = %d\n",desc->start[218]); - -for(i=0;i<=fontdb;i++){ - if(!desc->pic_a[i] || !desc->pic_b[i]){ - mp_msg(MSGT_OSD, MSGL_ERR, "font: Missing bitmap(s) for sub-font #%d\n",i); - goto fail_out; - } - //if(factor!=1.0f) - { - // re-sample alpha - int f=factor*256.0f; - int size=desc->pic_a[i]->w*desc->pic_a[i]->h; - int j; - mp_msg(MSGT_OSD, MSGL_DBG2, "font: resampling alpha by factor %5.3f (%d) ",factor,f);fflush(stdout); - for(j=0;jpic_a[i]->bmp[j]; // alpha - int y=desc->pic_b[i]->bmp[j]; // bitmap - -#ifdef FAST_OSD - x=(x<(255-f))?0:1; -#else - - x=255-((x*f)>>8); // scale - //if(x<0) x=0; else if(x>255) x=255; - //x^=255; // invert - - if(x+y>255) x=255-y; // to avoid overflows - - //x=0; - //x=((x*f*(255-y))>>16); - //x=((x*f*(255-y))>>16)+y; - //x=(x*f)>>8;if(x=252) x=0; -#endif - - desc->pic_a[i]->bmp[j]=x; -// desc->pic_b[i]->bmp[j]=0; // hack - } - mp_msg(MSGT_OSD, MSGL_DBG2, "DONE!\n"); - } - if(!desc->height) desc->height=desc->pic_a[i]->h; -} - -j='_';if(desc->font[j]<0) j='?'; -for(i=0;i<65536;i++) - if(desc->font[i]<0){ - desc->start[i]=desc->start[j]; - desc->width[i]=desc->width[j]; - desc->font[i]=desc->font[j]; - } -desc->font[' ']=-1; -desc->width[' ']=desc->spacewidth; - -mp_msg(MSGT_OSD, MSGL_V, "Bitmap font %s loaded successfully! (%d chars)\n",fname,chardb); - -return desc; - -fail_out: - if (f) - fclose(f); - free(desc->fpath); - free(desc->name); - free(desc); - return NULL; -} - -#ifndef CONFIG_FREETYPE -void render_one_glyph(font_desc_t *desc, int c) {} -int kerning(font_desc_t *desc, int prevc, int c) { return 0; } -#endif diff --git a/sub/font_load.h b/sub/font_load.h deleted file mode 100644 index 933f84804f..0000000000 --- a/sub/font_load.h +++ /dev/null @@ -1,108 +0,0 @@ -/* - * This file is part of MPlayer. - * - * MPlayer is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * MPlayer 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with MPlayer; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#ifndef MPLAYER_FONT_LOAD_H -#define MPLAYER_FONT_LOAD_H - -#include "config.h" - -#ifdef CONFIG_FREETYPE -#include -#include FT_FREETYPE_H -#endif - -typedef struct { - unsigned char *bmp; - unsigned char *pal; - int w,h,c; -#ifdef CONFIG_FREETYPE - int charwidth,charheight,pen,baseline,padding; - int current_count, current_alloc; -#endif -} raw_file; - -typedef struct font_desc { -#ifdef CONFIG_FREETYPE - int dynamic; -#endif - char *name; - char *fpath; - int spacewidth; - int charspace; - int height; -// char *fname_a; -// char *fname_b; - raw_file* pic_a[16]; - raw_file* pic_b[16]; - short font[65536]; - int start[65536]; // short is not enough for unicode fonts - short width[65536]; - int freetype; - -#ifdef CONFIG_FREETYPE - int face_cnt; - - FT_Face faces[16]; - FT_UInt glyph_index[65536]; - - int max_width, max_height; - - struct - { - int g_r; - int o_r; - int g_w; - int o_w; - int o_size; - unsigned volume; - - unsigned *g; - unsigned *gt2; - unsigned *om; - unsigned char *omt; - unsigned short *tmp; - } tables; -#endif - -} font_desc_t; - -extern font_desc_t* vo_font; - -extern int vo_image_width; -extern int vo_image_height; - -extern int force_load_font; - -int init_freetype(void); -int done_freetype(void); - -font_desc_t* read_font_desc_ft(const char* fname,int face_index,int movie_width, int movie_height, float font_scale_factor); -void free_font_desc(font_desc_t *desc); - -void render_one_glyph(font_desc_t *desc, int c); -int kerning(font_desc_t *desc, int prevc, int c); - -void load_font_ft(int width, int height, font_desc_t **desc, const char *name, float font_scale_factor); - -void blur(unsigned char *buffer, unsigned short *tmp2, int width, int height, - int stride, int *m2, int r, int mwidth); - -raw_file* load_raw(char *name,int verbose); -font_desc_t* read_font_desc(const char* fname,float factor,int verbose); - -#endif /* MPLAYER_FONT_LOAD_H */ diff --git a/sub/font_load_ft.c b/sub/font_load_ft.c deleted file mode 100644 index 9eb0ab50e8..0000000000 --- a/sub/font_load_ft.c +++ /dev/null @@ -1,1169 +0,0 @@ -/* - * Renders antialiased fonts for mplayer using freetype library. - * Should work with TrueType, Type1 and any other font supported by libfreetype. - * - * Artur Zaprzala - * - * ported inside MPlayer by Jindrich Makovicka - * - * This file is part of MPlayer. - * - * MPlayer is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * MPlayer 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with MPlayer; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#include "config.h" - -#include -#include -#include -#include - -#ifdef CONFIG_ICONV -#include -#endif - -#include -#include FT_FREETYPE_H -#include FT_GLYPH_H - -#ifdef CONFIG_FONTCONFIG -#include -#endif - -#include "libavutil/common.h" -#include "mpbswap.h" -#include "font_load.h" -#include "mp_msg.h" -#include "mplayer.h" -#include "path.h" -#include "sub/sub.h" - -#include "osd_font.h" - -#if (FREETYPE_MAJOR > 2) || (FREETYPE_MAJOR == 2 && FREETYPE_MINOR >= 1) -#define HAVE_FREETYPE21 -#endif - -int vo_image_width = 0; -int vo_image_height = 0; -int force_load_font; - -int using_freetype = 0; -#ifdef CONFIG_FONTCONFIG -int font_fontconfig = 1; -#else -int font_fontconfig = -1; -#endif - -//// constants -static unsigned int const colors = 256; -static unsigned int const maxcolor = 255; -static unsigned const base = 256; -static unsigned const first_char = 33; -#define MAX_CHARSET_SIZE 60000 - -static FT_Library library; - -#define OSD_CHARSET_SIZE 15 - -static const FT_ULong osd_charset[OSD_CHARSET_SIZE] = -{ - 0xe001, 0xe002, 0xe003, 0xe004, 0xe005, 0xe006, 0xe007, 0xe008, - 0xe009, 0xe00a, 0xe00b, 0xe010, 0xe011, 0xe012, 0xe013 -}; - -static const FT_ULong osd_charcodes[OSD_CHARSET_SIZE] = -{ - 0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08, - 0x09,0x0a,0x0b,0x10,0x11,0x12,0x13 -}; - -#define f266ToInt(x) (((x)+32)>>6) // round fractional fixed point number to integer - // coordinates are in 26.6 pixels (i.e. 1/64th of pixels) -#define f266CeilToInt(x) (((x)+63)>>6) // ceiling -#define f266FloorToInt(x) ((x)>>6) // floor -#define f1616ToInt(x) (((x)+0x8000)>>16) // 16.16 -#define floatTof266(x) ((int)((x)*(1<<6)+0.5)) - -#define ALIGN(x) (((x)+7)&~7) // 8 byte align - -#define WARNING(msg, args...) mp_msg(MSGT_OSD, MSGL_WARN, msg "\n", ## args) - -#define DEBUG 0 - -//static double ttime; - - -static void paste_bitmap(unsigned char *bbuffer, FT_Bitmap *bitmap, int x, int y, int width, int height, int bwidth) { - int drow = x+y*width; - int srow = 0; - int sp, dp, w, h; - if (bitmap->pixel_mode==ft_pixel_mode_mono) - for (h = bitmap->rows; h>0 && height > 0; --h, height--, drow+=width, srow+=bitmap->pitch) - for (w = bwidth, sp=dp=0; w>0; --w, ++dp, ++sp) - bbuffer[drow+dp] = (bitmap->buffer[srow+sp/8] & (0x80>>(sp%8))) ? 255:0; - else - for (h = bitmap->rows; h>0 && height > 0; --h, height--, drow+=width, srow+=bitmap->pitch) - for (w = bwidth, sp=dp=0; w>0; --w, ++dp, ++sp) - bbuffer[drow+dp] = bitmap->buffer[srow+sp]; -} - - -static int check_font(font_desc_t *desc, float ppem, int padding, int pic_idx, - int charset_size, const FT_ULong *charset, - const FT_ULong *charcodes, int unicode) -{ - FT_Error error; - FT_Face face = desc->faces[pic_idx]; - int const load_flags = FT_LOAD_DEFAULT; - int ymin = INT_MAX, ymax = INT_MIN; - int space_advance = 20; - int width, height; - unsigned char *bbuffer; - int i, uni_charmap = 1; - - error = FT_Select_Charmap(face, ft_encoding_unicode); -// fprintf(stderr, "select unicode charmap: %d\n", error); - - if (face->charmap==NULL || face->charmap->encoding!=ft_encoding_unicode) { - WARNING("Unicode charmap not available for this font. Very bad!"); - uni_charmap = 0; - error = FT_Set_Charmap(face, face->charmaps[0]); - if (error) WARNING("No charmaps! Strange."); - } - - /* set size */ - if (FT_IS_SCALABLE(face)) { - error = FT_Set_Char_Size(face, 0, floatTof266(ppem), 0, 0); - if (error) WARNING("FT_Set_Char_Size failed."); - } else { - int j = 0; - int jppem = face->available_sizes[0].height; - /* find closest size */ - for (i = 0; inum_fixed_sizes; ++i) { - if (fabs(face->available_sizes[i].height - ppem) < abs(face->available_sizes[i].height - jppem)) { - j = i; - jppem = face->available_sizes[i].height; - } - } - WARNING("Selected font is not scalable. Using ppem=%i.", face->available_sizes[j].height); - error = FT_Set_Pixel_Sizes(face, face->available_sizes[j].width, face->available_sizes[j].height); - if (error) WARNING("FT_Set_Pixel_Sizes failed."); - } - - if (FT_IS_FIXED_WIDTH(face)) - WARNING("Selected font is fixed-width."); - - /* compute space advance */ - error = FT_Load_Char(face, ' ', load_flags); - if (error) WARNING("spacewidth set to default."); - else space_advance = f266ToInt(face->glyph->advance.x); - - if (!desc->spacewidth) desc->spacewidth = 2*padding + space_advance; - if (!desc->charspace) desc->charspace = -2*padding; - if (!desc->height) desc->height = f266ToInt(face->size->metrics.height); - - - for (i= 0; ifont[unicode?character:code] = pic_idx; - // get glyph index - if (character==0) - glyph_index = 0; - else { - glyph_index = FT_Get_Char_Index(face, uni_charmap ? character:code); - if (glyph_index==0) { - WARNING("Glyph for char 0x%02lx|U+%04lX|%c not found.", code, character, - code<' '||code>255 ? '.':(char)code); - desc->font[unicode?character:code] = -1; - continue; - } - } - desc->glyph_index[unicode?character:code] = glyph_index; - } -// fprintf(stderr, "font height: %f\n", (double)(face->bbox.yMax-face->bbox.yMin)/(double)face->units_per_EM*ppem); -// fprintf(stderr, "font width: %f\n", (double)(face->bbox.xMax-face->bbox.xMin)/(double)face->units_per_EM*ppem); - - ymax = (double)(face->bbox.yMax)/(double)face->units_per_EM*ppem+1; - ymin = (double)(face->bbox.yMin)/(double)face->units_per_EM*ppem-1; - - width = ppem*(face->bbox.xMax-face->bbox.xMin)/face->units_per_EM+3+2*padding; - if (desc->max_width < width) desc->max_width = width; - width = ALIGN(width); - desc->pic_b[pic_idx]->charwidth = width; - - if (width <= 0) { - mp_msg(MSGT_OSD, MSGL_ERR, "Wrong bounding box, width <= 0 !\n"); - return -1; - } - - if (ymax<=ymin) { - mp_msg(MSGT_OSD, MSGL_ERR, "Something went wrong. Use the source!\n"); - return -1; - } - - height = ymax - ymin + 2*padding; - if (height <= 0) { - mp_msg(MSGT_OSD, MSGL_ERR, "Wrong bounding box, height <= 0 !\n"); - return -1; - } - - if (desc->max_height < height) desc->max_height = height; - desc->pic_b[pic_idx]->charheight = height; - -// fprintf(stderr, "font height2: %d\n", height); - desc->pic_b[pic_idx]->baseline = ymax + padding; - desc->pic_b[pic_idx]->padding = padding; - desc->pic_b[pic_idx]->current_alloc = 0; - desc->pic_b[pic_idx]->current_count = 0; - - bbuffer = NULL; - - desc->pic_b[pic_idx]->w = width; - desc->pic_b[pic_idx]->h = height; - desc->pic_b[pic_idx]->c = colors; - desc->pic_b[pic_idx]->bmp = bbuffer; - desc->pic_b[pic_idx]->pen = 0; - return 0; -} - -// general outline -static void outline( - unsigned char *s, - unsigned char *t, - int width, - int height, - int stride, - unsigned char *m, - int r, - int mwidth, - int msize) { - - int x, y; - - for (y = 0; y=width ) ? r+width -x : 2*r+1; - const int y2=(y+r>=height) ? r+height-y : 2*r+1; - register unsigned char *dstp= t + (y1+y-r)* stride + x-r; - //register int *mp = m + y1 *mwidth; - register unsigned char *mp= m + msize*src + y1*mwidth; - int my; - - for(my= y1; mymaxcolor ? maxcolor : v; - } - *t++ = *s++; - s += skip; - t += skip; - } - for (x = 0; x>8; - unsigned *m3= m2 + src2*mwidth; - - int mx; - *srcp= 128; - for(mx=r-1; mx>8; - unsigned *m3= m2 + src2*mwidth; - - int mx; - *srcp= 128; - for(mx=0; mx>8; - unsigned *m3= m2 + src2*mwidth; - - int mx; - *srcp= 128; - for(mx=0; mx>8; - } - s+= stride; - t+= width + 1; - } -} - -static void resample_alpha(unsigned char *abuf, unsigned char *bbuf, int width, int height, int stride, float factor) -{ - int f=factor*256.0f; - int i,j; - for (i = 0; i < height; i++) { - unsigned char *a = abuf+i*stride; - unsigned char *b = bbuf+i*stride; - for(j=0;j>8); // scale - if (x+y>255) x=255-y; // to avoid overflows - if (x<1) x=1; else if (x>=252) x=0; - *a=x; - } - } -} - -#define ALLOC_INCR 32 -void render_one_glyph(font_desc_t *desc, int c) -{ - FT_GlyphSlot slot; - FT_UInt glyph_index; - FT_BitmapGlyph glyph; - int width, height, stride, maxw, off; - unsigned char *abuffer, *bbuffer; - - int const load_flags = FT_LOAD_DEFAULT; - int pen_xa; - int font = desc->font[c]; - int error; - -// fprintf(stderr, "render_one_glyph %d\n", c); - - if (!desc->dynamic) return; - if (desc->width[c] != -1) return; - if (desc->font[c] == -1) return; - - glyph_index = desc->glyph_index[c]; - - // load glyph - error = FT_Load_Glyph(desc->faces[font], glyph_index, load_flags); - if (error) { - WARNING("FT_Load_Glyph 0x%02x (char 0x%04x) failed.", glyph_index, c); - desc->font[c] = -1; - return; - } - slot = desc->faces[font]->glyph; - - // render glyph - if (slot->format != ft_glyph_format_bitmap) { - error = FT_Render_Glyph(slot, ft_render_mode_normal); - if (error) { - WARNING("FT_Render_Glyph 0x%04x (char 0x%04x) failed.", glyph_index, c); - desc->font[c] = -1; - return; - } - } - - // extract glyph image - error = FT_Get_Glyph(slot, (FT_Glyph*)&glyph); - if (error) { - WARNING("FT_Get_Glyph 0x%04x (char 0x%04x) failed.", glyph_index, c); - desc->font[c] = -1; - return; - } - -// fprintf(stderr, "glyph generated\n"); - - maxw = desc->pic_b[font]->charwidth; - - if (glyph->bitmap.width > maxw) { - fprintf(stderr, "glyph too wide!\n"); - } - - // allocate new memory, if needed -// fprintf(stderr, "\n%d %d %d\n", desc->pic_b[font]->charwidth, desc->pic_b[font]->charheight, desc->pic_b[font]->current_alloc); - if (desc->pic_b[font]->current_count >= desc->pic_b[font]->current_alloc) { - int newsize = desc->pic_b[font]->charwidth*desc->pic_b[font]->charheight*(desc->pic_b[font]->current_alloc+ALLOC_INCR); - int increment = desc->pic_b[font]->charwidth*desc->pic_b[font]->charheight*ALLOC_INCR; - desc->pic_b[font]->current_alloc += ALLOC_INCR; - -// fprintf(stderr, "\nns = %d inc = %d\n", newsize, increment); - - desc->pic_b[font]->bmp = realloc(desc->pic_b[font]->bmp, newsize); - desc->pic_a[font]->bmp = realloc(desc->pic_a[font]->bmp, newsize); - - off = desc->pic_b[font]->current_count*desc->pic_b[font]->charwidth*desc->pic_b[font]->charheight; - memset(desc->pic_b[font]->bmp+off, 0, increment); - memset(desc->pic_a[font]->bmp+off, 0, increment); - } - - abuffer = desc->pic_a[font]->bmp; - bbuffer = desc->pic_b[font]->bmp; - - off = desc->pic_b[font]->current_count*desc->pic_b[font]->charwidth*desc->pic_b[font]->charheight; - - paste_bitmap(bbuffer+off, - &glyph->bitmap, - desc->pic_b[font]->padding + glyph->left, - desc->pic_b[font]->baseline - glyph->top, - desc->pic_b[font]->charwidth, desc->pic_b[font]->charheight, - glyph->bitmap.width <= maxw ? glyph->bitmap.width : maxw); - -// fprintf(stderr, "glyph pasted\n"); - FT_Done_Glyph((FT_Glyph)glyph); - - /* advance pen */ - pen_xa = f266ToInt(slot->advance.x) + 2*desc->pic_b[font]->padding; - if (pen_xa > maxw) pen_xa = maxw; - - desc->start[c] = off; - width = desc->width[c] = pen_xa; - height = desc->pic_b[font]->charheight; - stride = desc->pic_b[font]->w; - - if (desc->tables.o_r == 0) { - outline0(bbuffer+off, abuffer+off, width, height, stride); - } else if (desc->tables.o_r == 1) { - outline1(bbuffer+off, abuffer+off, width, height, stride); - } else { - outline(bbuffer+off, abuffer+off, width, height, stride, - desc->tables.omt, desc->tables.o_r, desc->tables.o_w, - desc->tables.o_size); - } -// fprintf(stderr, "fg: outline t = %f\n", GetTimer()-t); - - if (desc->tables.g_r) { - blur(abuffer+off, desc->tables.tmp, width, height, stride, - desc->tables.gt2, desc->tables.g_r, - desc->tables.g_w); -// fprintf(stderr, "fg: blur t = %f\n", GetTimer()-t); - } - - resample_alpha(abuffer+off, bbuffer+off, width, height, stride, font_factor); - - desc->pic_b[font]->current_count++; -} - - -static int prepare_font(font_desc_t *desc, FT_Face face, float ppem, - int pic_idx, int charset_size, - const FT_ULong *charset, const FT_ULong *charcodes, - int unicode, double thickness, double radius) -{ - int i, err; - int padding = ceil(radius) + ceil(thickness); - - desc->faces[pic_idx] = face; - - desc->pic_a[pic_idx] = malloc(sizeof(raw_file)); - if (!desc->pic_a[pic_idx]) return -1; - desc->pic_b[pic_idx] = malloc(sizeof(raw_file)); - if (!desc->pic_b[pic_idx]) return -1; - - desc->pic_a[pic_idx]->bmp = NULL; - desc->pic_a[pic_idx]->pal = NULL; - desc->pic_b[pic_idx]->bmp = NULL; - desc->pic_b[pic_idx]->pal = NULL; - - desc->pic_a[pic_idx]->pal = malloc(sizeof(unsigned char)*256*3); - if (!desc->pic_a[pic_idx]->pal) return -1; - for (i = 0; i<768; ++i) desc->pic_a[pic_idx]->pal[i] = i/3; - - desc->pic_b[pic_idx]->pal = malloc(sizeof(unsigned char)*256*3); - if (!desc->pic_b[pic_idx]->pal) return -1; - for (i = 0; i<768; ++i) desc->pic_b[pic_idx]->pal[i] = i/3; - -// ttime = GetTimer(); - err = check_font(desc, ppem, padding, pic_idx, charset_size, charset, charcodes, unicode); -// ttime=GetTimer()-ttime; -// printf("render: %7f us\n",ttime); - if (err) return -1; -// fprintf(stderr, "fg: render t = %f\n", GetTimer()-t); - - desc->pic_a[pic_idx]->w = desc->pic_b[pic_idx]->w; - desc->pic_a[pic_idx]->h = desc->pic_b[pic_idx]->h; - desc->pic_a[pic_idx]->c = colors; - - desc->pic_a[pic_idx]->bmp = NULL; - -// fprintf(stderr, "fg: w = %d, h = %d\n", desc->pic_a[pic_idx]->w, desc->pic_a[pic_idx]->h); - return 0; - -} - -static int generate_tables(font_desc_t *desc, double thickness, double radius) -{ - int width = desc->max_height; - int height = desc->max_width; - - double A = log(1.0/base)/(radius*radius*2); - int mx, my, i; - double volume_diff, volume_factor = 0; - unsigned char *omtp; - - desc->tables.g_r = ceil(radius); - desc->tables.o_r = ceil(thickness); - desc->tables.g_w = 2*desc->tables.g_r+1; - desc->tables.o_w = 2*desc->tables.o_r+1; - desc->tables.o_size = desc->tables.o_w * desc->tables.o_w; - -// fprintf(stderr, "o_r = %d\n", desc->tables.o_r); - - if (desc->tables.g_r) { - desc->tables.g = malloc(desc->tables.g_w * sizeof(unsigned)); - desc->tables.gt2 = malloc(256 * desc->tables.g_w * sizeof(unsigned)); - if (desc->tables.g==NULL || desc->tables.gt2==NULL) { - return -1; - } - } - desc->tables.om = malloc(desc->tables.o_w*desc->tables.o_w * sizeof(unsigned)); - desc->tables.omt = malloc(desc->tables.o_size*256); - - omtp = desc->tables.omt; - desc->tables.tmp = malloc((width+1)*height*sizeof(short)); - - if (desc->tables.om==NULL || desc->tables.omt==NULL || desc->tables.tmp==NULL) { - return -1; - }; - - if (desc->tables.g_r) { - // gaussian curve with volume = 256 - for (volume_diff=10000000; volume_diff>0.0000001; volume_diff*=0.5){ - volume_factor+= volume_diff; - desc->tables.volume=0; - for (i = 0; itables.g_w; ++i) { - desc->tables.g[i] = (unsigned)(exp(A * (i-desc->tables.g_r)*(i-desc->tables.g_r)) * volume_factor + .5); - desc->tables.volume+= desc->tables.g[i]; - } - if(desc->tables.volume>256) volume_factor-= volume_diff; - } - desc->tables.volume=0; - for (i = 0; itables.g_w; ++i) { - desc->tables.g[i] = (unsigned)(exp(A * (i-desc->tables.g_r)*(i-desc->tables.g_r)) * volume_factor + .5); - desc->tables.volume+= desc->tables.g[i]; - } - - // gauss table: - for(mx=0;mxtables.g_w;mx++){ - for(i=0;i<256;i++){ - desc->tables.gt2[mx+i*desc->tables.g_w] = i*desc->tables.g[mx]; - } - } - } - - /* outline matrix */ - for (my = 0; mytables.o_w; ++my) { - for (mx = 0; mxtables.o_w; ++mx) { - // antialiased circle would be perfect here, but this one is good enough - double d = thickness + 1 - sqrt((mx-desc->tables.o_r)*(mx-desc->tables.o_r)+(my-desc->tables.o_r)*(my-desc->tables.o_r)); - desc->tables.om[mx+my*desc->tables.o_w] = d>=1 ? base : d<=0 ? 0 : (d*base + .5); - } - } - - // outline table: - for(i=0;i<256;i++){ - for(mx=0;mxtables.o_size;mx++) *(omtp++) = (i*desc->tables.om[mx] + (base/2))/base; - } - - return 0; -} - -#ifdef CONFIG_ICONV -/* decode from 'encoding' to unicode */ -static FT_ULong decode_char(iconv_t *cd, char c) { - FT_ULong o; - char *inbuf = &c; - char *outbuf = (char*)&o; - size_t inbytesleft = 1; - size_t outbytesleft = sizeof(FT_ULong); - - iconv(*cd, &inbuf, &inbytesleft, &outbuf, &outbytesleft); - - /* convert unicode BigEndian -> MachineEndian */ - o = be2me_32(o); - - // if (count==-1) o = 0; // not OK, at least my iconv() returns E2BIG for all - if (outbytesleft!=0) o = 0; - - /* we don't want control characters */ - if (o>=0x7f && o<0xa0) o = 0; - return o; -} - -static int prepare_charset(char *charmap, char *encoding, FT_ULong *charset, FT_ULong *charcodes) { - FT_ULong i; - int count = 0; - int charset_size; - iconv_t cd; - - // check if ucs-4 is available - cd = iconv_open(charmap, charmap); - if (cd==(iconv_t)-1) { - mp_msg(MSGT_OSD, MSGL_ERR, "iconv doesn't know %s encoding. Use the source!\n", charmap); - return -1; - } - - iconv_close(cd); - - cd = iconv_open(charmap, encoding); - if (cd==(iconv_t)-1) { - mp_msg(MSGT_OSD, MSGL_ERR, "Unsupported encoding `%s', use iconv --list to list character sets known on your system.\n", encoding); - return -1; - } - - charset_size = 256 - first_char; - for (i = 0; icharmap==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; -} -#endif - -static font_desc_t* init_font_desc(void) -{ - font_desc_t *desc; - - desc = calloc(1, sizeof(*desc)); - if(!desc) return NULL; - - desc->dynamic = 1; - - /* setup sane defaults */ - desc->freetype = 1; - - memset(desc->start, 0xff, sizeof(desc->start)); - memset(desc->width, 0xff, sizeof(desc->width)); - memset(desc->font, 0xff, sizeof(desc->font)); - - 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 - - free(desc->name); - free(desc->fpath); - - for(i = 0; i < 16; i++) { - if (desc->pic_a[i]) { - free(desc->pic_a[i]->bmp); - free(desc->pic_a[i]->pal); - free(desc->pic_a[i]); - } - if (desc->pic_b[i]) { - free(desc->pic_b[i]->bmp); - free(desc->pic_b[i]->pal); - free(desc->pic_b[i]); - } - } - - free(desc->tables.g); - free(desc->tables.gt2); - free(desc->tables.om); - free(desc->tables.omt); - 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, int face_index, FT_Face *face) -{ - int err = -1; - - if (name) err = FT_New_Face(library, name, face_index, 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_tmsg(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_tmsg(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 face_index, int movie_width, int movie_height, float font_scale_factor) -{ - 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*font_scale_factor/100.0; - osd_font_ppem = movie_size*(font_scale_factor+1)/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_index, &face); - if (err) { - mp_tmsg(MSGT_OSD, MSGL_WARN, "subtitle font: load_sub_face failed.\n"); - goto gen_osd; - } - desc->face_cnt++; - -#ifdef CONFIG_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_tmsg(MSGT_OSD, MSGL_ERR, "subtitle font: prepare_charset failed.\n"); - goto err_out; - } -#else - goto err_out; -#endif - -// fprintf(stderr, "fg: prepare t = %f\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_tmsg(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_tmsg(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_tmsg(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_tmsg(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, float font_scale_factor) -{ -#ifdef CONFIG_FONTCONFIG - FcPattern *fc_pattern; - FcPattern *fc_pattern2; - FcChar8 *s; - int face_index; - FcBool scalable; - FcResult result; -#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 CONFIG_FONTCONFIG - if (font_fontconfig > 0) - { - FcInit(); - fc_pattern = FcNameParse(font_name ? font_name : "sans-serif"); - FcConfigSubstitute(0, fc_pattern, FcMatchPattern); - FcDefaultSubstitute(fc_pattern); - fc_pattern2 = fc_pattern; - fc_pattern = FcFontMatch(0, fc_pattern, &result); - if (fc_pattern) { - 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, &result); - FcPatternDestroy(fc_pattern2); - } - // s doesn't need to be freed according to fontconfig docs - FcPatternGetString(fc_pattern, FC_FILE, 0, &s); - FcPatternGetInteger(fc_pattern, FC_INDEX, 0, &face_index); - *fontp=read_font_desc_ft(s, face_index, width, height, font_scale_factor); - FcPatternDestroy(fc_pattern); - return; - } - mp_tmsg(MSGT_OSD, MSGL_ERR, "Fontconfig failed to select a font. " - "Trying without fontconfig...\n"); - } -#endif - *fontp=read_font_desc_ft(font_name, 0, width, height, font_scale_factor); -} diff --git a/sub/osd_dummy.c b/sub/osd_dummy.c new file mode 100644 index 0000000000..ff40c19301 --- /dev/null +++ b/sub/osd_dummy.c @@ -0,0 +1,43 @@ +#include +#include +#include + +#include "config.h" +#include "talloc.h" +#include "sub.h" + +void vo_update_text_osd(struct osd_state *osd, mp_osd_obj_t *obj) +{ +} + +void vo_update_text_teletext(struct osd_state *osd, mp_osd_obj_t *obj) +{ +} + +void vo_update_text_progbar(struct osd_state *osd, mp_osd_obj_t *obj) +{ +} + +void vo_update_text_sub(struct osd_state *osd, mp_osd_obj_t *obj) +{ +} + +void osd_init_backend(struct osd_state *osd) +{ +} + +void osd_destroy_backend(struct osd_state *osd) +{ +} + +void osd_font_invalidate(void) +{ +} + +void osd_font_load(struct osd_state *osd) +{ +} + +void osd_get_function_sym(char *buffer, size_t buffer_size, int osd_function) +{ +} diff --git a/sub/osd_ft.c b/sub/osd_ft.c deleted file mode 100644 index f44100a3b9..0000000000 --- a/sub/osd_ft.c +++ /dev/null @@ -1,969 +0,0 @@ -#include -#include -#include - -#include "config.h" -#include "stream/stream.h" -#include "stream/stream_dvdnav.h" -#define OSD_NAV_BOX_ALPHA 0x7f - -#include "libmpcodecs/dec_teletext.h" -#include "osdep/timer.h" - -#include "talloc.h" -#include "mplayer.h" -#include "path.h" -#include "mp_msg.h" -#include "libvo/video_out.h" -#include "sub.h" -#include "sub/font_load.h" -#include "spudec.h" -#include "libavutil/common.h" - -#define FONT_LOAD_DEFER 6 -#define NEW_SPLITTING - -//static int vo_font_loaded=-1; -font_desc_t* vo_font=NULL; - -// Structures needed for the new splitting algorithm. -// osd_text_t contains the single subtitle word. -// osd_text_p is used to mark the lines of subtitles -struct osd_text_t { - int osd_kerning, //kerning with the previous word - osd_length, //orizontal length inside the bbox - text_length, //number of characters - *text; //characters - struct osd_text_t *prev, - *next; -}; - -struct osd_text_p { - int value; - struct osd_text_t *ott; - struct osd_text_p *prev, - *next; -}; -//^ - - -// return the real height of a char: -static inline int get_height(int c,int h){ - int font; - if ((font=vo_font->font[c])>=0) - if(hpic_a[font]->h) h=vo_font->pic_a[font]->h; - return h; -} - - -void vo_update_text_osd(struct osd_state *osd, mp_osd_obj_t *obj) -{ - const char *cp = osd->osd_text; - int x=20; - int h=0; - int font; - - obj->bbox.x1=obj->x=x; - obj->bbox.y1=obj->y=10; - - while (*cp){ - uint16_t c=utf8_get_char(&cp); - render_one_glyph(vo_font, c); - x+=vo_font->width[c]+vo_font->charspace; - h=get_height(c,h); - } - - obj->bbox.x2=x-vo_font->charspace; - obj->bbox.y2=obj->bbox.y1+h; - obj->flags|=OSDFLAG_BBOX; - - osd_alloc_buf(obj); - - cp = osd->osd_text; - x = obj->x; - while (*cp){ - uint16_t c=utf8_get_char(&cp); - if ((font=vo_font->font[c])>=0) - draw_alpha_buf(obj,x,obj->y, - vo_font->width[c], - vo_font->pic_a[font]->h, - vo_font->pic_b[font]->bmp+vo_font->start[c], - vo_font->pic_a[font]->bmp+vo_font->start[c], - vo_font->pic_a[font]->w); - x+=vo_font->width[c]+vo_font->charspace; - } -} - -static int vo_osd_teletext_scale=0; - -// renders char to a big per-object buffer where alpha and bitmap are separated -static void tt_draw_alpha_buf(mp_osd_obj_t* obj, int x0,int y0, int w,int h, unsigned char* src, int stride,int fg,int bg,int alpha) -{ - int dststride = obj->stride; - int dstskip = obj->stride-w; - int srcskip = stride-w; - int i, j; - unsigned char *b = obj->bitmap_buffer + (y0-obj->bbox.y1)*dststride + (x0-obj->bbox.x1); - unsigned char *a = obj->alpha_buffer + (y0-obj->bbox.y1)*dststride + (x0-obj->bbox.x1); - unsigned char *bs = src; - if (x0 < obj->bbox.x1 || x0+w > obj->bbox.x2 || y0 < obj->bbox.y1 || y0+h > obj->bbox.y2) { - mp_msg(MSGT_OSD,MSGL_ERR,"tt osd text out of range: bbox [%d %d %d %d], txt [%d %d %d %d]\n", - obj->bbox.x1, obj->bbox.x2, obj->bbox.y1, obj->bbox.y2, - x0, x0+w, y0, y0+h); - return; - } - for (i = 0; i < h; i++) { - for (j = 0; j < w; j++, b++, a++, bs++) { - *b=(fg-bg)*(*bs)/255+bg; - *a=alpha; - } - b+= dstskip; - a+= dstskip; - bs+= srcskip; - } -} -void vo_update_text_teletext(struct osd_state *osd, mp_osd_obj_t *obj) -{ - int h=0,w=0,i,j,font,flashon; - int wm,hm; - int color; - int x,y,x0,y0; - int cols,rows; - int wm12; - int hm13; - int hm23; - int start_row,max_rows; - int b,ax[6],ay[6],aw[6],ah[6]; - tt_char tc; - tt_char* tdp=vo_osd_teletext_page; - static const uint8_t colors[8]={1,85,150,226,70,105,179,254}; - unsigned char* buf[9]; - int dxs = osd->w, dys = osd->h; - - obj->flags|=OSDFLAG_CHANGED|OSDFLAG_VISIBLE; - if (!tdp || !vo_osd_teletext_mode) { - obj->flags&=~OSDFLAG_VISIBLE; - return; - } - flashon=(GetTimer()/1000000)%2; - switch(vo_osd_teletext_half){ - case TT_ZOOM_TOP_HALF: - start_row=0; - max_rows=VBI_ROWS/2; - break; - case TT_ZOOM_BOTTOM_HALF: - start_row=VBI_ROWS/2; - max_rows=VBI_ROWS/2; - break; - default: - start_row=0; - max_rows=VBI_ROWS; - break; - } - wm=0; - for(i=start_row;iwidth[tc.unicode]) - wm=vo_font->width[tc.unicode]; - } - } - } - - hm=vo_font->height+1; - wm=dxs*hm*max_rows/(dys*VBI_COLUMNS); - -#ifdef CONFIG_FREETYPE - //very simple teletext font auto scaling - if(!vo_osd_teletext_scale && hm*(max_rows+1)>dys){ - osd_font_scale_factor*=1.0*(dys)/((max_rows+1)*hm); - force_load_font=1; - vo_osd_teletext_scale=osd_font_scale_factor; - obj->flags&=~OSDFLAG_VISIBLE; - return; - } -#endif - - cols=dxs/wm; - rows=dys/hm; - - if(cols>VBI_COLUMNS) - cols=VBI_COLUMNS; - if(rows>max_rows) - rows=max_rows; - w=cols*wm-vo_font->charspace; - h=rows*hm-vo_font->charspace; - - if(w>1; - hm13=(hm+1)/3; - hm23=hm13<<1; - - for(i=0;i<6;i+=2){ - ax[i+0]=0; - aw[i+0]=wm12; - - ax[i+1]=wm12; - aw[i+1]=wm-wm12; - } - - for(i=0;i<2;i++){ - ay[i+0]=0; - ah[i+0]=hm13; - - ay[i+2]=hm13; - ah[i+2]=hm-hm23; - - ay[i+4]=hm-hm13; - ah[i+4]=hm13; - } - - obj->x = 0; - obj->y = 0; - obj->bbox.x1 = x0; - obj->bbox.y1 = y0; - obj->bbox.x2 = x0+w; - obj->bbox.y2 = y0+h; - obj->flags |= OSDFLAG_BBOX; - osd_alloc_buf(obj); - - for(i=0;i<9;i++) - buf[i]=malloc(wm*hm); - - //alpha - if(vo_osd_teletext_format==TT_FORMAT_OPAQUE ||vo_osd_teletext_format==TT_FORMAT_OPAQUE_INV) - color=1; - else - color=200; - memset(buf[8],color,wm*hm); - //colors - if(vo_osd_teletext_format==TT_FORMAT_OPAQUE ||vo_osd_teletext_format==TT_FORMAT_TRANSPARENT){ - for(i=0;i<8;i++){ - memset(buf[i],(unsigned char)(1.0*(255-color)*colors[i]/255),wm*hm); - } - }else{ - for(i=0;i<8;i++) - memset(buf[i],(unsigned char)(1.0*(255-color)*colors[7-i]/255),wm*hm); - } - - y=y0; - for(i=0;ifont[tc.unicode])>=0 && y+hmwidth[tc.unicode],vo_font->height, - vo_font->pic_b[font]->bmp+vo_font->start[tc.unicode]-vo_font->charspace*vo_font->pic_a[font]->w, - vo_font->pic_b[font]->w, - buf[tc.fg][0],buf[tc.bg][0],buf[8][0]); - } - }else{ -/* -Rendering one graphics character -TODO: support for separated graphics symbols (where six rectangles does not touch each other) - - +--+ +--+ 87654321 - |01| |12| -------- - |10| <= |34| <= 00100110 <= 0x26 - |01| |56| - +--+ +--+ - -(0:wm/2) (wm/2:wm-wm/2) - -********** *********** (0:hm/3) -*** **** **** **** -*** 1 **** **** 2 **** -*** **** **** **** -********** *********** -********** *********** - -********** *********** (hm/3:hm-2*hm/3) -********** *********** -*** **** **** **** -*** 3 **** **** 4 **** -*** **** **** **** -********** *********** -********** *********** -********** *********** - -********** *********** (hm-hm/3:hm/3) -*** **** **** **** -*** 5 **** **** 6 **** -*** **** **** **** -********** *********** -********** *********** - -*/ - if(tc.gfx>1){ //separated gfx - for(b=0;b<6;b++){ - color=(tc.unicode>>b)&1?tc.fg:tc.bg; - draw_alpha_buf(obj,x+ax[b]+1,y+ay[b]+1,aw[b]-2,ah[b]-2,buf[color],buf[8],wm); - } - //separated gfx (background borders) - //vertical - draw_alpha_buf(obj,x ,y,1,hm,buf[tc.bg],buf[8],wm); - draw_alpha_buf(obj,x+ax[1]-1,y,2,hm,buf[tc.bg],buf[8],wm); - draw_alpha_buf(obj,x+ax[1]+aw[1]-1,y,wm-ax[1]-aw[1]+1,hm,buf[tc.bg],buf[8],wm); - //horizontal - draw_alpha_buf(obj,x,y ,wm,1,buf[tc.bg],buf[8],wm); - draw_alpha_buf(obj,x,y+ay[0]+ah[0]-1,wm,2,buf[tc.bg],buf[8],wm); - draw_alpha_buf(obj,x,y+ay[2]+ah[2]-1,wm,2,buf[tc.bg],buf[8],wm); - draw_alpha_buf(obj,x,y+ay[4]+ah[4]-1,wm,hm-ay[4]-ah[4]+1,buf[tc.bg],buf[8],wm); - }else{ - for(b=0;b<6;b++){ - color=(tc.unicode>>b)&1?tc.fg:tc.bg; - draw_alpha_buf(obj,x+ax[b],y+ay[b],aw[b],ah[b],buf[color],buf[8],wm); - } - } - } - x+=wm; - } - y+=hm; - } - for(i=0;i<9;i++) - free(buf[i]); -} - -// if we have n=256 bars then OSD progbar looks like below -// -// 0 1 2 3 ... 256 <= vo_osd_progbar_value -// | | | | | -// [ === === === ... === ] -// -// the above schema is rescalled to n=elems bars - -void vo_update_text_progbar(struct osd_state *osd, mp_osd_obj_t *obj){ - - obj->flags|=OSDFLAG_CHANGED|OSDFLAG_VISIBLE; - - if(vo_osd_progbar_type<0 || !vo_font){ - obj->flags&=~OSDFLAG_VISIBLE; - return; - } - - render_one_glyph(vo_font, OSD_PB_START); - render_one_glyph(vo_font, OSD_PB_END); - render_one_glyph(vo_font, OSD_PB_0); - render_one_glyph(vo_font, OSD_PB_1); - render_one_glyph(vo_font, vo_osd_progbar_type); - - // calculate bbox corners: - { int h=0; - int y=(osd->h-vo_font->height)/2; - int delimw=vo_font->width[OSD_PB_START] - +vo_font->width[OSD_PB_END] - +vo_font->charspace; - int width=(2*osd->w-3*delimw)/3; - int charw=vo_font->width[OSD_PB_0]+vo_font->charspace; - int elems=width/charw; - int x=(osd->w-elems*charw-delimw)/2; - int delta = 0; - h=get_height(OSD_PB_START,h); - h=get_height(OSD_PB_END,h); - h=get_height(OSD_PB_0,h); - h=get_height(OSD_PB_1,h); - if (vo_osd_progbar_type>0 && vo_font->font[vo_osd_progbar_type]>=0){ - delta = vo_font->width[vo_osd_progbar_type]+vo_font->spacewidth; - delta = (x-delta > 0) ? delta : x; - h=get_height(vo_osd_progbar_type,h); - } - obj->bbox.x1=obj->x=x; - obj->bbox.y1=obj->y=y; - obj->bbox.x2=x+width+delimw; - obj->bbox.y2=y+h; //vo_font->height; - obj->flags|=OSDFLAG_BBOX; - obj->params.progbar.elems=elems; - obj->bbox.x1-=delta; // space for an icon - } - - osd_alloc_buf(obj); - - { - int minw = vo_font->width[OSD_PB_START]+vo_font->width[OSD_PB_END]+vo_font->width[OSD_PB_0]; - if (vo_osd_progbar_type>0 && vo_font->font[vo_osd_progbar_type]>=0){ - minw += vo_font->width[vo_osd_progbar_type]+vo_font->charspace+vo_font->spacewidth; - } - if (obj->bbox.x2 - obj->bbox.x1 < minw) return; // space too small, don't render anything - } - - // render it: - { unsigned char *s; - unsigned char *sa; - int i,w,h,st,mark; - int x=obj->x; - int y=obj->y; - int c,font; - int charw=vo_font->width[OSD_PB_0]+vo_font->charspace; - int elems=obj->params.progbar.elems; - - if (vo_osd_progbar_value<=0) - mark=0; - else { - int ev=vo_osd_progbar_value*elems; - mark=ev>>8; - if (ev & 0xFF) mark++; - if (mark>elems) mark=elems; - } - - -// printf("osd.progbar width=%d xpos=%d\n",width,x); - - c=vo_osd_progbar_type; - if(vo_osd_progbar_type>0 && (font=vo_font->font[c])>=0) { - int xp=x-vo_font->width[c]-vo_font->spacewidth; - draw_alpha_buf(obj,(xp<0?0:xp),y, - vo_font->width[c], - vo_font->pic_a[font]->h, - vo_font->pic_b[font]->bmp+vo_font->start[c], - vo_font->pic_a[font]->bmp+vo_font->start[c], - vo_font->pic_a[font]->w); - } - - c=OSD_PB_START; - if ((font=vo_font->font[c])>=0) - draw_alpha_buf(obj,x,y, - vo_font->width[c], - vo_font->pic_a[font]->h, - vo_font->pic_b[font]->bmp+vo_font->start[c], - vo_font->pic_a[font]->bmp+vo_font->start[c], - vo_font->pic_a[font]->w); - x+=vo_font->width[c]+vo_font->charspace; - - c=OSD_PB_0; - if ((font=vo_font->font[c])>=0){ - w=vo_font->width[c]; - h=vo_font->pic_a[font]->h; - s=vo_font->pic_b[font]->bmp+vo_font->start[c]; - sa=vo_font->pic_a[font]->bmp+vo_font->start[c]; - st=vo_font->pic_a[font]->w; - if ((i=mark)) do { - draw_alpha_buf(obj,x,y,w,h,s,sa,st); - x+=charw; - } while(--i); - } - - c=OSD_PB_1; - if ((font=vo_font->font[c])>=0){ - w=vo_font->width[c]; - h=vo_font->pic_a[font]->h; - s =vo_font->pic_b[font]->bmp+vo_font->start[c]; - sa=vo_font->pic_a[font]->bmp+vo_font->start[c]; - st=vo_font->pic_a[font]->w; - if ((i=elems-mark)) do { - draw_alpha_buf(obj,x,y,w,h,s,sa,st); - x+=charw; - } while(--i); - } - - c=OSD_PB_END; - if ((font=vo_font->font[c])>=0) - draw_alpha_buf(obj,x,y, - vo_font->width[c], - vo_font->pic_a[font]->h, - vo_font->pic_b[font]->bmp+