#include <vlc_common.h>
#include <vlc_plugin.h>
-#include <vlc_osd.h>
#include <vlc_filter.h>
#include <vlc_stream.h>
#include <vlc_xml.h>
int i_display_height;
#ifdef HAVE_FONTCONFIG
char* psz_fontfamily;
- xml_t *p_xml;
+ xml_reader_t *p_xml;
#endif
input_attachment_t **pp_font_attachments;
p_filter->p_sys = p_sys = malloc( sizeof( filter_sys_t ) );
if( !p_sys )
return VLC_ENOMEM;
- #ifdef HAVE_FONTCONFIG
+#ifdef HAVE_FONTCONFIG
p_sys->psz_fontfamily = NULL;
p_sys->p_xml = NULL;
#endif
var_Create( p_filter, "freetype-rel-fontsize",
VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
- 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" );
+ psz_fontfamily = var_InheritString( p_filter, "freetype-font" );
+ p_sys->i_default_font_size = var_InheritInteger( p_filter, "freetype-fontsize" );
+ p_sys->i_effect = var_InheritInteger( p_filter, "freetype-effect" );
+ p_sys->i_font_opacity = var_InheritInteger( 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 = var_InheritInteger( p_filter, "freetype-color" );
p_sys->i_font_color = __MAX( __MIN( p_sys->i_font_color , 0xFFFFFF ), 0 );
fontindex=0;
}
#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;
+ msg_Dbg( p_filter, "Building font databases.");
+ mtime_t t1, t2;
+ t1 = mdate();
#ifdef WIN32
dialog_progress_bar_t *p_dialog = NULL;
+ FcConfig *fcConfig = FcInitLoadConfig();
- if( !FcConfigUptoDate( NULL ) )
- {
- p_dialog = dialog_ProgressCreate( p_filter,
+ p_dialog = dialog_ProgressCreate( p_filter,
_("Building font cache"),
_("Please wait while your font cache is rebuilt.\n"
"This should take less than a few minutes."), NULL );
- }
- char *path = xmalloc( 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 ); */
+ FcConfigBuildFonts( fcConfig );
+ t2 = mdate();
+ msg_Dbg( p_filter, "Took %ld microseconds", (long)((t2 - t1)) );
if( p_dialog )
- dialog_ProgressSet( p_dialog, NULL, 0.5 );
+ {
+// dialog_ProgressSet( p_dialog, NULL, 1.0 );
+ dialog_ProgressDestroy( p_dialog );
+ p_dialog = NULL;
+ }
#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)) );
+ /* 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 )
{
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 );
}
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.*/
msg_Dbg( p_filter, "Using %s as font from file %s", psz_fontfamily,
psz_fontfile ? psz_fontfile : "(null)" );
p_sys->psz_fontfamily = strdup( psz_fontfamily );
-# ifdef WIN32
- if( p_dialog )
- {
- dialog_ProgressSet( p_dialog, NULL, 1.0 );
- dialog_ProgressDestroy( p_dialog );
- p_dialog = NULL;
- }
-# endif
#else
-#ifdef HAVE_FONTCONFIG
- p_sys->psz_fontfamily = strdup( DEFAULT_FONT );
psz_fontfile = psz_fontfamily;
-#endif
#endif
#ifdef HAVE_FONTCONFIG
if( fontmatch ) FcPatternDestroy( fontmatch );
if( fontpattern ) FcPatternDestroy( fontpattern );
-#endif
#ifdef WIN32
if( p_dialog )
dialog_ProgressDestroy( p_dialog );
+#endif
#endif
if( p_sys->p_face ) FT_Done_Face( p_sys->p_face );
}
#ifdef HAVE_FONTCONFIG
- if( p_sys->p_xml ) xml_Delete( p_sys->p_xml );
+ if( p_sys->p_xml ) xml_ReaderDelete( p_sys->p_xml );
free( p_sys->psz_fontfamily );
#endif
static int LoadFontsFromAttachments( filter_t *p_filter )
{
filter_sys_t *p_sys = p_filter->p_sys;
- input_thread_t *p_input;
input_attachment_t **pp_attachments;
int i_attachments_cnt;
- int k;
- int rv = VLC_SUCCESS;
- p_input = (input_thread_t *)vlc_object_find( p_filter, VLC_OBJECT_INPUT, FIND_PARENT );
- if( ! p_input )
+ if( filter_GetInputAttachments( p_filter, &pp_attachments, &i_attachments_cnt ) )
return VLC_EGENERIC;
- if( VLC_SUCCESS != input_Control( p_input, INPUT_GET_ATTACHMENTS, &pp_attachments, &i_attachments_cnt ))
- {
- vlc_object_release(p_input);
- return VLC_EGENERIC;
- }
-
p_sys->i_font_attachments = 0;
p_sys->pp_font_attachments = malloc( i_attachments_cnt * sizeof( input_attachment_t * ));
- if(! p_sys->pp_font_attachments )
- rv = VLC_ENOMEM;
+ if( !p_sys->pp_font_attachments )
+ return VLC_ENOMEM;
- for( k = 0; k < i_attachments_cnt; k++ )
+ for( int k = 0; k < i_attachments_cnt; k++ )
{
input_attachment_t *p_attach = pp_attachments[k];
- if( p_sys->pp_font_attachments )
+ if( ( !strcmp( p_attach->psz_mime, "application/x-truetype-font" ) || // TTF
+ !strcmp( p_attach->psz_mime, "application/x-font-otf" ) ) && // OTF
+ p_attach->i_data > 0 && p_attach->p_data )
{
- if(( !strcmp( p_attach->psz_mime, "application/x-truetype-font" ) || // TTF
- !strcmp( p_attach->psz_mime, "application/x-font-otf" ) ) && // OTF
- ( p_attach->i_data > 0 ) &&
- ( p_attach->p_data != NULL ) )
- {
- p_sys->pp_font_attachments[ p_sys->i_font_attachments++ ] = p_attach;
- }
- else
- {
- vlc_input_attachment_Delete( p_attach );
- }
+ p_sys->pp_font_attachments[ p_sys->i_font_attachments++ ] = p_attach;
}
else
{
}
free( pp_attachments );
- vlc_object_release(p_input);
-
- return rv;
+ return VLC_SUCCESS;
}
/*****************************************************************************
}
p_line->p_glyph_pos[ i ].x = i_pen_x;
p_line->p_glyph_pos[ i ].y = i_pen_y;
- i_error = FT_Load_Glyph( face, i_glyph_index, FT_LOAD_DEFAULT );
+ i_error = FT_Load_Glyph( face, i_glyph_index, FT_LOAD_NO_BITMAP | FT_LOAD_DEFAULT );
if( i_error )
{
- msg_Err( p_filter, "unable to render text FT_Load_Glyph returned"
- " %d", i_error );
- goto error;
+ i_error = FT_Load_Glyph( face, i_glyph_index, FT_LOAD_DEFAULT );
+ if( i_error )
+ {
+ msg_Err( p_filter, "unable to render text FT_Load_Glyph returned"
+ " %d", i_error );
+ goto error;
+ }
}
i_error = FT_Get_Glyph( glyph, &tmp_glyph );
if( i_error )
p_line->p_glyph_pos[ i ].x = *pi_pen_x;
p_line->p_glyph_pos[ i ].y = i_pen_y;
- i_error = FT_Load_Glyph( p_face, i_glyph_index, FT_LOAD_DEFAULT );
+ i_error = FT_Load_Glyph( p_face, i_glyph_index, FT_LOAD_NO_BITMAP | FT_LOAD_DEFAULT );
if( i_error )
{
- msg_Err( p_filter,
- "unable to render text FT_Load_Glyph returned %d", i_error );
- p_line->pp_glyphs[ i ] = NULL;
- return VLC_EGENERIC;
+ i_error = FT_Load_Glyph( p_face, i_glyph_index, FT_LOAD_DEFAULT );
+ if( i_error )
+ {
+ msg_Err( p_filter,
+ "unable to render text FT_Load_Glyph returned %d", i_error );
+ p_line->pp_glyphs[ i ] = NULL;
+ return VLC_EGENERIC;
+ }
}
/* Do synthetic styling now that Freetype supports it;
{
int rv = VLC_SUCCESS;
stream_t *p_sub = NULL;
- xml_reader_t *p_xml_reader = NULL;
if( !p_region_in || !p_region_in->psz_html )
return VLC_EGENERIC;
(uint8_t *) p_region_in->psz_html,
strlen( p_region_in->psz_html ),
true );
- if( p_sub )
+ if( unlikely(p_sub == NULL) )
+ return VLC_SUCCESS;
+
+ xml_reader_t *p_xml_reader = p_filter->p_sys->p_xml;
+ bool b_karaoke = false;
+
+ if( !p_xml_reader )
+ p_xml_reader = xml_ReaderCreate( p_filter, p_sub );
+ else
+ p_xml_reader = xml_ReaderReset( p_xml_reader, p_sub );
+
+ p_filter->p_sys->p_xml = p_xml_reader;
+ if( p_xml_reader )
{
- if( !p_filter->p_sys->p_xml ) p_filter->p_sys->p_xml = xml_Create( p_filter );
- if( p_filter->p_sys->p_xml )
+ /* Look for Root Node */
+ if( xml_ReaderRead( p_xml_reader ) == 1 )
{
- bool b_karaoke = false;
+ char *psz_node = xml_ReaderName( p_xml_reader );
- p_xml_reader = xml_ReaderCreate( p_filter->p_sys->p_xml, p_sub );
- if( p_xml_reader )
+ if( !strcasecmp( "karaoke", psz_node ) )
{
- /* Look for Root Node */
- if( xml_ReaderRead( p_xml_reader ) == 1 )
- {
- char *psz_node = xml_ReaderName( p_xml_reader );
-
- if( !strcasecmp( "karaoke", psz_node ) )
- {
- /* We're going to have to render the text a number
- * of times to show the progress marker on the text.
- */
- var_SetBool( p_filter, "text-rerender", true );
- b_karaoke = true;
- }
- else if( !strcasecmp( "text", psz_node ) )
- {
- b_karaoke = false;
- }
- else
- {
- /* Only text and karaoke tags are supported */
- msg_Dbg( p_filter, "Unsupported top-level tag '%s' ignored.", psz_node );
- xml_ReaderDelete( p_filter->p_sys->p_xml, p_xml_reader );
- p_xml_reader = NULL;
- rv = VLC_EGENERIC;
- }
-
- free( psz_node );
- }
+ /* We're going to have to render the text a number
+ * of times to show the progress marker on the text.
+ */
+ var_SetBool( p_filter, "text-rerender", true );
+ b_karaoke = true;
}
-
- if( p_xml_reader )
+ else if( !strcasecmp( "text", psz_node ) )
{
- uint32_t *psz_text;
- int i_len = 0;
- uint32_t i_runs = 0;
- uint32_t i_k_runs = 0;
- uint32_t *pi_run_lengths = NULL;
- uint32_t *pi_k_run_lengths = NULL;
- uint32_t *pi_k_durations = NULL;
- ft_style_t **pp_styles = NULL;
- FT_Vector result;
- line_desc_t *p_lines = NULL;
-
- psz_text = (uint32_t *)malloc( strlen( p_region_in->psz_html ) *
- sizeof( uint32_t ) );
- if( psz_text )
- {
- uint32_t k;
-
- rv = ProcessNodes( p_filter, p_xml_reader,
- p_region_in->p_style, psz_text, &i_len,
- &i_runs, &pi_run_lengths, &pp_styles,
+ b_karaoke = false;
+ }
+ else
+ {
+ /* Only text and karaoke tags are supported */
+ msg_Dbg( p_filter, "Unsupported top-level tag '%s' ignored.", psz_node );
+ p_filter->p_sys->p_xml = xml_ReaderReset( p_xml_reader, NULL );
+ p_xml_reader = NULL;
+ rv = VLC_EGENERIC;
+ }
- b_karaoke, &i_k_runs, &pi_k_run_lengths,
- &pi_k_durations );
+ free( psz_node );
+ }
+ }
- p_region_out->i_x = p_region_in->i_x;
- p_region_out->i_y = p_region_in->i_y;
+ if( p_xml_reader )
+ {
+ uint32_t *psz_text;
+ int i_len = 0;
+ uint32_t i_runs = 0;
+ uint32_t i_k_runs = 0;
+ uint32_t *pi_run_lengths = NULL;
+ uint32_t *pi_k_run_lengths = NULL;
+ uint32_t *pi_k_durations = NULL;
+ ft_style_t **pp_styles = NULL;
+ FT_Vector result;
+ line_desc_t *p_lines = NULL;
+
+ psz_text = (uint32_t *)malloc( strlen( p_region_in->psz_html ) *
+ sizeof( uint32_t ) );
+ if( psz_text )
+ {
+ rv = ProcessNodes( p_filter, p_xml_reader,
+ p_region_in->p_style, psz_text, &i_len,
+ &i_runs, &pi_run_lengths, &pp_styles,
+ b_karaoke, &i_k_runs, &pi_k_run_lengths,
+ &pi_k_durations );
- if(( rv == VLC_SUCCESS ) && ( i_len > 0 ))
- {
- rv = ProcessLines( p_filter, psz_text, i_len, i_runs,
- pi_run_lengths, pp_styles, &p_lines, &result,
- b_karaoke, i_k_runs, pi_k_run_lengths,
- pi_k_durations );
- }
+ p_region_out->i_x = p_region_in->i_x;
+ p_region_out->i_y = p_region_in->i_y;
- for( k=0; k<i_runs; k++)
- DeleteStyle( pp_styles[k] );
- free( pp_styles );
- free( pi_run_lengths );
- free( psz_text );
+ if(( rv == VLC_SUCCESS ) && ( i_len > 0 ))
+ {
+ rv = ProcessLines( p_filter, psz_text, i_len, i_runs,
+ pi_run_lengths, pp_styles, &p_lines,
+ &result, b_karaoke, i_k_runs,
+ pi_k_run_lengths, pi_k_durations );
+ }
- /* Don't attempt to render text that couldn't be layed out
- * properly.
- */
- if(( rv == VLC_SUCCESS ) && ( i_len > 0 ))
- {
- if( var_InheritBool( p_filter, "freetype-yuvp" ) )
- {
- Render( p_filter, p_region_out, p_lines,
- result.x, result.y );
- }
- else
- {
- RenderYUVA( p_filter, p_region_out, p_lines,
- result.x, result.y );
- }
- }
- }
- FreeLines( p_lines );
+ for( uint_fast32_t k=0; k<i_runs; k++)
+ DeleteStyle( pp_styles[k] );
+ free( pp_styles );
+ free( pi_run_lengths );
+ free( psz_text );
- xml_ReaderDelete( p_filter->p_sys->p_xml, p_xml_reader );
+ /* Don't attempt to render text that couldn't be layed out
+ * properly. */
+ if(( rv == VLC_SUCCESS ) && ( i_len > 0 ))
+ {
+ if( var_InheritBool( p_filter, "freetype-yuvp" ) )
+ Render( p_filter, p_region_out, p_lines,
+ result.x, result.y );
+ else
+ RenderYUVA( p_filter, p_region_out, p_lines,
+ result.x, result.y );
}
}
- stream_Delete( p_sub );
+ p_filter->p_sys->p_xml = xml_ReaderReset( p_xml_reader, NULL );
+ FreeLines( p_lines );
}
-
+ stream_Delete( p_sub );
return rv;
}