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

Nouveau moteur de fontes.

parent aab60d48
...@@ -35,7 +35,7 @@ SYS=LINUX ...@@ -35,7 +35,7 @@ SYS=LINUX
#DECODER=old #DECODER=old
DECODER=new DECODER=new
# Debugging mode on or off # Debugging mode on or off (set to 1 to activate)
DEBUG=1 DEBUG=1
#----------------- do not change anything below this line ---------------------- #----------------- do not change anything below this line ----------------------
...@@ -49,7 +49,7 @@ PROGRAM_VERSION = 1.0-dev ...@@ -49,7 +49,7 @@ PROGRAM_VERSION = 1.0-dev
# PROGRAM_OPTIONS is an identification string of the compilation options # PROGRAM_OPTIONS is an identification string of the compilation options
PROGRAM_OPTIONS = $(VIDEO) $(ARCH) $(SYS) PROGRAM_OPTIONS = $(VIDEO) $(ARCH) $(SYS)
ifneq ($(DEBUG),) ifeq ($(DEBUG),1)
PROGRAM_OPTIONS += DEBUG PROGRAM_OPTIONS += DEBUG
endif endif
...@@ -64,7 +64,7 @@ DEFINE += -DSYS_$(SYS) ...@@ -64,7 +64,7 @@ DEFINE += -DSYS_$(SYS)
DEFINE += -DPROGRAM_VERSION="\"$(PROGRAM_VERSION)\"" DEFINE += -DPROGRAM_VERSION="\"$(PROGRAM_VERSION)\""
DEFINE += -DPROGRAM_OPTIONS="\"$(PROGRAM_OPTIONS)\"" DEFINE += -DPROGRAM_OPTIONS="\"$(PROGRAM_OPTIONS)\""
DEFINE += -DPROGRAM_BUILD="\"$(PROGRAM_BUILD)\"" DEFINE += -DPROGRAM_BUILD="\"$(PROGRAM_BUILD)\""
ifneq ($(DEBUG),) ifeq ($(DEBUG),1)
DEFINE += -DDEBUG DEFINE += -DDEBUG
endif endif
...@@ -163,7 +163,7 @@ endif ...@@ -163,7 +163,7 @@ endif
# #
# Debugging support # Debugging support
ifneq ($(DEBUG),) ifeq ($(DEBUG),1)
CFLAGS += -g CFLAGS += -g
#CFLAGS += -pg #CFLAGS += -pg
endif endif
...@@ -198,6 +198,7 @@ audio_output_obj = audio_output/audio_output.o \ ...@@ -198,6 +198,7 @@ audio_output_obj = audio_output/audio_output.o \
video_output_obj = video_output/video_output.o \ video_output_obj = video_output/video_output.o \
video_output/video_$(video).o \ video_output/video_$(video).o \
video_output/video_text.o \
video_output/video_yuv.o video_output/video_yuv.o
ac3_decoder_obj = ac3_decoder/ac3_decoder.o \ ac3_decoder_obj = ac3_decoder/ac3_decoder.o \
......
...@@ -61,12 +61,14 @@ typedef struct aout_thread_s * p_aout_thread_t; ...@@ -61,12 +61,14 @@ typedef struct aout_thread_s * p_aout_thread_t;
/* Video */ /* Video */
struct vout_thread_s; struct vout_thread_s;
struct vout_font_s;
struct vout_sys_s; struct vout_sys_s;
struct vdec_thread_s; struct vdec_thread_s;
struct vpar_thread_s; struct vpar_thread_s;
struct video_parser_s; struct video_parser_s;
typedef struct vout_thread_s * p_vout_thread_t; 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 vout_sys_s * p_vout_sys_t;
typedef struct vdec_thread_s * p_vdec_thread_t; typedef struct vdec_thread_s * p_vdec_thread_t;
typedef struct vpar_thread_s * p_vpar_thread_t; typedef struct vpar_thread_s * p_vpar_thread_t;
......
...@@ -239,6 +239,10 @@ ...@@ -239,6 +239,10 @@
/* Default gamma */ /* Default gamma */
#define VOUT_GAMMA 0. #define VOUT_GAMMA 0.
/* Default fonts */
#define VOUT_DEFAULT_FONT "Resources/default8x9.psf"
#define VOUT_LARGE_FONT "Resources/default8x16.psf"
/* /*
* Time settings * Time settings
*/ */
...@@ -270,15 +274,6 @@ ...@@ -270,15 +274,6 @@
#define VOUT_FB_DEV_VAR "vlc_fb_dev" #define VOUT_FB_DEV_VAR "vlc_fb_dev"
#define VOUT_FB_DEV_DEFAULT "/dev/fb0" #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 * Video parser configuration
*******************************************************************************/ *******************************************************************************/
......
...@@ -101,6 +101,10 @@ typedef struct vout_thread_s ...@@ -101,6 +101,10 @@ typedef struct vout_thread_s
vout_convert_t * p_ConvertYUV420; /* YUV 4:2:0 converter */ vout_convert_t * p_ConvertYUV420; /* YUV 4:2:0 converter */
vout_convert_t * p_ConvertYUV422; /* YUV 4:2:2 converter */ vout_convert_t * p_ConvertYUV422; /* YUV 4:2:2 converter */
vout_convert_t * p_ConvertYUV444; /* YUV 4:4:4 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; } vout_thread_t;
/* Flags for changes - these flags are set in the i_changes field when another /* 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 ...@@ -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 ); ...@@ -13,9 +13,6 @@ void vout_SysDestroy ( p_vout_thread_t p_vout );
int vout_SysManage ( 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_SysDisplay ( p_vout_thread_t p_vout );
void * vout_SysGetPicture ( 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 @@ ...@@ -21,6 +21,7 @@
#include "vlc_thread.h" #include "vlc_thread.h"
#include "video.h" #include "video.h"
#include "video_output.h" #include "video_output.h"
#include "video_text.h"
#include "video_sys.h" #include "video_sys.h"
#include "video_yuv.h" #include "video_yuv.h"
#include "intf_msg.h" #include "intf_msg.h"
...@@ -33,6 +34,7 @@ static int InitThread ( vout_thread_t *p_vout ); ...@@ -33,6 +34,7 @@ static int InitThread ( vout_thread_t *p_vout );
static void RunThread ( vout_thread_t *p_vout ); static void RunThread ( vout_thread_t *p_vout );
static void ErrorThread ( vout_thread_t *p_vout ); static void ErrorThread ( vout_thread_t *p_vout );
static void EndThread ( 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 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 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 ); 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_ ...@@ -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", 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_width, p_vout->i_height, p_vout->i_screen_depth,
p_vout->i_bytes_per_pixel, p_vout->i_bytes_per_line ); 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 #ifdef STATS
/* Initialize statistics fields */ /* Initialize statistics fields */
...@@ -119,6 +138,8 @@ vout_thread_t * vout_CreateThread ( char *psz_display, int i_root_ ...@@ -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) ) if( vlc_thread_create( &p_vout->thread_id, "video output", (void *) RunThread, (void *) p_vout) )
{ {
intf_ErrMsg("error: %s\n", strerror(ENOMEM)); 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 ); vout_SysDestroy( p_vout );
free( p_vout ); free( p_vout );
return( NULL ); return( NULL );
...@@ -600,6 +621,7 @@ static void RunThread( vout_thread_t *p_vout) ...@@ -600,6 +621,7 @@ static void RunThread( vout_thread_t *p_vout)
p_vout->b_error = InitThread( p_vout ); p_vout->b_error = InitThread( p_vout );
if( p_vout->b_error ) if( p_vout->b_error )
{ {
//??
free( p_vout ); /* destroy descriptor */ free( p_vout ); /* destroy descriptor */
return; return;
} }
...@@ -792,8 +814,10 @@ static void EndThread( vout_thread_t *p_vout ) ...@@ -792,8 +814,10 @@ static void EndThread( vout_thread_t *p_vout )
/* Destroy translation tables */ /* Destroy translation tables */
vout_EndTables( p_vout ); vout_EndTables( p_vout );
/* Destroy thread structures allocated by InitThread */ /* Destroy thread structures allocated by Create and InitThread */
vout_SysEnd( p_vout ); vout_SysEnd( p_vout );
vout_UnloadFont( p_vout->p_default_font );
vout_UnloadFont( p_vout->p_large_font );
vout_SysDestroy( p_vout ); vout_SysDestroy( p_vout );
free( p_vout ); free( p_vout );
...@@ -801,6 +825,53 @@ static void EndThread( vout_thread_t *p_vout ) ...@@ -801,6 +825,53 @@ static void EndThread( vout_thread_t *p_vout )
*pi_status = THREAD_OVER; *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 * RenderBlank: render a blank screen
****************************************************************************** ******************************************************************************
...@@ -972,7 +1043,7 @@ static int RenderPictureInfo( vout_thread_t *p_vout, picture_t *p_pic, boolean_t ...@@ -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 / 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 - 1) % VOUT_FPS_SAMPLES ] -
p_vout->fps_sample[ p_vout->c_fps_samples % 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 ...@@ -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", sprintf( psz_buffer, "%ld frames render time: %lu us",
p_vout->c_fps_samples, (long unsigned) p_vout->render_time ); 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 #endif
#ifdef DEBUG #ifdef DEBUG
...@@ -998,7 +1069,7 @@ static int RenderPictureInfo( vout_thread_t *p_vout, picture_t *p_pic, boolean_t ...@@ -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_3_4_PICTURE) ? "4:3" :
((p_pic->i_aspect_ratio == AR_16_9_PICTURE) ? "16:9" : ((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" )))); ((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 #endif
return( 0 ); return( 0 );
...@@ -1018,8 +1089,8 @@ static int RenderIdle( vout_thread_t *p_vout, boolean_t b_blank ) ...@@ -1018,8 +1089,8 @@ static int RenderIdle( vout_thread_t *p_vout, boolean_t b_blank )
{ {
RenderBlank( p_vout ); RenderBlank( p_vout );
p_vout->last_display_date = mdate(); p_vout->last_display_date = mdate();
vout_SysPrint( p_vout, p_vout->i_width / 2, p_vout->i_height / 2, 0, 0, Print( p_vout, p_vout->i_width / 2, p_vout->i_height / 2, 0, 0,
"no stream" ); "no stream" ); //??
return( 1 ); return( 1 );
} }
...@@ -1063,9 +1134,10 @@ static int RenderInfo( vout_thread_t *p_vout, boolean_t b_blank ) ...@@ -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->i_width, p_vout->i_height, p_vout->i_screen_depth,
p_vout->f_gamma, i_reserved_pic, i_ready_pic, p_vout->f_gamma, i_reserved_pic, i_ready_pic,
VOUT_MAX_PICTURES ); 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 #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;
#ifdef DEBUG
default:
intf_DbgMsg("error: invalid bytes per pixel %d\n", i_bytes_per_pixel );
p_PutByte = NULL;
break;
#endif
}
/* Choose masks and copy font data to local variables */
i_char_mask = (i_style & VOID_TEXT) ? 0 : 0xff;
i_border_mask = (i_style & OUTLINED_TEXT) ? 0xff : 0;
i_bg_mask = (i_style & TRANSPARENT_TEXT) ? 0 : 0xff;
i_font_bytes_per_line = p_font->i_bytes_per_line;
i_font_height = p_font->i_height;
i_interspacing = i_bytes_per_pixel * ((i_style & WIDE_TEXT) ?
p_font->i_interspacing * 2 :
p_font->i_interspacing);
/* Print text */
for( ; *psz_text != '\0'; psz_text++ )
{
/* Check that the character is valid */
if( (*psz_text >= p_font->i_first) && (*psz_text <= p_font->i_last) )
{
/* Select character - bytes per char is always valid, event for
* non fixed fonts */
p_char = p_font->p_data + (*psz_text - p_font->i_first) * p_font->i_bytes_per_char;
p_border = p_char + (p_font->i_last - p_font->i_first + 1) * p_font->i_bytes_per_char;
/* Select base address for output */
switch( p_font->i_type )
{
case VOUT_FIXED_FONT:
/*
* Simple fixed width font
*/
/* Italic text: shift picture start right */
if( i_style & ITALIC_TEXT )
{
p_pic += i_bytes_per_pixel * (p_font->i_height / 3);
}
/* Print character */
for( i_line = 0; i_line < i_font_height; i_line ++ )
{
for( i_byte = 0; i_byte < i_font_bytes_per_line; i_byte++, p_char++, p_border++)
{
/* Put pixels */
p_PutByte( p_pic + i_bytes_per_line * i_line, i_byte,
*p_char & i_char_mask, *p_border & i_border_mask, i_bg_mask,
i_char_color, i_border_color, i_bg_color );
}
/* Italic text: shift picture start left */
if( (i_style & ITALIC_TEXT) && !(i_line % 3) )
{
p_pic -= i_bytes_per_pixel;
}
}
/* Jump to next character */
p_pic += i_interspacing;
break;
#ifdef DEBUG
default:
intf_DbgMsg("error: unknown font type %d\n", p_font->i_type );
break;
#endif
}
}
}
}
/* following functions are local */
/*******************************************************************************
* PutByte16: print a fixed width font character byte in 15 or 16 bpp
*******************************************************************************/
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 )
{
/* Computes position offset and background mask */
p_pic += 8 * i_byte;
i_bg &= ~(i_char | i_border);
/* Put character bits */
TREE(i_char, i_char_color);
TREE(i_border, i_border_color);
TREE(i_bg, i_bg_color);
}
/*******************************************************************************
* PutByte24: print a fixed width font character byte in 24 bpp
*******************************************************************************/
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 )
{
//??
}
/*******************************************************************************
* PutByte32: print a fixed width font character byte in 32 bpp
*******************************************************************************/
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 )
{
/* Computes position offset and background mask */
p_pic += 8 * i_byte;
i_bg &= ~(i_char | i_border);
/* Put character bits */
TREE(i_char, i_char_color);
TREE(i_border, i_border_color);
TREE(i_bg, i_bg_color);
}
...@@ -47,12 +47,6 @@ typedef struct vout_sys_s ...@@ -47,12 +47,6 @@ typedef struct vout_sys_s
Window window; /* window instance handler */ Window window; /* window instance handler */
GC gc; /* graphic context instance handler */ GC gc; /* graphic context instance handler */
/* Font information */
int i_char_bytes_per_line; /* character width (bytes) */
int i_char_height; /* character height (lines) */
int i_char_interspacing; /* space between centers (pixels) */
byte_t * pi_font; /* pointer to font data */
/* Display buffers and shared memory information */ /* Display buffers and shared memory information */
int i_buffer_index; /* buffer index */ int i_buffer_index; /* buffer index */
XImage * p_ximage[2]; /* XImage pointer */ XImage * p_ximage[2]; /* XImage pointer */
...@@ -64,7 +58,6 @@ typedef struct vout_sys_s ...@@ -64,7 +58,6 @@ typedef struct vout_sys_s
*******************************************************************************/ *******************************************************************************/
static int X11OpenDisplay ( vout_thread_t *p_vout, char *psz_display, Window root_window ); static int X11OpenDisplay ( vout_thread_t *p_vout, char *psz_display, Window root_window );
static void X11CloseDisplay ( vout_thread_t *p_vout ); static void X11CloseDisplay ( vout_thread_t *p_vout );
static int X11GetFont ( vout_thread_t *p_vout );
static int X11CreateWindow ( vout_thread_t *p_vout ); static int X11CreateWindow ( vout_thread_t *p_vout );
static void X11DestroyWindow ( vout_thread_t *p_vout ); static void X11DestroyWindow ( vout_thread_t *p_vout );
static int X11CreateImage ( vout_thread_t *p_vout, XImage **pp_ximage ); static int X11CreateImage ( vout_thread_t *p_vout, XImage **pp_ximage );
...@@ -211,7 +204,7 @@ void vout_SysDestroy( vout_thread_t *p_vout ) ...@@ -211,7 +204,7 @@ void vout_SysDestroy( vout_thread_t *p_vout )
*******************************************************************************/ *******************************************************************************/
int vout_SysManage( vout_thread_t *p_vout ) int vout_SysManage( vout_thread_t *p_vout )
{ {
if( p_vout->i_changes & VOUT_SIZE_CHANGE ) if( p_vout->i_changes & VOUT_SIZE_CHANGE )
{ {
intf_DbgMsg("resizing window\n"); intf_DbgMsg("resizing window\n");
p_vout->i_changes &= ~VOUT_SIZE_CHANGE; p_vout->i_changes &= ~VOUT_SIZE_CHANGE;
...@@ -281,89 +274,6 @@ void * vout_SysGetPicture( vout_thread_t *p_vout ) ...@@ -281,89 +274,6 @@ void * vout_SysGetPicture( vout_thread_t *p_vout )
return( p_vout->p_sys->p_ximage[ p_vout->p_sys->i_buffer_index ]->data ); return( p_vout->p_sys->p_ximage[ p_vout->p_sys->i_buffer_index ]->data );
} }
/*******************************************************************************
* vout_SysPrint: 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, not to render subtitles.
* Since there is no way to print text on an Ximage directly, this function
* copy directly the pixels from a font.
*******************************************************************************/
void vout_SysPrint( vout_thread_t *p_vout, int i_x, int i_y, int i_halign,
int i_valign, unsigned char *psz_text )
{
int i_line; /* line in character matrix */
int i_byte; /* byte offset in character line */
int i_height; /* character height */
int i_char_bytes_per_line; /* total bytes per line */
int i_text_width; /* total text width */
byte_t * pi_pic; /* picture data */
byte_t * pi_char; /* character data */
/* Update upper left coordinates according to alignment */
i_text_width = p_vout->p_sys->i_char_interspacing * strlen( psz_text );
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 -= p_vout->p_sys->i_char_height / 2;
break;
case 1: /* bottom aligned */
i_y -= p_vout->p_sys->i_char_height;
break;
}
/* Copy used variables to local */
i_height = p_vout->p_sys->i_char_height;
i_char_bytes_per_line = p_vout->p_sys->i_char_bytes_per_line;
/* Check that the text is in the screen vertically and horizontally */
if( (i_y < 0) || (i_y + i_height > p_vout->i_height) || (i_x < 0) ||
(i_x + i_text_width > p_vout->i_width) )
{
intf_DbgMsg("text '%s' would print outside the screen\n", psz_text);
return;
}
/* Print text */
for( ; *psz_text != '\0'; psz_text++ )
{
/* Check that the character is valid and in the screen horizontally */
if( (*psz_text >= VOUT_MIN_CHAR) && (*psz_text < VOUT_MAX_CHAR) )
{
/* Select character */
pi_char = p_vout->p_sys->pi_font + (*psz_text - VOUT_MIN_CHAR) *
i_height * i_char_bytes_per_line;
pi_pic = p_vout->p_sys->p_ximage[ p_vout->p_sys->i_buffer_index ]->data +
i_y * p_vout->i_bytes_per_line + i_x * p_vout->i_bytes_per_pixel;
/* Copy character */
for( i_line = 0; i_line < i_height; i_line++ )
{
/* Copy line */
for( i_byte = 0; i_byte < i_char_bytes_per_line; i_byte++ )
{
pi_pic[ i_byte ] = *pi_char++;
}
/* Go to next line */
pi_pic += p_vout->i_bytes_per_line;
}
}
/* Jump to next character */
i_x += p_vout->p_sys->i_char_interspacing;
}
}
/* following functions are local */ /* following functions are local */
/******************************************************************************* /*******************************************************************************
...@@ -421,16 +331,6 @@ static int X11OpenDisplay( vout_thread_t *p_vout, char *psz_display, Window root ...@@ -421,16 +331,6 @@ static int X11OpenDisplay( vout_thread_t *p_vout, char *psz_display, Window root
XCloseDisplay( p_vout->p_sys->p_display ); XCloseDisplay( p_vout->p_sys->p_display );
return( 1 ); return( 1 );
} }
/* Get font information */
if( X11GetFont( p_vout ) )
{
intf_ErrMsg("error: can't read default font\n");
X11DestroyWindow( p_vout );
XCloseDisplay( p_vout->p_sys->p_display );
return( 1 );
}
return( 0 ); return( 0 );
} }
...@@ -442,101 +342,11 @@ static int X11OpenDisplay( vout_thread_t *p_vout, char *psz_display, Window root ...@@ -442,101 +342,11 @@ static int X11OpenDisplay( vout_thread_t *p_vout, char *psz_display, Window root
*******************************************************************************/ *******************************************************************************/
static void X11CloseDisplay( vout_thread_t *p_vout ) static void X11CloseDisplay( vout_thread_t *p_vout )
{ {
// Free font info /* Destroy window and close display */
free( p_vout->p_sys->pi_font );
// Destroy window and close display
X11DestroyWindow( p_vout ); X11DestroyWindow( p_vout );
XCloseDisplay( p_vout->p_sys->p_display ); XCloseDisplay( p_vout->p_sys->p_display );
} }
/*******************************************************************************
* X11GetFont: get default font bitmap informations
*******************************************************************************
* This function will convert a font into a bitmap for later use by the
* vout_SysPrint function.
*******************************************************************************/
static int X11GetFont( vout_thread_t *p_vout )
{
XFontStruct * p_font_info; /* font information structure */
Pixmap pixmap; /* pixmap used to draw characters */
GC gc; /* graphic context */
XGCValues gc_values; /* graphic context properties */
XImage * p_ximage; /* ximage for character */
unsigned char i_char; /* character index */
int i_char_width; /* character width (pixels) */
int i_char_bytes; /* total character size */
/* Load font */
p_font_info = XLoadQueryFont( p_vout->p_sys->p_display, "fixed" );
if( p_font_info == NULL )
{
intf_ErrMsg("error: can't load 'fixed' font\n");
return( 1 );
}
/* Get character size */
i_char_width = p_font_info->max_bounds.lbearing +
p_font_info->max_bounds.rbearing;
p_vout->p_sys->i_char_bytes_per_line = i_char_width * p_vout->i_bytes_per_pixel;
p_vout->p_sys->i_char_height = p_font_info->max_bounds.ascent +
p_font_info->max_bounds.descent;
i_char_bytes = p_vout->p_sys->i_char_bytes_per_line *
p_vout->p_sys->i_char_height;
p_vout->p_sys->i_char_interspacing = p_font_info->max_bounds.width;
/* Allocate font descriptor */
p_vout->p_sys->pi_font = malloc( i_char_bytes * ( VOUT_MAX_CHAR - VOUT_MIN_CHAR ) );
if( p_vout->p_sys->pi_font == NULL )
{
intf_ErrMsg("error: %s\n", strerror( ENOMEM ) );
XFreeFont( p_vout->p_sys->p_display, p_font_info );
return( 1 );
}
/* Create drawable and graphic context */
gc_values.foreground = XBlackPixel( p_vout->p_sys->p_display,
p_vout->p_sys->i_screen );
gc_values.background = XBlackPixel( p_vout->p_sys->p_display,
p_vout->p_sys->i_screen );
gc_values.font = p_font_info->fid;
pixmap = XCreatePixmap( p_vout->p_sys->p_display, p_vout->p_sys->window,
i_char_width,
p_vout->p_sys->i_char_height *(VOUT_MAX_CHAR-VOUT_MIN_CHAR),
p_vout->i_screen_depth );
gc = XCreateGC( p_vout->p_sys->p_display, pixmap,
GCForeground | GCBackground | GCFont, &gc_values );
/* Clear pixmap and invert graphic context */
XFillRectangle( p_vout->p_sys->p_display, pixmap, gc, 0, 0, i_char_width,
p_vout->p_sys->i_char_height*(VOUT_MAX_CHAR-VOUT_MIN_CHAR) );
XSetForeground( p_vout->p_sys->p_display, gc,
XWhitePixel( p_vout->p_sys->p_display, p_vout->p_sys->i_screen ) );
XSetBackground( p_vout->p_sys->p_display, gc,
XBlackPixel( p_vout->p_sys->p_display, p_vout->p_sys->i_screen ) );
/* Copy characters bitmaps to font descriptor */
for( i_char = VOUT_MIN_CHAR; i_char < VOUT_MAX_CHAR; i_char++ )
{
XDrawString( p_vout->p_sys->p_display, pixmap, gc, 0,
p_font_info->max_bounds.ascent +
(i_char-VOUT_MIN_CHAR) * p_vout->p_sys->i_char_height,
&i_char, 1 );
}
p_ximage = XGetImage( p_vout->p_sys->p_display, pixmap, 0, 0, i_char_width,
p_vout->p_sys->i_char_height*(VOUT_MAX_CHAR-VOUT_MIN_CHAR),
-1, ZPixmap );
memcpy( p_vout->p_sys->pi_font, p_ximage->data,
i_char_bytes*(VOUT_MAX_CHAR-VOUT_MIN_CHAR));
/* Free resources, unload font and return */
XDestroyImage( p_ximage );
XFreeGC( p_vout->p_sys->p_display, gc );
XFreePixmap( p_vout->p_sys->p_display, pixmap );
XFreeFont( p_vout->p_sys->p_display, p_font_info );
return( 0 );
}
/******************************************************************************* /*******************************************************************************
* X11CreateWindow: create X11 vout window * X11CreateWindow: create X11 vout window
******************************************************************************* *******************************************************************************
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment