[MPlayer-dev-eng] [PATCH][RFC] Font layer fixes/improvements

Krzysztof Rusocki kszysiu at iceberg.elsat.net.pl
Tue Feb 17 04:07:25 CET 2004


Hi,

While using MPlayer 1.0pre3 we've encountered few
issues related to font handling, attached patch
(against CVS as of 2004-02-13) (implicitly or explicitly)
tries to deal with them.

Before you go on and your blood pressure reaches
extraordinarily high values... keep in mind that:

- although I've tried not to break mplayer's design
  it is quite possible that I missed something
  (these are my first steps with mplayer sources),

- this patch does not tend to be a complete solution
  (docs modification is not done, console
   messages are probably excessive), I'd rather
  would like to hear from you whether the steps
  I've taken are the good way to fix things,


THE DETAILS

If mplayer is compiled with HAVE_FREETYPE and HAVE_FONTCONFIG
following things happen:

1. When launched:

    $ (g)mplayer -font nonexistant

  mplayer segfaults when it's about to show osd
  see libvo/sub.c:~610 - vo_font->font[40] is -1
  thus we end with negative array offset

  (the patch does not fix this since I didn't figure
   out how to cope with this cleanly)

2. In Gui font is reloaded on every widget activity
  (size bars and scale radio buttons), it seems to be
  quite significant and needless (?) overhead. 

3. With -fontconfig, it is impossible to load font
  via file dialog in Gui (or by -font parameter), this
  seems pretty confusing - one would expect a .ttf/.pfb
  to be loaded from file dialog.

4. Despite being configured with Freetype, mplayer
  tries (needlessly) to load .desc font on startup
  and if such font gets loaded - then:
  
  4.1. If -font is specified - loaded .desc font is
      overridden by freetype font_load_ft codepath anyway
  4.2. If -font is NOT specified - default freetype font
      (subfont.ttf) isn't touched at all, while (I believe)
      it should be tried.

5. When launched:

    $ mplayer -zoom -fs

  (with autoscale enabled) font is scaled to original (unzoomed) movie
  dimensions.


The patch is fairly large, but, I think that changes will ease
future development... Here's what has been done (in general),

I've created a fairly unified interface for font loading
(libvo/font_if.{c,h}), so there's no need to put so many #ifdefs
around or wonder ,,what if we have freetype enabled? or not?''

int init_font();
int uninit_font();
void render_one_glyph(font_desc_t *desc, int c);
int kerning(font_desc_t *desc, int prevc, int c);

These work similarily to the previous ones, i.e. they do things when
freetype is enabled, otherwise they are no-ops.

void free_font_desc(font_desc_t *desc);

free_font_desc() has been moved from load_font_ft.c, since it's rather
common function for fonts.

#define load_font(n, w, h) _load_font(n, w, h, __FILE__, __LINE__)
void _load_font(char * name, int width, int height, char * fn, int ln);

That's the most tricky thing, load_font tries to load font with specified
name, the font is loaded in either of three cases:

- no font has been loaded at all
- screen dimensions's changed
- force_load_font variable was set to non-zero value

The way font is loaded depends on HAVE_FREETYPE. If defined - the order of
things is as follows (font_if.c/try_load_font_ft()):

- load font "name" via freetype, if it fails,
- load font "name" via freetype+fontconfig (if supported), if it fails,
- load default font (subfont.ttf) via freetype, if it fails,
- load default fontconfig font ("sans-serif") (if supported),

If font still isn't loaded, there is a codepath that loads only OSD face,
however that causes a segfault mentioned earlier (1), hence it is disabled.

Now, let's move to the case when there's no freetype (try_load_font_desc()).
That is a simple
- load font "name"
- load default font
fallback.

Mentioned changes allow easier font (re)loading and unloading, see changes in
Gui/interface.c, mplayer.c, mencoder.c.

I have removed -fontconfig/-nofontconfig options since they seem superfluous
in face of font load code proposed in the patch, I didn't find any reason
why they should be kept.


If you need more info, feel free to mail,
also, any feedback is welcome (including napalm).


Cheers,
Krzysztof
-------------- next part --------------
diff -Nru main.orig/cfg-common.h main/cfg-common.h
--- main.orig/cfg-common.h	2004-02-05 18:08:55.000000000 +0100
+++ main/cfg-common.h	2004-02-16 23:39:26.381981536 +0100
@@ -260,13 +260,7 @@
  	{"subfont-outline", &subtitle_font_thickness, CONF_TYPE_FLOAT, CONF_RANGE, 0, 8, NULL},
  	{"subfont-autoscale", &subtitle_autoscale, CONF_TYPE_INT, CONF_RANGE, 0, 3, NULL},
 #endif
-#ifdef HAVE_FONTCONFIG
-	{"fontconfig", &font_fontconfig, CONF_TYPE_FLAG, 0, 0, 1, NULL},
-	{"nofontconfig", &font_fontconfig, CONF_TYPE_FLAG, 0, 1, 0, NULL},
-#else
-	{"fontconfig", "MPlayer wasn't compiled with Fontconfig support\n", CONF_TYPE_PRINT, CONF_NOCFG, 0, 0, NULL},
-	{"nofontconfig", "MPlayer wasn't compiled with Fontconfig support\n", CONF_TYPE_PRINT, CONF_NOCFG, 0, 0, NULL},
-#endif
+
 #endif
 
 #else
diff -Nru main.orig/Gui/cfg.c main/Gui/cfg.c
--- main.orig/Gui/cfg.c	2003-11-08 01:26:44.000000000 +0100
+++ main/Gui/cfg.c	2004-02-16 23:39:26.383981232 +0100
@@ -8,6 +8,7 @@
 #include "../mplayer.h"
 #include "../m_config.h"
 #include "../m_option.h"
+#include "../libvo/font_if.h"
 
 #ifdef USE_SETLOCALE
 #include <locale.h>
diff -Nru main.orig/Gui/interface.c main/Gui/interface.c
--- main.orig/Gui/interface.c	2004-02-03 20:02:45.000000000 +0100
+++ main/Gui/interface.c	2004-02-16 23:40:24.582133768 +0100
@@ -22,7 +22,7 @@
 #include "../subreader.h"
 #include "../libvo/x11_common.h"
 #include "../libvo/video_out.h"
-#include "../libvo/font_load.h"
+#include "../libvo/font_if.h"
 #include "../libvo/sub.h"
 #include "../input/input.h"
 #include "../libao2/audio_out.h"
@@ -373,44 +373,8 @@
 #if defined( USE_OSD ) || defined( USE_SUB )
 void guiLoadFont( void )
 {
-#ifdef HAVE_FREETYPE
-  load_font_ft(vo_image_width, vo_image_height);
-#else
- if ( vo_font )
-  {
-   int i;
-   if ( vo_font->name ) free( vo_font->name );
-   if ( vo_font->fpath ) free( vo_font->fpath );
-   for ( i=0;i<16;i++ )
-    if ( vo_font->pic_a[i] )
-     {
-      if ( vo_font->pic_a[i]->bmp ) free( vo_font->pic_a[i]->bmp );
-      if ( vo_font->pic_a[i]->pal ) free( vo_font->pic_a[i]->pal );
-     }
-   for ( i=0;i<16;i++ )
-    if ( vo_font->pic_b[i] )
-     {
-      if ( vo_font->pic_b[i]->bmp ) free( vo_font->pic_b[i]->bmp );
-      if ( vo_font->pic_b[i]->pal ) free( vo_font->pic_b[i]->pal );
-     }
-   free( vo_font ); vo_font=NULL;
-  }
- if ( font_name )
-  {
-   vo_font=read_font_desc( font_name,font_factor,0 );
-   if ( !vo_font ) mp_msg( MSGT_CPLAYER,MSGL_ERR,MSGTR_CantLoadFont,font_name );
-  } 
-  else
-   {
-    font_name=gstrdup( get_path( "font/font.desc" ) );
-    vo_font=read_font_desc( font_name,font_factor,0 );
-    if ( !vo_font )
-     {
-      gfree( (void **)&font_name ); font_name=gstrdup(MPLAYER_DATADIR "/font/font.desc" );
-      vo_font=read_font_desc( font_name,font_factor,0 );
-     }
-   }
-#endif
+  force_load_font = 1;
+  load_font(font_name, vo_image_width, vo_image_height);
 }
 #endif
 
@@ -999,33 +963,26 @@
 #ifndef HAVE_FREETYPE
    case gtkSetFontFactor:
         font_factor=fparam;
-	guiLoadFont();
 	return NULL;
 #else
    case gtkSetFontOutLine:
         subtitle_font_thickness=( 8.0f / 100.0f ) * fparam;
-	guiLoadFont();
 	return NULL;
    case gtkSetFontBlur:
 	subtitle_font_radius=( 8.0f / 100.0f ) * fparam;
-	guiLoadFont();
 	return NULL;
    case gtkSetFontTextScale:
 	text_font_scale_factor=fparam;
-	guiLoadFont();
 	return NULL;
    case gtkSetFontOSDScale:
 	osd_font_scale_factor=fparam;
-	guiLoadFont();
 	return NULL;
    case gtkSetFontEncoding:
 	gfree( (void **)&subtitle_font_encoding );
 	subtitle_font_encoding=gstrdup( (char *)vparam );
-	guiLoadFont();
 	return NULL;
    case gtkSetFontAutoScale:
 	subtitle_autoscale=(int)fparam;
-	guiLoadFont();
 	return NULL;
 #endif
 #ifdef USE_ICONV
diff -Nru main.orig/Gui/interface.h main/Gui/interface.h
--- main.orig/Gui/interface.h	2003-08-15 13:55:21.000000000 +0200
+++ main/Gui/interface.h	2004-02-16 23:39:26.390980168 +0100
@@ -5,7 +5,6 @@
 #include "../config.h"
 #include "mplayer/play.h"
 #include "../mplayer.h"
-#include "../libvo/font_load.h"
 #include "cfg.h"
 
 #ifdef USE_DVDREAD
diff -Nru main.orig/Gui/mplayer/gtk/opts.c main/Gui/mplayer/gtk/opts.c
--- main.orig/Gui/mplayer/gtk/opts.c	2004-02-03 20:02:45.000000000 +0100
+++ main/Gui/mplayer/gtk/opts.c	2004-02-16 23:39:26.394979560 +0100
@@ -12,6 +12,7 @@
 #include "../../../mixer.h"
 #include "../../../libao2/audio_out.h"
 #include "../../../libvo/video_out.h"
+#include "../libvo/font_if.h"
 
 #include "../../app.h"
 #include "../../cfg.h"
@@ -570,6 +571,7 @@
 	if ( gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( RBFontAutoScaleWidth ) ) ) gtkSet( gtkSetFontAutoScale,2,NULL );
 	if ( gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( RBFontAutoScaleDiagonal ) ) ) gtkSet( gtkSetFontAutoScale,3,NULL );
 #endif
+	guiLoadFont();
 
 	// -- 5. page
 	force_ni=gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( CBNonInterlaved ) );
diff -Nru main.orig/libmenu/menu.c main/libmenu/menu.c
--- main.orig/libmenu/menu.c	2003-08-16 11:50:45.000000000 +0200
+++ main/libmenu/menu.c	2004-02-16 23:39:26.397979104 +0100
@@ -8,7 +8,7 @@
 #include <unistd.h>
 
 #include "../libvo/osd.h"
-#include "../libvo/font_load.h"
+#include "../libvo/font_if.h"
 #include "../osdep/keycodes.h"
 #include "../asxparser.h"
 #include "../libmpdemux/stream.h"
diff -Nru main.orig/libmenu/menu_cmdlist.c main/libmenu/menu_cmdlist.c
--- main.orig/libmenu/menu_cmdlist.c	2002-12-28 19:51:09.000000000 +0100
+++ main/libmenu/menu_cmdlist.c	2004-02-16 23:39:26.399978800 +0100
@@ -15,7 +15,7 @@
 #include "menu.h"
 #include "menu_list.h"
 
-#include "../libvo/font_load.h"
+#include "../libvo/font_if.h"
 
 #include "../input/input.h"
 #include "../version.h"
diff -Nru main.orig/libmenu/menu_console.c main/libmenu/menu_console.c
--- main.orig/libmenu/menu_console.c	2003-09-13 20:02:20.000000000 +0200
+++ main/libmenu/menu_console.c	2004-02-16 23:39:26.407977584 +0100
@@ -20,7 +20,7 @@
 #include "../m_option.h"
 #include "menu.h"
 
-#include "../libvo/font_load.h"
+#include "../libvo/font_if.h"
 #include "../osdep/keycodes.h"
 #include "../input/input.h"
 #include "../osdep/timer.h"
diff -Nru main.orig/libmenu/menu_list.c main/libmenu/menu_list.c
--- main.orig/libmenu/menu_list.c	2003-09-24 09:35:59.000000000 +0200
+++ main/libmenu/menu_list.c	2004-02-16 23:39:26.409977280 +0100
@@ -12,7 +12,7 @@
 #include "m_struct.h"
 #include "menu.h"
 
-#include "../libvo/font_load.h"
+#include "../libvo/font_if.h"
 #include "../osdep/keycodes.h"
 
 #define IMPL 1
diff -Nru main.orig/libmenu/menu_txt.c main/libmenu/menu_txt.c
--- main.orig/libmenu/menu_txt.c	2003-02-09 21:18:20.000000000 +0100
+++ main/libmenu/menu_txt.c	2004-02-16 23:39:26.412976824 +0100
@@ -12,7 +12,7 @@
 #include "../m_option.h"
 #include "menu.h"
 
-#include "../libvo/font_load.h"
+#include "../libvo/font_if.h"
 #include "../osdep/keycodes.h"
 
 struct menu_priv_s {
diff -Nru main.orig/libmenu/vf_menu.c main/libmenu/vf_menu.c
--- main.orig/libmenu/vf_menu.c	2003-07-09 03:30:23.000000000 +0200
+++ main/libmenu/vf_menu.c	2004-02-16 23:39:26.414976520 +0100
@@ -17,9 +17,10 @@
 
 #include "../libvo/fastmemcpy.h"
 #include "../libvo/video_out.h"
-#include "../libvo/font_load.h"
+#include "../libvo/font_if.h"
 #include "../input/input.h"
 #include "../m_struct.h"
+#include "../mplayer.h" // font_name
 #include "menu.h"
 
 extern vo_functions_t* video_out;
@@ -242,13 +243,8 @@
 
 static int config(struct vf_instance_s* vf, int width, int height, int d_width, int d_height,
 		  unsigned int flags, unsigned int outfmt) { 
-#ifdef HAVE_FREETYPE    
   // here is the right place to get screen dimensions
-  if (force_load_font) {
-    force_load_font = 0;
-    load_font_ft(width,height);
-  }
-#endif
+  load_font(font_name, width, height);
   return vf_next_config(vf,width,height,d_width,d_height,flags,outfmt);
 }
 static int open(vf_instance_t *vf, char* args){
diff -Nru main.orig/libvo/font_if.c main/libvo/font_if.c
--- main.orig/libvo/font_if.c	1970-01-01 01:00:00.000000000 +0100
+++ main/libvo/font_if.c	2004-02-17 00:21:13.173891240 +0100
@@ -0,0 +1,189 @@
+
+#include "config.h"
+#include <stdlib.h>
+#include "font_load.h"
+#include "font_load_ft.h"
+#include "../mplayer.h"
+#include "../mp_msg.h"
+#include "font_if.h"
+
+extern char *get_path(char *filename);
+
+int vo_image_width = 0;
+int vo_image_height = 0;
+
+int force_load_font; /* set to 1 when some component requests font reload */
+static int font_loaded = 0;
+
+#ifdef HAVE_FREETYPE
+char *subtitle_font_encoding = NULL;
+float text_font_scale_factor = 5.0;
+float osd_font_scale_factor = 6.0;
+float subtitle_font_radius = 2.0;
+float subtitle_font_thickness = 2.0;
+// 0 = no autoscale
+// 1 = video height
+// 2 = video width
+// 3 = diagonal
+int subtitle_autoscale = 3;
+#endif
+
+int init_font()
+{
+	int ret = 0;
+#ifdef HAVE_FREETYPE
+	ret = init_freetype();
+#endif
+	return ret;
+}
+
+int uninit_font()
+{
+	int ret = 0;
+	if (vo_font)
+		free_font_desc(vo_font);
+	vo_font = NULL;
+#ifdef HAVE_FREETYPE
+	ret = done_freetype();
+#endif
+	return ret;
+}
+
+void render_one_glyph(font_desc_t *desc, int c)
+{
+#ifdef HAVE_FREETYPE
+	render_one_glyph_ft(desc, c);
+#endif
+}
+
+int kerning(font_desc_t *desc, int prevc, int c)
+{
+	int ret = 0;
+	
+#ifdef HAVE_FREETYPE
+	ret = kerning_ft(desc, prevc, c);
+#endif
+	return ret;
+}
+
+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);
+	}
+	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);
+	}
+    }
+
+#ifdef HAVE_FREETYPE
+    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]);
+    }
+#endif
+
+    free(desc);
+}
+
+void try_load_font_desc(char * name, int width, int height)
+{
+	if (name) {
+		vo_font = read_font_desc(name, font_factor, verbose>1);
+		if (vo_font)
+			return;
+	}
+    	mp_msg(MSGT_CPLAYER,MSGL_INFO,"Trying default fonts...\n");
+	vo_font = read_font_desc(get_path("font/font.desc"), font_factor, verbose>1);
+	if (vo_font)
+		return;
+	vo_font = read_font_desc(MPLAYER_DATADIR "/font/font.desc", font_factor, verbose>1);
+}
+
+#ifdef HAVE_FREETYPE
+void try_load_font_ft(char * name, int width, int height)
+{
+	if (name) {
+		load_font_ft(name, width, height);
+		if (vo_font)
+			return;
+		load_font_fc_ft(name, width, height);
+		if (vo_font)
+			return;
+	}
+    	mp_msg(MSGT_CPLAYER,MSGL_INFO,"Trying default fonts...\n");
+	load_font_ft(get_path("subfont.ttf"), width, height);
+	if (vo_font)
+		return;
+	load_font_ft(MPLAYER_DATADIR "/subfont.ttf", width, height);
+	if (vo_font)
+		return;
+	load_font_fc_ft("sans-serif", width, height);
+	if (vo_font)
+		return;
+
+	/*
+	 * load OSD face only
+	 * segfaults in sub.c:~611, vo_font->font[40] == -1
+	 */
+	/* load_font_ft(NULL, width, height); */
+}
+#endif
+
+void _load_font(char * name, int width, int height, char * fn, int ln)
+{
+	//mp_msg(MSGT_CPLAYER,MSGL_INFO, "%s:%d: load_font: w: %d, h: %d, force: %d, loaded: %d\n", fn, ln, width, height, force_load_font, font_loaded);
+
+#ifdef HAVE_FREETYPE
+	if (vo_image_width != width || vo_image_height != height) {
+		force_load_font = 1;
+	}
+#endif
+
+	vo_image_width = width;
+	vo_image_height = height;
+
+	if (vo_font) {
+		if (force_load_font == 0)
+			return;
+#ifdef HAVE_FREETYPE
+		// protection against vo_aa font hacks
+		if (!vo_font->dynamic) {
+			force_load_font = 0;
+			return;
+		}
+#endif
+		free_font_desc(vo_font);
+		font_loaded = 0;
+		vo_font = NULL;
+	}
+	if (font_loaded && force_load_font == 0)
+		return;
+	force_load_font = 0;
+	font_loaded = 1;
+#ifdef HAVE_FREETYPE
+	try_load_font_ft(name, width, height);
+#else
+	try_load_font_desc(name, width, height);
+#endif
+	if (!vo_font) {
+		mp_msg(MSGT_CPLAYER,MSGL_INFO, "No fonts found!\n");
+	}
+}
diff -Nru main.orig/libvo/font_if.h main/libvo/font_if.h
--- main.orig/libvo/font_if.h	1970-01-01 01:00:00.000000000 +0100
+++ main/libvo/font_if.h	2004-02-16 23:39:26.420975608 +0100
@@ -0,0 +1,91 @@
+
+#ifndef __MPLAYER_FONT_IF_H
+#define __MPLAYER_FONT_IF_H
+
+#include "config.h"
+#ifdef HAVE_FREETYPE
+#include <ft2build.h>
+#include FT_FREETYPE_H
+#endif
+
+typedef struct {
+    unsigned char *bmp;
+    unsigned char *pal;
+    int w,h,c;
+#ifdef HAVE_FREETYPE
+    int charwidth,charheight,pen,baseline,padding;
+    int current_count, current_alloc;
+#endif
+} raw_file;
+
+typedef struct {
+#ifdef HAVE_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 HAVE_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 force_load_font;
+
+extern int vo_image_width;
+extern int vo_image_height;
+
+#ifdef HAVE_FREETYPE
+extern char *subtitle_font_encoding;
+extern float text_font_scale_factor;
+extern float osd_font_scale_factor;
+extern float subtitle_font_radius;
+extern float subtitle_font_thickness;
+extern int subtitle_autoscale;
+#endif
+
+int init_font();
+int uninit_font();
+
+void render_one_glyph(font_desc_t *desc, int c);
+int kerning(font_desc_t *desc, int prevc, int c);
+void free_font_desc(font_desc_t *desc);
+
+#define load_font(n, w, h) _load_font(n, w, h, __FILE__, __LINE__)
+void _load_font(char * name, int width, int height, char * fn, int ln);
+
+#endif /* ! __MPLAYER_FONT_IF_H */
diff -Nru main.orig/libvo/font_load_ft.c main/libvo/font_load_ft.c
--- main.orig/libvo/font_load_ft.c	2003-12-08 14:30:30.000000000 +0100
+++ main/libvo/font_load_ft.c	2004-02-16 23:45:22.117901456 +0100
@@ -38,25 +38,7 @@
 #define HAVE_FREETYPE21
 #endif
 
-char *get_path(char *filename);
-
-char *subtitle_font_encoding = NULL;
-float text_font_scale_factor = 5.0;
-float osd_font_scale_factor = 6.0;
-float subtitle_font_radius = 2.0;
-float subtitle_font_thickness = 2.0;
-// 0 = no autoscale
-// 1 = video height
-// 2 = video width
-// 3 = diagonal
-int subtitle_autoscale = 3;
-
-int vo_image_width = 0;
-int vo_image_height = 0;
-int force_load_font;
-
 int using_freetype = 0;
-int font_fontconfig = 0;
 
 //// constants
 static unsigned int const colors = 256;
@@ -488,7 +470,7 @@
 }
 
 #define ALLOC_INCR 32
-void render_one_glyph(font_desc_t *desc, int c)
+void render_one_glyph_ft(font_desc_t *desc, int c)
 {
     FT_GlyphSlot	slot;
     FT_UInt		glyph_index;
@@ -867,57 +849,16 @@
     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);
-	}
-	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);
-	}
-    }
-
-    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(char *name, FT_Face *face)
 {
     int err = -1;
     
-    if (name) err = FT_New_Face(library, name, 0, face);
+    if (name)
+    	err = FT_New_Face(library, name, 0, face);
+    
+    if (err)
+	    mp_msg(MSGT_OSD, MSGL_WARN, "Freetype: New_Face couldn't load \"%s\".\n", name);
 
-    if (err) {
-	err = FT_New_Face(library, get_path("subfont.ttf"), 0, face);
-	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;
 }
 
@@ -930,7 +871,7 @@
     return 0;
 }
 
-int kerning(font_desc_t *desc, int prevc, int c)
+int kerning_ft(font_desc_t *desc, int prevc, int c)
 {
     FT_Vector kern;
     
@@ -1004,10 +945,13 @@
 //    t=GetTimer();
 
     /* generate the subtitle font */
+    if (!fname)
+	goto gen_osd;
     err = load_sub_face(fname, &face);
     if (err) {
-	mp_msg(MSGT_OSD, MSGL_WARN, "subtitle font: load_sub_face failed.\n");
-	goto gen_osd;
+	//mp_msg(MSGT_OSD, MSGL_WARN, "subtitle font: load_sub_face failed.\n");
+	free_font_desc(desc);
+	return NULL;
     }
     desc->face_cnt++;
 
@@ -1116,48 +1060,55 @@
     return 0;
 }
 
-void load_font_ft(int width, int height) 
-{
 #ifdef HAVE_FONTCONFIG
+static char * fontconfig_get_name(char * name)
+{
     FcPattern *fc_pattern;
     FcChar8 *s;
     FcBool scalable;
-#endif
-    vo_image_width = width;
-    vo_image_height = height;
+    char * ret = NULL;
 
-    // protection against vo_aa font hacks
-    if (vo_font && !vo_font->dynamic) return;
+    FcInit();
+    fc_pattern = FcNameParse(name);
+    FcConfigSubstitute(0, fc_pattern, FcMatchPattern);
+    FcDefaultSubstitute(fc_pattern);
+
+    fc_pattern = FcFontMatch(0, fc_pattern, 0);
+	/* NOTE: it seems that second allocation of fc_pattern takes place
+	 * here, what is more, last (FcResult*) argument is totally ignored
+	 * by fontconfig as of 2.2.92
+	 */
 
-    if (vo_font) free_font_desc(vo_font);
-
-#ifdef USE_OSD
-#ifdef HAVE_FONTCONFIG
-    if (font_fontconfig)
-    {
-	if (!font_name)
-	    font_name = "sans-serif";
-	FcInit();
-	fc_pattern = FcNameParse(font_name);
-	FcConfigSubstitute(0, fc_pattern, FcMatchPattern);
-	FcDefaultSubstitute(fc_pattern);
-	fc_pattern = FcFontMatch(0, fc_pattern, 0);
-	FcPatternGetBool(fc_pattern, FC_SCALABLE, 0, &scalable);
-	if (scalable != FcTrue) {
-    	    fc_pattern = FcNameParse("sans-serif");
-    	    FcConfigSubstitute(0, fc_pattern, FcMatchPattern);
-    	    FcDefaultSubstitute(fc_pattern);
-    	    fc_pattern = FcFontMatch(0, fc_pattern, 0);
-	}
+    FcPatternGetBool(fc_pattern, FC_SCALABLE, 0, &scalable);
+    if (scalable == FcTrue) {
 	// s doesn't need to be freed according to fontconfig docs
 	FcPatternGetString(fc_pattern, FC_FILE, 0, &s);
-	vo_font=read_font_desc_ft(s, width, height);
-	free(fc_pattern);
+	//mp_msg(MSGT_CPLAYER, MSGL_ERR, "fontconfig: fc_ret: %d, font: %s\n", fc_ret, s);
+	ret = s;
     }
-    else
+    free(fc_pattern);
+    return ret;
+}
 #endif
-    vo_font=read_font_desc_ft(font_name, width, height);
+
+void load_font_ft(char * name, int width, int height) 
+{
+    vo_font = read_font_desc_ft(name, width, height);
+    if (vo_font)
+	mp_msg(MSGT_CPLAYER, MSGL_INFO, "Freetype: loaded \"%s\"\n", name);
+}
+
+void load_font_fc_ft(char * name, int width, int height)
+{
+    char * tmp = NULL;
+
+#ifdef HAVE_FONTCONFIG    
+    tmp = fontconfig_get_name(name);
 #endif
+    if (tmp) {
+    	mp_msg(MSGT_CPLAYER, MSGL_INFO, "Fontconfig: found \"%s\" for \"%s\"\n", tmp, name);
+    	load_font_ft(tmp, width, height);
+    }
 }
 
 #endif /* HAVE_FREETYPE */
diff -Nru main.orig/libvo/font_load_ft.h main/libvo/font_load_ft.h
--- main.orig/libvo/font_load_ft.h	1970-01-01 01:00:00.000000000 +0100
+++ main/libvo/font_load_ft.h	2004-02-16 23:39:26.425974848 +0100
@@ -0,0 +1,16 @@
+
+#ifndef __MPLAYER_FONT_LOAD_FT_H
+#define __MPLAYER_FONT_LOAD_FT_H
+
+#ifdef HAVE_FREETYPE
+
+int init_freetype();
+int done_freetype();
+void load_font_ft(char * name, int width, int height) ;
+void load_font_fc_ft(char * name, int width, int height);
+void render_one_glyph_ft(font_desc_t *desc, int c);
+int kerning_ft(font_desc_t *desc, int prevc, int c);
+
+#endif /* HAVE_FREETYPE */
+
+#endif /* ! __MPLAYER_FONT_LOAD_FT_H */
diff -Nru main.orig/libvo/font_load.h main/libvo/font_load.h
--- main.orig/libvo/font_load.h	2003-11-20 17:25:40.000000000 +0100
+++ main/libvo/font_load.h	2004-02-16 23:39:26.427974544 +0100
@@ -1,99 +1,7 @@
 #ifndef __MPLAYER_FONT_LOAD_H
 #define __MPLAYER_FONT_LOAD_H
 
-#ifdef HAVE_FREETYPE
-#include <ft2build.h>
-#include FT_FREETYPE_H
-#endif
-
-typedef struct {
-    unsigned char *bmp;
-    unsigned char *pal;
-    int w,h,c;
-#ifdef HAVE_FREETYPE
-    int charwidth,charheight,pen,baseline,padding;
-    int current_count, current_alloc;
-#endif
-} raw_file;
-
-typedef struct {
-#ifdef HAVE_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 HAVE_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;
-
-#ifdef HAVE_FREETYPE
-
-extern char *subtitle_font_encoding;
-extern float text_font_scale_factor;
-extern float osd_font_scale_factor;
-extern float subtitle_font_radius;
-extern float subtitle_font_thickness;
-extern int subtitle_autoscale;
-
-extern int vo_image_width;
-extern int vo_image_height;
-
-extern int force_load_font;
-
-int init_freetype();
-int done_freetype();
-
-font_desc_t* read_font_desc_ft(char* fname,int movie_width, int movie_height);
-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);
-
-#else
-
-static void render_one_glyph(font_desc_t *desc, int c) {}
-static int kerning(font_desc_t *desc, int prevc, int c) { return 0; }
-
-#endif
+#include "font_if.h"
 
 raw_file* load_raw(char *name,int verbose);
 font_desc_t* read_font_desc(char* fname,float factor,int verbose);
diff -Nru main.orig/libvo/Makefile main/libvo/Makefile
--- main.orig/libvo/Makefile	2004-01-10 10:48:14.000000000 +0100
+++ main/libvo/Makefile	2004-02-16 23:39:26.429974240 +0100
@@ -3,7 +3,7 @@
 
 LIBNAME = libvo.a
 
-SRCS=geometry.c aspect.c aclib.c osd.c font_load.c gtf.c spuenc.c video_out.c vo_null.c vo_pgm.c vo_md5.c vo_mpegpes.c vo_yuv4mpeg.c $(OPTIONAL_SRCS) sub.c font_load_ft.c
+SRCS=geometry.c aspect.c aclib.c osd.c font_load.c gtf.c spuenc.c video_out.c vo_null.c vo_pgm.c vo_md5.c vo_mpegpes.c vo_yuv4mpeg.c $(OPTIONAL_SRCS) sub.c font_load_ft.c font_if.c
 OBJS=$(SRCS:.c=.o)
 
 ifeq ($(VIDIX),yes)
diff -Nru main.orig/libvo/sub.c main/libvo/sub.c
--- main.orig/libvo/sub.c	2003-10-27 22:36:29.000000000 +0100
+++ main/libvo/sub.c	2004-02-16 23:39:26.432973784 +0100
@@ -10,9 +10,10 @@
 
 #include "mp_msg.h"
 #include "video_out.h"
-#include "font_load.h"
+#include "font_if.h"
 #include "sub.h"
 #include "../spudec.h"
+#include "../mplayer.h" /* font_name, don't like it */
 
 #define NEW_SPLITTING
 
@@ -755,13 +756,8 @@
     mp_osd_obj_t* obj=vo_osd_list;
     int chg=0;
 
-#ifdef HAVE_FREETYPE    
     // here is the right place to get screen dimensions
-    if (!vo_font || force_load_font) {
-	force_load_font = 0;
-	load_font_ft(dxs, dys);
-    }
-#endif
+    load_font(font_name, dxs, dys);
 
     while(obj){
       if(dxs!=obj->dxs || dys!=obj->dys || obj->flags&OSDFLAG_FORCE_UPDATE){
@@ -835,9 +831,7 @@
     new_osd_obj(OSDTYPE_SUBTITLE);
     new_osd_obj(OSDTYPE_PROGBAR);
     new_osd_obj(OSDTYPE_SPU);
-#ifdef HAVE_FREETYPE
     force_load_font = 1;
-#endif
 }
 
 int vo_osd_changed_flag=0;
diff -Nru main.orig/libvo/vo_aa.c main/libvo/vo_aa.c
--- main.orig/libvo/vo_aa.c	2003-08-13 18:45:02.000000000 +0200
+++ main/libvo/vo_aa.c	2004-02-16 23:39:26.443972112 +0100
@@ -29,7 +29,7 @@
 #include "aspect.h"
 #include "../postproc/swscale.h"
 #include "../libmpcodecs/vf_scale.h"
-#include "font_load.h"
+#include "font_if.h"
 #include "sub.h"
 
 #include "osdep/keycodes.h"
diff -Nru main.orig/Makefile main/Makefile
--- main.orig/Makefile	2003-12-10 13:03:54.000000000 +0100
+++ main/Makefile	2004-02-16 23:39:26.446971656 +0100
@@ -22,7 +22,7 @@
 endif
 
 SRCS_COMMON = cpudetect.c codec-cfg.c spudec.c playtree.c playtreeparser.c asxparser.c vobsub.c subreader.c sub_cc.c find_sub.c m_config.c m_option.c parser-cfg.c m_struct.c
-SRCS_MENCODER = mencoder.c mp_msg-mencoder.c $(SRCS_COMMON) libao2/afmt.c divx4_vbr.c libvo/aclib.c libvo/osd.c libvo/sub.c libvo/font_load.c libvo/font_load_ft.c xvid_vbr.c parser-mecmd.c
+SRCS_MENCODER = mencoder.c mp_msg-mencoder.c $(SRCS_COMMON) libao2/afmt.c divx4_vbr.c libvo/aclib.c libvo/osd.c libvo/sub.c libvo/font_load.c libvo/font_load_ft.c xvid_vbr.c parser-mecmd.c libvo/font_if.c
 SRCS_MPLAYER = mplayer.c mp_msg.c $(SRCS_COMMON) mixer.c parser-mpcmd.c
 
 ifeq ($(UNRARLIB),yes)
diff -Nru main.orig/mencoder.c main/mencoder.c
--- main.orig/mencoder.c	2004-02-10 15:12:26.000000000 +0100
+++ main/mencoder.c	2004-02-16 23:39:26.450971048 +0100
@@ -445,27 +445,8 @@
 
   mp_msg_set_level(verbose+MSGL_STATUS);
 
-// check font
 #ifdef USE_OSD
-#ifdef HAVE_FREETYPE
-  init_freetype();
-#endif
-#ifdef HAVE_FONTCONFIG
-  if(!font_fontconfig)
-  {
-#endif
-  if(font_name){
-       vo_font=read_font_desc(font_name,font_factor,verbose>1);
-       if(!vo_font) mp_msg(MSGT_CPLAYER,MSGL_ERR,MSGTR_CantLoadFont,font_name);
-  } else {
-      // try default:
-       vo_font=read_font_desc(get_path("font/font.desc"),font_factor,verbose>1);
-       if(!vo_font)
-       vo_font=read_font_desc(MPLAYER_DATADIR "/font/font.desc",font_factor,verbose>1);
-  }
-#ifdef HAVE_FONTCONFIG
-  }
-#endif
+    init_font();
 #endif
 
   vo_init_osd();
diff -Nru main.orig/mplayer.c main/mplayer.c
--- main.orig/mplayer.c	2004-02-09 21:20:24.000000000 +0100
+++ main/mplayer.c	2004-02-16 23:39:26.458969832 +0100
@@ -284,9 +284,6 @@
 
 // sub:
 char *font_name=NULL;
-#ifdef HAVE_FONTCONFIG
-extern int font_fontconfig;
-#endif
 float font_factor=0.75;
 char **sub_name=NULL;
 float sub_delay=0;
@@ -1060,28 +1057,10 @@
 
 //------ load global data first ------
 
-// check font
 #ifdef USE_OSD
-#ifdef HAVE_FREETYPE
-  init_freetype();
-#endif
-#ifdef HAVE_FONTCONFIG
-  if(!font_fontconfig)
-  {
-#endif
-  if(font_name){
-       vo_font=read_font_desc(font_name,font_factor,verbose>1);
-       if(!vo_font) mp_msg(MSGT_CPLAYER,MSGL_ERR,MSGTR_CantLoadFont,font_name);
-  } else {
-      // try default:
-       vo_font=read_font_desc(get_path("font/font.desc"),font_factor,verbose>1);
-       if(!vo_font)
-       vo_font=read_font_desc(MPLAYER_DATADIR "/font/font.desc",font_factor,verbose>1);
-  }
-#ifdef HAVE_FONTCONFIG
-  }
-#endif
+    init_font();
 #endif
+
   vo_init_osd();
 
 #ifdef HAVE_RTC
@@ -1779,9 +1758,7 @@
    if(vo_flags & 0x08 && vo_spudec)
       spudec_set_hw_spu(vo_spudec,video_out);
 
-#ifdef HAVE_FREETYPE
    force_load_font = 1;
-#endif
 
 //================== MAIN: ==========================
 main:
@@ -3770,11 +3747,9 @@
   goto play_next_file;
 }
 
-#ifdef HAVE_FREETYPE
+#ifdef USE_OSD
 current_module="uninit_font";
-if (vo_font) free_font_desc(vo_font);
-vo_font = NULL;
-done_freetype();
+uninit_font();
 #endif
 
 exit_player_with_rc(MSGTR_Exit_eof, 0);


More information about the MPlayer-dev-eng mailing list