add linux system fonts to registry on startup

Mike Hearn mh at codeweavers.com
Thu Feb 26 19:17:04 CST 2004


Hi,

This is a first cut at adding the entries for system fonts to the
CurrentVersion\Fonts keys. By "system fonts" I mean fonts found via
fontconfig, loaded from c:\windows\fonts etc.

Basically this works by adding code to AddFontFileToList to add registry
entries. 

It's not perfect:
* Really the data should be volatile I guess. At the moment if you add a
font, run Wine, then remove it, we get a dead registry entry floating
around. Unfortunately Win32 is dumb and you can't set values as volatile,
only keys. CurrentVersion\Fonts is of course already used as another way
to configure fonts, so we can't just delete it and recreate it as volatile.

* We will end up setting the same value more than once in some cases. A
minor loss of efficiency but annoying nonetheless

Nonetheless, here it is. Comments on how to improve it are welcome.

This should help improve the stability of Internet Explorer, oddly enough.

ChangeLog:
Mike Hearn <mh at codeweavers.com>
Add system fonts to the registry

Index: dlls/gdi/freetype.c
===================================================================
RCS file: /home/wine/wine/dlls/gdi/freetype.c,v
retrieving revision 1.55
diff -u -r1.55 freetype.c
--- dlls/gdi/freetype.c 12 Feb 2004 20:05:47 -0000      1.55
+++ dlls/gdi/freetype.c 27 Feb 2004 01:08:01 -0000
@@ -271,6 +271,54 @@
        return (FT_Fixed)((long)f.value << 16 | (unsigned long)f.fract);
 }
  
+/* register the font in the registry. some DLLs like MLANG require this data */
+static void register_font(WCHAR *family, WCHAR *style, const char *file)
+{
+    HKEY fonts = 0;
+    DWORD ret;
+    WCHAR truetype[] = {' ','(','T','r','u','e','T','y','p','e',')','\0'};
+    WCHAR fontskey9x[] = {'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'};
+    WCHAR fontskeyNT[] = {'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'};
+    WCHAR spacer[] = {' ','\0'};
+    WCHAR *name = HeapAlloc(GetProcessHeap(), 0, (strlenW(family) + strlenW(spacer) + strlenW(style) + strlenW(spacer) + strlenW(truetype) + 1) * sizeof(WCHAR));
+    DWORD len = MultiByteToWideChar(CP_ACP, 0, file, -1, NULL, 0);
+    WCHAR *fileW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
+
+    TRACE("registering font %s %s = %s\n", debugstr_w(family), debugstr_w(style), file);
+
+    /* convert filename to unicode */
+    MultiByteToWideChar(CP_ACP, 0, file, -1, fileW, len);
+
+    /* paste together the name */
+    strcpyW(name, family);
+    strcatW(name, spacer);
+    strcatW(name, style);
+    strcatW(name, truetype);
+
+    ret = RegOpenKeyW(HKEY_LOCAL_MACHINE, fontskey9x, &fonts);
+    if (ret) goto error;
+
+    ret = RegSetValueExW(fonts, name, 0, REG_SZ, (LPBYTE)fileW, strlen(file)+1);
+    if (ret) goto error;
+
+    RegCloseKey(fonts);
+    fonts = 0;
+
+    ret = RegOpenKeyW(HKEY_LOCAL_MACHINE, fontskeyNT, &fonts);
+    if (ret) goto error;
+
+    ret = RegSetValueExW(fonts, name, 0, REG_SZ, (LPBYTE)fileW, strlen(file)+1);
+    if (ret) goto error;
+
+    goto end;
+error:
+    ERR("failed to set %s[ NT]\\%s to %s\n", debugstr_w(fontskey9x), debugstr_w(name), file);
+end:
+    if (fonts) RegCloseKey(fonts);
+    HeapFree(GetProcessHeap(), 0, fileW);
+    HeapFree(GetProcessHeap(), 0, name);
+}
+
 static BOOL AddFontFileToList(const char *file, char *fake_family)
 {
     FT_Face ft_face;
@@ -428,8 +476,12 @@
         if((*insertface)->fs.fsCsb[0] & ~(1L << 31))
             have_installed_roman_font = TRUE;
  
+       /* Now let's register in the font locations */
+       register_font(FamilyW, StyleW, file);
+
        num_faces = ft_face->num_faces;
        pFT_Done_Face(ft_face);
+
        TRACE("Added font %s %s\n", debugstr_w(family->FamilyName),
              debugstr_w(StyleW));
     } while(num_faces > ++face_index);





More information about the wine-patches mailing list