]> git.sesse.net Git - vlc/commitdiff
Nouveau moteur de fontes.
authorVincent Seguin <seguin@videolan.org>
Thu, 27 Jan 2000 18:30:01 +0000 (18:30 +0000)
committerVincent Seguin <seguin@videolan.org>
Thu, 27 Jan 2000 18:30:01 +0000 (18:30 +0000)
Makefile
include/common.h
include/config.h
include/video_output.h
include/video_sys.h
include/video_text.h [new file with mode: 0644]
lib/default8x16.psf [new file with mode: 0644]
lib/default8x9.psf [new file with mode: 0644]
src/video_output/video_output.c
src/video_output/video_text.c [new file with mode: 0644]
src/video_output/video_x11.c

index d0fcbfd5c4b36d132adb49b067de3fa6a786278d..e0d4759f766529819269c4b4e7387fcd3bf50c64 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -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 \
index 1dc4551163785106a67484c727afefb2f5bc91d7..b20e25133490f7fae1715a8321ef7ccb90f525a6 100644 (file)
@@ -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;
index 4da38f474594e45fa90b92a62815110db2d2cd5c..e14fe45afb3fdbc8d2c37c9bc814c4a23b9c39f7 100644 (file)
 /* Default gamma */
 #define VOUT_GAMMA                      0.
 
+/* Default fonts */
+#define VOUT_DEFAULT_FONT               "Resources/default8x9.psf"
+#define VOUT_LARGE_FONT                 "Resources/default8x16.psf"
+
 /*
  * Time settings
  */
 #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
  *******************************************************************************/
index 7c25566684c50ec9439c28e4aa8382deab531d2d..cbc3e82a5cc637296b8adaa451c9e7a54ba7b5c2 100644 (file)
@@ -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
 
 
 
-
-
-
-
-
-
-
index 97e3b4052513be8f1d5305b45c79b4f9e4ea57db..9be4617ba8bf1da25e80ea85554df1808343738a 100644 (file)
@@ -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 );
 
 
 
diff --git a/include/video_text.h b/include/video_text.h
new file mode 100644 (file)
index 0000000..e3da823
--- /dev/null
@@ -0,0 +1,35 @@
+/*******************************************************************************
+ * 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 );
+
+
+
+
+
+
+
+
+
+
diff --git a/lib/default8x16.psf b/lib/default8x16.psf
new file mode 100644 (file)
index 0000000..2d8df51
Binary files /dev/null and b/lib/default8x16.psf differ
diff --git a/lib/default8x9.psf b/lib/default8x9.psf
new file mode 100644 (file)
index 0000000..a383fa2
Binary files /dev/null and b/lib/default8x9.psf differ
index c6cda5c91bdaecc0653d274ed20fc0ebd4b2df28..dc0dea7449cb6b0fcdeaf9447affe54ca4e3b58d 100644 (file)
@@ -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 );    
 }
 
 /******************************************************************************
diff --git a/src/video_output/video_text.c b/src/video_output/video_text.c
new file mode 100644 (file)
index 0000000..f8fc977
--- /dev/null
@@ -0,0 +1,480 @@
+/*******************************************************************************
+ * 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);
+}
+
index e6b7226cca7dc2924d66dfe6da3d60df4aaee09f..72e7dc8d2746ea3aea79e56d935177241f434ebd 100644 (file)
@@ -47,12 +47,6 @@ typedef struct vout_sys_s
     Window              window;                     /* window 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 */
     int                 i_buffer_index;                        /* buffer index */
     XImage *            p_ximage[2];                         /* XImage pointer */   
@@ -64,7 +58,6 @@ typedef struct vout_sys_s
  *******************************************************************************/
 static int  X11OpenDisplay      ( vout_thread_t *p_vout, char *psz_display, Window root_window );
 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 void X11DestroyWindow    ( vout_thread_t *p_vout );
 static int  X11CreateImage      ( vout_thread_t *p_vout, XImage **pp_ximage );
@@ -211,7 +204,7 @@ void vout_SysDestroy( 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");      
         p_vout->i_changes &= ~VOUT_SIZE_CHANGE;       
@@ -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 );        
 }
 
-/*******************************************************************************
- * 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 */
 
 /*******************************************************************************
@@ -421,16 +331,6 @@ static int X11OpenDisplay( vout_thread_t *p_vout, char *psz_display, Window root
         XCloseDisplay( p_vout->p_sys->p_display );        
         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 );    
 }
 
@@ -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 )
 {
-    // Free font info
-    free( p_vout->p_sys->pi_font );    
-
-    // Destroy window and close display
+    /* Destroy window and close display */
     X11DestroyWindow( p_vout );
     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
  *******************************************************************************