Commit 5b22bedf authored by Vincent Seguin's avatar Vincent Seguin

Nouveau moteur de fontes.

parent aab60d48
......@@ -35,7 +35,7 @@ SYS=LINUX
#DECODER=old
DECODER=new
# Debugging mode on or off
# Debugging mode on or off (set to 1 to activate)
DEBUG=1
#----------------- do not change anything below this line ----------------------
......@@ -49,7 +49,7 @@ PROGRAM_VERSION = 1.0-dev
# PROGRAM_OPTIONS is an identification string of the compilation options
PROGRAM_OPTIONS = $(VIDEO) $(ARCH) $(SYS)
ifneq ($(DEBUG),)
ifeq ($(DEBUG),1)
PROGRAM_OPTIONS += DEBUG
endif
......@@ -64,7 +64,7 @@ DEFINE += -DSYS_$(SYS)
DEFINE += -DPROGRAM_VERSION="\"$(PROGRAM_VERSION)\""
DEFINE += -DPROGRAM_OPTIONS="\"$(PROGRAM_OPTIONS)\""
DEFINE += -DPROGRAM_BUILD="\"$(PROGRAM_BUILD)\""
ifneq ($(DEBUG),)
ifeq ($(DEBUG),1)
DEFINE += -DDEBUG
endif
......@@ -163,7 +163,7 @@ endif
#
# Debugging support
ifneq ($(DEBUG),)
ifeq ($(DEBUG),1)
CFLAGS += -g
#CFLAGS += -pg
endif
......@@ -198,6 +198,7 @@ audio_output_obj = audio_output/audio_output.o \
video_output_obj = video_output/video_output.o \
video_output/video_$(video).o \
video_output/video_text.o \
video_output/video_yuv.o
ac3_decoder_obj = ac3_decoder/ac3_decoder.o \
......
......@@ -61,12 +61,14 @@ typedef struct aout_thread_s * p_aout_thread_t;
/* Video */
struct vout_thread_s;
struct vout_font_s;
struct vout_sys_s;
struct vdec_thread_s;
struct vpar_thread_s;
struct video_parser_s;
typedef struct vout_thread_s * p_vout_thread_t;
typedef struct vout_font_s * p_vout_font_t;
typedef struct vout_sys_s * p_vout_sys_t;
typedef struct vdec_thread_s * p_vdec_thread_t;
typedef struct vpar_thread_s * p_vpar_thread_t;
......
......@@ -239,6 +239,10 @@
/* Default gamma */
#define VOUT_GAMMA 0.
/* Default fonts */
#define VOUT_DEFAULT_FONT "Resources/default8x9.psf"
#define VOUT_LARGE_FONT "Resources/default8x16.psf"
/*
* Time settings
*/
......@@ -270,15 +274,6 @@
#define VOUT_FB_DEV_VAR "vlc_fb_dev"
#define VOUT_FB_DEV_DEFAULT "/dev/fb0"
/*
* X11 settings
*/
/* Font maximum and minimum characters - characters outside this range are not
* printed - maximum range is 1-256 */
#define VOUT_MIN_CHAR 1
#define VOUT_MAX_CHAR 128
/*******************************************************************************
* Video parser configuration
*******************************************************************************/
......
......@@ -101,6 +101,10 @@ typedef struct vout_thread_s
vout_convert_t * p_ConvertYUV420; /* YUV 4:2:0 converter */
vout_convert_t * p_ConvertYUV422; /* YUV 4:2:2 converter */
vout_convert_t * p_ConvertYUV444; /* YUV 4:4:4 converter */
/* Bitmap fonts */
p_vout_font_t p_default_font; /* default font */
p_vout_font_t p_large_font; /* large font */
} vout_thread_t;
/* Flags for changes - these flags are set in the i_changes field when another
......@@ -137,10 +141,3 @@ void vout_DisplaySubtitle ( vout_thread_t *p_vout, subtitle_t *p_s
......@@ -13,9 +13,6 @@ void vout_SysDestroy ( p_vout_thread_t p_vout );
int vout_SysManage ( p_vout_thread_t p_vout );
void vout_SysDisplay ( p_vout_thread_t p_vout );
void * vout_SysGetPicture ( p_vout_thread_t p_vout );
void vout_SysPrint ( p_vout_thread_t p_vout, int i_x, int i_y,
int i_halign, int i_valign,
unsigned char *psz_text );
/*******************************************************************************
* video_text.h : text manipulation functions
* (c)1999 VideoLAN
*******************************************************************************/
/* Text styles - these are primary text styles, used by the vout_Print function.
* They may be ignored or interpreted by higher level functions */
#define WIDE_TEXT 1 /* interspacing is doubled */
#define ITALIC_TEXT 2 /* italic */
#define TRANSPARENT_TEXT 4 /* transparent text */
#define OUTLINED_TEXT 8 /* border around letters */
#define VOID_TEXT 16 /* no foreground */
/*******************************************************************************
* Prototypes
*******************************************************************************/
p_vout_font_t vout_LoadFont ( char *psz_name );
void vout_UnloadFont ( p_vout_font_t p_font );
void vout_TextSize ( p_vout_font_t p_font, int i_style, char *psz_text,
int *pi_width, int *pi_height );
void vout_Print ( p_vout_font_t p_font, byte_t *p_pic, int i_depth,
int i_bytes_per_pixel, u32 i_char_color,
u32 i_border_color, u32 i_bg_color,
int i_style, char *psz_text );
......@@ -21,6 +21,7 @@
#include "vlc_thread.h"
#include "video.h"
#include "video_output.h"
#include "video_text.h"
#include "video_sys.h"
#include "video_yuv.h"
#include "intf_msg.h"
......@@ -33,6 +34,7 @@ static int InitThread ( vout_thread_t *p_vout );
static void RunThread ( vout_thread_t *p_vout );
static void ErrorThread ( vout_thread_t *p_vout );
static void EndThread ( vout_thread_t *p_vout );
static void Print ( vout_thread_t *p_vout, int i_x, int i_y, int i_halign, int i_valign, unsigned char *psz_text );
static void RenderBlank ( vout_thread_t *p_vout );
static int RenderPicture ( vout_thread_t *p_vout, picture_t *p_pic, boolean_t b_blank );
static int RenderPictureInfo ( vout_thread_t *p_vout, picture_t *p_pic, boolean_t b_blank );
......@@ -99,6 +101,23 @@ vout_thread_t * vout_CreateThread ( char *psz_display, int i_root_
intf_DbgMsg("actual configuration: %dx%d,%d (%d bytes/pixel, %d bytes/line)\n",
p_vout->i_width, p_vout->i_height, p_vout->i_screen_depth,
p_vout->i_bytes_per_pixel, p_vout->i_bytes_per_line );
/* Load fonts */
p_vout->p_default_font = vout_LoadFont( VOUT_DEFAULT_FONT );
if( p_vout->p_default_font == NULL )
{
vout_SysDestroy( p_vout );
free( p_vout );
return( NULL );
}
p_vout->p_large_font = vout_LoadFont( VOUT_LARGE_FONT );
if( p_vout->p_large_font == NULL )
{
vout_UnloadFont( p_vout->p_default_font );
vout_SysDestroy( p_vout );
free( p_vout );
return( NULL );
}
#ifdef STATS
/* Initialize statistics fields */
......@@ -119,6 +138,8 @@ vout_thread_t * vout_CreateThread ( char *psz_display, int i_root_
if( vlc_thread_create( &p_vout->thread_id, "video output", (void *) RunThread, (void *) p_vout) )
{
intf_ErrMsg("error: %s\n", strerror(ENOMEM));
vout_UnloadFont( p_vout->p_default_font );
vout_UnloadFont( p_vout->p_large_font );
vout_SysDestroy( p_vout );
free( p_vout );
return( NULL );
......@@ -600,6 +621,7 @@ static void RunThread( vout_thread_t *p_vout)
p_vout->b_error = InitThread( p_vout );
if( p_vout->b_error )
{
//??
free( p_vout ); /* destroy descriptor */
return;
}
......@@ -792,8 +814,10 @@ static void EndThread( vout_thread_t *p_vout )
/* Destroy translation tables */
vout_EndTables( p_vout );
/* Destroy thread structures allocated by InitThread */
/* Destroy thread structures allocated by Create and InitThread */
vout_SysEnd( p_vout );
vout_UnloadFont( p_vout->p_default_font );
vout_UnloadFont( p_vout->p_large_font );
vout_SysDestroy( p_vout );
free( p_vout );
......@@ -801,6 +825,53 @@ static void EndThread( vout_thread_t *p_vout )
*pi_status = THREAD_OVER;
}
/*******************************************************************************
* Print: print simple text on a picture
*******************************************************************************
* This function will print a simple text on the picture. It is designed to
* print debugging or general informations.
*******************************************************************************/
void Print( vout_thread_t *p_vout, int i_x, int i_y, int i_halign, int i_valign, unsigned char *psz_text )
{
int i_text_height; /* total text height */
int i_text_width; /* total text width */
/* Update upper left coordinates according to alignment */
vout_TextSize( p_vout->p_default_font, 0, psz_text, &i_text_width, &i_text_height );
switch( i_halign )
{
case 0: /* centered */
i_x -= i_text_width / 2;
break;
case 1: /* right aligned */
i_x -= i_text_width;
break;
}
switch( i_valign )
{
case 0: /* centered */
i_y -= i_text_height / 2;
break;
case 1: /* bottom aligned */
i_y -= i_text_height;
break;
}
/* Check clipping */
if( (i_y < 0) || (i_y + i_text_height > p_vout->i_height) ||
(i_x < 0) || (i_x + i_text_width > p_vout->i_width) )
{
intf_DbgMsg("'%s' would print outside the screen\n", psz_text);
return;
}
/* Print text */
vout_Print( p_vout->p_default_font, vout_SysGetPicture( p_vout ) +
i_y * p_vout->i_bytes_per_line + i_x * p_vout->i_bytes_per_pixel,
p_vout->i_bytes_per_pixel, p_vout->i_bytes_per_line,
0xffffffff, 0x00000000, 0x00000000, 0, psz_text );
}
/******************************************************************************
* RenderBlank: render a blank screen
******************************************************************************
......@@ -972,7 +1043,7 @@ static int RenderPictureInfo( vout_thread_t *p_vout, picture_t *p_pic, boolean_t
sprintf( psz_buffer, "%.2f fps", (double) VOUT_FPS_SAMPLES * 1000000 /
( p_vout->fps_sample[ (p_vout->c_fps_samples - 1) % VOUT_FPS_SAMPLES ] -
p_vout->fps_sample[ p_vout->c_fps_samples % VOUT_FPS_SAMPLES ] ) );
vout_SysPrint( p_vout, p_vout->i_width, 0, 1, -1, psz_buffer );
Print( p_vout, p_vout->i_width, 0, 1, -1, psz_buffer );
}
/*
......@@ -980,7 +1051,7 @@ static int RenderPictureInfo( vout_thread_t *p_vout, picture_t *p_pic, boolean_t
*/
sprintf( psz_buffer, "%ld frames render time: %lu us",
p_vout->c_fps_samples, (long unsigned) p_vout->render_time );
vout_SysPrint( p_vout, 0, 0, -1, -1, psz_buffer );
Print( p_vout, 0, 0, -1, -1, psz_buffer );
#endif
#ifdef DEBUG
......@@ -998,7 +1069,7 @@ static int RenderPictureInfo( vout_thread_t *p_vout, picture_t *p_pic, boolean_t
((p_pic->i_aspect_ratio == AR_3_4_PICTURE) ? "4:3" :
((p_pic->i_aspect_ratio == AR_16_9_PICTURE) ? "16:9" :
((p_pic->i_aspect_ratio == AR_221_1_PICTURE) ? "2.21:1" : "ukn-ar" ))));
vout_SysPrint( p_vout, p_vout->i_width, p_vout->i_height, 1, 1, psz_buffer );
Print( p_vout, p_vout->i_width, p_vout->i_height, 1, 1, psz_buffer );
#endif
return( 0 );
......@@ -1018,8 +1089,8 @@ static int RenderIdle( vout_thread_t *p_vout, boolean_t b_blank )
{
RenderBlank( p_vout );
p_vout->last_display_date = mdate();
vout_SysPrint( p_vout, p_vout->i_width / 2, p_vout->i_height / 2, 0, 0,
"no stream" );
Print( p_vout, p_vout->i_width / 2, p_vout->i_height / 2, 0, 0,
"no stream" ); //??
return( 1 );
}
......@@ -1063,9 +1134,10 @@ static int RenderInfo( vout_thread_t *p_vout, boolean_t b_blank )
p_vout->i_width, p_vout->i_height, p_vout->i_screen_depth,
p_vout->f_gamma, i_reserved_pic, i_ready_pic,
VOUT_MAX_PICTURES );
vout_SysPrint( p_vout, 0, p_vout->i_height, -1, 1, psz_buffer );
Print( p_vout, 0, p_vout->i_height, -1, 1, psz_buffer );
#endif
return( 0 );
return( 0 );
}
/******************************************************************************
......
/*******************************************************************************
* video_text.c : text manipulation functions
* (c)1999 VideoLAN
*******************************************************************************/
/*******************************************************************************
* Preamble
*******************************************************************************/
#include <errno.h>
#include <fcntl.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include "common.h"
#include "config.h"
#include "video_text.h"
#include "intf_msg.h"
/*******************************************************************************
* vout_font_t: bitmap font
*******************************************************************************
* This structure is used when the system doesn't provide a convenient function
* to print simple characters in a buffer.
* VOUT_FIXED_FONTs are stored in raw mode, character after character, with a
* first array of characters followed by a second array of borders masks.
* Therefore the border masks can't be complete if the font has pixels on the
* border.
*******************************************************************************/
typedef struct vout_font_s
{
int i_type; /* font type */
int i_width; /* character width in pixels */
int i_height; /* character height in pixels */
int i_interspacing; /* characters interspacing in pixels */
int i_bytes_per_line; /* bytes per character line */
int i_bytes_per_char; /* bytes per character */
u16 i_first; /* first character */
u16 i_last; /* last character */
byte_t * p_data; /* font character data */
} vout_font_t;
/* Font types */
#define VOUT_FIXED_FONT 0 /* simple fixed font */
/*******************************************************************************
* vout_put_byte_t: PutByte function
*******************************************************************************
* These functions will transform masks in a set of pixels. For each pixel,
* character, then border and background masks are tested, and the first
* encountered color is set.
*******************************************************************************/
typedef void (vout_put_byte_t)( void *p_pic, int i_byte, int i_char, int i_border,
int i_bg, u32 i_char_color, u32 i_border_color, u32 i_bg_color );
/*******************************************************************************
* Macros
*******************************************************************************/
/* PUT_BYTE_MASK: put pixels from a byte-wide mask. It uses a branching tree
* to optimize the number of tests. It is used in the PutByte functions. */
#define TREE( i_mask, i_mask_color ) \
if( i_mask & 0xf0 ) /* one from 1111 */ \
{ \
if( i_mask & 0xc0 ) /* one from 1100 */ \
{ \
if( i_mask & 0x80 ) /* 1000 */ \
{ \
p_pic[0] = i_mask_color; \
if( i_mask & 0x40 ) /* 0100 */ \
{ \
p_pic[1] = i_mask_color; \
} \
} \
else /* not 1000 means 0100 */ \
{ \
p_pic[1] = i_mask_color; \
} \
if( i_mask & 0x30 ) /* one from 0011 */ \
{ \
if( i_mask & 0x20 ) /* 0010 */ \
{ \
p_pic[2] = i_mask_color; \
if( i_mask & 0x10 ) /* 0001 */ \
{ \
p_pic[3] = i_mask_color; \
} \
} \
else /* not 0010 means 0001 */ \
{ \
p_pic[3] = i_mask_color; \
} \
} \
} \
else /* not 1100 means 0011 */ \
{ \
if( i_mask & 0x20 ) /* 0010 */ \
{ \
p_pic[2] = i_mask_color; \
if( i_mask & 0x10 ) /* 0001 */ \
{ \
p_pic[3] = i_mask_color; \
} \
} \
else /* not 0010 means 0001 */ \
{ \
p_pic[3] = i_mask_color; \
} \
} \
} \
if( i_mask & 0x0f ) \
{ \
if( i_mask & 0x0c ) /* one from 1100 */ \
{ \
if( i_mask & 0x08 ) /* 1000 */ \
{ \
p_pic[4] = i_mask_color; \
if( i_mask & 0x04 ) /* 0100 */ \
{ \
p_pic[5] = i_mask_color; \
} \
} \
else /* not 1000 means 0100 */ \
{ \
p_pic[5] = i_mask_color; \
} \
if( i_mask & 0x03 ) /* one from 0011 */ \
{ \
if( i_mask & 0x02 ) /* 0010 */ \
{ \
p_pic[6] = i_mask_color; \
if( i_mask & 0x01 ) /* 0001 */ \
{ \
p_pic[7] = i_mask_color; \
} \
} \
else /* not 0010 means 0001 */ \
{ \
p_pic[7] = i_mask_color; \
} \
} \
} \
else /* not 1100 means 0011 */ \
{ \
if( i_mask & 0x02 ) /* 0010 */ \
{ \
p_pic[6] = i_mask_color; \
if( i_mask & 0x01 ) /* 0001 */ \
{ \
p_pic[7] = i_mask_color; \
} \
} \
else /* not 0010 means 0001 */ \
{ \
p_pic[7] = i_mask_color; \
} \
} \
}
/*******************************************************************************
* Local prototypes
*******************************************************************************/
static void PutByte16( u16 *p_pic, int i_byte, int i_char, int i_border, int i_bg,
u32 i_char_color, u32 i_border_color, u32 i_bg_color );
static void PutByte24( void *p_pic, int i_byte, byte_t i_char, byte_t i_border, byte_t i_bg,
u32 i_char_color, u32 i_border_color, u32 i_bg_color );
static void PutByte32( u32 *p_pic, int i_byte, byte_t i_char, byte_t i_border, byte_t i_bg,
u32 i_char_color, u32 i_border_color, u32 i_bg_color );
/*******************************************************************************
* vout_LoadFont: load a bitmap font from a file
*******************************************************************************
* This function will try to open a .psf font and load it. It will return
* NULL on error.
*******************************************************************************/
vout_font_t *vout_LoadFont( char *psz_name )
{
int i_char, i_line; /* character and line indexes */
int i_file; /* source file */
byte_t pi_buffer[2]; /* file buffer */
vout_font_t * p_font; /* the font itself */
/* Open file */
i_file = open( psz_name, O_RDONLY );
if( i_file == -1 )
{
intf_ErrMsg("error: can't open file '%s' (%s)\n", psz_name, strerror(errno));
return( NULL );
}
/* Read magick number */
if( read( i_file, pi_buffer, 2 ) != 2 )
{
intf_ErrMsg("error: unexpected end of file '%s'\n", psz_name );
close( i_file );
return( NULL );
}
/* Allocate font descriptor */
p_font = malloc( sizeof( vout_font_t ) );
if( p_font == NULL )
{
intf_ErrMsg("error: %s\n", strerror(ENOMEM));
close( i_file );
return( NULL );
}
/* Read file */
switch( ((u16)pi_buffer[0] << 8) | pi_buffer[1] )
{
case 0x3604: /* .psf file */
/*
* PSF font: simple fixed font. Only the first 256 characters are read.
* Those fonts are always 1 byte width, and 256 or 512 characters long.
*/
/* Read font header - two bytes indicate the font properties */
if( read( i_file, pi_buffer, 2 ) != 2)
{
intf_ErrMsg("error: unexpected end of file '%s'\n", psz_name );
free( p_font );
close( i_file );
return( NULL );
}
/* Copy font properties */
p_font->i_type = VOUT_FIXED_FONT;
p_font->i_width = 8;
p_font->i_height = pi_buffer[1];
p_font->i_interspacing = 8;
p_font->i_bytes_per_line = 1;
p_font->i_bytes_per_char = pi_buffer[1];
p_font->i_first = 0;
p_font->i_last = 255;
/* Allocate font space */
p_font->p_data = malloc( 2 * 256 * pi_buffer[1] );
if( p_font->p_data == NULL )
{
intf_ErrMsg("error: %s\n", strerror(ENOMEM));
free( p_font );
close( i_file );
return( NULL );
}
/* Copy raw data */
if( read( i_file, p_font->p_data, 256 * pi_buffer[1] ) != 256 * pi_buffer[1] )
{
intf_ErrMsg("error: unexpected end of file '%s'\n", psz_name );
free( p_font->p_data );
free( p_font );
close( i_file );
return( NULL );
}
/* Computes border masks - remember that masks have the same matrix as
* characters, so an empty character border is required to have a complete
* border mask. */
for( i_char = 0; i_char <= 255; i_char++ )
{
for( i_line = 0; i_line < pi_buffer[1]; i_line++ )
{
p_font->p_data[ (i_char + 256) * pi_buffer[1] + i_line ] =
((p_font->p_data[ i_char * pi_buffer[1] + i_line ] << 1) |
(p_font->p_data[ i_char * pi_buffer[1] + i_line ] >> 1) |
(i_line > 0 ? p_font->p_data[ i_char * pi_buffer[1] + i_line - 1]: 0) |
(i_line < pi_buffer[1] ? p_font->p_data[ i_char * pi_buffer[1] + i_line + 1]: 0))
& ~p_font->p_data[ i_char * pi_buffer[1] + i_line ];
}
}
break;
default:
intf_ErrMsg("error: file '%s' has an unknown format\n", psz_name );
free( p_font );
close( i_file );
return( NULL );
break;
}
intf_DbgMsg( "loaded %s: type %d, %d-%dx%d\n", psz_name, p_font->i_type,
p_font->i_width, p_font->i_interspacing, p_font->i_height );
return( p_font );
}
/*******************************************************************************
* vout_UnloadFont: unload a font
*******************************************************************************
* This function free the resources allocated by vout_LoadFont
*******************************************************************************/
void vout_UnloadFont( vout_font_t *p_font )
{
intf_DbgMsg( "font %p\n", p_font );
free( p_font->p_data );
free( p_font );
}
/*******************************************************************************
* vout_TextSize: return the dimensions of a text
*******************************************************************************
* This function is used to align text. It returns the width and height of a
* given text.
*******************************************************************************/
void vout_TextSize( vout_font_t *p_font, int i_style, char *psz_text, int *pi_width, int *pi_height )
{
switch( p_font->i_type )
{
case VOUT_FIXED_FONT:
*pi_width = ((i_style & WIDE_TEXT) ? p_font->i_interspacing * 2 : p_font->i_interspacing) *
(strlen( psz_text ) - 1) + p_font->i_width;
*pi_height = p_font->i_height;
if( i_style & ITALIC_TEXT )
{
*pi_width = *pi_height / 3;
}
break;
#ifdef DEBUG
default:
intf_DbgMsg("error: unknown font type %d\n", p_font->i_type );
break;
#endif
}
}
/*******************************************************************************
* vout_Print: low level printing function
*******************************************************************************
* This function prints a text, without clipping, in a buffer using a previously
* loaded bitmap font.
*******************************************************************************/
void vout_Print( vout_font_t *p_font, byte_t *p_pic, int i_bytes_per_pixel, int i_bytes_per_line,
u32 i_char_color, u32 i_border_color, u32 i_bg_color, int i_style, char *psz_text )
{
byte_t *p_char, *p_border; /* character and border mask data */
int i_char_mask, i_border_mask, i_bg_mask; /* masks */
int i_line; /* current line in character */
int i_byte; /* current byte in character */
int i_interspacing; /* offset between two chars */
int i_font_bytes_per_line, i_font_height; /* font properties */
vout_put_byte_t *p_PutByte; /* PutByte function */
//?? background: can be something else that whole byte
/* Select output function */
switch( i_bytes_per_pixel )
{
case 2:
p_PutByte = (vout_put_byte_t *) PutByte16;
break;
case 3:
p_PutByte = (vout_put_byte_t *) PutByte24;
break;
case 4:
#ifndef DEBUG
default:
#endif
p_PutByte = (vout_put_byte_t *) PutByte32;
break;