X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;ds=sidebyside;f=modules%2Fmisc%2Ffreetype.c;h=76c58d3ba938fe7b889c7327659631ed4eb9f97d;hb=6b385019009c2dc10cb20dc96dd2735a8de6a5ef;hp=bcb48a3c7d4b2d20e635dafdd5431529910d0443;hpb=a90a19a6b0468ea9fedadc27cfc1118d70295263;p=vlc diff --git a/modules/misc/freetype.c b/modules/misc/freetype.c index bcb48a3c7d..76c58d3ba9 100644 --- a/modules/misc/freetype.c +++ b/modules/misc/freetype.c @@ -1,7 +1,7 @@ /***************************************************************************** * freetype.c : Put text on the video, using freetype2 ***************************************************************************** - * Copyright (C) 2002, 2003 VideoLAN + * Copyright (C) 2002 - 2005 VideoLAN * $Id$ * * Authors: Sigmund Augdal @@ -70,7 +70,8 @@ typedef struct line_desc_t line_desc_t; static int Create ( vlc_object_t * ); static void Destroy( vlc_object_t * ); -static subpicture_t *RenderText( filter_t *, block_t * ); +/* The RenderText call maps to pf_render_string, defined in vlc_filter.h */ +static subpicture_t *RenderText( filter_t *, block_t *, int, int, int ); static line_desc_t *NewLine( byte_t * ); /***************************************************************************** @@ -82,12 +83,25 @@ static line_desc_t *NewLine( byte_t * ); #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. " \ + "1 = 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[] = { 0x00000000, 0x00808080, 0x00C0C0C0, 0x00FFFFFF, 0x00800000, + 0x00FF0000, 0x00FF00FF, 0x00FFFF00, 0x00808000, 0x00008000, 0x00008080, + 0x0000FF00, 0x00800080, 0x00000080, 0x000000FF, 0x0000FFFF}; +static char *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_description( _("freetype2 font renderer") ); @@ -98,6 +112,13 @@ vlc_module_begin(); VLC_FALSE ); add_integer( "freetype-fontsize", 0, NULL, FONTSIZE_TEXT, FONTSIZE_LONGTEXT, VLC_TRUE ); + /* opacity valid on 0..255, with default 255 = fully opaque */ + add_integer_with_range( "freetype-opacity", 255, 0, 255, NULL, + OPACITY_TEXT, OPACITY_LONGTEXT, VLC_FALSE ); + /* hook to the color values list, with default 0x00ffffff = white */ + add_integer( "freetype-color", 0x00FFFFFF, NULL, COLOR_TEXT, COLOR_LONGTEXT, VLC_TRUE ); + change_integer_list( pi_color_values, ppsz_color_descriptions, 0 ); + add_integer( "freetype-rel-fontsize", 16, NULL, FONTSIZER_TEXT, FONTSIZER_LONGTEXT, VLC_FALSE ); change_integer_list( pi_sizes, ppsz_sizes_text, 0 ); @@ -131,7 +152,8 @@ struct line_desc_t line_desc_t *p_next; }; -static void Render ( filter_t *, subpicture_t *, subpicture_data_t * ); +static void Render ( filter_t *, subpicture_t *, subpicture_data_t *, uint8_t, + int, int, int ); static void FreeString( subpicture_data_t * ); static void FreeLine( line_desc_t * ); @@ -146,6 +168,11 @@ struct filter_sys_t FT_Library p_library; /* handle to library */ FT_Face p_face; /* handle to face object */ vlc_bool_t i_use_kerning; + uint8_t i_font_opacity; /* freetype-opacity */ + int i_font_color; /* freetype-color */ + int i_red, i_blue, i_green; /* function vars to render */ + int i_font_size; + uint8_t i_opacity; /* function var to render */ uint8_t pi_gamma[256]; }; @@ -160,7 +187,6 @@ static int Create( vlc_object_t *p_this ) filter_sys_t *p_sys; char *psz_fontfile = NULL; int i, i_error; - int i_fontsize = 0; vlc_value_t val; /* Allocate structure */ @@ -172,7 +198,8 @@ static int Create( vlc_object_t *p_this ) } p_sys->p_face = 0; p_sys->p_library = 0; - + p_sys->i_font_size = 0; + for( i = 0; i < 256; i++ ) { p_sys->pi_gamma[i] = (uint8_t)( pow( (double)i * 255.0f, 0.5f ) ); @@ -184,6 +211,16 @@ static int Create( vlc_object_t *p_this ) 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_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 ); + if ( ( val.i_int > -1 ) && ( val.i_int < 0x01000000 ) ) /* valid range */ + { + p_sys->i_font_color = val.i_int; + } + else msg_Warn(p_filter, "Invalid freetype color specified, using white [0xFFFFFF]"); /* Look what method was requested */ var_Get( p_filter, "freetype-font", &val ); @@ -232,27 +269,28 @@ 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 ); if( val.i_int ) { - i_fontsize = val.i_int; + p_sys->i_font_size = val.i_int; } else { var_Get( p_filter, "freetype-rel-fontsize", &val ); - i_fontsize = (int)p_filter->fmt_out.video.i_height / val.i_int; + p_sys->i_font_size = (int)p_filter->fmt_out.video.i_height / val.i_int; } - if( i_fontsize <= 0 ) + if( p_sys->i_font_size <= 0 ) { msg_Warn( p_filter, "Invalid fontsize, using 12" ); - i_fontsize = 12; + p_sys->i_font_size = 12; } - msg_Dbg( p_filter, "Using fontsize: %i", i_fontsize); + msg_Dbg( p_filter, "Using fontsize: %i", p_sys->i_font_size); - i_error = FT_Set_Pixel_Sizes( p_sys->p_face, 0, i_fontsize ); + i_error = FT_Set_Pixel_Sizes( p_sys->p_face, 0, p_sys->i_font_size ); if( i_error ) { - msg_Err( p_filter, "couldn't set font size to %d", i_fontsize ); + msg_Err( p_filter, "couldn't set font size to %d", p_sys->i_font_size ); goto error; } @@ -278,6 +316,7 @@ static void Destroy( vlc_object_t *p_this ) { filter_t *p_filter = (filter_t *)p_this; filter_sys_t *p_sys = p_filter->p_sys; + FT_Done_Face( p_sys->p_face ); FT_Done_FreeType( p_sys->p_library ); free( p_sys ); @@ -289,13 +328,20 @@ static void Destroy( vlc_object_t *p_this ) * This function merges the previously rendered freetype glyphs into a picture *****************************************************************************/ static void Render( filter_t *p_filter, subpicture_t *p_spu, - subpicture_data_t *p_string ) + subpicture_data_t *p_string, uint8_t opacity, + int red, int green, int blue) { filter_sys_t *p_sys = p_filter->p_sys; line_desc_t *p_line; uint8_t *p_y, *p_u, *p_v, *p_a; video_format_t fmt; int i, x, y, i_pitch; + uint8_t i_y, i_u, i_v; /* YUV values, derived from incoming RGB */ + + /* calculate text color components: */ + i_y = (uint8_t) ( ( 66 * red + 129 * green + 25 * blue + 128) >> 8) + 16; + i_u = (uint8_t) ( ( -38 * red - 74 * green + 112 * blue + 128) >> 8) + 128; + i_v = (uint8_t) ( ( 112 * red - 94 * green - 18 * blue + 128) >> 8) + 128; /* Create a new subpicture region */ memset( &fmt, 0, sizeof(video_format_t) ); @@ -318,7 +364,7 @@ static void Render( filter_t *p_filter, subpicture_t *p_spu, p_a = p_spu->p_region->picture.A_PIXELS; i_pitch = p_spu->p_region->picture.Y_PITCH; - /* Initialize the region pixels (only the alpha will be changed later) */ + /* Initialize the region pixels */ memset( p_y, 0x00, i_pitch * p_spu->p_region->fmt.i_height ); memset( p_u, 0x80, i_pitch * p_spu->p_region->fmt.i_height ); memset( p_v, 0x80, i_pitch * p_spu->p_region->fmt.i_height ); @@ -353,16 +399,16 @@ static void Render( filter_t *p_filter, subpicture_t *p_spu, i_offset -= i_pitch; p_a[i_offset + x] = ((uint16_t)p_a[i_offset + x] + - pi_gamma[p_glyph->bitmap.buffer[i_bitmap_offset]])/2; + pi_gamma[p_glyph->bitmap.buffer[i_bitmap_offset]])*opacity/512; i_offset += i_pitch; x--; p_a[i_offset + x] = ((uint16_t)p_a[i_offset + x] + - pi_gamma[p_glyph->bitmap.buffer[i_bitmap_offset]])/2; + pi_gamma[p_glyph->bitmap.buffer[i_bitmap_offset]])*opacity/512; x += 2; p_a[i_offset + x] = ((uint16_t)p_a[i_offset + x] + - pi_gamma[p_glyph->bitmap.buffer[i_bitmap_offset]])/2; + pi_gamma[p_glyph->bitmap.buffer[i_bitmap_offset]])*opacity/512; i_offset += i_pitch; x--; p_a[i_offset + x] = ((uint16_t)p_a[i_offset + x] + - pi_gamma[p_glyph->bitmap.buffer[i_bitmap_offset]])/2; + pi_gamma[p_glyph->bitmap.buffer[i_bitmap_offset]])*opacity/512; i_offset -= i_pitch; } i_offset += i_pitch; @@ -376,8 +422,9 @@ static void Render( filter_t *p_filter, subpicture_t *p_spu, { for( x = 0; x < p_glyph->bitmap.width; x++, i_bitmap_offset++ ) { - p_y[i_offset + x] = - pi_gamma[p_glyph->bitmap.buffer[i_bitmap_offset]]; + p_y[i_offset + x] = i_y*opacity*pi_gamma[p_glyph->bitmap.buffer[i_bitmap_offset]]/(256*256); + p_u[i_offset + x] = i_u; + p_v[i_offset + x] = i_v; } i_offset += i_pitch; } @@ -393,7 +440,8 @@ static void Render( filter_t *p_filter, subpicture_t *p_spu, * needed glyphs into memory. It is used as pf_add_string callback in * the vout method by this module */ -static subpicture_t *RenderText( filter_t *p_filter, block_t *p_block ) +static subpicture_t *RenderText( filter_t *p_filter, block_t *p_block, + int font_color, int font_opacity, int font_size ) { filter_sys_t *p_sys = p_filter->p_sys; subpicture_t *p_subpic = 0; @@ -455,10 +503,28 @@ static subpicture_t *RenderText( filter_t *p_filter, block_t *p_block ) #endif if( iconv_handle == (vlc_iconv_t)-1 ) { - msg_Warn( p_filter, "unable to do convertion" ); + msg_Warn( p_filter, "unable to do conversion" ); goto error; } + /* Set up the glyphs for the desired font size. By definition, + p_sys->i_font_size is a valid value, else the initial Create would + have failed. Using -1 as a flag to use the freetype-fontsize */ + if ( font_size < 0 ) + { + FT_Set_Pixel_Sizes( p_sys->p_face, 0, p_sys->i_font_size ); + } + else + { + i_error = FT_Set_Pixel_Sizes( p_sys->p_face, 0, font_size ); + if( i_error ) + { + msg_Warn( p_filter, "Invalid font size to RenderText, using %d", + p_sys->i_font_size ); + FT_Set_Pixel_Sizes( p_sys->p_face, 0, p_sys->i_font_size ); + } + } + { char *p_in_buffer, *p_out_buffer; size_t i_in_bytes, i_out_bytes, i_out_bytes_left, i_ret; @@ -639,8 +705,30 @@ static subpicture_t *RenderText( filter_t *p_filter, block_t *p_block ) #undef face #undef glyph +/* check to see whether to use the default color/opacity, or another one: */ + if( font_color < 0 ) + { + p_sys->i_blue = p_sys->i_font_color & 0x000000FF; + p_sys->i_green = (p_sys->i_font_color & 0x0000FF00)/256; + p_sys->i_red = (p_sys->i_font_color & 0x00FF0000)/(256*256); + } + else + { + p_sys->i_blue = font_color & 0x000000FF; + p_sys->i_green = (font_color & 0x0000FF00)/256; + p_sys->i_red = (font_color & 0x00FF0000)/(256*256); + } + if( font_opacity < 0 ) + { + p_sys->i_opacity = p_sys->i_font_opacity; + } + else + { + p_sys->i_opacity = (uint8_t) ( font_opacity & 0x000000FF ); + } - Render( p_filter, p_subpic, p_string ); + Render( p_filter, p_subpic, p_string, p_sys->i_opacity, + p_sys->i_red, p_sys->i_green, p_sys->i_blue ); FreeString( p_string ); block_Release( p_block ); if( psz_unicode_orig ) free( psz_unicode_orig );