[PATCH 8/8] gdi32: Create face first then initialize with ft_face.

Rémi Bernon rbernon at codeweavers.com
Wed Sep 9 05:22:04 CDT 2020


We will use FreeType cache manager to load FT_Face from Face pointers.

Signed-off-by: Rémi Bernon <rbernon at codeweavers.com>
---

When fontconfig is available, we will have a face_init_from_fc_pattern
equivalent, loading data from its caches for a huge time improvement.

 dlls/gdi32/freetype.c | 72 +++++++++++++++++++++----------------------
 1 file changed, 36 insertions(+), 36 deletions(-)

diff --git a/dlls/gdi32/freetype.c b/dlls/gdi32/freetype.c
index 6d559a917c1..2381514f6b4 100644
--- a/dlls/gdi32/freetype.c
+++ b/dlls/gdi32/freetype.c
@@ -2139,11 +2139,11 @@ 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 )
+static BOOL face_init_from_ft_face( Face *face, FT_Face ft_face )
 {
-    Face *face;
+    Family *family;
 
-    if (!(face = face_create( file, face_index, flags ))) return NULL;
+    if (!(family = get_family( ft_face, face->flags & ADDFONT_VERTICAL_FONT ))) return FALSE;
 
     face->style_name = ft_face_get_style_name( ft_face, GetSystemDefaultLangID() );
     face->full_name = ft_face_get_full_name( ft_face, GetSystemDefaultLangID() );
@@ -2160,26 +2160,14 @@ static Face *create_face( FT_Face ft_face, FT_Long face_index, const char *file,
           face->fs.fsUsb[0], face->fs.fsUsb[1],
           face->fs.fsUsb[2], face->fs.fsUsb[3]);
 
-    return face;
-}
-
-static void AddFaceToList( FT_Face ft_face, const char *file, FT_Long face_index, DWORD flags )
-{
-    Face *face;
-    Family *family;
-
-    face = create_face( ft_face, face_index, file, flags );
-    family = get_family( ft_face, flags & ADDFONT_VERTICAL_FONT );
-
     if (insert_face_in_family_list( face, family ))
     {
-        if (flags & ADDFONT_ADD_TO_CACHE)
-            add_face_to_cache( face );
+        if (face->flags & ADDFONT_ADD_TO_CACHE) add_face_to_cache( face );
         TRACE( "Added face %s to family %s\n", debugstr_w(face->full_name), debugstr_w(family->family_name) );
     }
 
-    face_release( face );
     family_release( family );
+    return TRUE;
 }
 
 static FT_Face new_ft_face( const char *file, FT_Long face_index, BOOL allow_bitmap )
@@ -2250,7 +2238,8 @@ fail:
 
 static int add_faces_from_unix_file( const char *unix_name, DWORD flags )
 {
-    FT_Face ft_face;
+    Face *face = NULL;
+    FT_Face ft_face = NULL;
     FT_Long face_index = 0, num_faces;
     int ret = 0;
 
@@ -2279,33 +2268,39 @@ static int add_faces_from_unix_file( const char *unix_name, DWORD flags )
 
     do
     {
-        FONTSIGNATURE fs;
-
-        ft_face = new_ft_face( unix_name, face_index, flags & ADDFONT_ALLOW_BITMAP );
-        if (!ft_face) return 0;
+        if (!(face = face_create( unix_name, face_index, flags ))) goto failed;
+        if (!(ft_face = new_ft_face( unix_name, face_index, flags & ADDFONT_ALLOW_BITMAP )))
+            goto failed;
 
         if (ft_face->family_name[0] == '.') /* Ignore fonts with names beginning with a dot */
         {
             TRACE( "Ignoring %s since its family name begins with a dot\n", debugstr_a(unix_name) );
-            pFT_Done_Face( ft_face );
-            return 0;
+            goto failed;
         }
 
-        AddFaceToList( ft_face, unix_name, face_index, flags );
+        if (!face_init_from_ft_face( face, ft_face )) goto failed;
         ++ret;
 
-        get_fontsig( ft_face, &fs );
-        if (fs.fsCsb[0] & FS_DBCS_MASK)
+        if (face->fs.fsCsb[0] & FS_DBCS_MASK)
         {
-            AddFaceToList( ft_face, unix_name, face_index, flags | ADDFONT_VERTICAL_FONT );
+            face_release( face );
+            if (!(face = face_create( unix_name, face_index, flags | ADDFONT_VERTICAL_FONT )))
+                goto failed;
+            if (!face_init_from_ft_face( face, ft_face )) goto failed;
             ++ret;
         }
 
         num_faces = ft_face->num_faces;
         pFT_Done_Face( ft_face );
+        face_release( face );
     } while (num_faces > ++face_index);
 
     return ret;
+
+failed:
+    if (ft_face) pFT_Done_Face( ft_face );
+    if (face) face_release( face );
+    return 0;
 }
 
 static int remove_font_resource( const WCHAR *file, DWORD flags )
@@ -3435,23 +3430,21 @@ static void GetEnumStructs(Face *face, const WCHAR *family_name, LPENUMLOGFONTEX
 
 static BOOL get_fontdir( const char *unix_name, struct fontdir *fd )
 {
-    FT_Face ft_face = new_ft_face( unix_name, 0, FALSE );
-    Face *face;
+    FT_Face ft_face = NULL;
+    Face *face = NULL;
     WCHAR *family_name;
     ENUMLOGFONTEXW elf;
     NEWTEXTMETRICEXW ntm;
     DWORD type;
 
-    if (!ft_face) return FALSE;
-    face = create_face( ft_face, 0, unix_name, 0 );
+    if (!(face = face_create( unix_name, 0, 0 ))) goto failed;
+    if (!(ft_face = new_ft_face( unix_name, 0, FALSE ))) goto failed;
+    if (!face_init_from_ft_face( face, ft_face )) goto failed;
     family_name = ft_face_get_family_name( ft_face, GetSystemDefaultLCID() );
-    pFT_Done_Face( ft_face );
-
     GetEnumStructs( face, family_name, &elf, &ntm, &type );
-    face_release( face );
     HeapFree( GetProcessHeap(), 0, family_name );
 
-    if ((type & TRUETYPE_FONTTYPE) == 0) return FALSE;
+    if ((type & TRUETYPE_FONTTYPE) == 0) goto failed;
 
     memset( fd, 0, sizeof(*fd) );
 
@@ -3487,7 +3480,14 @@ static BOOL get_fontdir( const char *unix_name, struct fontdir *fd )
     fd->dfReserved        = 0;
     WideCharToMultiByte( CP_ACP, 0, elf.elfLogFont.lfFaceName, -1, fd->szFaceName, LF_FACESIZE, NULL, NULL );
 
+    pFT_Done_Face( ft_face );
+    face_release( face );
     return TRUE;
+
+failed:
+    if (ft_face) pFT_Done_Face( ft_face );
+    if (face) face_release( face );
+    return FALSE;
 }
 
 #define NE_FFLAGS_LIBMODULE     0x8000
-- 
2.28.0




More information about the wine-devel mailing list