Add support for bitmap fonts.

diff --git a/configure b/configure
index 9c348ea..2369042 100755
--- a/configure
+++ b/configure
@@ -10541,6 +10541,7 @@
 
 
 
+
 for ac_header in ft2build.h \
                          freetype/freetype.h \
                          freetype/ftglyph.h \
@@ -10549,6 +10550,7 @@
                          freetype/ftsnames.h \
                          freetype/ttnameid.h \
                          freetype/ftoutln.h \
+                         freetype/ftwinfnt.h \
                          freetype/internal/sfnt.h
 do
 as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
diff --git a/configure.ac b/configure.ac
index 320543d..9aa65be 100644
--- a/configure.ac
+++ b/configure.ac
@@ -461,6 +461,7 @@
                          freetype/ftsnames.h \
                          freetype/ttnameid.h \
                          freetype/ftoutln.h \
+                         freetype/ftwinfnt.h \
                          freetype/internal/sfnt.h,,,
                          [#if HAVE_FT2BUILD_H
                           #include <ft2build.h>
diff --git a/dlls/gdi/freetype.c b/dlls/gdi/freetype.c
index b51a95a..1a56627 100644
--- a/dlls/gdi/freetype.c
+++ b/dlls/gdi/freetype.c
@@ -76,6 +76,9 @@
 #ifdef HAVE_FREETYPE_FTTRIGON_H
 #include <freetype/fttrigon.h>
 #endif
+#ifdef HAVE_FREETYPE_FTWINFNT_H
+#include <freetype/ftwinfnt.h>
+#endif
 
 #ifndef SONAME_LIBFREETYPE
 #define SONAME_LIBFREETYPE "libfreetype.so"
@@ -89,6 +92,7 @@
     FT_Int patch;
 } FT_Version_t;
 static FT_Version_t FT_Version;
+static DWORD FT_SimpleVersion;
 
 static void *ft_handle = NULL;
 
@@ -111,6 +115,9 @@
 static void (*pFT_Library_Version)(FT_Library,FT_Int*,FT_Int*,FT_Int*);
 static FT_Error (*pFT_Load_Sfnt_Table)(FT_Face,FT_ULong,FT_Long,FT_Byte*,FT_ULong*);
 static FT_ULong (*pFT_Get_First_Char)(FT_Face,FT_UInt*);
+#ifdef HAVE_FREETYPE_FTWINFNT_H
+MAKE_FUNCPTR(FT_Get_WinFNT_Header);
+#endif
 
 #ifdef HAVE_FONTCONFIG_FONTCONFIG_H
 #include <fontconfig/fontconfig.h>
@@ -134,6 +141,16 @@
 
 #define GET_BE_WORD(ptr) MAKEWORD( ((BYTE *)(ptr))[1], ((BYTE *)(ptr))[0] )
 
+/* This is bascially a copy of FT_Bitmap_Size with an extra element added */
+typedef struct {
+    FT_Short height;
+    FT_Short width;
+    FT_Pos  size;
+    FT_Pos x_ppem;
+    FT_Pos y_ppem;
+    FT_Short internal_leading;
+} Bitmap_Size;
+
 typedef struct tagFace {
     WCHAR *StyleName;
     char *file;
@@ -142,6 +159,8 @@
     BOOL Bold;
     FONTSIGNATURE fs;
     FT_Fixed font_version;
+    BOOL scalable;
+    Bitmap_Size size;     /* set if face is a bitmap */
     BOOL external; /* TRUE if we should manually add this font to the registry */
     struct tagFace *next;
     struct tagFamily *family;
@@ -198,6 +217,7 @@
 static const WCHAR HelvW[] = {'H','e','l','v','\0'};
 static const WCHAR RegularW[] = {'R','e','g','u','l','a','r','\0'};
 
+static const WCHAR fontsW[] = {'\\','F','o','n','t','s','\0'};
 static const WCHAR win9x_font_reg_key[] = {'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','\\',
@@ -208,6 +228,18 @@
                                            'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
                                            'F','o','n','t','s','\0'};
 
+static const WCHAR system_fonts_reg_key[] = {'S','o','f','t','w','a','r','e','\\','F','o','n','t','s','\0'};
+static const WCHAR FixedSys_Value[] = {'F','I','X','E','D','F','O','N','.','F','O','N','\0'};
+static const WCHAR System_Value[] = {'F','O','N','T','S','.','F','O','N','\0'};
+static const WCHAR OEMFont_Value[] = {'O','E','M','F','O','N','T','.','F','O','N','\0'};
+
+static const WCHAR *SystemFontValues[4] = {
+    FixedSys_Value,
+    System_Value,
+    OEMFont_Value,
+    NULL
+};
+
 static const WCHAR external_fonts_reg_key[] = {'S','o','f','t','w','a','r','e','\\','W','i','n','e','\\','W','i','n','e','\\',
                                                'F','o','n','t','s','\\','E','x','t','e','r','n','a','l',' ','F','o','n','t','s','\0'};
 
@@ -228,6 +260,7 @@
 static const WCHAR TurkishW[] = {'T','u','r','k','i','s','h','\0'};
 static const WCHAR VietnameseW[] = {'V','i','e','t','n','a','m','e','s','e','\0'};
 static const WCHAR WesternW[] = {'W','e','s','t','e','r','n','\0'};
+static const WCHAR OEM_DOSW[] = {'O','E','M','/','D','O','S','\0'};
 
 static const WCHAR *ElfScriptsW[32] = { /* these are in the order of the fsCsb[0] bits */
     WesternW, /*00*/
@@ -267,6 +300,38 @@
 
 static const WCHAR font_mutex_nameW[] = {'_','_','W','I','N','E','_','F','O','N','T','_','M','U','T','E','X','_','_','\0'};
 
+
+/****************************************
+ *   Notes on .fon files
+ *
+ * The fonts System, FixedSys and Terminal are special.  There are typically multiple
+ * versions installed for different resolutions and codepages.  Windows stores which one to use
+ * in HKEY_CURRENT_CONFIG\\Software\\Fonts.
+ *    Key            Meaning
+ *  FIXEDFON.FON    FixedSys
+ *  FONTS.FON       System
+ *  OEMFONT.FON     Termial
+ *  LogPixels       Current dpi set by the display control panel applet
+ *                  (HKLM\\Software\\Microsft\\Windows NT\\CurrentVersion\\FontDPI
+ *                  also has a LogPixels value that appears to mirror this)
+ *
+ * On my system these values have data: vgafix.fon, vgasys.fon, vga850.fon and 96 respectively
+ * (vgaoem.fon would be your oemfont.fon if you have a US setup).
+ * If the resolution is changed to be >= 109dpi then the fonts goto 8514fix, 8514sys and 8514oem
+ * (not sure what's happening to the oem codepage here). 109 is nicely halfway between 96 and 120dpi,
+ * so that makes sense.
+ *
+ * Additionally Windows also loads the fonts listed in the [386enh] section of system.ini (this doesn't appear
+ * to be mapped into the registry on Windows 2000 at least).
+ * I have
+ * woafont=app850.fon
+ * ega80woa.fon=ega80850.fon
+ * ega40woa.fon=ega40850.fon
+ * cga80woa.fon=cga80850.fon
+ * cga40woa.fon=cga40850.fon
+ */
+
+
 static inline BOOL is_win9x(void)
 {
     return GetVersion() & 0x80000000;
@@ -292,19 +357,23 @@
 	return (FT_Fixed)((long)f.value << 16 | (unsigned long)f.fract);
 }
 
-static BOOL AddFontFileToList(const char *file, char *fake_family, BOOL external_font)
+#define ADDFONT_EXTERNAL_FONT 0x01
+#define ADDFONT_FORCE_BITMAP  0x02
+static BOOL AddFontFileToList(const char *file, char *fake_family, DWORD flags)
 {
     FT_Face ft_face;
     TT_OS2 *pOS2;
-    TT_Header *pHeader;
+    TT_Header *pHeader = NULL;
     WCHAR *FamilyW, *StyleW;
     DWORD len;
-    Family *family = FontList;
-    Family **insert = &FontList;
+    Family **pfamily;
     Face **insertface, *next;
     FT_Error err;
     FT_Long face_index = 0, num_faces;
-    int i;
+#ifdef HAVE_FREETYPE_FTWINFNT_H
+    FT_WinFNT_HeaderRec winfnt_header;
+#endif
+    int i, bitmap_num;
 
     do {
         char *family_name = fake_family;
@@ -315,13 +384,20 @@
 	    return FALSE;
 	}
 
-	if(!FT_IS_SFNT(ft_face)) { /* for now we'll skip everything but TT/OT */
+	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*/
 	    pFT_Done_Face(ft_face);
 	    return FALSE;
 	}
-	if(!pFT_Get_Sfnt_Table(ft_face, ft_sfnt_os2) ||
+
+        /* 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))) {
+	    pFT_Done_Face(ft_face);
+	    return FALSE;
+	}
+
+	if(FT_IS_SFNT(ft_face) && (!pFT_Get_Sfnt_Table(ft_face, ft_sfnt_os2) ||
 	   !pFT_Get_Sfnt_Table(ft_face, ft_sfnt_hhea) ||
-           !(pHeader = pFT_Get_Sfnt_Table(ft_face, ft_sfnt_head))) {
+           !(pHeader = pFT_Get_Sfnt_Table(ft_face, ft_sfnt_head)))) {
 	    TRACE("Font file %s lacks either an OS2, HHEA or HEAD table.\n"
 		  "Skipping this font.\n", debugstr_a(file));
 	    pFT_Done_Face(ft_face);
@@ -337,122 +413,156 @@
         if(!family_name)
             family_name = ft_face->family_name;
 
-        len = MultiByteToWideChar(CP_ACP, 0, family_name, -1, NULL, 0);
-        FamilyW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
-        MultiByteToWideChar(CP_ACP, 0, family_name, -1, FamilyW, len);
+        bitmap_num = 0;
+        do {
+            len = MultiByteToWideChar(CP_ACP, 0, family_name, -1, NULL, 0);
+            FamilyW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
+            MultiByteToWideChar(CP_ACP, 0, family_name, -1, FamilyW, len);
 
-	while(family) {
-	    if(!strcmpW(family->FamilyName, FamilyW))
-	        break;
-	    insert = &family->next;
-	    family = family->next;
-	}
-	if(!family) {
-	    family = *insert = HeapAlloc(GetProcessHeap(), 0, sizeof(*family));
-	    family->FamilyName = FamilyW;
-	    family->FirstFace = NULL;
-	    family->next = NULL;
-	} else {
-	    HeapFree(GetProcessHeap(), 0, FamilyW);
-	}
-
-	len = MultiByteToWideChar(CP_ACP, 0, ft_face->style_name, -1, NULL, 0);
-	StyleW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
-	MultiByteToWideChar(CP_ACP, 0, ft_face->style_name, -1, StyleW, len);
-
-        next = NULL;
-	for(insertface = &family->FirstFace; *insertface;
-	    insertface = &(*insertface)->next) {
-	    if(!strcmpW((*insertface)->StyleName, StyleW)) {
-	        TRACE("Already loaded font %s %s original version is %lx, this version is %lx\n",
-                      debugstr_w(family->FamilyName), debugstr_w(StyleW),
-                      (*insertface)->font_version,  pHeader->Font_Revision);
-
-                if(fake_family) {
-                    TRACE("This font is a replacement but the original really exists, so we'll skip the replacement\n");
-                    HeapFree(GetProcessHeap(), 0, StyleW);
-                    pFT_Done_Face(ft_face);
-                    return FALSE;
-                }
-                if(pHeader->Font_Revision <= (*insertface)->font_version) {
-                    TRACE("Original font is newer so skipping this one\n");
-                    HeapFree(GetProcessHeap(), 0, StyleW);
-                    pFT_Done_Face(ft_face);
-                    return FALSE;
-                } else {
-                    TRACE("Replacing original with this one\n");
-                    next = (*insertface)->next;
-                    HeapFree(GetProcessHeap(), 0, (*insertface)->file);
-                    HeapFree(GetProcessHeap(), 0, (*insertface)->StyleName);
-                    HeapFree(GetProcessHeap(), 0, *insertface);
+            pfamily = &FontList;
+            while(*pfamily) {
+                if(!strcmpW((*pfamily)->FamilyName, FamilyW))
                     break;
+                pfamily = &(*pfamily)->next;
+            }
+            if(!*pfamily) {
+                *pfamily = HeapAlloc(GetProcessHeap(), 0, sizeof(**pfamily));
+                (*pfamily)->FamilyName = FamilyW;
+                (*pfamily)->FirstFace = NULL;
+                (*pfamily)->next = NULL;
+            } else {
+                HeapFree(GetProcessHeap(), 0, FamilyW);
+            }
+
+            len = MultiByteToWideChar(CP_ACP, 0, ft_face->style_name, -1, NULL, 0);
+            StyleW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
+            MultiByteToWideChar(CP_ACP, 0, ft_face->style_name, -1, StyleW, len);
+
+            next = NULL;
+            for(insertface = &(*pfamily)->FirstFace; *insertface;
+                insertface = &(*insertface)->next) {
+                if(!strcmpW((*insertface)->StyleName, StyleW) && FT_IS_SCALABLE(ft_face)) {
+                    TRACE("Already loaded font %s %s original version is %lx, this version is %lx\n",
+                          debugstr_w((*pfamily)->FamilyName), debugstr_w(StyleW),
+                          (*insertface)->font_version,  pHeader->Font_Revision);
+
+                    if(fake_family) {
+                        TRACE("This font is a replacement but the original really exists, so we'll skip the replacement\n");
+                        HeapFree(GetProcessHeap(), 0, StyleW);
+                        pFT_Done_Face(ft_face);
+                        return FALSE;
+                    }
+                    if(pHeader->Font_Revision <= (*insertface)->font_version) {
+                        TRACE("Original font is newer so skipping this one\n");
+                        HeapFree(GetProcessHeap(), 0, StyleW);
+                        pFT_Done_Face(ft_face);
+                        return FALSE;
+                    } else {
+                        TRACE("Replacing original with this one\n");
+                        next = (*insertface)->next;
+                        HeapFree(GetProcessHeap(), 0, (*insertface)->file);
+                        HeapFree(GetProcessHeap(), 0, (*insertface)->StyleName);
+                        HeapFree(GetProcessHeap(), 0, *insertface);
+                        break;
+                    }
                 }
             }
-        }
-	*insertface = HeapAlloc(GetProcessHeap(), 0, sizeof(**insertface));
-	(*insertface)->StyleName = StyleW;
-	(*insertface)->file = HeapAlloc(GetProcessHeap(),0,strlen(file)+1);
-	strcpy((*insertface)->file, file);
-	(*insertface)->face_index = face_index;
-	(*insertface)->next = next;
-	(*insertface)->Italic = (ft_face->style_flags & FT_STYLE_FLAG_ITALIC) ? 1 : 0;
-	(*insertface)->Bold = (ft_face->style_flags & FT_STYLE_FLAG_BOLD) ? 1 : 0;
-        (*insertface)->font_version = pHeader->Font_Revision;
-        (*insertface)->family = family;
-        (*insertface)->external = external_font;
+            *insertface = HeapAlloc(GetProcessHeap(), 0, sizeof(**insertface));
+            (*insertface)->StyleName = StyleW;
+            (*insertface)->file = HeapAlloc(GetProcessHeap(),0,strlen(file)+1);
+            strcpy((*insertface)->file, file);
+            (*insertface)->face_index = face_index;
+            (*insertface)->next = next;
+            (*insertface)->Italic = (ft_face->style_flags & FT_STYLE_FLAG_ITALIC) ? 1 : 0;
+            (*insertface)->Bold = (ft_face->style_flags & FT_STYLE_FLAG_BOLD) ? 1 : 0;
+            (*insertface)->font_version = pHeader ? pHeader->Font_Revision : 0;
+            (*insertface)->family = *pfamily;
+            (*insertface)->external = (flags & ADDFONT_EXTERNAL_FONT) ? TRUE : FALSE;
 
-	pOS2 = pFT_Get_Sfnt_Table(ft_face, ft_sfnt_os2);
-	if(pOS2) {
-            (*insertface)->fs.fsCsb[0] = pOS2->ulCodePageRange1;
-            (*insertface)->fs.fsCsb[1] = pOS2->ulCodePageRange2;
-            (*insertface)->fs.fsUsb[0] = pOS2->ulUnicodeRange1;
-            (*insertface)->fs.fsUsb[1] = pOS2->ulUnicodeRange2;
-            (*insertface)->fs.fsUsb[2] = pOS2->ulUnicodeRange3;
-            (*insertface)->fs.fsUsb[3] = pOS2->ulUnicodeRange4;
-	} else {
-            (*insertface)->fs.fsCsb[0] = (*insertface)->fs.fsCsb[1] = 0;
-            (*insertface)->fs.fsUsb[0] = 0;
-            (*insertface)->fs.fsUsb[1] = 0;
-            (*insertface)->fs.fsUsb[2] = 0;
-            (*insertface)->fs.fsUsb[3] = 0;
-	}
-	TRACE("fsCsb = %08lx %08lx/%08lx %08lx %08lx %08lx\n",
-              (*insertface)->fs.fsCsb[0], (*insertface)->fs.fsCsb[1],
-              (*insertface)->fs.fsUsb[0], (*insertface)->fs.fsUsb[1],
-              (*insertface)->fs.fsUsb[2], (*insertface)->fs.fsUsb[3]);
+            if(FT_IS_SCALABLE(ft_face)) {
+                memset(&(*insertface)->size, 0, sizeof((*insertface)->size));
+                (*insertface)->scalable = TRUE;
+            } else {
+                /* FT_Bitmap_Size gained 3 new elements between FreeType 2.1.4 and 2.1.5
+                   So to let this compile on older versions of FreeType we'll define the
+                   new structure here.  Note that this code is never executed when run with
+                   earlier versions of the library because of the version check above */
+                struct my_bitmap_size {
+                    FT_Short height, width;
+                    FT_Pos size, x_ppem, y_ppem;
+                } *size;
 
-        if(pOS2->version == 0) {
-            FT_UInt dummy;
-	
-	    /* If the function is not there, we assume the font is ok */
-            if(!pFT_Get_First_Char || (pFT_Get_First_Char( ft_face, &dummy ) < 0x100))
-                (*insertface)->fs.fsCsb[0] |= 1;
-            else
-                (*insertface)->fs.fsCsb[0] |= 1L << 31;
-        }
+                size = (struct my_bitmap_size *)ft_face->available_sizes + bitmap_num;
+                TRACE("Adding bitmap size h %d w %d size %ld x_ppem %ld y_ppem %ld\n",
+                      size->height, size->width, size->size >> 6,
+                      size->x_ppem >> 6, size->y_ppem >> 6);
+                (*insertface)->size.height = size->height;
+                (*insertface)->size.width = size->width;
+                (*insertface)->size.size = size->size;
+                (*insertface)->size.x_ppem = size->x_ppem;
+                (*insertface)->size.y_ppem = size->y_ppem;
+                (*insertface)->size.internal_leading = 0;
+                (*insertface)->scalable = FALSE;
+            }
 
-	if((*insertface)->fs.fsCsb[0] == 0) { /* let's see if we can find any interesting cmaps */
-	    for(i = 0; i < ft_face->num_charmaps; i++) {
-	        switch(ft_face->charmaps[i]->encoding) {
-		case ft_encoding_unicode:
-		case ft_encoding_apple_roman:
+            memset(&(*insertface)->fs, 0, sizeof((*insertface)->fs));
+
+            pOS2 = pFT_Get_Sfnt_Table(ft_face, ft_sfnt_os2);
+            if(pOS2) {
+                (*insertface)->fs.fsCsb[0] = pOS2->ulCodePageRange1;
+                (*insertface)->fs.fsCsb[1] = pOS2->ulCodePageRange2;
+                (*insertface)->fs.fsUsb[0] = pOS2->ulUnicodeRange1;
+                (*insertface)->fs.fsUsb[1] = pOS2->ulUnicodeRange2;
+                (*insertface)->fs.fsUsb[2] = pOS2->ulUnicodeRange3;
+                (*insertface)->fs.fsUsb[3] = pOS2->ulUnicodeRange4;
+                if(pOS2->version == 0) {
+                    FT_UInt dummy;
+
+                    if(!pFT_Get_First_Char || (pFT_Get_First_Char( ft_face, &dummy ) < 0x100))
+                        (*insertface)->fs.fsCsb[0] |= 1;
+                    else
+                        (*insertface)->fs.fsCsb[0] |= 1L << 31;
+                }
+            }
+#ifdef HAVE_FREETYPE_FTWINFNT_H
+            else if(pFT_Get_WinFNT_Header && !pFT_Get_WinFNT_Header(ft_face, &winfnt_header)) {
+                CHARSETINFO csi;
+                TRACE("pix_h %d charset %d dpi %dx%d pt %d\n", winfnt_header.pixel_height, winfnt_header.charset,
+                      winfnt_header.vertical_resolution,winfnt_header.horizontal_resolution, winfnt_header.nominal_point_size);
+                if(TranslateCharsetInfo((DWORD*)(UINT)winfnt_header.charset, &csi, TCI_SRCCHARSET))
+                    memcpy(&(*insertface)->fs, &csi.fs, sizeof(csi.fs));
+                (*insertface)->size.internal_leading = winfnt_header.internal_leading;
+            }
+#endif
+            TRACE("fsCsb = %08lx %08lx/%08lx %08lx %08lx %08lx\n",
+                  (*insertface)->fs.fsCsb[0], (*insertface)->fs.fsCsb[1],
+                  (*insertface)->fs.fsUsb[0], (*insertface)->fs.fsUsb[1],
+                  (*insertface)->fs.fsUsb[2], (*insertface)->fs.fsUsb[3]);
+
+
+            if((*insertface)->fs.fsCsb[0] == 0) { /* let's see if we can find any interesting cmaps */
+                for(i = 0; i < ft_face->num_charmaps; i++) {
+                    switch(ft_face->charmaps[i]->encoding) {
+                    case ft_encoding_unicode:
+                    case ft_encoding_apple_roman:
 			(*insertface)->fs.fsCsb[0] |= 1;
-		    break;
-		case ft_encoding_symbol:
-		    (*insertface)->fs.fsCsb[0] |= 1L << 31;
-		    break;
-		default:
-		    break;
-		}
-	    }
-	}
+                        break;
+                    case ft_encoding_symbol:
+                        (*insertface)->fs.fsCsb[0] |= 1L << 31;
+                        break;
+                    default:
+                        break;
+                    }
+                }
+            }
 
-        if((*insertface)->fs.fsCsb[0] & ~(1L << 31))
-            have_installed_roman_font = TRUE;
+            if((*insertface)->fs.fsCsb[0] & ~(1L << 31))
+                have_installed_roman_font = TRUE;
+        } while(!FT_IS_SCALABLE(ft_face) && ++bitmap_num < ft_face->num_fixed_sizes);
 
 	num_faces = ft_face->num_faces;
 	pFT_Done_Face(ft_face);
-	TRACE("Added font %s %s\n", debugstr_w(family->FamilyName),
+	TRACE("Added font %s %s\n", debugstr_w((*pfamily)->FamilyName),
 	      debugstr_w(StyleW));
     } while(num_faces > ++face_index);
     return TRUE;
@@ -466,7 +576,10 @@
     for(family = FontList; family; family = family->next) {
         TRACE("Family: %s\n", debugstr_w(family->FamilyName));
         for(face = family->FirstFace; face; face = face->next) {
-	    TRACE("\t%s\n", debugstr_w(face->StyleName));
+	    TRACE("\t%s", debugstr_w(face->StyleName));
+            if(!face->scalable)
+                TRACE(" %ld", face->size.y_ppem >> 6);
+            TRACE("\n");
 	}
     }
     return;
@@ -624,7 +737,7 @@
                         TRACE("mapping %s %s to %s\n", debugstr_w(family->FamilyName),
                               debugstr_w(face->StyleName), value);
                         /* Now add a new entry with the new family name */
-                        AddFontFileToList(face->file, value, face->external);
+                        AddFontFileToList(face->file, value, face->external ? ADDFONT_EXTERNAL_FONT : 0);
                     }
                     break;
                 }
@@ -671,7 +784,7 @@
 	if(S_ISDIR(statbuf.st_mode))
 	    ReadFontDir(path, external_fonts);
 	else
-	    AddFontFileToList(path, NULL, external_fonts);
+	    AddFontFileToList(path, NULL, external_fonts ? ADDFONT_EXTERNAL_FONT : 0);
     }
     closedir(dir);
     return TRUE;
@@ -729,7 +842,7 @@
         if(len < 4) continue;
         ext = v.u.s + len - 3;
         if(!strcasecmp(ext, "ttf") || !strcasecmp(ext, "ttc") || !strcasecmp(ext, "otf"))
-            AddFontFileToList(v.u.s, NULL, TRUE);
+            AddFontFileToList(v.u.s, NULL, ADDFONT_EXTERNAL_FONT);
     }
     pFcFontSetDestroy(fontset);
     pFcObjectSetDestroy(os);
@@ -739,6 +852,34 @@
     return;
 }
 
+
+void load_system_fonts(void)
+{
+    HKEY hkey;
+    WCHAR data[MAX_PATH], windowsdir[MAX_PATH], pathW[MAX_PATH];
+    const WCHAR **value;
+    DWORD dlen, type;
+    static const WCHAR fmtW[] = {'%','s','\\','%','s','\0'};
+    char *unixname;
+
+    if(RegOpenKeyW(HKEY_CURRENT_CONFIG, system_fonts_reg_key, &hkey) == ERROR_SUCCESS) {
+        GetWindowsDirectoryW(windowsdir, sizeof(windowsdir) / sizeof(WCHAR));
+        strcatW(windowsdir, fontsW);
+        for(value = SystemFontValues; *value; value++) { 
+            dlen = sizeof(data);
+            if(RegQueryValueExW(hkey, *value, 0, &type, (void*)data, &dlen) == ERROR_SUCCESS &&
+               type == REG_SZ) {
+                sprintfW(pathW, fmtW, windowsdir, data);
+                if((unixname = wine_get_unix_file_name(pathW))) {
+                    AddFontFileToList(unixname, NULL, ADDFONT_FORCE_BITMAP);
+                    HeapFree(GetProcessHeap(), 0, unixname);
+                }
+            }
+        }
+        RegCloseKey(hkey);
+    }
+}
+
 /*************************************************************
  *
  * This adds registry entries for any externally loaded fonts
@@ -858,7 +999,7 @@
 
         if((unixname = wine_get_unix_file_name(file)))
         {
-            AddFontFileToList(unixname, NULL, FALSE);
+            AddFontFileToList(unixname, NULL, ADDFONT_FORCE_BITMAP);
             HeapFree(GetProcessHeap(), 0, unixname);
         }
     }
@@ -882,7 +1023,7 @@
  */
 BOOL WineEngInit(void)
 {
-    static const WCHAR fontsW[] = {'\\','F','o','n','t','s','\0'};
+    static const WCHAR dot_fonW[] = {'.','f','o','n','\0'};
     HKEY hkey;
     DWORD valuelen, datalen, i = 0, type, dlen, vlen;
     LPVOID data;
@@ -925,7 +1066,9 @@
     pFT_Library_Version = wine_dlsym(ft_handle, "FT_Library_Version", NULL, 0);
     pFT_Load_Sfnt_Table = wine_dlsym(ft_handle, "FT_Load_Sfnt_Table", NULL, 0);
     pFT_Get_First_Char = wine_dlsym(ft_handle, "FT_Get_First_Char", NULL, 0);
-
+#ifdef HAVE_FREETYPE_FTWINFNT_H
+    pFT_Get_WinFNT_Header = wine_dlsym(ft_handle, "FT_Get_WinFNT_Header", NULL, 0);
+#endif
       if(!wine_dlsym(ft_handle, "FT_Get_Postscript_Name", NULL, 0) &&
 	 !wine_dlsym(ft_handle, "FT_Sqrt64", NULL, 0)) {
 	/* try to avoid 2.0.4: >= 2.0.5 has FT_Get_Postscript_Name and
@@ -951,6 +1094,9 @@
         FT_Version.patch=5;
     }
     TRACE("FreeType version is %d.%d.%d\n",FT_Version.major,FT_Version.minor,FT_Version.patch);
+    FT_SimpleVersion = ((FT_Version.major << 16) & 0xff0000) |
+                       ((FT_Version.minor <<  8) & 0x00ff00) |
+                       ((FT_Version.patch      ) & 0x0000ff);
 
     if((font_mutex = CreateMutexW(NULL, FALSE, font_mutex_nameW)) == NULL) {
         ERR("Failed to create font mutex\n");
@@ -967,9 +1113,13 @@
         HeapFree(GetProcessHeap(), 0, unixname);
     }
 
+    /* now load the system fonts */
+    load_system_fonts();
+
     /* now look under HKLM\Software\Microsoft\Windows[ NT]\CurrentVersion\Fonts
        for any fonts not installed in %WINDOWSDIR%\Fonts.  They will have their
-       full path as the entry */
+       full path as the entry.  Also look for any .fon fonts, since ReadFontDir
+       will skip these. */
     if(RegOpenKeyW(HKEY_LOCAL_MACHINE,
                    is_win9x() ? win9x_font_reg_key : winnt_font_reg_key,
 		   &hkey) == ERROR_SUCCESS) {
@@ -987,11 +1137,24 @@
             while(RegEnumValueW(hkey, i++, valueW, &vlen, NULL, &type, data,
                                 &dlen) == ERROR_SUCCESS) {
                 if(((LPWSTR)data)[0] && ((LPWSTR)data)[1] == ':')
+                {
                     if((unixname = wine_get_unix_file_name((LPWSTR)data)))
                     {
-                        AddFontFileToList(unixname, NULL, FALSE);
+                        AddFontFileToList(unixname, NULL, ADDFONT_FORCE_BITMAP);
                         HeapFree(GetProcessHeap(), 0, unixname);
                     }
+                }
+                else if(dlen / 2 >= 6 && !strcmpiW(((LPWSTR)data) + dlen / 2 - 5, dot_fonW))
+                {
+                    WCHAR pathW[MAX_PATH];
+                    static const WCHAR fmtW[] = {'%','s','\\','%','s','\0'};
+                    sprintfW(pathW, fmtW, windowsdir, data);
+                    if((unixname = wine_get_unix_file_name(pathW)))
+                    {
+                        AddFontFileToList(unixname, NULL, ADDFONT_FORCE_BITMAP);
+                        HeapFree(GetProcessHeap(), 0, unixname);
+                    }
+                }
                 /* reset dlen and vlen */
                 dlen = datalen;
                 vlen = valuelen;
@@ -1094,7 +1257,7 @@
 
 static LONG load_VDMX(GdiFont, LONG);
 
-static FT_Face OpenFontFile(GdiFont font, char *file, FT_Long face_index, LONG height)
+static FT_Face OpenFontFile(GdiFont font, char *file, FT_Long face_index, LONG width, LONG height)
 {
     FT_Error err;
     FT_Face ft_face;
@@ -1109,13 +1272,18 @@
     /* set it here, as load_VDMX needs it */
     font->ft_face = ft_face;
 
-    /* load the VDMX table if we have one */
-    ppem = load_VDMX(font, height);
-    if(ppem == 0)
-        ppem = calc_ppem_for_height(ft_face, height);
+    if(FT_IS_SCALABLE(ft_face)) {
+        /* load the VDMX table if we have one */
+        ppem = load_VDMX(font, height);
+        if(ppem == 0)
+            ppem = calc_ppem_for_height(ft_face, height);
 
-    pFT_Set_Pixel_Sizes(ft_face, 0, ppem);
-
+        if((err = pFT_Set_Pixel_Sizes(ft_face, 0, ppem)) != 0)
+            WARN("FT_Set_Pixel_Sizes %d, %ld rets %x\n", 0, ppem, err);
+    } else {
+        if((err = pFT_Set_Pixel_Sizes(ft_face, width, height)) != 0)
+            WARN("FT_Set_Pixel_Sizes %ld, %ld rets %x\n", width, height, err);
+    }
     return ft_face;
 }
 
@@ -1327,14 +1495,16 @@
 GdiFont WineEngCreateFontInstance(DC *dc, HFONT hfont)
 {
     GdiFont ret;
-    Face *face;
+    Face *face, *best;
     Family *family = NULL;
-    INT height;
-    BOOL bd, it;
+    INT height, width = 0;
+    signed int diff = 0, newdiff;
+    BOOL bd, it, can_use_bitmap;
     LOGFONTW lf;
     CHARSETINFO csi;
 
     if (!GetObjectW( hfont, sizeof(lf), &lf )) return NULL;
+    can_use_bitmap = GetDeviceCaps(dc->hSelf, TEXTCAPS) & TC_RA_ABLE;
 
     TRACE("%s, h=%ld, it=%d, weight=%ld, PandF=%02x, charset=%d orient %ld escapement %ld\n",
 	  debugstr_w(lf.lfFaceName), lf.lfHeight, lf.lfItalic,
@@ -1343,7 +1513,9 @@
 
     /* check the cache first */
     for(ret = GdiFontList; ret; ret = ret->next) {
-	if(ret->hfont == hfont && !memcmp(&ret->xform, &dc->xformWorld2Vport, offsetof(XFORM, eDx))) {
+	if(ret->hfont == hfont && !memcmp(&ret->xform, &dc->xformWorld2Vport, offsetof(XFORM, eDx)) &&
+           (can_use_bitmap || FT_IS_SCALABLE(ret->ft_face))) {
+
 	    TRACE("returning cached gdiFont(%p) for hFont %p\n", ret, hfont);
 	    return ret;
 	}
@@ -1400,28 +1572,11 @@
         for(family = FontList; family; family = family->next) {
 	    if(!strcmpiW(family->FamilyName, lf.lfFaceName))
 	        if((csi.fs.fsCsb[0] & family->FirstFace->fs.fsCsb[0]) || !csi.fs.fsCsb[0])
-		    break;
-	}
-
-	if(!family) { /* do other aliases here */
-	    if(!strcmpiW(lf.lfFaceName, SystemW))
-	        strcpyW(lf.lfFaceName, defSystem);
-	    else if(!strcmpiW(lf.lfFaceName, MSSansSerifW))
-	        strcpyW(lf.lfFaceName, defSans);
-	    else if(!strcmpiW(lf.lfFaceName, HelvW))
-	        strcpyW(lf.lfFaceName, defSans);
-	    else
-	        goto not_found;
-
-	    for(family = FontList; family; family = family->next) {
-	        if(!strcmpiW(family->FamilyName, lf.lfFaceName))
-		  if((csi.fs.fsCsb[0] & family->FirstFace->fs.fsCsb[0]) || !csi.fs.fsCsb[0])
-		      break;
-	    }
+                    if(family->FirstFace->scalable || can_use_bitmap)
+                        break;
 	}
     }
 
-not_found:
     if(!family) {
       /* If requested charset was DEFAULT_CHARSET then try using charset
 	 corresponding to the current ansi codepage */
@@ -1449,14 +1604,16 @@
 	for(family = FontList; family; family = family->next) {
 	    if(!strcmpiW(family->FamilyName, lf.lfFaceName) &&
 	       (csi.fs.fsCsb[0] & family->FirstFace->fs.fsCsb[0]))
-	        break;
+                    if(family->FirstFace->scalable || can_use_bitmap)
+                        break;
 	}
     }
 
     if(!family) {
         for(family = FontList; family; family = family->next) {
 	    if(csi.fs.fsCsb[0] & family->FirstFace->fs.fsCsb[0])
-	        break;
+                if(family->FirstFace->scalable || can_use_bitmap)
+                    break;
 	}
     }
 
@@ -1469,11 +1626,31 @@
     it = lf.lfItalic ? 1 : 0;
     bd = lf.lfWeight > 550 ? 1 : 0;
 
+    height = GDI_ROUND( (FLOAT)lf.lfHeight * dc->xformWorld2Vport.eM22 );
+    height = lf.lfHeight < 0 ? -abs(height) : abs(height);
+
+    best = NULL;
     for(face = family->FirstFace; face; face = face->next) {
-      if(!(face->Italic ^ it) && !(face->Bold ^ bd))
-	break;
+        if(!(face->Italic ^ it) && !(face->Bold ^ bd)) {
+            if(face->scalable)
+                break;
+            if(height > 0)
+                newdiff = height - (signed int)(face->size.y_ppem >> 6);
+            else
+                newdiff = -height - ((signed int)(face->size.y_ppem >> 6) - face->size.internal_leading);
+            if(!best || (diff > 0 && newdiff < diff && newdiff >= 0) ||
+               (diff < 0 && newdiff > diff)) {
+                TRACE("%ld is better for %d diff was %d\n", face->size.y_ppem >> 6, height, diff);
+                diff = newdiff;
+                best = face;
+                if(diff == 0)
+                    break;
+            }
+        }
     }
-    if(!face) {
+    if(!face && best)
+        face = best;
+    else if(!face) {
         face = family->FirstFace;
 	if(it && !face->Italic) ret->fake_italic = TRUE;
 	if(bd && !face->Bold) ret->fake_bold = TRUE;
@@ -1489,9 +1666,12 @@
     TRACE("Chosen: %s %s\n", debugstr_w(family->FamilyName),
 	  debugstr_w(face->StyleName));
 
-    height = GDI_ROUND( (FLOAT)lf.lfHeight * dc->xformWorld2Vport.eM22 );
-    ret->ft_face = OpenFontFile(ret, face->file, face->face_index,
-                                lf.lfHeight < 0 ? -abs(height) : abs(height));
+    if(!face->scalable) {
+        width = face->size.x_ppem >> 6;
+        height = face->size.y_ppem >> 6;
+    }
+    ret->ft_face = OpenFontFile(ret, face->file, face->face_index, width, height);
+
     if (!ret->ft_face)
     {
         free_font( ret );
@@ -1574,11 +1754,21 @@
 static void GetEnumStructs(Face *face, LPENUMLOGFONTEXW pelf,
 			   NEWTEXTMETRICEXW *pntm, LPDWORD ptype)
 {
-    OUTLINETEXTMETRICW *potm;
+    OUTLINETEXTMETRICW *potm = NULL;
     UINT size;
+    TEXTMETRICW tm, *ptm;
     GdiFont font = alloc_font();
+    LONG width, height;
 
-    if (!(font->ft_face = OpenFontFile(font, face->file, face->face_index, 100)))
+    if(face->scalable) {
+        height = 100;
+        width = 0;
+    } else {
+        height = face->size.y_ppem >> 6;
+        width = face->size.x_ppem >> 6;
+    }
+    
+    if (!(font->ft_face = OpenFontFile(font, face->file, face->face_index, width, height)))
     {
         free_font(font);
         return;
@@ -1589,60 +1779,71 @@
     memset(&pelf->elfLogFont, 0, sizeof(LOGFONTW));
 
     size = WineEngGetOutlineTextMetrics(font, 0, NULL);
-    potm = HeapAlloc(GetProcessHeap(), 0, size);
-    WineEngGetOutlineTextMetrics(font, size, potm);
-
-#define TM potm->otmTextMetrics
-
-    pntm->ntmTm.tmHeight = pelf->elfLogFont.lfHeight = TM.tmHeight;
-    pntm->ntmTm.tmAscent = TM.tmAscent;
-    pntm->ntmTm.tmDescent = TM.tmDescent;
-    pntm->ntmTm.tmInternalLeading = TM.tmInternalLeading;
-    pntm->ntmTm.tmExternalLeading = TM.tmExternalLeading;
-    pntm->ntmTm.tmAveCharWidth = pelf->elfLogFont.lfWidth = TM.tmAveCharWidth;
-    pntm->ntmTm.tmMaxCharWidth = TM.tmMaxCharWidth;
-    pntm->ntmTm.tmWeight = pelf->elfLogFont.lfWeight = TM.tmWeight;
-    pntm->ntmTm.tmOverhang = TM.tmOverhang;
-    pntm->ntmTm.tmDigitizedAspectX = TM.tmDigitizedAspectX;
-    pntm->ntmTm.tmDigitizedAspectY = TM.tmDigitizedAspectY;
-    pntm->ntmTm.tmFirstChar = TM.tmFirstChar;
-    pntm->ntmTm.tmLastChar = TM.tmLastChar;
-    pntm->ntmTm.tmDefaultChar = TM.tmDefaultChar;
-    pntm->ntmTm.tmBreakChar = TM.tmBreakChar;
-    pntm->ntmTm.tmItalic = pelf->elfLogFont.lfItalic = TM.tmItalic;
-    pntm->ntmTm.tmUnderlined = pelf->elfLogFont.lfUnderline = TM.tmUnderlined;
-    pntm->ntmTm.tmStruckOut = pelf->elfLogFont.lfStrikeOut = TM.tmStruckOut;
-    pntm->ntmTm.tmPitchAndFamily = TM.tmPitchAndFamily;
-    pelf->elfLogFont.lfPitchAndFamily = (TM.tmPitchAndFamily & 0xf1) + 1;
-    pntm->ntmTm.tmCharSet = pelf->elfLogFont.lfCharSet = TM.tmCharSet;
+    if(size) {
+        potm = HeapAlloc(GetProcessHeap(), 0, size);
+        WineEngGetOutlineTextMetrics(font, size, potm);
+        ptm = (TEXTMETRICW*)&potm->otmTextMetrics;
+    } else {
+        WineEngGetTextMetrics(font, &tm);
+        ptm = &tm;
+    }
+        
+    pntm->ntmTm.tmHeight = pelf->elfLogFont.lfHeight = ptm->tmHeight;
+    pntm->ntmTm.tmAscent = ptm->tmAscent;
+    pntm->ntmTm.tmDescent = ptm->tmDescent;
+    pntm->ntmTm.tmInternalLeading = ptm->tmInternalLeading;
+    pntm->ntmTm.tmExternalLeading = ptm->tmExternalLeading;
+    pntm->ntmTm.tmAveCharWidth = pelf->elfLogFont.lfWidth = ptm->tmAveCharWidth;
+    pntm->ntmTm.tmMaxCharWidth = ptm->tmMaxCharWidth;
+    pntm->ntmTm.tmWeight = pelf->elfLogFont.lfWeight = ptm->tmWeight;
+    pntm->ntmTm.tmOverhang = ptm->tmOverhang;
+    pntm->ntmTm.tmDigitizedAspectX = ptm->tmDigitizedAspectX;
+    pntm->ntmTm.tmDigitizedAspectY = ptm->tmDigitizedAspectY;
+    pntm->ntmTm.tmFirstChar = ptm->tmFirstChar;
+    pntm->ntmTm.tmLastChar = ptm->tmLastChar;
+    pntm->ntmTm.tmDefaultChar = ptm->tmDefaultChar;
+    pntm->ntmTm.tmBreakChar = ptm->tmBreakChar;
+    pntm->ntmTm.tmItalic = pelf->elfLogFont.lfItalic = ptm->tmItalic;
+    pntm->ntmTm.tmUnderlined = pelf->elfLogFont.lfUnderline = ptm->tmUnderlined;
+    pntm->ntmTm.tmStruckOut = pelf->elfLogFont.lfStrikeOut = ptm->tmStruckOut;
+    pntm->ntmTm.tmPitchAndFamily = ptm->tmPitchAndFamily;
+    pelf->elfLogFont.lfPitchAndFamily = (ptm->tmPitchAndFamily & 0xf1) + 1;
+    pntm->ntmTm.tmCharSet = pelf->elfLogFont.lfCharSet = ptm->tmCharSet;
     pelf->elfLogFont.lfOutPrecision = OUT_STROKE_PRECIS;
     pelf->elfLogFont.lfClipPrecision = CLIP_STROKE_PRECIS;
     pelf->elfLogFont.lfQuality = DRAFT_QUALITY;
 
-    pntm->ntmTm.ntmFlags = TM.tmItalic ? NTM_ITALIC : 0;
-    if(TM.tmWeight > 550) pntm->ntmTm.ntmFlags |= NTM_BOLD;
-    if(pntm->ntmTm.ntmFlags == 0) pntm->ntmTm.ntmFlags = NTM_REGULAR;
-
-    pntm->ntmTm.ntmSizeEM = potm->otmEMSquare;
-    pntm->ntmTm.ntmCellHeight = 0;
-    pntm->ntmTm.ntmAvgWidth = 0;
-
-    *ptype = TM.tmPitchAndFamily & TMPF_TRUETYPE ? TRUETYPE_FONTTYPE : 0;
-    if(!(TM.tmPitchAndFamily & TMPF_VECTOR))
+    *ptype = ptm->tmPitchAndFamily & TMPF_TRUETYPE ? TRUETYPE_FONTTYPE : 0;
+    if(!(ptm->tmPitchAndFamily & TMPF_VECTOR))
         *ptype |= RASTER_FONTTYPE;
 
-#undef TM
-    memset(&pntm->ntmFontSig, 0, sizeof(FONTSIGNATURE));
+    if(potm) {
+        pntm->ntmTm.ntmFlags = ptm->tmItalic ? NTM_ITALIC : 0;
+        if(ptm->tmWeight > 550) pntm->ntmTm.ntmFlags |= NTM_BOLD;
+        if(pntm->ntmTm.ntmFlags == 0) pntm->ntmTm.ntmFlags = NTM_REGULAR;
 
-    strncpyW(pelf->elfLogFont.lfFaceName,
-	     (WCHAR*)((char*)potm + (ptrdiff_t)potm->otmpFamilyName),
-	     LF_FACESIZE);
-    strncpyW(pelf->elfFullName,
-	     (WCHAR*)((char*)potm + (ptrdiff_t)potm->otmpFaceName),
-	     LF_FULLFACESIZE);
-    strncpyW(pelf->elfStyle,
-	     (WCHAR*)((char*)potm + (ptrdiff_t)potm->otmpStyleName),
-	     LF_FACESIZE);
+        pntm->ntmTm.ntmSizeEM = potm->otmEMSquare;
+        pntm->ntmTm.ntmCellHeight = 0;
+        pntm->ntmTm.ntmAvgWidth = 0;
+
+        memset(&pntm->ntmFontSig, 0, sizeof(FONTSIGNATURE));
+
+        strncpyW(pelf->elfLogFont.lfFaceName,
+                 (WCHAR*)((char*)potm + (ptrdiff_t)potm->otmpFamilyName),
+                 LF_FACESIZE);
+        strncpyW(pelf->elfFullName,
+                 (WCHAR*)((char*)potm + (ptrdiff_t)potm->otmpFaceName),
+                 LF_FULLFACESIZE);
+        strncpyW(pelf->elfStyle,
+                 (WCHAR*)((char*)potm + (ptrdiff_t)potm->otmpStyleName),
+                 LF_FACESIZE);
+
+    } else {
+        strncpyW(pelf->elfLogFont.lfFaceName, face->family->FamilyName, LF_FACESIZE);
+        strncpyW(pelf->elfFullName, face->family->FamilyName, LF_FACESIZE);
+        pelf->elfStyle[0] = '\0';
+    }
+
     pelf->elfScript[0] = '\0'; /* This will get set in WineEngEnumFonts */
 
     HeapFree(GetProcessHeap(), 0, potm);
@@ -1687,30 +1888,36 @@
 	        for(face = family->FirstFace; face; face = face->next) {
 		    GetEnumStructs(face, &elf, &ntm, &type);
 		    for(i = 0; i < 32; i++) {
-		        if(face->fs.fsCsb[0] & (1L << i)) {
-			    fs.fsCsb[0] = 1L << i;
-			    fs.fsCsb[1] = 0;
-			    if(!TranslateCharsetInfo(fs.fsCsb, &csi,
-						     TCI_SRCFONTSIG))
-			        csi.ciCharset = DEFAULT_CHARSET;
-			    if(i == 31) csi.ciCharset = SYMBOL_CHARSET;
-			    if(csi.ciCharset != DEFAULT_CHARSET) {
-			        elf.elfLogFont.lfCharSet =
-				  ntm.ntmTm.tmCharSet = csi.ciCharset;
-				if(ElfScriptsW[i])
-				    strcpyW(elf.elfScript, ElfScriptsW[i]);
-				else
-				    FIXME("Unknown elfscript for bit %d\n", i);
-				TRACE("enuming face %s full %s style %s charset %d type %ld script %s it %d weight %ld ntmflags %08lx\n",
-				      debugstr_w(elf.elfLogFont.lfFaceName),
-				      debugstr_w(elf.elfFullName), debugstr_w(elf.elfStyle),
-				      csi.ciCharset, type, debugstr_w(elf.elfScript),
-				      elf.elfLogFont.lfItalic, elf.elfLogFont.lfWeight,
-				      ntm.ntmTm.ntmFlags);
-				ret = proc(&elf.elfLogFont, (TEXTMETRICW *)&ntm, type, lparam);
-				if(!ret) goto end;
-			    }
-			}
+                        if(!face->scalable && face->fs.fsCsb[0] == 0) { /* OEM bitmap */
+                            elf.elfLogFont.lfCharSet = ntm.ntmTm.tmCharSet = OEM_CHARSET;
+                            strcpyW(elf.elfScript, OEM_DOSW);
+                            i = 32; /* break out of loop */
+                        } else if(!(face->fs.fsCsb[0] & (1L << i)))
+                            continue;
+                        else {
+                            fs.fsCsb[0] = 1L << i;
+                            fs.fsCsb[1] = 0;
+                            if(!TranslateCharsetInfo(fs.fsCsb, &csi,
+                                                     TCI_SRCFONTSIG))
+                                csi.ciCharset = DEFAULT_CHARSET;
+                            if(i == 31) csi.ciCharset = SYMBOL_CHARSET;
+                            if(csi.ciCharset != DEFAULT_CHARSET) {
+                                elf.elfLogFont.lfCharSet =
+                                    ntm.ntmTm.tmCharSet = csi.ciCharset;
+                                if(ElfScriptsW[i])
+                                    strcpyW(elf.elfScript, ElfScriptsW[i]);
+                                else
+                                    FIXME("Unknown elfscript for bit %d\n", i);
+                            }
+                        }
+                        TRACE("enuming face %s full %s style %s charset %d type %ld script %s it %d weight %ld ntmflags %08lx\n",
+                              debugstr_w(elf.elfLogFont.lfFaceName),
+                              debugstr_w(elf.elfFullName), debugstr_w(elf.elfStyle),
+                              csi.ciCharset, type, debugstr_w(elf.elfScript),
+                              elf.elfLogFont.lfItalic, elf.elfLogFont.lfWeight,
+                              ntm.ntmTm.ntmFlags);
+                        ret = proc(&elf.elfLogFont, (TEXTMETRICW *)&ntm, type, lparam);
+                        if(!ret) goto end;
 		    }
 		}
 	    }
@@ -1719,7 +1926,13 @@
         for(family = FontList; family; family = family->next) {
 	    GetEnumStructs(family->FirstFace, &elf, &ntm, &type);
 	    for(i = 0; i < 32; i++) {
-	        if(family->FirstFace->fs.fsCsb[0] & (1L << i)) {
+                if(!family->FirstFace->scalable && family->FirstFace->fs.fsCsb[0] == 0) { /* OEM bitmap */
+                    elf.elfLogFont.lfCharSet = ntm.ntmTm.tmCharSet = OEM_CHARSET;
+                    strcpyW(elf.elfScript, OEM_DOSW);
+                    i = 32; /* break out of loop */
+	        } else if(!(family->FirstFace->fs.fsCsb[0] & (1L << i)))
+                    continue;
+                else {
 		    fs.fsCsb[0] = 1L << i;
 		    fs.fsCsb[1] = 0;
 		    if(!TranslateCharsetInfo(fs.fsCsb, &csi,
@@ -1733,16 +1946,16 @@
 			      strcpyW(elf.elfScript, ElfScriptsW[i]);
 			  else
 			      FIXME("Unknown elfscript for bit %d\n", i);
-			TRACE("enuming face %s full %s style %s charset = %d type %ld script %s it %d weight %ld ntmflags %08lx\n",
-			      debugstr_w(elf.elfLogFont.lfFaceName),
-			      debugstr_w(elf.elfFullName), debugstr_w(elf.elfStyle),
-			      csi.ciCharset, type, debugstr_w(elf.elfScript),
-			      elf.elfLogFont.lfItalic, elf.elfLogFont.lfWeight,
-			      ntm.ntmTm.ntmFlags);
-			ret = proc(&elf.elfLogFont, (TEXTMETRICW *)&ntm, type, lparam);
-			if(!ret) goto end;
-		    }
-		}
+                    }
+                }
+                TRACE("enuming face %s full %s style %s charset = %d type %ld script %s it %d weight %ld ntmflags %08lx\n",
+                      debugstr_w(elf.elfLogFont.lfFaceName),
+                      debugstr_w(elf.elfFullName), debugstr_w(elf.elfStyle),
+                      csi.ciCharset, type, debugstr_w(elf.elfScript),
+                      elf.elfLogFont.lfItalic, elf.elfLogFont.lfWeight,
+                      ntm.ntmTm.ntmFlags);
+                ret = proc(&elf.elfLogFont, (TEXTMETRICW *)&ntm, type, lparam);
+                if(!ret) goto end;
 	    }
 	}
     }
@@ -1946,7 +2159,7 @@
     }
 
     if(ft_face->glyph->format != ft_glyph_format_outline && format != GGO_BITMAP) {
-        FIXME("loaded a bitmap\n");
+        TRACE("loaded a bitmap\n");
 	return GDI_ERROR;
     }
 
@@ -2236,6 +2449,71 @@
     return needed;
 }
 
+static BOOL get_bitmap_text_metrics(GdiFont font)
+{
+    FT_Face ft_face = font->ft_face;
+#ifdef HAVE_FREETYPE_FTWINFNT_H
+    FT_WinFNT_HeaderRec winfnt_header;
+#endif
+    const DWORD size = offsetof(OUTLINETEXTMETRICW, otmFiller); 
+    font->potm = HeapAlloc(GetProcessHeap(), 0, size);
+    font->potm->otmSize = size;
+
+#define TM font->potm->otmTextMetrics
+#ifdef HAVE_FREETYPE_FTWINFNT_H
+    if(pFT_Get_WinFNT_Header && !pFT_Get_WinFNT_Header(ft_face, &winfnt_header))
+    {
+        TM.tmHeight = winfnt_header.pixel_height;
+        TM.tmAscent = winfnt_header.ascent;
+        TM.tmDescent = TM.tmHeight - TM.tmAscent;
+        TM.tmInternalLeading = winfnt_header.internal_leading;
+        TM.tmExternalLeading = winfnt_header.external_leading;
+        TM.tmAveCharWidth = winfnt_header.avg_width;
+        TM.tmMaxCharWidth = winfnt_header.max_width;
+        TM.tmWeight = winfnt_header.weight;
+        TM.tmOverhang = 0;
+        TM.tmDigitizedAspectX = winfnt_header.horizontal_resolution;
+        TM.tmDigitizedAspectY = winfnt_header.vertical_resolution;
+        TM.tmFirstChar = winfnt_header.first_char;
+        TM.tmLastChar = winfnt_header.last_char;
+        TM.tmDefaultChar = winfnt_header.default_char;
+        TM.tmBreakChar = winfnt_header.break_char;
+        TM.tmItalic = winfnt_header.italic;
+        TM.tmUnderlined = winfnt_header.underline;
+        TM.tmStruckOut = winfnt_header.strike_out;
+        TM.tmPitchAndFamily = winfnt_header.pitch_and_family;
+        TM.tmCharSet = winfnt_header.charset;
+    }
+    else
+#endif
+    {
+        TM.tmAscent = ft_face->size->metrics.ascender >> 6;
+        TM.tmDescent = -ft_face->size->metrics.descender >> 6;
+        TM.tmHeight = TM.tmAscent + TM.tmDescent;
+        TM.tmInternalLeading = TM.tmHeight - ft_face->size->metrics.y_ppem;
+        TM.tmExternalLeading = (ft_face->size->metrics.height >> 6) - TM.tmHeight;
+        TM.tmMaxCharWidth = ft_face->size->metrics.max_advance >> 6;
+        TM.tmAveCharWidth = TM.tmMaxCharWidth * 2 / 3; /* FIXME */
+        TM.tmWeight = ft_face->style_flags & FT_STYLE_FLAG_BOLD ? FW_BOLD : FW_NORMAL;
+        TM.tmOverhang = 0;
+        TM.tmDigitizedAspectX = 96; /* FIXME */
+        TM.tmDigitizedAspectY = 96; /* FIXME */
+        TM.tmFirstChar = 1;
+        TM.tmLastChar = 255;
+        TM.tmDefaultChar = 32;
+        TM.tmBreakChar = 32;
+        TM.tmItalic = ft_face->style_flags & FT_STYLE_FLAG_ITALIC ? 1 : 0;
+        TM.tmUnderlined = 0;
+        TM.tmStruckOut = 0;
+        /* NB inverted meaning of TMPF_FIXED_PITCH */
+        TM.tmPitchAndFamily = ft_face->face_flags & FT_FACE_FLAG_FIXED_WIDTH ? 0 : TMPF_FIXED_PITCH;
+        TM.tmCharSet = font->charset;
+    }
+#undef TM
+
+    return TRUE;
+}
+
 /*************************************************************
  * WineEngGetTextMetrics
  *
@@ -2244,7 +2522,8 @@
 {
     if(!font->potm) {
         if(!WineEngGetOutlineTextMetrics(font, 0, NULL))
-	    return FALSE;
+            if(!get_bitmap_text_metrics(font))
+                return FALSE;
     }
     if(!font->potm) return FALSE;
     memcpy(ptm, &font->potm->otmTextMetrics, sizeof(*ptm));
@@ -2276,12 +2555,16 @@
 
     TRACE("font=%p\n", font);
 
+    if(!FT_IS_SCALABLE(ft_face))
+        return 0;
+
     if(font->potm) {
         if(cbSize >= font->potm->otmSize)
 	    memcpy(potm, font->potm, font->potm->otmSize);
 	return font->potm->otmSize;
     }
 
+
     needed = sizeof(*potm);
 
     lenfam = (strlenW(font->name) + 1) * sizeof(WCHAR);
@@ -2594,7 +2877,7 @@
     WineEngGetTextMetrics(font, &tm);
     size->cy = tm.tmHeight;
 
-   for(idx = 0; idx < count; idx++) {
+    for(idx = 0; idx < count; idx++) {
         WineEngGetGlyphOutline(font, indices[idx],
 			       GGO_METRICS | GGO_GLYPH_INDEX, &gm, 0, NULL,
 			       NULL);
diff --git a/include/config.h.in b/include/config.h.in
index c339ea9b4..0f64a77 100644
--- a/include/config.h.in
+++ b/include/config.h.in
@@ -110,6 +110,9 @@
 /* Define if you have the <freetype/fttrigon.h> header file. */
 #undef HAVE_FREETYPE_FTTRIGON_H
 
+/* Define to 1 if you have the <freetype/ftwinfnt.h> header file. */
+#undef HAVE_FREETYPE_FTWINFNT_H
+
 /* Define to 1 if you have the <freetype/internal/sfnt.h> header file. */
 #undef HAVE_FREETYPE_INTERNAL_SFNT_H
 
diff --git a/objects/font.c b/objects/font.c
index c11b6d0..d52fe95 100644
--- a/objects/font.c
+++ b/objects/font.c
@@ -627,8 +627,9 @@
     DC *dc;
 
     /* lfCharSet is at the same offset in both LOGFONTA and LOGFONTW */
-    if( pfe->lpLogFontParam->lfCharSet == DEFAULT_CHARSET ||
-        pfe->lpLogFontParam->lfCharSet == plf->lfCharSet )
+    if((pfe->lpLogFontParam->lfCharSet == DEFAULT_CHARSET ||
+        pfe->lpLogFontParam->lfCharSet == plf->lfCharSet) &&
+       (!(fType & RASTER_FONTTYPE) || GetDeviceCaps(pfe->hdc, TEXTCAPS) & TC_RA_ABLE) )
     {
 	/* convert font metrics */
         ENUMLOGFONTEXA logfont;