Commit b54170d5 authored by Jean-Baptiste Kempf's avatar Jean-Baptiste Kempf

Freetype: split fontconfig management to its own file

parent 41eb7f4e
......@@ -11,6 +11,9 @@ libfreetype_plugin_la_SOURCES = \
if HAVE_WIN32
libfreetype_plugin_la_SOURCES += text_renderer/fonts/win32.c
endif
if HAVE_FONTCONFIG
libfreetype_plugin_la_SOURCES += text_renderer/fonts/fontconfig.c
endif
libfreetype_plugin_la_CPPFLAGS = $(AM_CPPFLAGS) $(FREETYPE_CFLAGS)
libfreetype_plugin_la_LIBADD = $(LIBM) $(FREETYPE_LIBS)
......
/*****************************************************************************
* freetype.c : Put text on the video, using freetype2
*****************************************************************************
* Copyright (C) 2002 - 2015 VLC authors and VideoLAN
* $Id$
*
* Authors: Sigmund Augdal Helberg <dnumgis@videolan.org>
* Gildas Bazin <gbazin@videolan.org>
* Bernie Purcell <bitmap@videolan.org>
* Jean-Baptiste Kempf <jb@videolan.org>
* Felix Paul Kühne <fkuehne@videolan.org>
* Salah-Eddin Shaban <salshaaban@gmail.com>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation, Inc.,
* 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_filter.h> /* filter_sys_t */
#include <fontconfig/fontconfig.h>
#include "../platform_fonts.h"
#include "freetype.h"
int FontConfig_Prepare( filter_t *p_filter )
{
/* */
msg_Dbg( p_filter, "Building font databases.");
mtime_t t1, t2;
t1 = mdate();
#ifdef __OS2__
FcInit();
#endif
#if defined( _WIN32 ) || defined( __APPLE__ )
dialog_progress_bar_t *p_dialog = NULL;
FcConfig *fcConfig = FcInitLoadConfig();
p_dialog = dialog_ProgressCreate( p_filter,
_("Building font cache"),
_("Please wait while your font cache is rebuilt.\n"
"This should take less than a few minutes."), NULL );
/* if( p_dialog )
dialog_ProgressSet( p_dialog, NULL, 0.5 ); */
if( FcConfigBuildFonts( fcConfig ) == FcFalse )
return VLC_ENOMEM;
#if defined( __APPLE__ )
// By default, scan only the directory /System/Library/Fonts.
// So build the set of available fonts under another directories,
// and add the set to the current configuration.
FcConfigAppFontAddDir( NULL, "~/Library/Fonts" );
FcConfigAppFontAddDir( NULL, "/Library/Fonts" );
FcConfigAppFontAddDir( NULL, "/Network/Library/Fonts" );
//FcConfigAppFontAddDir( NULL, "/System/Library/Fonts" );
#endif
if( p_dialog )
{
// dialog_ProgressSet( p_dialog, NULL, 1.0 );
dialog_ProgressDestroy( p_dialog );
p_dialog = NULL;
}
#endif
t2 = mdate();
msg_Dbg( p_filter, "Took %ld microseconds", (long)((t2 - t1)) );
return VLC_SUCCESS;
}
const vlc_family_t *FontConfig_GetFamily( filter_t *p_filter, const char *psz_family )
{
filter_sys_t *p_sys = p_filter->p_sys;
char *psz_lc = ToLower( psz_family );
if( unlikely( !psz_lc ) )
return NULL;
vlc_family_t *p_family =
vlc_dictionary_value_for_key( &p_sys->family_map, psz_lc );
if( p_family != kVLCDictionaryNotFound )
{
free( psz_lc );
return p_family;
}
p_family = NewFamily( p_filter, psz_lc, &p_sys->p_families,
&p_sys->family_map, psz_lc );
free( psz_lc );
if( !p_family )
return NULL;
bool b_bold, b_italic;
for( int i = 0; i < 4; ++i )
{
switch( i )
{
case 0:
b_bold = false;
b_italic = false;
break;
case 1:
b_bold = true;
b_italic = false;
break;
case 2:
b_bold = false;
b_italic = true;
break;
case 3:
b_bold = true;
b_italic = true;
break;
}
int i_index = 0;
FcResult result = FcResultMatch;
FcPattern *pat, *p_pat;
FcChar8* val_s;
FcBool val_b;
char *psz_fontfile = NULL;
FcConfig* config = NULL;
/* Create a pattern and fill it */
pat = FcPatternCreate();
if (!pat) continue;
/* */
FcPatternAddString( pat, FC_FAMILY, (const FcChar8*) psz_family );
FcPatternAddBool( pat, FC_OUTLINE, FcTrue );
FcPatternAddInteger( pat, FC_SLANT, b_italic ? FC_SLANT_ITALIC : FC_SLANT_ROMAN );
FcPatternAddInteger( pat, FC_WEIGHT, b_bold ? FC_WEIGHT_EXTRABOLD : FC_WEIGHT_NORMAL );
/* */
FcDefaultSubstitute( pat );
if( !FcConfigSubstitute( config, pat, FcMatchPattern ) )
{
FcPatternDestroy( pat );
continue;
}
/* Find the best font for the pattern, destroy the pattern */
p_pat = FcFontMatch( config, pat, &result );
FcPatternDestroy( pat );
if( !p_pat || result == FcResultNoMatch ) continue;
/* Check the new pattern */
if( ( FcResultMatch != FcPatternGetBool( p_pat, FC_OUTLINE, 0, &val_b ) )
|| ( val_b != FcTrue ) )
{
FcPatternDestroy( p_pat );
continue;
}
if( FcResultMatch != FcPatternGetInteger( p_pat, FC_INDEX, 0, &i_index ) )
{
i_index = 0;
}
if( FcResultMatch != FcPatternGetString( p_pat, FC_FAMILY, 0, &val_s ) )
{
FcPatternDestroy( p_pat );
continue;
}
if( FcResultMatch == FcPatternGetString( p_pat, FC_FILE, 0, &val_s ) )
psz_fontfile = strdup( (const char*)val_s );
FcPatternDestroy( p_pat );
if( !psz_fontfile )
continue;
NewFont( psz_fontfile, i_index, b_bold, b_italic, p_family );
}
return p_family;
}
vlc_family_t *FontConfig_GetFallbacks( filter_t *p_filter, const char *psz_family,
uni_char_t codepoint )
{
VLC_UNUSED( codepoint );
vlc_family_t *p_family = NULL;
filter_sys_t *p_sys = p_filter->p_sys;
char *psz_lc = ToLower( psz_family );
if( unlikely( !psz_lc ) )
return NULL;
p_family = vlc_dictionary_value_for_key( &p_sys->fallback_map, psz_lc );
if( p_family != kVLCDictionaryNotFound )
{
free( psz_lc );
return p_family;
}
else
p_family = NULL;
const char *psz_last_name = "";
FcPattern *p_pattern = FcPatternCreate();
FcValue family;
family.type = FcTypeString;
family.u.s = ( const FcChar8* ) psz_family;
FcPatternAdd( p_pattern, FC_FAMILY, family, FcFalse );
if( FcConfigSubstitute( NULL, p_pattern, FcMatchPattern ) == FcTrue )
{
FcDefaultSubstitute( p_pattern );
FcResult result;
FcFontSet* p_font_set = FcFontSort( NULL, p_pattern, FcTrue, NULL, &result );
if( p_font_set )
{
for( int i = 0; i < p_font_set->nfont; ++i )
{
char* psz_name = NULL;
FcPatternGetString( p_font_set->fonts[i],
FC_FAMILY, 0, ( FcChar8** )( &psz_name ) );
/* Avoid duplicate family names */
if( strcasecmp( psz_last_name, psz_name ) )
{
vlc_family_t *p_temp = NewFamily( p_filter, psz_name,
&p_family, NULL, NULL );
if( unlikely( !p_temp ) )
{
FcFontSetDestroy( p_font_set );
FcPatternDestroy( p_pattern );
if( p_family )
FreeFamilies( p_family, NULL );
free( psz_lc );
return NULL;
}
psz_last_name = p_temp->psz_name;
}
}
FcFontSetDestroy( p_font_set );
}
}
FcPatternDestroy( p_pattern );
if( p_family )
vlc_dictionary_insert( &p_sys->fallback_map, psz_lc, p_family );
free( psz_lc );
return p_family;
}
......@@ -56,11 +56,6 @@
# undef HAVE_FONTCONFIG
#endif
/* FontConfig */
#ifdef HAVE_FONTCONFIG
# include <fontconfig/fontconfig.h>
#endif
#include "platform_fonts.h"
#include "freetype.h"
......@@ -561,241 +556,6 @@ char* Generic_Select( filter_t *p_filter, const char* psz_family,
return File_Select( SYSTEM_DEFAULT_FONT_FILE );
}
#ifdef HAVE_FONTCONFIG
int FontConfig_Prepare( filter_t *p_filter )
{
/* */
msg_Dbg( p_filter, "Building font databases.");
mtime_t t1, t2;
t1 = mdate();
#ifdef __OS2__
FcInit();
#endif
#if defined( _WIN32 ) || defined( __APPLE__ )
dialog_progress_bar_t *p_dialog = NULL;
FcConfig *fcConfig = FcInitLoadConfig();
p_dialog = dialog_ProgressCreate( p_filter,
_("Building font cache"),
_("Please wait while your font cache is rebuilt.\n"
"This should take less than a few minutes."), NULL );
/* if( p_dialog )
dialog_ProgressSet( p_dialog, NULL, 0.5 ); */
if( FcConfigBuildFonts( fcConfig ) == FcFalse )
return VLC_ENOMEM;
#if defined( __APPLE__ )
// By default, scan only the directory /System/Library/Fonts.
// So build the set of available fonts under another directories,
// and add the set to the current configuration.
FcConfigAppFontAddDir( NULL, "~/Library/Fonts" );
FcConfigAppFontAddDir( NULL, "/Library/Fonts" );
FcConfigAppFontAddDir( NULL, "/Network/Library/Fonts" );
//FcConfigAppFontAddDir( NULL, "/System/Library/Fonts" );
#endif
if( p_dialog )
{
// dialog_ProgressSet( p_dialog, NULL, 1.0 );
dialog_ProgressDestroy( p_dialog );
p_dialog = NULL;
}
#endif
t2 = mdate();
msg_Dbg( p_filter, "Took %ld microseconds", (long)((t2 - t1)) );
return VLC_SUCCESS;
}
const vlc_family_t *FontConfig_GetFamily( filter_t *p_filter, const char *psz_family )
{
filter_sys_t *p_sys = p_filter->p_sys;
char *psz_lc = ToLower( psz_family );
if( unlikely( !psz_lc ) )
return NULL;
vlc_family_t *p_family =
vlc_dictionary_value_for_key( &p_sys->family_map, psz_lc );
if( p_family != kVLCDictionaryNotFound )
{
free( psz_lc );
return p_family;
}
p_family = NewFamily( p_filter, psz_lc, &p_sys->p_families,
&p_sys->family_map, psz_lc );
free( psz_lc );
if( !p_family )
return NULL;
bool b_bold, b_italic;
for( int i = 0; i < 4; ++i )
{
switch( i )
{
case 0:
b_bold = false;
b_italic = false;
break;
case 1:
b_bold = true;
b_italic = false;
break;
case 2:
b_bold = false;
b_italic = true;
break;
case 3:
b_bold = true;
b_italic = true;
break;
}
int i_index = 0;
FcResult result = FcResultMatch;
FcPattern *pat, *p_pat;
FcChar8* val_s;
FcBool val_b;
char *psz_fontfile = NULL;
FcConfig* config = NULL;
/* Create a pattern and fill it */
pat = FcPatternCreate();
if (!pat) continue;
/* */
FcPatternAddString( pat, FC_FAMILY, (const FcChar8*) psz_family );
FcPatternAddBool( pat, FC_OUTLINE, FcTrue );
FcPatternAddInteger( pat, FC_SLANT, b_italic ? FC_SLANT_ITALIC : FC_SLANT_ROMAN );
FcPatternAddInteger( pat, FC_WEIGHT, b_bold ? FC_WEIGHT_EXTRABOLD : FC_WEIGHT_NORMAL );
/* */
FcDefaultSubstitute( pat );
if( !FcConfigSubstitute( config, pat, FcMatchPattern ) )
{
FcPatternDestroy( pat );
continue;
}
/* Find the best font for the pattern, destroy the pattern */
p_pat = FcFontMatch( config, pat, &result );
FcPatternDestroy( pat );
if( !p_pat || result == FcResultNoMatch ) continue;
/* Check the new pattern */
if( ( FcResultMatch != FcPatternGetBool( p_pat, FC_OUTLINE, 0, &val_b ) )
|| ( val_b != FcTrue ) )
{
FcPatternDestroy( p_pat );
continue;
}
if( FcResultMatch != FcPatternGetInteger( p_pat, FC_INDEX, 0, &i_index ) )
{
i_index = 0;
}
if( FcResultMatch != FcPatternGetString( p_pat, FC_FAMILY, 0, &val_s ) )
{
FcPatternDestroy( p_pat );
continue;
}
if( FcResultMatch == FcPatternGetString( p_pat, FC_FILE, 0, &val_s ) )
psz_fontfile = strdup( (const char*)val_s );
FcPatternDestroy( p_pat );
if( !psz_fontfile )
continue;
NewFont( psz_fontfile, i_index, b_bold, b_italic, p_family );
}
return p_family;
}
vlc_family_t *FontConfig_GetFallbacks( filter_t *p_filter, const char *psz_family,
uni_char_t codepoint )
{
VLC_UNUSED( codepoint );
vlc_family_t *p_family = NULL;
filter_sys_t *p_sys = p_filter->p_sys;
char *psz_lc = ToLower( psz_family );
if( unlikely( !psz_lc ) )
return NULL;
p_family = vlc_dictionary_value_for_key( &p_sys->fallback_map, psz_lc );
if( p_family != kVLCDictionaryNotFound )
{
free( psz_lc );
return p_family;
}
else
p_family = NULL;
const char *psz_last_name = "";
FcPattern *p_pattern = FcPatternCreate();
FcValue family;
family.type = FcTypeString;
family.u.s = ( const FcChar8* ) psz_family;
FcPatternAdd( p_pattern, FC_FAMILY, family, FcFalse );
if( FcConfigSubstitute( NULL, p_pattern, FcMatchPattern ) == FcTrue )
{
FcDefaultSubstitute( p_pattern );
FcResult result;
FcFontSet* p_font_set = FcFontSort( NULL, p_pattern, FcTrue, NULL, &result );
if( p_font_set )
{
for( int i = 0; i < p_font_set->nfont; ++i )
{
char* psz_name = NULL;
FcPatternGetString( p_font_set->fonts[i],
FC_FAMILY, 0, ( FcChar8** )( &psz_name ) );
/* Avoid duplicate family names */
if( strcasecmp( psz_last_name, psz_name ) )
{
vlc_family_t *p_temp = NewFamily( p_filter, psz_name,
&p_family, NULL, NULL );
if( unlikely( !p_temp ) )
{
FcFontSetDestroy( p_font_set );
FcPatternDestroy( p_pattern );
if( p_family )
FreeFamilies( p_family, NULL );
free( psz_lc );
return NULL;
}
psz_last_name = p_temp->psz_name;
}
}
FcFontSetDestroy( p_font_set );
}
}
FcPatternDestroy( p_pattern );
if( p_family )
vlc_dictionary_insert( &p_sys->fallback_map, psz_lc, p_family );
free( psz_lc );
return p_family;
}
#endif
#ifdef __APPLE__
#if !TARGET_OS_IPHONE
char* MacLegacy_Select( filter_t *p_filter, const char* psz_fontname,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment