[vlc-commits] freetype: have consistent unified font selection
Francois Cartegnie
git at videolan.org
Tue Jul 21 16:07:14 CEST 2020
vlc | branch: master | Francois Cartegnie <fcvlcdev at free.fr> | Fri Jun 19 14:54:06 2020 +0200| [c620f925be4a45ea8e00f6a09c50ffedffa2aa83] | committer: Francois Cartegnie
freetype: have consistent unified font selection
> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=c620f925be4a45ea8e00f6a09c50ffedffa2aa83
---
modules/text_renderer/freetype/fonts/win32.c | 42 +++---
modules/text_renderer/freetype/freetype.c | 40 +++---
modules/text_renderer/freetype/freetype.h | 10 +-
modules/text_renderer/freetype/platform_fonts.c | 168 +++++++++++++++---------
modules/text_renderer/freetype/platform_fonts.h | 19 +--
5 files changed, 167 insertions(+), 112 deletions(-)
diff --git a/modules/text_renderer/freetype/fonts/win32.c b/modules/text_renderer/freetype/fonts/win32.c
index e9b8f47b4e..04097a0dff 100644
--- a/modules/text_renderer/freetype/fonts/win32.c
+++ b/modules/text_renderer/freetype/fonts/win32.c
@@ -329,13 +329,20 @@ done:
return psz_result;
}
+struct enumFontCallbackContext
+{
+ filter_t *p_filter;
+ vlc_family_t *p_family;
+};
+
static int CALLBACK EnumFontCallback(const ENUMLOGFONTEX *lpelfe, const NEWTEXTMETRICEX *metric,
DWORD type, LPARAM lParam)
{
VLC_UNUSED( metric );
if( (type & RASTER_FONTTYPE) ) return 1;
- vlc_family_t *p_family = ( vlc_family_t * ) lParam;
+ struct enumFontCallbackContext *ctx = ( struct enumFontCallbackContext * ) lParam;
+ vlc_family_t *p_family = ctx->p_family;
bool b_bold = ( lpelfe->elfLogFont.lfWeight == FW_BOLD );
bool b_italic = ( lpelfe->elfLogFont.lfItalic != 0 );
@@ -421,7 +428,10 @@ const vlc_family_t *Win32_GetFamily( filter_t *p_filter, const char *psz_family
/* */
HDC hDC = GetDC( NULL );
- EnumFontFamiliesEx(hDC, &lf, (FONTENUMPROC)&EnumFontCallback, (LPARAM)p_family, 0);
+ struct enumFontCallbackContext ctx;
+ ctx.p_filter = p_filter;
+ ctx.p_family = NULL;
+ EnumFontFamiliesEx(hDC, &lf, (FONTENUMPROC)&EnumFontCallback, (LPARAM)&ctx, 0);
ReleaseDC(NULL, hDC);
return p_family;
@@ -575,24 +585,26 @@ done:
return p_family;
}
-char* Dummy_Select( filter_t *p_filter, const char* psz_font,
- bool b_bold, bool b_italic,
- int *i_idx, uni_char_t codepoint )
+char * MakeFilePath( filter_t *p_filter, const char *psz_filename )
{
VLC_UNUSED(p_filter);
- VLC_UNUSED(b_bold);
- VLC_UNUSED(b_italic);
- VLC_UNUSED(codepoint);
- VLC_UNUSED(i_idx);
- char *psz_fontname;
+ if( !psz_filename )
+ return NULL;
+
+ /* FIXME test FQN */
+
/* Get Windows Font folder */
- char *psz_win_fonts_path = GetWindowsFontPath();
- if( asprintf( &psz_fontname, "%s\\%s", psz_win_fonts_path, psz_font ) == -1 )
- psz_fontname = NULL;
- free(psz_win_fonts_path);
+ char *psz_fonts_path = GetWindowsFontPath();
+
+ char *psz_filepath;
+ if( asprintf( &psz_filepath, "%s" DIR_SEP "%s",
+ psz_fonts_path ? psz_fonts_path : "",
+ psz_filename ) == -1 )
+ psz_filepath = NULL;
+ free( psz_fonts_path );
- return psz_fontname;
+ return psz_filepath;
}
#endif
diff --git a/modules/text_renderer/freetype/freetype.c b/modules/text_renderer/freetype/freetype.c
index 9fd6eb8edd..cb8494a026 100644
--- a/modules/text_renderer/freetype/freetype.c
+++ b/modules/text_renderer/freetype/freetype.c
@@ -1006,28 +1006,24 @@ static void FillDefaultStyles( filter_t *p_filter )
{
filter_sys_t *p_sys = p_filter->p_sys;
+#ifdef HAVE_GET_FONT_BY_FAMILY_NAME
p_sys->p_default_style->psz_fontname = var_InheritString( p_filter, "freetype-font" );
+#endif
/* Set default psz_fontname */
if( !p_sys->p_default_style->psz_fontname || !*p_sys->p_default_style->psz_fontname )
{
free( p_sys->p_default_style->psz_fontname );
-#ifdef HAVE_GET_FONT_BY_FAMILY_NAME
p_sys->p_default_style->psz_fontname = strdup( DEFAULT_FAMILY );
-#else
- p_sys->p_default_style->psz_fontname = File_Select( DEFAULT_FONT_FILE );
-#endif
}
+#ifdef HAVE_GET_FONT_BY_FAMILY_NAME
p_sys->p_default_style->psz_monofontname = var_InheritString( p_filter, "freetype-monofont" );
+#endif
/* set default psz_monofontname */
if( !p_sys->p_default_style->psz_monofontname || !*p_sys->p_default_style->psz_monofontname )
{
free( p_sys->p_default_style->psz_monofontname );
-#ifdef HAVE_GET_FONT_BY_FAMILY_NAME
p_sys->p_default_style->psz_monofontname = strdup( DEFAULT_MONOSPACE_FAMILY );
-#else
- p_sys->p_default_style->psz_monofontname = File_Select( DEFAULT_MONOSPACE_FONT_FILE );
-#endif
}
UpdateDefaultLiveStyles( p_filter );
@@ -1235,7 +1231,7 @@ static int Render( filter_t *p_filter, subpicture_region_t *p_region_out,
/*
* Update the default face to reflect changes in video size or text scaling
*/
- p_sys->p_face = SelectAndLoadFace( p_filter, p_sys->p_default_style, 0 );
+ p_sys->p_face = SelectAndLoadFace( p_filter, p_sys->p_default_style, ' ' );
if( !p_sys->p_face )
{
msg_Err( p_filter, "Render(): Error loading default face" );
@@ -1465,6 +1461,11 @@ static int Create( vlc_object_t *p_this )
if(unlikely(!p_sys->p_forced_style))
goto error;
+#ifndef HAVE_GET_FONT_BY_FAMILY_NAME
+ p_sys->psz_fontfile = var_InheritString( p_filter, "freetype-font" );
+ p_sys->psz_monofontfile = var_InheritString( p_filter, "freetype-monofont" );
+#endif
+
/* fills default and forced style */
FillDefaultStyles( p_filter );
@@ -1485,14 +1486,12 @@ static int Create( vlc_object_t *p_this )
goto error;
#ifdef HAVE_FONTCONFIG
- p_sys->pf_select = Generic_Select;
p_sys->pf_get_family = FontConfig_GetFamily;
p_sys->pf_get_fallbacks = FontConfig_GetFallbacks;
if( FontConfig_Prepare( p_filter ) )
goto error;
#elif defined( __APPLE__ )
- p_sys->pf_select = Generic_Select;
p_sys->pf_get_family = CoreText_GetFamily;
p_sys->pf_get_fallbacks = CoreText_GetFallbacks;
#elif defined( _WIN32 )
@@ -1500,7 +1499,6 @@ static int Create( vlc_object_t *p_this )
{
p_sys->pf_get_family = DWrite_GetFamily;
p_sys->pf_get_fallbacks = DWrite_GetFallbacks;
- p_sys->pf_select = Generic_Select;
}
else
{
@@ -1513,7 +1511,6 @@ static int Create( vlc_object_t *p_this )
{ "Tahoma", "FangSong", "SimHei", "KaiTi" };
p_sys->pf_get_family = Win32_GetFamily;
p_sys->pf_get_fallbacks = Win32_GetFallbacks;
- p_sys->pf_select = Generic_Select;
InitDefaultList( p_filter, ppsz_win32_default,
sizeof( ppsz_win32_default ) / sizeof( *ppsz_win32_default ) );
#endif
@@ -1521,18 +1518,24 @@ static int Create( vlc_object_t *p_this )
#elif defined( __ANDROID__ )
p_sys->pf_get_family = Android_GetFamily;
p_sys->pf_get_fallbacks = Android_GetFallbacks;
- p_sys->pf_select = Generic_Select;
if( Android_Prepare( p_filter ) == VLC_ENOMEM )
goto error;
#else
- p_sys->pf_select = Dummy_Select;
+ p_sys->pf_get_family = StaticMap_GetFamily;
+ p_sys->pf_get_fallbacks = NULL;
+ /* The default static fonts are also fallback fonts */
+ const char *const ppsz_default[] =
+ { DEFAULT_FAMILY, DEFAULT_MONOSPACE_FAMILY };
+ InitDefaultList( p_filter, ppsz_default,
+ sizeof( ppsz_default ) / sizeof( *ppsz_default ) );
#endif
- p_sys->p_face = SelectAndLoadFace( p_filter, p_sys->p_default_style, 0 );
+ p_sys->p_face = SelectAndLoadFace( p_filter, p_sys->p_default_style, ' ' );
if( !p_sys->p_face )
{
- msg_Err( p_filter, "Error loading default face" );
+ msg_Err( p_filter, "Error loading default face %s",
+ p_sys->p_default_style->psz_fontname );
#ifdef HAVE_FONTCONFIG
FontConfig_Unprepare();
#endif
@@ -1573,6 +1576,9 @@ static void Destroy( vlc_object_t *p_this )
DumpDictionary( p_filter, &p_sys->fallback_map, true, -1 );
#endif
+ free( p_sys->psz_fontfile );
+ free( p_sys->psz_monofontfile );
+
/* Text styles */
text_style_Delete( p_sys->p_default_style );
text_style_Delete( p_sys->p_forced_style );
diff --git a/modules/text_renderer/freetype/freetype.h b/modules/text_renderer/freetype/freetype.h
index b9e47c1601..f1a7dbbc53 100644
--- a/modules/text_renderer/freetype/freetype.h
+++ b/modules/text_renderer/freetype/freetype.h
@@ -81,6 +81,9 @@ typedef struct
text_style_t *p_default_style;
text_style_t *p_forced_style; /* Renderer overridings */
+ char *psz_fontfile;
+ char *psz_monofontfile;
+
/* More styles... */
float f_shadow_vector_x;
float f_shadow_vector_y;
@@ -115,13 +118,6 @@ typedef struct
/* Current scaling of the text, default is 100 (%) */
int i_scale;
- /**
- * Select a font, based on the family, the styles and the codepoint
- */
- char * (*pf_select) (filter_t *, const char* family,
- bool bold, bool italic,
- int *index, uni_char_t codepoint);
-
/**
* Get a pointer to the vlc_family_t in the master list that matches \p psz_family.
* Add this family to the list if it hasn't been added yet.
diff --git a/modules/text_renderer/freetype/platform_fonts.c b/modules/text_renderer/freetype/platform_fonts.c
index 184c201718..5051b0edc0 100644
--- a/modules/text_renderer/freetype/platform_fonts.c
+++ b/modules/text_renderer/freetype/platform_fonts.c
@@ -471,61 +471,29 @@ int ConvertToLiveSize( filter_t *p_filter, const text_style_t *p_style )
return i_font_size;
}
-FT_Face SelectAndLoadFace( filter_t *p_filter, const text_style_t *p_style,
- uni_char_t codepoint )
+static char * SelectFontWithFamilyFallback( filter_t *p_filter, const char *psz_name,
+ const text_style_t *p_style,
+ int *pi_idx, uni_char_t codepoint )
{
filter_sys_t *p_sys = p_filter->p_sys;
- const char *psz_fontname = (p_style->i_style_flags & STYLE_MONOSPACED)
- ? p_style->psz_monofontname : p_style->psz_fontname;
-
- bool b_bold = p_style->i_style_flags & STYLE_BOLD;
- bool b_italic = p_style->i_style_flags & STYLE_ITALIC;
-
- FT_Face p_face = NULL;
-
-
- int i_idx = 0;
- char *psz_fontfile = NULL;
- if( p_sys->pf_select )
- psz_fontfile = p_sys->pf_select( p_filter, psz_fontname, b_bold, b_italic,
- &i_idx, codepoint );
- else
- psz_fontfile = NULL;
-
- if( !psz_fontfile || *psz_fontfile == '\0' )
- {
- msg_Warn( p_filter,
- "SelectAndLoadFace: no font found for family: %s, codepoint: 0x%x",
- psz_fontname, codepoint );
- free( psz_fontfile );
- return NULL;
- }
-
- p_face = LoadFace( p_filter, psz_fontfile, i_idx, p_style );
-
- free( psz_fontfile );
- return p_face;
-}
-char* Generic_Select( filter_t *p_filter, const char* psz_family,
- bool b_bold, bool b_italic,
- int *i_idx, uni_char_t codepoint )
-{
-
- filter_sys_t *p_sys = p_filter->p_sys;
+ const bool b_bold = p_style->i_style_flags & STYLE_BOLD;
+ const bool b_italic = p_style->i_style_flags & STYLE_ITALIC;
const vlc_family_t *p_family = NULL;
- vlc_family_t *p_fallbacks = NULL;
if( codepoint )
{
+ vlc_family_t *p_fallbacks;
/*
* Try regular face of the same family first.
* It usually has the best coverage.
*/
- const vlc_family_t *p_temp = p_sys->pf_get_family( p_filter, psz_family );
- if( p_temp && p_temp->p_fonts &&
- GetFace( p_filter, p_temp->p_fonts, codepoint ) )
- p_family = p_temp;
+ p_family = p_sys->pf_get_family( p_filter, psz_name );
+ if( p_family && p_family->p_fonts &&
+ !GetFace( p_filter, p_temp->p_fonts, codepoint ) )
+ {
+ p_family = NULL;
+ }
/* Try font attachments */
if( !p_family )
@@ -537,9 +505,10 @@ char* Generic_Select( filter_t *p_filter, const char* psz_family,
}
/* Try system fallbacks */
+ if( p_sys->pf_get_fallbacks )
if( !p_family )
{
- p_fallbacks = p_sys->pf_get_fallbacks( p_filter, psz_family, codepoint );
+ p_fallbacks = p_sys->pf_get_fallbacks( p_filter, psz_name, codepoint );
if( p_fallbacks )
p_family = SearchFallbacks( p_filter, p_fallbacks, codepoint );
}
@@ -557,9 +526,6 @@ char* Generic_Select( filter_t *p_filter, const char* psz_family,
return NULL;
}
- if( !p_family )
- p_family = p_sys->pf_get_family( p_filter, psz_family );
-
if( !p_family || !p_family->p_fonts )
p_family = p_sys->pf_get_family( p_filter, DEFAULT_FAMILY );
@@ -567,26 +533,110 @@ char* Generic_Select( filter_t *p_filter, const char* psz_family,
if( p_family && ( p_font = GetBestFont( p_filter, p_family, b_bold,
b_italic, codepoint ) ) )
{
- *i_idx = p_font->i_index;
+ *pi_idx = p_font->i_index;
return strdup( p_font->psz_fontfile );
}
- return File_Select( DEFAULT_FONT_FILE );
+ return NULL;
}
+FT_Face SelectAndLoadFace( filter_t *p_filter, const text_style_t *p_style,
+ uni_char_t codepoint )
+{
+ const char *psz_family = (p_style->i_style_flags & STYLE_MONOSPACED)
+ ? p_style->psz_monofontname : p_style->psz_fontname;
+ FT_Face p_face = NULL;
+ int i_idx = 0;
+
+ char *psz_fontfile =
+ SelectFontWithFamilyFallback( p_filter, psz_family, p_style,
+ &i_idx, codepoint );
+ if( !psz_fontfile || *psz_fontfile == '\0' )
+ {
+ msg_Warn( p_filter,
+ "SelectAndLoadFace: no font found for family: %s, codepoint: 0x%x",
+ psz_family, codepoint );
+ goto end;
+ }
+
+ p_face = LoadFace( p_filter, psz_fontfile, i_idx, p_style );
+
+end:
+ free( psz_fontfile );
+ return p_face;
+}
+
+#ifndef HAVE_GET_FONT_BY_FAMILY_NAME
+const vlc_family_t * StaticMap_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 )
+ {
+ free( psz_lc );
+ return p_family;
+ }
+
+ const char *psz_file = NULL;
+ if( !strcasecmp( psz_family, DEFAULT_FAMILY ) )
+ {
+ psz_file = p_sys->psz_fontfile ? p_sys->psz_fontfile
+ : DEFAULT_FONT_FILE;
+ }
+ else if( !strcasecmp( psz_family, DEFAULT_MONOSPACE_FAMILY ) )
+ {
+ psz_file = p_sys->psz_monofontfile ? p_sys->psz_monofontfile
+ : DEFAULT_MONOSPACE_FONT_FILE;
+ }
+
+ if( !psz_file )
+ {
+ free( psz_lc );
+ return NULL;
+ }
+
+ /* Create new entry */
+ p_family = NewFamily( p_filter, psz_lc, &p_sys->p_families,
+ &p_sys->family_map, psz_lc );
+
+ free( psz_lc );
+
+ if( unlikely( !p_family ) )
+ return NULL;
+
+ char *psz_font_file = MakeFilePath( p_filter, psz_file );
+ if( psz_font_file )
+ NewFont( psz_font_file, 0, false, false, p_family );
+
+ return p_family;
+}
+#endif
+
#if !defined(_WIN32) || VLC_WINSTORE_APP
-char* Dummy_Select( filter_t *p_filter, const char* psz_font,
- bool b_bold, bool b_italic,
- int *i_idx, uni_char_t codepoint )
+
+char * MakeFilePath( filter_t *p_filter, const char *psz_filename )
{
VLC_UNUSED(p_filter);
- VLC_UNUSED(b_bold);
- VLC_UNUSED(b_italic);
- VLC_UNUSED(codepoint);
- VLC_UNUSED(i_idx);
- char *psz_fontname = strdup( psz_font );
+ if( !psz_filename )
+ return NULL;
+
+ /* Handle the case where the user redefined *_FILE using FQN */
+ if( psz_filename[0] == DIR_SEP_CHAR )
+ return strdup( psz_filename );
+
+ char *psz_filepath;
+ if( asprintf( &psz_filepath, "%s" DIR_SEP "%s",
+ SYSTEM_FONT_PATH, psz_filename ) == -1 )
+ psz_filepath = NULL;
- return psz_fontname;
+ return psz_filepath;
}
#endif
diff --git a/modules/text_renderer/freetype/platform_fonts.h b/modules/text_renderer/freetype/platform_fonts.h
index e9c15eb578..d401b077e8 100644
--- a/modules/text_renderer/freetype/platform_fonts.h
+++ b/modules/text_renderer/freetype/platform_fonts.h
@@ -87,8 +87,7 @@ extern "C" {
#endif
#ifndef DEFAULT_FONT_FILE
-# define DEFAULT_FONT_FILE \
- SYSTEM_FONT_PATH DIR_SEP SYSTEM_DEFAULT_FONT_FILE
+# define DEFAULT_FONT_FILE SYSTEM_DEFAULT_FONT_FILE
#endif
#ifndef DEFAULT_FAMILY
@@ -96,8 +95,7 @@ extern "C" {
#endif
#ifndef DEFAULT_MONOSPACE_FONT_FILE
-# define DEFAULT_MONOSPACE_FONT_FILE \
- SYSTEM_FONT_PATH DIR_SEP SYSTEM_DEFAULT_MONOSPACE_FONT_FILE
+# define DEFAULT_MONOSPACE_FONT_FILE SYSTEM_DEFAULT_MONOSPACE_FONT_FILE
#endif
#ifndef DEFAULT_MONOSPACE_FAMILY
@@ -184,16 +182,7 @@ vlc_family_t *Android_GetFallbacks( filter_t *p_filter, const char *psz_family,
int Android_Prepare( filter_t *p_filter );
#endif /* __ANDROID__ */
-char* Dummy_Select( filter_t *p_filter, const char* family,
- bool b_bold, bool b_italic,
- int *i_idx, uni_char_t codepoint );
-
-#define File_Select(a) Dummy_Select(NULL, a, 0, 0, NULL, 0)
-
-char* Generic_Select( filter_t *p_filter, const char* family,
- bool b_bold, bool b_italic,
- int *i_idx, uni_char_t codepoint );
-
+const vlc_family_t * StaticMap_GetFamily( filter_t *p_filter, const char *psz_family );
/* ******************
* Family and fonts *
@@ -299,6 +288,8 @@ vlc_family_t *SearchFallbacks( filter_t *p_filter, vlc_family_t *p_fallbacks,
uni_char_t codepoint );
FT_Face GetFace( filter_t *p_filter, vlc_font_t *p_font, uni_char_t codepoint );
+char * MakeFilePath( filter_t *p_filter, const char *psz_filename );
+
#ifdef __cplusplus
}
#endif
More information about the vlc-commits
mailing list