[PATCH 3/7] Revise AddFontToList to enable it to return a Face pointer without affecting the global font list

Jeremy White jwhite at codeweavers.com
Wed Apr 23 23:26:12 CDT 2008


This is largely the design of Dmitry Timoshkov
---
 dlls/gdi32/freetype.c |  103 +++++++++++++++++++++++++++---------------------
 1 files changed, 58 insertions(+), 45 deletions(-)

diff --git a/dlls/gdi32/freetype.c b/dlls/gdi32/freetype.c
index 82150d3..a6a7180 100644
--- a/dlls/gdi32/freetype.c
+++ b/dlls/gdi32/freetype.c
@@ -1116,10 +1116,11 @@ static FT_Error load_sfnt_table(FT_Face ft_face, FT_ULong table, FT_Long offset,
     return err;
 }

-
-#define ADDFONT_EXTERNAL_FONT 0x01
-#define ADDFONT_FORCE_BITMAP  0x02
-static INT AddFontToList(const char *file, void *font_data_ptr, DWORD font_data_size, char *fake_family, const WCHAR *target_family, DWORD flags)
+
+#define ADDFONT_EXTERNAL_FONT   0x01
+#define ADDFONT_FORCE_BITMAP    0x02
+#define ADDFONT_IGNORE_GLOBALS  0x04
+static INT AddFontToList(const char *file, void *font_data_ptr, DWORD font_data_size, char *fake_family, const WCHAR *target_family, DWORD flags, Face **return_face)
 {
     FT_Face ft_face;
     TT_OS2 *pOS2;
@@ -1151,7 +1152,7 @@ static INT AddFontToList(const char *file, void *font_data_ptr, DWORD font_data_
             for(cursor = mac_list; *cursor; cursor++)
             {
                 had_one = TRUE;
-                AddFontToList(*cursor, NULL, 0, NULL, NULL, flags);
+                AddFontToList(*cursor, NULL, 0, NULL, NULL, flags, return_face);
                 HeapFree(GetProcessHeap(), 0, *cursor);
             }
             HeapFree(GetProcessHeap(), 0, mac_list);
@@ -1271,19 +1272,21 @@ static INT AddFontToList(const char *file, void *font_data_ptr, DWORD font_data_
             }

             family = NULL;
-            LIST_FOR_EACH(family_elem_ptr, &font_list) {
-                family = LIST_ENTRY(family_elem_ptr, Family, entry);
-                if(!strcmpW(family->FamilyName, localised_family ? localised_family : english_family))
-                    break;
-                family = NULL;
-            }
+            if (! (flags & ADDFONT_IGNORE_GLOBALS))
+                LIST_FOR_EACH(family_elem_ptr, &font_list) {
+                    family = LIST_ENTRY(family_elem_ptr, Family, entry);
+                    if(!strcmpW(family->FamilyName, localised_family ? localised_family : english_family))
+                        break;
+                    family = NULL;
+                }
             if(!family) {
                 family = HeapAlloc(GetProcessHeap(), 0, sizeof(*family));
                 family->FamilyName = strdupW(localised_family ? localised_family : english_family);
                 list_init(&family->faces);
-                list_add_tail(&font_list, &family->entry);
+                if (! (flags & ADDFONT_IGNORE_GLOBALS))
+                    list_add_tail(&font_list, &family->entry);

-                if(localised_family) {
+                if(localised_family && ! (flags & ADDFONT_IGNORE_GLOBALS)) {
                     FontSubst *subst = HeapAlloc(GetProcessHeap(), 0, sizeof(*subst));
                     subst->from.name = strdupW(english_family);
                     subst->from.charset = -1;
@@ -1330,40 +1333,43 @@ static INT AddFontToList(const char *file, void *font_data_ptr, DWORD font_data_
             }
 #endif

-            face_elem_ptr = list_head(&family->faces);
-            while(face_elem_ptr) {
-                face = LIST_ENTRY(face_elem_ptr, Face, entry);
-                face_elem_ptr = list_next(&family->faces, face_elem_ptr);
-                if(!strcmpW(face->StyleName, StyleW) &&
-                   (FT_IS_SCALABLE(ft_face) || ((size->y_ppem == face->size.y_ppem) && !memcmp(&fs, &face->fs, sizeof(fs)) ))) {
-                    TRACE("Already loaded font %s %s original version is %lx, this version is %lx\n",
-                          debugstr_w(family->FamilyName), debugstr_w(StyleW),
-                          face->font_version,  pHeader ? pHeader->Font_Revision : 0);
-
-                    if(fake_family) {
-                        TRACE("This font is a replacement but the original really exists, so we'll skip the replacement\n");
-                        HeapFree(GetProcessHeap(), 0, StyleW);
-                        pFT_Done_Face(ft_face);
-                        return 1;
-                    }
-                    if(!pHeader || pHeader->Font_Revision <= face->font_version) {
-                        TRACE("Original font is newer so skipping this one\n");
-                        HeapFree(GetProcessHeap(), 0, StyleW);
-                        pFT_Done_Face(ft_face);
-                        return 1;
-                    } else {
-                        TRACE("Replacing original with this one\n");
-                        list_remove(&face->entry);
-                        HeapFree(GetProcessHeap(), 0, face->file);
-                        HeapFree(GetProcessHeap(), 0, face->StyleName);
-                        HeapFree(GetProcessHeap(), 0, face);
-                        break;
+            if (! (flags & ADDFONT_IGNORE_GLOBALS)) {
+                face_elem_ptr = list_head(&family->faces);
+                while(face_elem_ptr) {
+                    face = LIST_ENTRY(face_elem_ptr, Face, entry);
+                    face_elem_ptr = list_next(&family->faces, face_elem_ptr);
+                    if(!strcmpW(face->StyleName, StyleW) &&
+                       (FT_IS_SCALABLE(ft_face) || ((size->y_ppem == face->size.y_ppem) && !memcmp(&fs, &face->fs, sizeof(fs)) ))) {
+                        TRACE("Already loaded font %s %s original version is %lx, this version is %lx\n",
+                              debugstr_w(family->FamilyName), debugstr_w(StyleW),
+                              face->font_version,  pHeader ? pHeader->Font_Revision : 0);
+
+                        if(fake_family) {
+                            TRACE("This font is a replacement but the original really exists, so we'll skip the replacement\n");
+                            HeapFree(GetProcessHeap(), 0, StyleW);
+                            pFT_Done_Face(ft_face);
+                            return 1;
+                        }
+                        if(!pHeader || pHeader->Font_Revision <= face->font_version) {
+                            TRACE("Original font is newer so skipping this one\n");
+                            HeapFree(GetProcessHeap(), 0, StyleW);
+                            pFT_Done_Face(ft_face);
+                            return 1;
+                        } else {
+                            TRACE("Replacing original with this one\n");
+                            list_remove(&face->entry);
+                            HeapFree(GetProcessHeap(), 0, face->file);
+                            HeapFree(GetProcessHeap(), 0, face->StyleName);
+                            HeapFree(GetProcessHeap(), 0, face);
+                            break;
+                        }
                     }
                 }
             }
             face = HeapAlloc(GetProcessHeap(), 0, sizeof(*face));
             face->cached_enum_data = NULL;
-            list_add_tail(&family->faces, &face->entry);
+            if (! (flags & ADDFONT_IGNORE_GLOBALS))
+                list_add_tail(&family->faces, &face->entry);
             face->StyleName = StyleW;
             if (file)
             {
@@ -1438,6 +1444,13 @@ static INT AddFontToList(const char *file, void *font_data_ptr, DWORD font_data_

             if (!(face->fs.fsCsb[0] & FS_SYMBOL))
                 have_installed_roman_font = TRUE;
+
+            if (return_face)
+            {
+                pFT_Done_Face(ft_face);
+                *return_face = face;
+                return 1;
+            }
         } while(!FT_IS_SCALABLE(ft_face) && ++bitmap_num < ft_face->num_fixed_sizes);

 	num_faces = ft_face->num_faces;
@@ -1450,7 +1463,7 @@ static INT AddFontToList(const char *file, void *font_data_ptr, DWORD font_data_

 static INT AddFontFileToList(const char *file, char *fake_family, const WCHAR *target_family, DWORD flags)
 {
-    return AddFontToList(file, NULL, 0, fake_family, target_family, flags);
+    return AddFontToList(file, NULL, 0, fake_family, target_family, flags, NULL);
 }

 static void DumpFontList(void)
@@ -1524,7 +1537,7 @@ static void LoadReplaceList(void)
                         TRACE("mapping %s %s to %s\n", debugstr_w(family->FamilyName),
                               debugstr_w(face->StyleName), familyA);
                         /* Now add a new entry with the new family name */
-                        AddFontToList(face->file, face->font_data_ptr, face->font_data_size, familyA, family->FamilyName, ADDFONT_FORCE_BITMAP | (face->external ? ADDFONT_EXTERNAL_FONT : 0));
+                        AddFontToList(face->file, face->font_data_ptr, face->font_data_size, familyA, family->FamilyName, ADDFONT_FORCE_BITMAP | (face->external ? ADDFONT_EXTERNAL_FONT : 0), NULL);
                     }
                     break;
                 }
@@ -2049,7 +2062,7 @@ HANDLE WineEngAddFontMemResourceEx(PVOID pbFont, DWORD cbFont, PVOID pdv, DWORD
         memcpy(pFontCopy, pbFont, cbFont);

         EnterCriticalSection( &freetype_cs );
-        *pcFonts = AddFontToList(NULL, pFontCopy, cbFont, NULL, NULL, ADDFONT_FORCE_BITMAP);
+        *pcFonts = AddFontToList(NULL, pFontCopy, cbFont, NULL, NULL, ADDFONT_FORCE_BITMAP, NULL);
         LeaveCriticalSection( &freetype_cs );

         if (*pcFonts == 0)



More information about the wine-patches mailing list