From 43b62092a0ee28d7f92db6e2d2011ae791113c69 Mon Sep 17 00:00:00 2001 From: Huw D M Davies Date: Wed, 3 Apr 2002 20:51:20 +0000 Subject: [PATCH] Add font substitution lookup in the registry. We look under the key HKLM\Software\Microsoft\Windows NT\CurrentVersion\FontSubstitutes for "fromName[,cp]"="toName[,cp]" where cp can be an optional codepage. Substitution occurs before scanning the available font list, as is the case with Windows. --- dlls/gdi/freetype.c | 121 ++++++++++++++++++++++++++++++++++++++++++++ winedefault.reg | 20 ++++++++ 2 files changed, 141 insertions(+) diff --git a/dlls/gdi/freetype.c b/dlls/gdi/freetype.c index 2b6f2d3c43c..057ead6f486 100644 --- a/dlls/gdi/freetype.c +++ b/dlls/gdi/freetype.c @@ -179,6 +179,19 @@ static WCHAR *ElfScriptsW[32] = { /* these are in the order of the fsCsb[0] bits SymbolW /*31*/ }; +typedef struct { + WCHAR *name; + INT charset; +} NameCs; + +typedef struct tagFontSubst { + NameCs from; + NameCs to; + struct tagFontSubst *next; +} FontSubst; + +static FontSubst *substlist = NULL; + static BOOL AddFontFileToList(char *file) { FT_Face ft_face; @@ -290,6 +303,98 @@ static void DumpFontList(void) return; } +static void DumpSubstList(void) +{ + FontSubst *psub; + + for(psub = substlist; psub; psub = psub->next) + if(psub->from.charset != -1 || psub->to.charset != -1) + TRACE("%s:%d -> %s:%d\n", debugstr_w(psub->from.name), + psub->from.charset, debugstr_w(psub->to.name), psub->to.charset); + else + TRACE("%s -> %s\n", debugstr_w(psub->from.name), + debugstr_w(psub->to.name)); + return; +} + +static void split_subst_info(NameCs *nc, LPSTR str) +{ + CHAR *p = strrchr(str, ','); + DWORD len; + + nc->charset = -1; + if(p && *(p+1)) { + nc->charset = strtol(p+1, NULL, 10); + *p = '\0'; + } + len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0); + nc->name = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR)); + MultiByteToWideChar(CP_ACP, 0, str, -1, nc->name, len); +} + +static void LoadSubstList(void) +{ + FontSubst *psub, **ppsub; + HKEY hkey; + DWORD valuelen, datalen, i = 0, type, dlen, vlen; + LPSTR value; + LPVOID data; + + if(substlist) { + for(psub = substlist; psub;) { + FontSubst *ptmp; + HeapFree(GetProcessHeap(), 0, psub->to.name); + HeapFree(GetProcessHeap(), 0, psub->from.name); + ptmp = psub; + psub = psub->next; + HeapFree(GetProcessHeap(), 0, ptmp); + } + substlist = NULL; + } + + if(RegOpenKeyA(HKEY_LOCAL_MACHINE, + "Software\\Microsoft\\Windows NT\\CurrentVersion\\FontSubstitutes", + &hkey) == ERROR_SUCCESS) { + + RegQueryInfoKeyA(hkey, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + &valuelen, &datalen, NULL, NULL); + + valuelen++; /* returned value doesn't include room for '\0' */ + value = HeapAlloc(GetProcessHeap(), 0, valuelen * sizeof(CHAR)); + data = HeapAlloc(GetProcessHeap(), 0, datalen); + + dlen = datalen; + vlen = valuelen; + ppsub = &substlist; + while(RegEnumValueA(hkey, i++, value, &vlen, NULL, &type, data, + &dlen) == ERROR_SUCCESS) { + TRACE("Got %s=%s\n", debugstr_a(value), debugstr_a(data)); + + *ppsub = HeapAlloc(GetProcessHeap(), 0, sizeof(**ppsub)); + (*ppsub)->next = NULL; + split_subst_info(&((*ppsub)->from), value); + split_subst_info(&((*ppsub)->to), data); + + /* Win 2000 doesn't allow mapping between different charsets + or mapping of DEFAULT_CHARSET */ + if(((*ppsub)->to.charset != (*ppsub)->from.charset) || + (*ppsub)->to.charset == DEFAULT_CHARSET) { + HeapFree(GetProcessHeap(), 0, (*ppsub)->to.name); + HeapFree(GetProcessHeap(), 0, (*ppsub)->from.name); + HeapFree(GetProcessHeap(), 0, *ppsub); + } else { + ppsub = &((*ppsub)->next); + } + /* reset dlen and vlen */ + dlen = datalen; + vlen = valuelen; + } + HeapFree(GetProcessHeap(), 0, data); + HeapFree(GetProcessHeap(), 0, value); + RegCloseKey(hkey); + } +} + static BOOL ReadFontDir(char *dirname) { DIR *dir; @@ -421,6 +526,8 @@ BOOL WineEngInit(void) } DumpFontList(); + LoadSubstList(); + DumpSubstList(); return TRUE; sym_not_found: WINE_MESSAGE( @@ -713,6 +820,18 @@ GdiFont WineEngCreateFontInstance(HFONT hfont) strcpyW(FaceName, plf->lfFaceName); if(FaceName[0] != '\0') { + FontSubst *psub; + for(psub = substlist; psub; psub = psub->next) + if(!strcmpiW(FaceName, psub->from.name) && + (psub->from.charset == -1 || + psub->from.charset == plf->lfCharSet)) + break; + if(psub) { + TRACE("substituting %s -> %s\n", debugstr_w(FaceName), + debugstr_w(psub->to.name)); + strcpyW(FaceName, psub->to.name); + } + for(family = FontList; family; family = family->next) { if(!strcmpiW(family->FamilyName, FaceName)) break; @@ -744,6 +863,8 @@ not_found: strcpyW(FaceName, defSerif); else if(plf->lfPitchAndFamily & FF_SWISS) strcpyW(FaceName, defSans); + else + strcpyW(FaceName, defSans); for(family = FontList; family; family = family->next) { if(!strcmpiW(family->FamilyName, FaceName)) break; diff --git a/winedefault.reg b/winedefault.reg index d369c60390a..b86b837358a 100644 --- a/winedefault.reg +++ b/winedefault.reg @@ -690,3 +690,23 @@ [HKEY_LOCAL_MACHINE\TypeLib\{1339B53E-3453-11D2-93B9-000000000000}\1.0\0\win32] @="C:\mozilla\bin\mozctl.dll" +[HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\FontSubstitutes] +"Arial CE,238"="Arial,238" +"Arial CYR,204"="Arial,204" +"Arial Greek,161"="Arial,161" +"Arial TUR,162"="Arial,162" +"Courier New CE,238"="Courier New,238" +"Courier New CYR,204"="Courier New,204" +"Courier New Greek,161"="Courier New,161" +"Courier New TUR,162"="Courier New,162" +"Helv"="Arial" +"Helvetica"="Arial" +"MS Shell Dlg"="Tahoma" +"MS Shell Dlg 2"="Tahoma" +"Times"="Times New Roman" +"Times New Roman CE,238"="Times New Roman,238" +"Times New Roman CYR,204"="Times New Roman,204" +"Times New Roman Greek,161"="Times New Roman,161" +"Times New Roman TUR,162"="Times New Roman,162" +"Tms Rmn"="Times New Roman" +