[PATCH] Refactor AddFontToList to clarify function, and to expose a CreateWineFace function needed for CreateScalableFontResource

Jeremy White jwhite at codeweavers.com
Thu Oct 9 13:11:29 CDT 2008


---
 dlls/gdi32/freetype.c |  351 +++++++++++++++++++++++++++----------------------
 1 files changed, 195 insertions(+), 156 deletions(-)

diff --git a/dlls/gdi32/freetype.c b/dlls/gdi32/freetype.c
index 0baf822..8b4809a 100644
--- a/dlls/gdi32/freetype.c
+++ b/dlls/gdi32/freetype.c
@@ -1311,23 +1311,194 @@ static Family *GetFamily(FT_Face ft_face, char *family_name, char *fake_family)
     return family;
 }
 
+static void FreeFace(Face *face)
+{
+    HeapFree(GetProcessHeap(), 0, face->file);
+    HeapFree(GetProcessHeap(), 0, face->StyleName);
+    HeapFree(GetProcessHeap(), 0, face);
+}
 
-static INT AddFontToList(const char *file, void *font_data_ptr, DWORD font_data_size, char *fake_family, const WCHAR *target_family, DWORD flags)
+static BOOL FaceExists(Face *newface, Family *family, char *fake_family, Face **face_to_replace)
 {
-    FT_Face ft_face;
-    TT_OS2 *pOS2;
+    struct list *face_elem_ptr;
+    Face *face;
+
+    *face_to_replace = NULL;
+
+    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, newface->StyleName) &&
+           (newface->scalable || ((newface->size.y_ppem == face->size.y_ppem) &&
+                                                !memcmp(&newface->fs, &face->fs, sizeof(face->fs)) ))) {
+            TRACE("Already loaded font %s %s original version is %lx, this version is %lx\n",
+                  debugstr_w(family->FamilyName), debugstr_w(newface->StyleName),
+                  face->font_version,  newface->font_version);
+
+            if(fake_family) {
+                TRACE("This font is a replacement but the original really exists, so we'll skip the replacement\n");
+                return TRUE;
+            }
+            if(newface->font_version <= face->font_version) {
+                TRACE("Original font is newer so skipping this one\n");
+                return TRUE;
+            } else {
+                *face_to_replace = face;
+                return TRUE;
+            }
+        }
+    }
+
+    return FALSE;
+}
+
+
+static Face * CreateWineFace(FT_Face ft_face,
+            const char *file, void *font_data_ptr, DWORD font_data_size,
+            DWORD flags, FT_Long face_index, int bitmap_num, Family *family)
+{
+    My_FT_Bitmap_Size *size = NULL;
     TT_Header *pHeader = NULL;
-    WCHAR *StyleW;
     DWORD len;
-    Family *family;
-    Face *face;
-    struct list *face_elem_ptr;
-    FT_Long face_index = 0, num_faces;
+    Face * face;
+    FT_ULong tmp_size;
+    WCHAR *StyleW;
+    int i;
+    int internal_leading;
+    FONTSIGNATURE fs;
+    TT_OS2 *pOS2;
 #ifdef HAVE_FREETYPE_FTWINFNT_H
     FT_WinFNT_HeaderRec winfnt_header;
 #endif
-    int i, bitmap_num, internal_leading;
-    FONTSIGNATURE fs;
+
+    if(FT_IS_SFNT(ft_face))
+       pHeader = pFT_Get_Sfnt_Table(ft_face, ft_sfnt_head);
+
+    if(!FT_IS_SCALABLE(ft_face))
+        size = (My_FT_Bitmap_Size *)ft_face->available_sizes + bitmap_num;
+
+    len = MultiByteToWideChar(CP_ACP, 0, ft_face->style_name, -1, NULL, 0);
+    StyleW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
+    MultiByteToWideChar(CP_ACP, 0, ft_face->style_name, -1, StyleW, len);
+
+    internal_leading = 0;
+    memset(&fs, 0, sizeof(fs));
+
+    pOS2 = pFT_Get_Sfnt_Table(ft_face, ft_sfnt_os2);
+    if(pOS2) {
+        fs.fsCsb[0] = pOS2->ulCodePageRange1;
+        fs.fsCsb[1] = pOS2->ulCodePageRange2;
+        fs.fsUsb[0] = pOS2->ulUnicodeRange1;
+        fs.fsUsb[1] = pOS2->ulUnicodeRange2;
+        fs.fsUsb[2] = pOS2->ulUnicodeRange3;
+        fs.fsUsb[3] = pOS2->ulUnicodeRange4;
+        if(pOS2->version == 0) {
+            FT_UInt dummy;
+
+            if(!pFT_Get_First_Char || (pFT_Get_First_Char( ft_face, &dummy ) < 0x100))
+                fs.fsCsb[0] |= FS_LATIN1;
+            else
+                fs.fsCsb[0] |= FS_SYMBOL;
+        }
+    }
+#ifdef HAVE_FREETYPE_FTWINFNT_H
+    else if(pFT_Get_WinFNT_Header && !pFT_Get_WinFNT_Header(ft_face, &winfnt_header)) {
+        CHARSETINFO csi;
+        TRACE("pix_h %d charset %d dpi %dx%d pt %d\n", winfnt_header.pixel_height, winfnt_header.charset,
+              winfnt_header.vertical_resolution,winfnt_header.horizontal_resolution, winfnt_header.nominal_point_size);
+        if(TranslateCharsetInfo((DWORD*)(UINT_PTR)winfnt_header.charset, &csi, TCI_SRCCHARSET))
+            fs = csi.fs;
+        internal_leading = winfnt_header.internal_leading;
+    }
+#endif
+
+    face = HeapAlloc(GetProcessHeap(), 0, sizeof(*face));
+    face->cached_enum_data = NULL;
+    face->StyleName = StyleW;
+    if (file)
+    {
+        face->file = strdupA(file);
+        face->font_data_ptr = NULL;
+        face->font_data_size = 0;
+    }
+    else
+    {
+        face->file = NULL;
+        face->font_data_ptr = font_data_ptr;
+        face->font_data_size = font_data_size;
+    }
+    face->face_index = face_index;
+    face->ntmFlags = 0;
+    if (ft_face->style_flags & FT_STYLE_FLAG_ITALIC)
+        face->ntmFlags |= NTM_ITALIC;
+    if (ft_face->style_flags & FT_STYLE_FLAG_BOLD)
+        face->ntmFlags |= NTM_BOLD;
+    if (face->ntmFlags == 0) face->ntmFlags = NTM_REGULAR;
+    face->font_version = pHeader ? pHeader->Font_Revision : 0;
+    face->family = family;
+    face->external = (flags & ADDFONT_EXTERNAL_FONT) ? TRUE : FALSE;
+    face->fs = fs;
+    memset(&face->fs_links, 0, sizeof(face->fs_links));
+
+    if(FT_IS_SCALABLE(ft_face)) {
+        memset(&face->size, 0, sizeof(face->size));
+        face->scalable = TRUE;
+    } else {
+        TRACE("Adding bitmap size h %d w %d size %ld x_ppem %ld y_ppem %ld\n",
+              size->height, size->width, size->size >> 6,
+              size->x_ppem >> 6, size->y_ppem >> 6);
+        face->size.height = size->height;
+        face->size.width = size->width;
+        face->size.size = size->size;
+        face->size.x_ppem = size->x_ppem;
+        face->size.y_ppem = size->y_ppem;
+        face->size.internal_leading = internal_leading;
+        face->scalable = FALSE;
+    }
+
+    /* check for the presence of the 'CFF ' table to check if the font is Type1 */
+    tmp_size = 0;
+    if (pFT_Load_Sfnt_Table && !pFT_Load_Sfnt_Table(ft_face, FT_MAKE_TAG('C','F','F',' '), 0, NULL, &tmp_size))
+    {
+        TRACE("Font %s/%p is OTF Type1\n", wine_dbgstr_a(file), font_data_ptr);
+        face->ntmFlags |= NTM_PS_OPENTYPE;
+    }
+
+    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],
+          face->fs.fsUsb[2], face->fs.fsUsb[3]);
+
+
+    if(face->fs.fsCsb[0] == 0) { /* let's see if we can find any interesting cmaps */
+        for(i = 0; i < ft_face->num_charmaps; i++) {
+            switch(ft_face->charmaps[i]->encoding) {
+            case FT_ENCODING_UNICODE:
+            case FT_ENCODING_APPLE_ROMAN:
+                face->fs.fsCsb[0] |= FS_LATIN1;
+                break;
+            case FT_ENCODING_MS_SYMBOL:
+                face->fs.fsCsb[0] |= FS_SYMBOL;
+                break;
+            default:
+                break;
+            }
+        }
+    }
+
+    return face;
+}
+
+
+static INT AddFontToList(const char *file, void *font_data_ptr, DWORD font_data_size, char *fake_family, const WCHAR *target_family, DWORD flags)
+{
+    FT_Face ft_face;
+    Family *family;
+    Face *face;
+    Face *face_to_replace;
+    FT_Long face_index = 0, num_faces;
+    int bitmap_num;
 
     /* we always load external fonts from files - otherwise we would get a crash in update_reg_entries */
     assert(file || !(flags & ADDFONT_EXTERNAL_FONT));
@@ -1360,9 +1531,6 @@ static INT AddFontToList(const char *file, void *font_data_ptr, DWORD font_data_
             return 0;
         num_faces = ft_face->num_faces;
 
-        if(FT_IS_SFNT(ft_face))
-           pHeader = pFT_Get_Sfnt_Table(ft_face, ft_sfnt_head);
-
         if (target_family)
         {
             WCHAR *localised_family;
@@ -1382,151 +1550,22 @@ static INT AddFontToList(const char *file, void *font_data_ptr, DWORD font_data_
 
         bitmap_num = 0;
         do {
-            My_FT_Bitmap_Size *size = NULL;
-            FT_ULong tmp_size;
-
-            if(!FT_IS_SCALABLE(ft_face))
-                size = (My_FT_Bitmap_Size *)ft_face->available_sizes + bitmap_num;
-
             family = GetFamily(ft_face, family_name, fake_family);
 
-            len = MultiByteToWideChar(CP_ACP, 0, ft_face->style_name, -1, NULL, 0);
-            StyleW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
-            MultiByteToWideChar(CP_ACP, 0, ft_face->style_name, -1, StyleW, len);
-
-            internal_leading = 0;
-            memset(&fs, 0, sizeof(fs));
-
-            pOS2 = pFT_Get_Sfnt_Table(ft_face, ft_sfnt_os2);
-            if(pOS2) {
-                fs.fsCsb[0] = pOS2->ulCodePageRange1;
-                fs.fsCsb[1] = pOS2->ulCodePageRange2;
-                fs.fsUsb[0] = pOS2->ulUnicodeRange1;
-                fs.fsUsb[1] = pOS2->ulUnicodeRange2;
-                fs.fsUsb[2] = pOS2->ulUnicodeRange3;
-                fs.fsUsb[3] = pOS2->ulUnicodeRange4;
-                if(pOS2->version == 0) {
-                    FT_UInt dummy;
-
-                    if(!pFT_Get_First_Char || (pFT_Get_First_Char( ft_face, &dummy ) < 0x100))
-                        fs.fsCsb[0] |= FS_LATIN1;
-                    else
-                        fs.fsCsb[0] |= FS_SYMBOL;
-                }
-            }
-#ifdef HAVE_FREETYPE_FTWINFNT_H
-            else if(pFT_Get_WinFNT_Header && !pFT_Get_WinFNT_Header(ft_face, &winfnt_header)) {
-                CHARSETINFO csi;
-                TRACE("pix_h %d charset %d dpi %dx%d pt %d\n", winfnt_header.pixel_height, winfnt_header.charset,
-                      winfnt_header.vertical_resolution,winfnt_header.horizontal_resolution, winfnt_header.nominal_point_size);
-                if(TranslateCharsetInfo((DWORD*)(UINT_PTR)winfnt_header.charset, &csi, TCI_SRCCHARSET))
-                    fs = csi.fs;
-                internal_leading = winfnt_header.internal_leading;
-            }
-#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;
-                    }
-                }
-            }
-            face = HeapAlloc(GetProcessHeap(), 0, sizeof(*face));
-            face->cached_enum_data = NULL;
-            face->StyleName = StyleW;
-            if (file)
-            {
-                face->file = strdupA(file);
-                face->font_data_ptr = NULL;
-                face->font_data_size = 0;
-            }
-            else
-            {
-                face->file = NULL;
-                face->font_data_ptr = font_data_ptr;
-                face->font_data_size = font_data_size;
-            }
-            face->face_index = face_index;
-            face->ntmFlags = 0;
-            if (ft_face->style_flags & FT_STYLE_FLAG_ITALIC)
-                face->ntmFlags |= NTM_ITALIC;
-            if (ft_face->style_flags & FT_STYLE_FLAG_BOLD)
-                face->ntmFlags |= NTM_BOLD;
-            if (face->ntmFlags == 0) face->ntmFlags = NTM_REGULAR;
-            face->font_version = pHeader ? pHeader->Font_Revision : 0;
-            face->family = family;
-            face->external = (flags & ADDFONT_EXTERNAL_FONT) ? TRUE : FALSE;
-            face->fs = fs;
-            memset(&face->fs_links, 0, sizeof(face->fs_links));
-
-            if(FT_IS_SCALABLE(ft_face)) {
-                memset(&face->size, 0, sizeof(face->size));
-                face->scalable = TRUE;
-            } else {
-                TRACE("Adding bitmap size h %d w %d size %ld x_ppem %ld y_ppem %ld\n",
-                      size->height, size->width, size->size >> 6,
-                      size->x_ppem >> 6, size->y_ppem >> 6);
-                face->size.height = size->height;
-                face->size.width = size->width;
-                face->size.size = size->size;
-                face->size.x_ppem = size->x_ppem;
-                face->size.y_ppem = size->y_ppem;
-                face->size.internal_leading = internal_leading;
-                face->scalable = FALSE;
-            }
-
-            /* check for the presence of the 'CFF ' table to check if the font is Type1 */
-            tmp_size = 0;
-            if (pFT_Load_Sfnt_Table && !pFT_Load_Sfnt_Table(ft_face, FT_MAKE_TAG('C','F','F',' '), 0, NULL, &tmp_size))
+            face = CreateWineFace(ft_face, file, font_data_ptr, font_data_size, flags, face_index, bitmap_num, family);
+            if (FaceExists(face, family, fake_family, &face_to_replace))
             {
-                TRACE("Font %s/%p is OTF Type1\n", wine_dbgstr_a(file), font_data_ptr);
-                face->ntmFlags |= NTM_PS_OPENTYPE;
-            }
-
-            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],
-                  face->fs.fsUsb[2], face->fs.fsUsb[3]);
-
-
-            if(face->fs.fsCsb[0] == 0) { /* let's see if we can find any interesting cmaps */
-                for(i = 0; i < ft_face->num_charmaps; i++) {
-                    switch(ft_face->charmaps[i]->encoding) {
-                    case FT_ENCODING_UNICODE:
-                    case FT_ENCODING_APPLE_ROMAN:
-			face->fs.fsCsb[0] |= FS_LATIN1;
-                        break;
-                    case FT_ENCODING_MS_SYMBOL:
-                        face->fs.fsCsb[0] |= FS_SYMBOL;
-                        break;
-                    default:
-                        break;
-                    }
+                if (face_to_replace)
+                {
+                    TRACE("Replacing original face %s with this one %s\n", debugstr_w(face_to_replace->StyleName), debugstr_w(face->StyleName));
+                    list_remove(&face_to_replace->entry);
+                    FreeFace(face_to_replace);
+                }
+                else
+                {
+                    pFT_Done_Face(ft_face);
+                    FreeFace(face);
+                    return 1;
                 }
             }
 
@@ -1539,7 +1578,7 @@ static INT AddFontToList(const char *file, void *font_data_ptr, DWORD font_data_
 
 	pFT_Done_Face(ft_face);
 	TRACE("Added font %s %s\n", debugstr_w(family->FamilyName),
-	      debugstr_w(StyleW));
+	      debugstr_w(face->StyleName));
     } while(num_faces > ++face_index);
     return num_faces;
 }
-- 
1.5.3.6


--------------090801060605020700020201--



More information about the wine-devel mailing list