And use unix_name + face_index as identifier instead of dev/ino.
Signed-off-by: Rémi Bernon rbernon@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;