Rémi Bernon : gdi32: Load font list directly from fontconfig cache.
Alexandre Julliard
julliard at winehq.org
Fri Nov 20 14:54:32 CST 2020
Module: wine
Branch: master
Commit: a51d68e35c53f94f2af28ede3b008c5166b8f741
URL: https://source.winehq.org/git/wine.git/?a=commit;h=a51d68e35c53f94f2af28ede3b008c5166b8f741
Author: Rémi Bernon <rbernon at codeweavers.com>
Date: Fri Nov 20 10:40:41 2020 +0000
gdi32: Load font list directly from fontconfig cache.
Instead of going through the -slow- font matching.
Signed-off-by: Rémi Bernon <rbernon at codeweavers.com>
Signed-off-by: Huw Davies <huw at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
dlls/gdi32/freetype.c | 169 +++++++++++++++++++++++++++++++++++++-------------
1 file changed, 125 insertions(+), 44 deletions(-)
diff --git a/dlls/gdi32/freetype.c b/dlls/gdi32/freetype.c
index 45b5e94d341..7d8bc5f5b05 100644
--- a/dlls/gdi32/freetype.c
+++ b/dlls/gdi32/freetype.c
@@ -190,6 +190,20 @@ MAKE_FUNCPTR(FcPatternDestroy);
MAKE_FUNCPTR(FcPatternGetBool);
MAKE_FUNCPTR(FcPatternGetInteger);
MAKE_FUNCPTR(FcPatternGetString);
+MAKE_FUNCPTR(FcConfigGetFontDirs);
+MAKE_FUNCPTR(FcConfigGetCurrent);
+MAKE_FUNCPTR(FcCacheCopySet);
+MAKE_FUNCPTR(FcCacheNumSubdir);
+MAKE_FUNCPTR(FcCacheSubdir);
+MAKE_FUNCPTR(FcDirCacheRead);
+MAKE_FUNCPTR(FcDirCacheUnload);
+MAKE_FUNCPTR(FcStrListCreate);
+MAKE_FUNCPTR(FcStrListDone);
+MAKE_FUNCPTR(FcStrListNext);
+MAKE_FUNCPTR(FcStrSetAdd);
+MAKE_FUNCPTR(FcStrSetCreate);
+MAKE_FUNCPTR(FcStrSetDestroy);
+MAKE_FUNCPTR(FcStrSetMember);
#ifndef FC_NAMELANG
#define FC_NAMELANG "namelang"
#endif
@@ -1346,6 +1360,51 @@ static FcPattern *create_family_pattern( const char *name )
return NULL;
}
+static void fontconfig_add_font( FcPattern *pattern, DWORD flags )
+{
+ const char *unix_name, *format;
+ WCHAR *dos_name;
+ FcBool scalable;
+ DWORD aa_flags;
+ int face_index;
+
+ TRACE( "(%p %#x)\n", pattern, flags );
+
+ if (pFcPatternGetString( pattern, FC_FILE, 0, (FcChar8 **)&unix_name ) != FcResultMatch)
+ return;
+
+ if (pFcPatternGetBool( pattern, FC_SCALABLE, 0, &scalable ) != FcResultMatch)
+ scalable = FALSE;
+
+ if (pFcPatternGetString( pattern, FC_FONTFORMAT, 0, (FcChar8 **)&format ) != FcResultMatch)
+ {
+ TRACE( "ignoring unknown font format %s\n", debugstr_a(unix_name) );
+ return;
+ }
+
+ if (!strcmp( format, "Type 1" ))
+ {
+ TRACE( "ignoring Type 1 font %s\n", debugstr_a(unix_name) );
+ return;
+ }
+
+ if (!scalable && !(flags & ADDFONT_ALLOW_BITMAP))
+ {
+ TRACE( "ignoring non-scalable font %s\n", debugstr_a(unix_name) );
+ return;
+ }
+
+ if (!(aa_flags = parse_aa_pattern( pattern ))) aa_flags = default_aa_flags;
+ flags |= ADDFONT_AA_FLAGS(aa_flags);
+
+ if (pFcPatternGetInteger( pattern, FC_INDEX, 0, &face_index ) != FcResultMatch)
+ face_index = 0;
+
+ dos_name = get_dos_file_name( unix_name );
+ add_unix_face( unix_name, dos_name, NULL, 0, face_index, flags, NULL );
+ RtlFreeHeap( GetProcessHeap(), 0, dos_name );
+}
+
static void init_fontconfig(void)
{
void *fc_handle = dlopen(SONAME_LIBFONTCONFIG, RTLD_NOW);
@@ -1369,6 +1428,20 @@ static void init_fontconfig(void)
LOAD_FUNCPTR(FcPatternGetBool);
LOAD_FUNCPTR(FcPatternGetInteger);
LOAD_FUNCPTR(FcPatternGetString);
+ LOAD_FUNCPTR(FcConfigGetFontDirs);
+ LOAD_FUNCPTR(FcConfigGetCurrent);
+ LOAD_FUNCPTR(FcCacheCopySet);
+ LOAD_FUNCPTR(FcCacheNumSubdir);
+ LOAD_FUNCPTR(FcCacheSubdir);
+ LOAD_FUNCPTR(FcDirCacheRead);
+ LOAD_FUNCPTR(FcDirCacheUnload);
+ LOAD_FUNCPTR(FcStrListCreate);
+ LOAD_FUNCPTR(FcStrListDone);
+ LOAD_FUNCPTR(FcStrListNext);
+ LOAD_FUNCPTR(FcStrSetAdd);
+ LOAD_FUNCPTR(FcStrSetCreate);
+ LOAD_FUNCPTR(FcStrSetDestroy);
+ LOAD_FUNCPTR(FcStrSetMember);
#undef LOAD_FUNCPTR
if (pFcInit())
@@ -1394,61 +1467,69 @@ static void init_fontconfig(void)
}
}
-static void load_fontconfig_fonts(void)
+static void fontconfig_add_fonts_from_dir_list( FcConfig *config, FcStrList *dir_list, FcStrSet *done_set, DWORD flags )
{
- FcPattern *pat;
- FcFontSet *fontset;
- const char *format;
+ const FcChar8 *dir;
+ FcFontSet *font_set;
+ FcStrList *subdir_list = NULL;
+ FcStrSet *subdir_set = NULL;
+ FcCache *cache = NULL;
int i;
- char *file;
- if (!fontconfig_enabled) return;
-
- pat = pFcPatternCreate();
- if (!pat) return;
+ TRACE( "(%p %p %p %#x)\n", config, dir_list, done_set, flags );
- fontset = pFcFontList(NULL, pat, NULL);
- if (!fontset)
+ while ((dir = pFcStrListNext( dir_list )))
{
- pFcPatternDestroy(pat);
- return;
+ if (pFcStrSetMember( done_set, dir )) continue;
+
+ TRACE( "adding fonts from %s\n", dir );
+ if (!(cache = pFcDirCacheRead( dir, FcFalse, config ))) continue;
+
+ if (!(font_set = pFcCacheCopySet( cache ))) goto done;
+ for (i = 0; i < font_set->nfont; i++)
+ fontconfig_add_font( font_set->fonts[i], flags );
+ pFcFontSetDestroy( font_set );
+ font_set = NULL;
+
+ if (!(subdir_set = pFcStrSetCreate())) goto done;
+ for (i = 0; i < pFcCacheNumSubdir( cache ); i++)
+ pFcStrSetAdd( subdir_set, pFcCacheSubdir( cache, i ) );
+ pFcDirCacheUnload( cache );
+ cache = NULL;
+
+ if (!(subdir_list = pFcStrListCreate( subdir_set ))) goto done;
+ pFcStrSetDestroy( subdir_set );
+ subdir_set = NULL;
+
+ pFcStrSetAdd( done_set, dir );
+ fontconfig_add_fonts_from_dir_list( config, subdir_list, done_set, flags );
+ pFcStrListDone( subdir_list );
+ subdir_list = NULL;
}
- for(i = 0; i < fontset->nfont; i++) {
- FcBool scalable;
- DWORD aa_flags;
-
- if(pFcPatternGetString(fontset->fonts[i], FC_FILE, 0, (FcChar8**)&file) != FcResultMatch)
- continue;
-
- pFcConfigSubstitute( NULL, fontset->fonts[i], FcMatchFont );
-
- if(pFcPatternGetBool(fontset->fonts[i], FC_SCALABLE, 0, &scalable) == FcResultMatch && !scalable)
- {
- TRACE("not scalable\n");
- continue;
- }
+done:
+ if (font_set) pFcFontSetDestroy( font_set );
+ if (subdir_list) pFcStrListDone( subdir_list );
+ if (subdir_set) pFcStrSetDestroy( subdir_set );
+ if (cache) pFcDirCacheUnload( cache );
+}
- if (pFcPatternGetString( fontset->fonts[i], FC_FONTFORMAT, 0, (FcChar8 **)&format ) != FcResultMatch)
- {
- TRACE( "ignoring unknown font format %s\n", debugstr_a(file) );
- continue;
- }
+static void load_fontconfig_fonts( void )
+{
+ FcStrList *dir_list = NULL;
+ FcStrSet *done_set = NULL;
+ FcConfig *config;
- if (!strcmp( format, "Type 1" ))
- {
- TRACE( "ignoring Type 1 font %s\n", debugstr_a(file) );
- continue;
- }
+ if (!fontconfig_enabled) return;
+ if (!(config = pFcConfigGetCurrent())) goto done;
+ if (!(done_set = pFcStrSetCreate())) goto done;
+ if (!(dir_list = pFcConfigGetFontDirs( config ))) goto done;
- aa_flags = parse_aa_pattern( fontset->fonts[i] );
- TRACE("fontconfig: %s aa %x\n", file, aa_flags);
+ fontconfig_add_fonts_from_dir_list( config, dir_list, done_set, ADDFONT_EXTERNAL_FONT | ADDFONT_ADD_TO_CACHE );
- AddFontToList( NULL, file, NULL, 0,
- ADDFONT_EXTERNAL_FONT | ADDFONT_ADD_TO_CACHE | ADDFONT_AA_FLAGS(aa_flags) );
- }
- pFcFontSetDestroy(fontset);
- pFcPatternDestroy(pat);
+done:
+ if (dir_list) pFcStrListDone( dir_list );
+ if (done_set) pFcStrSetDestroy( done_set );
}
#elif defined(HAVE_CARBON_CARBON_H)
More information about the wine-cvs
mailing list