⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 freetype.c

📁 VLC Player Source Code
💻 C
📖 第 1 页 / 共 5 页
字号:
static int PopFont( font_stack_t **p_font ){    font_stack_t *p_last, *p_next_to_last;    if( !p_font || !*p_font )        return VLC_EGENERIC;    p_next_to_last = NULL;    for( p_last = *p_font;         p_last->p_next;         p_last = p_last->p_next )    {        p_next_to_last = p_last;    }    if( p_next_to_last )        p_next_to_last->p_next = NULL;    else        *p_font = NULL;    free( p_last->psz_name );    free( p_last );    return VLC_SUCCESS;}static int PeekFont( font_stack_t **p_font, char **psz_name, int *i_size,                     uint32_t *i_color, uint32_t *i_karaoke_bg_color ){    font_stack_t *p_last;    if( !p_font || !*p_font )        return VLC_EGENERIC;    for( p_last=*p_font;         p_last->p_next;         p_last=p_last->p_next )    ;    *psz_name            = p_last->psz_name;    *i_size              = p_last->i_size;    *i_color             = p_last->i_color;    *i_karaoke_bg_color  = p_last->i_karaoke_bg_color;    return VLC_SUCCESS;}static void IconvText( filter_t *p_filter, const char *psz_string,                       uint32_t *i_string_length, uint32_t **ppsz_unicode ){    vlc_iconv_t iconv_handle = (vlc_iconv_t)(-1);    /* If memory hasn't been allocated for our output string, allocate it here     * - the calling function must now be responsible for freeing it.     */    if( !*ppsz_unicode )        *ppsz_unicode = (uint32_t *)            malloc( (strlen( psz_string ) + 1) * sizeof( uint32_t ));    /* We don't need to handle a NULL pointer in *ppsz_unicode     * if we are instead testing for a non NULL value like we are here */    if( *ppsz_unicode )    {#if defined(WORDS_BIGENDIAN)        iconv_handle = vlc_iconv_open( "UCS-4BE", "UTF-8" );#else        iconv_handle = vlc_iconv_open( "UCS-4LE", "UTF-8" );#endif        if( iconv_handle != (vlc_iconv_t)-1 )        {            char *p_in_buffer, *p_out_buffer;            size_t i_in_bytes, i_out_bytes, i_out_bytes_left, i_ret;            i_in_bytes = strlen( psz_string );            i_out_bytes = i_in_bytes * sizeof( uint32_t );            i_out_bytes_left = i_out_bytes;            p_in_buffer = (char *) psz_string;            p_out_buffer = (char *) *ppsz_unicode;            i_ret = vlc_iconv( iconv_handle, (const char**)&p_in_buffer,                    &i_in_bytes, &p_out_buffer, &i_out_bytes_left );            vlc_iconv_close( iconv_handle );            if( i_in_bytes )            {                msg_Warn( p_filter, "failed to convert string to unicode (%m), "                          "bytes left %u", (unsigned)i_in_bytes );            }            else            {                *(uint32_t*)p_out_buffer = 0;                *i_string_length =                    (i_out_bytes - i_out_bytes_left) / sizeof(uint32_t);            }        }        else        {            msg_Warn( p_filter, "unable to do conversion" );        }    }}static ft_style_t *GetStyleFromFontStack( filter_sys_t *p_sys,        font_stack_t **p_fonts, bool b_bold, bool b_italic,        bool b_uline ){    ft_style_t   *p_style = NULL;    char       *psz_fontname = NULL;    uint32_t    i_font_color = p_sys->i_font_color & 0x00ffffff;    uint32_t    i_karaoke_bg_color = i_font_color;    int         i_font_size  = p_sys->i_font_size;    if( VLC_SUCCESS == PeekFont( p_fonts, &psz_fontname, &i_font_size,                                 &i_font_color, &i_karaoke_bg_color ))    {        p_style = CreateStyle( psz_fontname, i_font_size, i_font_color,                i_karaoke_bg_color, b_bold, b_italic, b_uline );    }    return p_style;}static int RenderTag( filter_t *p_filter, FT_Face p_face, int i_font_color,                      bool b_uline, int i_karaoke_bgcolor,                      line_desc_t *p_line, uint32_t *psz_unicode,                      int *pi_pen_x, int i_pen_y, int *pi_start,                      FT_Vector *p_result ){    FT_BBox      line;    int          i_yMin, i_yMax;    int          i;    bool   b_first_on_line = true;    int          i_previous = 0;    int          i_pen_x_start = *pi_pen_x;    uint32_t *psz_unicode_start = psz_unicode;    line.xMin = line.xMax = line.yMin = line.yMax = 0;    /* Account for part of line already in position */    for( i=0; i<*pi_start; i++ )    {        FT_BBox glyph_size;        FT_Glyph_Get_CBox( (FT_Glyph) p_line->pp_glyphs[ i ],                            ft_glyph_bbox_pixels, &glyph_size );        line.xMax = p_line->p_glyph_pos[ i ].x + glyph_size.xMax -            glyph_size.xMin + p_line->pp_glyphs[ i ]->left;        line.yMax = __MAX( line.yMax, glyph_size.yMax );        line.yMin = __MIN( line.yMin, glyph_size.yMin );    }    i_yMin = line.yMin;    i_yMax = line.yMax;    if( line.xMax > 0 )        b_first_on_line = false;    while( *psz_unicode && ( *psz_unicode != '\n' ) )    {        FT_BBox glyph_size;        FT_Glyph tmp_glyph;        int i_error;        int i_glyph_index = FT_Get_Char_Index( p_face, *psz_unicode++ );        if( FT_HAS_KERNING( p_face ) && i_glyph_index            && i_previous )        {            FT_Vector delta;            FT_Get_Kerning( p_face, i_previous, i_glyph_index,                            ft_kerning_default, &delta );            *pi_pen_x += delta.x >> 6;        }        p_line->p_glyph_pos[ i ].x = *pi_pen_x;        p_line->p_glyph_pos[ i ].y = i_pen_y;        i_error = FT_Load_Glyph( p_face, i_glyph_index, FT_LOAD_DEFAULT );        if( i_error )        {            msg_Err( p_filter,                   "unable to render text FT_Load_Glyph returned %d", i_error );            p_line->pp_glyphs[ i ] = NULL;            return VLC_EGENERIC;        }        i_error = FT_Get_Glyph( p_face->glyph, &tmp_glyph );        if( i_error )        {            msg_Err( p_filter,                    "unable to render text FT_Get_Glyph returned %d", i_error );            p_line->pp_glyphs[ i ] = NULL;            return VLC_EGENERIC;        }        FT_Glyph_Get_CBox( tmp_glyph, ft_glyph_bbox_pixels, &glyph_size );        i_error = FT_Glyph_To_Bitmap( &tmp_glyph, FT_RENDER_MODE_NORMAL, 0, 1);        if( i_error )        {            FT_Done_Glyph( tmp_glyph );            continue;        }        if( b_uline )        {            float aOffset = FT_FLOOR(FT_MulFix(p_face->underline_position,                                               p_face->size->metrics.y_scale));            float aSize = FT_CEIL(FT_MulFix(p_face->underline_thickness,                                            p_face->size->metrics.y_scale));            p_line->pi_underline_offset[ i ]  =                                       ( aOffset < 0 ) ? -aOffset : aOffset;            p_line->pi_underline_thickness[ i ] =                                       ( aSize < 0 ) ? -aSize   : aSize;        }        p_line->pp_glyphs[ i ] = (FT_BitmapGlyph)tmp_glyph;        p_line->p_fg_rgb[ i ] = i_font_color & 0x00ffffff;        p_line->p_bg_rgb[ i ] = i_karaoke_bgcolor & 0x00ffffff;        p_line->p_fg_bg_ratio[ i ] = 0x00;        line.xMax = p_line->p_glyph_pos[i].x + glyph_size.xMax -                    glyph_size.xMin + ((FT_BitmapGlyph)tmp_glyph)->left;        if( line.xMax > (int)p_filter->fmt_out.video.i_visible_width - 20 )        {            while( --i > *pi_start )            {                FT_Done_Glyph( (FT_Glyph)p_line->pp_glyphs[ i ] );            }            while( psz_unicode > psz_unicode_start && *psz_unicode != ' ' )            {                psz_unicode--;            }            if( psz_unicode == psz_unicode_start )            {                if( b_first_on_line )                {                    msg_Warn( p_filter, "unbreakable string" );                    p_line->pp_glyphs[ i ] = NULL;                    return VLC_EGENERIC;                }                *pi_pen_x = i_pen_x_start;                p_line->i_width = line.xMax;                p_line->i_height = __MAX( p_line->i_height,                                          p_face->size->metrics.height >> 6 );                p_line->pp_glyphs[ i ] = NULL;                p_result->x = __MAX( p_result->x, line.xMax );                p_result->y = __MAX( p_result->y, __MAX( p_line->i_height,                                                         i_yMax - i_yMin ) );                *pi_start = i;                return VLC_SUCCESS;            }            else            {                *psz_unicode = '\n';            }            psz_unicode = psz_unicode_start;            *pi_pen_x = i_pen_x_start;            i_previous = 0;            line.yMax = i_yMax;            line.yMin = i_yMin;            continue;        }        line.yMax = __MAX( line.yMax, glyph_size.yMax );        line.yMin = __MIN( line.yMin, glyph_size.yMin );        i_previous = i_glyph_index;        *pi_pen_x += p_face->glyph->advance.x >> 6;        i++;    }    p_line->i_width = line.xMax;    p_line->i_height = __MAX( p_line->i_height,                              p_face->size->metrics.height >> 6 );    p_line->pp_glyphs[ i ] = NULL;    p_result->x = __MAX( p_result->x, line.xMax );    p_result->y = __MAX( p_result->y, __MAX( p_line->i_height,                         line.yMax - line.yMin ) );    *pi_start = i;    /* Get rid of any text processed - if necessary repositioning     * at the start of a new line of text     */    if( !*psz_unicode )    {        *psz_unicode_start = '\0';    }    else if( psz_unicode > psz_unicode_start )    {        for( i=0; psz_unicode[ i ]; i++ )            psz_unicode_start[ i ] = psz_unicode[ i ];        psz_unicode_start[ i ] = '\0';    }    return VLC_SUCCESS;}static int HandleFontAttributes( xml_reader_t *p_xml_reader,                                  font_stack_t **p_fonts, int i_scale ){    int        rv;    char      *psz_fontname = NULL;    uint32_t   i_font_color = 0xffffff;    int        i_font_alpha = 0;    uint32_t   i_karaoke_bg_color = 0x00ffffff;    int        i_font_size  = 24;    /* Default all attributes to the top font in the stack -- in case not     * all attributes are specified in the sub-font     */    if( VLC_SUCCESS == PeekFont( p_fonts,                                 &psz_fontname,                                 &i_font_size,                                 &i_font_color,                                 &i_karaoke_bg_color ))    {        psz_fontname = strdup( psz_fontname );        i_font_size = i_font_size * 1000 / i_scale;    }    i_font_alpha = (i_font_color >> 24) & 0xff;    i_font_color &= 0x00ffffff;    while ( xml_ReaderNextAttr( p_xml_reader ) == VLC_SUCCESS )    {        char *psz_name = xml_ReaderName( p_xml_reader );        char *psz_value = xml_ReaderValue( p_xml_reader );        if( psz_name && psz_value )        {            if( !strcasecmp( "face", psz_name ) )            {                free( psz_fontname );                psz_fontname = strdup( psz_value );            }            else if( !strcasecmp( "size", psz_name ) )            {                if( ( *psz_value == '+' ) || ( *psz_value == '-' ) )                {                    int i_value = atoi( psz_value );                    if( ( i_value >= -5 ) && ( i_value <= 5 ) )                        i_font_size += ( i_value * i_font_size ) / 10;                    else if( i_value < -5 )                        i_font_size = - i_value;                    else if( i_value > 5 )                        i_font_size = i_value;                }                else                    i_font_size = atoi( psz_value );            }            else if( !strcasecmp( "color", psz_name )  &&                     ( psz_value[0] == '#' ) )            {                i_font_color = strtol( psz_value + 1, NULL, 16 );                i_font_color &= 0x00ffffff;            }            else if( !strcasecmp( "alpha", psz_name ) &&                     ( psz_value[0] == '#' ) )            {                i_font_alpha = strtol( psz_value + 1, NULL, 16 );                i_font_alpha &= 0xff;            }        }        free( psz_name );        free( psz_value );    }    rv = PushFont( p_fonts,                   psz_fontname,                   i_font_size * i_scale / 100

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -