From a2047323c9c41b44c743c345674ec934fb4cd685 Mon Sep 17 00:00:00 2001 From: Dmitry Timoshkov Date: Wed, 27 Oct 2010 18:30:32 +0900 Subject: [PATCH] gdi32: Make AddFontToList skip adding a face into global lists if the font is not supposed to be enumerated, and return a pointer to first loaded face. --- dlls/gdi32/freetype.c | 190 ++++++++++++++++++++++++++++---------------------- 1 file changed, 107 insertions(+), 83 deletions(-) diff --git a/dlls/gdi32/freetype.c b/dlls/gdi32/freetype.c index e2db1aa7be4..c35e3327eb4 100644 --- a/dlls/gdi32/freetype.c +++ b/dlls/gdi32/freetype.c @@ -1207,15 +1207,17 @@ static void AddFaceToFamily(Face *face, Family *family) #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_HIDDEN 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 **face_to_return) { FT_Face ft_face; TT_OS2 *pOS2; TT_Header *pHeader = NULL; WCHAR *english_family, *localised_family, *StyleW; DWORD len; - Family *family; - Face *face; + Family *family = NULL; + Face *face, *first_face = NULL; struct list *family_elem_ptr, *face_elem_ptr; FT_Error err; FT_Long face_index = 0, num_faces; @@ -1239,7 +1241,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, face_to_return); HeapFree(GetProcessHeap(), 0, *cursor); } HeapFree(GetProcessHeap(), 0, mac_list); @@ -1345,44 +1347,6 @@ static INT AddFontToList(const char *file, void *font_data_ptr, DWORD font_data_ if(!FT_IS_SCALABLE(ft_face)) size = (My_FT_Bitmap_Size *)ft_face->available_sizes + bitmap_num; - len = MultiByteToWideChar(CP_ACP, 0, family_name, -1, NULL, 0); - english_family = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR)); - MultiByteToWideChar(CP_ACP, 0, family_name, -1, english_family, len); - - localised_family = NULL; - if(!fake_family) { - localised_family = get_familyname(ft_face); - if(localised_family && !strcmpiW(localised_family, english_family)) { - HeapFree(GetProcessHeap(), 0, localised_family); - localised_family = NULL; - } - } - - family = NULL; - LIST_FOR_EACH(family_elem_ptr, &font_list) { - family = LIST_ENTRY(family_elem_ptr, Family, entry); - if(!strcmpiW(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(localised_family) { - FontSubst *subst = HeapAlloc(GetProcessHeap(), 0, sizeof(*subst)); - subst->from.name = strdupW(english_family); - subst->from.charset = -1; - subst->to.name = strdupW(localised_family); - subst->to.charset = -1; - add_font_subst(&font_subst_list, subst, 0); - } - } - HeapFree(GetProcessHeap(), 0, localised_family); - HeapFree(GetProcessHeap(), 0, english_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); @@ -1418,37 +1382,90 @@ 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(!strcmpiW(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 (!(flags & ADDFONT_HIDDEN)) + { + len = MultiByteToWideChar(CP_ACP, 0, family_name, -1, NULL, 0); + english_family = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR)); + MultiByteToWideChar(CP_ACP, 0, family_name, -1, english_family, len); + + localised_family = NULL; + if (!fake_family) + { + localised_family = get_familyname(ft_face); + if (localised_family && !strcmpiW(localised_family, english_family)) + { + HeapFree(GetProcessHeap(), 0, localised_family); + localised_family = NULL; } - 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); + } + + family = NULL; + LIST_FOR_EACH(family_elem_ptr, &font_list) + { + family = LIST_ENTRY(family_elem_ptr, Family, entry); + if(!strcmpiW(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 (localised_family) + { + FontSubst *subst = HeapAlloc(GetProcessHeap(), 0, sizeof(*subst)); + subst->from.name = strdupW(english_family); + subst->from.charset = -1; + subst->to.name = strdupW(localised_family); + subst->to.charset = -1; + add_font_subst(&font_subst_list, subst, 0); + } + } + HeapFree(GetProcessHeap(), 0, localised_family); + HeapFree(GetProcessHeap(), 0, english_family); + + 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 (!strcmpiW(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; @@ -1523,11 +1540,15 @@ 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 (!(flags & ADDFONT_HIDDEN)) + { + if (!(face->fs.fsCsb[0] & FS_SYMBOL)) + have_installed_roman_font = TRUE; - AddFaceToFamily(face, family); + AddFaceToFamily(face, family); + } + if (!first_face) first_face = face; } while(!FT_IS_SCALABLE(ft_face) && ++bitmap_num < ft_face->num_fixed_sizes); num_faces = ft_face->num_faces; @@ -1535,12 +1556,15 @@ static INT AddFontToList(const char *file, void *font_data_ptr, DWORD font_data_ TRACE("Added font %s %s\n", debugstr_w(family->FamilyName), debugstr_w(StyleW)); } while(num_faces > ++face_index); + + if (face_to_return) *face_to_return = first_face; + return num_faces; } -static INT AddFontFileToList(const char *file, char *fake_family, const WCHAR *target_family, DWORD flags) +static INT AddFontFileToList(const char *file, char *fake_family, const WCHAR *target_family, DWORD flags, Face **face_to_return) { - return AddFontToList(file, NULL, 0, fake_family, target_family, flags); + return AddFontToList(file, NULL, 0, fake_family, target_family, flags, face_to_return); } static void DumpFontList(void) @@ -1614,7 +1638,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; } @@ -1790,7 +1814,7 @@ static BOOL ReadFontDir(const char *dirname, BOOL external_fonts) if(S_ISDIR(statbuf.st_mode)) ReadFontDir(path, external_fonts); else - AddFontFileToList(path, NULL, NULL, external_fonts ? ADDFONT_EXTERNAL_FONT : 0); + AddFontFileToList(path, NULL, NULL, external_fonts ? ADDFONT_EXTERNAL_FONT : 0, NULL); } closedir(dir); return TRUE; @@ -1858,7 +1882,7 @@ LOAD_FUNCPTR(FcPatternGetString); if(len < 4) continue; ext = &file[ len - 3 ]; if(strcasecmp(ext, "pfa") && strcasecmp(ext, "pfb")) - AddFontFileToList(file, NULL, NULL, ADDFONT_EXTERNAL_FONT); + AddFontFileToList(file, NULL, NULL, ADDFONT_EXTERNAL_FONT, NULL); } pFcFontSetDestroy(fontset); pFcObjectSetDestroy(os); @@ -1890,7 +1914,7 @@ static BOOL load_font_from_data_dir(LPCWSTR file) WideCharToMultiByte(CP_UNIXCP, 0, file, -1, unix_name + strlen(unix_name), len, NULL, NULL); EnterCriticalSection( &freetype_cs ); - ret = AddFontFileToList(unix_name, NULL, NULL, ADDFONT_FORCE_BITMAP); + ret = AddFontFileToList(unix_name, NULL, NULL, ADDFONT_FORCE_BITMAP, NULL); LeaveCriticalSection( &freetype_cs ); HeapFree(GetProcessHeap(), 0, unix_name); } @@ -1910,7 +1934,7 @@ static BOOL load_font_from_winfonts_dir(LPCWSTR file) strcatW(windowsdir, file); if ((unixname = wine_get_unix_file_name(windowsdir))) { EnterCriticalSection( &freetype_cs ); - ret = AddFontFileToList(unixname, NULL, NULL, ADDFONT_FORCE_BITMAP); + ret = AddFontFileToList(unixname, NULL, NULL, ADDFONT_FORCE_BITMAP, NULL); LeaveCriticalSection( &freetype_cs ); HeapFree(GetProcessHeap(), 0, unixname); } @@ -1937,7 +1961,7 @@ static void load_system_fonts(void) sprintfW(pathW, fmtW, windowsdir, data); if((unixname = wine_get_unix_file_name(pathW))) { - added = AddFontFileToList(unixname, NULL, NULL, ADDFONT_FORCE_BITMAP); + added = AddFontFileToList(unixname, NULL, NULL, ADDFONT_FORCE_BITMAP, NULL); HeapFree(GetProcessHeap(), 0, unixname); } if (!added) @@ -2110,7 +2134,7 @@ INT WineEngAddFontResourceEx(LPCWSTR file, DWORD flags, PVOID pdv) if((unixname = wine_get_unix_file_name(file))) { EnterCriticalSection( &freetype_cs ); - ret = AddFontFileToList(unixname, NULL, NULL, ADDFONT_FORCE_BITMAP); + ret = AddFontFileToList(unixname, NULL, NULL, ADDFONT_FORCE_BITMAP, NULL); LeaveCriticalSection( &freetype_cs ); HeapFree(GetProcessHeap(), 0, unixname); } @@ -2144,7 +2168,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) @@ -2806,7 +2830,7 @@ BOOL WineEngInit(void) { if((unixname = wine_get_unix_file_name(data))) { - AddFontFileToList(unixname, NULL, NULL, ADDFONT_FORCE_BITMAP); + AddFontFileToList(unixname, NULL, NULL, ADDFONT_FORCE_BITMAP, NULL); HeapFree(GetProcessHeap(), 0, unixname); } } @@ -2819,7 +2843,7 @@ BOOL WineEngInit(void) sprintfW(pathW, fmtW, windowsdir, data); if((unixname = wine_get_unix_file_name(pathW))) { - added = AddFontFileToList(unixname, NULL, NULL, ADDFONT_FORCE_BITMAP); + added = AddFontFileToList(unixname, NULL, NULL, ADDFONT_FORCE_BITMAP, NULL); HeapFree(GetProcessHeap(), 0, unixname); } if (!added) -- 2.11.4.GIT