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

📄 freetype.c

📁 uclinux 下的vlc播放器源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
    }    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;    }    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 )    {        msg_Err( p_filter, "out of memory" );        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_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 = psz_string;        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 (%s), "                      "bytes left %d", strerror(errno), (int)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;        int start_pos, pos = 0;        p_fribidi_string = malloc( (i_string_length + 1) * sizeof(uint32_t) );        /* 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( (byte_t *)psz_string )) )    {        msg_Err( p_filter, "out of memory" );        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( (byte_t *)psz_string )) )            {                msg_Err( p_filter, "out of memory" );                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 )        {            p_line->pp_glyphs[ i ] = NULL;            FreeLine( p_line );            p_line = NewLine( (byte_t *)psz_string );            if( p_prev ) p_prev->p_next = p_line;            else p_lines = p_line;            while( psz_unicode > psz_line_start && *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 );    if( psz_unicode_orig ) free( psz_unicode_orig );    FreeLines( p_lines );    return VLC_SUCCESS; error:    if( psz_unicode_orig ) free( psz_unicode_orig );    FreeLines( p_lines );    return VLC_EGENERIC;}static void FreeLine( line_desc_t *p_line ){    unsigned int i;    for( i = 0; p_line->pp_glyphs[ i ] != NULL; i++ )    {        FT_Done_Glyph( (FT_Glyph)p_line->pp_glyphs[ i ] );    }    free( p_line->pp_glyphs );    free( p_line->p_glyph_pos );    free( p_line );}static void FreeLines( line_desc_t *p_lines ){    line_desc_t *p_line, *p_next;    if( !p_lines ) return;    for( p_line = p_lines; p_line != NULL; p_line = p_next )    {        p_next = p_line->p_next;        FreeLine( p_line );    }}static line_desc_t *NewLine( byte_t *psz_string ){    int i_count;    line_desc_t *p_line = malloc( sizeof(line_desc_t) );    if( !p_line ) return NULL;    p_line->i_height = 0;    p_line->i_width = 0;    p_line->p_next = NULL;    /* We don't use CountUtf8Characters() here because we are not acutally     * sure the string is utf8. Better be safe than sorry. */    i_count = strlen( (char *)psz_string );    p_line->pp_glyphs = malloc( sizeof(FT_BitmapGlyph) * ( i_count + 1 ) );    if( p_line->pp_glyphs == NULL )    {        free( p_line );        return NULL;    }    p_line->pp_glyphs[0] = NULL;    p_line->p_glyph_pos = malloc( sizeof( FT_Vector ) * i_count + 1 );    if( p_line->p_glyph_pos == NULL )    {        free( p_line->pp_glyphs );        free( p_line );        return NULL;    }    return p_line;}static int SetFontSize( filter_t *p_filter, int i_size ){    filter_sys_t *p_sys = p_filter->p_sys;    if( i_size && i_size == p_sys->i_font_size ) return VLC_SUCCESS;    if( !i_size )    {        vlc_value_t val;        if( !p_sys->i_default_font_size &&            p_sys->i_display_height == (int)p_filter->fmt_out.video.i_height )            return VLC_SUCCESS;        if( p_sys->i_default_font_size )        {            i_size = p_sys->i_default_font_size;        }        else        {            var_Get( p_filter, "freetype-rel-fontsize", &val );            i_size = (int)p_filter->fmt_out.video.i_height / val.i_int;            p_filter->p_sys->i_display_height =                p_filter->fmt_out.video.i_height;        }        if( i_size <= 0 )        {            msg_Warn( p_filter, "invalid fontsize, using 12" );            i_size = 12;        }        msg_Dbg( p_filter, "using fontsize: %i", i_size );    }    p_sys->i_font_size = i_size;    if( FT_Set_Pixel_Sizes( p_sys->p_face, 0, i_size ) )    {        msg_Err( p_filter, "couldn't set font size to %d", i_size );        return VLC_EGENERIC;    }    return VLC_SUCCESS;}

⌨️ 快捷键说明

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