]> git.sesse.net Git - vlc/blobdiff - modules/misc/freetype.c
freetype.c: basic YUY2 rendering (Y only)
[vlc] / modules / misc / freetype.c
index d433306296e34ee10797fa618cd8320ebe6336bf..3b9fb54f6b43247766e01b27132dabdbb6de7b9b 100644 (file)
@@ -2,7 +2,7 @@
  * freetype.c : Put text on the video, using freetype2
  *****************************************************************************
  * Copyright (C) 2002, 2003 VideoLAN
- * $Id: freetype.c,v 1.10 2003/07/23 21:45:13 hartman Exp $
+ * $Id: freetype.c,v 1.14 2003/07/26 18:54:20 titer Exp $
  *
  * Authors: Sigmund Augdal <sigmunau@idi.ntnu.no>
  *
@@ -54,6 +54,8 @@ static void Render    ( vout_thread_t *, picture_t *,
                         const subpicture_t * );
 static void RenderI420( vout_thread_t *, picture_t *,
                         const subpicture_t * );
+static void RenderYUY2( vout_thread_t *, picture_t *,
+                        const subpicture_t * );
 static int  AddText   ( vout_thread_t *, byte_t *, text_style_t *, int,
                         int, int, mtime_t, mtime_t );
 static int  GetUnicodeCharFromUTF8( byte_t ** );
@@ -137,23 +139,14 @@ static int Create( vlc_object_t *p_this )
             (uint8_t)( pow( (double)i / 255.0f, gamma_inv) * 255.0f );
     }
 
-    if( !var_Type( p_vout, "freetype-font" ) )
-    {
-        var_Create( p_vout, "freetype-font", VLC_VAR_STRING );
-        var_Change( p_vout, "freetype-font", VLC_VAR_INHERITVALUE, NULL, NULL );
-    }
-    if( !var_Type( p_vout, "freetype-fontsize" ) )
-    {
-        var_Create( p_vout, "freetype-fontsize", VLC_VAR_INTEGER );
-        var_Change( p_vout, "freetype-fontsize", VLC_VAR_INHERITVALUE, NULL, NULL );
-    }
+    var_Create( p_vout, "freetype-font", VLC_VAR_STRING | VLC_VAR_DOINHERIT );
+    var_Create( p_vout, "freetype-fontsize",
+                VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
 
     /* Look what method was requested */
     var_Get( p_vout, "freetype-font", &val );
-    psz_fontfile = (char *)malloc( PATH_MAX + 1 );
-    strcat( psz_fontfile, val.psz_string );
-    free( val.psz_string);
-    
+    psz_fontfile = val.psz_string;
+
     if( !psz_fontfile || !*psz_fontfile )
     {
         if( psz_fontfile ) free( psz_fontfile );
@@ -162,7 +155,11 @@ static int Create( vlc_object_t *p_this )
         GetWindowsDirectory( psz_fontfile, PATH_MAX + 1 );
         strcat( psz_fontfile, "\\fonts\\arial.ttf" );
 #elif SYS_DARWIN
-        strcat( psz_fontfile, DEFAULT_FONT );
+        strcpy( psz_fontfile, DEFAULT_FONT );
+#else
+        msg_Err( p_vout, "user didn't specify a font" );
+        free( p_vout->p_text_renderer_data );
+        return VLC_EGENERIC;
 #endif
     }
 
@@ -253,20 +250,20 @@ static void Render( vout_thread_t *p_vout, picture_t *p_pic,
 #if 0
         /* RV16 target, scaling */
         case VLC_FOURCC('R','V','1','6'):
-            RenderRV16( p_vout, p_pic, p_spu, p_spu->p_sys->b_crop );
+            RenderRV16( p_vout, p_pic, p_subpic );
             break;
 
         /* RV32 target, scaling */
         case VLC_FOURCC('R','V','2','4'):
         case VLC_FOURCC('R','V','3','2'):
-            RenderRV32( p_vout, p_pic, p_spu, p_spu->p_sys->b_crop );
+            RenderRV32( p_vout, p_pic, p_subpic );
             break;
-
-        /* NVidia overlay, no scaling */
+#endif
+        /* NVidia or BeOS overlay, no scaling */
         case VLC_FOURCC('Y','U','Y','2'):
-            RenderYUY2( p_vout, p_pic, p_spu, p_spu->p_sys->b_crop );
+            RenderYUY2( p_vout, p_pic, p_subpic );
             break;
-#endif
+
         default:
             msg_Err( p_vout, "unknown chroma, can't render SPU" );
             break;
@@ -301,6 +298,7 @@ static void RenderI420( vout_thread_t *p_vout, picture_t *p_pic,
             {
                 pen_y = p_string->i_y_margin;
             }
+            pen_y += p_vout->p_text_renderer_data->p_face->size->metrics.height / 100;
             if ( p_string->i_flags & OSD_ALIGN_RIGHT )
             {
                 pen_x = i_pitch - p_string->i_width
@@ -342,6 +340,7 @@ static void RenderI420( vout_thread_t *p_vout, picture_t *p_pic,
             {
                 pen_y = p_string->i_y_margin >> 1;
             }
+            pen_y += p_vout->p_text_renderer_data->p_face->size->metrics.height / 200;
             if ( p_string->i_flags & OSD_ALIGN_RIGHT )
             {
                 pen_x = i_pitch - ( p_string->i_width >> 1 )
@@ -375,6 +374,63 @@ static void RenderI420( vout_thread_t *p_vout, picture_t *p_pic,
     }
 }
 
+/**
+ * Draw a string on a YUY2 picture
+ */
+static void RenderYUY2( vout_thread_t *p_vout, picture_t *p_pic,
+                        const subpicture_t *p_subpic )
+{
+    subpicture_sys_t *p_string = p_subpic->p_sys;
+    int x, y, pen_x, pen_y;
+    unsigned int i;
+
+    uint8_t *p_in;
+    int i_pitch = p_pic->p[0].i_pitch;
+
+    p_in = p_pic->p->p_pixels;
+
+    if ( p_string->i_flags & OSD_ALIGN_BOTTOM )
+    {
+        pen_y = p_pic->p->i_lines - p_string->i_height -
+                p_string->i_y_margin;
+    }
+    else
+    {
+        pen_y = p_string->i_y_margin;
+    }
+    pen_y += p_vout->p_text_renderer_data->p_face->size->metrics.height / 100;
+    if ( p_string->i_flags & OSD_ALIGN_RIGHT )
+    {
+        pen_x = i_pitch - p_string->i_width - p_string->i_x_margin;
+    }
+    else
+    {
+        pen_x = p_string->i_x_margin;
+    }
+
+    /* TODO : set U & V bytes */
+    for( i = 0; p_string->pp_glyphs[i] != NULL; i++ )
+    {
+        if( p_string->pp_glyphs[i] )
+        {
+            FT_BitmapGlyph p_glyph = p_string->pp_glyphs[ i ];
+#define alpha p_vout->p_text_renderer_data->pi_gamma[ p_glyph->bitmap.buffer[ x + y * p_glyph->bitmap.width ] ]
+#define pixel p_in[ ( p_string->p_glyph_pos[ i ].y + pen_y + y - p_glyph->top ) * i_pitch + 2 * ( x + pen_x + p_string->p_glyph_pos[ i ].x + p_glyph->left ) ]
+            for( y = 0; y < p_glyph->bitmap.rows; y++ )
+            {
+                for( x = 0; x < p_glyph->bitmap.width; x++ )
+                {
+                    pixel = ( ( pixel * ( 255 - alpha ) ) >> 8 ) +
+                            ( 255 * alpha >> 8 );
+#undef alpha
+#undef pixel
+                }
+            }
+        }
+    }
+}
+
+
 /**
  * This function receives a string and creates a subpicture for it. It
  * also calculates the size needed for this string, and renders the
@@ -458,16 +514,20 @@ static int AddText ( vout_thread_t *p_vout, byte_t *psz_string,
         i_char = GetUnicodeCharFromUTF8( &psz_string );
 #define face p_vout->p_text_renderer_data->p_face
 #define glyph face->glyph
+        if ( i_char == 13 ) /* ignore CR chars wherever they may be */
+        {
+            continue;
+        }
         if ( i_char == '\n' )
         {
             i_pen_x = 0;
             result.x = __MAX( result.x, line.xMax );
-            result.y += face->size->metrics.height / 26.6;
+            result.y += face->size->metrics.height / 100;
             line.xMin = 0;
             line.xMax = 0;
             line.yMin = 0;
             line.yMax = 0;
-            i_pen_y += face->size->metrics.height / 26.6;
+            i_pen_y += face->size->metrics.height / 100;
             continue;
         }
         i_glyph_index = FT_Get_Char_Index( face, i_char );
@@ -497,7 +557,7 @@ static int AddText ( vout_thread_t *p_vout, byte_t *psz_string,
         FT_Glyph_Get_CBox( tmp_glyph, ft_glyph_bbox_pixels, &glyph_size );
         i_error = FT_Glyph_To_Bitmap( &tmp_glyph,
                                       ft_render_mode_normal,
-                                      &p_string->p_glyph_pos[i],
+                                      NULL,
                                       1 );
         if ( i_error ) continue;
         p_string->pp_glyphs[ i ] = (FT_BitmapGlyph)tmp_glyph;