Perform automatic bitmap font configuration based on the current locale

Dmitry Timoshkov dmitry at baikal.ru
Mon Dec 13 09:39:58 CST 2004


Hello,

due to a GDI bug new values don't actually work, and that's another
thing I'm going to look at.

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

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-13 23:25:50.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,175 @@ 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_registry_key
+ *
+ * Create the HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\\Fonts
+ * registry subkey.
+ */
+inline static HKEY create_fonts_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_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 void update_font_info(LCID lcid)
+{
+    static const struct
+    {
+        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",
+        }
+    };
+    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};
+            static const WCHAR courierW[] = {'C','o','u','r','i','e','r',0};
+            static const WCHAR sserifW[] = {'M','S',' ','S','a','n','s',' ','S','e','r','i','f',0};
+            static const WCHAR serifW[] = {'M','S',' ','S','e','r','i','f',0};
+            static const WCHAR smallW[] = {'S','m','a','l','l',' ','F','o','n','t','s',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_registry_key();
+
+            strcpynAtoW(bufW, nls_update_font_list[i].courier, sizeof(bufW)/sizeof(WCHAR));
+            RtlInitUnicodeString(&nameW, courierW);
+            NtSetValueKey(hkey, &nameW, 0, REG_SZ, bufW, (strlenW(bufW) + 1) * sizeof(WCHAR) );
+
+            strcpynAtoW(bufW, nls_update_font_list[i].serif, sizeof(bufW)/sizeof(WCHAR));
+            RtlInitUnicodeString(&nameW, serifW);
+            NtSetValueKey(hkey, &nameW, 0, REG_SZ, bufW, (strlenW(bufW) + 1) * sizeof(WCHAR) );
+
+            strcpynAtoW(bufW, nls_update_font_list[i].small, sizeof(bufW)/sizeof(WCHAR));
+            RtlInitUnicodeString(&nameW, smallW);
+            NtSetValueKey(hkey, &nameW, 0, REG_SZ, bufW, (strlenW(bufW) + 1) * sizeof(WCHAR) );
+
+            strcpynAtoW(bufW, nls_update_font_list[i].sserif, sizeof(bufW)/sizeof(WCHAR));
+            RtlInitUnicodeString(&nameW, sserifW);
+            NtSetValueKey(hkey, &nameW, 0, REG_SZ, bufW, (strlenW(bufW) + 1) * sizeof(WCHAR) );
+
+            NtClose(hkey);
+            return;
+        }
+    }
+    FIXME("there is no font defaults for lcid %04lx/ansi_cp %u", lcid, ansi_cp);
+}
 
 /***********************************************************************
  *		LOCALE_InitRegistry
@@ -341,6 +492,8 @@ void LOCALE_InitRegistry(void)
     }
 
     NtClose( hkey );
+
+    update_font_info( lcid );
 }
 
 
@@ -431,9 +584,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 +2727,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;






More information about the wine-patches mailing list