gdi32: Store the face filename as a DOS path.

Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Alexandre Julliard 2020-10-06 15:12:09 +02:00
parent 0a6e46e436
commit f51fe9ead3
1 changed files with 61 additions and 77 deletions

View File

@ -1045,7 +1045,7 @@ static Face *find_face_from_filename(const WCHAR *file_name, const WCHAR *face_n
{ {
if (!face->file) if (!face->file)
continue; continue;
file = strrchrW(face->file, '/'); file = strrchrW(face->file, '\\');
if(!file) if(!file)
file = face->file; file = face->file;
else else
@ -1170,14 +1170,6 @@ static WCHAR *towstr(UINT cp, const char *str)
return wstr; return wstr;
} }
static char *strWtoA(UINT cp, const WCHAR *str)
{
int len = WideCharToMultiByte( cp, 0, str, -1, NULL, 0, NULL, NULL );
char *ret = HeapAlloc( GetProcessHeap(), 0, len );
WideCharToMultiByte( cp, 0, str, -1, ret, len, NULL, NULL );
return ret;
}
static void split_subst_info(NameCs *nc, LPSTR str) static void split_subst_info(NameCs *nc, LPSTR str)
{ {
CHAR *p = strrchr(str, ','); CHAR *p = strrchr(str, ',');
@ -2108,8 +2100,8 @@ 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, void *font_data_ptr, DWORD font_data_size, static Face *create_face( FT_Face ft_face, FT_Long face_index, const WCHAR *dos_name, const char *unix_name,
DWORD flags ) void *font_data_ptr, DWORD font_data_size, DWORD flags )
{ {
struct stat st; struct stat st;
Face *face = HeapAlloc( GetProcessHeap(), 0, sizeof(*face) ); Face *face = HeapAlloc( GetProcessHeap(), 0, sizeof(*face) );
@ -2121,12 +2113,12 @@ static Face *create_face( FT_Face ft_face, FT_Long face_index, const char *file,
face->dev = 0; face->dev = 0;
face->ino = 0; face->ino = 0;
if (file) if (unix_name)
{ {
face->file = towstr( CP_UNIXCP, file ); face->file = dos_name ? strdupW( dos_name ) : wine_get_dos_file_name( unix_name );
face->font_data_ptr = NULL; face->font_data_ptr = NULL;
face->font_data_size = 0; face->font_data_size = 0;
if (!stat( file, &st )) if (!stat( unix_name, &st ))
{ {
face->dev = st.st_dev; face->dev = st.st_dev;
face->ino = st.st_ino; face->ino = st.st_ino;
@ -2168,13 +2160,13 @@ static Face *create_face( FT_Face ft_face, FT_Long face_index, const char *file,
return face; return face;
} }
static void AddFaceToList(FT_Face ft_face, const char *file, void *font_data_ptr, DWORD font_data_size, static void AddFaceToList(FT_Face ft_face, const WCHAR *dos_name, const char *unix_name,
FT_Long face_index, DWORD flags ) void *font_data_ptr, DWORD font_data_size, FT_Long face_index, DWORD flags )
{ {
Face *face; Face *face;
Family *family; Family *family;
face = create_face( ft_face, face_index, file, font_data_ptr, font_data_size, flags ); face = create_face( ft_face, face_index, dos_name, unix_name, font_data_ptr, font_data_size, flags );
family = get_family( ft_face, flags & ADDFONT_VERTICAL_FONT ); family = get_family( ft_face, flags & ADDFONT_VERTICAL_FONT );
if (insert_face_in_family_list( face, family )) if (insert_face_in_family_list( face, family ))
@ -2263,19 +2255,20 @@ fail:
return NULL; return NULL;
} }
static INT AddFontToList(const char *file, void *font_data_ptr, DWORD font_data_size, DWORD flags) static INT AddFontToList(const WCHAR *dos_name, const char *unix_name, void *font_data_ptr,
DWORD font_data_size, DWORD flags)
{ {
FT_Face ft_face; FT_Face ft_face;
FT_Long face_index = 0, num_faces; FT_Long face_index = 0, num_faces;
INT ret = 0; INT ret = 0;
/* we always load external fonts from files - otherwise we would get a crash in update_reg_entries */ /* we always load external fonts from files - otherwise we would get a crash in update_reg_entries */
assert(file || !(flags & ADDFONT_EXTERNAL_FONT)); assert(unix_name || !(flags & ADDFONT_EXTERNAL_FONT));
#ifdef HAVE_CARBON_CARBON_H #ifdef HAVE_CARBON_CARBON_H
if(file) if(unix_name)
{ {
char **mac_list = expand_mac_font(file); char **mac_list = expand_mac_font(unix_name);
if(mac_list) if(mac_list)
{ {
BOOL had_one = FALSE; BOOL had_one = FALSE;
@ -2283,7 +2276,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, flags); AddFontToList(NULL, *cursor, NULL, 0, flags);
HeapFree(GetProcessHeap(), 0, *cursor); HeapFree(GetProcessHeap(), 0, *cursor);
} }
HeapFree(GetProcessHeap(), 0, mac_list); HeapFree(GetProcessHeap(), 0, mac_list);
@ -2296,23 +2289,23 @@ static INT AddFontToList(const char *file, void *font_data_ptr, DWORD font_data_
do { do {
FONTSIGNATURE fs; FONTSIGNATURE fs;
ft_face = new_ft_face( file, font_data_ptr, font_data_size, face_index, flags & ADDFONT_ALLOW_BITMAP ); ft_face = new_ft_face( unix_name, font_data_ptr, font_data_size, face_index, flags & ADDFONT_ALLOW_BITMAP );
if (!ft_face) return 0; if (!ft_face) return 0;
if(ft_face->family_name[0] == '.') /* Ignore fonts with names beginning with a dot */ 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(file)); TRACE("Ignoring %s since its family name begins with a dot\n", debugstr_a(unix_name));
pFT_Done_Face(ft_face); pFT_Done_Face(ft_face);
return 0; return 0;
} }
AddFaceToList(ft_face, file, font_data_ptr, font_data_size, face_index, flags); AddFaceToList(ft_face, dos_name, unix_name, font_data_ptr, font_data_size, face_index, flags);
++ret; ++ret;
get_fontsig(ft_face, &fs); get_fontsig(ft_face, &fs);
if (fs.fsCsb[0] & FS_DBCS_MASK) if (fs.fsCsb[0] & FS_DBCS_MASK)
{ {
AddFaceToList(ft_face, file, font_data_ptr, font_data_size, face_index, AddFaceToList(ft_face, dos_name, unix_name, font_data_ptr, font_data_size, face_index,
flags | ADDFONT_VERTICAL_FONT); flags | ADDFONT_VERTICAL_FONT);
++ret; ++ret;
} }
@ -2330,7 +2323,7 @@ static int add_font_resource( const WCHAR *file, DWORD flags )
if (unixname) if (unixname)
{ {
ret = AddFontToList( unixname, NULL, 0, flags ); ret = AddFontToList( file, unixname, NULL, 0, flags );
HeapFree( GetProcessHeap(), 0, unixname ); HeapFree( GetProcessHeap(), 0, unixname );
} }
return ret; return ret;
@ -2601,7 +2594,7 @@ static void populate_system_links(const WCHAR *name, const WCHAR *const *values)
{ {
if (!face->file) if (!face->file)
continue; continue;
file = strrchrW(face->file, '/'); file = strrchrW(face->file, '\\');
if (!file) if (!file)
file = face->file; file = face->file;
else else
@ -2819,7 +2812,7 @@ static BOOL ReadFontDir(const char *dirname, BOOL external_fonts)
{ {
DWORD addfont_flags = ADDFONT_ADD_TO_CACHE; DWORD addfont_flags = ADDFONT_ADD_TO_CACHE;
if(external_fonts) addfont_flags |= ADDFONT_EXTERNAL_FONT; if(external_fonts) addfont_flags |= ADDFONT_EXTERNAL_FONT;
AddFontToList(path, NULL, 0, addfont_flags); AddFontToList(NULL, path, NULL, 0, addfont_flags);
} }
} }
closedir(dir); closedir(dir);
@ -2954,7 +2947,7 @@ static void load_fontconfig_fonts(void)
if(len < 4) continue; if(len < 4) continue;
ext = &file[ len - 3 ]; ext = &file[ len - 3 ];
if(_strnicmp(ext, "pfa", -1) && _strnicmp(ext, "pfb", -1)) if(_strnicmp(ext, "pfa", -1) && _strnicmp(ext, "pfb", -1))
AddFontToList(file, NULL, 0, AddFontToList(NULL, file, NULL, 0,
ADDFONT_EXTERNAL_FONT | ADDFONT_ADD_TO_CACHE | ADDFONT_AA_FLAGS(aa_flags) ); ADDFONT_EXTERNAL_FONT | ADDFONT_ADD_TO_CACHE | ADDFONT_AA_FLAGS(aa_flags) );
} }
pFcFontSetDestroy(fontset); pFcFontSetDestroy(fontset);
@ -2974,7 +2967,7 @@ static void load_mac_font_callback(const void *value, void *context)
if (path && CFStringGetFileSystemRepresentation(pathStr, path, len)) if (path && CFStringGetFileSystemRepresentation(pathStr, path, len))
{ {
TRACE("font file %s\n", path); TRACE("font file %s\n", path);
AddFontToList(path, NULL, 0, ADDFONT_EXTERNAL_FONT | ADDFONT_ADD_TO_CACHE); AddFontToList(NULL, path, NULL, 0, ADDFONT_EXTERNAL_FONT | ADDFONT_ADD_TO_CACHE);
} }
HeapFree(GetProcessHeap(), 0, path); HeapFree(GetProcessHeap(), 0, path);
} }
@ -3102,7 +3095,8 @@ static void get_font_dir( WCHAR *path )
{ {
strcatW( path, fontsW ); strcatW( path, fontsW );
} }
path[1] = '\\'; /* change \??\ to \\?\ */ if (path[5] == ':') memmove( path, path + 4, (strlenW(path) - 3) * sizeof(WCHAR) );
else path[1] = '\\'; /* change \??\ to \\?\ */
} }
static void get_data_dir_path( LPCWSTR file, WCHAR *path ) static void get_data_dir_path( LPCWSTR file, WCHAR *path )
@ -3189,7 +3183,7 @@ static void update_reg_entries(void)
DWORD len; DWORD len;
Family *family; Family *family;
Face *face; Face *face;
WCHAR *file, *path, *full_path; WCHAR *file, *path;
static const WCHAR TrueType[] = {' ','(','T','r','u','e','T','y','p','e',')','\0'}; static const WCHAR TrueType[] = {' ','(','T','r','u','e','T','y','p','e',')','\0'};
if(RegCreateKeyExW(HKEY_LOCAL_MACHINE, winnt_font_reg_key, if(RegCreateKeyExW(HKEY_LOCAL_MACHINE, winnt_font_reg_key,
@ -3214,7 +3208,6 @@ static void update_reg_entries(void)
LIST_FOR_EACH_ENTRY( family, &font_list, Family, entry ) { LIST_FOR_EACH_ENTRY( family, &font_list, Family, entry ) {
LIST_FOR_EACH_ENTRY( face, &family->faces, Face, entry ) { LIST_FOR_EACH_ENTRY( face, &family->faces, Face, entry ) {
char *buffer;
if (!(face->flags & ADDFONT_EXTERNAL_FONT)) continue; if (!(face->flags & ADDFONT_EXTERNAL_FONT)) continue;
len = strlenW( face->full_name ) + 1; len = strlenW( face->full_name ) + 1;
@ -3227,20 +3220,11 @@ static void update_reg_entries(void)
if (face->scalable) if (face->scalable)
strcatW(valueW, TrueType); strcatW(valueW, TrueType);
buffer = strWtoA( CP_UNIXCP, face->file ); if ((path = get_full_path_name(face->file)))
path = wine_get_dos_file_name( buffer );
HeapFree( GetProcessHeap(), 0, buffer );
if (path)
{ {
if ((full_path = get_full_path_name(path)))
{
HeapFree(GetProcessHeap(), 0, path);
path = full_path;
}
file = path; file = path;
} }
else if ((file = strrchrW(face->file, '/'))) else if ((file = strrchrW(face->file, '\\')))
{ {
file++; file++;
} }
@ -3348,7 +3332,8 @@ INT WineEngAddFontResourceEx(LPCWSTR file, DWORD flags, PVOID pdv)
EnterCriticalSection( &freetype_cs ); EnterCriticalSection( &freetype_cs );
if (!(flags & FR_PRIVATE)) addfont_flags |= ADDFONT_ADD_TO_CACHE; if (!(flags & FR_PRIVATE)) addfont_flags |= ADDFONT_ADD_TO_CACHE;
ret = add_font_resource( file, addfont_flags ); if (GetFullPathNameW( file, MAX_PATH, path, NULL ))
ret = add_font_resource( path, addfont_flags );
if (!ret && !strchrW(file, '\\')) { if (!ret && !strchrW(file, '\\')) {
/* Try in %WINDIR%/fonts, needed for Fotobuch Designer */ /* Try in %WINDIR%/fonts, needed for Fotobuch Designer */
@ -3383,7 +3368,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, ADDFONT_ALLOW_BITMAP | ADDFONT_ADD_RESOURCE); *pcFonts = AddFontToList(NULL, NULL, pFontCopy, cbFont, ADDFONT_ALLOW_BITMAP | ADDFONT_ADD_RESOURCE);
LeaveCriticalSection( &freetype_cs ); LeaveCriticalSection( &freetype_cs );
if (*pcFonts == 0) if (*pcFonts == 0)
@ -3421,7 +3406,8 @@ BOOL WineEngRemoveFontResourceEx(LPCWSTR file, DWORD flags, PVOID pdv)
EnterCriticalSection( &freetype_cs ); EnterCriticalSection( &freetype_cs );
if(!(flags & FR_PRIVATE)) addfont_flags |= ADDFONT_ADD_TO_CACHE; if(!(flags & FR_PRIVATE)) addfont_flags |= ADDFONT_ADD_TO_CACHE;
ret = remove_font_resource( file, addfont_flags ); if (GetFullPathNameW( file, MAX_PATH, path, NULL ))
ret = remove_font_resource( path, addfont_flags );
if (!ret && !strchrW(file, '\\')) if (!ret && !strchrW(file, '\\'))
{ {
@ -3439,10 +3425,9 @@ BOOL WineEngRemoveFontResourceEx(LPCWSTR file, DWORD flags, PVOID pdv)
return ret; return ret;
} }
static char *get_ttf_file_name( LPCWSTR font_file, LPCWSTR font_path ) static WCHAR *get_ttf_file_name( LPCWSTR font_file, LPCWSTR font_path )
{ {
WCHAR *fullname; WCHAR *fullname;
char *unix_name;
int file_len; int file_len;
if (!font_file) return NULL; if (!font_file) return NULL;
@ -3457,19 +3442,9 @@ static char *get_ttf_file_name( LPCWSTR font_file, LPCWSTR font_path )
memcpy( fullname, font_path, path_len * sizeof(WCHAR) ); memcpy( fullname, font_path, path_len * sizeof(WCHAR) );
fullname[path_len] = '\\'; fullname[path_len] = '\\';
memcpy( fullname + path_len + 1, font_file, (file_len + 1) * sizeof(WCHAR) ); memcpy( fullname + path_len + 1, font_file, (file_len + 1) * sizeof(WCHAR) );
return fullname;
} }
else return get_full_path_name( font_file );
{
int len = GetFullPathNameW( font_file, 0, NULL, NULL );
if (!len) return NULL;
fullname = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
if (!fullname) return NULL;
GetFullPathNameW( font_file, len, fullname, NULL );
}
unix_name = wine_get_unix_file_name( fullname );
HeapFree( GetProcessHeap(), 0, fullname );
return unix_name;
} }
#include <pshpack1.h> #include <pshpack1.h>
@ -3513,24 +3488,33 @@ struct fontdir
static void GetEnumStructs(Face *face, const WCHAR *family_name, LPENUMLOGFONTEXW pelf, static void GetEnumStructs(Face *face, const WCHAR *family_name, LPENUMLOGFONTEXW pelf,
NEWTEXTMETRICEXW *pntm, LPDWORD ptype); NEWTEXTMETRICEXW *pntm, LPDWORD ptype);
static BOOL get_fontdir( const char *unix_name, struct fontdir *fd ) static BOOL get_fontdir( const WCHAR *dos_name, struct fontdir *fd )
{ {
FT_Face ft_face = new_ft_face( unix_name, NULL, 0, 0, FALSE ); FT_Face ft_face;
Face *face; Face *face = NULL;
char *unix_name;
WCHAR *family_name; WCHAR *family_name;
ENUMLOGFONTEXW elf; ENUMLOGFONTEXW elf;
NEWTEXTMETRICEXW ntm; NEWTEXTMETRICEXW ntm;
DWORD type; DWORD type;
if (!ft_face) return FALSE; if (!(unix_name = wine_get_unix_file_name( dos_name ))) return FALSE;
face = create_face( ft_face, 0, unix_name, NULL, 0, 0 ); ft_face = new_ft_face( unix_name, NULL, 0, 0, FALSE );
if (ft_face)
{
face = create_face( ft_face, 0, dos_name, unix_name, NULL, 0, 0 );
if (face)
{
family_name = ft_face_get_family_name( ft_face, GetSystemDefaultLCID() ); family_name = ft_face_get_family_name( ft_face, GetSystemDefaultLCID() );
pFT_Done_Face( ft_face );
GetEnumStructs( face, family_name, &elf, &ntm, &type ); GetEnumStructs( face, family_name, &elf, &ntm, &type );
release_face( face ); release_face( face );
HeapFree( GetProcessHeap(), 0, family_name ); HeapFree( GetProcessHeap(), 0, family_name );
}
pFT_Done_Face( ft_face );
}
HeapFree( GetProcessHeap(), 0, unix_name );
if (!face) return FALSE;
if ((type & TRUETYPE_FONTTYPE) == 0) return FALSE; if ((type & TRUETYPE_FONTTYPE) == 0) return FALSE;
memset( fd, 0, sizeof(*fd) ); memset( fd, 0, sizeof(*fd) );
@ -3724,11 +3708,11 @@ static BOOL create_fot( const WCHAR *resource, const WCHAR *font_file, const str
BOOL WineEngCreateScalableFontResource( DWORD hidden, LPCWSTR resource, BOOL WineEngCreateScalableFontResource( DWORD hidden, LPCWSTR resource,
LPCWSTR font_file, LPCWSTR font_path ) LPCWSTR font_file, LPCWSTR font_path )
{ {
char *unix_name = get_ttf_file_name( font_file, font_path ); WCHAR *filename = get_ttf_file_name( font_file, font_path );
struct fontdir fontdir; struct fontdir fontdir;
BOOL ret = FALSE; BOOL ret = FALSE;
if (!unix_name || !get_fontdir( unix_name, &fontdir )) if (!filename || !get_fontdir( filename, &fontdir ))
SetLastError( ERROR_INVALID_PARAMETER ); SetLastError( ERROR_INVALID_PARAMETER );
else else
{ {
@ -3736,7 +3720,7 @@ BOOL WineEngCreateScalableFontResource( DWORD hidden, LPCWSTR resource,
ret = create_fot( resource, font_file, &fontdir ); ret = create_fot( resource, font_file, &fontdir );
} }
HeapFree( GetProcessHeap(), 0, unix_name ); HeapFree( GetProcessHeap(), 0, filename );
return ret; return ret;
} }
@ -4176,7 +4160,7 @@ static FT_Face OpenFontFace(GdiFont *font, Face *face, LONG width, LONG height)
if (face->file) if (face->file)
{ {
char *filename = strWtoA( CP_UNIXCP, face->file ); char *filename = wine_get_unix_file_name( face->file );
font->mapping = map_font_file( filename ); font->mapping = map_font_file( filename );
HeapFree( GetProcessHeap(), 0, filename ); HeapFree( GetProcessHeap(), 0, filename );
if (!font->mapping) if (!font->mapping)