Perform automatic bitmap font configuration based on the current locale. Take 2

Dmitry Timoshkov dmitry at baikal.ru
Tue Dec 14 08:09:12 CST 2004


Hello,

this version finally works as expected after copying bitmap fonts to
Windows\Fonts (a possible wineprefixcreate improvement) and upgrading
system version of FreeType.

Now Wine is able to display localized menus and dialogs after the default
install.

Changelog:
    Dmitry Timoshkov <dmitry at codeweavers.com>
    Perform automatic bitmap font configuration based on the current locale.

diff -up cvs/hq/wine/dlls/gdi/freetype.c wine/dlls/gdi/freetype.c
--- cvs/hq/wine/dlls/gdi/freetype.c	2004-10-20 17:06:30.000000000 +0900
+++ wine/dlls/gdi/freetype.c	2004-12-14 20:50:03.000000000 +0800
@@ -428,12 +428,14 @@ static BOOL AddFontFileToList(const char
 	}
 
 	if(!FT_IS_SFNT(ft_face) && (FT_IS_SCALABLE(ft_face) || !(flags & ADDFONT_FORCE_BITMAP))) { /* for now we'll accept TT/OT or bitmap fonts*/
+	    WARN("Ignoring font %s\n", debugstr_a(file));
 	    pFT_Done_Face(ft_face);
 	    return FALSE;
 	}
 
         /* There are too many bugs in FreeType < 2.1.9 for bitmap font support */
         if(!FT_IS_SCALABLE(ft_face) && FT_SimpleVersion < ((2 << 16) | (1 << 8) | (9 << 0))) {
+	    WARN("FreeType version < 2.1.9, skipping bitmap font %s\n", debugstr_a(file));
 	    pFT_Done_Face(ft_face);
 	    return FALSE;
 	}
@@ -1653,11 +1655,16 @@ GdiFont WineEngCreateFontInstance(DC *dc
     }
 
     TRACE("not in cache\n");
-    if(list_empty(&font_list) || !have_installed_roman_font) /* No fonts installed */
+    if(list_empty(&font_list)) /* No fonts installed */
     {
 	TRACE("No fonts installed\n");
 	return NULL;
     }
+    if(!have_installed_roman_font)
+    {
+	TRACE("No roman font installed\n");
+	return NULL;
+    }
 
     ret = alloc_font();
 
diff -up cvs/hq/wine/dlls/kernel/locale.c wine/dlls/kernel/locale.c
--- cvs/hq/wine/dlls/kernel/locale.c	2004-11-22 17:52:19.000000000 +0800
+++ wine/dlls/kernel/locale.c	2004-12-14 21:21:45.000000000 +0800
@@ -5,6 +5,7 @@
  * Copyright 1998 David Lee Lambert
  * Copyright 2000 Julio César Gázquez
  * Copyright 2002 Alexandre Julliard for CodeWeavers
+ * Copyright 2003, 2004 Dmitry Timoshkov
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -226,25 +227,204 @@ inline static HKEY create_registry_key(v
 {
     static const WCHAR intlW[] = {'C','o','n','t','r','o','l',' ','P','a','n','e','l','\\',
                                   'I','n','t','e','r','n','a','t','i','o','n','a','l',0};
-    OBJECT_ATTRIBUTES attr;
-    UNICODE_STRING nameW;
     HKEY hkey;
 
     if (RtlOpenCurrentUser( KEY_ALL_ACCESS, &hkey ) != STATUS_SUCCESS) return 0;
 
-    attr.Length = sizeof(attr);
-    attr.RootDirectory = hkey;
-    attr.ObjectName = &nameW;
-    attr.Attributes = 0;
-    attr.SecurityDescriptor = NULL;
-    attr.SecurityQualityOfService = NULL;
-    RtlInitUnicodeString( &nameW, intlW );
+    return NLS_RegOpenSubKey( hkey, intlW );
+}
 
-    if (NtCreateKey( &hkey, KEY_ALL_ACCESS, &attr, 0, NULL, 0, NULL ) != STATUS_SUCCESS) hkey = 0;
-    NtClose( attr.RootDirectory );
-    return hkey;
+/***********************************************************************
+ *		create_fonts_NT_registry_key
+ *
+ * Create the HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\\Fonts
+ * registry subkey.
+ */
+inline static HKEY create_fonts_NT_registry_key(void)
+{
+    static const WCHAR fontsW[] = {
+        'M','a','c','h','i','n','e','\\','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};
+
+    return NLS_RegOpenKey( 0, fontsW );
+}
+
+/***********************************************************************
+ *		create_fonts_9x_registry_key
+ *
+ * Create the HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\\Fonts
+ * registry subkey.
+ */
+inline static HKEY create_fonts_9x_registry_key(void)
+{
+    static const WCHAR fontsW[] = {
+        'M','a','c','h','i','n','e','\\','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};
+
+    return NLS_RegOpenKey( 0, fontsW );
+}
+
+/***********************************************************************
+ *		create_config_fonts_registry_key
+ *
+ * Create the HKEY_CURRENT_CONFIG\Software\Fonts registry key.
+ */
+inline static HKEY create_config_fonts_registry_key(void)
+{
+    static const WCHAR fontsW[] = {
+        'M','a','c','h','i','n','e','\\',
+        'S','y','s','t','e','m','\\',
+        'C','u','r','r','e','n','t','C','o','n','t','r','o','l','S','e','t','\\',
+        'H','a','r','d','w','a','r','e',' ','P','r','o','f','i','l','e','s','\\',
+        'C','u','r','r','e','n','t','\\',
+        'S','o','f','t','w','a','r','e','\\',
+        'F','o','n','t','s',0 };
+
+    return NLS_RegOpenKey( 0, fontsW );
+}
+
+static const struct nls_update_font_list
+{
+    UINT ansi_cp;
+    const char *oem, *fixed, *system;
+    const char *courier, *serif, *small, *sserif;
+} nls_update_font_list[] =
+{
+    /* Arabic */
+    { 1256, "wine_vgaoem.fon", "wine_vgaf1256.fon", "wine_vgas1256.fon",
+      "wine_coue1256.fon", "wine_sere1256.fon", "wine_smae1256.fon", "wine_ssee1256.fon",
+    },
+    /* Baltic */
+    { 1257, "wine_vga775.fon", "wine_vgaf1257.fon", "wine_vgas1257.fon",
+      "wine_coue1257.fon", "wine_sere1257.fon", "wine_smae1257.fon", "wine_ssee1257.fon",
+    },
+    /* Chinese Simplified */
+    { 936, "wine_vga936.fon", "wine_svgafix.fon", "wine_svgasys.fon",
+      "wine_coure.fon", "wine_serife.fon", "wine_smalle.fon", "wine_sserife.fon",
+    },
+    /* Chinese Traditional */
+    { 950, "wine_vga950.fon", "wine_cvgafix.fon", "wine_cvgasys.fon",
+      "wine_coure.fon", "wine_serife.fon", "wine_smalle.fon", "wine_sserife.fon",
+    },
+    /* Central European */
+    { 1250, "wine_vga852.fon", "wine_vgafixe.fon", "wine_vgasyse.fon",
+      "wine_couree.fon", "wine_serifee.fon", "wine_smallee.fon", "wine_sserifee.fon",
+    },
+    /* Cyrillic */
+    { 1251, "wine_vga866.fon", "wine_vgafixr.fon", "wine_vgasysr.fon",
+      "wine_courer.fon", "wine_serifer.fon", "wine_smaller.fon", "wine_sserifer.fon",
+    },
+    /* Greek */
+    { 1253, "wine_vga869.fon", "wine_vgafixg.fon", "wine_vgasysg.fon",
+      "wine_coureg.fon", "wine_serifeg.fon", "wine_smalleg.fon", "wine_sserifeg.fon",
+    },
+    /* Hebrew */
+    { 1255, "wine_vgaoem.fon", "wine_vgaf1255.fon", "wine_vgas1255.fon",
+      "wine_coue1255.fon", "wine_sere1255.fon", "wine_smae1255.fon", "wine_ssee1255.fon",
+    },
+    /* "Japanese */
+    { 932, "wine_vga932.fon", "wine_jvgafix.fon", "wine_jvgasys.fon",
+      "wine_coure.fon", "wine_serife.fon", "wine_jsmalle.fon", "wine_sserife.fon",
+    },
+    /* Korean */
+    { 949, "wine_vga949.fon", "wine_hvgafix.fon", "wine_hvgasys.fon",
+      "wine_coure.fon", "wine_serife.fon", "wine_smalle.fon", "wine_sserife.fon",
+    },
+    /* Thai */
+    { 874, "wine_vga850.fon", "wine_vgaf874.fon", "wine_vgas874.fon",
+      "wine_coure.fon", "wine_serife.fon", "wine_smalle.fon", "wine_ssee874.fon",
+    },
+    /* Turkish */
+    { 1254, "wine_vga857.fon", "wine_vgafixt.fon", "wine_vgasyst.fon",
+      "wine_couret.fon", "wine_serifet.fon", "wine_smallet.fon", "wine_sserifet.fon",
+    },
+    /* Vietnamese */
+    { 1258, "wine_vga850.fon", "wine_vgafix.fon", "wine_vgasys.fon",
+      "wine_coure.fon", "wine_serife.fon", "wine_smalle.fon", "wine_sserife.fon",
+    },
+    /* Western European */
+    { 1252, "wine_vgaoem.fon", "wine_vgafix.fon", "wine_vgasys.fon",
+      "wine_coure.fon", "wine_serife.fon", "wine_smalle.fon", "wine_sserife.fon",
+    }
+};
+
+static void add_font_list(HKEY hkey, const struct nls_update_font_list *fl)
+{
+    static const WCHAR courierW[] = {'W','i','n','e',' ','C','o','u','r','i','e','r',0};
+    static const WCHAR sserifW[] = {'W','i','n','e',' ','S','a','n','s',' ','S','e','r','i','f',0};
+    static const WCHAR serifW[] = {'W','i','n','e',' ','S','e','r','i','f',0};
+    static const WCHAR smallW[] = {'W','i','n','e',' ','S','m','a','l','l',' ','F','o','n','t','s',0};
+    UNICODE_STRING nameW;
+    WCHAR bufW[32];
+
+    strcpynAtoW(bufW, fl->courier, sizeof(bufW)/sizeof(WCHAR));
+    RtlInitUnicodeString(&nameW, courierW);
+    NtSetValueKey(hkey, &nameW, 0, REG_SZ, bufW, (strlenW(bufW) + 1) * sizeof(WCHAR) );
+
+    strcpynAtoW(bufW, fl->serif, sizeof(bufW)/sizeof(WCHAR));
+    RtlInitUnicodeString(&nameW, serifW);
+    NtSetValueKey(hkey, &nameW, 0, REG_SZ, bufW, (strlenW(bufW) + 1) * sizeof(WCHAR) );
+
+    strcpynAtoW(bufW, fl->small, sizeof(bufW)/sizeof(WCHAR));
+    RtlInitUnicodeString(&nameW, smallW);
+    NtSetValueKey(hkey, &nameW, 0, REG_SZ, bufW, (strlenW(bufW) + 1) * sizeof(WCHAR) );
+
+    strcpynAtoW(bufW, fl->sserif, sizeof(bufW)/sizeof(WCHAR));
+    RtlInitUnicodeString(&nameW, sserifW);
+    NtSetValueKey(hkey, &nameW, 0, REG_SZ, bufW, (strlenW(bufW) + 1) * sizeof(WCHAR) );
 }
 
+static const void update_font_info(LCID lcid)
+{
+    UINT i, ansi_cp = 0;
+
+    GetLocaleInfoW(lcid, LOCALE_IDEFAULTANSICODEPAGE|LOCALE_RETURN_NUMBER|LOCALE_NOUSEROVERRIDE,
+                   (WCHAR *)&ansi_cp, sizeof(ansi_cp)/sizeof(WCHAR));
+
+    for (i = 0; i < sizeof(nls_update_font_list)/sizeof(nls_update_font_list[0]); i++)
+    {
+        if (nls_update_font_list[i].ansi_cp == ansi_cp)
+        {
+            static const WCHAR oemW[] = {'O','E','M','F','O','N','T','.','F','O','N',0};
+            static const WCHAR fixedW[] = {'F','I','X','E','D','F','O','N','.','F','O','N',0};
+            static const WCHAR systemW[] = {'F','O','N','T','S','.','F','O','N',0};
+            UNICODE_STRING nameW;
+            WCHAR bufW[32];
+            HKEY hkey;
+
+            hkey = create_config_fonts_registry_key();
+
+            strcpynAtoW(bufW, nls_update_font_list[i].oem, sizeof(bufW)/sizeof(WCHAR));
+            RtlInitUnicodeString(&nameW, oemW);
+            NtSetValueKey(hkey, &nameW, 0, REG_SZ, bufW, (strlenW(bufW) + 1) * sizeof(WCHAR) );
+
+            strcpynAtoW(bufW, nls_update_font_list[i].fixed, sizeof(bufW)/sizeof(WCHAR));
+            RtlInitUnicodeString(&nameW, fixedW);
+            NtSetValueKey(hkey, &nameW, 0, REG_SZ, bufW, (strlenW(bufW) + 1) * sizeof(WCHAR) );
+
+            strcpynAtoW(bufW, nls_update_font_list[i].system, sizeof(bufW)/sizeof(WCHAR));
+            RtlInitUnicodeString(&nameW, systemW);
+            NtSetValueKey(hkey, &nameW, 0, REG_SZ, bufW, (strlenW(bufW) + 1) * sizeof(WCHAR) );
+
+            NtClose(hkey);
+
+            hkey = create_fonts_NT_registry_key();
+            add_font_list(hkey, &nls_update_font_list[i]);
+            NtClose(hkey);
+
+            hkey = create_fonts_9x_registry_key();
+            add_font_list(hkey, &nls_update_font_list[i]);
+            NtClose(hkey);
+
+            return;
+        }
+    }
+    FIXME("there is no font defaults for lcid %04lx/ansi_cp %u", lcid, ansi_cp);
+}
 
 /***********************************************************************
  *		LOCALE_InitRegistry
@@ -341,6 +521,8 @@ void LOCALE_InitRegistry(void)
     }
 
     NtClose( hkey );
+
+    update_font_info( lcid );
 }
 
 
@@ -431,9 +613,9 @@ static LANGID get_language_id(LPCSTR Lan
     }
 
     l_data.n_found = 0;
-    strcpynAtoW(l_data.lang, Lang, sizeof(l_data.lang));
+    strcpynAtoW(l_data.lang, Lang, sizeof(l_data.lang)/sizeof(WCHAR));
 
-    if (Country) strcpynAtoW(l_data.country, Country, sizeof(l_data.country));
+    if (Country) strcpynAtoW(l_data.country, Country, sizeof(l_data.country)/sizeof(WCHAR));
     else l_data.country[0] = 0;
 
     EnumResourceLanguagesW(kernel32_handle, (LPCWSTR)RT_STRING, (LPCWSTR)LOCALE_ILANGUAGE,
@@ -2574,7 +2756,7 @@ static HKEY NLS_RegOpenKey(HKEY hRootKey
     RtlInitUnicodeString( &keyName, szKeyName );
     InitializeObjectAttributes(&attr, &keyName, 0, hRootKey, NULL);
 
-    if (NtOpenKey( &hkey, KEY_ALL_ACCESS, &attr ) != STATUS_SUCCESS)
+    if (NtCreateKey( &hkey, KEY_ALL_ACCESS, &attr, 0, NULL, 0, NULL ) != STATUS_SUCCESS)
         hkey = 0;
 
     return hkey;
diff -up cvs/hq/wine/tools/wine.inf wine/tools/wine.inf
--- cvs/hq/wine/tools/wine.inf	2004-11-29 08:58:41.000000000 +0800
+++ wine/tools/wine.inf	2004-12-14 21:41:27.000000000 +0800
@@ -36,6 +36,7 @@ AddReg=\
     DirectX,\
     Environment,\
     Fonts,\
+    FontReplacements,\
     MCI,\
     Misc,\
     Nls,\
@@ -161,6 +162,14 @@ HKLM,%FontSubStr%,"Times New Roman TUR,1
 HKLM,%FontSubStr%,"Tms Rmn",,"Times New Roman"
 HKLM,System\CurrentControlSet\Hardware Profiles\Current\Software\Fonts,"LogPixels",0x10001,00000060
 
+[FontReplacements]
+HKLM,Software\Wine\Wine\FontReplacements,"Courier",,"Wine Courier"
+HKLM,Software\Wine\Wine\FontReplacements,"Marlett",,"Wine Marlett"
+HKLM,Software\Wine\Wine\FontReplacements,"MS Sans Serif",,"Wine Sans Serif"
+HKLM,Software\Wine\Wine\FontReplacements,"MS Serif",,"Wine Serif"
+HKLM,Software\Wine\Wine\FontReplacements,"Small Fonts",,"Wine Small Fonts"
+HKLM,Software\Wine\Wine\FontReplacements,"System",,"Wine System"
+
 [MCI]
 HKLM,%Mci32Str%,"AVIVideo",,"mciavi.drv"
 HKLM,%Mci32Str%,"CDAudio",,"mcicda.drv"






More information about the wine-patches mailing list