X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=modules%2Fmisc%2Ffreetype.c;h=2e17338f52103b6d1f748d4d9fe68310f7bcea28;hb=2053866380d8c54371c519e5619566e3f2164226;hp=a0c3a93fdc75c301e81467fab424d14a2663849b;hpb=6a616fca335a24409c39cabcfea8a45b7e1995f3;p=vlc diff --git a/modules/misc/freetype.c b/modules/misc/freetype.c index a0c3a93fdc..2e17338f52 100644 --- a/modules/misc/freetype.c +++ b/modules/misc/freetype.c @@ -39,6 +39,7 @@ #include #include #include +#include #include #include @@ -48,7 +49,9 @@ #include FT_GLYPH_H #define FT_FLOOR(X) ((X & -64) >> 6) #define FT_CEIL(X) (((X + 63) & -64) >> 6) -#define FT_MulFix(v, s) (((v)*(s))>>16) +#ifndef FT_MulFix + #define FT_MulFix(v, s) (((v)*(s))>>16) +#endif #ifdef __APPLE__ #define DEFAULT_FONT "/System/Library/Fonts/LucidaGrande.dfont" @@ -142,7 +145,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, @@ -238,16 +241,6 @@ 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 * ); -#ifdef HAVE_FONTCONFIG -static vlc_object_t *FontBuilderAttach( filter_t *p_filter ); -static void FontBuilderDetach( filter_t *p_filter, vlc_object_t *p_fontbuilder ); -static void* FontBuilderThread( vlc_object_t *p_this); -static void FontBuilderDestructor( vlc_object_t *p_this ); -static void FontBuilderGetFcConfig( filter_t *p_filter, vlc_object_t *p_fontbuilder ); -static int FontBuilderDone( vlc_object_t*, const char *, vlc_value_t, vlc_value_t, - void* ); -#endif - /***************************************************************************** * filter_sys_t: freetype local data ***************************************************************************** @@ -267,18 +260,17 @@ struct filter_sys_t int i_default_font_size; int i_display_height; #ifdef HAVE_FONTCONFIG - bool b_fontconfig_ok; - FcConfig *p_fontconfig; + char* psz_fontfamily; + xml_t *p_xml; #endif input_attachment_t **pp_font_attachments; int i_font_attachments; - vlc_object_t *p_fontbuilder; }; #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" @@ -297,8 +289,10 @@ static int Create( vlc_object_t *p_this ) int i_error,fontindex; #ifdef HAVE_FONTCONFIG - FcPattern *fontpattern, *fontmatch; - FcResult fontresult; + FcPattern *fontpattern = NULL, *fontmatch = NULL; + /* Initialise result to Match, as fontconfig doesnt + * really set this other than some error-cases */ + FcResult fontresult = FcResultMatch; #endif @@ -306,6 +300,10 @@ static int Create( vlc_object_t *p_this ) 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; @@ -348,38 +346,97 @@ static int Create( vlc_object_t *p_this ) char *psz_fontsize; if( asprintf( &psz_fontsize, "%d", p_sys->i_default_font_size ) == -1 ) goto error; + +#ifdef WIN32 + dialog_progress_bar_t *p_dialog = dialog_ProgressCreate( p_filter, + _("Building font cache"), + _("Please wait while your font cache is rebuilt.\n" + "This should take less than few minutes."), NULL ); + char *path; + path = (char *)malloc( PATH_MAX + 1 ); + /* Fontconfig doesnt seem to know where windows fonts are with + * current contribs. So just tell default windows font directory + * is the place to search fonts + */ + GetWindowsDirectory( path, PATH_MAX + 1 ); + strcat( path, "\\fonts" ); + if( p_dialog ) + dialog_ProgressSet( p_dialog, NULL, 0.4 ); + + FcConfigAppFontAddDir( NULL , path ); + free(path); + + + if( p_dialog ) + dialog_ProgressSet( p_dialog, NULL, 0.5 ); +#endif + mtime_t t1, t2; + + msg_Dbg( p_filter, "Building font database."); + t1 = mdate(); + FcConfigBuildFonts( NULL ); + t2 = mdate(); + + msg_Dbg( p_filter, "Finished building font database." ); + msg_Dbg( p_filter, "Took %ld microseconds", (long)((t2 - t1)) ); + fontpattern = FcPatternCreate(); + + if( !fontpattern ) + { + msg_Err( p_filter, "Creating fontpattern failed"); + goto error; + } + +#ifdef WIN32 + if( p_dialog ) + dialog_ProgressSet( p_dialog, NULL, 0.7 ); +#endif FcPatternAddString( fontpattern, FC_FAMILY, psz_fontfamily); FcPatternAddString( fontpattern, FC_SIZE, psz_fontsize ); + free( psz_fontsize ); if( FcConfigSubstitute( NULL, fontpattern, FcMatchPattern ) == FcFalse ) { - FcPatternDestroy( fontpattern ); - free( psz_fontsize ); + msg_Err( p_filter, "FontSubstitute failed"); goto error; } FcDefaultSubstitute( fontpattern ); +#ifdef WIN32 + if( p_dialog ) + dialog_ProgressSet( p_dialog, NULL, 0.8 ); +#endif + /* 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( fontresult == FcResultNoMatch ) + if( !fontmatch || fontresult == FcResultNoMatch ) { - free( psz_fontsize ); - FcPatternDestroy( fontpattern ); - FcPatternDestroy( fontmatch ); + msg_Err( p_filter, "Fontmatching failed"); goto error; } FcPatternGetString( fontmatch, FC_FILE, 0, (FcChar8 **)&psz_fontfile); FcPatternGetInteger( fontmatch, FC_INDEX, 0, &fontindex ); - free( psz_fontsize ); if( !psz_fontfile ) { - FcPatternDestroy( fontpattern ); - FcPatternDestroy( fontmatch ); + msg_Err( p_filter, "Failed to get fontfile"); goto error; } - msg_Dbg( p_filter, "Using %s as font from file %s", psz_fontfamily, psz_fontfile); + + msg_Dbg( p_filter, "Using %s as font from file %s", psz_fontfamily, psz_fontfile ); + p_sys->psz_fontfamily = strdup( psz_fontfamily ); +# ifdef WIN32 + if( p_dialog ) + { + dialog_ProgressSet( p_dialog, NULL, 1.0 ); + dialog_ProgressDestroy( p_dialog ); + } +# endif + #else + p_sys->psz_fontfamily = strdup( DEFAULT_FONT ) psz_fontfile = psz_fontfamily; #endif @@ -411,12 +468,6 @@ static int Create( vlc_object_t *p_this ) goto error; } -#ifdef HAVE_FONTCONFIG - p_sys->b_fontconfig_ok = false; - p_sys->p_fontconfig = NULL; - p_sys->p_fontbuilder = FontBuilderAttach( p_filter ); -#endif - p_sys->i_use_kerning = FT_HAS_KERNING( p_sys->p_face ); if( SetFontSize( p_filter, 0 ) != VLC_SUCCESS ) goto error; @@ -439,10 +490,14 @@ static int Create( vlc_object_t *p_this ) 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; } @@ -468,7 +523,8 @@ static void Destroy( vlc_object_t *p_this ) } #ifdef HAVE_FONTCONFIG - FontBuilderDetach( p_filter, p_sys->p_fontbuilder ); + if( p_sys->p_xml ) xml_Delete( p_sys->p_xml ); + free( p_sys->psz_fontfamily ); #endif /* FcFini asserts calling the subfunction FcCacheFini() @@ -480,153 +536,6 @@ static void Destroy( vlc_object_t *p_this ) free( p_sys ); } -#ifdef HAVE_FONTCONFIG -static vlc_mutex_t fb_lock = VLC_STATIC_MUTEX; - -static vlc_object_t *FontBuilderAttach( filter_t *p_filter ) -{ - /* Check for an existing Fontbuilder thread */ - vlc_mutex_lock( &fb_lock ); - vlc_object_t *p_fontbuilder = - vlc_object_find_name( p_filter->p_libvlc, - "fontlist builder", FIND_CHILD ); - - if( !p_fontbuilder ) - { - /* Create the FontBuilderThread thread as a child of a top-level - * object, so that it can survive the destruction of the - * freetype object - the fontlist only needs to be built once, - * and calling the fontbuild a second time while the first is - * still in progress can cause thread instabilities. - * - * XXX The fontbuilder will be destroy as soon as it is unused. - */ - - p_fontbuilder = vlc_object_create( p_filter->p_libvlc, - sizeof(vlc_object_t) ); - if( p_fontbuilder ) - { - p_fontbuilder->psz_object_name = strdup( "fontlist builder" ); - p_fontbuilder->p_private = NULL; - vlc_object_set_destructor( p_fontbuilder, FontBuilderDestructor ); - - vlc_object_attach( p_fontbuilder, p_filter->p_libvlc ); - - var_Create( p_fontbuilder, "build-done", VLC_VAR_BOOL ); - var_SetBool( p_fontbuilder, "build-done", false ); - var_Create( p_fontbuilder, "build-joined", VLC_VAR_BOOL ); - var_SetBool( p_fontbuilder, "build-joined", false ); - - if( vlc_thread_create( p_fontbuilder, - "fontlist builder", - FontBuilderThread, - VLC_THREAD_PRIORITY_LOW ) ) - { - msg_Warn( p_filter, "fontconfig database builder thread can't " - "be launched. Font styling support will be limited." ); - } - } - } - - if( p_fontbuilder ) - { - var_AddCallback( p_fontbuilder, "build-done", FontBuilderDone, p_filter ); - FontBuilderGetFcConfig( p_filter, p_fontbuilder ); - } - vlc_mutex_unlock( &fb_lock ); - return p_fontbuilder; -} -static void FontBuilderDetach( filter_t *p_filter, vlc_object_t *p_fontbuilder ) -{ - vlc_mutex_lock( &fb_lock ); - if( p_fontbuilder ) - { - var_DelCallback( p_fontbuilder, "build-done", FontBuilderDone, p_filter ); - - /* We wait for the thread on the first FontBuilderDetach */ - if( !var_GetBool( p_fontbuilder, "build-joined" ) ) - { - var_SetBool( p_fontbuilder, "build-joined", true ); - vlc_mutex_unlock( &fb_lock ); - /* We need to unlock otherwise we may not join (the thread waiting - * for the lock). It is safe to unlock as no one else will try a - * join and we have a reference on the object) */ - vlc_thread_join( p_fontbuilder ); - vlc_mutex_lock( &fb_lock ); - } - vlc_object_release( p_fontbuilder ); - } - vlc_mutex_unlock( &fb_lock ); -} -static void* FontBuilderThread( vlc_object_t *p_this ) -{ - FcConfig *p_fontconfig = FcInitLoadConfig(); - - if( p_fontconfig ) - { - mtime_t t1, t2; - int canc = vlc_savecancel (); - - //msg_Dbg( p_this, "Building font database..." ); - msg_Dbg( p_this, "Building font database..." ); - t1 = mdate(); - if(! FcConfigBuildFonts( 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_this, "fontconfig database can't be built. " - "Font styling won't be available" ); - } - t2 = mdate(); - - msg_Dbg( p_this, "Finished building font database." ); - msg_Dbg( p_this, "Took %ld microseconds", (long)((t2 - t1)) ); - - vlc_mutex_lock( &fb_lock ); - p_this->p_private = p_fontconfig; - vlc_mutex_unlock( &fb_lock ); - - var_SetBool( p_this, "build-done", true ); - vlc_restorecancel (canc); - } - return NULL; -} -static void FontBuilderGetFcConfig( filter_t *p_filter, vlc_object_t *p_fontbuilder ) -{ - filter_sys_t *p_sys = p_filter->p_sys; - - p_sys->p_fontconfig = p_fontbuilder->p_private; - p_sys->b_fontconfig_ok = p_fontbuilder->p_private != NULL; -} -static void FontBuilderDestructor( vlc_object_t *p_this ) -{ - FcConfig *p_fontconfig = p_this->p_private; - - if( p_fontconfig ) - FcConfigDestroy( p_fontconfig ); -} -static int FontBuilderDone( vlc_object_t *p_this, const char *psz_var, - vlc_value_t oldval, vlc_value_t newval, void *param ) -{ - filter_t *p_filter = param; - - if( newval.b_bool ) - { - vlc_mutex_lock( &fb_lock ); - - FontBuilderGetFcConfig( p_filter, p_this ); - - vlc_mutex_unlock( &fb_lock ); - } - - VLC_UNUSED(psz_var); - VLC_UNUSED(oldval); - return VLC_SUCCESS; -} -#endif - /***************************************************************************** * Make any TTF/OTF fonts present in the attachments of the media file * and store them for later use by the FreeType Engine @@ -693,6 +602,7 @@ static int LoadFontsFromAttachments( filter_t *p_filter ) static int Render( filter_t *p_filter, subpicture_region_t *p_region, line_desc_t *p_line, int i_width, int i_height ) { + VLC_UNUSED(p_filter); static const uint8_t pi_gamma[16] = {0x00, 0x52, 0x84, 0x96, 0xb8, 0xca, 0xdc, 0xee, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; @@ -2063,19 +1973,11 @@ static int ProcessLines( filter_t *p_filter, { char *psz_fontfile = NULL; - vlc_mutex_lock( &fb_lock ); - if( p_sys->b_fontconfig_ok ) - { - /* FIXME Is there really a race condition between FontConfig_Select with default fontconfig(NULL) - * and FcConfigBuildFonts ? If not it would be better to remove the check on b_fontconfig_ok */ - 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( &fb_lock ); - + psz_fontfile = FontConfig_Select( NULL, + p_style->psz_fontname, + p_style->b_bold, + p_style->b_italic, + &i_idx ); if( psz_fontfile && ! *psz_fontfile ) { msg_Warn( p_filter, "Fontconfig was unable to find a font: \"%s\" %s" @@ -2278,7 +2180,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 ) @@ -2293,12 +2194,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 */ @@ -2322,7 +2223,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; } @@ -2393,9 +2294,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 ); }