Perform automatic bitmap font configuration. Take 4

Dmitry Timoshkov dmitry at baikal.ru
Tue Sep 13 02:45:30 CDT 2005


Hello,

Alexandre asked me to move locale font config to GDI and merge it with
other font stuff.

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	2005-09-13 15:09:24.000000000 +0900
+++ wine/dlls/gdi/freetype.c	2005-09-13 16:23:21.000000000 +0900
@@ -450,12 +450,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;
 	}
@@ -1187,6 +1189,7 @@ static void update_reg_entries(void)
     externalkey = 0;
     RegDeleteKeyW(HKEY_CURRENT_USER, external_fonts_reg_key);
 
+    /* @@ Wine registry key: HKCU\Software\Wine\Fonts\ExternalFonts */
     if(RegCreateKeyExW(HKEY_CURRENT_USER, external_fonts_reg_key,
                        0, NULL, 0, KEY_ALL_ACCESS, NULL, &externalkey, NULL) != ERROR_SUCCESS) {
         ERR("Can't create external font reg key\n");
@@ -1267,6 +1270,162 @@ BOOL WineEngRemoveFontResourceEx(LPCWSTR
     return TRUE;
 }
 
+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, "vgaoem.fon", "vgaf1256.fon", "vgas1256.fon",
+      "coue1256.fon", "sere1256.fon", "smae1256.fon", "ssee1256.fon",
+    },
+    /* Baltic */
+    { 1257, "vga775.fon", "vgaf1257.fon", "vgas1257.fon",
+      "coue1257.fon", "sere1257.fon", "smae1257.fon", "ssee1257.fon",
+    },
+    /* Chinese Simplified */
+    { 936, "vga936.fon", "svgafix.fon", "svgasys.fon",
+      "coure.fon", "serife.fon", "smalle.fon", "sserife.fon",
+    },
+    /* Chinese Traditional */
+    { 950, "vga950.fon", "cvgafix.fon", "cvgasys.fon",
+      "coure.fon", "serife.fon", "smalle.fon", "sserife.fon",
+    },
+    /* Central European */
+    { 1250, "vga852.fon", "vgafixe.fon", "vgasyse.fon",
+      "couree.fon", "serifee.fon", "smallee.fon", "sserifee.fon",
+    },
+    /* Cyrillic */
+    { 1251, "vga866.fon", "vgafixr.fon", "vgasysr.fon",
+      "courer.fon", "serifer.fon", "smaller.fon", "sserifer.fon",
+    },
+    /* Greek */
+    { 1253, "vga869.fon", "vgafixg.fon", "vgasysg.fon",
+      "coureg.fon", "serifeg.fon", "smalleg.fon", "sserifeg.fon",
+    },
+    /* Hebrew */
+    { 1255, "vgaoem.fon", "vgaf1255.fon", "vgas1255.fon",
+      "coue1255.fon", "sere1255.fon", "smae1255.fon", "ssee1255.fon",
+    },
+    /* "Japanese */
+    { 932, "vga932.fon", "jvgafix.fon", "jvgasys.fon",
+      "coure.fon", "serife.fon", "jsmalle.fon", "sserife.fon",
+    },
+    /* Korean */
+    { 949, "vga949.fon", "hvgafix.fon", "hvgasys.fon",
+      "coure.fon", "serife.fon", "smalle.fon", "sserife.fon",
+    },
+    /* Thai */
+    { 874, "vga850.fon", "vgaf874.fon", "vgas874.fon",
+      "coure.fon", "serife.fon", "smalle.fon", "ssee874.fon",
+    },
+    /* Turkish */
+    { 1254, "vga857.fon", "vgafixt.fon", "vgasyst.fon",
+      "couret.fon", "serifet.fon", "smallet.fon", "sserifet.fon",
+    },
+    /* Vietnamese */
+    { 1258, "vga850.fon", "vgafix.fon", "vgasys.fon",
+      "coure.fon", "serife.fon", "smalle.fon", "sserife.fon",
+    },
+    /* Western European */
+    { 1252, "vgaoem.fon", "vgafix.fon", "vgasys.fon",
+      "coure.fon", "serife.fon", "smalle.fon", "sserife.fon",
+    }
+};
+
+inline static HKEY create_fonts_NT_registry_key(void)
+{
+    HKEY hkey = 0;
+
+    RegCreateKeyExW(HKEY_LOCAL_MACHINE, winnt_font_reg_key, 0, NULL,
+                    0, KEY_ALL_ACCESS, NULL, &hkey, NULL);
+    return hkey;
+}
+
+inline static HKEY create_fonts_9x_registry_key(void)
+{
+    HKEY hkey = 0;
+
+    RegCreateKeyExW(HKEY_LOCAL_MACHINE, win9x_font_reg_key, 0, NULL,
+                    0, KEY_ALL_ACCESS, NULL, &hkey, NULL);
+    return hkey;
+}
+
+inline static HKEY create_config_fonts_registry_key(void)
+{
+    HKEY hkey = 0;
+
+    RegCreateKeyExW(HKEY_CURRENT_CONFIG, system_fonts_reg_key, 0, NULL,
+                    0, KEY_ALL_ACCESS, NULL, &hkey, NULL);
+    return hkey;
+}
+
+static void add_font_list(HKEY hkey, const struct nls_update_font_list *fl)
+{
+    RegSetValueExA(hkey, "Courier", 0, REG_SZ, fl->courier, strlen(fl->courier)+1);
+    RegSetValueExA(hkey, "MS Serif", 0, REG_SZ, fl->serif, strlen(fl->serif)+1);
+    RegSetValueExA(hkey, "MS Sans Serif", 0, REG_SZ, fl->sserif, strlen(fl->sserif)+1);
+    RegSetValueExA(hkey, "Small Fonts", 0, REG_SZ, fl->small, strlen(fl->small)+1);
+}
+
+static const void update_font_info(void)
+{
+    BYTE buf[80];
+    DWORD len, type;
+    HKEY hkey = 0;
+    UINT i, ansi_cp = 0;
+    LCID lcid = GetUserDefaultLCID();
+
+    if (RegOpenKeyA(HKEY_CURRENT_USER, "Control Panel\\International", &hkey) != ERROR_SUCCESS)
+        return;
+
+    len = sizeof(buf);
+    if (RegQueryValueExA(hkey, "Locale", 0, &type, buf, &len) == ERROR_SUCCESS && type == REG_SZ)
+    {
+        if (strtoul(buf, NULL, 16 ) == lcid)  /* already set correctly */
+        {
+            RegCloseKey(hkey);
+            return;
+        }
+        TRACE("updating registry, locale changed %s -> %08lx\n", debugstr_a(buf), lcid);
+    }
+    else TRACE("updating registry, locale changed none -> %08lx\n", lcid);
+
+    sprintf(buf, "%08lx", lcid);
+    RegSetValueExA(hkey, "Locale", 0, REG_SZ, buf, strlen(buf)+1);
+    RegCloseKey(hkey);
+
+    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)
+        {
+            HKEY hkey;
+
+            hkey = create_config_fonts_registry_key();
+            RegSetValueExA(hkey, "OEMFONT.FON", 0, REG_SZ, nls_update_font_list[i].oem, strlen(nls_update_font_list[i].oem)+1);
+            RegSetValueExA(hkey, "FIXED.FON", 0, REG_SZ, nls_update_font_list[i].fixed, strlen(nls_update_font_list[i].fixed)+1);
+            RegSetValueExA(hkey, "FONTS.FON", 0, REG_SZ, nls_update_font_list[i].system, strlen(nls_update_font_list[i].system)+1);
+            RegCloseKey(hkey);
+
+            hkey = create_fonts_NT_registry_key();
+            add_font_list(hkey, &nls_update_font_list[i]);
+            RegCloseKey(hkey);
+
+            hkey = create_fonts_9x_registry_key();
+            add_font_list(hkey, &nls_update_font_list[i]);
+            RegCloseKey(hkey);
+
+            return;
+        }
+    }
+    FIXME("there is no font defaults for lcid %04lx/ansi_cp %u", lcid, ansi_cp);
+}
+
 /*************************************************************
  *    WineEngInit
  *
@@ -1285,6 +1444,9 @@ BOOL WineEngInit(void)
 
     TRACE("\n");
 
+    /* update locale dependent font info in registry */
+    update_font_info();
+
     ft_handle = wine_dlopen(SONAME_LIBFREETYPE, RTLD_NOW, NULL, 0);
     if(!ft_handle) {
         WINE_MESSAGE(
@@ -1922,11 +2084,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/gdi/gdi16.c wine/dlls/gdi/gdi16.c
--- cvs/hq/wine/dlls/gdi/gdi16.c	2005-09-07 20:08:44.000000000 +0900
+++ wine/dlls/gdi/gdi16.c	2005-09-13 15:48:22.000000000 +0900
@@ -2854,3 +2854,12 @@ BOOL16 WINAPI SetLayout16( HDC16 hdc, DW
 {
     return SetLayout( HDC_32(hdc), layout );
 }
+
+
+/***********************************************************************
+ *           Copy   (GDI.250)
+ */
+void WINAPI Copy16( LPVOID src, LPVOID dst, WORD size )
+{
+    memcpy( dst, src, size );
+}
diff -up cvs/hq/wine/dlls/gdi/gdi_main.c wine/dlls/gdi/gdi_main.c
--- cvs/hq/wine/dlls/gdi/gdi_main.c	2005-06-03 13:43:25.000000000 +0900
+++ wine/dlls/gdi/gdi_main.c	2005-09-13 16:31:07.000000000 +0900
@@ -19,11 +19,8 @@
  */
 
 #include <stdarg.h>
-#include <string.h>
 #include "windef.h"
 #include "winbase.h"
-#include "wingdi.h"
-#include "wine/winbase16.h"
 #include "gdi.h"
 #include "gdi_private.h"
 
@@ -37,12 +34,3 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, 
     LoadLibrary16( "gdi.exe" );
     return GDI_Init();
 }
-
-
-/***********************************************************************
- *           Copy   (GDI.250)
- */
-void WINAPI Copy16( LPVOID src, LPVOID dst, WORD size )
-{
-    memcpy( dst, src, size );
-}
diff -up cvs/hq/wine/dlls/kernel/locale.c wine/dlls/kernel/locale.c
--- cvs/hq/wine/dlls/kernel/locale.c	2005-09-13 15:09:25.000000000 +0900
+++ wine/dlls/kernel/locale.c	2005-09-13 16:20:39.000000000 +0900
@@ -288,7 +288,6 @@ void LOCALE_InitRegistry(void)
     };
     static const WCHAR LocaleW[] = {'L','o','c','a','l','e',0};
     UNICODE_STRING nameW;
-    char buffer[20];
     WCHAR bufferW[80];
     DWORD count, i;
     HANDLE hkey;
@@ -313,10 +312,7 @@ void LOCALE_InitRegistry(void)
     }
     else TRACE( "updating registry, locale changed none -> %08lx\n", lcid );
 
-    sprintf( buffer, "%08lx", lcid );
-    /* Note: '9' constant below is strlen(buffer) + 1 */
-    RtlMultiByteToUnicodeN( bufferW, sizeof(bufferW), NULL, buffer, 9 );
-    NtSetValueKey( hkey, &nameW, 0, REG_SZ, bufferW, 9 * sizeof(WCHAR) );
+    /* GDI32 detects locale change as well, it will update the registry */
     NtClose( hkey );
 
     for (i = 0; i < sizeof(updateValues)/sizeof(updateValues[0]); i++)






More information about the wine-patches mailing list