Changeset 6df5e4eca4fcbd38de041352b908c79149523191
- Timestamp:
- 31/07/07 08:47:01
(1 year ago)
- Author:
- Bernie Purcell <bitmap@videolan.org>
- git-committer:
- Bernie Purcell <bitmap@videolan.org> 1185864421 +0000
- git-parent:
[1decebd2c8ade2eba2b637e87a5519b5a76a9295]
- git-author:
- Bernie Purcell <bitmap@videolan.org> 1185864421 +0000
- Message:
Dynamically load any TTF or OTF fonts available in the attachments of
the media file and make them available to FreeType? as memory based fonts
for subtitle rendering.
-
Files:
-
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
| r4a1b6b0 |
r6df5e4e |
|
| 7 | 7 | * Authors: Sigmund Augdal Helberg <dnumgis@videolan.org> |
|---|
| 8 | 8 | * Gildas Bazin <gbazin@videolan.org> |
|---|
| 9 | | * Bernie Purcell <b dot purcell at adbglobal dot com> |
|---|
| | 9 | * Bernie Purcell <bitmap@videolan.org> |
|---|
| 10 | 10 | * |
|---|
| 11 | 11 | * This program is free software; you can redistribute it and/or modify |
|---|
| … | … | |
| 41 | 41 | #include <vlc_stream.h> |
|---|
| 42 | 42 | #include <vlc_xml.h> |
|---|
| | 43 | #include <vlc_input.h> |
|---|
| 43 | 44 | |
|---|
| 44 | 45 | #include <math.h> |
|---|
| … | … | |
| 84 | 85 | static int Create ( vlc_object_t * ); |
|---|
| 85 | 86 | static void Destroy( vlc_object_t * ); |
|---|
| | 87 | |
|---|
| | 88 | static int LoadFontsFromAttachments( filter_t *p_filter ); |
|---|
| 86 | 89 | |
|---|
| 87 | 90 | /* The RenderText call maps to pf_render_string, defined in vlc_filter.h */ |
|---|
| … | … | |
| 259 | 262 | FcConfig *p_fontconfig; |
|---|
| 260 | 263 | #endif |
|---|
| | 264 | |
|---|
| | 265 | input_attachment_t **pp_font_attachments; |
|---|
| | 266 | int i_font_attachments; |
|---|
| 261 | 267 | }; |
|---|
| 262 | 268 | |
|---|
| … | … | |
| 366 | 372 | |
|---|
| 367 | 373 | if( psz_fontfile ) free( psz_fontfile ); |
|---|
| | 374 | |
|---|
| | 375 | p_sys->pp_font_attachments = NULL; |
|---|
| | 376 | p_sys->i_font_attachments = 0; |
|---|
| | 377 | |
|---|
| 368 | 378 | p_filter->pf_render_text = RenderText; |
|---|
| 369 | 379 | #ifdef HAVE_FONTCONFIG |
|---|
| … | … | |
| 372 | 382 | p_filter->pf_render_html = NULL; |
|---|
| 373 | 383 | #endif |
|---|
| | 384 | |
|---|
| | 385 | LoadFontsFromAttachments( p_filter ); |
|---|
| | 386 | |
|---|
| 374 | 387 | return VLC_SUCCESS; |
|---|
| 375 | 388 | |
|---|
| … | … | |
| 391 | 404 | filter_t *p_filter = (filter_t *)p_this; |
|---|
| 392 | 405 | filter_sys_t *p_sys = p_filter->p_sys; |
|---|
| | 406 | |
|---|
| | 407 | if( p_sys->pp_font_attachments ) |
|---|
| | 408 | { |
|---|
| | 409 | int k; |
|---|
| | 410 | |
|---|
| | 411 | for( k = 0; k < p_sys->i_font_attachments; k++ ) |
|---|
| | 412 | { |
|---|
| | 413 | vlc_input_attachment_Delete( p_sys->pp_font_attachments[k] ); |
|---|
| | 414 | } |
|---|
| | 415 | |
|---|
| | 416 | free( p_sys->pp_font_attachments ); |
|---|
| | 417 | } |
|---|
| 393 | 418 | |
|---|
| 394 | 419 | #ifdef HAVE_FONTCONFIG |
|---|
| … | … | |
| 402 | 427 | FT_Done_FreeType( p_sys->p_library ); |
|---|
| 403 | 428 | free( p_sys ); |
|---|
| | 429 | } |
|---|
| | 430 | |
|---|
| | 431 | /***************************************************************************** |
|---|
| | 432 | * Make any TTF/OTF fonts present in the attachments of the media file |
|---|
| | 433 | * and store them for later use by the FreeType Engine |
|---|
| | 434 | *****************************************************************************/ |
|---|
| | 435 | static int LoadFontsFromAttachments( filter_t *p_filter ) |
|---|
| | 436 | { |
|---|
| | 437 | filter_sys_t *p_sys = p_filter->p_sys; |
|---|
| | 438 | input_thread_t *p_input; |
|---|
| | 439 | input_attachment_t **pp_attachments; |
|---|
| | 440 | int i_attachments_cnt; |
|---|
| | 441 | int k; |
|---|
| | 442 | int rv = VLC_SUCCESS; |
|---|
| | 443 | |
|---|
| | 444 | p_input = (input_thread_t *)vlc_object_find( p_filter, VLC_OBJECT_INPUT, FIND_PARENT ); |
|---|
| | 445 | if( ! p_input ) |
|---|
| | 446 | return VLC_EGENERIC; |
|---|
| | 447 | |
|---|
| | 448 | if( VLC_SUCCESS != input_Control( p_input, INPUT_GET_ATTACHMENTS, &pp_attachments, &i_attachments_cnt )) |
|---|
| | 449 | return VLC_EGENERIC; |
|---|
| | 450 | |
|---|
| | 451 | p_sys->i_font_attachments = 0; |
|---|
| | 452 | p_sys->pp_font_attachments = malloc( i_attachments_cnt * sizeof( input_attachment_t * )); |
|---|
| | 453 | if(! p_sys->pp_font_attachments ) |
|---|
| | 454 | rv = VLC_ENOMEM; |
|---|
| | 455 | |
|---|
| | 456 | for( k = 0; k < i_attachments_cnt; k++ ) |
|---|
| | 457 | { |
|---|
| | 458 | input_attachment_t *p_attach = pp_attachments[k]; |
|---|
| | 459 | |
|---|
| | 460 | if( p_sys->pp_font_attachments ) |
|---|
| | 461 | { |
|---|
| | 462 | if(( !strcmp( p_attach->psz_mime, "application/x-truetype-font" ) || // TTF |
|---|
| | 463 | !strcmp( p_attach->psz_mime, "application/x-font-otf" ) ) && // OTF |
|---|
| | 464 | ( p_attach->i_data > 0 ) && |
|---|
| | 465 | ( p_attach->p_data != NULL ) ) |
|---|
| | 466 | { |
|---|
| | 467 | p_sys->pp_font_attachments[ p_sys->i_font_attachments++ ] = p_attach; |
|---|
| | 468 | } |
|---|
| | 469 | else |
|---|
| | 470 | { |
|---|
| | 471 | vlc_input_attachment_Delete( p_attach ); |
|---|
| | 472 | } |
|---|
| | 473 | } |
|---|
| | 474 | else |
|---|
| | 475 | { |
|---|
| | 476 | vlc_input_attachment_Delete( p_attach ); |
|---|
| | 477 | } |
|---|
| | 478 | } |
|---|
| | 479 | free( pp_attachments ); |
|---|
| | 480 | |
|---|
| | 481 | return rv; |
|---|
| 404 | 482 | } |
|---|
| 405 | 483 | |
|---|
| … | … | |
| 1933 | 2011 | } |
|---|
| 1934 | 2012 | |
|---|
| | 2013 | static int CheckForEmbeddedFont( filter_sys_t *p_sys, FT_Face *pp_face, ft_style_t *p_style ) |
|---|
| | 2014 | { |
|---|
| | 2015 | int k; |
|---|
| | 2016 | |
|---|
| | 2017 | for( k=0; k < p_sys->i_font_attachments; k++ ) |
|---|
| | 2018 | { |
|---|
| | 2019 | input_attachment_t *p_attach = p_sys->pp_font_attachments[k]; |
|---|
| | 2020 | int i_font_idx = 0; |
|---|
| | 2021 | FT_Face p_face = NULL; |
|---|
| | 2022 | |
|---|
| | 2023 | while( 0 == FT_New_Memory_Face( p_sys->p_library, |
|---|
| | 2024 | p_attach->p_data, |
|---|
| | 2025 | p_attach->i_data, |
|---|
| | 2026 | i_font_idx, |
|---|
| | 2027 | &p_face )) |
|---|
| | 2028 | { |
|---|
| | 2029 | if( p_face ) |
|---|
| | 2030 | { |
|---|
| | 2031 | vlc_bool_t match = !strcasecmp( p_face->family_name, |
|---|
| | 2032 | p_style->psz_fontname ); |
|---|
| | 2033 | |
|---|
| | 2034 | if( p_face->style_flags & FT_STYLE_FLAG_BOLD ) |
|---|
| | 2035 | match = match && p_style->b_bold; |
|---|
| | 2036 | else |
|---|
| | 2037 | match = match && !p_style->b_bold; |
|---|
| | 2038 | |
|---|
| | 2039 | if( p_face->style_flags & FT_STYLE_FLAG_ITALIC ) |
|---|
| | 2040 | match = match && p_style->b_italic; |
|---|
| | 2041 | else |
|---|
| | 2042 | match = match && !p_style->b_italic; |
|---|
| | 2043 | |
|---|
| | 2044 | if( match ) |
|---|
| | 2045 | { |
|---|
| | 2046 | *pp_face = p_face; |
|---|
| | 2047 | return VLC_SUCCESS; |
|---|
| | 2048 | } |
|---|
| | 2049 | |
|---|
| | 2050 | FT_Done_Face( p_face ); |
|---|
| | 2051 | } |
|---|
| | 2052 | i_font_idx++; |
|---|
| | 2053 | } |
|---|
| | 2054 | } |
|---|
| | 2055 | return VLC_EGENERIC; |
|---|
| | 2056 | } |
|---|
| | 2057 | |
|---|
| 1935 | 2058 | static int ProcessLines( filter_t *p_filter, |
|---|
| 1936 | 2059 | uint32_t *psz_text, |
|---|
| … | … | |
| 2145 | 2268 | FT_Face p_face = NULL; |
|---|
| 2146 | 2269 | int i_idx = 0; |
|---|
| 2147 | | char *psz_fontfile = FontConfig_Select( p_sys->p_fontconfig, |
|---|
| 2148 | | p_style->psz_fontname, |
|---|
| 2149 | | p_style->b_bold, |
|---|
| 2150 | | p_style->b_italic, |
|---|
| 2151 | | &i_idx ); |
|---|
| 2152 | | if( psz_fontfile ) |
|---|
| 2153 | | { |
|---|
| 2154 | | if( FT_New_Face( p_sys->p_library, |
|---|
| 2155 | | psz_fontfile ? psz_fontfile : "", i_idx, &p_face ) ) |
|---|
| | 2270 | |
|---|
| | 2271 | /* Look for a match amongst our attachments first */ |
|---|
| | 2272 | CheckForEmbeddedFont( p_sys, &p_face, p_style ); |
|---|
| | 2273 | |
|---|
| | 2274 | if( ! p_face ) |
|---|
| | 2275 | { |
|---|
| | 2276 | char *psz_fontfile = FontConfig_Select( p_sys->p_fontconfig, |
|---|
| | 2277 | p_style->psz_fontname, |
|---|
| | 2278 | p_style->b_bold, |
|---|
| | 2279 | p_style->b_italic, |
|---|
| | 2280 | &i_idx ); |
|---|
| | 2281 | if( psz_fontfile ) |
|---|
| 2156 | 2282 | { |
|---|
| | 2283 | if( FT_New_Face( p_sys->p_library, |
|---|
| | 2284 | psz_fontfile ? psz_fontfile : "", i_idx, &p_face ) ) |
|---|
| | 2285 | { |
|---|
| | 2286 | free( psz_fontfile ); |
|---|
| | 2287 | free( pp_char_styles ); |
|---|
| | 2288 | #if defined(HAVE_FRIBIDI) |
|---|
| | 2289 | free( psz_text ); |
|---|
| | 2290 | #endif |
|---|
| | 2291 | if( pi_karaoke_bar ) |
|---|
| | 2292 | free( pi_karaoke_bar ); |
|---|
| | 2293 | return VLC_EGENERIC; |
|---|
| | 2294 | } |
|---|
| 2157 | 2295 | free( psz_fontfile ); |
|---|
| 2158 | | free( pp_char_styles ); |
|---|
| 2159 | | #if defined(HAVE_FRIBIDI) |
|---|
| 2160 | | free( psz_text ); |
|---|
| 2161 | | #endif |
|---|
| 2162 | | if( pi_karaoke_bar ) |
|---|
| 2163 | | free( pi_karaoke_bar ); |
|---|
| 2164 | | return VLC_EGENERIC; |
|---|
| 2165 | 2296 | } |
|---|
| 2166 | | free( psz_fontfile ); |
|---|
| | 2297 | } |
|---|
| | 2298 | if( p_face && |
|---|
| | 2299 | FT_Select_Charmap( p_face, ft_encoding_unicode ) ) |
|---|
| | 2300 | { |
|---|
| | 2301 | /* We've loaded a font face which is unhelpful for actually |
|---|
| | 2302 | * rendering text - fallback to the default one. |
|---|
| | 2303 | */ |
|---|
| | 2304 | FT_Done_Face( p_face ); |
|---|
| | 2305 | p_face = NULL; |
|---|
| 2167 | 2306 | } |
|---|
| 2168 | 2307 | |
|---|