VLC_ADD_PLUGINS([freetype])
VLC_ADD_CFLAGS([freetype],[`${FREETYPE_CONFIG} --cflags`])
VLC_ADD_LDFLAGS([freetype],[`${FREETYPE_CONFIG} --libs`])
+ if test "${SYS}" = "mingw32"; then
+ VLC_ADD_LDFLAGS([freetype],[-lxml2])]
+ fi
AC_CHECK_HEADERS(fontconfig/fontconfig.h,
[VLC_ADD_CFLAGS([freetype],[-DHAVE_FONTCONFIG])
VLC_ADD_LDFLAGS([freetype],[-lfontconfig])])
.png .gpg-error .gcrypt .gnutls .mpcdec \
.dvdnav .dvbpsi .wxwidgets .qt4 .dirac .SDL_image \
.dx_headers .dshow_headers .gecko-win32 .unicows .dca \
- .lua .tag \
+ .lua .tag .fontconfig \
.aclocal
# .daap .cddb .cdio .vcdimager .portaudio
CLEAN_PKG += libiconv
DISTCLEAN_PKG += libiconv-$(LIBICONV_VERSION).tar.gz
+# ***************************************************************************
+# fontconfig
+# ***************************************************************************
+
+fontconfig-$(FONTCONFIG_VERSION).tar.gz:
+ $(WGET) $(FONTCONFIG_URL)
+
+fontconfig: fontconfig-$(FONTCONFIG_VERSION).tar.gz
+ $(EXTRACT_GZ)
+ patch -p0 < Patches/fontconfig.patch
+
+.fontconfig: fontconfig
+ifdef HAVE_WIN32
+ ifdef HAVE_CYGWIN
+ (cd $<; ./configure --target=$(HOST) --disable-pic --disable-shared --with-cache-dir=WINDOWSTEMPDIR --with-arch=i686 --prefix=$(PREFIX) && make && make install)
+ else
+ (cd $<; $(HOSTCC) ./configure $(HOSTCONF) --with-cache-dir=WINDOWSTEMPDIR --with-arch=i686 --prefix=$(PREFIX) && make && make install)
+ endif
+else
+ (cd $<; $(HOSTCC) ./configure $(HOSTCONF) --prefix=$(PREFIX) && make && make install)
+endif
+ $(INSTALL_NAME)
+ touch $@
+
+CLEAN_FILE += .fontconfig
+CLEAN_PKG += fontconfig
+DISTCLEAN_PKG += fontconfig-$(FONTCONFIG_VERSION).tar.gz
+
# ***************************************************************************
# freetype2
# ***************************************************************************
--- /dev/null
+--- fontconfig/src/Makefile.am Mon Sep 18 07:06:41 2006
++++ fontconfig/src/Makefile.am Sat Aug 18 20:48:45 2007
+***************
+*** 31,35 ****
+
+ install-libtool-import-lib:
+- $(INSTALL) .libs/libfontconfig.dll.a $(DESTDIR)$(libdir)
+ $(INSTALL) fontconfig.def $(DESTDIR)$(libdir)/fontconfig.def
+
+--- 31,34 ----
+--- fontconfig/src/Makefile.in Sun Dec 3 10:27:33 2006
++++ fontconfig/src/Makefile.in Sat Aug 18 20:53:40 2007
+***************
+*** 614,618 ****
+
+ @OS_WIN32_TRUE@install-libtool-import-lib:
+- @OS_WIN32_TRUE@ $(INSTALL) .libs/libfontconfig.dll.a $(DESTDIR)$(libdir)
+ @OS_WIN32_TRUE@ $(INSTALL) fontconfig.def $(DESTDIR)$(libdir)/fontconfig.def
+
+--- 614,617 ----
+--- fontconfig/src/fcinit.c Sun Dec 3 07:10:30 2006
++++ fontconfig/src/fcinit.c Sun Aug 19 00:52:07 2007
+***************
+*** 26,32 ****
+--- 26,94 ----
+ #include <stdlib.h>
+
++ #ifdef _WIN32
++ #define STRICT
++ #include <windows.h>
++ #undef STRICT
++
++ static char *IsWindowsDir(char *p_dir_in, char **p_dir_out)
++ {
++ *p_dir_out = NULL;
++
++ if( ! strcmp( p_dir_in, "WINDOWSFONTDIR" ))
++ {
++ int rc;
++
++ *p_dir_out = malloc( 1000 );
++ if( !*p_dir_out )
++ {
++ fprintf( stderr, "Fontconfig error: out of memory" );
++ return p_dir_in;
++ }
++ rc = GetWindowsDirectory( *p_dir_out, 800 );
++ if( rc == 0 || rc > 800 )
++ {
++ fprintf( stderr, "Fontconfig error: GetWindowsDirectory failed" );
++ free( *p_dir_out );
++ *p_dir_out = NULL;
++
++ return p_dir_in;
++ }
++ if( *p_dir_out[ strlen( *p_dir_out ) - 1 ] != '\\' )
++ strcat( *p_dir_out, "\\" );
++ strcat( *p_dir_out, "fonts" );
++
++ return *p_dir_out;
++ }
++ else if( ! strcmp( p_dir_in, "WINDOWSTEMPDIR" ))
++ {
++ int rc;
++
++ *p_dir_out = malloc( 1000 );
++ if( !*p_dir_out )
++ {
++ fprintf( stderr, "Fontconfig error: out of memory" );
++ return p_dir_in;
++ }
++ rc = GetTempPath( 800, *p_dir_out );
++ if( rc == 0 || rc > 800 )
++ {
++ fprintf( stderr, "Fontconfig error: GetTempPath failed" );
++ free( *p_dir_out );
++ *p_dir_out = NULL;
++
++ return p_dir_in;
++ }
++ return *p_dir_out;
++ }
++ return p_dir_in;
++ }
++ #else
++ #define IsWindowsDir(A, B) A
++ #endif
++
+ static FcConfig *
+ FcInitFallbackConfig (void)
+ {
++ char *p_dir_out = NULL;
+ FcConfig *config;
+
+***************
+*** 34,40 ****
+ if (!config)
+ goto bail0;
+! if (!FcConfigAddDir (config, (FcChar8 *) FC_DEFAULT_FONTS))
+ goto bail1;
+! if (!FcConfigAddCacheDir (config, (FcChar8 *) FC_CACHEDIR))
+ goto bail1;
+ return config;
+--- 96,106 ----
+ if (!config)
+ goto bail0;
+! if (!FcConfigAddDir (config, (FcChar8 *) IsWindowsDir(FC_DEFAULT_FONTS, &p_dir_out)))
+ goto bail1;
+! if (p_dir_out)
+! free(p_dir_out);
+! p_dir_out = NULL;
+!
+! if (!FcConfigAddCacheDir (config, (FcChar8 *) IsWindowsDir(FC_CACHEDIR, &p_dir_out)))
+ goto bail1;
+ return config;
+***************
+*** 43,46 ****
+--- 109,114 ----
+ FcConfigDestroy (config);
+ bail0:
++ if (p_dir_out)
++ free(p_dir_out);
+ return 0;
+ }
+***************
+*** 73,84 ****
+ if (config->cacheDirs && config->cacheDirs->num == 0)
+ {
+ fprintf (stderr,
+ "Fontconfig warning: no <cachedir> elements found. Check configuration.\n");
+ fprintf (stderr,
+ "Fontconfig warning: adding <cachedir>%s</cachedir>\n",
+! FC_CACHEDIR);
+ fprintf (stderr,
+ "Fontconfig warning: adding <cachedir>~/.fontconfig</cachedir>\n");
+! if (!FcConfigAddCacheDir (config, (FcChar8 *) FC_CACHEDIR) ||
+ !FcConfigAddCacheDir (config, (FcChar8 *) "~/.fontconfig"))
+ {
+--- 141,158 ----
+ if (config->cacheDirs && config->cacheDirs->num == 0)
+ {
++ char *p_dir_out = NULL;
++
+ fprintf (stderr,
+ "Fontconfig warning: no <cachedir> elements found. Check configuration.\n");
+ fprintf (stderr,
+ "Fontconfig warning: adding <cachedir>%s</cachedir>\n",
+! IsWindowsDir(FC_CACHEDIR, &p_dir_out));
+ fprintf (stderr,
+ "Fontconfig warning: adding <cachedir>~/.fontconfig</cachedir>\n");
+! if (p_dir_out)
+! free(p_dir_out);
+! p_dir_out = NULL;
+!
+! if (!FcConfigAddCacheDir (config, (FcChar8 *) IsWindowsDir(FC_CACHEDIR, &p_dir_out)) ||
+ !FcConfigAddCacheDir (config, (FcChar8 *) "~/.fontconfig"))
+ {
+***************
+*** 86,91 ****
+--- 160,172 ----
+ "Fontconfig error: out of memory");
+ FcConfigDestroy (config);
++
++ if (p_dir_out)
++ free(p_dir_out);
++ p_dir_out = NULL;
++
+ return FcInitFallbackConfig ();
+ }
++ if (p_dir_out)
++ free(p_dir_out);
+ }
+
LIBICONV_URL=$(GNU)/libiconv/libiconv-$(LIBICONV_VERSION).tar.gz
GETTEXT_VERSION=0.16.1
GETTEXT_URL=$(GNU)/gettext/gettext-$(GETTEXT_VERSION).tar.gz
+FONTCONFIG_VERSION=2.4.2
+FONTCONFIG_URL=http://fontconfig.org/release/fontconfig-$(FONTCONFIG_VERSION).tar.gz
FREETYPE2_VERSION=2.3.5
FREETYPE2_URL=$(SF)/freetype/freetype-$(FREETYPE2_VERSION).tar.gz
FRIBIDI_VERSION=0.10.4
+#include <time.h>
/*****************************************************************************
* freetype.c : Put text on the video, using freetype2
*****************************************************************************
static int Render( filter_t *, subpicture_region_t *, line_desc_t *, int, int);
static void FreeLines( line_desc_t * );
static void FreeLine( line_desc_t * );
+static void FontBuilder( vlc_object_t *p_this);
/*****************************************************************************
* filter_sys_t: freetype local data
int i_display_height;
#ifdef HAVE_FONTCONFIG
FcConfig *p_fontconfig;
+ vlc_bool_t b_fontconfig_ok;
+ vlc_mutex_t fontconfig_lock;
#endif
input_attachment_t **pp_font_attachments;
}
#ifdef HAVE_FONTCONFIG
- if( FcInit() )
- p_sys->p_fontconfig = FcConfigGetCurrent();
+ vlc_mutex_init( p_filter, &p_sys->fontconfig_lock );
+ p_sys->b_fontconfig_ok = VLC_FALSE;
+
+ p_sys->p_fontconfig = FcInitLoadConfig();
+
+ if( p_sys->p_fontconfig )
+ {
+ /* Normally this doesn't take very long, but an initial build of
+ * the fontconfig database or the addition of a lot of new fonts
+ * can cause it to take several minutes for a large number of fonts.
+ * Even a small number can take several seconds - much longer than
+ * we can afford to block, so we build the list in the background
+ * and if it succeeds we allow fontconfig to be used.
+ */
+ if( vlc_thread_create( p_filter, "fontlist builder", FontBuilder,
+ VLC_THREAD_PRIORITY_LOW, VLC_FALSE ) )
+ {
+ /* Don't destroy the fontconfig object - we won't be able to do
+ * italics or bold or change the font face, but we will still
+ * be able to do underline and change the font size.
+ */
+ msg_Warn( p_filter, "fontconfig database builder thread can't "
+ "be launched. Font styling support will be limited." );
+ };
+ }
else
- p_sys->p_fontconfig = NULL;
+ {
+ msg_Warn( p_filter, "Couldn't initialise Fontconfig. "
+ "Font styling won't be available." );
+ }
#endif
i_error = FT_Init_FreeType( &p_sys->p_library );
if( i_error )
p_filter->pf_render_text = RenderText;
#ifdef HAVE_FONTCONFIG
- p_filter->pf_render_html = RenderHtml;
-#else
- p_filter->pf_render_html = NULL;
+ if( p_sys->p_fontconfig )
+ p_filter->pf_render_html = RenderHtml;
+ else
#endif
+ p_filter->pf_render_html = NULL;
LoadFontsFromAttachments( p_filter );
}
#ifdef HAVE_FONTCONFIG
- FcConfigDestroy( p_sys->p_fontconfig );
- p_sys->p_fontconfig = NULL;
+ vlc_mutex_destroy( &p_sys->fontconfig_lock );
+
+ if( p_sys->p_fontconfig )
+ {
+ FcConfigDestroy( p_sys->p_fontconfig );
+ p_sys->p_fontconfig = NULL;
+ }
/* FcFini asserts calling the subfunction FcCacheFini()
* even if no other library functions have been made since FcInit(),
* so don't call it. */
free( p_sys );
}
+static void FontBuilder( vlc_object_t *p_this)
+{
+ filter_t *p_filter = (filter_t*)p_this;
+ filter_sys_t *p_sys = p_filter->p_sys;
+ time_t t1, t2;
+
+ /* Find the session to announce */
+ vlc_mutex_lock( &p_sys->fontconfig_lock );
+
+ msg_Dbg( p_filter, "Building font database..." );
+ time(&t1);
+ if(! FcConfigBuildFonts( p_sys->p_fontconfig ))
+ {
+ /* Don't destroy the fontconfig object - we won't be able to do
+ * italics or bold or change the font face, but we will still
+ * be able to do underline and change the font size.
+ */
+ msg_Err( p_filter, "fontconfig database can't be built. "
+ "Font styling won't be available" );
+ }
+ time(&t2);
+
+ msg_Dbg( p_filter, "Finished building font database." );
+ if( t1 > 0 && t2 > 0 )
+ msg_Dbg( p_filter, "Took %ld seconds", t2 - t1 );
+
+ FcConfigSetCurrent( p_sys->p_fontconfig );
+ p_sys->b_fontconfig_ok = VLC_TRUE;
+
+ vlc_mutex_unlock( &p_sys->fontconfig_lock );
+}
+
/*****************************************************************************
* Make any TTF/OTF fonts present in the attachments of the media file
* and store them for later use by the FreeType Engine
/* Look for a match amongst our attachments first */
CheckForEmbeddedFont( p_sys, &p_face, p_style );
- if( ! p_face )
+ if( ! p_face && p_sys->b_fontconfig_ok )
{
- char *psz_fontfile = FontConfig_Select( p_sys->p_fontconfig,
- p_style->psz_fontname,
- p_style->b_bold,
- p_style->b_italic,
- &i_idx );
+ char *psz_fontfile;
+
+ vlc_mutex_lock( &p_sys->fontconfig_lock );
+
+ psz_fontfile = FontConfig_Select( p_sys->p_fontconfig,
+ p_style->psz_fontname,
+ p_style->b_bold,
+ p_style->b_italic,
+ &i_idx );
+
+ vlc_mutex_unlock( &p_sys->fontconfig_lock );
+
if( psz_fontfile )
{
if( FT_New_Face( p_sys->p_library,
- psz_fontfile ? psz_fontfile : "", i_idx, &p_face ) )
+ psz_fontfile, i_idx, &p_face ) )
{
free( psz_fontfile );
free( pp_char_styles );