]> git.sesse.net Git - vlc/blobdiff - modules/misc/freetype.c
Freetype: more debug for Fc Building, aimed at Win32
[vlc] / modules / misc / freetype.c
index 11d7bb8c5d7c4f5e303b17268d6ee0c6fc01ea58..8181a6e1131256db5d560868c03d83880eaa9bcd 100644 (file)
@@ -70,6 +70,8 @@
 
 #ifdef HAVE_FONTCONFIG
 #include <fontconfig/fontconfig.h>
+#undef DEFAULT_FONT
+#define DEFAULT_FONT FC_DEFAULT_FONT
 #endif
 
 #include <assert.h>
@@ -81,7 +83,13 @@ static int  Create ( vlc_object_t * );
 static void Destroy( vlc_object_t * );
 
 #define FONT_TEXT N_("Font")
-#define FONT_LONGTEXT N_("Filename for the font you want to use")
+
+#ifdef HAVE_FONTCONFIG
+#define FONT_LONGTEXT N_("Font family for the font you want to use")
+#else
+#define FONT_LONGTEXT N_("Fontfile for the font you want to use")
+#endif
+
 #define FONTSIZE_TEXT N_("Font size in pixels")
 #define FONTSIZE_LONGTEXT N_("This is the default size of the fonts " \
     "that will be rendered on the video. " \
@@ -134,7 +142,7 @@ vlc_module_begin ()
     set_category( CAT_VIDEO )
     set_subcategory( SUBCAT_VIDEO_SUBPIC )
 
-    add_file( "freetype-font", DEFAULT_FONT, NULL, FONT_TEXT, FONT_LONGTEXT,
+    add_font( "freetype-font", DEFAULT_FONT, NULL, FONT_TEXT, FONT_LONGTEXT,
               false )
 
     add_integer( "freetype-fontsize", 0, NULL, FONTSIZE_TEXT,
@@ -259,8 +267,10 @@ struct filter_sys_t
     int            i_default_font_size;
     int            i_display_height;
 #ifdef HAVE_FONTCONFIG
+    char*          psz_fontfamily;
     bool           b_fontconfig_ok;
     FcConfig      *p_fontconfig;
+    xml_t         *p_xml;
 #endif
 
     input_attachment_t **pp_font_attachments;
@@ -270,7 +280,7 @@ struct filter_sys_t
 };
 
 #define UCHAR uint32_t
-#define TR_DEFAULT_FONT FC_DEFAULT_FONT
+#define TR_DEFAULT_FONT p_sys->psz_fontfamily
 #define TR_FONT_STYLE_PTR ft_style_t *
 
 #include "text_renderer.h"
@@ -284,65 +294,110 @@ static int Create( vlc_object_t *p_this )
 {
     filter_t      *p_filter = (filter_t *)p_this;
     filter_sys_t  *p_sys;
-    char          *psz_fontfile = NULL;
-    int            i_error;
-    vlc_value_t    val;
+    char          *psz_fontfile=NULL;
+    char          *psz_fontfamily=NULL;
+    int            i_error,fontindex;
+
+#ifdef HAVE_FONTCONFIG
+    FcPattern     *fontpattern = NULL, *fontmatch = NULL;
+    /* Initialise result to Match, as fontconfig doesnt
+     * really set this other than some error-cases */
+    FcResult       fontresult = FcResultMatch;
+#endif
+
 
     /* Allocate structure */
     p_filter->p_sys = p_sys = malloc( sizeof( filter_sys_t ) );
     if( !p_sys )
         return VLC_ENOMEM;
+ #ifdef HAVE_FONTCONFIG
+    p_sys->psz_fontfamily = NULL;
+    p_sys->p_xml = NULL;
+#endif
     p_sys->p_face = 0;
     p_sys->p_library = 0;
     p_sys->i_font_size = 0;
     p_sys->i_display_height = 0;
 
-    var_Create( p_filter, "freetype-font",
-                VLC_VAR_STRING | VLC_VAR_DOINHERIT );
-    var_Create( p_filter, "freetype-fontsize",
-                VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
     var_Create( p_filter, "freetype-rel-fontsize",
                 VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
-    var_Create( p_filter, "freetype-opacity",
-                VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
-    var_Create( p_filter, "freetype-effect",
-                VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
-    var_Get( p_filter, "freetype-opacity", &val );
-    p_sys->i_font_opacity = __MAX( __MIN( val.i_int, 255 ), 0 );
-    var_Create( p_filter, "freetype-color",
-                VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
-    var_Get( p_filter, "freetype-color", &val );
-    p_sys->i_font_color = __MAX( __MIN( val.i_int, 0xFFFFFF ), 0 );
-    p_sys->i_effect = var_GetInteger( p_filter, "freetype-effect" );
-
-    /* Look what method was requested */
-    var_Get( p_filter, "freetype-font", &val );
-    psz_fontfile = val.psz_string;
-    if( !psz_fontfile || !*psz_fontfile )
+
+    psz_fontfamily = var_CreateGetString( p_filter, "freetype-font" );
+    p_sys->i_default_font_size = var_CreateGetInteger( p_filter, "freetype-fontsize" );
+    p_sys->i_effect = var_CreateGetInteger( p_filter, "freetype-effect" );
+    p_sys->i_font_opacity = var_CreateGetInteger( p_filter,"freetype-opacity" );
+    p_sys->i_font_opacity = __MAX( __MIN( p_sys->i_font_opacity, 255 ), 0 );
+    p_sys->i_font_color = var_CreateGetInteger( p_filter, "freetype-color" );
+    p_sys->i_font_color = __MAX( __MIN( p_sys->i_font_color , 0xFFFFFF ), 0 );
+
+    fontindex=0;
+    if( !psz_fontfamily || !*psz_fontfamily )
     {
-        free( psz_fontfile );
-        psz_fontfile = (char *)malloc( PATH_MAX + 1 );
-        if( !psz_fontfile )
-            goto error;
-#ifdef WIN32
-        GetWindowsDirectory( psz_fontfile, PATH_MAX + 1 );
-        strcat( psz_fontfile, "\\fonts\\arial.ttf" );
-#elif defined(__APPLE__)
-        strcpy( psz_fontfile, DEFAULT_FONT );
+#ifdef HAVE_FONTCONFIG
+        free( psz_fontfamily);
+        psz_fontfamily=strdup( DEFAULT_FONT );
 #else
-        msg_Err( p_filter, "user didn't specify a font" );
-        goto error;
+        free( psz_fontfamily );
+        psz_fontfamily = (char *)malloc( PATH_MAX + 1 );
+        if( !psz_fontfamily )
+            goto error;
+# ifdef WIN32
+        GetWindowsDirectory( psz_fontfamily , PATH_MAX + 1 );
+        strcat( psz_fontfamily, "\\fonts\\arial.ttf" );
+# else
+        strcpy( psz_fontfamily, DEFAULT_FONT );
+# endif
+        msg_Err( p_filter,"User didn't specify fontfile, using %s", psz_fontfamily);
 #endif
     }
 
+#ifdef HAVE_FONTCONFIG
+    /* Lets find some fontfile from freetype-font variable family */
+    char *psz_fontsize;
+    if( asprintf( &psz_fontsize, "%d", p_sys->i_default_font_size ) == -1 )
+        goto error;
+
+    fontpattern = FcPatternCreate();
+
+    if( !fontpattern )
+        goto error;
+
+    FcPatternAddString( fontpattern, FC_FAMILY, psz_fontfamily);
+    FcPatternAddString( fontpattern, FC_SIZE, psz_fontsize );
+    free( psz_fontsize );
+
+    if( FcConfigSubstitute( NULL, fontpattern, FcMatchPattern ) == FcFalse )
+        goto error;
+    FcDefaultSubstitute( fontpattern );
+
+    /* testing fontresult here doesn't do any good really, but maybe it will
+     * in future as fontconfig code doesn't set it in all cases and just
+     * returns NULL or doesn't set to to Match on all Match cases.*/
+    fontmatch = FcFontMatch( NULL, fontpattern, &fontresult );
+    if( !fontmatch || fontresult == FcResultNoMatch )
+        goto error;
+
+    FcPatternGetString( fontmatch, FC_FILE, 0, (FcChar8 **)&psz_fontfile);
+    FcPatternGetInteger( fontmatch, FC_INDEX, 0, &fontindex );
+    if( !psz_fontfile )
+        goto error;
+    msg_Dbg( p_filter, "Using %s as font from file %s", psz_fontfamily, psz_fontfile );
+    p_sys->psz_fontfamily = strdup( psz_fontfamily );
+#else
+    p_sys->psz_fontfamily = strdup( DEFAULT_FONT )
+    psz_fontfile = psz_fontfamily;
+#endif
+
     i_error = FT_Init_FreeType( &p_sys->p_library );
     if( i_error )
     {
         msg_Err( p_filter, "couldn't initialize freetype" );
         goto error;
     }
+
     i_error = FT_New_Face( p_sys->p_library, psz_fontfile ? psz_fontfile : "",
-                           0, &p_sys->p_face );
+                           fontindex, &p_sys->p_face );
+
     if( i_error == FT_Err_Unknown_File_Format )
     {
         msg_Err( p_filter, "file %s have unknown format", psz_fontfile );
@@ -369,11 +424,8 @@ static int Create( vlc_object_t *p_this )
 
     p_sys->i_use_kerning = FT_HAS_KERNING( p_sys->p_face );
 
-    var_Get( p_filter, "freetype-fontsize", &val );
-    p_sys->i_default_font_size = val.i_int;
     if( SetFontSize( p_filter, 0 ) != VLC_SUCCESS ) goto error;
 
-    free( psz_fontfile );
 
     p_sys->pp_font_attachments = NULL;
     p_sys->i_font_attachments = 0;
@@ -381,18 +433,25 @@ static int Create( vlc_object_t *p_this )
     p_filter->pf_render_text = RenderText;
 #ifdef HAVE_FONTCONFIG
     p_filter->pf_render_html = RenderHtml;
+    FcPatternDestroy( fontmatch );
+    FcPatternDestroy( fontpattern );
 #else
     p_filter->pf_render_html = NULL;
 #endif
 
+    free( psz_fontfamily );
     LoadFontsFromAttachments( p_filter );
 
     return VLC_SUCCESS;
 
- error:
+error:
+#ifdef HAVE_FONTCONFIG
+    if( fontmatch ) FcPatternDestroy( fontmatch );
+    if( fontpattern ) FcPatternDestroy( fontpattern );
+#endif
     if( p_sys->p_face ) FT_Done_Face( p_sys->p_face );
     if( p_sys->p_library ) FT_Done_FreeType( p_sys->p_library );
-    free( psz_fontfile );
+    free( psz_fontfamily );
     free( p_sys );
     return VLC_EGENERIC;
 }
@@ -419,6 +478,8 @@ static void Destroy( vlc_object_t *p_this )
 
 #ifdef HAVE_FONTCONFIG
     FontBuilderDetach( p_filter, p_sys->p_fontbuilder );
+    xml_Delete( p_sys->p_xml );
+    free( p_sys->psz_fontfamily );
 #endif
 
     /* FcFini asserts calling the subfunction FcCacheFini()
@@ -481,6 +542,7 @@ static vlc_object_t *FontBuilderAttach( filter_t *p_filter )
     if( p_fontbuilder )
     {
         var_AddCallback( p_fontbuilder, "build-done", FontBuilderDone, p_filter );
+        msg_Warn( p_filter, "Building the Fontconfig cache" );
         FontBuilderGetFcConfig( p_filter, p_fontbuilder );
     }
     vlc_mutex_unlock( &fb_lock );
@@ -2228,7 +2290,6 @@ static int RenderHtml( filter_t *p_filter, subpicture_region_t *p_region_out,
 {
     int          rv = VLC_SUCCESS;
     stream_t     *p_sub = NULL;
-    xml_t        *p_xml = NULL;
     xml_reader_t *p_xml_reader = NULL;
 
     if( !p_region_in || !p_region_in->psz_html )
@@ -2243,12 +2304,12 @@ static int RenderHtml( filter_t *p_filter, subpicture_region_t *p_region_out,
                               true );
     if( p_sub )
     {
-        p_xml = xml_Create( p_filter );
-        if( p_xml )
+        if( !p_filter->p_sys->p_xml ) p_filter->p_sys->p_xml = xml_Create( p_filter );
+        if( p_filter->p_sys->p_xml )
         {
             bool b_karaoke = false;
 
-            p_xml_reader = xml_ReaderCreate( p_xml, p_sub );
+            p_xml_reader = xml_ReaderCreate( p_filter->p_sys->p_xml, p_sub );
             if( p_xml_reader )
             {
                 /* Look for Root Node */
@@ -2272,7 +2333,7 @@ static int RenderHtml( filter_t *p_filter, subpicture_region_t *p_region_out,
                     {
                         /* Only text and karaoke tags are supported */
                         msg_Dbg( p_filter, "Unsupported top-level tag '%s' ignored.", psz_node );
-                        xml_ReaderDelete( p_xml, p_xml_reader );
+                        xml_ReaderDelete( p_filter->p_sys->p_xml, p_xml_reader );
                         p_xml_reader = NULL;
                         rv = VLC_EGENERIC;
                     }
@@ -2343,9 +2404,8 @@ static int RenderHtml( filter_t *p_filter, subpicture_region_t *p_region_out,
                 }
                 FreeLines( p_lines );
 
-                xml_ReaderDelete( p_xml, p_xml_reader );
+                xml_ReaderDelete( p_filter->p_sys->p_xml, p_xml_reader );
             }
-            xml_Delete( p_xml );
         }
         stream_Delete( p_sub );
     }