Add registry entries for any fonts found by fontconfig or that are in
the FontDirs directories.
This commit is contained in:
parent
fb1ae96cf7
commit
db226a8049
@ -142,6 +142,7 @@ typedef struct tagFace {
|
|||||||
BOOL Bold;
|
BOOL Bold;
|
||||||
FONTSIGNATURE fs;
|
FONTSIGNATURE fs;
|
||||||
FT_Fixed font_version;
|
FT_Fixed font_version;
|
||||||
|
BOOL external; /* TRUE if we should manually add this font to the registry */
|
||||||
struct tagFace *next;
|
struct tagFace *next;
|
||||||
struct tagFamily *family;
|
struct tagFamily *family;
|
||||||
} Face;
|
} Face;
|
||||||
@ -195,6 +196,20 @@ static const WCHAR SystemW[] = {'S','y','s','t','e','m','\0'};
|
|||||||
static const WCHAR MSSansSerifW[] = {'M','S',' ','S','a','n','s',' ',
|
static const WCHAR MSSansSerifW[] = {'M','S',' ','S','a','n','s',' ',
|
||||||
'S','e','r','i','f','\0'};
|
'S','e','r','i','f','\0'};
|
||||||
static const WCHAR HelvW[] = {'H','e','l','v','\0'};
|
static const WCHAR HelvW[] = {'H','e','l','v','\0'};
|
||||||
|
static const WCHAR RegularW[] = {'R','e','g','u','l','a','r','\0'};
|
||||||
|
|
||||||
|
static const WCHAR win9x_font_reg_key[] = {'S','o','f','t','w','a','r','e','\\','M','i','c','r','o','s','o','f','t','\\',
|
||||||
|
'W','i','n','d','o','w','s','\\',
|
||||||
|
'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
|
||||||
|
'F','o','n','t','s','\0'};
|
||||||
|
|
||||||
|
static const WCHAR winnt_font_reg_key[] = {'S','o','f','t','w','a','r','e','\\','M','i','c','r','o','s','o','f','t','\\',
|
||||||
|
'W','i','n','d','o','w','s',' ','N','T','\\',
|
||||||
|
'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
|
||||||
|
'F','o','n','t','s','\0'};
|
||||||
|
|
||||||
|
static const WCHAR external_fonts_reg_key[] = {'S','o','f','t','w','a','r','e','\\','W','i','n','e','\\','W','i','n','e','\\',
|
||||||
|
'F','o','n','t','s','\\','E','x','t','e','r','n','a','l',' ','F','o','n','t','s','\0'};
|
||||||
|
|
||||||
static const WCHAR ArabicW[] = {'A','r','a','b','i','c','\0'};
|
static const WCHAR ArabicW[] = {'A','r','a','b','i','c','\0'};
|
||||||
static const WCHAR BalticW[] = {'B','a','l','t','i','c','\0'};
|
static const WCHAR BalticW[] = {'B','a','l','t','i','c','\0'};
|
||||||
@ -250,6 +265,12 @@ typedef struct tagFontSubst {
|
|||||||
static FontSubst *substlist = NULL;
|
static FontSubst *substlist = NULL;
|
||||||
static BOOL have_installed_roman_font = FALSE; /* CreateFontInstance will fail if this is still FALSE */
|
static BOOL have_installed_roman_font = FALSE; /* CreateFontInstance will fail if this is still FALSE */
|
||||||
|
|
||||||
|
static const WCHAR font_mutex_nameW[] = {'_','_','W','I','N','E','_','F','O','N','T','_','M','U','T','E','X','_','_','\0'};
|
||||||
|
|
||||||
|
static inline BOOL is_win9x(void)
|
||||||
|
{
|
||||||
|
return GetVersion() & 0x80000000;
|
||||||
|
}
|
||||||
/*
|
/*
|
||||||
This function builds an FT_Fixed from a float. It puts the integer part
|
This function builds an FT_Fixed from a float. It puts the integer part
|
||||||
in the highest 16 bits and the decimal part in the lowest 16 bits of the FT_Fixed.
|
in the highest 16 bits and the decimal part in the lowest 16 bits of the FT_Fixed.
|
||||||
@ -271,7 +292,7 @@ static inline FT_Fixed FT_FixedFromFIXED(FIXED f)
|
|||||||
return (FT_Fixed)((long)f.value << 16 | (unsigned long)f.fract);
|
return (FT_Fixed)((long)f.value << 16 | (unsigned long)f.fract);
|
||||||
}
|
}
|
||||||
|
|
||||||
static BOOL AddFontFileToList(const char *file, char *fake_family)
|
static BOOL AddFontFileToList(const char *file, char *fake_family, BOOL external_font)
|
||||||
{
|
{
|
||||||
FT_Face ft_face;
|
FT_Face ft_face;
|
||||||
TT_OS2 *pOS2;
|
TT_OS2 *pOS2;
|
||||||
@ -378,6 +399,7 @@ static BOOL AddFontFileToList(const char *file, char *fake_family)
|
|||||||
(*insertface)->Bold = (ft_face->style_flags & FT_STYLE_FLAG_BOLD) ? 1 : 0;
|
(*insertface)->Bold = (ft_face->style_flags & FT_STYLE_FLAG_BOLD) ? 1 : 0;
|
||||||
(*insertface)->font_version = pHeader->Font_Revision;
|
(*insertface)->font_version = pHeader->Font_Revision;
|
||||||
(*insertface)->family = family;
|
(*insertface)->family = family;
|
||||||
|
(*insertface)->external = external_font;
|
||||||
|
|
||||||
pOS2 = pFT_Get_Sfnt_Table(ft_face, ft_sfnt_os2);
|
pOS2 = pFT_Get_Sfnt_Table(ft_face, ft_sfnt_os2);
|
||||||
if(pOS2) {
|
if(pOS2) {
|
||||||
@ -602,7 +624,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), value);
|
debugstr_w(face->StyleName), value);
|
||||||
/* Now add a new entry with the new family name */
|
/* Now add a new entry with the new family name */
|
||||||
AddFontFileToList(face->file, value);
|
AddFontFileToList(face->file, value, face->external);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -618,7 +640,7 @@ static void LoadReplaceList(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static BOOL ReadFontDir(const char *dirname)
|
static BOOL ReadFontDir(const char *dirname, BOOL external_fonts)
|
||||||
{
|
{
|
||||||
DIR *dir;
|
DIR *dir;
|
||||||
struct dirent *dent;
|
struct dirent *dent;
|
||||||
@ -647,9 +669,9 @@ static BOOL ReadFontDir(const char *dirname)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if(S_ISDIR(statbuf.st_mode))
|
if(S_ISDIR(statbuf.st_mode))
|
||||||
ReadFontDir(path);
|
ReadFontDir(path, external_fonts);
|
||||||
else
|
else
|
||||||
AddFontFileToList(path, NULL);
|
AddFontFileToList(path, NULL, external_fonts);
|
||||||
}
|
}
|
||||||
closedir(dir);
|
closedir(dir);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
@ -707,7 +729,7 @@ LOAD_FUNCPTR(FcPatternGet);
|
|||||||
if(len < 4) continue;
|
if(len < 4) continue;
|
||||||
ext = v.u.s + len - 3;
|
ext = v.u.s + len - 3;
|
||||||
if(!strcasecmp(ext, "ttf") || !strcasecmp(ext, "ttc") || !strcasecmp(ext, "otf"))
|
if(!strcasecmp(ext, "ttf") || !strcasecmp(ext, "ttc") || !strcasecmp(ext, "otf"))
|
||||||
AddFontFileToList(v.u.s, NULL);
|
AddFontFileToList(v.u.s, NULL, TRUE);
|
||||||
}
|
}
|
||||||
pFcFontSetDestroy(fontset);
|
pFcFontSetDestroy(fontset);
|
||||||
pFcObjectSetDestroy(os);
|
pFcObjectSetDestroy(os);
|
||||||
@ -716,6 +738,111 @@ LOAD_FUNCPTR(FcPatternGet);
|
|||||||
#endif
|
#endif
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*************************************************************
|
||||||
|
*
|
||||||
|
* This adds registry entries for any externally loaded fonts
|
||||||
|
* (fonts from fontconfig or FontDirs). It also deletes entries
|
||||||
|
* of no longer existing fonts.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void update_reg_entries(void)
|
||||||
|
{
|
||||||
|
HKEY winkey = 0, externalkey = 0;
|
||||||
|
LPWSTR valueW;
|
||||||
|
LPVOID data;
|
||||||
|
DWORD dlen, vlen, datalen, valuelen, i, type, len, len_fam;
|
||||||
|
Family *family;
|
||||||
|
Face *face;
|
||||||
|
WCHAR *file;
|
||||||
|
const WCHAR TrueType[] = {' ','(','T','r','u','e','T','y','p','e',')','\0'};
|
||||||
|
const WCHAR spaceW[] = {' ', '\0'};
|
||||||
|
char *path;
|
||||||
|
|
||||||
|
if(RegCreateKeyExW(HKEY_LOCAL_MACHINE, is_win9x() ? win9x_font_reg_key : winnt_font_reg_key,
|
||||||
|
0, NULL, 0, KEY_ALL_ACCESS, NULL, &winkey, NULL) != ERROR_SUCCESS) {
|
||||||
|
ERR("Can't create Windows font reg key\n");
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
if(RegCreateKeyExW(HKEY_LOCAL_MACHINE, external_fonts_reg_key,
|
||||||
|
0, NULL, 0, KEY_ALL_ACCESS, NULL, &externalkey, NULL) != ERROR_SUCCESS) {
|
||||||
|
ERR("Can't create external font reg key\n");
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Delete all external fonts added last time */
|
||||||
|
|
||||||
|
RegQueryInfoKeyW(externalkey, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||||
|
&valuelen, &datalen, NULL, NULL);
|
||||||
|
valuelen++; /* returned value doesn't include room for '\0' */
|
||||||
|
valueW = HeapAlloc(GetProcessHeap(), 0, valuelen * sizeof(WCHAR));
|
||||||
|
data = HeapAlloc(GetProcessHeap(), 0, datalen * sizeof(WCHAR));
|
||||||
|
|
||||||
|
dlen = datalen * sizeof(WCHAR);
|
||||||
|
vlen = valuelen;
|
||||||
|
i = 0;
|
||||||
|
while(RegEnumValueW(externalkey, i++, valueW, &vlen, NULL, &type, data,
|
||||||
|
&dlen) == ERROR_SUCCESS) {
|
||||||
|
|
||||||
|
RegDeleteValueW(winkey, valueW);
|
||||||
|
/* reset dlen and vlen */
|
||||||
|
dlen = datalen;
|
||||||
|
vlen = valuelen;
|
||||||
|
}
|
||||||
|
HeapFree(GetProcessHeap(), 0, data);
|
||||||
|
HeapFree(GetProcessHeap(), 0, valueW);
|
||||||
|
|
||||||
|
/* Delete the old external fonts key */
|
||||||
|
RegCloseKey(externalkey);
|
||||||
|
externalkey = 0;
|
||||||
|
RegDeleteKeyW(HKEY_LOCAL_MACHINE, external_fonts_reg_key);
|
||||||
|
|
||||||
|
if(RegCreateKeyExW(HKEY_LOCAL_MACHINE, external_fonts_reg_key,
|
||||||
|
0, NULL, 0, KEY_ALL_ACCESS, NULL, &externalkey, NULL) != ERROR_SUCCESS) {
|
||||||
|
ERR("Can't create external font reg key\n");
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* enumerate the fonts and add external ones to the two keys */
|
||||||
|
|
||||||
|
for(family = FontList; family; family = family->next) {
|
||||||
|
len_fam = strlenW(family->FamilyName) + sizeof(TrueType) / sizeof(WCHAR) + 1;
|
||||||
|
for(face = family->FirstFace; face; face = face->next) {
|
||||||
|
if(!face->external) continue;
|
||||||
|
len = len_fam;
|
||||||
|
if(strcmpiW(face->StyleName, RegularW))
|
||||||
|
len = len_fam + strlenW(face->StyleName) + 1;
|
||||||
|
valueW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
|
||||||
|
strcpyW(valueW, family->FamilyName);
|
||||||
|
if(len != len_fam) {
|
||||||
|
strcatW(valueW, spaceW);
|
||||||
|
strcatW(valueW, face->StyleName);
|
||||||
|
}
|
||||||
|
strcatW(valueW, TrueType);
|
||||||
|
if((path = strrchr(face->file, '/')) == NULL)
|
||||||
|
path = face->file;
|
||||||
|
else
|
||||||
|
path++;
|
||||||
|
len = MultiByteToWideChar(CP_ACP, 0, path, -1, NULL, 0);
|
||||||
|
|
||||||
|
file = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
|
||||||
|
MultiByteToWideChar(CP_ACP, 0, path, -1, file, len);
|
||||||
|
RegSetValueExW(winkey, valueW, 0, REG_SZ, (BYTE*)file, len * sizeof(WCHAR));
|
||||||
|
RegSetValueExW(externalkey, valueW, 0, REG_SZ, (BYTE*)file, len * sizeof(WCHAR));
|
||||||
|
|
||||||
|
HeapFree(GetProcessHeap(), 0, file);
|
||||||
|
HeapFree(GetProcessHeap(), 0, valueW);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
end:
|
||||||
|
if(externalkey)
|
||||||
|
RegCloseKey(externalkey);
|
||||||
|
if(winkey)
|
||||||
|
RegCloseKey(winkey);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************
|
/*************************************************************
|
||||||
* WineEngAddFontResourceEx
|
* WineEngAddFontResourceEx
|
||||||
*
|
*
|
||||||
@ -730,7 +857,7 @@ INT WineEngAddFontResourceEx(LPCWSTR file, DWORD flags, PVOID pdv)
|
|||||||
FIXME("Ignoring flags %lx\n", flags);
|
FIXME("Ignoring flags %lx\n", flags);
|
||||||
|
|
||||||
if(wine_get_unix_file_name(file, unixname, sizeof(unixname)))
|
if(wine_get_unix_file_name(file, unixname, sizeof(unixname)))
|
||||||
AddFontFileToList(unixname, NULL);
|
AddFontFileToList(unixname, NULL, FALSE);
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -758,6 +885,7 @@ BOOL WineEngInit(void)
|
|||||||
LPVOID data;
|
LPVOID data;
|
||||||
WCHAR windowsdir[MAX_PATH];
|
WCHAR windowsdir[MAX_PATH];
|
||||||
char unixname[MAX_PATH];
|
char unixname[MAX_PATH];
|
||||||
|
HANDLE font_mutex;
|
||||||
|
|
||||||
TRACE("\n");
|
TRACE("\n");
|
||||||
|
|
||||||
@ -821,17 +949,23 @@ BOOL WineEngInit(void)
|
|||||||
}
|
}
|
||||||
TRACE("FreeType version is %d.%d.%d\n",FT_Version.major,FT_Version.minor,FT_Version.patch);
|
TRACE("FreeType version is %d.%d.%d\n",FT_Version.major,FT_Version.minor,FT_Version.patch);
|
||||||
|
|
||||||
|
if((font_mutex = CreateMutexW(NULL, FALSE, font_mutex_nameW)) == NULL) {
|
||||||
|
ERR("Failed to create font mutex\n");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
WaitForSingleObject(font_mutex, INFINITE);
|
||||||
|
|
||||||
/* load in the fonts from %WINDOWSDIR%\\Fonts first of all */
|
/* load in the fonts from %WINDOWSDIR%\\Fonts first of all */
|
||||||
GetWindowsDirectoryW(windowsdir, sizeof(windowsdir) / sizeof(WCHAR));
|
GetWindowsDirectoryW(windowsdir, sizeof(windowsdir) / sizeof(WCHAR));
|
||||||
strcatW(windowsdir, fontsW);
|
strcatW(windowsdir, fontsW);
|
||||||
if(wine_get_unix_file_name(windowsdir, unixname, sizeof(unixname)))
|
if(wine_get_unix_file_name(windowsdir, unixname, sizeof(unixname)))
|
||||||
ReadFontDir(unixname);
|
ReadFontDir(unixname, FALSE);
|
||||||
|
|
||||||
/* now look under HKLM\Software\Microsoft\Windows\CurrentVersion\Fonts
|
/* now look under HKLM\Software\Microsoft\Windows[ NT]\CurrentVersion\Fonts
|
||||||
for any fonts not installed in %WINDOWSDIR%\Fonts. They will have their
|
for any fonts not installed in %WINDOWSDIR%\Fonts. They will have their
|
||||||
full path as the entry */
|
full path as the entry */
|
||||||
if(RegOpenKeyA(HKEY_LOCAL_MACHINE,
|
if(RegOpenKeyW(HKEY_LOCAL_MACHINE,
|
||||||
"Software\\Microsoft\\Windows\\CurrentVersion\\Fonts",
|
is_win9x() ? win9x_font_reg_key : winnt_font_reg_key,
|
||||||
&hkey) == ERROR_SUCCESS) {
|
&hkey) == ERROR_SUCCESS) {
|
||||||
LPWSTR valueW;
|
LPWSTR valueW;
|
||||||
RegQueryInfoKeyW(hkey, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
RegQueryInfoKeyW(hkey, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||||
@ -847,7 +981,7 @@ BOOL WineEngInit(void)
|
|||||||
&dlen) == ERROR_SUCCESS) {
|
&dlen) == ERROR_SUCCESS) {
|
||||||
if(((LPWSTR)data)[0] && ((LPWSTR)data)[1] == ':')
|
if(((LPWSTR)data)[0] && ((LPWSTR)data)[1] == ':')
|
||||||
if(wine_get_unix_file_name((LPWSTR)data, unixname, sizeof(unixname)))
|
if(wine_get_unix_file_name((LPWSTR)data, unixname, sizeof(unixname)))
|
||||||
AddFontFileToList(unixname, NULL);
|
AddFontFileToList(unixname, NULL, FALSE);
|
||||||
|
|
||||||
/* reset dlen and vlen */
|
/* reset dlen and vlen */
|
||||||
dlen = datalen;
|
dlen = datalen;
|
||||||
@ -878,7 +1012,7 @@ BOOL WineEngInit(void)
|
|||||||
while(RegEnumValueA(hkey, i++, value, &vlen, NULL, &type, data,
|
while(RegEnumValueA(hkey, i++, value, &vlen, NULL, &type, data,
|
||||||
&dlen) == ERROR_SUCCESS) {
|
&dlen) == ERROR_SUCCESS) {
|
||||||
TRACE("Got %s=%s\n", value, (LPSTR)data);
|
TRACE("Got %s=%s\n", value, (LPSTR)data);
|
||||||
ReadFontDir((LPSTR)data);
|
ReadFontDir((LPSTR)data, TRUE);
|
||||||
/* reset dlen and vlen */
|
/* reset dlen and vlen */
|
||||||
dlen = datalen;
|
dlen = datalen;
|
||||||
vlen = valuelen;
|
vlen = valuelen;
|
||||||
@ -892,6 +1026,9 @@ BOOL WineEngInit(void)
|
|||||||
LoadSubstList();
|
LoadSubstList();
|
||||||
DumpSubstList();
|
DumpSubstList();
|
||||||
LoadReplaceList();
|
LoadReplaceList();
|
||||||
|
update_reg_entries();
|
||||||
|
|
||||||
|
ReleaseMutex(font_mutex);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
sym_not_found:
|
sym_not_found:
|
||||||
WINE_MESSAGE(
|
WINE_MESSAGE(
|
||||||
|
Loading…
x
Reference in New Issue
Block a user