[vlc-commits] freetype: use FcFontList instead of multiple FcMatch
Francois Cartegnie
git at videolan.org
Mon Aug 24 17:38:59 CEST 2020
vlc | branch: master | Francois Cartegnie <fcvlcdev at free.fr> | Wed Aug 5 16:47:56 2020 +0200| [189cc0f03b32dbb5b423697c4eef7dfd75f23b8b] | committer: Francois Cartegnie
freetype: use FcFontList instead of multiple FcMatch
Better performance listing fonts with the previouly
matched family instead of criterion match
> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=189cc0f03b32dbb5b423697c4eef7dfd75f23b8b
---
modules/text_renderer/freetype/fonts/fontconfig.c | 185 +++++++++++++---------
modules/text_renderer/freetype/platform_fonts.c | 2 +-
2 files changed, 115 insertions(+), 72 deletions(-)
diff --git a/modules/text_renderer/freetype/fonts/fontconfig.c b/modules/text_renderer/freetype/fonts/fontconfig.c
index fff08913f2..93a6253e0e 100644
--- a/modules/text_renderer/freetype/fonts/fontconfig.c
+++ b/modules/text_renderer/freetype/fonts/fontconfig.c
@@ -106,97 +106,140 @@ void FontConfig_Unprepare( vlc_font_select_t *fs )
vlc_mutex_unlock( &lock );
}
-int FontConfig_SelectAmongFamilies( vlc_font_select_t *fs, const fontfamilies_t *families,
- const vlc_family_t **pp_result )
+static void FontConfig_AddFromFcPattern( FcPattern *p_pat, vlc_family_t *p_family )
{
- vlc_family_t *p_family = NULL;
+ int bold;
+ int italic;
+ FcChar8* val_s;
+ int i_index = 0;
+ char *psz_fontfile = NULL;
+
+ if( FcResultMatch != FcPatternGetInteger( p_pat, FC_INDEX, 0, &i_index ) )
+ i_index = 0;
+
+ if( FcResultMatch != FcPatternGetInteger( p_pat, FC_WEIGHT, 0, &bold ) )
+ bold = FC_WEIGHT_NORMAL;
+ if( bold < FC_WEIGHT_NORMAL )
+ return;
+
+ if( FcResultMatch != FcPatternGetInteger( p_pat, FC_SLANT, 0, &italic ) )
+ italic = FC_SLANT_ROMAN;
+
+ if( FcResultMatch != FcPatternGetString( p_pat, FC_FILE, 0, &val_s ) )
+ return;
+
+ psz_fontfile = strdup( (const char*)val_s );
+ if( psz_fontfile )
+ NewFont( psz_fontfile, i_index,
+ bold > FC_WEIGHT_NORMAL,
+ italic != FC_SLANT_ROMAN,
+ p_family );
+}
+
+static void FontConfig_FillFaces( vlc_family_t *p_family )
+{
+ FcPattern *pat = FcPatternCreate();
+ if ( !pat )
+ return;
- for( int i = 0; i < 4; ++i ) /* Iterate through FC_{SLANT,WEIGHT} combos */
+ FcObjectSet *os = FcObjectSetBuild ( FC_FILE, FC_SLANT, FC_WEIGHT,
+ FC_INDEX, FC_WIDTH, (char *) 0 );
+ if( os )
{
- bool const b_bold = i & 1;
- bool const b_italic = i & 2;
-
- int i_index = 0;
- FcResult result = FcResultMatch;
- FcPattern *pat, *p_pat;
- FcChar8* val_s;
- FcBool val_b;
- char *psz_fontfile = NULL;
-
- /* Create a pattern and fill it */
- pat = FcPatternCreate();
- if (!pat) continue;
-
- /* */
- const char *psz_lcname;
- vlc_vector_foreach( psz_lcname, &families->vec )
- FcPatternAddString( pat, FC_FAMILY, (const FcChar8*) psz_lcname );
+ FcPatternAddString( pat, FC_FAMILY, (const FcChar8 *) p_family->psz_name );
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;
-
- if( FcResultMatch != FcPatternGetString( p_pat, FC_FAMILY, 0, &val_s ) )
- {
- FcPatternDestroy( p_pat );
- continue;
- }
- if( !p_family )
+ FcFontSet *fs = FcFontList( 0, pat, os );
+ FcObjectSetDestroy( os );
+ if( fs )
{
- char *psz_fnlc = LowercaseDup((const char *)val_s);
- p_family = vlc_dictionary_value_for_key( &fs->family_map, psz_fnlc );
- if( p_family == kVLCDictionaryNotFound )
+ for( int pass=0; pass<2 && !p_family->p_fonts; pass++ )
{
- p_family = NewFamily( fs, psz_fnlc, &fs->p_families,
- &fs->family_map, psz_fnlc );
- if( !p_family )
+ for ( int i = 0; i < fs->nfont; i++ )
{
- free(psz_fnlc);
- FcPatternDestroy( pat );
- return VLC_ENOMEM;
+ int i_width = 0;
+ FcPattern *p_pat = fs->fonts[i];
+
+ /* we relax the WIDTH condition if we did not get any match */
+ if( pass == 0 &&
+ FcResultMatch == FcPatternGetInteger( p_pat, FC_WIDTH, 0, &i_width ) &&
+ i_width != FC_WIDTH_NORMAL )
+ continue;
+
+ FontConfig_AddFromFcPattern( p_pat, p_family );
}
}
- free(psz_fnlc);
+ FcFontSetDestroy( fs );
}
+ }
+ FcPatternDestroy( pat );
+}
- /* Check the new pattern */
- if( ( FcResultMatch != FcPatternGetBool( p_pat, FC_OUTLINE, 0, &val_b ) )
- || ( val_b != FcTrue ) )
- {
- FcPatternDestroy( p_pat );
- continue;
- }
+int FontConfig_SelectAmongFamilies( vlc_font_select_t *fs, const fontfamilies_t *families,
+ const vlc_family_t **pp_result )
+{
+ FcResult result = FcResultMatch;
+ FcPattern *pat, *p_matchpat;
+ FcChar8* val_s;
- if( FcResultMatch != FcPatternGetInteger( p_pat, FC_INDEX, 0, &i_index ) )
- {
- i_index = 0;
- }
+ /* Create a pattern and fill it */
+ pat = FcPatternCreate();
+ if (!pat)
+ return VLC_EGENERIC;
+
+ /* */
+ const char *psz_lcname;
+ vlc_vector_foreach( psz_lcname, &families->vec )
+ FcPatternAddString( pat, FC_FAMILY, (const FcChar8*) psz_lcname );
+ FcPatternAddBool( pat, FC_OUTLINE, FcTrue );
- if( FcResultMatch == FcPatternGetString( p_pat, FC_FILE, 0, &val_s ) )
- psz_fontfile = strdup( (const char*)val_s );
+ /* */
+ FcDefaultSubstitute( pat );
+ if( !FcConfigSubstitute( config, pat, FcMatchPattern ) )
+ {
+ FcPatternDestroy( pat );
+ return VLC_EGENERIC;
+ }
- FcPatternDestroy( p_pat );
+ /* Find the best font for the pattern, destroy the pattern */
+ p_matchpat = FcFontMatch( config, pat, &result );
+ if( !p_matchpat )
+ return VLC_EGENERIC;
+ FcPatternDestroy( pat );
+ if( result == FcResultNoMatch )
+ {
+ *pp_result = NULL;
+ return VLC_SUCCESS;
+ }
- if( !psz_fontfile )
- continue;
+ if( FcResultMatch != FcPatternGetString( p_matchpat, FC_FAMILY, 0, &val_s ) )
+ {
+ FcPatternDestroy( p_matchpat );
+ return VLC_EGENERIC;
+ }
- NewFont( psz_fontfile, i_index, b_bold, b_italic, p_family );
+ char *psz_fnlc = LowercaseDup((const char *)val_s);
+ vlc_family_t *p_family = vlc_dictionary_value_for_key( &fs->family_map, psz_fnlc );
+ if( p_family == kVLCDictionaryNotFound )
+ {
+ p_family = NewFamily( fs, psz_fnlc, &fs->p_families,
+ &fs->family_map, psz_fnlc );
+ if( !p_family )
+ {
+ free( psz_fnlc );
+ FcPatternDestroy( p_matchpat );
+ return VLC_EGENERIC;
+ }
}
+ free(psz_fnlc);
+ FcPatternDestroy( p_matchpat );
+
+ if( p_family ) /* Populate with fonts */
+ FontConfig_FillFaces( p_family );
+
*pp_result = p_family;
+
return VLC_SUCCESS;
}
diff --git a/modules/text_renderer/freetype/platform_fonts.c b/modules/text_renderer/freetype/platform_fonts.c
index 67446f280f..8d601fd142 100644
--- a/modules/text_renderer/freetype/platform_fonts.c
+++ b/modules/text_renderer/freetype/platform_fonts.c
@@ -718,7 +718,7 @@ static char* SelectFontWithFamilyFallback( vlc_font_select_t *fs,
if( p_family && ( p_font = GetBestFont( fs, p_family, b_bold,
b_italic, codepoint ) ) )
{
- Debug( fs->p_obj, "Selected best font file \"%s\"", p_font->psz_fontfile );
+ Debug( fs->p_obj, "Selected best font file \"%s\" %d %d", p_font->psz_fontfile, b_bold, b_italic );
*pi_idx = p_font->i_index;
return strdup( p_font->psz_fontfile );
}
More information about the vlc-commits
mailing list