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.
This commit is contained in:
parent
c9dcef156e
commit
a2047323c9
|
@ -1207,15 +1207,17 @@ static void AddFaceToFamily(Face *face, Family *family)
|
||||||
|
|
||||||
#define ADDFONT_EXTERNAL_FONT 0x01
|
#define ADDFONT_EXTERNAL_FONT 0x01
|
||||||
#define ADDFONT_FORCE_BITMAP 0x02
|
#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;
|
FT_Face ft_face;
|
||||||
TT_OS2 *pOS2;
|
TT_OS2 *pOS2;
|
||||||
TT_Header *pHeader = NULL;
|
TT_Header *pHeader = NULL;
|
||||||
WCHAR *english_family, *localised_family, *StyleW;
|
WCHAR *english_family, *localised_family, *StyleW;
|
||||||
DWORD len;
|
DWORD len;
|
||||||
Family *family;
|
Family *family = NULL;
|
||||||
Face *face;
|
Face *face, *first_face = NULL;
|
||||||
struct list *family_elem_ptr, *face_elem_ptr;
|
struct list *family_elem_ptr, *face_elem_ptr;
|
||||||
FT_Error err;
|
FT_Error err;
|
||||||
FT_Long face_index = 0, num_faces;
|
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++)
|
for(cursor = mac_list; *cursor; cursor++)
|
||||||
{
|
{
|
||||||
had_one = TRUE;
|
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, *cursor);
|
||||||
}
|
}
|
||||||
HeapFree(GetProcessHeap(), 0, mac_list);
|
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))
|
if(!FT_IS_SCALABLE(ft_face))
|
||||||
size = (My_FT_Bitmap_Size *)ft_face->available_sizes + bitmap_num;
|
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);
|
len = MultiByteToWideChar(CP_ACP, 0, ft_face->style_name, -1, NULL, 0);
|
||||||
StyleW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
|
StyleW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
|
||||||
MultiByteToWideChar(CP_ACP, 0, ft_face->style_name, -1, StyleW, len);
|
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
|
#endif
|
||||||
|
|
||||||
face_elem_ptr = list_head(&family->faces);
|
if (!(flags & ADDFONT_HIDDEN))
|
||||||
while(face_elem_ptr) {
|
{
|
||||||
face = LIST_ENTRY(face_elem_ptr, Face, entry);
|
len = MultiByteToWideChar(CP_ACP, 0, family_name, -1, NULL, 0);
|
||||||
face_elem_ptr = list_next(&family->faces, face_elem_ptr);
|
english_family = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
|
||||||
if(!strcmpiW(face->StyleName, StyleW) &&
|
MultiByteToWideChar(CP_ACP, 0, family_name, -1, english_family, len);
|
||||||
(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) {
|
localised_family = NULL;
|
||||||
TRACE("This font is a replacement but the original really exists, so we'll skip the replacement\n");
|
if (!fake_family)
|
||||||
HeapFree(GetProcessHeap(), 0, StyleW);
|
{
|
||||||
pFT_Done_Face(ft_face);
|
localised_family = get_familyname(ft_face);
|
||||||
return 1;
|
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);
|
family = NULL;
|
||||||
pFT_Done_Face(ft_face);
|
LIST_FOR_EACH(family_elem_ptr, &font_list)
|
||||||
return 1;
|
{
|
||||||
} else {
|
family = LIST_ENTRY(family_elem_ptr, Family, entry);
|
||||||
TRACE("Replacing original with this one\n");
|
if(!strcmpiW(family->FamilyName, localised_family ? localised_family : english_family))
|
||||||
list_remove(&face->entry);
|
|
||||||
HeapFree(GetProcessHeap(), 0, face->file);
|
|
||||||
HeapFree(GetProcessHeap(), 0, face->StyleName);
|
|
||||||
HeapFree(GetProcessHeap(), 0, face);
|
|
||||||
break;
|
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 = HeapAlloc(GetProcessHeap(), 0, sizeof(*face));
|
||||||
face->cached_enum_data = NULL;
|
face->cached_enum_data = NULL;
|
||||||
face->StyleName = StyleW;
|
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))
|
if (!(flags & ADDFONT_HIDDEN))
|
||||||
have_installed_roman_font = TRUE;
|
{
|
||||||
|
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);
|
} while(!FT_IS_SCALABLE(ft_face) && ++bitmap_num < ft_face->num_fixed_sizes);
|
||||||
|
|
||||||
num_faces = ft_face->num_faces;
|
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),
|
TRACE("Added font %s %s\n", debugstr_w(family->FamilyName),
|
||||||
debugstr_w(StyleW));
|
debugstr_w(StyleW));
|
||||||
} while(num_faces > ++face_index);
|
} while(num_faces > ++face_index);
|
||||||
|
|
||||||
|
if (face_to_return) *face_to_return = first_face;
|
||||||
|
|
||||||
return num_faces;
|
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)
|
static void DumpFontList(void)
|
||||||
|
@ -1614,7 +1638,7 @@ static void LoadReplaceList(void)
|
||||||
TRACE("mapping %s %s to %s\n", debugstr_w(family->FamilyName),
|
TRACE("mapping %s %s to %s\n", debugstr_w(family->FamilyName),
|
||||||
debugstr_w(face->StyleName), familyA);
|
debugstr_w(face->StyleName), familyA);
|
||||||
/* Now add a new entry with the new family name */
|
/* 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;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1790,7 +1814,7 @@ static BOOL ReadFontDir(const char *dirname, BOOL external_fonts)
|
||||||
if(S_ISDIR(statbuf.st_mode))
|
if(S_ISDIR(statbuf.st_mode))
|
||||||
ReadFontDir(path, external_fonts);
|
ReadFontDir(path, external_fonts);
|
||||||
else
|
else
|
||||||
AddFontFileToList(path, NULL, NULL, external_fonts ? ADDFONT_EXTERNAL_FONT : 0);
|
AddFontFileToList(path, NULL, NULL, external_fonts ? ADDFONT_EXTERNAL_FONT : 0, NULL);
|
||||||
}
|
}
|
||||||
closedir(dir);
|
closedir(dir);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
@ -1858,7 +1882,7 @@ LOAD_FUNCPTR(FcPatternGetString);
|
||||||
if(len < 4) continue;
|
if(len < 4) continue;
|
||||||
ext = &file[ len - 3 ];
|
ext = &file[ len - 3 ];
|
||||||
if(strcasecmp(ext, "pfa") && strcasecmp(ext, "pfb"))
|
if(strcasecmp(ext, "pfa") && strcasecmp(ext, "pfb"))
|
||||||
AddFontFileToList(file, NULL, NULL, ADDFONT_EXTERNAL_FONT);
|
AddFontFileToList(file, NULL, NULL, ADDFONT_EXTERNAL_FONT, NULL);
|
||||||
}
|
}
|
||||||
pFcFontSetDestroy(fontset);
|
pFcFontSetDestroy(fontset);
|
||||||
pFcObjectSetDestroy(os);
|
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);
|
WideCharToMultiByte(CP_UNIXCP, 0, file, -1, unix_name + strlen(unix_name), len, NULL, NULL);
|
||||||
|
|
||||||
EnterCriticalSection( &freetype_cs );
|
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 );
|
LeaveCriticalSection( &freetype_cs );
|
||||||
HeapFree(GetProcessHeap(), 0, unix_name);
|
HeapFree(GetProcessHeap(), 0, unix_name);
|
||||||
}
|
}
|
||||||
|
@ -1910,7 +1934,7 @@ static BOOL load_font_from_winfonts_dir(LPCWSTR file)
|
||||||
strcatW(windowsdir, file);
|
strcatW(windowsdir, file);
|
||||||
if ((unixname = wine_get_unix_file_name(windowsdir))) {
|
if ((unixname = wine_get_unix_file_name(windowsdir))) {
|
||||||
EnterCriticalSection( &freetype_cs );
|
EnterCriticalSection( &freetype_cs );
|
||||||
ret = AddFontFileToList(unixname, NULL, NULL, ADDFONT_FORCE_BITMAP);
|
ret = AddFontFileToList(unixname, NULL, NULL, ADDFONT_FORCE_BITMAP, NULL);
|
||||||
LeaveCriticalSection( &freetype_cs );
|
LeaveCriticalSection( &freetype_cs );
|
||||||
HeapFree(GetProcessHeap(), 0, unixname);
|
HeapFree(GetProcessHeap(), 0, unixname);
|
||||||
}
|
}
|
||||||
|
@ -1937,7 +1961,7 @@ static void load_system_fonts(void)
|
||||||
|
|
||||||
sprintfW(pathW, fmtW, windowsdir, data);
|
sprintfW(pathW, fmtW, windowsdir, data);
|
||||||
if((unixname = wine_get_unix_file_name(pathW))) {
|
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);
|
HeapFree(GetProcessHeap(), 0, unixname);
|
||||||
}
|
}
|
||||||
if (!added)
|
if (!added)
|
||||||
|
@ -2110,7 +2134,7 @@ INT WineEngAddFontResourceEx(LPCWSTR file, DWORD flags, PVOID pdv)
|
||||||
if((unixname = wine_get_unix_file_name(file)))
|
if((unixname = wine_get_unix_file_name(file)))
|
||||||
{
|
{
|
||||||
EnterCriticalSection( &freetype_cs );
|
EnterCriticalSection( &freetype_cs );
|
||||||
ret = AddFontFileToList(unixname, NULL, NULL, ADDFONT_FORCE_BITMAP);
|
ret = AddFontFileToList(unixname, NULL, NULL, ADDFONT_FORCE_BITMAP, NULL);
|
||||||
LeaveCriticalSection( &freetype_cs );
|
LeaveCriticalSection( &freetype_cs );
|
||||||
HeapFree(GetProcessHeap(), 0, unixname);
|
HeapFree(GetProcessHeap(), 0, unixname);
|
||||||
}
|
}
|
||||||
|
@ -2144,7 +2168,7 @@ HANDLE WineEngAddFontMemResourceEx(PVOID pbFont, DWORD cbFont, PVOID pdv, DWORD
|
||||||
memcpy(pFontCopy, pbFont, cbFont);
|
memcpy(pFontCopy, pbFont, cbFont);
|
||||||
|
|
||||||
EnterCriticalSection( &freetype_cs );
|
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 );
|
LeaveCriticalSection( &freetype_cs );
|
||||||
|
|
||||||
if (*pcFonts == 0)
|
if (*pcFonts == 0)
|
||||||
|
@ -2806,7 +2830,7 @@ BOOL WineEngInit(void)
|
||||||
{
|
{
|
||||||
if((unixname = wine_get_unix_file_name(data)))
|
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);
|
HeapFree(GetProcessHeap(), 0, unixname);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2819,7 +2843,7 @@ BOOL WineEngInit(void)
|
||||||
sprintfW(pathW, fmtW, windowsdir, data);
|
sprintfW(pathW, fmtW, windowsdir, data);
|
||||||
if((unixname = wine_get_unix_file_name(pathW)))
|
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);
|
HeapFree(GetProcessHeap(), 0, unixname);
|
||||||
}
|
}
|
||||||
if (!added)
|
if (!added)
|
||||||
|
|
Loading…
Reference in New Issue