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

📄 freetype.c

📁 VLC Player Source Code
💻 C
📖 第 1 页 / 共 5 页
字号:
    p_sys->i_use_kerning = FT_HAS_KERNING( p_sys->p_face );    var_Get( p_filter, "freetype-fontsize", &val );    p_sys->i_default_font_size = val.i_int;    if( SetFontSize( p_filter, 0 ) != VLC_SUCCESS ) goto error;    free( psz_fontfile );    p_sys->pp_font_attachments = NULL;    p_sys->i_font_attachments = 0;    p_filter->pf_render_text = RenderText;#ifdef HAVE_FONTCONFIG    p_filter->pf_render_html = RenderHtml;#else    p_filter->pf_render_html = NULL;#endif    LoadFontsFromAttachments( p_filter );    return VLC_SUCCESS; error:    if( p_sys->p_face ) FT_Done_Face( p_sys->p_face );    if( p_sys->p_library ) FT_Done_FreeType( p_sys->p_library );    free( psz_fontfile );    free( p_sys );    return VLC_EGENERIC;}/***************************************************************************** * Destroy: destroy Clone video thread output method ***************************************************************************** * Clean up all data and library connections *****************************************************************************/static void Destroy( vlc_object_t *p_this ){    filter_t *p_filter = (filter_t *)p_this;    filter_sys_t *p_sys = p_filter->p_sys;    if( p_sys->pp_font_attachments )    {        int   k;        for( k = 0; k < p_sys->i_font_attachments; k++ )            vlc_input_attachment_Delete( p_sys->pp_font_attachments[k] );        free( p_sys->pp_font_attachments );    }#ifdef HAVE_FONTCONFIG    FontBuilderDetach( p_filter, p_sys->p_fontbuilder );#endif    /* FcFini asserts calling the subfunction FcCacheFini()     * even if no other library functions have been made since FcInit(),     * so don't call it. */    FT_Done_Face( p_sys->p_face );    FT_Done_FreeType( p_sys->p_library );    free( p_sys );}#ifdef HAVE_FONTCONFIGstatic vlc_object_t *FontBuilderAttach( filter_t *p_filter, vlc_mutex_t **pp_lock ){    /* Check for an existing Fontbuilder thread */    vlc_mutex_t *p_lock = var_AcquireMutex( "fontbuilder" );    vlc_object_t *p_fontbuilder =        vlc_object_find_name( p_filter->p_libvlc,                              "fontlist builder", FIND_CHILD );    if( !p_fontbuilder )    {        /* Create the FontBuilderThread thread as a child of a top-level         * object, so that it can survive the destruction of the         * freetype object - the fontlist only needs to be built once,         * and calling the fontbuild a second time while the first is         * still in progress can cause thread instabilities.         *         * XXX The fontbuilder will be destroy as soon as it is unused.         */        p_fontbuilder = vlc_object_create( p_filter->p_libvlc,                                           sizeof(vlc_object_t) );        if( p_fontbuilder )        {            p_fontbuilder->psz_object_name = strdup( "fontlist builder" );            p_fontbuilder->p_private = NULL;            vlc_object_set_destructor( p_fontbuilder, FontBuilderDestructor );            vlc_object_attach( p_fontbuilder, p_filter->p_libvlc );            var_Create( p_fontbuilder, "build-done", VLC_VAR_BOOL );            var_SetBool( p_fontbuilder, "build-done", false );            if( vlc_thread_create( p_fontbuilder,                                   "fontlist builder",                                   FontBuilderThread,                                   VLC_THREAD_PRIORITY_LOW,                                   false ) )            {                msg_Warn( p_filter, "fontconfig database builder thread can't "                        "be launched. Font styling support will be limited." );            }        }    }    if( p_fontbuilder )    {        var_AddCallback( p_fontbuilder, "build-done", FontBuilderDone, p_filter );        FontBuilderGetFcConfig( p_filter, p_fontbuilder );    }    vlc_mutex_unlock( p_lock );    *pp_lock = p_lock;    return p_fontbuilder;}static void FontBuilderDetach( filter_t *p_filter, vlc_object_t *p_fontbuilder ){    vlc_mutex_t *lock = var_AcquireMutex( "fontbuilder" );    if( p_fontbuilder )    {        const bool b_alive = vlc_object_alive( p_fontbuilder );        var_DelCallback( p_fontbuilder, "build-done", FontBuilderDone, p_filter );        /* We wait for the thread on the first FontBuilderDetach */        if( b_alive )        {            vlc_object_kill( p_fontbuilder );            vlc_mutex_unlock( lock );            /* We need to unlock otherwise we may not join (the thread waiting             * for the lock). It is safe to unlock as no one else will try a             * join and we have a reference on the object) */            vlc_thread_join( p_fontbuilder );            vlc_mutex_lock( lock );        }        vlc_object_release( p_fontbuilder );    }    vlc_mutex_unlock( lock );}static void* FontBuilderThread( vlc_object_t *p_this ){    FcConfig      *p_fontconfig = FcInitLoadConfig();    vlc_thread_ready( p_this );    if( p_fontconfig )    {        mtime_t    t1, t2;        //msg_Dbg( p_this, "Building font database..." );        msg_Dbg( p_this, "Building font database..." );        t1 = mdate();        if(! FcConfigBuildFonts( p_fontconfig ))        {            /* Don't destroy the fontconfig object - we won't be able to do             * italics or bold or change the font face, but we will still             * be able to do underline and change the font size.             */            msg_Err( p_this, "fontconfig database can't be built. "                                    "Font styling won't be available" );        }        t2 = mdate();        msg_Dbg( p_this, "Finished building font database." );        msg_Dbg( p_this, "Took %ld seconds", (long)((t2 - t1)/1000000) );        vlc_mutex_t *p_lock = var_AcquireMutex( "fontbuilder" );        p_this->p_private = p_fontconfig;        vlc_mutex_unlock( p_lock );        var_SetBool( p_this, "build-done", true );    }    return NULL;}static void FontBuilderGetFcConfig( filter_t *p_filter, vlc_object_t *p_fontbuilder ){    filter_sys_t *p_sys = p_filter->p_sys;    p_sys->p_fontconfig = p_fontbuilder->p_private;    p_sys->b_fontconfig_ok = p_fontbuilder->p_private != NULL;}static void FontBuilderDestructor( vlc_object_t *p_this ){    FcConfig *p_fontconfig = p_this->p_private;    if( p_fontconfig )        FcConfigDestroy( p_fontconfig );}static int FontBuilderDone( vlc_object_t *p_this, const char *psz_var,                       vlc_value_t oldval, vlc_value_t newval, void *param ){    filter_t *p_filter = param;    if( newval.b_bool )    {        vlc_mutex_t *p_lock = var_AcquireMutex( "fontbuilder" );        FontBuilderGetFcConfig( p_filter, p_this );        vlc_mutex_unlock( p_lock );    }    VLC_UNUSED(psz_var);    VLC_UNUSED(oldval);    return VLC_SUCCESS;}#endif/***************************************************************************** * Make any TTF/OTF fonts present in the attachments of the media file * and store them for later use by the FreeType Engine *****************************************************************************/static int LoadFontsFromAttachments( filter_t *p_filter ){    filter_sys_t         *p_sys = p_filter->p_sys;    input_thread_t       *p_input;    input_attachment_t  **pp_attachments;    int                   i_attachments_cnt;    int                   k;    int                   rv = VLC_SUCCESS;    p_input = (input_thread_t *)vlc_object_find( p_filter, VLC_OBJECT_INPUT, FIND_PARENT );    if( ! p_input )        return VLC_EGENERIC;    if( VLC_SUCCESS != input_Control( p_input, INPUT_GET_ATTACHMENTS, &pp_attachments, &i_attachments_cnt ))    {        vlc_object_release(p_input);        return VLC_EGENERIC;    }    p_sys->i_font_attachments = 0;    p_sys->pp_font_attachments = malloc( i_attachments_cnt * sizeof( input_attachment_t * ));    if(! p_sys->pp_font_attachments )        rv = VLC_ENOMEM;    for( k = 0; k < i_attachments_cnt; k++ )    {        input_attachment_t *p_attach = pp_attachments[k];        if( p_sys->pp_font_attachments )        {            if(( !strcmp( p_attach->psz_mime, "application/x-truetype-font" ) || // TTF                 !strcmp( p_attach->psz_mime, "application/x-font-otf" ) ) &&    // OTF               ( p_attach->i_data > 0 ) &&               ( p_attach->p_data != NULL ) )            {                p_sys->pp_font_attachments[ p_sys->i_font_attachments++ ] = p_attach;            }            else            {                vlc_input_attachment_Delete( p_attach );            }        }        else        {            vlc_input_attachment_Delete( p_attach );        }    }    free( pp_attachments );    vlc_object_release(p_input);    return rv;}/***************************************************************************** * Render: place string in picture ***************************************************************************** * This function merges the previously rendered freetype glyphs into a picture *****************************************************************************/static int Render( filter_t *p_filter, subpicture_region_t *p_region,                   line_desc_t *p_line, int i_width, int i_height ){    static const uint8_t pi_gamma[16] =        {0x00, 0x52, 0x84, 0x96, 0xb8, 0xca, 0xdc, 0xee, 0xff,          0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};    uint8_t *p_dst;    video_format_t fmt;    int i, x, y, i_pitch;    uint8_t i_y; /* YUV values, derived from incoming RGB */    int8_t i_u, i_v;    subpicture_region_t *p_region_tmp;    /* Create a new subpicture region */    memset( &fmt, 0, sizeof(video_format_t) );    fmt.i_chroma = VLC_FOURCC('Y','U','V','P');    fmt.i_aspect = 0;    fmt.i_width = fmt.i_visible_width = i_width + 4;    fmt.i_height = fmt.i_visible_height = i_height + 4;    if( p_region->fmt.i_visible_width > 0 )        fmt.i_visible_width = p_region->fmt.i_visible_width;    if( p_region->fmt.i_visible_height > 0 )        fmt.i_visible_height = p_region->fmt.i_visible_height;    fmt.i_x_offset = fmt.i_y_offset = 0;    p_region_tmp = spu_CreateRegion( p_filter, &fmt );    if( !p_region_tmp )    {        msg_Err( p_filter, "cannot allocate SPU region" );        return VLC_EGENERIC;    }    p_region->fmt = p_region_tmp->fmt;    p_region->picture = p_region_tmp->picture;    free( p_region_tmp );    /* Calculate text color components */    i_y = (uint8_t)(( 66 * p_line->i_red  + 129 * p_line->i_green +                      25 * p_line->i_blue + 128) >> 8) +  16;    i_u = (int8_t)(( -38 * p_line->i_red  -  74 * p_line->i_green +                     112 * p_line->i_blue + 128) >> 8) + 128;    i_v = (int8_t)(( 112 * p_line->i_red  -  94 * p_line->i_green -                      18 * p_line->i_blue + 128) >> 8) + 128;    /* Build palette */    fmt.p_palette->i_entries = 16;    for( i = 0; i < 8; i++ )    {        fmt.p_palette->palette[i][0] = 0;        fmt.p_palette->palette[i][1] = 0x80;        fmt.p_palette->palette[i][2] = 0x80;        fmt.p_palette->palette[i][3] = pi_gamma[i];        fmt.p_palette->palette[i][3] =            (int)fmt.p_palette->palette[i][3] * (255 - p_line->i_alpha) / 255;    }    for( i = 8; i < fmt.p_palette->i_entries; i++ )    {        fmt.p_palette->palette[i][0] = i * 16 * i_y / 256;        fmt.p_palette->palette[i][1] = i_u;        fmt.p_palette->palette[i][2] = i_v;        fmt.p_palette->palette[i][3] = pi_gamma[i];        fmt.p_palette->palette[i][3] =            (int)fmt.p_palette->palette[i][3] * (255 - p_line->i_alpha) / 255;    }    p_dst = p_region->picture.Y_PIXELS;    i_pitch = p_region->picture.Y_PITCH;    /* Initialize the region pixels */    memset( p_dst, 0, i_pitch * p_region->fmt.i_height );    for( ; p_line != NULL; p_line = p_line->p_next )    {        int i_glyph_tmax = 0;        int i_bitmap_offset, i_offset, i_align_offset = 0;        for( i = 0; p_line->pp_glyphs[i] != NULL; i++ )        {            FT_BitmapGlyph p_glyph = p_line->pp_glyphs[ i ];            i_glyph_tmax = __MAX( i_glyph_tmax, p_glyph->top );        }        if( p_line->i_width < i_width )        {            if( (p_region->i_align & 0x3) == SUBPICTURE_ALIGN_RIGHT )            {                i_align_offset = i_width - p_line->i_width;            }            else if( (p_region->i_align & 0x3) != SUBPICTURE_ALIGN_LEFT )            {                i_align_offset = ( i_width - p_line->i_width ) / 2;            }        }        for( i = 0; p_line->pp_glyphs[i] != NULL; i++ )        {            FT_BitmapGlyph p_glyph = p_line->pp_glyphs[ i ];            i_offset = ( p_line->p_glyph_pos[ i ].y +                i_glyph_tmax - p_glyph->top + 2 ) *                i_pitch + p_line->p_glyph_pos[ i ].x + p_glyph->left + 2 +                i_align_offset;

⌨️ 快捷键说明

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