X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=modules%2Fmisc%2Fwin32text.c;h=e3464674ed26ea50961fd1afe1b8455918d1fc0e;hb=e30cb4fb539e4fa5ae16ae04c45fe9c6ed52f586;hp=a51dc035a799bc04089ac4b67484cf82bfaabdab;hpb=2cb472dba008f7d877ffe6bae9c5575253365282;p=vlc diff --git a/modules/misc/win32text.c b/modules/misc/win32text.c index a51dc035a7..e3464674ed 100644 --- a/modules/misc/win32text.c +++ b/modules/misc/win32text.c @@ -1,10 +1,11 @@ /***************************************************************************** * win32text.c : Text drawing routines using the TextOut win32 API ***************************************************************************** - * Copyright (C) 2002 - 2005 the VideoLAN team + * Copyright (C) 2002 - 2009 the VideoLAN team * $Id$ * * Authors: Gildas Bazin + * Pierre Ynard * * 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 @@ -24,14 +25,17 @@ /***************************************************************************** * Preamble *****************************************************************************/ -#include /* malloc(), free() */ -#include -#include -#include -#include "vlc_osd.h" -#include "vlc_block.h" -#include "vlc_filter.h" +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include +#include +#include +#include +#include #include @@ -52,60 +56,65 @@ static int SetFont( filter_t *, int ); * Module descriptor *****************************************************************************/ #define FONT_TEXT N_("Font") -#define FONT_LONGTEXT N_("Font filename") +#define FONT_LONGTEXT N_("Filename for the font you want to use") #define FONTSIZE_TEXT N_("Font size in pixels") -#define FONTSIZE_LONGTEXT N_("The size of the fonts used by the osd module. " \ - "If set to something different than 0 this option will override the " \ - "relative font size " ) -#define OPACITY_TEXT N_("Opacity, 0..255") -#define OPACITY_LONGTEXT N_("The opacity (inverse of transparency) of " \ - "overlay text. 0 = transparent, 255 = totally opaque. " ) -#define COLOR_TEXT N_("Text Default Color") -#define COLOR_LONGTEXT N_("The color of overlay text. 1 byte for each color, "\ - "hexadecimal. #000000 = all colors off, 0xFF0000 = just Red, " \ - "0xFFFFFF = all color on [White]" ) -#define FONTSIZER_TEXT N_("Font size") -#define FONTSIZER_LONGTEXT N_("The size of the fonts used by the osd module" ) - -static int pi_sizes[] = { 20, 18, 16, 12, 6 }; -static char *ppsz_sizes_text[] = { N_("Smaller"), N_("Small"), N_("Normal"), - N_("Large"), N_("Larger") }; -static int pi_color_values[] = { +#define FONTSIZE_LONGTEXT N_("This is the default size of the fonts " \ + "that will be rendered on the video. " \ + "If set to something different than 0 this option will override the " \ + "relative font size." ) +#define OPACITY_TEXT N_("Opacity") +#define OPACITY_LONGTEXT N_("The opacity (inverse of transparency) of the " \ + "text that will be rendered on the video. 0 = transparent, " \ + "255 = totally opaque. " ) +#define COLOR_TEXT N_("Text default color") +#define COLOR_LONGTEXT N_("The color of the text that will be rendered on "\ + "the video. This must be an hexadecimal (like HTML colors). The first two "\ + "chars are for red, then green, then blue. #000000 = black, #FF0000 = red,"\ + " #00FF00 = green, #FFFF00 = yellow (red + green), #FFFFFF = white" ) +#define FONTSIZER_TEXT N_("Relative font size") +#define FONTSIZER_LONGTEXT N_("This is the relative default size of the " \ + "fonts that will be rendered on the video. If absolute font size is set, "\ + "relative size will be overriden." ) + +static int const pi_sizes[] = { 20, 18, 16, 12, 6 }; +static char *const ppsz_sizes_text[] = { + N_("Smaller"), N_("Small"), N_("Normal"), N_("Large"), N_("Larger") }; +static const int pi_color_values[] = { 0x00000000, 0x00808080, 0x00C0C0C0, 0x00FFFFFF, 0x00800000, - 0x00FF0000, 0x00FF00FF, 0x00FFFF00, 0x00808000, 0x00008000, 0x00008080, - 0x0000FF00, 0x00800080, 0x00000080, 0x000000FF, 0x0000FFFF }; + 0x00FF0000, 0x00FF00FF, 0x00FFFF00, 0x00808000, 0x00008000, 0x00008080, + 0x0000FF00, 0x00800080, 0x00000080, 0x000000FF, 0x0000FFFF }; -static char *ppsz_color_descriptions[] = { +static const char *const ppsz_color_descriptions[] = { N_("Black"), N_("Gray"), N_("Silver"), N_("White"), N_("Maroon"), N_("Red"), N_("Fuchsia"), N_("Yellow"), N_("Olive"), N_("Green"), N_("Teal"), N_("Lime"), N_("Purple"), N_("Navy"), N_("Blue"), N_("Aqua") }; -vlc_module_begin(); - set_shortname( _("Text renderer")); - set_description( _("Win32 font renderer") ); - set_category( CAT_VIDEO ); - set_subcategory( SUBCAT_VIDEO_SUBPIC ); +vlc_module_begin () + set_shortname( N_("Text renderer")) + set_description( N_("Win32 font renderer") ) + set_category( CAT_VIDEO ) + set_subcategory( SUBCAT_VIDEO_SUBPIC ) add_integer( "win32text-fontsize", 0, NULL, FONTSIZE_TEXT, - FONTSIZE_LONGTEXT, VLC_TRUE ); + FONTSIZE_LONGTEXT, true ) /* opacity valid on 0..255, with default 255 = fully opaque */ add_integer_with_range( "win32-opacity", 255, 0, 255, NULL, - OPACITY_TEXT, OPACITY_LONGTEXT, VLC_FALSE ); + OPACITY_TEXT, OPACITY_LONGTEXT, false ) /* hook to the color values list, with default 0x00ffffff = white */ add_integer( "win32text-color", 0x00FFFFFF, NULL, COLOR_TEXT, - COLOR_LONGTEXT, VLC_TRUE ); - change_integer_list( pi_color_values, ppsz_color_descriptions, 0 ); + COLOR_LONGTEXT, true ) + change_integer_list( pi_color_values, ppsz_color_descriptions, NULL ); add_integer( "win32text-rel-fontsize", 16, NULL, FONTSIZER_TEXT, - FONTSIZER_LONGTEXT, VLC_FALSE ); - change_integer_list( pi_sizes, ppsz_sizes_text, 0 ); + FONTSIZER_LONGTEXT, false ) + change_integer_list( pi_sizes, ppsz_sizes_text, NULL ); - set_capability( "text renderer", 50 ); - add_shortcut( "text" ); - set_callbacks( Create, Destroy ); -vlc_module_end(); + set_capability( "text renderer", 50 ) + add_shortcut( "text" ) + set_callbacks( Create, Destroy ) +vlc_module_end () /***************************************************************************** * filter_sys_t: win32text local data @@ -125,7 +134,7 @@ struct filter_sys_t int i_logpy; }; -static uint8_t pi_gamma[16] = +static const uint8_t pi_gamma[16] = {0x00, 0x41, 0x52, 0x63, 0x84, 0x85, 0x96, 0xa7, 0xb8, 0xc9, 0xca, 0xdb, 0xdc, 0xed, 0xee, 0xff}; @@ -143,10 +152,7 @@ static int Create( vlc_object_t *p_this ) /* Allocate structure */ p_filter->p_sys = p_sys = malloc( sizeof( filter_sys_t ) ); if( !p_sys ) - { - msg_Err( p_filter, "out of memory" ); return VLC_ENOMEM; - } p_sys->i_font_size = 0; p_sys->i_display_height = 0; @@ -176,12 +182,13 @@ static int Create( vlc_object_t *p_this ) p_sys->i_default_font_size = val.i_int; if( SetFont( p_filter, 0 ) != VLC_SUCCESS ) goto error; - if( psz_fontfile ) free( psz_fontfile ); + free( psz_fontfile ); p_filter->pf_render_text = RenderText; + p_filter->pf_render_html = NULL; return VLC_SUCCESS; error: - if( psz_fontfile ) free( psz_fontfile ); + free( psz_fontfile ); free( p_sys ); return VLC_EGENERIC; } @@ -211,23 +218,19 @@ static int Render( filter_t *p_filter, subpicture_region_t *p_region, uint8_t *p_dst; video_format_t fmt; int i, i_pitch; - subpicture_region_t *p_region_tmp; - vlc_bool_t b_outline = VLC_TRUE; + bool b_outline = true; /* Create a new subpicture region */ memset( &fmt, 0, sizeof(video_format_t) ); - fmt.i_chroma = VLC_FOURCC('Y','U','V','P'); + fmt.i_chroma = VLC_CODEC_YUVP; fmt.i_width = fmt.i_visible_width = i_width + (b_outline ? 4 : 0); fmt.i_height = fmt.i_visible_height = i_height + (b_outline ? 4 : 0); fmt.i_x_offset = fmt.i_y_offset = 0; - p_region_tmp = spu_CreateRegion( p_filter, &fmt ); - if( !p_region_tmp ) - { - msg_Err( p_filter, "cannot allocate SPU region" ); - return VLC_EGENERIC; - } /* Build palette */ + fmt.p_palette = calloc( 1, sizeof(*fmt.p_palette) ); + if( !fmt.p_palette ) + return VLC_EGENERIC; fmt.p_palette->i_entries = 16; for( i = 0; i < fmt.p_palette->i_entries; i++ ) { @@ -237,17 +240,21 @@ static int Render( filter_t *p_filter, subpicture_region_t *p_region, fmt.p_palette->palette[i][3] = pi_gamma[i]; } - p_region->fmt = p_region_tmp->fmt; - p_region->picture = p_region_tmp->picture; - free( p_region_tmp ); + p_region->p_picture = picture_NewFromFormat( &fmt ); + if( !p_region->p_picture ) + { + free( fmt.p_palette ); + return VLC_EGENERIC; + } + p_region->fmt = fmt; - p_dst = p_region->picture.Y_PIXELS; - i_pitch = p_region->picture.Y_PITCH; + p_dst = p_region->p_picture->Y_PIXELS; + i_pitch = p_region->p_picture->Y_PITCH; if( b_outline ) { memset( p_dst, 0, i_pitch * fmt.i_height ); - p_dst += p_region->picture.Y_PITCH * 2 + 2; + p_dst += p_region->p_picture->Y_PITCH * 2 + 2; } for( i = 0; i < i_height; i++ ) @@ -264,7 +271,7 @@ static int Render( filter_t *p_filter, subpicture_region_t *p_region, uint8_t left, current; int x, y; - p_dst = p_region->picture.Y_PIXELS; + p_dst = p_region->p_picture->Y_PIXELS; for( y = 1; y < (int)fmt.i_height - 1; y++ ) { @@ -296,13 +303,17 @@ static int RenderText( filter_t *p_filter, subpicture_region_t *p_region_out, int i, i_width, i_height; HBITMAP bitmap, bitmap_bak; BITMAPINFO *p_bmi; - RECT rect = {0}; - SIZE size; + RECT rect = { 0, 0, 0, 0 }; /* Sanity check */ if( !p_region_in || !p_region_out ) return VLC_EGENERIC; -#ifdef UNICODE + if( !p_region_in->psz_text || !*p_region_in->psz_text ) + return VLC_EGENERIC; + psz_string = malloc( (strlen( p_region_in->psz_text )+1) * sizeof(TCHAR) ); + if( !psz_string ) + return VLC_ENOMEM; +#ifdef UNICODE if( mbstowcs( psz_string, p_region_in->psz_text, strlen( p_region_in->psz_text ) * sizeof(TCHAR) ) < 0 ) { @@ -310,26 +321,35 @@ static int RenderText( filter_t *p_filter, subpicture_region_t *p_region_out, return VLC_EGENERIC; } #else - psz_string = strdup( p_region_in->psz_text ); + strcpy( psz_string, p_region_in->psz_text ); #endif - 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; - - i_font_alpha = __MAX( __MIN( p_region_in->i_text_alpha, 255 ), 0 ); - if( !i_font_alpha ) i_font_alpha = 255 - p_sys->i_font_opacity; + if( !*psz_string ) + { + free( psz_string ); + return VLC_EGENERIC; + } - i_font_size = __MAX( __MIN( p_region_in->i_text_size, 255 ), 0 ); + 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; + } SetFont( p_filter, i_font_size ); SetTextColor( p_sys->hcdc, RGB( (i_font_color >> 16) & 0xff, (i_font_color >> 8) & 0xff, i_font_color & 0xff) ); - GetTextExtentExPoint( p_sys->hcdc, psz_string, _tcslen(psz_string), - 0, 0, 0, &size ); - i_width = rect.right = size.cx; i_height = rect.bottom = size.cy; + DrawText( p_sys->hcdc, psz_string, -1, &rect, + DT_CALCRECT | DT_CENTER | DT_NOPREFIX ); + i_width = rect.right; i_height = rect.bottom; p_bmi = malloc(sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD)*16); memset( p_bmi, 0, sizeof(BITMAPINFOHEADER) ); @@ -353,14 +373,15 @@ static int RenderText( filter_t *p_filter, subpicture_region_t *p_region_out, if( !bitmap ) { msg_Err( p_filter, "could not create bitmap" ); + free( psz_string ); return VLC_EGENERIC; } bitmap_bak = SelectObject( p_sys->hcdc, bitmap ); FillRect( p_sys->hcdc, &rect, (HBRUSH)GetStockObject(BLACK_BRUSH) ); - //TextOut( p_sys->hcdc, 0, 0, psz_string, strlen(psz_string) ); - if( !DrawText( p_sys->hcdc, psz_string, -1, &rect, 0 ) ) + if( !DrawText( p_sys->hcdc, psz_string, -1, &rect, + DT_CENTER | DT_NOPREFIX ) ) { msg_Err( p_filter, "could not draw text" ); } @@ -371,6 +392,7 @@ static int RenderText( filter_t *p_filter, subpicture_region_t *p_region_out, SelectObject( p_sys->hcdc, bitmap_bak ); DeleteObject( bitmap ); + free( psz_string ); return VLC_SUCCESS; } @@ -402,11 +424,11 @@ static int SetFont( filter_t *p_filter, int i_size ) } if( i_size <= 0 ) { - msg_Warn( p_filter, "Invalid fontsize, using 12" ); + msg_Warn( p_filter, "invalid fontsize, using 12" ); i_size = 12; } - msg_Dbg( p_filter, "Using fontsize: %i", i_size ); + msg_Dbg( p_filter, "using fontsize: %i", i_size ); } p_sys->i_font_size = i_size;