[vlc-commits] freetype: implement GDI font linking fallback
vlc | branch: master | Francois Cartegnie | Fri Aug 21 00:10:34 2020 +0200| [db28beebd7d93cbf69003440570f008ac6ec88cd] | committer: Francois Cartegnie freetype: implement GDI font linking fallback > http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=db28beebd7d93cbf69003440570f008ac6ec88cd --- modules/text_renderer/freetype/fonts/backends.h | 1 + modules/text_renderer/freetype/fonts/win32.c| 115 +--- modules/text_renderer/freetype/platform_fonts.c | 8 ++ 3 files changed, 114 insertions(+), 10 deletions(-) diff --git a/modules/text_renderer/freetype/fonts/backends.h b/modules/text_renderer/freetype/fonts/backends.h index abfc1b1ca5..6730ba46a4 100644 --- a/modules/text_renderer/freetype/fonts/backends.h +++ b/modules/text_renderer/freetype/fonts/backends.h @@ -64,6 +64,7 @@ struct vlc_font_select_t #if defined( _WIN32 ) void *p_dw_sys; +vlc_dictionary_t fontlinking_map; #endif }; diff --git a/modules/text_renderer/freetype/fonts/win32.c b/modules/text_renderer/freetype/fonts/win32.c index 8b5f22c67c..17cc85371b 100644 --- a/modules/text_renderer/freetype/fonts/win32.c +++ b/modules/text_renderer/freetype/fonts/win32.c @@ -59,6 +59,7 @@ #if !VLC_WINSTORE_APP #define FONT_DIR_NT TEXT("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Fonts") +#define FONT_LINKING_NT TEXT("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\FontLink\\SystemLink") static inline void AppendFamily( vlc_family_t **pp_list, vlc_family_t *p_family ) { @@ -396,6 +397,82 @@ static int CALLBACK EnumFontCallback(const ENUMLOGFONTEX *lpelfe, const NEWTEXTM return 1; } +static void FillLinkedFontsForFamily( vlc_font_select_t *fs, + LPTSTR name, vlc_family_t *p_family ) +{ +HDC hDC = GetDC( NULL ); +if( !hDC ) +return; + +struct enumFontCallbackContext ctx; +ctx.fs = fs; +ctx.p_family = p_family; +ctx.prevFullName[0] = 0; + +LOGFONT lf = { 0 }; +lf.lfCharSet = DEFAULT_CHARSET; +wcsncpy( (LPTSTR), name, LF_FACESIZE ); + +EnumFontFamiliesEx( hDC, , (FONTENUMPROC), (LPARAM), 0 ); +ReleaseDC( NULL, hDC ); +} + +static int AddLinkedFonts( vlc_font_select_t *fs, const char *psz_family, + vlc_family_t *p_family ) +{ +HKEY fontLinkKey; +if (FAILED(RegOpenKeyEx( HKEY_LOCAL_MACHINE, FONT_LINKING_NT, + 0, KEY_READ, ))) +return VLC_EGENERIC; + +LPTSTR psz_buffer = ToWide( psz_family ); +if( !psz_buffer ) +{ +RegCloseKey( fontLinkKey ); +return VLC_EGENERIC; +} + +DWORD linkedFontsBufferSize = 0; +DWORD lpType; +if( FAILED(RegQueryValueEx( fontLinkKey, psz_buffer, 0, , + NULL, )) ) +{ +free( psz_buffer ); +RegCloseKey( fontLinkKey ); +return VLC_EGENERIC; +} + +WCHAR* linkedFonts = (WCHAR*) malloc(linkedFontsBufferSize); + +if ( linkedFonts && + SUCCEEDED(RegQueryValueEx( fontLinkKey, psz_buffer, 0, , + (BYTE*)linkedFonts, ) ) +&& lpType == REG_MULTI_SZ) +{ +DWORD start = 0; +for( DWORD i=0; i < linkedFontsBufferSize / sizeof(WCHAR); i++ ) +{ +if( linkedFonts[i] == 0 && i > start ) +{ +for( DWORD j=start + 1; j < i; j++ ) +{ +if( linkedFonts[j] != ',' ) +continue; +FillLinkedFontsForFamily( fs, [j + 1], p_family ); +break; +} +start = i + 1; +} +} +} + +free(psz_buffer); +free(linkedFonts); +RegCloseKey(fontLinkKey); + +return VLC_SUCCESS; +} + int Win32_GetFamily( vlc_font_select_t *fs, const char *psz_lcname, const vlc_family_t **pp_result ) { vlc_family_t *p_family = @@ -531,6 +608,7 @@ int Win32_GetFallbacks( vlc_font_select_t *fs, const char *psz_lcname, vlc_family_t *p_family = NULL; vlc_family_t *p_fallbacks = NULL; char *psz_uniscribe = NULL; +char *psz_linkname = NULL; inti_ret = VLC_EGENERIC; p_fallbacks = vlc_dictionary_value_for_key( >fallback_map, psz_lcname ); @@ -553,23 +631,39 @@ int Win32_GetFallbacks( vlc_font_select_t *fs, const char *psz_lcname, goto done; } -const vlc_family_t *p_uniscribe = NULL; -if( Win32_GetFamily( fs, psz_uniscribe, _uniscribe ) != VLC_SUCCESS ) -goto done; - -if( !p_uniscribe || !p_uniscribe->p_fonts || -!CheckFace( fs, p_uniscribe->p_fonts, codepoint ) ) +/* Search for existing listing inserted from a different + * codepoint in fallbacks (and that means the fallback will not work) */ +for( vlc_family_t *p = p_fallbacks; p; p = p->p_next ) { -i_ret = VLC_SUCCESS; -
[vlc-commits] freetype: implement GDI font linking fallback
vlc | branch: master | Francois Cartegnie | Fri Aug 21 00:10:34 2020 +0200| [a813845992587fbeaa434156d5b0d568e885bc48] | committer: Francois Cartegnie freetype: implement GDI font linking fallback > http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=a813845992587fbeaa434156d5b0d568e885bc48 --- modules/text_renderer/freetype/fonts/backends.h | 1 + modules/text_renderer/freetype/fonts/win32.c| 115 +--- modules/text_renderer/freetype/platform_fonts.c | 8 ++ 3 files changed, 114 insertions(+), 10 deletions(-) diff --git a/modules/text_renderer/freetype/fonts/backends.h b/modules/text_renderer/freetype/fonts/backends.h index abfc1b1ca5..6730ba46a4 100644 --- a/modules/text_renderer/freetype/fonts/backends.h +++ b/modules/text_renderer/freetype/fonts/backends.h @@ -64,6 +64,7 @@ struct vlc_font_select_t #if defined( _WIN32 ) void *p_dw_sys; +vlc_dictionary_t fontlinking_map; #endif }; diff --git a/modules/text_renderer/freetype/fonts/win32.c b/modules/text_renderer/freetype/fonts/win32.c index 8b5f22c67c..17cc85371b 100644 --- a/modules/text_renderer/freetype/fonts/win32.c +++ b/modules/text_renderer/freetype/fonts/win32.c @@ -59,6 +59,7 @@ #if !VLC_WINSTORE_APP #define FONT_DIR_NT TEXT("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Fonts") +#define FONT_LINKING_NT TEXT("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\FontLink\\SystemLink") static inline void AppendFamily( vlc_family_t **pp_list, vlc_family_t *p_family ) { @@ -396,6 +397,82 @@ static int CALLBACK EnumFontCallback(const ENUMLOGFONTEX *lpelfe, const NEWTEXTM return 1; } +static void FillLinkedFontsForFamily( vlc_font_select_t *fs, + LPTSTR name, vlc_family_t *p_family ) +{ +HDC hDC = GetDC( NULL ); +if( !hDC ) +return; + +struct enumFontCallbackContext ctx; +ctx.fs = fs; +ctx.p_family = p_family; +ctx.prevFullName[0] = 0; + +LOGFONT lf = { 0 }; +lf.lfCharSet = DEFAULT_CHARSET; +wcsncpy( (LPTSTR), name, LF_FACESIZE ); + +EnumFontFamiliesEx( hDC, , (FONTENUMPROC), (LPARAM), 0 ); +ReleaseDC( NULL, hDC ); +} + +static int AddLinkedFonts( vlc_font_select_t *fs, const char *psz_family, + vlc_family_t *p_family ) +{ +HKEY fontLinkKey; +if (FAILED(RegOpenKeyEx( HKEY_LOCAL_MACHINE, FONT_LINKING_NT, + 0, KEY_READ, ))) +return VLC_EGENERIC; + +LPTSTR psz_buffer = ToWide( psz_family ); +if( !psz_buffer ) +{ +RegCloseKey( fontLinkKey ); +return VLC_EGENERIC; +} + +DWORD linkedFontsBufferSize = 0; +DWORD lpType; +if( FAILED(RegQueryValueEx( fontLinkKey, psz_buffer, 0, , + NULL, )) ) +{ +free( psz_buffer ); +RegCloseKey( fontLinkKey ); +return VLC_EGENERIC; +} + +WCHAR* linkedFonts = (WCHAR*) malloc(linkedFontsBufferSize); + +if ( linkedFonts && + SUCCEEDED(RegQueryValueEx( fontLinkKey, psz_buffer, 0, , + (BYTE*)linkedFonts, ) ) +&& lpType == REG_MULTI_SZ) +{ +DWORD start = 0; +for( DWORD i=0; i < linkedFontsBufferSize / sizeof(WCHAR); i++ ) +{ +if( linkedFonts[i] == 0 && i > start ) +{ +for( DWORD j=start + 1; j < i; j++ ) +{ +if( linkedFonts[j] != ',' ) +continue; +FillLinkedFontsForFamily( fs, [j + 1], p_family ); +break; +} +start = i + 1; +} +} +} + +free(psz_buffer); +free(linkedFonts); +RegCloseKey(fontLinkKey); + +return VLC_SUCCESS; +} + int Win32_GetFamily( vlc_font_select_t *fs, const char *psz_lcname, const vlc_family_t **pp_result ) { vlc_family_t *p_family = @@ -531,6 +608,7 @@ int Win32_GetFallbacks( vlc_font_select_t *fs, const char *psz_lcname, vlc_family_t *p_family = NULL; vlc_family_t *p_fallbacks = NULL; char *psz_uniscribe = NULL; +char *psz_linkname = NULL; inti_ret = VLC_EGENERIC; p_fallbacks = vlc_dictionary_value_for_key( >fallback_map, psz_lcname ); @@ -553,23 +631,39 @@ int Win32_GetFallbacks( vlc_font_select_t *fs, const char *psz_lcname, goto done; } -const vlc_family_t *p_uniscribe = NULL; -if( Win32_GetFamily( fs, psz_uniscribe, _uniscribe ) != VLC_SUCCESS ) -goto done; - -if( !p_uniscribe || !p_uniscribe->p_fonts || -!CheckFace( fs, p_uniscribe->p_fonts, codepoint ) ) +/* Search for existing listing inserted from a different + * codepoint in fallbacks (and that means the fallback will not work) */ +for( vlc_family_t *p = p_fallbacks; p; p = p->p_next ) { -i_ret = VLC_SUCCESS; -