From c5cc4e5248e0bdff53b90ea66412c524cc24ee91 Mon Sep 17 00:00:00 2001 From: Derk-Jan Hartman Date: Tue, 7 Feb 2006 15:18:06 +0000 Subject: [PATCH] * Introduced a new text_style_t * basic support for SSA formatted subs. (disable with --no-subsdec-formatted option) * changes to freetype renderer to support the font color, size and alpha options of text_style_t (other options are possible, just not implemented yet. Full text_style_t support requires a more advanced renderer though. ) * changes to modules to support text_style_t instead of the old sub options. * Some changes to subsdec to only iconv to UTF-8 if source is !UTF-8. refs #82 not supported are style runs (styles on substrings). --- include/vlc_osd.h | 47 ++- include/vlc_video.h | 5 +- modules/codec/cmml/intf.c | 8 +- modules/codec/subsdec.c | 538 ++++++++++++++++++++++------ modules/misc/freetype.c | 48 +-- modules/video_filter/marq.c | 24 +- modules/video_filter/rss.c | 17 +- modules/video_filter/time.c | 32 +- src/video_output/vout_subpictures.c | 10 +- 9 files changed, 544 insertions(+), 185 deletions(-) diff --git a/include/vlc_osd.h b/include/vlc_osd.h index 8bd8ba3f1c..d192cdf385 100644 --- a/include/vlc_osd.h +++ b/include/vlc_osd.h @@ -39,7 +39,7 @@ * if used inside a transcoding command. For example: * * vlc dvdsimple:///dev/dvd --extraintf rc - * --sout='#transcode{osd}:std{access=udp,mux=ts,dst=dest_ipaddr}' + * --sout='#transcode{osd}:std{access=udp,mux=ts,url=dest_ipaddr}' * --osdmenu-file=share/osdmenu/dvd.cfg * * Each OSD menu element, called "action", defines a hotkey action. Each action @@ -117,18 +117,47 @@ extern "C" { #define OSD_MUTE_ICON 4 /** - * Text style information. - * This struct is currently ignored + * Text style + * + * A text style is used to specify the formatting of text. + * A font renderer can use the supplied information to render the text specified. */ struct text_style_t { - int i_size; - uint32_t i_color; - vlc_bool_t b_italic; - vlc_bool_t b_bold; - vlc_bool_t b_underline; + char * psz_fontname; /**< The name of the font */ + int i_font_size; /**< The font size in pixels */ + int i_font_color; /**< The color of the text 0xRRGGBB (native endianness) */ + int i_font_alpha; /**< The transparency of the text. + 0x00 is fully opaque, 0xFF fully transparent */ + int i_style_flags; /**< Formatting style flags */ + int i_outline_color; /**< The color of the outline 0xRRGGBB */ + int i_outline_alpha; /**< The transparency of the outline. + 0x00 is fully opaque, 0xFF fully transparent */ + int i_shadow_color; /**< The color of the shadow 0xRRGGBB */ + int i_shadow_alpha; /**< The transparency of the shadow. + 0x00 is fully opaque, 0xFF fully transparent */ + int i_background_color; /**< The color of the background 0xRRGGBB */ + int i_background_alpha; /**< The transparency of the background. + 0x00 is fully opaque, 0xFF fully transparent */ + int i_outline_width; /**< The width of the outline in pixels */ + int i_shadow_width; /**< The width of the shadow in pixels */ + int i_spacing; /**< The spaceing between glyphs in pixels */ + int i_text_align; /**< An alignment hint for the text */ }; -static const text_style_t default_text_style = { 22, 0xffffff, VLC_FALSE, VLC_FALSE, VLC_FALSE }; + +/* Style flags for \ref text_style_t */ +#define STYLE_BOLD 1 +#define STYLE_ITALIC 2 +#define STYLE_OUTLINE 4 +#define STYLE_SHADOW 8 +#define STYLE_BACKGROUND 16 +#define STYLE_UNDERLINE 32 +#define STYLE_STRIKEOUT 64 + +static const text_style_t default_text_style = { NULL, 22, 0xffffff, 0xff, STYLE_OUTLINE, + 0x000000, 0xff, 0x000000, 0xff, 0xffffff, 0x80, 1, 0, -1, 0 }; + + /** * OSD menu button states diff --git a/include/vlc_video.h b/include/vlc_video.h index 3790f2af5b..156a3b5bb6 100644 --- a/include/vlc_video.h +++ b/include/vlc_video.h @@ -209,10 +209,7 @@ struct subpicture_region_t int i_y; /**< position of region */ char *psz_text; /**< text string comprising this region */ - int i_text_color; /**< text color (RGB native endianess) */ - int i_text_alpha; /**< text transparency */ - int i_text_size; /**< text size */ - int i_text_align; /**< horizontal alignment hint for */ + text_style_t *p_style; /* a description of the text style formatting */ subpicture_region_t *p_next; /**< next region in the list */ subpicture_region_t *p_cache; /**< modified version of this region */ diff --git a/modules/codec/cmml/intf.c b/modules/codec/cmml/intf.c index c55e54eb99..b8a71fd124 100644 --- a/modules/codec/cmml/intf.c +++ b/modules/codec/cmml/intf.c @@ -821,15 +821,11 @@ static int DisplayAnchor( intf_thread_t *p_intf, { text_style_t *p_style = NULL; - text_style_t blue_with_underline = default_text_style; - blue_with_underline.b_underline = VLC_TRUE; - blue_with_underline.i_color = 0x22ff22; - if( psz_anchor_url ) { /* Should display subtitle underlined and in blue, but it looks * like VLC doesn't implement any text styles yet. D'oh! */ - p_style = &blue_with_underline; + // p_style = &blue_with_underline; } @@ -837,7 +833,7 @@ static int DisplayAnchor( intf_thread_t *p_intf, * coordinates. Need to look at the subpicture display system to * work out why. */ if ( vout_ShowTextAbsolute( p_vout, DEFAULT_CHAN, - psz_anchor_description, p_style, OSD_ALIGN_BOTTOM, + psz_anchor_description, NULL, OSD_ALIGN_BOTTOM, i_margin_h, i_margin_v, i_now, 0 ) == VLC_SUCCESS ) { /* Displayed successfully */ diff --git a/modules/codec/subsdec.c b/modules/codec/subsdec.c index 256646d4ab..26f0ef8f2e 100644 --- a/modules/codec/subsdec.c +++ b/modules/codec/subsdec.c @@ -6,6 +6,7 @@ * * Authors: Gildas Bazin * Samuel Hocevar + * Derk-Jan Hartman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -31,16 +32,30 @@ #include "vlc_osd.h" #include "vlc_filter.h" - #include "charset.h" +typedef struct +{ + char * psz_stylename; /* The name of the style, no comma's allowed */ + text_style_t font_style; + int i_align; + int i_margin_h; + int i_margin_v; +} ssa_style_t; + /***************************************************************************** * decoder_sys_t : decoder descriptor *****************************************************************************/ struct decoder_sys_t { + vlc_bool_t b_ass; /* The subs are ASS */ + int i_original_height; + int i_original_width; int i_align; /* Subtitles alignment on the vout */ vlc_iconv_t iconv_handle; /* handle to iconv instance */ + + ssa_style_t **pp_ssa_styles; + int i_ssa_styles; }; /***************************************************************************** @@ -51,9 +66,13 @@ static void CloseDecoder ( vlc_object_t * ); static subpicture_t *DecodeBlock ( decoder_t *, block_t ** ); static subpicture_t *ParseText ( decoder_t *, block_t * ); +static void ParseSSAHeader ( decoder_t * ); +static void ParseSSAString ( decoder_t *, char *, subpicture_t * ); +static void ParseColor ( decoder_t *, char *, int *, int * ); static void StripTags ( char * ); #define DEFAULT_NAME "Default" +#define MAX_LINE 8192 /***************************************************************************** * Module descriptor. @@ -87,6 +106,10 @@ static char *ppsz_justification_text[] = {N_("Center"),N_("Left"),N_("Right")}; #define ENCODING_LONGTEXT N_("Set the encoding used in text subtitles") #define ALIGN_TEXT N_("Subtitles justification") #define ALIGN_LONGTEXT N_("Set the justification of subtitles") +#define FORMAT_TEXT N_("Formatted Subtitles") +#define FORMAT_LONGTEXT N_("Some subtitle formats allow for text formatting.\ + VLC partly implements this, but you can choose to disable all formatting.") + vlc_module_begin(); set_shortname( _("Subtitles")); @@ -102,6 +125,8 @@ vlc_module_begin(); add_string( "subsdec-encoding", DEFAULT_NAME, NULL, ENCODING_TEXT, ENCODING_LONGTEXT, VLC_FALSE ); change_string_list( ppsz_encodings, 0, 0 ); + add_bool( "subsdec-formatted", VLC_TRUE, NULL, FORMAT_TEXT, FORMAT_LONGTEXT, + VLC_FALSE ); vlc_module_end(); /***************************************************************************** @@ -114,7 +139,7 @@ static int OpenDecoder( vlc_object_t *p_this ) { decoder_t *p_dec = (decoder_t*)p_this; decoder_sys_t *p_sys; - vlc_value_t val; + vlc_value_t val; if( p_dec->fmt_in.i_codec != VLC_FOURCC('s','u','b','t') && p_dec->fmt_in.i_codec != VLC_FOURCC('s','s','a',' ') ) @@ -131,17 +156,22 @@ static int OpenDecoder( vlc_object_t *p_this ) msg_Err( p_dec, "out of memory" ); return VLC_EGENERIC; } - - var_Create( p_dec, "subsdec-align", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT ); - var_Get( p_dec, "subsdec-align", &val ); - p_sys->i_align = val.i_int; + + /* init of p_sys */ + p_sys->i_align = 0; + p_sys->iconv_handle = (vlc_iconv_t)-1; + p_sys->b_ass = VLC_FALSE; + p_sys->i_original_height = -1; + p_sys->i_original_width = -1; + p_sys->pp_ssa_styles = NULL; + p_sys->i_ssa_styles = 0; if( p_dec->fmt_in.subs.psz_encoding && *p_dec->fmt_in.subs.psz_encoding ) { msg_Dbg( p_dec, "using character encoding: %s", p_dec->fmt_in.subs.psz_encoding ); - p_sys->iconv_handle = - vlc_iconv_open( "UTF-8", p_dec->fmt_in.subs.psz_encoding ); + if( strcmp( p_dec->fmt_in.subs.psz_encoding, "UTF-8" ) ) + p_sys->iconv_handle = vlc_iconv_open( "UTF-8", p_dec->fmt_in.subs.psz_encoding ); } else { @@ -150,22 +180,42 @@ static int OpenDecoder( vlc_object_t *p_this ) var_Get( p_dec, "subsdec-encoding", &val ); if( !strcmp( val.psz_string, DEFAULT_NAME ) ) { - p_sys->iconv_handle = vlc_iconv_open( "UTF-8", "ISO-8859-1" ); - msg_Dbg( p_dec, "using default character encoding: %s", "ISO-8859-1" ); + char *psz_charset =(char*)malloc( 100 ); +#ifdef __APPLE__ + /* Most subtitles are not in UTF-8, which is the default on Mac OS X */ + psz_charset = "ISO-8859-1"; +#else + vlc_current_charset( &psz_charset ); +#endif + p_sys->iconv_handle = vlc_iconv_open( "UTF-8", psz_charset ); + msg_Dbg( p_dec, "using default character encoding: %s", psz_charset ); + free( psz_charset ); + } + else if( !strcmp( val.psz_string, "UTF-8" ) ) + { + msg_Dbg( p_dec, "using character encoding: UTF-8" ); } else if( val.psz_string ) { msg_Dbg( p_dec, "using character encoding: %s", val.psz_string ); p_sys->iconv_handle = vlc_iconv_open( "UTF-8", val.psz_string ); + if( p_sys->iconv_handle == (vlc_iconv_t)-1 ) + { + msg_Warn( p_dec, "unable to do requested conversion" ); + } } - - if( p_sys->iconv_handle == (vlc_iconv_t)-1 ) - { - msg_Warn( p_dec, "unable to do requested conversion" ); - } - if( val.psz_string ) free( val.psz_string ); } + + var_Create( p_dec, "subsdec-align", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT ); + var_Get( p_dec, "subsdec-align", &val ); + p_sys->i_align = val.i_int; + + if( p_dec->fmt_in.i_codec == VLC_FOURCC('s','s','a',' ') && var_CreateGetBool( p_dec, "subsdec-formatted" ) ) + { + if( p_dec->fmt_in.i_extra > 0 ) + ParseSSAHeader( p_dec ); + } return VLC_SUCCESS; } @@ -177,7 +227,7 @@ static int OpenDecoder( vlc_object_t *p_this ) ****************************************************************************/ static subpicture_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block ) { - subpicture_t *p_spu; + subpicture_t *p_spu = NULL; if( !pp_block || *pp_block == NULL ) return NULL; @@ -201,6 +251,20 @@ static void CloseDecoder( vlc_object_t *p_this ) { vlc_iconv_close( p_sys->iconv_handle ); } + + if( p_sys->pp_ssa_styles ) + { + int i; + for( i = 0; i < p_sys->i_ssa_styles; i++ ) + { + if( p_sys->pp_ssa_styles[i]->psz_stylename ) free( p_sys->pp_ssa_styles[i]->psz_stylename ); + p_sys->pp_ssa_styles[i]->psz_stylename = NULL; + if( p_sys->pp_ssa_styles[i]->font_style.psz_fontname ) free( p_sys->pp_ssa_styles[i]->font_style.psz_fontname ); + p_sys->pp_ssa_styles[i]->font_style.psz_fontname = NULL; + if( p_sys->pp_ssa_styles[i] ) free( p_sys->pp_ssa_styles[i] ); p_sys->pp_ssa_styles[i] = NULL; + } + free( p_sys->pp_ssa_styles ); p_sys->pp_ssa_styles = NULL; + } free( p_sys ); } @@ -211,9 +275,8 @@ static void CloseDecoder( vlc_object_t *p_this ) static subpicture_t *ParseText( decoder_t *p_dec, block_t *p_block ) { decoder_sys_t *p_sys = p_dec->p_sys; - subpicture_t *p_spu = 0; - char *psz_subtitle; - int i_align_h, i_align_v; + subpicture_t *p_spu = NULL; + char *psz_subtitle = NULL; video_format_t fmt; /* We cannot display a subpicture with no date */ @@ -234,9 +297,6 @@ static subpicture_t *ParseText( decoder_t *p_dec, block_t *p_block ) psz_subtitle = strndup( (const char *)p_block->p_buffer, p_block->i_buffer ); - i_align_h = p_sys->i_align ? 20 : 0; - i_align_v = 10; - if( p_sys->iconv_handle != (vlc_iconv_t)-1 ) { char *psz_new_subtitle; @@ -254,88 +314,26 @@ static subpicture_t *ParseText( decoder_t *p_dec, block_t *p_block ) &outbytes_left ); *psz_convert_buffer_out = '\0'; + if( psz_subtitle ) free( psz_subtitle ); + psz_subtitle = NULL; + if( inbytes_left ) { - msg_Warn( p_dec, "Failed to convert subtitle encoding, " - "dropping subtitle.\nTry setting a different " - "character-encoding for the subtitle." ); - free( psz_subtitle ); + msg_Err( p_dec, _("Failed to convert subtitle encoding.\n" + "Try manually setting a character-encoding " + "before you open the file.") ); return NULL; } - else - { - free( psz_subtitle ); - psz_subtitle = psz_new_subtitle; - } - } - - if( p_dec->fmt_in.i_codec == VLC_FOURCC('s','s','a',' ') ) - { - /* Decode SSA strings */ - /* We expect: ReadOrder, Layer, Style, Name, MarginL, MarginR, - * MarginV, Effect, Text */ - char *psz_new_subtitle; - char *psz_buffer_sub; - int i_comma; - int i_text; - - psz_buffer_sub = psz_subtitle; - for( ;; ) - { - i_comma = 0; - while( i_comma < 8 && - *psz_buffer_sub != '\0' ) - { - if( *psz_buffer_sub == ',' ) - { - i_comma++; - } - psz_buffer_sub++; - } - psz_new_subtitle = malloc( strlen( psz_buffer_sub ) + 1); - i_text = 0; - while( psz_buffer_sub[0] != '\0' ) - { - if( psz_buffer_sub[0] == '\\' && ( psz_buffer_sub[1] == 'n' || - psz_buffer_sub[1] == 'N' ) ) - { - psz_new_subtitle[i_text] = '\n'; - i_text++; - psz_buffer_sub += 2; - } - else if( psz_buffer_sub[0] == '{' && - psz_buffer_sub[1] == '\\' ) - { - /* SSA control code */ - while( psz_buffer_sub[0] != '\0' && - psz_buffer_sub[0] != '}' ) - { - psz_buffer_sub++; - } - psz_buffer_sub++; - } - else - { - psz_new_subtitle[i_text] = psz_buffer_sub[0]; - i_text++; - psz_buffer_sub++; - } - } - psz_new_subtitle[i_text] = '\0'; - free( psz_subtitle ); - psz_subtitle = psz_new_subtitle; - break; - } + psz_subtitle = psz_new_subtitle; } - StripTags( psz_subtitle ); - + /* Create the subpicture unit */ p_spu = p_dec->pf_spu_buffer_new( p_dec ); if( !p_spu ) { msg_Warn( p_dec, "can't get spu buffer" ); - free( psz_subtitle ); - return 0; + if( psz_subtitle ) free( psz_subtitle ); + return NULL; } /* Create a new subpicture region */ @@ -348,22 +346,350 @@ static subpicture_t *ParseText( decoder_t *p_dec, block_t *p_block ) if( !p_spu->p_region ) { msg_Err( p_dec, "cannot allocate SPU region" ); - free( psz_subtitle ); + if( psz_subtitle ) free( psz_subtitle ); p_dec->pf_spu_buffer_del( p_dec, p_spu ); - return 0; + return NULL; } - p_spu->p_region->psz_text = psz_subtitle; - p_spu->i_start = p_block->i_pts; - p_spu->i_stop = p_block->i_pts + p_block->i_length; - p_spu->b_ephemer = (p_block->i_length == 0); - p_spu->b_absolute = VLC_FALSE; + /* Decode and format the subpicture unit */ + if( p_dec->fmt_in.i_codec != VLC_FOURCC('s','s','a',' ') ) + { + /* Normal text subs, easy markup */ + p_spu->i_flags = SUBPICTURE_ALIGN_BOTTOM | p_sys->i_align; + p_spu->i_x = p_sys->i_align ? 20 : 0; + p_spu->i_y = 10; + + /* Remove formatting from string */ + StripTags( psz_subtitle ); + + p_spu->p_region->psz_text = psz_subtitle; + p_spu->i_start = p_block->i_pts; + p_spu->i_stop = p_block->i_pts + p_block->i_length; + p_spu->b_ephemer = (p_block->i_length == 0); + p_spu->b_absolute = VLC_FALSE; + } + else + { + /* Decode SSA strings */ + ParseSSAString( p_dec, psz_subtitle, p_spu ); + p_spu->i_start = p_block->i_pts; + p_spu->i_stop = p_block->i_pts + p_block->i_length; + p_spu->b_ephemer = (p_block->i_length == 0); + p_spu->b_absolute = VLC_FALSE; + if( psz_subtitle ) free( psz_subtitle ); + } + return p_spu; +} - p_spu->i_flags = OSD_ALIGN_BOTTOM | p_sys->i_align; - p_spu->i_x = i_align_h; - p_spu->i_y = i_align_v; +static void ParseSSAString( decoder_t *p_dec, char *psz_subtitle, subpicture_t *p_spu_in ) +{ + /* We expect MKV formatted SSA: + * ReadOrder, Layer, Style, CharacterName, MarginL, MarginR, + * MarginV, Effect, Text */ + decoder_sys_t *p_sys = p_dec->p_sys; + subpicture_t *p_spu = p_spu_in; + ssa_style_t *p_style = NULL; + char *psz_new_subtitle = NULL; + char *psz_buffer_sub = NULL; + char *psz_style = NULL; + char *psz_style_start = NULL; + char *psz_style_end = NULL; + int i_text = 0, i_comma = 0, i_strlen = 0, i; + int i_margin_l = 0, i_margin_r = 0, i_margin_v = 0; + + psz_buffer_sub = psz_subtitle; + + i_comma = 0; + while( i_comma < 8 && *psz_buffer_sub != '\0' ) + { + if( *psz_buffer_sub == ',' ) + { + i_comma++; + if( i_comma == 2 ) psz_style_start = &psz_buffer_sub[1]; + if( i_comma == 3 ) psz_style_end = &psz_buffer_sub[0]; + if( i_comma == 4 ) i_margin_l = (int)strtol( psz_buffer_sub+1, NULL, 10 ); + if( i_comma == 5 ) i_margin_r = (int)strtol( psz_buffer_sub+1, NULL, 10 ); + if( i_comma == 6 ) i_margin_v = (int)strtol( psz_buffer_sub+1, NULL, 10 ); + } + psz_buffer_sub++; + } - return p_spu; + if( *psz_buffer_sub == '\0' && i_comma == 8 ) + { + msg_Dbg( p_dec, "couldn't find all fields in this SSA line" ); + return; + } + + psz_new_subtitle = malloc( strlen( psz_buffer_sub ) + 1); + i_text = 0; + while( psz_buffer_sub[0] != '\0' ) + { + if( psz_buffer_sub[0] == '\\' && psz_buffer_sub[0] == 'n' ) + { + psz_new_subtitle[i_text] = ' '; + i_text++; + psz_buffer_sub += 2; + } + else if( psz_buffer_sub[0] == '\\' && psz_buffer_sub[1] == 'N' ) + { + psz_new_subtitle[i_text] = '\n'; + i_text++; + psz_buffer_sub += 2; + } + else if( psz_buffer_sub[0] == '{' && + psz_buffer_sub[1] == '\\' ) + { + /* SSA control code */ + while( psz_buffer_sub[0] != '\0' && + psz_buffer_sub[0] != '}' ) + { + psz_buffer_sub++; + } + psz_buffer_sub++; + } + else + { + psz_new_subtitle[i_text] = psz_buffer_sub[0]; + i_text++; + psz_buffer_sub++; + } + } + psz_new_subtitle[i_text] = '\0'; + + i_strlen = __MAX( psz_style_end - psz_style_start, 0); + psz_style = (char *)malloc( i_strlen + 1); + psz_style = memcpy( psz_style, psz_style_start, i_strlen ); + psz_style[i_strlen] = '\0'; + + for( i = 0; i < p_sys->i_ssa_styles; i++ ) + { + if( !strcmp( p_sys->pp_ssa_styles[i]->psz_stylename, psz_style ) ) + p_style = p_sys->pp_ssa_styles[i]; + } + if( psz_style ) free( psz_style ); + + p_spu->p_region->psz_text = psz_new_subtitle; + if( p_style == NULL ) + { + p_spu->i_flags = SUBPICTURE_ALIGN_BOTTOM | p_sys->i_align; + p_spu->i_x = p_sys->i_align ? 20 : 0; + p_spu->i_y = 10; + } + else + { + msg_Dbg( p_dec, "style is: %s", p_style->psz_stylename); + p_spu->p_region->p_style = &p_style->font_style; + p_spu->i_flags = p_style->i_align; + if( p_style->i_align & SUBPICTURE_ALIGN_LEFT ) + { + p_spu->i_x = (i_margin_l) ? i_margin_l : p_style->i_margin_h; + } + else if( p_style->i_align & SUBPICTURE_ALIGN_RIGHT ) + { + p_spu->i_x = (i_margin_r) ? i_margin_r : p_style->i_margin_h; + } + p_spu->i_y = (i_margin_v) ? i_margin_v : p_style->i_margin_v; + } +} + +static char* GotoNextLine( char *psz_text ) +{ + char *p_newline = psz_text; + + while( p_newline[0] != '\0' ) + { + if( p_newline[0] == '\n' || p_newline[0] == '\r' ) + { + p_newline++; + while( p_newline[0] == '\n' || p_newline[0] == '\r' ) + p_newline++; + break; + } + else p_newline++; + } + return p_newline; +} + +/***************************************************************************** + * ParseColor: SSA stores color in BBGGRR, in ASS it uses AABBGGRR + * The string value in the string can be a pure integer, or hexadecimal &HBBGGRR + *****************************************************************************/ +static void ParseColor( decoder_t *p_dec, char *psz_color, int *pi_color, int *pi_alpha ) +{ + int i_color = 0; + if( !strncasecmp( psz_color, "&H", 2 ) ) + { + /* textual HEX representation */ + i_color = (int) strtol( psz_color+2, NULL, 16 ); + } + else i_color = (int) strtol( psz_color, NULL, 0 ); + + *pi_color = 0; + *pi_color |= ( ( i_color & 0x000000FF ) << 16 ); /* Red */ + *pi_color |= ( ( i_color & 0x0000FF00 ) ); /* Green */ + *pi_color |= ( ( i_color & 0x00FF0000 ) >> 16 ); /* Blue */ + + if( pi_alpha != NULL ) + *pi_alpha = ( i_color & 0xFF000000 ) >> 24; +} + +/***************************************************************************** + * ParseSSAHeader: Retrieve global formatting information etc + *****************************************************************************/ +static void ParseSSAHeader( decoder_t *p_dec ) +{ + decoder_sys_t *p_sys = p_dec->p_sys; + char *psz_parser = NULL; + char *psz_header = malloc( p_dec->fmt_in.i_extra+1 ); + int i_section_type = 1; + + memcpy( psz_header, p_dec->fmt_in.p_extra, p_dec->fmt_in.i_extra ); + psz_header[ p_dec->fmt_in.i_extra] = '\0'; + + /* Handle [Script Info] section */ + psz_parser = strcasestr( psz_header, "[Script Info]" ); + if( psz_parser == NULL ) goto eof; + + psz_parser = GotoNextLine( psz_parser ); + + while( psz_parser[0] != '\0' ) + { + int temp; + char buffer_text[MAX_LINE + 1]; + + if( psz_parser[0] == '!' || psz_parser[0] == ';' ) /* comment */; + else if( sscanf( psz_parser, "PlayResX: %d", &temp ) == 1 ) + p_sys->i_original_width = temp; + else if( sscanf( psz_parser, "PlayResY: %d", &temp ) == 1 ) + p_sys->i_original_height = temp; + else if( sscanf( psz_parser, "Script Type: %8192s", buffer_text ) == 1 ) + { + if( !strcasecmp( buffer_text, "V4.00+" ) ) p_sys->b_ass = VLC_TRUE; + } + else if( !strncasecmp( psz_parser, "[V4 Styles]", 11 ) ) + i_section_type = 1; + else if( !strncasecmp( psz_parser, "[V4+ Styles]", 12) ) + { + i_section_type = 2; + p_sys->b_ass = VLC_TRUE; + } + else if( !strncasecmp( psz_parser, "[Events]", 8 ) ) + i_section_type = 4; + else if( !strncasecmp( psz_parser, "Style:", 6 ) ) + { + int i_font_size, i_bold, i_italic, i_border, i_outline, i_shadow, i_underline, + i_strikeout, i_scale_x, i_scale_y, i_spacing, i_align, i_margin_l, i_margin_r, i_margin_v; + + char psz_temp_stylename[MAX_LINE+1]; + char psz_temp_fontname[MAX_LINE+1]; + char psz_temp_color1[MAX_LINE+1]; + char psz_temp_color2[MAX_LINE+1]; + char psz_temp_color3[MAX_LINE+1]; + char psz_temp_color4[MAX_LINE+1]; + + if( i_section_type == 1 ) /* V4 */ + { + if( sscanf( psz_parser, "Style: %8192[^,],%8192[^,],%d,%8192[^,],%8192[^,],%8192[^,],%8192[^,],%d,%d,%d,%d,%d,%d,%d,%d,%d%*[^\r\n]", + psz_temp_stylename, psz_temp_fontname, &i_font_size, + psz_temp_color1, psz_temp_color2, psz_temp_color3, psz_temp_color4, &i_bold, &i_italic, + &i_border, &i_outline, &i_shadow, &i_align, &i_margin_l, &i_margin_r, &i_margin_v ) == 16 ) + { + ssa_style_t *p_style = malloc( sizeof(ssa_style_t) ); + + p_style->psz_stylename = strdup( psz_temp_stylename ); + p_style->font_style.psz_fontname = strdup( psz_temp_fontname ); + p_style->font_style.i_font_size = i_font_size; + + ParseColor( p_dec, psz_temp_color1, &p_style->font_style.i_font_color, NULL ); + ParseColor( p_dec, psz_temp_color4, &p_style->font_style.i_shadow_color, NULL ); + p_style->font_style.i_outline_color = p_style->font_style.i_shadow_color; + p_style->font_style.i_font_alpha = p_style->font_style.i_outline_alpha = p_style->font_style.i_shadow_alpha = 0x00; + p_style->font_style.i_style_flags = 0; + if( i_bold ) p_style->font_style.i_style_flags |= STYLE_BOLD; + if( i_italic ) p_style->font_style.i_style_flags |= STYLE_ITALIC; + + if( i_border == 1 ) p_style->font_style.i_style_flags |= (STYLE_ITALIC | STYLE_OUTLINE); + else if( i_border == 3 ) + { + p_style->font_style.i_style_flags |= STYLE_BACKGROUND; + p_style->font_style.i_background_color = p_style->font_style.i_shadow_color; + p_style->font_style.i_background_alpha = p_style->font_style.i_shadow_alpha; + } + p_style->font_style.i_shadow_width = i_shadow; + p_style->font_style.i_outline_width = i_outline; + + p_style->i_align = 0; + if( i_align == 1 || i_align == 5 || i_align == 9 ) p_style->i_align |= SUBPICTURE_ALIGN_LEFT; + if( i_align == 3 || i_align == 7 || i_align == 11 ) p_style->i_align |= SUBPICTURE_ALIGN_RIGHT; + if( i_align < 4 ) p_style->i_align |= SUBPICTURE_ALIGN_BOTTOM; + else if( i_align < 8 ) p_style->i_align |= SUBPICTURE_ALIGN_TOP; + + p_style->i_margin_h = ( p_style->i_align & SUBPICTURE_ALIGN_RIGHT ) ? i_margin_r : i_margin_l; + p_style->i_margin_v = i_margin_v; + + TAB_APPEND( p_sys->i_ssa_styles, p_sys->pp_ssa_styles, p_style ); + } + else msg_Warn( p_dec, "SSA v4 styleline parsing failed" ); + } + else if( i_section_type == 2 ) /* V4+ */ + { + /* Format: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, OutlineColour, BackColour, + Bold, Italic, Underline, StrikeOut, ScaleX, ScaleY, Spacing, Angle, BorderStyle, Outline, + Shadow, Alignment, MarginL, MarginR, MarginV, Encoding + */ + if( sscanf( psz_parser, "Style: %8192[^,],%8192[^,],%d,%8192[^,],%8192[^,],%8192[^,],%8192[^,],%d,%d,%d,%d,%d,%d,%d,%*f,%d,%d,%d,%d,%d,%d,%d%*[^\r\n]", + psz_temp_stylename, psz_temp_fontname, &i_font_size, + psz_temp_color1, psz_temp_color2, psz_temp_color3, psz_temp_color4, &i_bold, &i_italic, + &i_underline, &i_strikeout, &i_scale_x, &i_scale_y, &i_spacing, &i_border, &i_outline, + &i_shadow, &i_align, &i_margin_l, &i_margin_r, &i_margin_v ) == 21 ) + { + ssa_style_t *p_style = malloc( sizeof(ssa_style_t) ); + + p_style->psz_stylename = strdup( psz_temp_stylename ); + p_style->font_style.psz_fontname = strdup( psz_temp_fontname ); + p_style->font_style.i_font_size = i_font_size; + msg_Dbg( p_dec, psz_temp_color1 ); + ParseColor( p_dec, psz_temp_color1, &p_style->font_style.i_font_color, &p_style->font_style.i_font_alpha ); + ParseColor( p_dec, psz_temp_color3, &p_style->font_style.i_outline_color, &p_style->font_style.i_outline_alpha ); + ParseColor( p_dec, psz_temp_color4, &p_style->font_style.i_shadow_color, &p_style->font_style.i_shadow_alpha ); + + p_style->font_style.i_style_flags = 0; + if( i_bold ) p_style->font_style.i_style_flags |= STYLE_BOLD; + if( i_italic ) p_style->font_style.i_style_flags |= STYLE_ITALIC; + if( i_underline ) p_style->font_style.i_style_flags |= STYLE_UNDERLINE; + if( i_strikeout ) p_style->font_style.i_style_flags |= STYLE_STRIKEOUT; + if( i_border == 1 ) p_style->font_style.i_style_flags |= (STYLE_ITALIC | STYLE_OUTLINE); + else if( i_border == 3 ) + { + p_style->font_style.i_style_flags |= STYLE_BACKGROUND; + p_style->font_style.i_background_color = p_style->font_style.i_shadow_color; + p_style->font_style.i_background_alpha = p_style->font_style.i_shadow_alpha; + } + p_style->font_style.i_shadow_width = ( i_border == 1 ) ? i_shadow : 0; + p_style->font_style.i_outline_width = ( i_border == 1 ) ? i_outline : 0; + p_style->font_style.i_spacing = i_spacing; + //p_style->font_style.f_angle = f_angle; + + p_style->i_align = 0; + if( i_align == 0x1 || i_align == 0x4 || i_align == 0x1 ) p_style->i_align |= SUBPICTURE_ALIGN_LEFT; + if( i_align == 0x3 || i_align == 0x6 || i_align == 0x9 ) p_style->i_align |= SUBPICTURE_ALIGN_RIGHT; + if( i_align == 0x7 || i_align == 0x8 || i_align == 0x9 ) p_style->i_align |= SUBPICTURE_ALIGN_TOP; + if( i_align == 0x1 || i_align == 0x2 || i_align == 0x3 ) p_style->i_align |= SUBPICTURE_ALIGN_BOTTOM; + p_style->i_margin_h = ( p_style->i_align & SUBPICTURE_ALIGN_RIGHT ) ? i_margin_r : i_margin_l; + p_style->i_margin_v = i_margin_v; + + /*TODO: Ignored: angle i_scale_x|y (fontscaling), i_encoding */ + TAB_APPEND( p_sys->i_ssa_styles, p_sys->pp_ssa_styles, p_style ); + } + else msg_Dbg( p_dec, "SSA V4+ styleline parsing failed" ); + } + } + psz_parser = GotoNextLine( psz_parser ); + } + +eof: + if( psz_header ) free( psz_header ); + return; } static void StripTags( char *psz_text ) diff --git a/modules/misc/freetype.c b/modules/misc/freetype.c index 04fb9ac522..2e404bc634 100644 --- a/modules/misc/freetype.c +++ b/modules/misc/freetype.c @@ -398,13 +398,13 @@ static int Render( filter_t *p_filter, subpicture_region_t *p_region, i_glyph_tmax = __MAX( i_glyph_tmax, p_glyph->top ); } - if( p_line->i_width < i_width ) + if( p_region->p_style && p_line->i_width < i_width ) { - if( p_region->i_text_align == SUBPICTURE_ALIGN_RIGHT ) + if( p_region->p_style->i_text_align == SUBPICTURE_ALIGN_RIGHT ) { i_align_offset = i_width - p_line->i_width; } - else if( p_region->i_text_align != SUBPICTURE_ALIGN_LEFT ) + else if( p_region->p_style->i_text_align != SUBPICTURE_ALIGN_LEFT ) { i_align_offset = ( i_width - p_line->i_width ) / 2; } @@ -475,13 +475,13 @@ static void DrawBlack( line_desc_t *p_line, int i_width, subpicture_region_t *p_ i_glyph_tmax = __MAX( i_glyph_tmax, p_glyph->top ); } - if( p_line->i_width < i_width ) + if( p_region->p_style && p_line->i_width < i_width ) { - if( p_region->i_text_align == SUBPICTURE_ALIGN_RIGHT ) + if( p_region->p_style->i_text_align == SUBPICTURE_ALIGN_RIGHT ) { i_align_offset = i_width - p_line->i_width; } - else if( p_region->i_text_align != SUBPICTURE_ALIGN_LEFT ) + else if( p_region->p_style->i_text_align != SUBPICTURE_ALIGN_LEFT ) { i_align_offset = ( i_width - p_line->i_width ) / 2; } @@ -625,13 +625,13 @@ static int RenderYUVA( filter_t *p_filter, subpicture_region_t *p_region, i_glyph_tmax = __MAX( i_glyph_tmax, p_glyph->top ); } - if( p_line->i_width < i_width ) + if( p_region->p_style && p_line->i_width < i_width ) { - if( p_region->i_text_align == SUBPICTURE_ALIGN_RIGHT ) + if( p_region->p_style->i_text_align == SUBPICTURE_ALIGN_RIGHT ) { i_align_offset = i_width - p_line->i_width; } - else if( p_region->i_text_align != SUBPICTURE_ALIGN_LEFT ) + else if( p_region->p_style->i_text_align != SUBPICTURE_ALIGN_LEFT ) { i_align_offset = ( i_width - p_line->i_width ) / 2; } @@ -668,7 +668,7 @@ static int RenderYUVA( filter_t *p_filter, subpicture_region_t *p_region, } /* Apply the alpha setting */ - for( i = 0; i < fmt.i_height * i_pitch; i++ ) + for( i = 0; i < (int)fmt.i_height * i_pitch; i++ ) p_dst_a[i] = p_dst_a[i] * (255 - i_alpha) / 255; return VLC_SUCCESS; @@ -702,13 +702,21 @@ static int RenderText( filter_t *p_filter, subpicture_region_t *p_region_out, psz_string = p_region_in->psz_text; if( !psz_string || !*psz_string ) return VLC_EGENERIC; - i_font_color = __MAX( __MIN( p_region_in->i_text_color, 0xFFFFFF ), 0 ); - if( i_font_color == 0xFFFFFF ) i_font_color = p_sys->i_font_color; + if( p_region_in->p_style ) + { + i_font_color = __MAX( __MIN( p_region_in->p_style->i_font_color, 0xFFFFFF ), 0 ); + i_font_alpha = __MAX( __MIN( p_region_in->p_style->i_font_alpha, 255 ), 0 ); + i_font_size = __MAX( __MIN( p_region_in->p_style->i_font_size, 255 ), 0 ); + } + else + { + i_font_color = p_sys->i_font_color; + i_font_alpha = 255 - p_sys->i_font_opacity; + i_font_size = p_sys->i_default_font_size; + } - i_font_alpha = __MAX( __MIN( p_region_in->i_text_alpha, 255 ), 0 ); + if( i_font_color == 0xFFFFFF ) i_font_color = p_sys->i_font_color; if( !i_font_alpha ) i_font_alpha = 255 - p_sys->i_font_opacity; - - i_font_size = __MAX( __MIN( p_region_in->i_text_size, 255 ), 0 ); SetFontSize( p_filter, i_font_size ); i_red = ( i_font_color & 0x00FF0000 ) >> 16; @@ -752,7 +760,7 @@ static int RenderText( filter_t *p_filter, subpicture_region_t *p_region_out, if( i_in_bytes ) { msg_Warn( p_filter, "failed to convert string to unicode (%s), " - "bytes left %d", strerror(errno), i_in_bytes ); + "bytes left %d", strerror(errno), (int)i_in_bytes ); goto error; } *(uint32_t*)p_out_buffer = 0; @@ -799,7 +807,7 @@ static int RenderText( filter_t *p_filter, subpicture_region_t *p_region_out, /* Calculate relative glyph positions and a bounding box for the * entire string */ - if( !(p_line = NewLine( psz_string )) ) + if( !(p_line = NewLine( (byte_t *)psz_string )) ) { msg_Err( p_filter, "out of memory" ); goto error; @@ -823,7 +831,7 @@ static int RenderText( filter_t *p_filter, subpicture_region_t *p_region_out, if( i_char == '\n' ) { psz_line_start = psz_unicode; - if( !(p_next = NewLine( psz_string )) ) + if( !(p_next = NewLine( (byte_t *)psz_string )) ) { msg_Err( p_filter, "out of memory" ); goto error; @@ -890,7 +898,7 @@ static int RenderText( filter_t *p_filter, subpicture_region_t *p_region_out, { p_line->pp_glyphs[ i ] = NULL; FreeLine( p_line ); - p_line = NewLine( psz_string ); + p_line = NewLine( (byte_t *)psz_string ); if( p_prev ) p_prev->p_next = p_line; else p_lines = p_line; @@ -989,7 +997,7 @@ static line_desc_t *NewLine( byte_t *psz_string ) /* We don't use CountUtf8Characters() here because we are not acutally * sure the string is utf8. Better be safe than sorry. */ - i_count = strlen( psz_string ); + i_count = strlen( (char *)psz_string ); p_line->pp_glyphs = malloc( sizeof(FT_BitmapGlyph) * ( i_count + 1 ) ); if( p_line->pp_glyphs == NULL ) diff --git a/modules/video_filter/marq.c b/modules/video_filter/marq.c index 6b7f457429..c3c58fa7a9 100644 --- a/modules/video_filter/marq.c +++ b/modules/video_filter/marq.c @@ -66,7 +66,7 @@ struct filter_sys_t char *psz_marquee; /* marquee string */ - int i_font_color, i_font_opacity, i_font_size; /* font control */ + text_style_t *p_style; /* font control */ time_t last_time; @@ -165,15 +165,17 @@ static int CreateFilter( vlc_object_t *p_this ) return VLC_ENOOBJ; } + p_sys->p_style = malloc( sizeof( text_style_t ) ); + memcpy( p_sys->p_style, &default_text_style, sizeof( text_style_t ) ); + p_sys->i_xoff = var_CreateGetInteger( p_input->p_libvlc , "marq-x" ); p_sys->i_yoff = var_CreateGetInteger( p_input->p_libvlc , "marq-y" ); p_sys->i_timeout = var_CreateGetInteger( p_input->p_libvlc , "marq-timeout" ); p_sys->i_pos = var_CreateGetInteger( p_input->p_libvlc , "marq-position" ); p_sys->psz_marquee = var_CreateGetString( p_input->p_libvlc, "marq-marquee" ); - var_Create( p_input->p_libvlc, "marq-opacity", VLC_VAR_INTEGER|VLC_VAR_DOINHERIT ); - p_sys->i_font_opacity = var_CreateGetInteger( p_input->p_libvlc , "marq-opacity" ); - p_sys->i_font_color = var_CreateGetInteger( p_input->p_libvlc , "marq-color" ); - p_sys->i_font_size = var_CreateGetInteger( p_input->p_libvlc , "marq-size" ); + p_sys->p_style->i_font_alpha = 255 - var_CreateGetInteger( p_input->p_libvlc , "marq-opacity" ); + p_sys->p_style->i_font_color = var_CreateGetInteger( p_input->p_libvlc , "marq-color" ); + p_sys->p_style->i_font_size = var_CreateGetInteger( p_input->p_libvlc , "marq-size" ); var_AddCallback( p_input->p_libvlc, "marq-x", MarqueeCallback, p_sys ); var_AddCallback( p_input->p_libvlc, "marq-y", MarqueeCallback, p_sys ); @@ -203,6 +205,7 @@ static void DestroyFilter( vlc_object_t *p_this ) filter_sys_t *p_sys = p_filter->p_sys; vlc_object_t *p_input; + if( p_sys->p_style ) free( p_sys->p_style ); if( p_sys->psz_marquee ) free( p_sys->psz_marquee ); free( p_sys ); @@ -293,10 +296,7 @@ static subpicture_t *Filter( filter_t *p_filter, mtime_t date ) p_spu->i_y = p_sys->i_yoff; p_spu->b_absolute = VLC_TRUE; } - p_spu->p_region->i_text_color = p_sys->i_font_color; - p_spu->p_region->i_text_alpha = 255 - p_sys->i_font_opacity; - p_spu->p_region->i_text_size = p_sys->i_font_size; - + p_spu->p_region->p_style = p_sys->p_style; p_sys->b_need_update = VLC_FALSE; return p_spu; @@ -326,15 +326,15 @@ static int MarqueeCallback( vlc_object_t *p_this, char const *psz_var, } else if ( !strncmp( psz_var, "marq-color", 8 ) ) /* "marq-col" */ { - p_sys->i_font_color = newval.i_int; + p_sys->p_style->i_font_color = newval.i_int; } else if ( !strncmp( psz_var, "marq-opacity", 8 ) ) /* "marq-opa" */ { - p_sys->i_font_opacity = newval.i_int; + p_sys->p_style->i_font_alpha = 255 - newval.i_int; } else if ( !strncmp( psz_var, "marq-size", 6 ) ) { - p_sys->i_font_size = newval.i_int; + p_sys->p_style->i_font_size = newval.i_int; } else if ( !strncmp( psz_var, "marq-timeout", 12 ) ) { diff --git a/modules/video_filter/rss.c b/modules/video_filter/rss.c index c33cf887bc..b1f5e92fef 100644 --- a/modules/video_filter/rss.c +++ b/modules/video_filter/rss.c @@ -91,7 +91,7 @@ struct filter_sys_t char *psz_marquee; /* marquee string */ - int i_font_color, i_font_opacity, i_font_size; /* font control */ + text_style_t *p_style; /* font control */ mtime_t last_date; @@ -212,13 +212,15 @@ static int CreateFilter( vlc_object_t *p_this ) p_sys->i_ttl = __MAX( 0, var_CreateGetInteger( p_filter, "rss-ttl" ) ); p_sys->psz_marquee = (char *)malloc( p_sys->i_length ); + p_sys->p_style = malloc( sizeof( text_style_t )); + memcpy( p_sys->p_style, &default_text_style, sizeof( text_style_t )); + p_sys->i_xoff = var_CreateGetInteger( p_filter, "rss-x" ); p_sys->i_yoff = var_CreateGetInteger( p_filter, "rss-y" ); p_sys->i_pos = var_CreateGetInteger( p_filter, "rss-position" ); - var_Create( p_filter, "rss-opacity", VLC_VAR_INTEGER|VLC_VAR_DOINHERIT ); - p_sys->i_font_opacity = var_CreateGetInteger( p_filter, "rss-opacity" ); - p_sys->i_font_color = var_CreateGetInteger( p_filter, "rss-color" ); - p_sys->i_font_size = var_CreateGetInteger( p_filter, "rss-size" ); + p_sys->p_style->i_font_alpha = 255 - var_CreateGetInteger( p_filter, "rss-opacity" ); + p_sys->p_style->i_font_color = var_CreateGetInteger( p_filter, "rss-color" ); + p_sys->p_style->i_font_size = var_CreateGetInteger( p_filter, "rss-size" ); if( FetchRSS( p_filter ) ) { @@ -258,6 +260,7 @@ static void DestroyFilter( vlc_object_t *p_this ) vlc_mutex_lock( &p_sys->lock ); + if( p_sys->p_style ) free( p_sys->p_style ); if( p_sys->psz_marquee ) free( p_sys->psz_marquee ); free( p_sys->psz_urls ); FreeRSS( p_filter ); @@ -383,9 +386,7 @@ static subpicture_t *Filter( filter_t *p_filter, mtime_t date ) p_spu->b_absolute = VLC_TRUE; } p_spu->i_height = 1; - p_spu->p_region->i_text_color = p_sys->i_font_color; - p_spu->p_region->i_text_alpha = 255 - p_sys->i_font_opacity; - p_spu->p_region->i_text_size = p_sys->i_font_size; + p_spu->p_region->p_style = p_sys->p_style; vlc_mutex_unlock( &p_sys->lock ); return p_spu; diff --git a/modules/video_filter/time.c b/modules/video_filter/time.c index aaa2d3fe37..130e820e27 100644 --- a/modules/video_filter/time.c +++ b/modules/video_filter/time.c @@ -60,10 +60,10 @@ static char *ppsz_color_descriptions[] = { N_("Default"), N_("Black"), *****************************************************************************/ struct filter_sys_t { - int i_xoff, i_yoff; /* offsets for the display string in the video window */ - char *psz_format; /* time format string */ - int i_pos; /* permit relative positioning (top, bottom, left, right, center) */ - int i_font_color, i_font_opacity, i_font_size; /* font control */ + int i_xoff, i_yoff; /* offsets for the display string in the video window */ + char *psz_format; /* time format string */ + int i_pos; /* permit relative positioning (top, bottom, left, right, center) */ + text_style_t *p_style; /* font control */ time_t last_time; }; @@ -145,14 +145,17 @@ static int CreateFilter( vlc_object_t *p_this ) return VLC_ENOOBJ; } + p_sys->p_style = malloc( sizeof( text_style_t ) ); + memcpy( p_sys->p_style, &default_text_style, sizeof( text_style_t ) ); + p_sys->i_xoff = var_CreateGetInteger( p_input->p_libvlc , "time-x" ); p_sys->i_yoff = var_CreateGetInteger( p_input->p_libvlc , "time-y" ); p_sys->psz_format = var_CreateGetString( p_input->p_libvlc, "time-format" ); p_sys->i_pos = var_CreateGetInteger( p_input->p_libvlc , "time-position" ); - var_Create( p_input->p_libvlc, "time-opacity", VLC_VAR_INTEGER|VLC_VAR_DOINHERIT ); - p_sys->i_font_opacity = var_CreateGetInteger( p_input->p_libvlc , "time-opacity" ); - p_sys->i_font_color = var_CreateGetInteger( p_input->p_libvlc , "time-color" ); - p_sys->i_font_size = var_CreateGetInteger( p_input->p_libvlc , "time-size" ); + + p_sys->p_style->i_font_alpha = 255 - var_CreateGetInteger( p_input->p_libvlc , "time-opacity" ); + p_sys->p_style->i_font_color = var_CreateGetInteger( p_input->p_libvlc , "time-color" ); + p_sys->p_style->i_font_size = var_CreateGetInteger( p_input->p_libvlc , "time-size" ); var_AddCallback( p_input->p_libvlc, "time-x", TimeCallback, p_sys ); var_AddCallback( p_input->p_libvlc, "time-y", TimeCallback, p_sys ); @@ -179,6 +182,7 @@ static void DestroyFilter( vlc_object_t *p_this ) filter_sys_t *p_sys = p_filter->p_sys; vlc_object_t *p_input; + if( p_sys->p_style ) free( p_sys->p_style ); if( p_sys->psz_format ) free( p_sys->psz_format ); free( p_sys ); /* Delete the time variables */ @@ -268,14 +272,12 @@ static subpicture_t *Filter( filter_t *p_filter, mtime_t date ) } else { /* set to an absolute xy, referenced to upper left corner */ - p_spu->i_flags = OSD_ALIGN_LEFT | OSD_ALIGN_TOP; + p_spu->i_flags = OSD_ALIGN_LEFT | OSD_ALIGN_TOP; p_spu->i_x = p_sys->i_xoff; p_spu->i_y = p_sys->i_yoff; p_spu->b_absolute = VLC_TRUE; } - p_spu->p_region->i_text_color = p_sys->i_font_color; - p_spu->p_region->i_text_alpha = 255 - p_sys->i_font_opacity; - p_spu->p_region->i_text_size = p_sys->i_font_size; + p_spu->p_region->p_style = p_sys->p_style; return p_spu; } @@ -303,15 +305,15 @@ static int TimeCallback( vlc_object_t *p_this, char const *psz_var, } else if ( !strncmp( psz_var, "time-color", 8 ) ) /* "time-c" */ { - p_sys->i_font_color = newval.i_int; + p_sys->p_style->i_font_color = newval.i_int; } else if ( !strncmp( psz_var, "time-opacity", 8 ) ) /* "time-o" */ { - p_sys->i_font_opacity = newval.i_int; + p_sys->p_style->i_font_alpha = 255 - newval.i_int; } else if ( !strncmp( psz_var, "time-size", 6 ) ) { - p_sys->i_font_size = newval.i_int; + p_sys->p_style->i_font_size = newval.i_int; } else if ( !strncmp( psz_var, "time-position", 8 ) ) /* willing to accept a match against time-pos */ diff --git a/src/video_output/vout_subpictures.c b/src/video_output/vout_subpictures.c index 12814124b3..a79c44aa44 100644 --- a/src/video_output/vout_subpictures.c +++ b/src/video_output/vout_subpictures.c @@ -256,7 +256,7 @@ subpicture_region_t *__spu_CreateRegion( vlc_object_t *p_this, p_region->p_cache = 0; p_region->fmt = *p_fmt; p_region->psz_text = 0; - p_region->i_text_color = 0xFFFFFF; + p_region->p_style = NULL; if( p_fmt->i_chroma == VLC_FOURCC('Y','U','V','P') ) p_fmt->p_palette = p_region->fmt.p_palette = @@ -299,7 +299,7 @@ subpicture_region_t *__spu_MakeRegion( vlc_object_t *p_this, p_region->p_cache = 0; p_region->fmt = *p_fmt; p_region->psz_text = 0; - p_region->i_text_color = 0xFFFFFF; + p_region->p_style = NULL; if( p_fmt->i_chroma == VLC_FOURCC('Y','U','V','P') ) p_fmt->p_palette = p_region->fmt.p_palette = @@ -324,7 +324,6 @@ void __spu_DestroyRegion( vlc_object_t *p_this, subpicture_region_t *p_region ) if( p_region->picture.pf_release ) p_region->picture.pf_release( &p_region->picture ); if( p_region->fmt.p_palette ) free( p_region->fmt.p_palette ); - if( p_region->psz_text ) free( p_region->psz_text ); if( p_region->p_cache ) __spu_DestroyRegion( p_this, p_region->p_cache ); free( p_region ); } @@ -591,8 +590,9 @@ void spu_RenderSubpictures( spu_t *p_spu, video_format_t *p_fmt, { if( p_spu->p_text && p_spu->p_text->p_module && p_spu->p_text->pf_render_text ) - { - p_region->i_text_align = p_subpic->i_flags & 0x3; + {/* + if( p_region->p_style ) + p_region->p_style->i_text_align = p_subpic->i_flags & 0x3; */ p_spu->p_text->pf_render_text( p_spu->p_text, p_region, p_region ); } -- 2.39.2