* osd_text.c : Filter to put text on the video, using freetype2
*****************************************************************************
* Copyright (C) 2002, 2003 VideoLAN
- * $Id: osd_text.c,v 1.1 2003/03/23 16:38:40 sigmunau Exp $
+ * $Id: osd_text.c,v 1.5 2003/06/11 20:36:22 gbazin Exp $
*
* Authors: Sigmund Augdal <sigmunau@idi.ntnu.no>
*
#include <vlc/vlc.h>
#include <vlc/vout.h>
#include <osd.h>
+#include <math.h>
#include "filter_common.h"
#include FT_FREETYPE_H
#include FT_GLYPH_H
+#define FT_RENDER_MODE_NORMAL 0 /* Why do we have to do that ? */
+
/*****************************************************************************
* Local prototypes
*****************************************************************************/
mtime_t i_end_date;
vlc_mutex_t *lock;
vlc_bool_t i_use_kerning;
+ uint8_t pi_gamma[256];
};
/* more prototypes */
static void ComputeBoundingBox( string_info_t * );
*****************************************************************************
* This function allocates and initializes a Clone vout method.
*****************************************************************************/
+#define gamma_value 2.0
static int Create( vlc_object_t *p_this )
{
vout_thread_t *p_vout = (vout_thread_t *)p_this;
char *psz_fontfile;
- int i_error;
+ int i, i_error;
+ vlc_value_t val;
+ double gamma_inv = 1.0f / gamma_value;
/* Allocate structure */
p_vout->p_sys = malloc( sizeof( vout_sys_t ) );
msg_Err( p_vout, "out of memory" );
return VLC_ENOMEM;
}
- p_vout->p_sys->p_strings = malloc( sizeof( string_info_t ) );
- if( p_vout->p_sys->p_strings == NULL )
- {
- msg_Err( p_vout, "out of memory" );
- return VLC_ENOMEM;
- }
p_vout->p_sys->p_strings = NULL;
-#if 0
- p_vout->p_sys->p_strings->i_x_margin = 20;
- p_vout->p_sys->p_strings->i_y_margin = 100;
- p_vout->p_sys->p_strings->i_start_date = 0;
- p_vout->p_sys->p_strings->i_end_date = 0xFFFFFFFFFFFFFFFll;
- p_vout->p_sys->p_strings->psz_text = "VideoLAN";
- p_vout->p_sys->p_strings->p_next = NULL;
- p_vout->p_sys->p_strings->p_next = malloc(sizeof(string_info_t));
- if( p_vout->p_sys->p_strings->p_next == NULL )
- {
- msg_Err( p_vout, "out of memory" );
- return VLC_ENOMEM;
- }
- p_vout->p_sys->p_strings->p_next->i_x_margin = 50;
- p_vout->p_sys->p_strings->p_next->i_y_margin = 300;
- p_vout->p_sys->p_strings->p_next->i_start_date = 0;
- p_vout->p_sys->p_strings->p_next->i_end_date = 0xFFFFFFFFFFFFFFFll;
- p_vout->p_sys->p_strings->p_next->psz_text = "freetype is cool!";
- p_vout->p_sys->p_strings->p_next->p_next = NULL;
-#endif
p_vout->p_sys->i_x_margin = 50;
p_vout->p_sys->i_y_margin = 50;
p_vout->p_sys->i_flags = 0;
return VLC_ENOMEM;
}
vlc_mutex_init( p_vout, p_vout->p_sys->lock);
+
+ for (i = 0; i < 256; i++) {
+ p_vout->p_sys->pi_gamma[i] =
+ (uint8_t)( pow( (double)i / 255.0f, gamma_inv) * 255.0f );
+ msg_Dbg( p_vout, "%d", p_vout->p_sys->pi_gamma[i]);
+ }
p_vout->pf_init = Init;
p_vout->pf_end = End;
p_vout->pf_manage = NULL;
i_error = FT_Set_Pixel_Sizes( p_vout->p_sys->p_face, 0, config_GetInt( p_vout, "osd-fontsize" ) );
if( i_error )
{
- msg_Err( p_vout, "couldn't set font size to 64" );
+ msg_Err( p_vout, "couldn't set font size to %d",
+ config_GetInt( p_vout, "osd-fontsize" ) );
free( p_vout->p_sys );
return VLC_EGENERIC;
}
var_AddCallback( p_vout, "end-date", SetMargin, NULL );
var_Create( p_vout, "string", VLC_VAR_STRING | VLC_VAR_ISCOMMAND );
var_AddCallback( p_vout, "string", AddText, NULL );
+
+ val.psz_string = "Videolan";
+// var_Set( p_vout, "string", val );
+// p_vout->p_sys->p_strings->i_end_date = 0xFFFFFFFFFFFFFFF;
+
return VLC_SUCCESS;
}
msg_Err( p_vout, "failed to start vout" );
return VLC_EGENERIC;
}
+
ADD_CALLBACKS( p_vout->p_sys->p_vout, SendEvents );
ALLOCATE_DIRECTBUFFERS( VOUT_MAX_PICTURES );
msleep( VOUT_OUTMEM_SLEEP );
}
+ vout_DatePicture( p_vout->p_sys->p_vout,
+ p_outpic, p_pic->date );
if( p_vout->i_changes )
{
p_vout->p_sys->p_vout->i_changes = p_vout->i_changes;
FreeString( p_string );
}
- vout_DatePicture( p_vout->p_sys->p_vout,
- p_outpic, p_pic->date );
vlc_mutex_lock( p_vout->p_sys->lock );
}
/* pen_x = 20;
pen_y = 100;*/
- if ( i_plane == 0 ) {
+ if ( i_plane == 0 )
+ {
for( p_string = p_vout->p_sys->p_strings; p_string != NULL;
p_string = p_string->p_next )
{
0 );
if ( i_error ) continue;
p_image = (FT_BitmapGlyph)p_glyph;
-#define alpha p_image->bitmap.buffer[x+ y*p_image->bitmap.width]
+#define alpha p_vout->p_sys->pi_gamma[p_image->bitmap.buffer[x+ y*p_image->bitmap.width]]
#define pixel p_out[(p_string->p_glyph_pos[i].y + pen_y + y - p_image->top)*i_out_pitch+x+pen_x+p_string->p_glyph_pos[i].x+p_image->left]
for(y = 0; y < p_image->bitmap.rows; y++ )
{
for( x = 0; x < p_image->bitmap.width; x++ )
{
+// pixel = alpha;
+// pixel = (pixel^alpha)^pixel;
pixel = ((pixel*(255-alpha))>>8) + (255*alpha>>8);
}
}
}
else if( !strcmp( psz_command, "start-date" ) )
{
- p_vout->p_sys->i_start_date = newval.i_int;
+ p_vout->p_sys->i_start_date = ( (mtime_t) newval.time.i_high << 32 )
+ + newval.time.i_low;
}
else if( !strcmp( psz_command, "end-date" ) )
{
- p_vout->p_sys->i_end_date = newval.i_int;
+ p_vout->p_sys->i_end_date = ( (mtime_t) newval.time.i_high << 32 )
+ + newval.time.i_low;
}
else if( !strcmp( psz_command, "flags" ) )
{
static void ComputeBoundingBox( string_info_t *p_string )
{
unsigned int i;
- int pen_y = 0;
+ int i_pen_y = 0;
+ int i_firstline_height = 0;
FT_Vector result;
- FT_Vector line;
+ FT_BBox line;
FT_BBox glyph_size;
-
+
result.x = 0;
result.y = 0;
- line.x = 0;
- line.y = 0;
+ line.xMin = 0;
+ line.xMax = 0;
+ line.yMin = 0;
+ line.yMax = 0;
for ( i = 0; i < strlen( p_string->psz_text ); i++ )
{
if ( p_string->psz_text[i] == '\n' )
{
- result.x = __MAX( result.x, line.x );
- result.y += line.y;
- pen_y = result.y;
+ result.x = __MAX( result.x, line.xMax );
+ result.y += line.yMax - line.yMin;
+ if ( !i_firstline_height )
+ {
+ i_firstline_height = result.y;
+ }
+ line.xMin = 0;
+ line.xMax = 0;
+ line.yMin = 0;
+ line.yMax = 0;
+ i_pen_y = result.y + 1;
continue;
}
- p_string->p_glyph_pos[ i ].y = pen_y;
+ p_string->p_glyph_pos[ i ].y = i_pen_y;
FT_Glyph_Get_CBox( p_string->pp_glyphs[i],
ft_glyph_bbox_pixels, &glyph_size );
/* Do rest */
- line.x = p_string->p_glyph_pos[i].x + glyph_size.xMax - glyph_size.xMin;
- line.y = __MAX( line.y, glyph_size.yMax - glyph_size.yMin );
+ line.xMax = p_string->p_glyph_pos[i].x + glyph_size.xMax - glyph_size.xMin;
+ line.yMax = __MAX( line.yMax, glyph_size.yMax );
+ line.yMin = __MIN( line.yMin, glyph_size.yMin );
}
- result.x = __MAX( result.x, line.x );
- result.y += line.y;
+ result.x = __MAX( result.x, line.xMax );
+ result.y += line.yMax - line.yMin;
p_string->i_height = result.y;
p_string->i_width = result.x;
+ if ( !i_firstline_height )
+ {
+ i_firstline_height = result.y;
+ }
+ for ( i = 0; i < strlen( p_string->psz_text ); i++ )
+ {
+ p_string->p_glyph_pos[ i ].y += i_firstline_height;
+ }
return;
}
free( p_string->pp_glyphs );
free( p_string );
}
+