Paul TBBle Hampson : gdi32: Autopopulate FontLinks when autopopulating FontSubstitutes.
Alexandre Julliard
julliard at winehq.org
Tue May 12 09:08:47 CDT 2009
Module: wine
Branch: master
Commit: 87cd36db5e3e7f389765b9ff4538df0effa9f6c9
URL: http://source.winehq.org/git/wine.git/?a=commit;h=87cd36db5e3e7f389765b9ff4538df0effa9f6c9
Author: Paul TBBle Hampson <Paul.Hampson at Pobox.com>
Date: Sun May 10 03:12:40 2009 +1000
gdi32: Autopopulate FontLinks when autopopulating FontSubstitutes.
When Wine's codepage changes, FontSubstitutes is redefined to use
fonts appropriate for that codepage. Configure FontLinks to reasonable
defaults at the same time.
---
dlls/gdi32/freetype.c | 188 +++++++++++++++++++++++++++++++++++++++++++++++--
1 files changed, 183 insertions(+), 5 deletions(-)
diff --git a/dlls/gdi32/freetype.c b/dlls/gdi32/freetype.c
index 7b0afa8..60c5f21 100644
--- a/dlls/gdi32/freetype.c
+++ b/dlls/gdi32/freetype.c
@@ -400,6 +400,16 @@ static const WCHAR * const SystemFontValues[4] = {
static const WCHAR external_fonts_reg_key[] = {'S','o','f','t','w','a','r','e','\\','W','i','n','e','\\',
'F','o','n','t','s','\\','E','x','t','e','r','n','a','l',' ','F','o','n','t','s','\0'};
+/* Interesting and well-known (frequently-assumed!) font names */
+static const WCHAR Lucida_Sans_Unicode[] = {'L','u','c','i','d','a',' ','S','a','n','s',' ','U','n','i','c','o','d','e',0};
+static const WCHAR Microsoft_Sans_Serif[] = {'M','i','c','r','o','s','o','f','t',' ','S','a','n','s',' ','S','e','r','i','f',0 };
+static const WCHAR Tahoma[] = {'T','a','h','o','m','a',0};
+static const WCHAR MS_UI_Gothic[] = {'M','S',' ','U','I',' ','G','o','t','h','i','c',0};
+static const WCHAR SimSun[] = {'S','i','m','S','u','n',0};
+static const WCHAR Gulim[] = {'G','u','l','i','m',0};
+static const WCHAR PMingLiU[] = {'P','M','i','n','g','L','i','U',0};
+static const WCHAR Batang[] = {'B','a','t','a','n','g',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 CHINESE_BIG5W[] = {'C','H','I','N','E','S','E','_','B','I','G','5','\0'};
@@ -482,6 +492,11 @@ static BOOL use_default_fallback = FALSE;
static BOOL get_glyph_index_linked(GdiFont *font, UINT c, GdiFont **linked_font, FT_UInt *glyph);
+static const WCHAR system_link[] = {'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','L','i','n','k','\\',
+ 'S','y','s','t','e','m','L','i','n','k',0};
+
/****************************************
* Notes on .fon files
*
@@ -1622,10 +1637,6 @@ static void LoadReplaceList(void)
*/
static BOOL init_system_links(void)
{
- static const WCHAR system_link[] = {'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','L','i','n','k','\\',
- 'S','y','s','t','e','m','L','i','n','k',0};
HKEY hkey;
BOOL ret = FALSE;
DWORD type, max_val, max_data, val_len, data_len, index;
@@ -1633,7 +1644,6 @@ static BOOL init_system_links(void)
WCHAR *entry, *next;
SYSTEM_LINKS *font_link, *system_font_link;
CHILD_FONT *child_font;
- static const WCHAR Tahoma[] = {'T','a','h','o','m','a',0};
static const WCHAR tahoma_ttf[] = {'t','a','h','o','m','a','.','t','t','f',0};
static const WCHAR System[] = {'S','y','s','t','e','m',0};
FONTSIGNATURE fs;
@@ -2313,6 +2323,46 @@ static const struct nls_update_font_list
}
};
+static const WCHAR *font_links_list[] =
+{
+ Lucida_Sans_Unicode,
+ Microsoft_Sans_Serif,
+ Tahoma
+};
+
+static const struct font_links_defaults_list
+{
+ /* Keyed off substitution for "MS Shell Dlg" */
+ const WCHAR *shelldlg;
+ /* Maximum of four substitutes, plus terminating NULL pointer */
+ const WCHAR *substitutes[5];
+} font_links_defaults_list[] =
+{
+ /* Non East-Asian */
+ { Tahoma, /* FIXME unverified ordering */
+ { MS_UI_Gothic, SimSun, Gulim, PMingLiU, NULL }
+ },
+ /* Below lists are courtesy of
+ * http://blogs.msdn.com/michkap/archive/2005/06/18/430507.aspx
+ */
+ /* Japanese */
+ { MS_UI_Gothic,
+ { MS_UI_Gothic, PMingLiU, SimSun, Gulim, NULL }
+ },
+ /* Chinese Simplified */
+ { SimSun,
+ { SimSun, PMingLiU, MS_UI_Gothic, Batang, NULL }
+ },
+ /* Korean */
+ { Gulim,
+ { Gulim, PMingLiU, MS_UI_Gothic, SimSun, NULL }
+ },
+ /* Chinese Traditional */
+ { PMingLiU,
+ { PMingLiU, SimSun, MS_UI_Gothic, Batang, NULL }
+ }
+};
+
static inline BOOL is_dbcs_ansi_cp(UINT ansi_cp)
{
return ( ansi_cp == 932 /* CP932 for Japanese */
@@ -2459,6 +2509,133 @@ static void update_font_info(void)
}
if (!done)
FIXME("there is no font defaults for codepages %u,%u\n", ansi_cp, oem_cp);
+
+ /* Clear out system links */
+ RegDeleteKeyW(HKEY_LOCAL_MACHINE, system_link);
+}
+
+static void populate_system_links(HKEY hkey, const WCHAR *name, const WCHAR *const *values)
+{
+ const WCHAR *value;
+ int i;
+ FontSubst *psub;
+ Family *family;
+ Face *face;
+ const char *file;
+ WCHAR *fileW;
+ int fileLen;
+ WCHAR buff[MAX_PATH];
+ WCHAR *data;
+ int entryLen;
+
+ static const WCHAR comma[] = {',',0};
+
+ RegDeleteValueW(hkey, name);
+ if (values)
+ {
+ data = buff;
+ data[0] = '\0';
+ for (i = 0; values[i] != NULL; i++)
+ {
+ value = values[i];
+ if (!strcmpiW(name,value))
+ continue;
+ psub = get_font_subst(&font_subst_list, value, -1);
+ if(psub)
+ value = psub->to.name;
+ family = find_family_from_name(value);
+ if (!family)
+ continue;
+ file = NULL;
+ /* Use first extant filename for this Family */
+ LIST_FOR_EACH_ENTRY(face, &family->faces, Face, entry)
+ {
+ if (!face->file)
+ continue;
+ file = strrchr(face->file, '/');
+ if (!file)
+ file = face->file;
+ else
+ file++;
+ break;
+ }
+ if (!file)
+ continue;
+ fileLen = MultiByteToWideChar(CP_UNIXCP, 0, file, -1, NULL, 0);
+ fileW = HeapAlloc(GetProcessHeap(), 0, fileLen * sizeof(WCHAR));
+ MultiByteToWideChar(CP_UNIXCP, 0, file, -1, fileW, fileLen);
+ entryLen = strlenW(fileW) + 1 + strlenW(value) + 1;
+ if (sizeof(buff)-(data-buff) < entryLen + 1)
+ {
+ WARN("creating SystemLink for %s, ran out of buffer space\n", debugstr_w(name));
+ HeapFree(GetProcessHeap(), 0, fileW);
+ break;
+ }
+ strcpyW(data, fileW);
+ strcatW(data, comma);
+ strcatW(data, value);
+ data += entryLen;
+ TRACE("added SystemLink for %s to %s in %s\n", debugstr_w(name), debugstr_w(value),debugstr_w(fileW));
+ HeapFree(GetProcessHeap(), 0, fileW);
+ }
+ if (data != buff)
+ {
+ *data='\0';
+ data++;
+ RegSetValueExW(hkey, name, 0, REG_MULTI_SZ, (BYTE*)buff, (data-buff) * sizeof(WCHAR));
+ } else
+ TRACE("no SystemLink fonts found for %s\n", debugstr_w(name));
+ } else
+ TRACE("removed SystemLink for %s\n", debugstr_w(name));
+}
+
+static void update_system_links(void)
+{
+ HKEY hkey = 0;
+ UINT i, j;
+ BOOL done = FALSE;
+ DWORD disposition;
+ FontSubst *psub;
+
+ static const WCHAR MS_Shell_Dlg[] = {'M','S',' ','S','h','e','l','l',' ','D','l','g',0};
+
+ if (!RegCreateKeyExW(HKEY_LOCAL_MACHINE, system_link, 0, NULL, 0, KEY_ALL_ACCESS, NULL, &hkey, &disposition))
+ {
+ if (disposition == REG_OPENED_EXISTING_KEY)
+ {
+ TRACE("SystemLink key already exists, doing nothing\n");
+ RegCloseKey(hkey);
+ return;
+ }
+
+ psub = get_font_subst(&font_subst_list, MS_Shell_Dlg, -1);
+ if (!psub) {
+ WARN("could not find FontSubstitute for MS Shell Dlg\n");
+ RegCloseKey(hkey);
+ return;
+ }
+
+ for (i = 0; i < sizeof(font_links_defaults_list)/sizeof(font_links_defaults_list[0]); i++)
+ {
+ if (!strcmpiW(font_links_defaults_list[i].shelldlg, psub->to.name))
+ {
+ for (j = 0; j < sizeof(font_links_list)/sizeof(font_links_list[0]); j++)
+ populate_system_links(hkey, font_links_list[j], font_links_defaults_list[i].substitutes);
+
+ if (!strcmpiW(psub->to.name, font_links_defaults_list[i].substitutes[0]))
+ populate_system_links(hkey, psub->to.name, font_links_defaults_list[i].substitutes);
+ done = TRUE;
+ }
+ else if (strcmpiW(psub->to.name, font_links_defaults_list[i].substitutes[0]))
+ {
+ populate_system_links(hkey, font_links_defaults_list[i].substitutes[0], NULL);
+ }
+ }
+ RegCloseKey(hkey);
+ if (!done)
+ WARN("there is no SystemLink default list for MS Shell Dlg %s\n", debugstr_w(psub->to.name));
+ } else
+ WARN("failed to create SystemLink key\n");
}
@@ -2701,6 +2878,7 @@ BOOL WineEngInit(void)
LoadReplaceList();
update_reg_entries();
+ update_system_links();
init_system_links();
ReleaseMutex(font_mutex);
More information about the wine-cvs
mailing list