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

📄 freetype.c

📁 VLC Player Source Code
💻 C
📖 第 1 页 / 共 5 页
字号:
    vlc_value_t val;    int i_scale = 1000;    FT_BBox line;    FT_BBox glyph_size;    FT_Vector result;    FT_Glyph tmp_glyph;    /* Sanity check */    if( !p_region_in || !p_region_out ) return VLC_EGENERIC;    psz_string = p_region_in->psz_text;    if( !psz_string || !*psz_string ) return VLC_EGENERIC;    if( VLC_SUCCESS == var_Get( p_filter, "scale", &val ))        i_scale = val.i_int;    if( p_region_in->p_style )    {        i_font_color = __MAX( __MIN( p_region_in->p_style->i_font_color, 0xFFFFFF ), 0 );        i_font_alpha = __MAX( __MIN( p_region_in->p_style->i_font_alpha, 255 ), 0 );        i_font_size  = __MAX( __MIN( p_region_in->p_style->i_font_size, 255 ), 0 ) * i_scale / 1000;    }    else    {        i_font_color = p_sys->i_font_color;        i_font_alpha = 255 - p_sys->i_font_opacity;        i_font_size  = p_sys->i_default_font_size * i_scale / 1000;    }    if( i_font_color == 0xFFFFFF ) i_font_color = p_sys->i_font_color;    if( !i_font_alpha ) i_font_alpha = 255 - p_sys->i_font_opacity;    SetFontSize( p_filter, i_font_size );    i_red   = ( i_font_color & 0x00FF0000 ) >> 16;    i_green = ( i_font_color & 0x0000FF00 ) >>  8;    i_blue  =   i_font_color & 0x000000FF;    result.x =  result.y = 0;    line.xMin = line.xMax = line.yMin = line.yMax = 0;    psz_unicode = psz_unicode_orig =        malloc( ( strlen(psz_string) + 1 ) * sizeof(uint32_t) );    if( psz_unicode == NULL )        goto error;#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 )    {        msg_Warn( p_filter, "unable to do conversion" );        goto error;    }    {        char *p_out_buffer;        const char *p_in_buffer = psz_string;        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_out_buffer = (char *)psz_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 );            goto error;        }        *(uint32_t*)p_out_buffer = 0;        i_string_length = (i_out_bytes - i_out_bytes_left) / sizeof(uint32_t);    }#if defined(HAVE_FRIBIDI)    {        uint32_t *p_fribidi_string;        int32_t start_pos, pos = 0;        p_fribidi_string = malloc( (i_string_length + 1) * sizeof(uint32_t) );        if( !p_fribidi_string )            goto error;        /* Do bidi conversion line-by-line */        while( pos < i_string_length )        {            while( pos < i_string_length )             {                i_char = psz_unicode[pos];                if (i_char != '\r' && i_char != '\n')                    break;                p_fribidi_string[pos] = i_char;                ++pos;            }            start_pos = pos;            while( pos < i_string_length )            {                i_char = psz_unicode[pos];                if (i_char == '\r' || i_char == '\n')                    break;                ++pos;            }            if (pos > start_pos)            {                FriBidiCharType base_dir = FRIBIDI_TYPE_LTR;                fribidi_log2vis((FriBidiChar*)psz_unicode + start_pos,                                pos - start_pos,                                &base_dir,                                (FriBidiChar*)p_fribidi_string + start_pos,                                0, 0, 0);            }        }        free( psz_unicode_orig );        psz_unicode = psz_unicode_orig = p_fribidi_string;        p_fribidi_string[ i_string_length ] = 0;    }#endif    /* Calculate relative glyph positions and a bounding box for the     * entire string */    if( !(p_line = NewLine( strlen( psz_string ))) )        goto error;    p_lines = p_line;    i_pen_x = i_pen_y = 0;    i_previous = i = 0;    psz_line_start = psz_unicode;#define face p_sys->p_face#define glyph face->glyph    while( *psz_unicode )    {        i_char = *psz_unicode++;        if( i_char == '\r' ) /* ignore CR chars wherever they may be */        {            continue;        }        if( i_char == '\n' )        {            psz_line_start = psz_unicode;            if( !(p_next = NewLine( strlen( psz_string ))) )                goto error;            p_line->p_next = p_next;            p_line->i_width = line.xMax;            p_line->i_height = face->size->metrics.height >> 6;            p_line->pp_glyphs[ i ] = NULL;            p_line->i_alpha = i_font_alpha;            p_line->i_red = i_red;            p_line->i_green = i_green;            p_line->i_blue = i_blue;            p_prev = p_line;            p_line = p_next;            result.x = __MAX( result.x, line.xMax );            result.y += face->size->metrics.height >> 6;            i_pen_x = 0;            i_previous = i = 0;            line.xMin = line.xMax = line.yMin = line.yMax = 0;            i_pen_y += face->size->metrics.height >> 6;#if 0            msg_Dbg( p_filter, "Creating new line, i is %d", i );#endif            continue;        }        i_glyph_index = FT_Get_Char_Index( face, i_char );        if( p_sys->i_use_kerning && i_glyph_index            && i_previous )        {            FT_Vector delta;            FT_Get_Kerning( face, i_previous, i_glyph_index,                            ft_kerning_default, &delta );            i_pen_x += delta.x >> 6;        }        p_line->p_glyph_pos[ i ].x = i_pen_x;        p_line->p_glyph_pos[ i ].y = i_pen_y;        i_error = FT_Load_Glyph( 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 );            goto error;        }        i_error = FT_Get_Glyph( glyph, &tmp_glyph );        if( i_error )        {            msg_Err( p_filter, "unable to render text FT_Get_Glyph returned "                               "%d", i_error );            goto error;        }        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;        }        p_line->pp_glyphs[ i ] = (FT_BitmapGlyph)tmp_glyph;        /* Do rest */        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 )        {            FT_Done_Glyph( (FT_Glyph)p_line->pp_glyphs[ i ] );            p_line->pp_glyphs[ i ] = NULL;            FreeLine( p_line );            p_line = NewLine( strlen( psz_string ));            if( p_prev ) p_prev->p_next = p_line;            else p_lines = p_line;            uint32_t *psz_unicode_saved = psz_unicode;            while( psz_unicode > psz_line_start && *psz_unicode != ' ' )            {                psz_unicode--;            }            if( psz_unicode == psz_line_start )            {   /* try harder to break that line */                psz_unicode = psz_unicode_saved;                while( psz_unicode > psz_line_start &&                    *psz_unicode != '_'  && *psz_unicode != '/' &&                    *psz_unicode != '\\' && *psz_unicode != '.' )                {                    psz_unicode--;                }            }            if( psz_unicode == psz_line_start )            {                msg_Warn( p_filter, "unbreakable string" );                goto error;            }            else            {                *psz_unicode = '\n';            }            psz_unicode = psz_line_start;            i_pen_x = 0;            i_previous = i = 0;            line.xMin = line.xMax = line.yMin = line.yMax = 0;            continue;        }        line.yMax = __MAX( line.yMax, glyph_size.yMax );        line.yMin = __MIN( line.yMin, glyph_size.yMin );        i_previous = i_glyph_index;        i_pen_x += glyph->advance.x >> 6;        i++;    }    p_line->i_width = line.xMax;    p_line->i_height = face->size->metrics.height >> 6;    p_line->pp_glyphs[ i ] = NULL;    p_line->i_alpha = i_font_alpha;    p_line->i_red = i_red;    p_line->i_green = i_green;    p_line->i_blue = i_blue;    result.x = __MAX( result.x, line.xMax );    result.y += line.yMax - line.yMin;#undef face#undef glyph    p_region_out->i_x = p_region_in->i_x;    p_region_out->i_y = p_region_in->i_y;    if( config_GetInt( p_filter, "freetype-yuvp" ) )        Render( p_filter, p_region_out, p_lines, result.x, result.y );    else        RenderYUVA( p_filter, p_region_out, p_lines, result.x, result.y );    free( psz_unicode_orig );    FreeLines( p_lines );    return VLC_SUCCESS; error:    free( psz_unicode_orig );    FreeLines( p_lines );    return VLC_EGENERIC;}#ifdef HAVE_FONTCONFIGstatic ft_style_t *CreateStyle( char *psz_fontname, int i_font_size,        uint32_t i_font_color, uint32_t i_karaoke_bg_color, bool b_bold,        bool b_italic, bool b_uline ){    ft_style_t  *p_style = malloc( sizeof( ft_style_t ));    if( p_style )    {        p_style->i_font_size        = i_font_size;        p_style->i_font_color       = i_font_color;        p_style->i_karaoke_bg_color = i_karaoke_bg_color;        p_style->b_italic           = b_italic;        p_style->b_bold             = b_bold;        p_style->b_underline        = b_uline;        p_style->psz_fontname = strdup( psz_fontname );    }    return p_style;}static void DeleteStyle( ft_style_t *p_style ){    if( p_style )    {        free( p_style->psz_fontname );        free( p_style );    }}static bool StyleEquals( ft_style_t *s1, ft_style_t *s2 ){    if( !s1 || !s2 )        return false;    if( s1 == s2 )        return true;    if(( s1->i_font_size  == s2->i_font_size ) &&       ( s1->i_font_color == s2->i_font_color ) &&       ( s1->b_italic     == s2->b_italic ) &&       ( s1->b_bold       == s2->b_bold ) &&       ( s1->b_underline  == s2->b_underline ) &&       ( !strcmp( s1->psz_fontname, s2->psz_fontname )))    {        return true;    }    return false;}static int PushFont( font_stack_t **p_font, const char *psz_name, int i_size,                     uint32_t i_color, uint32_t i_karaoke_bg_color ){    font_stack_t *p_new;    if( !p_font )        return VLC_EGENERIC;    p_new = malloc( sizeof( font_stack_t ) );    if( ! p_new )        return VLC_ENOMEM;    p_new->p_next = NULL;    if( psz_name )        p_new->psz_name = strdup( psz_name );    else        p_new->psz_name = NULL;    p_new->i_size              = i_size;    p_new->i_color             = i_color;    p_new->i_karaoke_bg_color  = i_karaoke_bg_color;    if( !*p_font )    {        *p_font = p_new;    }    else    {        font_stack_t *p_last;        for( p_last = *p_font;             p_last->p_next;             p_last = p_last->p_next )        ;        p_last->p_next = p_new;    }    return VLC_SUCCESS;}

⌨️ 快捷键说明

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