[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