[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