[PATCH v2 6/7] gdi32: Store unix file name on font faces.

Rémi Bernon rbernon at codeweavers.com
Thu Sep 17 10:01:36 CDT 2020


So we can then more easily invert the creation order between faces and
ft_face, and eventually use FreeType cache with Face* as FTC_FaceID.

Signed-off-by: Rémi Bernon <rbernon at codeweavers.com>
---
 dlls/gdi32/freetype.c | 64 ++++++++++++++++---------------------------
 1 file changed, 24 insertions(+), 40 deletions(-)

diff --git a/dlls/gdi32/freetype.c b/dlls/gdi32/freetype.c
index 6ed4e52c70e..d2c47b0a263 100644
--- a/dlls/gdi32/freetype.c
+++ b/dlls/gdi32/freetype.c
@@ -272,6 +272,7 @@ typedef struct tagFace {
     WCHAR *style_name;
     WCHAR *full_name;
     WCHAR *file;
+    const char *unix_name;
     dev_t dev;
     ino_t ino;
     void *font_data_ptr;
@@ -290,7 +291,7 @@ typedef struct tagFace {
 
 static inline const char *debugstr_face( Face *face )
 {
-    if (face->file) return wine_dbg_sprintf( "%s (%ld)", debugstr_w(face->file), face->face_index );
+    if (face->unix_name) return wine_dbg_sprintf( "%s (%ld)", debugstr_a(face->unix_name), face->face_index );
     else return wine_dbg_sprintf( "%p-%p (%ld)", face->font_data_ptr, (char *)face->font_data_ptr + face->font_data_size, face->face_index );
 }
 
@@ -1177,14 +1178,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, ',');
@@ -1546,6 +1539,7 @@ static Face *face_create( const char *unix_name, DWORD face_index, void *font_da
                           DWORD font_data_size, DWORD flags )
 {
     struct stat st;
+    DWORD length = 0;
     Face *face;
     int fd;
 
@@ -1554,19 +1548,23 @@ static Face *face_create( const char *unix_name, DWORD face_index, void *font_da
 
     if (unix_name)
     {
+        length = strlen( unix_name ) + 1;
         if ((fd = open( unix_name, O_RDONLY )) == -1) return NULL;
         if (fstat( fd, &st )) return NULL;
         close( fd );
     }
 
-    if (!(face = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*face) ))) return NULL;
+    if (!(face = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*face) + length )))
+        return NULL;
     face->refcount = 1;
 
     list_init( &face->entry );
 
     if (unix_name)
     {
-        face->file = towstr( CP_UNIXCP, unix_name );
+        face->unix_name = (char *)(face + 1);
+        strcpy( (char *)face->unix_name, unix_name );
+        face->file = towstr( CP_UNIXCP, face->unix_name );
         face->dev = st.st_dev;
         face->ino = st.st_ino;
     }
@@ -1630,7 +1628,7 @@ 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->file && face->dev == cursor->dev && face->ino == cursor->ino)
+            if (face->unix_name && face->dev == cursor->dev && face->ino == cursor->ino)
             {
                 cursor->refcount++;
                 TRACE( "face %s already in list, refcount now %d\n", debugstr_face(face), cursor->refcount );
@@ -1903,7 +1901,6 @@ static void add_face_to_cache(Face *face)
 {
     HKEY hkey_family, hkey_face;
     WCHAR *face_key_name;
-    char *unix_name;
 
     RegCreateKeyExW( hkey_font_cache, face->family->family_name, 0, NULL, REG_OPTION_VOLATILE,
                      KEY_ALL_ACCESS, NULL, &hkey_family, NULL );
@@ -1923,9 +1920,8 @@ static void add_face_to_cache(Face *face)
     if(!face->scalable)
         HeapFree(GetProcessHeap(), 0, face_key_name);
 
-    unix_name = strWtoA( CP_UNIXCP, face->file );
-    RegSetValueExW( hkey_face, face_unix_name_value, 0, REG_BINARY, (BYTE *)unix_name, strlen( unix_name ) + 1 );
-    HeapFree( GetProcessHeap(), 0, unix_name );
+    RegSetValueExW( hkey_face, face_unix_name_value, 0, REG_BINARY, (BYTE *)face->unix_name,
+                    strlen( face->unix_name ) + 1 );
 
     RegSetValueExW( hkey_face, face_full_name_value, 0, REG_SZ, (BYTE *)face->full_name,
                     (strlenW( face->full_name ) + 1) * sizeof(WCHAR) );
@@ -2358,7 +2354,7 @@ static int remove_font_resource( const WCHAR *file, DWORD flags )
         family->refcount++;
         LIST_FOR_EACH_ENTRY_SAFE( face, face_next, &family->faces, Face, entry )
         {
-            if (!face->file) continue;
+            if (!face->unix_name) continue;
             if (LOWORD(face->flags) != LOWORD(flags)) continue;
             if (st.st_dev == face->dev && st.st_ino == face->ino)
             {
@@ -3218,7 +3214,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;
@@ -3231,11 +3226,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)))
                 {
@@ -4604,11 +4595,9 @@ static FT_Face OpenFontFace(GdiFont *font, Face *face, LONG width, LONG height)
 
     TRACE( "%s, %d x %d\n", debugstr_face(face), width, height );
 
-    if (face->file)
+    if (face->unix_name)
     {
-        char *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_face(face) );
@@ -5529,25 +5518,20 @@ static const VOID * get_GSUB_vert_feature(const GdiFont *font)
 static void fill_fileinfo_from_face( GdiFont *font, Face *face )
 {
     WIN32_FILE_ATTRIBUTE_DATA info;
-    int len;
+    SIZE_T path_size;
+    WCHAR *path = NULL;
 
-    if (!face->file)
-    {
-        font->fileinfo = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*font->fileinfo));
-        font->fileinfo->size.QuadPart = face->font_data_size;
-        return;
-    }
+    if (!face->unix_name || !(path = wine_get_dos_file_name( face->unix_name ))) path_size = 0;
+    else path_size = strlenW( path ) * sizeof(WCHAR);
 
-    len = strlenW(face->file);
-    font->fileinfo = HeapAlloc(GetProcessHeap(), 0, sizeof(*font->fileinfo) + len * sizeof(WCHAR));
-    if (GetFileAttributesExW(face->file, GetFileExInfoStandard, &info))
+    font->fileinfo = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*font->fileinfo) + path_size );
+    if (!face->unix_name) font->fileinfo->size.QuadPart = face->font_data_size;
+    else 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 );
     }
-    else
-        memset(font->fileinfo, 0, sizeof(*font->fileinfo) + len * sizeof(WCHAR));
 }
 
 /*************************************************************
-- 
2.28.0




More information about the wine-devel mailing list