text_renderer.h

Go to the documentation of this file.
00001 /*****************************************************************************
00002  * text_renderer.h: common text renderer code
00003  *****************************************************************************
00004  * Copyright (C) 2007-2008 the VideoLAN team
00005  * $Id: cddaab7127c59f54f1e342d52b799bfd4c49f055 $
00006  *
00007  * Authors: Bernie Purcell <bitmap@videolan.org>
00008  *          Laurent Aimar < fenrir AT videolan DOT org >
00009  *
00010  * This program is free software; you can redistribute it and/or modify
00011  * it under the terms of the GNU General Public License as published by
00012  * the Free Software Foundation; either version 2 of the License, or
00013  * (at your option) any later version.
00014  *
00015  * This program is distributed in the hope that it will be useful,
00016  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00017  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018  * GNU General Public License for more details.
00019  *
00020  * You should have received a copy of the GNU General Public License
00021  * along with this program; if not, write to the Free Software
00022  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
00023  *****************************************************************************/
00024 
00025 typedef struct font_stack_t font_stack_t;
00026 struct font_stack_t
00027 {
00028     char          *psz_name;
00029     int            i_size;
00030     uint32_t       i_color;            /* ARGB */
00031     uint32_t       i_karaoke_bg_color; /* ARGB */
00032 
00033     font_stack_t  *p_next;
00034 };
00035 
00036 static void SetupLine( filter_t *p_filter, const char *psz_text_in,
00037                        UCHAR **psz_text_out, uint32_t *pi_runs,
00038                        uint32_t **ppi_run_lengths, TR_FONT_STYLE_PTR **ppp_styles,
00039                        TR_FONT_STYLE_PTR p_style );
00040 
00041 static TR_FONT_STYLE_PTR GetStyleFromFontStack( filter_sys_t *p_sys,
00042                                           font_stack_t **p_fonts, bool b_bold, bool b_italic,
00043                                           bool b_uline );
00044 
00045 static int PushFont( font_stack_t **p_font, const char *psz_name, int i_size,
00046                      uint32_t i_color, uint32_t i_karaoke_bg_color )
00047 {
00048     font_stack_t *p_new;
00049 
00050     if( !p_font )
00051         return VLC_EGENERIC;
00052 
00053     p_new = malloc( sizeof( font_stack_t ) );
00054     if( ! p_new )
00055         return VLC_ENOMEM;
00056 
00057     p_new->p_next = NULL;
00058 
00059     if( psz_name )
00060         p_new->psz_name = strdup( psz_name );
00061     else
00062         p_new->psz_name = NULL;
00063 
00064     p_new->i_size              = i_size;
00065     p_new->i_color             = i_color;
00066     p_new->i_karaoke_bg_color  = i_karaoke_bg_color;
00067 
00068     if( !*p_font )
00069     {
00070         *p_font = p_new;
00071     }
00072     else
00073     {
00074         font_stack_t *p_last;
00075 
00076         for( p_last = *p_font;
00077              p_last->p_next;
00078              p_last = p_last->p_next )
00079         ;
00080 
00081         p_last->p_next = p_new;
00082     }
00083     return VLC_SUCCESS;
00084 }
00085 
00086 static int PopFont( font_stack_t **p_font )
00087 {
00088     font_stack_t *p_last, *p_next_to_last;
00089 
00090     if( !p_font || !*p_font )
00091         return VLC_EGENERIC;
00092 
00093     p_next_to_last = NULL;
00094     for( p_last = *p_font;
00095          p_last->p_next;
00096          p_last = p_last->p_next )
00097     {
00098         p_next_to_last = p_last;
00099     }
00100 
00101     if( p_next_to_last )
00102         p_next_to_last->p_next = NULL;
00103     else
00104         *p_font = NULL;
00105 
00106     free( p_last->psz_name );
00107     free( p_last );
00108 
00109     return VLC_SUCCESS;
00110 }
00111 
00112 static int PeekFont( font_stack_t **p_font, char **psz_name, int *i_size,
00113                      uint32_t *i_color, uint32_t *i_karaoke_bg_color )
00114 {
00115     font_stack_t *p_last;
00116 
00117     if( !p_font || !*p_font )
00118         return VLC_EGENERIC;
00119 
00120     for( p_last=*p_font;
00121          p_last->p_next;
00122          p_last=p_last->p_next )
00123     ;
00124 
00125     *psz_name            = p_last->psz_name;
00126     *i_size              = p_last->i_size;
00127     *i_color             = p_last->i_color;
00128     *i_karaoke_bg_color  = p_last->i_karaoke_bg_color;
00129 
00130     return VLC_SUCCESS;
00131 }
00132 
00133 static const struct {
00134     const char *psz_name;
00135     uint32_t   i_value;
00136 } p_html_colors[] = {
00137     /* Official html colors */
00138     { "Aqua",    0x00FFFF },
00139     { "Black",   0x000000 },
00140     { "Blue",    0x0000FF },
00141     { "Fuchsia", 0xFF00FF },
00142     { "Gray",    0x808080 },
00143     { "Green",   0x008000 },
00144     { "Lime",    0x00FF00 },
00145     { "Maroon",  0x800000 },
00146     { "Navy",    0x000080 },
00147     { "Olive",   0x808000 },
00148     { "Purple",  0x800080 },
00149     { "Red",     0xFF0000 },
00150     { "Silver",  0xC0C0C0 },
00151     { "Teal",    0x008080 },
00152     { "White",   0xFFFFFF },
00153     { "Yellow",  0xFFFF00 },
00154 
00155     /* Common ones */
00156     { "AliceBlue", 0xF0F8FF },
00157     { "AntiqueWhite", 0xFAEBD7 },
00158     { "Aqua", 0x00FFFF },
00159     { "Aquamarine", 0x7FFFD4 },
00160     { "Azure", 0xF0FFFF },
00161     { "Beige", 0xF5F5DC },
00162     { "Bisque", 0xFFE4C4 },
00163     { "Black", 0x000000 },
00164     { "BlanchedAlmond", 0xFFEBCD },
00165     { "Blue", 0x0000FF },
00166     { "BlueViolet", 0x8A2BE2 },
00167     { "Brown", 0xA52A2A },
00168     { "BurlyWood", 0xDEB887 },
00169     { "CadetBlue", 0x5F9EA0 },
00170     { "Chartreuse", 0x7FFF00 },
00171     { "Chocolate", 0xD2691E },
00172     { "Coral", 0xFF7F50 },
00173     { "CornflowerBlue", 0x6495ED },
00174     { "Cornsilk", 0xFFF8DC },
00175     { "Crimson", 0xDC143C },
00176     { "Cyan", 0x00FFFF },
00177     { "DarkBlue", 0x00008B },
00178     { "DarkCyan", 0x008B8B },
00179     { "DarkGoldenRod", 0xB8860B },
00180     { "DarkGray", 0xA9A9A9 },
00181     { "DarkGrey", 0xA9A9A9 },
00182     { "DarkGreen", 0x006400 },
00183     { "DarkKhaki", 0xBDB76B },
00184     { "DarkMagenta", 0x8B008B },
00185     { "DarkOliveGreen", 0x556B2F },
00186     { "Darkorange", 0xFF8C00 },
00187     { "DarkOrchid", 0x9932CC },
00188     { "DarkRed", 0x8B0000 },
00189     { "DarkSalmon", 0xE9967A },
00190     { "DarkSeaGreen", 0x8FBC8F },
00191     { "DarkSlateBlue", 0x483D8B },
00192     { "DarkSlateGray", 0x2F4F4F },
00193     { "DarkSlateGrey", 0x2F4F4F },
00194     { "DarkTurquoise", 0x00CED1 },
00195     { "DarkViolet", 0x9400D3 },
00196     { "DeepPink", 0xFF1493 },
00197     { "DeepSkyBlue", 0x00BFFF },
00198     { "DimGray", 0x696969 },
00199     { "DimGrey", 0x696969 },
00200     { "DodgerBlue", 0x1E90FF },
00201     { "FireBrick", 0xB22222 },
00202     { "FloralWhite", 0xFFFAF0 },
00203     { "ForestGreen", 0x228B22 },
00204     { "Fuchsia", 0xFF00FF },
00205     { "Gainsboro", 0xDCDCDC },
00206     { "GhostWhite", 0xF8F8FF },
00207     { "Gold", 0xFFD700 },
00208     { "GoldenRod", 0xDAA520 },
00209     { "Gray", 0x808080 },
00210     { "Grey", 0x808080 },
00211     { "Green", 0x008000 },
00212     { "GreenYellow", 0xADFF2F },
00213     { "HoneyDew", 0xF0FFF0 },
00214     { "HotPink", 0xFF69B4 },
00215     { "IndianRed", 0xCD5C5C },
00216     { "Indigo", 0x4B0082 },
00217     { "Ivory", 0xFFFFF0 },
00218     { "Khaki", 0xF0E68C },
00219     { "Lavender", 0xE6E6FA },
00220     { "LavenderBlush", 0xFFF0F5 },
00221     { "LawnGreen", 0x7CFC00 },
00222     { "LemonChiffon", 0xFFFACD },
00223     { "LightBlue", 0xADD8E6 },
00224     { "LightCoral", 0xF08080 },
00225     { "LightCyan", 0xE0FFFF },
00226     { "LightGoldenRodYellow", 0xFAFAD2 },
00227     { "LightGray", 0xD3D3D3 },
00228     { "LightGrey", 0xD3D3D3 },
00229     { "LightGreen", 0x90EE90 },
00230     { "LightPink", 0xFFB6C1 },
00231     { "LightSalmon", 0xFFA07A },
00232     { "LightSeaGreen", 0x20B2AA },
00233     { "LightSkyBlue", 0x87CEFA },
00234     { "LightSlateGray", 0x778899 },
00235     { "LightSlateGrey", 0x778899 },
00236     { "LightSteelBlue", 0xB0C4DE },
00237     { "LightYellow", 0xFFFFE0 },
00238     { "Lime", 0x00FF00 },
00239     { "LimeGreen", 0x32CD32 },
00240     { "Linen", 0xFAF0E6 },
00241     { "Magenta", 0xFF00FF },
00242     { "Maroon", 0x800000 },
00243     { "MediumAquaMarine", 0x66CDAA },
00244     { "MediumBlue", 0x0000CD },
00245     { "MediumOrchid", 0xBA55D3 },
00246     { "MediumPurple", 0x9370D8 },
00247     { "MediumSeaGreen", 0x3CB371 },
00248     { "MediumSlateBlue", 0x7B68EE },
00249     { "MediumSpringGreen", 0x00FA9A },
00250     { "MediumTurquoise", 0x48D1CC },
00251     { "MediumVioletRed", 0xC71585 },
00252     { "MidnightBlue", 0x191970 },
00253     { "MintCream", 0xF5FFFA },
00254     { "MistyRose", 0xFFE4E1 },
00255     { "Moccasin", 0xFFE4B5 },
00256     { "NavajoWhite", 0xFFDEAD },
00257     { "Navy", 0x000080 },
00258     { "OldLace", 0xFDF5E6 },
00259     { "Olive", 0x808000 },
00260     { "OliveDrab", 0x6B8E23 },
00261     { "Orange", 0xFFA500 },
00262     { "OrangeRed", 0xFF4500 },
00263     { "Orchid", 0xDA70D6 },
00264     { "PaleGoldenRod", 0xEEE8AA },
00265     { "PaleGreen", 0x98FB98 },
00266     { "PaleTurquoise", 0xAFEEEE },
00267     { "PaleVioletRed", 0xD87093 },
00268     { "PapayaWhip", 0xFFEFD5 },
00269     { "PeachPuff", 0xFFDAB9 },
00270     { "Peru", 0xCD853F },
00271     { "Pink", 0xFFC0CB },
00272     { "Plum", 0xDDA0DD },
00273     { "PowderBlue", 0xB0E0E6 },
00274     { "Purple", 0x800080 },
00275     { "Red", 0xFF0000 },
00276     { "RosyBrown", 0xBC8F8F },
00277     { "RoyalBlue", 0x4169E1 },
00278     { "SaddleBrown", 0x8B4513 },
00279     { "Salmon", 0xFA8072 },
00280     { "SandyBrown", 0xF4A460 },
00281     { "SeaGreen", 0x2E8B57 },
00282     { "SeaShell", 0xFFF5EE },
00283     { "Sienna", 0xA0522D },
00284     { "Silver", 0xC0C0C0 },
00285     { "SkyBlue", 0x87CEEB },
00286     { "SlateBlue", 0x6A5ACD },
00287     { "SlateGray", 0x708090 },
00288     { "SlateGrey", 0x708090 },
00289     { "Snow", 0xFFFAFA },
00290     { "SpringGreen", 0x00FF7F },
00291     { "SteelBlue", 0x4682B4 },
00292     { "Tan", 0xD2B48C },
00293     { "Teal", 0x008080 },
00294     { "Thistle", 0xD8BFD8 },
00295     { "Tomato", 0xFF6347 },
00296     { "Turquoise", 0x40E0D0 },
00297     { "Violet", 0xEE82EE },
00298     { "Wheat", 0xF5DEB3 },
00299     { "White", 0xFFFFFF },
00300     { "WhiteSmoke", 0xF5F5F5 },
00301     { "Yellow", 0xFFFF00 },
00302     { "YellowGreen", 0x9ACD32 },
00303 
00304     { NULL, 0 }
00305 };
00306 
00307 static int HandleFontAttributes( xml_reader_t *p_xml_reader,
00308                                   font_stack_t **p_fonts, int i_scale )
00309 {
00310     int        rv;
00311     char      *psz_fontname = NULL;
00312     uint32_t   i_font_color = 0xffffff;
00313     int        i_font_alpha = 0;
00314     uint32_t   i_karaoke_bg_color = 0x00ffffff;
00315     int        i_font_size  = 24;
00316 
00317     /* Default all attributes to the top font in the stack -- in case not
00318      * all attributes are specified in the sub-font
00319      */
00320     if( VLC_SUCCESS == PeekFont( p_fonts,
00321                                  &psz_fontname,
00322                                  &i_font_size,
00323                                  &i_font_color,
00324                                  &i_karaoke_bg_color ))
00325     {
00326         psz_fontname = strdup( psz_fontname );
00327         i_font_size = i_font_size * 1000 / i_scale;
00328     }
00329     i_font_alpha = (i_font_color >> 24) & 0xff;
00330     i_font_color &= 0x00ffffff;
00331 
00332     while ( xml_ReaderNextAttr( p_xml_reader ) == VLC_SUCCESS )
00333     {
00334         char *psz_name = xml_ReaderName( p_xml_reader );
00335         char *psz_value = xml_ReaderValue( p_xml_reader );
00336 
00337         if( psz_name && psz_value )
00338         {
00339             if( !strcasecmp( "face", psz_name ) )
00340             {
00341                 free( psz_fontname );
00342                 psz_fontname = strdup( psz_value );
00343             }
00344             else if( !strcasecmp( "size", psz_name ) )
00345             {
00346                 if( ( *psz_value == '+' ) || ( *psz_value == '-' ) )
00347                 {
00348                     int i_value = atoi( psz_value );
00349 
00350                     if( ( i_value >= -5 ) && ( i_value <= 5 ) )
00351                         i_font_size += ( i_value * i_font_size ) / 10;
00352                     else if( i_value < -5 )
00353                         i_font_size = - i_value;
00354                     else if( i_value > 5 )
00355                         i_font_size = i_value;
00356                 }
00357                 else
00358                     i_font_size = atoi( psz_value );
00359             }
00360             else if( !strcasecmp( "color", psz_name ) )
00361             {
00362                 if( psz_value[0] == '#' )
00363                 {
00364                     i_font_color = strtol( psz_value + 1, NULL, 16 );
00365                     i_font_color &= 0x00ffffff;
00366                 }
00367                 else
00368                 {
00369                     for( int i = 0; p_html_colors[i].psz_name != NULL; i++ )
00370                     {
00371                         if( !strncasecmp( psz_value, p_html_colors[i].psz_name, strlen(p_html_colors[i].psz_name) ) )
00372                         {
00373                             i_font_color = p_html_colors[i].i_value;
00374                             break;
00375                         }
00376                     }
00377                 }
00378             }
00379             else if( !strcasecmp( "alpha", psz_name ) &&
00380                      ( psz_value[0] == '#' ) )
00381             {
00382                 i_font_alpha = strtol( psz_value + 1, NULL, 16 );
00383                 i_font_alpha &= 0xff;
00384             }
00385         }
00386         free( psz_name );
00387         free( psz_value );
00388     }
00389     rv = PushFont( p_fonts,
00390                    psz_fontname,
00391                    i_font_size * i_scale / 1000,
00392                    (i_font_color & 0xffffff) | ((i_font_alpha & 0xff) << 24),
00393                    i_karaoke_bg_color );
00394 
00395     free( psz_fontname );
00396 
00397     return rv;
00398 }
00399 
00400 static void SetKaraokeLen( uint32_t i_runs, uint32_t *pi_run_lengths,
00401                            uint32_t i_k_runs, uint32_t *pi_k_run_lengths )
00402 {
00403     /* Karaoke tags _PRECEDE_ the text they specify a duration
00404      * for, therefore we are working out the length for the
00405      * previous tag, and first time through we have nothing
00406      */
00407     if( pi_k_run_lengths )
00408     {
00409         int i_chars = 0;
00410         uint32_t i;
00411 
00412         /* Work out how many characters are presently in the string
00413          */
00414         for( i = 0; i < i_runs; i++ )
00415             i_chars += pi_run_lengths[ i ];
00416 
00417         /* Subtract away those we've already allocated to other
00418          * karaoke tags
00419          */
00420         for( i = 0; i < i_k_runs; i++ )
00421             i_chars -= pi_k_run_lengths[ i ];
00422 
00423         pi_k_run_lengths[ i_k_runs - 1 ] = i_chars;
00424     }
00425 }
00426 
00427 static void SetupKaraoke( xml_reader_t *p_xml_reader, uint32_t *pi_k_runs,
00428                           uint32_t **ppi_k_run_lengths,
00429                           uint32_t **ppi_k_durations )
00430 {
00431     while ( xml_ReaderNextAttr( p_xml_reader ) == VLC_SUCCESS )
00432     {
00433         char *psz_name = xml_ReaderName( p_xml_reader );
00434         char *psz_value = xml_ReaderValue( p_xml_reader );
00435 
00436         if( psz_name && psz_value &&
00437             !strcasecmp( "t", psz_name ) )
00438         {
00439             if( ppi_k_durations && ppi_k_run_lengths )
00440             {
00441                 (*pi_k_runs)++;
00442 
00443                 if( *ppi_k_durations )
00444                 {
00445                     *ppi_k_durations = (uint32_t *)
00446                         realloc( *ppi_k_durations,
00447                                  *pi_k_runs * sizeof( uint32_t ) );
00448                 }
00449                 else if( *pi_k_runs == 1 )
00450                 {
00451                     *ppi_k_durations = (uint32_t *)
00452                         malloc( *pi_k_runs * sizeof( uint32_t ) );
00453                 }
00454 
00455                 if( *ppi_k_run_lengths )
00456                 {
00457                     *ppi_k_run_lengths = (uint32_t *)
00458                         realloc( *ppi_k_run_lengths,
00459                                  *pi_k_runs * sizeof( uint32_t ) );
00460                 }
00461                 else if( *pi_k_runs == 1 )
00462                 {
00463                     *ppi_k_run_lengths = (uint32_t *)
00464                         malloc( *pi_k_runs * sizeof( uint32_t ) );
00465                 }
00466                 if( *ppi_k_durations )
00467                     (*ppi_k_durations)[ *pi_k_runs - 1 ] = atoi( psz_value );
00468 
00469                 if( *ppi_k_run_lengths )
00470                     (*ppi_k_run_lengths)[ *pi_k_runs - 1 ] = 0;
00471             }
00472         }
00473         free( psz_name );
00474         free( psz_value );
00475     }
00476 }
00477 
00478 /* Turn any multiple-whitespaces into single spaces */
00479 static void HandleWhiteSpace( char *psz_node )
00480 {
00481     char *s = strpbrk( psz_node, "\t\r\n " );
00482     while( s )
00483     {
00484         int i_whitespace = strspn( s, "\t\r\n " );
00485 
00486         if( i_whitespace > 1 )
00487             memmove( &s[1],
00488                      &s[i_whitespace],
00489                      strlen( s ) - i_whitespace + 1 );
00490         *s++ = ' ';
00491 
00492         s = strpbrk( s, "\t\r\n " );
00493     }
00494 }
00495 
00496 /* */
00497 static int ProcessNodes( filter_t *p_filter,
00498                          xml_reader_t *p_xml_reader,
00499                          text_style_t *p_font_style,
00500                          UCHAR *psz_text,
00501                          int *pi_len,
00502 
00503                          uint32_t *pi_runs,
00504                          uint32_t **ppi_run_lengths,
00505                          TR_FONT_STYLE_PTR **ppp_styles,
00506 
00507                          bool b_karaoke,
00508                          uint32_t *pi_k_runs,
00509                          uint32_t **ppi_k_run_lengths,
00510                          uint32_t **ppi_k_durations )
00511 {
00512     int           rv             = VLC_SUCCESS;
00513     filter_sys_t *p_sys          = p_filter->p_sys;
00514     UCHAR        *psz_text_orig  = psz_text;
00515     font_stack_t *p_fonts        = NULL;
00516     vlc_value_t   val;
00517     int           i_scale        = 1000;
00518 
00519     char *psz_node  = NULL;
00520 
00521     bool b_italic = false;
00522     bool b_bold   = false;
00523     bool b_uline  = false;
00524 
00525     if( VLC_SUCCESS == var_Get( p_filter, "scale", &val ))
00526         i_scale = val.i_int;
00527 
00528     if( p_font_style )
00529     {
00530         rv = PushFont( &p_fonts,
00531                p_font_style->psz_fontname,
00532                p_font_style->i_font_size * i_scale / 1000,
00533                (p_font_style->i_font_color & 0xffffff) |
00534                    ((p_font_style->i_font_alpha & 0xff) << 24),
00535                (p_font_style->i_karaoke_background_color & 0xffffff) |
00536                    ((p_font_style->i_karaoke_background_alpha & 0xff) << 24));
00537 
00538         if( p_font_style->i_style_flags & STYLE_BOLD )
00539             b_bold = true;
00540         if( p_font_style->i_style_flags & STYLE_ITALIC )
00541             b_italic = true;
00542         if( p_font_style->i_style_flags & STYLE_UNDERLINE )
00543             b_uline = true;
00544     }
00545 #ifdef HAVE_FONTCONFIG
00546     else
00547     {
00548         rv = PushFont( &p_fonts,
00549                        TR_DEFAULT_FONT,
00550                        p_sys->i_font_size,
00551                        (p_sys->i_font_color & 0xffffff) |
00552                           (((255-p_sys->i_font_opacity) & 0xff) << 24),
00553                        0x00ffffff );
00554     }
00555 #endif
00556 
00557     if( rv != VLC_SUCCESS )
00558         return rv;
00559 
00560     while ( ( xml_ReaderRead( p_xml_reader ) == 1 ) )
00561     {
00562         switch ( xml_ReaderNodeType( p_xml_reader ) )
00563         {
00564             case XML_READER_NONE:
00565                 break;
00566             case XML_READER_ENDELEM:
00567                 psz_node = xml_ReaderName( p_xml_reader );
00568                 if( psz_node )
00569                 {
00570                     if( !strcasecmp( "font", psz_node ) )
00571                         PopFont( &p_fonts );
00572                     else if( !strcasecmp( "b", psz_node ) )
00573                         b_bold   = false;
00574                     else if( !strcasecmp( "i", psz_node ) )
00575                         b_italic = false;
00576                     else if( !strcasecmp( "u", psz_node ) )
00577                         b_uline  = false;
00578 
00579                     free( psz_node );
00580                 }
00581                 break;
00582             case XML_READER_STARTELEM:
00583                 psz_node = xml_ReaderName( p_xml_reader );
00584                 if( psz_node )
00585                 {
00586                     if( !strcasecmp( "font", psz_node ) )
00587                         rv = HandleFontAttributes( p_xml_reader, &p_fonts, i_scale );
00588                     else if( !strcasecmp( "b", psz_node ) )
00589                         b_bold = true;
00590                     else if( !strcasecmp( "i", psz_node ) )
00591                         b_italic = true;
00592                     else if( !strcasecmp( "u", psz_node ) )
00593                         b_uline = true;
00594                     else if( !strcasecmp( "br", psz_node ) )
00595                     {
00596                         SetupLine( p_filter, "\n", &psz_text,
00597                                    pi_runs, ppi_run_lengths, ppp_styles,
00598                                    GetStyleFromFontStack( p_sys,
00599                                                           &p_fonts,
00600                                                           b_bold,
00601                                                           b_italic,
00602                                                           b_uline ) );
00603                     }
00604                     else if( !strcasecmp( "k", psz_node ) )
00605                     {
00606                         /* Only valid in karaoke */
00607                         if( b_karaoke )
00608                         {
00609                             if( *pi_k_runs > 0 )
00610                             {
00611                                 SetKaraokeLen( *pi_runs, *ppi_run_lengths,
00612                                                *pi_k_runs, *ppi_k_run_lengths );
00613                             }
00614                             SetupKaraoke( p_xml_reader, pi_k_runs,
00615                                           ppi_k_run_lengths, ppi_k_durations );
00616                         }
00617                     }
00618 
00619                     free( psz_node );
00620                 }
00621                 break;
00622             case XML_READER_TEXT:
00623                 psz_node = xml_ReaderValue( p_xml_reader );
00624                 if( psz_node )
00625                 {
00626                     /* */
00627                     HandleWhiteSpace( psz_node );
00628                     resolve_xml_special_chars( psz_node );
00629 
00630                     SetupLine( p_filter, psz_node, &psz_text,
00631                                pi_runs, ppi_run_lengths, ppp_styles,
00632                                GetStyleFromFontStack( p_sys,
00633                                                       &p_fonts,
00634                                                       b_bold,
00635                                                       b_italic,
00636                                                       b_uline ) );
00637                     free( psz_node );
00638                 }
00639                 break;
00640         }
00641         if( rv != VLC_SUCCESS )
00642         {
00643             psz_text = psz_text_orig;
00644             break;
00645         }
00646     }
00647     if( b_karaoke )
00648     {
00649         SetKaraokeLen( *pi_runs, *ppi_run_lengths,
00650                        *pi_k_runs, *ppi_k_run_lengths );
00651     }
00652 
00653     *pi_len = psz_text - psz_text_orig;
00654 
00655     while( VLC_SUCCESS == PopFont( &p_fonts ) );
00656 
00657     return rv;
00658 }

Generated on Sat Nov 21 08:05:22 2009 for VLC by  doxygen 1.5.6