📄 freetype.c
字号:
/***************************************************************************** * freetype.c : Put text on the video, using freetype2 ***************************************************************************** * Copyright (C) 2002 - 2007 the VideoLAN team * $Id: 8d42bc0fafc2efd50558b662850faa8292a3db24 $ * * Authors: Sigmund Augdal Helberg <dnumgis@videolan.org> * Gildas Bazin <gbazin@videolan.org> * Bernie Purcell <bitmap@videolan.org> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. *****************************************************************************//***************************************************************************** * Preamble *****************************************************************************/#ifdef HAVE_CONFIG_H# include "config.h"#endif#include <vlc_common.h>#include <vlc_plugin.h>#include <vlc_vout.h>#include <vlc_osd.h>#include <vlc_block.h>#include <vlc_filter.h>#include <vlc_stream.h>#include <vlc_xml.h>#include <vlc_input.h>#include <math.h>#include <errno.h>#include <ft2build.h>#include FT_FREETYPE_H#include FT_GLYPH_H#define FT_FLOOR(X) ((X & -64) >> 6)#define FT_CEIL(X) (((X + 63) & -64) >> 6)#define FT_MulFix(v, s) (((v)*(s))>>16)#ifdef __APPLE__#define DEFAULT_FONT "/System/Library/Fonts/LucidaGrande.dfont"#define FC_DEFAULT_FONT "Lucida Grande"#elif defined( SYS_BEOS )#define DEFAULT_FONT "/boot/beos/etc/fonts/ttfonts/Swiss721.ttf"#define FC_DEFAULT_FONT "Swiss"#elif defined( WIN32 )#define DEFAULT_FONT "" /* Default font found at run-time */#define FC_DEFAULT_FONT "Arial"#else#define DEFAULT_FONT "/usr/share/fonts/truetype/freefont/FreeSerifBold.ttf"#define FC_DEFAULT_FONT "Serif Bold"#endif#if defined(HAVE_FRIBIDI)#include <fribidi/fribidi.h>#endif#ifdef HAVE_FONTCONFIG#include <fontconfig/fontconfig.h>#endif#include <assert.h>/***************************************************************************** * Module descriptor *****************************************************************************/static int Create ( vlc_object_t * );static void Destroy( vlc_object_t * );#define FONT_TEXT N_("Font")#define FONT_LONGTEXT N_("Filename for the font you want to use")#define FONTSIZE_TEXT N_("Font size in pixels")#define FONTSIZE_LONGTEXT N_("This is the default size of the fonts " \ "that will be rendered on the video. " \ "If set to something different than 0 this option will override the " \ "relative font size." )#define OPACITY_TEXT N_("Opacity")#define OPACITY_LONGTEXT N_("The opacity (inverse of transparency) of the " \ "text that will be rendered on the video. 0 = transparent, " \ "255 = totally opaque. " )#define COLOR_TEXT N_("Text default color")#define COLOR_LONGTEXT N_("The color of the text that will be rendered on "\ "the video. This must be an hexadecimal (like HTML colors). The first two "\ "chars are for red, then green, then blue. #000000 = black, #FF0000 = red,"\ " #00FF00 = green, #FFFF00 = yellow (red + green), #FFFFFF = white" )#define FONTSIZER_TEXT N_("Relative font size")#define FONTSIZER_LONGTEXT N_("This is the relative default size of the " \ "fonts that will be rendered on the video. If absolute font size is set, "\ "relative size will be overriden." )static const int pi_sizes[] = { 20, 18, 16, 12, 6 };static const char *const ppsz_sizes_text[] = { N_("Smaller"), N_("Small"), N_("Normal"), N_("Large"), N_("Larger") };#define YUVP_TEXT N_("Use YUVP renderer")#define YUVP_LONGTEXT N_("This renders the font using \"paletized YUV\". " \ "This option is only needed if you want to encode into DVB subtitles" )#define EFFECT_TEXT N_("Font Effect")#define EFFECT_LONGTEXT N_("It is possible to apply effects to the rendered " \"text to improve its readability." )#define EFFECT_BACKGROUND 1#define EFFECT_OUTLINE 2#define EFFECT_OUTLINE_FAT 3static int const pi_effects[] = { 1, 2, 3 };static const char *const ppsz_effects_text[] = { N_("Background"),N_("Outline"), N_("Fat Outline") };static const int pi_color_values[] = { 0x00000000, 0x00808080, 0x00C0C0C0, 0x00FFFFFF, 0x00800000, 0x00FF0000, 0x00FF00FF, 0x00FFFF00, 0x00808000, 0x00008000, 0x00008080, 0x0000FF00, 0x00800080, 0x00000080, 0x000000FF, 0x0000FFFF };static const char *const ppsz_color_descriptions[] = { N_("Black"), N_("Gray"), N_("Silver"), N_("White"), N_("Maroon"), N_("Red"), N_("Fuchsia"), N_("Yellow"), N_("Olive"), N_("Green"), N_("Teal"), N_("Lime"), N_("Purple"), N_("Navy"), N_("Blue"), N_("Aqua") };vlc_module_begin(); set_shortname( N_("Text renderer")); set_description( N_("Freetype2 font renderer") ); set_category( CAT_VIDEO ); set_subcategory( SUBCAT_VIDEO_SUBPIC ); add_file( "freetype-font", DEFAULT_FONT, NULL, FONT_TEXT, FONT_LONGTEXT, false ); add_integer( "freetype-fontsize", 0, NULL, FONTSIZE_TEXT, FONTSIZE_LONGTEXT, true ); /* opacity valid on 0..255, with default 255 = fully opaque */ add_integer_with_range( "freetype-opacity", 255, 0, 255, NULL, OPACITY_TEXT, OPACITY_LONGTEXT, true ); /* hook to the color values list, with default 0x00ffffff = white */ add_integer( "freetype-color", 0x00FFFFFF, NULL, COLOR_TEXT, COLOR_LONGTEXT, false ); change_integer_list( pi_color_values, ppsz_color_descriptions, NULL ); add_integer( "freetype-rel-fontsize", 16, NULL, FONTSIZER_TEXT, FONTSIZER_LONGTEXT, false ); change_integer_list( pi_sizes, ppsz_sizes_text, NULL ); add_integer( "freetype-effect", 2, NULL, EFFECT_TEXT, EFFECT_LONGTEXT, false ); change_integer_list( pi_effects, ppsz_effects_text, NULL ); add_bool( "freetype-yuvp", 0, NULL, YUVP_TEXT, YUVP_LONGTEXT, true ); set_capability( "text renderer", 100 ); add_shortcut( "text" ); set_callbacks( Create, Destroy );vlc_module_end();/***************************************************************************** * Local prototypes *****************************************************************************//* The RenderText call maps to pf_render_string, defined in vlc_filter.h */static int RenderText( filter_t *, subpicture_region_t *, subpicture_region_t * );#ifdef HAVE_FONTCONFIGstatic int RenderHtml( filter_t *, subpicture_region_t *, subpicture_region_t * );static char *FontConfig_Select( FcConfig *, const char *, bool, bool, int * );#endifstatic int LoadFontsFromAttachments( filter_t *p_filter );static int GetFontSize( filter_t *p_filter );static int SetFontSize( filter_t *, int );static void YUVFromRGB( uint32_t i_argb, uint8_t *pi_y, uint8_t *pi_u, uint8_t *pi_v );typedef struct line_desc_t line_desc_t;struct line_desc_t{ /** NULL-terminated list of glyphs making the string */ FT_BitmapGlyph *pp_glyphs; /** list of relative positions for the glyphs */ FT_Vector *p_glyph_pos; /** list of RGB information for styled text * -- if the rendering mode supports it (RenderYUVA) and * b_new_color_mode is set, then it becomes possible to * have multicoloured text within the subtitles. */ uint32_t *p_fg_rgb; uint32_t *p_bg_rgb; uint8_t *p_fg_bg_ratio; /* 0x00=100% FG --> 0x7F=100% BG */ bool b_new_color_mode; /** underline information -- only supplied if text should be underlined */ uint16_t *pi_underline_offset; uint16_t *pi_underline_thickness; int i_height; int i_width; int i_red, i_green, i_blue; int i_alpha; line_desc_t *p_next;};static line_desc_t *NewLine( int );typedef struct font_stack_t font_stack_t;struct font_stack_t{ char *psz_name; int i_size; uint32_t i_color; /* ARGB */ uint32_t i_karaoke_bg_color; /* ARGB */ font_stack_t *p_next;};typedef struct{ int i_font_size; uint32_t i_font_color; /* ARGB */ uint32_t i_karaoke_bg_color; /* ARGB */ bool b_italic; bool b_bold; bool b_underline; char *psz_fontname;} ft_style_t;static int Render( filter_t *, subpicture_region_t *, line_desc_t *, int, int);static void FreeLines( line_desc_t * );static void FreeLine( line_desc_t * );#ifdef HAVE_FONTCONFIGstatic vlc_object_t *FontBuilderAttach( filter_t *p_filter, vlc_mutex_t **pp_lock );static void FontBuilderDetach( filter_t *p_filter, vlc_object_t *p_fontbuilder );static void* FontBuilderThread( vlc_object_t *p_this);static void FontBuilderDestructor( vlc_object_t *p_this );static void FontBuilderGetFcConfig( filter_t *p_filter, vlc_object_t *p_fontbuilder );static int FontBuilderDone( vlc_object_t*, const char *, vlc_value_t, vlc_value_t, void* );#endif/***************************************************************************** * filter_sys_t: freetype local data ***************************************************************************** * This structure is part of the video output thread descriptor. * It describes the freetype specific properties of an output thread. *****************************************************************************/struct filter_sys_t{ FT_Library p_library; /* handle to library */ FT_Face p_face; /* handle to face object */ bool i_use_kerning; uint8_t i_font_opacity; int i_font_color; int i_font_size; int i_effect; int i_default_font_size; int i_display_height;#ifdef HAVE_FONTCONFIG vlc_mutex_t *p_fontconfig_lock; bool b_fontconfig_ok; FcConfig *p_fontconfig;#endif input_attachment_t **pp_font_attachments; int i_font_attachments; vlc_object_t *p_fontbuilder;};/***************************************************************************** * Create: allocates osd-text video thread output method ***************************************************************************** * This function allocates and initializes a Clone vout method. *****************************************************************************/static int Create( vlc_object_t *p_this ){ filter_t *p_filter = (filter_t *)p_this; filter_sys_t *p_sys; char *psz_fontfile = NULL; int i_error; vlc_value_t val; /* Allocate structure */ p_filter->p_sys = p_sys = malloc( sizeof( filter_sys_t ) ); if( !p_sys ) return VLC_ENOMEM; p_sys->p_face = 0; p_sys->p_library = 0; p_sys->i_font_size = 0; p_sys->i_display_height = 0; var_Create( p_filter, "freetype-font", VLC_VAR_STRING | VLC_VAR_DOINHERIT ); var_Create( p_filter, "freetype-fontsize", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT ); var_Create( p_filter, "freetype-rel-fontsize", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT ); var_Create( p_filter, "freetype-opacity", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT ); var_Create( p_filter, "freetype-effect", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT ); var_Get( p_filter, "freetype-opacity", &val ); p_sys->i_font_opacity = __MAX( __MIN( val.i_int, 255 ), 0 ); var_Create( p_filter, "freetype-color", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT ); var_Get( p_filter, "freetype-color", &val ); p_sys->i_font_color = __MAX( __MIN( val.i_int, 0xFFFFFF ), 0 ); p_sys->i_effect = var_GetInteger( p_filter, "freetype-effect" ); /* Look what method was requested */ var_Get( p_filter, "freetype-font", &val ); psz_fontfile = val.psz_string; if( !psz_fontfile || !*psz_fontfile ) { free( psz_fontfile ); psz_fontfile = (char *)malloc( PATH_MAX + 1 ); if( !psz_fontfile ) goto error;#ifdef WIN32 GetWindowsDirectory( psz_fontfile, PATH_MAX + 1 ); strcat( psz_fontfile, "\\fonts\\arial.ttf" );#elif defined(__APPLE__) strcpy( psz_fontfile, DEFAULT_FONT );#else msg_Err( p_filter, "user didn't specify a font" ); goto error;#endif } i_error = FT_Init_FreeType( &p_sys->p_library ); if( i_error ) { msg_Err( p_filter, "couldn't initialize freetype" ); goto error; } i_error = FT_New_Face( p_sys->p_library, psz_fontfile ? psz_fontfile : "", 0, &p_sys->p_face ); if( i_error == FT_Err_Unknown_File_Format ) { msg_Err( p_filter, "file %s have unknown format", psz_fontfile ); goto error; } else if( i_error ) { msg_Err( p_filter, "failed to load font file %s", psz_fontfile ); goto error; } i_error = FT_Select_Charmap( p_sys->p_face, ft_encoding_unicode ); if( i_error ) { msg_Err( p_filter, "font has no unicode translation table" ); goto error; }#ifdef HAVE_FONTCONFIG p_sys->b_fontconfig_ok = false; p_sys->p_fontconfig = NULL; p_sys->p_fontbuilder = FontBuilderAttach( p_filter, &p_sys->p_fontconfig_lock );#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -