[PATCH 4/8] gdi32: Create face from unix_name, face_index and flags.
Rémi Bernon
rbernon at codeweavers.com
Wed Sep 9 05:22:00 CDT 2020
And use unix_name + face_index as identifier instead of dev/ino.
Signed-off-by: Rémi Bernon <rbernon at codeweavers.com>
---
This will make it possible to use FreeType cache later, using Face* as
FTC_FaceID, and load FT_Face from them when needed.
dlls/gdi32/freetype.c | 151 ++++++++++++++++++------------------------
1 file changed, 64 insertions(+), 87 deletions(-)
diff --git a/dlls/gdi32/freetype.c b/dlls/gdi32/freetype.c
index f3f66e223e4..d0b076ce6fd 100644
--- a/dlls/gdi32/freetype.c
+++ b/dlls/gdi32/freetype.c
@@ -269,23 +269,27 @@ struct enum_data
typedef struct tagFace {
struct list entry;
LONG ref;
+ const char *unix_name;
+ FT_Long face_index;
+ DWORD flags;
WCHAR *style_name;
WCHAR *full_name;
WCHAR *file;
- dev_t dev;
- ino_t ino;
- FT_Long face_index;
FONTSIGNATURE fs;
DWORD ntmFlags;
FT_Fixed font_version;
BOOL scalable;
Bitmap_Size size; /* set if face is a bitmap */
- DWORD flags; /* ADDFONT flags */
struct tagFamily *family;
/* Cached data for Enum */
struct enum_data *cached_enum_data;
} Face;
+static inline const char *debugstr_face( Face *face )
+{
+ return wine_dbg_sprintf( "%s:%ld", debugstr_a(face->unix_name), face->face_index );
+}
+
#define FS_DBCS_MASK (FS_JISJAPAN|FS_CHINESESIMP|FS_WANSUNG|FS_CHINESETRAD|FS_JOHAB)
#define ADDFONT_EXTERNAL_FONT 0x01
@@ -585,7 +589,7 @@ static const WCHAR face_y_ppem_value[] = {'Y','p','p','e','m',0};
static const WCHAR face_flags_value[] = {'F','l','a','g','s',0};
static const WCHAR face_internal_leading_value[] = {'I','n','t','e','r','n','a','l',' ','L','e','a','d','i','n','g',0};
static const WCHAR face_font_sig_value[] = {'F','o','n','t',' ','S','i','g','n','a','t','u','r','e',0};
-static const WCHAR face_file_name_value[] = {'F','i','l','e',' ','N','a','m','e','\0'};
+static const WCHAR face_unix_name_value[] = {'U','n','i','x',' ','N','a','m','e','\0'};
static const WCHAR face_full_name_value[] = {'F','u','l','l',' ','N','a','m','e','\0'};
@@ -593,8 +597,7 @@ struct font_mapping
{
struct list entry;
int refcount;
- dev_t dev;
- ino_t ino;
+ char *unix_name;
void *data;
size_t size;
};
@@ -623,7 +626,7 @@ static Family *family_create( const WCHAR *family_name, const WCHAR *english_nam
static ULONG family_addref( Family *family );
static ULONG family_release( Family *family );
-static Face *face_create( void );
+static Face *face_create( const char *unix_name, DWORD face_index, DWORD flags );
static ULONG face_addref( Face *face );
static ULONG face_release( Face *face );
@@ -1177,14 +1180,6 @@ static WCHAR *towstr(UINT cp, const char *str)
return wstr;
}
-static char *strWtoA(UINT cp, const WCHAR *str)
-{
- int len = WideCharToMultiByte( cp, 0, str, -1, NULL, 0, NULL, NULL );
- char *ret = HeapAlloc( GetProcessHeap(), 0, len );
- WideCharToMultiByte( cp, 0, str, -1, ret, len, NULL, NULL );
- return ret;
-}
-
static void split_subst_info(NameCs *nc, LPSTR str)
{
CHAR *p = strrchr(str, ',');
@@ -1574,17 +1569,26 @@ static ULONG family_release( Family *family )
return ref;
}
-static Face *face_create( void )
+static Face *face_create( const char *unix_name, DWORD face_index, DWORD flags )
{
Face *face;
- if (!(face = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*face) ))) return NULL;
+ if (!(face = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*face) + strlen( unix_name ) + 1 )))
+ return NULL;
face->ref = 1;
- TRACE( "face %p\n", face );
+ TRACE( "face %p, unix_name %s, face_index %u, flags %#x\n", face, unix_name, face_index, flags );
list_init( &face->entry );
+ face->unix_name = (char *)(face + 1);
+ face->face_index = face_index;
+ face->flags = flags;
+ strcpy( (char *)face->unix_name, unix_name );
+
+ face->file = towstr( CP_UNIXCP, face->unix_name );
+ if (!HIWORD( face->flags )) face->flags |= ADDFONT_AA_FLAGS( default_aa_flags );
+
return face;
}
@@ -1646,22 +1650,20 @@ static BOOL insert_face_in_family_list( Face *face, Family *family )
debugstr_w(face->full_name), debugstr_w(family->family_name),
cursor->font_version, face->font_version );
- if (face->dev == cursor->dev && face->ino == cursor->ino)
+ if (face->face_index == cursor->face_index && !strcmp( face->unix_name, cursor->unix_name ))
{
- TRACE( "Font %s already in list\n", debugstr_w(face->file) );
+ TRACE( "face %s already in list\n", debugstr_face(face) );
face_addref( cursor );
return FALSE;
}
if (face->font_version <= cursor->font_version)
{
- TRACE("Original font %s is newer so skipping %s\n",
- debugstr_w(cursor->file), debugstr_w(face->file));
+ TRACE( "Original %s is newer so skipping %s\n", debugstr_face(cursor), debugstr_face(face) );
return FALSE;
}
else
{
- TRACE("Replacing original %s with %s\n",
- debugstr_w(cursor->file), debugstr_w(face->file));
+ TRACE( "Replacing original %s with %s\n", debugstr_face(cursor), debugstr_face(face) );
list_add_before( &cursor->entry, &face->entry );
face->family = family;
family_addref( family );
@@ -1675,7 +1677,7 @@ static BOOL insert_face_in_family_list( Face *face, Family *family )
}
TRACE( "Adding face %s in family %s from %s\n", debugstr_w(face->full_name),
- debugstr_w(family->family_name), debugstr_w(face->file) );
+ debugstr_w(family->family_name), debugstr_face(face) );
list_add_before( &cursor->entry, &face->entry );
face->family = family;
family_addref( family );
@@ -1719,17 +1721,18 @@ static inline LONG reg_save_dword(HKEY hkey, const WCHAR *value, DWORD data)
static void load_face(HKEY hkey_face, WCHAR *face_name, Family *family, void *buffer, DWORD buffer_size)
{
- DWORD needed, strike_index = 0;
+ DWORD face_index, flags, needed, strike_index = 0;
HKEY hkey_strike;
Face *face;
/* If we have a File Name key then this is a real font, not just the parent
key of a bunch of non-scalable strikes */
needed = buffer_size;
- if (RegQueryValueExW( hkey_face, face_file_name_value, NULL, NULL, buffer, &needed ) == ERROR_SUCCESS &&
- (face = face_create()))
+ if (RegQueryValueExW( hkey_face, face_unix_name_value, NULL, NULL, buffer, &needed ) == ERROR_SUCCESS &&
+ reg_load_dword( hkey_face, face_index_value, &face_index ) == ERROR_SUCCESS &&
+ reg_load_dword( hkey_face, face_flags_value, &flags ) == ERROR_SUCCESS &&
+ (face = face_create( buffer, face_index, flags )))
{
- face->file = strdupW( buffer );
face->style_name = strdupW( face_name );
needed = buffer_size;
@@ -1742,10 +1745,8 @@ static void load_face(HKEY hkey_face, WCHAR *face_name, Family *family, void *bu
}
face->full_name = strdupW( buffer );
- reg_load_ftlong(hkey_face, face_index_value, &face->face_index);
reg_load_dword(hkey_face, face_ntmflags_value, &face->ntmFlags);
reg_load_ftlong(hkey_face, face_version_value, &face->font_version);
- reg_load_dword(hkey_face, face_flags_value, &face->flags);
needed = sizeof(face->fs);
RegQueryValueExW(hkey_face, face_font_sig_value, NULL, NULL, (BYTE*)&face->fs, &needed);
@@ -1924,15 +1925,16 @@ static void add_face_to_cache(Face *face)
if(!face->scalable)
HeapFree(GetProcessHeap(), 0, face_key_name);
- RegSetValueExW(hkey_face, face_file_name_value, 0, REG_SZ, (BYTE *)face->file,
- (strlenW(face->file) + 1) * sizeof(WCHAR));
+ RegSetValueExW( hkey_face, face_unix_name_value, 0, REG_BINARY, (BYTE *)face->unix_name,
+ strlen( face->unix_name ) + 1 );
+ reg_save_dword( hkey_face, face_index_value, face->face_index );
+ reg_save_dword( hkey_face, face_flags_value, face->flags );
+
RegSetValueExW( hkey_face, face_full_name_value, 0, REG_SZ, (BYTE *)face->full_name,
(strlenW( face->full_name ) + 1) * sizeof(WCHAR) );
- reg_save_dword(hkey_face, face_index_value, face->face_index);
reg_save_dword(hkey_face, face_ntmflags_value, face->ntmFlags);
reg_save_dword(hkey_face, face_version_value, face->font_version);
- if (face->flags) reg_save_dword(hkey_face, face_flags_value, face->flags);
RegSetValueExW(hkey_face, face_font_sig_value, 0, REG_BINARY, (BYTE*)&face->fs, sizeof(face->fs));
@@ -2142,34 +2144,20 @@ static inline void get_fontsig( FT_Face ft_face, FONTSIGNATURE *fs )
static Face *create_face( FT_Face ft_face, FT_Long face_index, const char *file, DWORD flags )
{
- struct stat st;
Face *face;
- if (!(face = face_create())) return NULL;
+ if (!(face = face_create( file, face_index, flags ))) return NULL;
face->style_name = ft_face_get_style_name( ft_face, GetSystemDefaultLangID() );
face->full_name = ft_face_get_full_name( ft_face, GetSystemDefaultLangID() );
- if (flags & ADDFONT_VERTICAL_FONT) face->full_name = get_vertical_name( face->full_name );
-
- face->dev = 0;
- face->ino = 0;
- face->file = towstr( CP_UNIXCP, file );
- if (!stat( file, &st ))
- {
- face->dev = st.st_dev;
- face->ino = st.st_ino;
- }
+ if (face->flags & ADDFONT_VERTICAL_FONT) face->full_name = get_vertical_name( face->full_name );
- face->face_index = face_index;
get_fontsig( ft_face, &face->fs );
face->ntmFlags = get_ntm_flags( ft_face );
face->font_version = get_font_version( ft_face );
if (!(face->scalable = FT_IS_SCALABLE( ft_face ))) get_bitmap_size( ft_face, &face->size );
- if (!HIWORD( flags )) flags |= ADDFONT_AA_FLAGS( default_aa_flags );
- face->flags = flags;
-
TRACE("fsCsb = %08x %08x/%08x %08x %08x %08x\n",
face->fs.fsCsb[0], face->fs.fsCsb[1],
face->fs.fsUsb[0], face->fs.fsUsb[1],
@@ -2339,28 +2327,26 @@ static int remove_font_resource( const WCHAR *file, DWORD flags )
{
Family *family, *family_next;
Face *face, *face_next;
- struct stat st;
int count = 0;
char *unixname;
if (!(unixname = wine_get_unix_file_name( file ))) return 0;
- if (stat( unixname, &st ) == -1) goto done;
LIST_FOR_EACH_ENTRY_SAFE( family, family_next, &font_list, Family, entry )
{
family_addref( family );
LIST_FOR_EACH_ENTRY_SAFE( face, face_next, &family->faces, Face, entry )
{
if (LOWORD(face->flags) != LOWORD(flags)) continue;
- if (st.st_dev == face->dev && st.st_ino == face->ino)
+ if (!strcmp( unixname, face->unix_name ))
{
- TRACE( "removing matching face %s\n", debugstr_w(face->file) );
+ TRACE( "removing matching face %s\n", debugstr_face(face) );
face_release( face );
count++;
}
}
family_release( family );
}
-done:
+
HeapFree( GetProcessHeap(), 0, unixname );
return count;
}
@@ -2618,8 +2604,7 @@ static void populate_system_links(const WCHAR *name, const WCHAR *const *values)
child_font->font = NULL;
font_link->fs.fsCsb[0] |= face->fs.fsCsb[0];
font_link->fs.fsCsb[1] |= face->fs.fsCsb[1];
- TRACE("Adding file %s index %ld\n", debugstr_w(child_font->face->file),
- child_font->face->face_index);
+ TRACE( "Adding %s\n", debugstr_face(child_font->face) );
list_add_tail(&font_link->links, &child_font->entry);
TRACE("added internal SystemLink for %s to %s in %s\n", debugstr_w(name), debugstr_w(value),debugstr_w(file));
@@ -2699,8 +2684,7 @@ static void init_system_links(void)
child_font->font = NULL;
font_link->fs.fsCsb[0] |= face->fs.fsCsb[0];
font_link->fs.fsCsb[1] |= face->fs.fsCsb[1];
- TRACE("Adding file %s index %ld\n",
- debugstr_w(child_font->face->file), child_font->face->face_index);
+ TRACE( "Adding %s\n", debugstr_face(child_font->face) );
list_add_tail(&font_link->links, &child_font->entry);
}
list_add_tail(&system_links, &font_link->entry);
@@ -2758,8 +2742,7 @@ skip_internal:
child_font->font = NULL;
system_font_link->fs.fsCsb[0] |= face->fs.fsCsb[0];
system_font_link->fs.fsCsb[1] |= face->fs.fsCsb[1];
- TRACE("Found Tahoma in %s index %ld\n",
- debugstr_w(child_font->face->file), child_font->face->face_index);
+ TRACE( "Found Tahoma in %s\n", debugstr_face(child_font->face) );
list_add_tail(&system_font_link->links, &child_font->entry);
}
font_link = find_font_link(Tahoma);
@@ -3209,7 +3192,6 @@ static void update_reg_entries(void)
LIST_FOR_EACH_ENTRY( family, &font_list, Family, entry ) {
LIST_FOR_EACH_ENTRY( face, &family->faces, Face, entry ) {
- char *buffer;
if (!(face->flags & ADDFONT_EXTERNAL_FONT)) continue;
len = strlenW( face->full_name ) + 1;
@@ -3222,11 +3204,7 @@ static void update_reg_entries(void)
if (face->scalable)
strcatW(valueW, TrueType);
- buffer = strWtoA( CP_UNIXCP, face->file );
- path = wine_get_dos_file_name( buffer );
- HeapFree( GetProcessHeap(), 0, buffer );
-
- if (path)
+ if ((path = wine_get_dos_file_name( face->unix_name )))
{
if ((full_path = get_full_path_name(path)))
{
@@ -4509,14 +4487,14 @@ static struct font_mapping *map_font_file( const char *name )
LIST_FOR_EACH_ENTRY( mapping, &mappings_list, struct font_mapping, entry )
{
- if (mapping->dev == st.st_dev && mapping->ino == st.st_ino)
+ if (!strcmp( mapping->unix_name, name ))
{
mapping->refcount++;
close( fd );
return mapping;
}
}
- if (!(mapping = HeapAlloc( GetProcessHeap(), 0, sizeof(*mapping) )))
+ if (!(mapping = HeapAlloc( GetProcessHeap(), 0, sizeof(*mapping) + strlen( name ) + 1 )))
goto error;
mapping->data = mmap( NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0 );
@@ -4528,8 +4506,8 @@ static struct font_mapping *map_font_file( const char *name )
return NULL;
}
mapping->refcount = 1;
- mapping->dev = st.st_dev;
- mapping->ino = st.st_ino;
+ mapping->unix_name = (char *)(mapping + 1);
+ strcpy( mapping->unix_name, name );
mapping->size = st.st_size;
list_add_tail( &mappings_list, &mapping->entry );
return mapping;
@@ -4556,17 +4534,14 @@ static FT_Face OpenFontFace(GdiFont *font, Face *face, LONG width, LONG height)
FT_Error err;
FT_Face ft_face;
void *data_ptr;
- char *filename;
DWORD data_size;
- TRACE( "%s, %d x %d\n", debugstr_w(face->file), width, height );
+ TRACE( "%s, %d x %d\n", debugstr_face(face), width, height );
- filename = strWtoA( CP_UNIXCP, face->file );
- font->mapping = map_font_file( filename );
- HeapFree( GetProcessHeap(), 0, filename );
+ font->mapping = map_font_file( face->unix_name );
if (!font->mapping)
{
- WARN( "failed to map %s\n", debugstr_w(face->file) );
+ WARN( "failed to map %s\n", debugstr_face(face) );
return 0;
}
data_ptr = font->mapping->data;
@@ -4652,8 +4627,7 @@ static int get_nearest_charset(const WCHAR *family_name, Face *face, int *cp)
}
}
- FIXME("returning DEFAULT_CHARSET face->fs.fsCsb[0] = %08x file = %s\n",
- face->fs.fsCsb[0], debugstr_w(face->file));
+ FIXME( "returning DEFAULT_CHARSET face->fs.fsCsb[0] = %08x %s\n", face->fs.fsCsb[0], debugstr_face(face) );
*cp = acp;
return DEFAULT_CHARSET;
}
@@ -5086,7 +5060,7 @@ static BOOL create_child_font_list(GdiFont *font)
new_child->font = NULL;
face_addref( new_child->face );
list_add_tail(&font->child_fonts, &new_child->entry);
- TRACE("font %s %ld\n", debugstr_w(new_child->face->file), new_child->face->face_index);
+ TRACE( "face %s\n", debugstr_face(new_child->face) );
}
ret = TRUE;
}
@@ -5109,7 +5083,7 @@ static BOOL create_child_font_list(GdiFont *font)
new_child->font = NULL;
face_addref( new_child->face );
list_add_tail(&font->child_fonts, &new_child->entry);
- TRACE("font %s %ld\n", debugstr_w(new_child->face->file), new_child->face->face_index);
+ TRACE( "face %s\n", debugstr_face(new_child->face) );
}
ret = TRUE;
}
@@ -5480,14 +5454,17 @@ static void fill_fileinfo_from_face( GdiFont *font, Face *face )
{
WIN32_FILE_ATTRIBUTE_DATA info;
SIZE_T path_size;
+ WCHAR *path;
+
+ if (!(path = wine_get_dos_file_name( face->unix_name ))) path_size = 0;
+ else path_size = strlenW( path ) * sizeof(WCHAR);
- path_size = strlenW( face->file ) * sizeof(WCHAR);
font->fileinfo = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*font->fileinfo) + path_size );
- if (GetFileAttributesExW(face->file, GetFileExInfoStandard, &info))
+ if (path && GetFileAttributesExW( path, GetFileExInfoStandard, &info ))
{
font->fileinfo->writetime = info.ftLastWriteTime;
font->fileinfo->size.QuadPart = (LONGLONG)info.nFileSizeHigh << 32 | info.nFileSizeLow;
- strcpyW(font->fileinfo->path, face->file);
+ strcpyW( font->fileinfo->path, path );
}
/* clear the path if the face was supposed to be loaded from memory */
@@ -5840,7 +5817,7 @@ found_face:
else
ret->charset = get_nearest_charset( family->family_name, face, &ret->codepage );
- TRACE( "Chosen: %s (%s:%ld)\n", debugstr_w(face->full_name), debugstr_w(face->file), face->face_index );
+ TRACE( "Chosen: %s from %s\n", debugstr_w(face->full_name), debugstr_face(face) );
ret->aveWidth = height ? lf.lfWidth : 0;
--
2.28.0
More information about the wine-devel
mailing list