]> git.sesse.net Git - vlc/commitdiff
Changes to get styled subtitles working with Windows
authorBernie Purcell <bitmap@videolan.org>
Tue, 21 Aug 2007 07:49:24 +0000 (07:49 +0000)
committerBernie Purcell <bitmap@videolan.org>
Tue, 21 Aug 2007 07:49:24 +0000 (07:49 +0000)
configure.ac
extras/contrib/src/Distributions/win32.mak
extras/contrib/src/Makefile
extras/contrib/src/Patches/fontconfig.patch [new file with mode: 0644]
extras/contrib/src/packages.mak
modules/misc/freetype.c

index ee732a860b4bf7053d62e1db09f52e51aca5d015..ca709c8c4ce56f335c23dddf52efba9d2f6242b2 100644 (file)
@@ -4133,6 +4133,9 @@ then
     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])])
index 836e64f53e8b069ea5345395c7f1c8d129dd4880..0efa421d48501b82e943aae4acbeb1bcdf060db7 100644 (file)
@@ -6,6 +6,6 @@ all: .iconv .intl .freetype .fribidi .zlib \
         .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
index 4e1a0f769f41e42b4ca088a185ab255edaace433..07222731c3d1f3b1ce815be114a7cf8f214781ef 100644 (file)
@@ -430,6 +430,34 @@ CLEAN_FILE += .iconv
 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
 # ***************************************************************************
diff --git a/extras/contrib/src/Patches/fontconfig.patch b/extras/contrib/src/Patches/fontconfig.patch
new file mode 100644 (file)
index 0000000..cc1a030
--- /dev/null
@@ -0,0 +1,173 @@
+--- 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);
+      }
+  
index 30c228b215dc524695474bb5e801d89a2eb2594e..aa1c3bb7a233c6f251dbcdd87f200707e5cbd0c8 100644 (file)
@@ -42,6 +42,8 @@ LIBICONV_VERSION=1.9.2
 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
index 1b5fe8aefb38360d90dd0384d3ed2e8cc9488b01..64b22b1aae08eebca26020051c31f3028d9b7e64 100644 (file)
@@ -1,3 +1,4 @@
+#include <time.h>
 /*****************************************************************************
  * freetype.c : Put text on the video, using freetype2
  *****************************************************************************
@@ -238,6 +239,7 @@ typedef struct
 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
@@ -259,6 +261,8 @@ struct filter_sys_t
     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;
@@ -332,10 +336,36 @@ static int Create( vlc_object_t *p_this )
     }
 
 #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 )
@@ -376,10 +406,11 @@ static int Create( vlc_object_t *p_this )
 
     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 );
 
@@ -416,8 +447,13 @@ static void Destroy( vlc_object_t *p_this )
     }
 
 #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. */
@@ -427,6 +463,38 @@ static void Destroy( vlc_object_t *p_this )
     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
@@ -2281,17 +2349,24 @@ static int ProcessLines( filter_t *p_filter,
             /* 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 );