Change the callback declarations to a safer format.
[wine] / graphics / x11drv / xfont.c
index 6989bb6..3ab0e96 100644 (file)
@@ -9,11 +9,9 @@
 
 #include "config.h"
 
-#ifndef X_DISPLAY_MISSING
 #include <X11/Xatom.h>
+
 #include "ts_xlib.h"
-#include "x11font.h"
-#endif /* !defined(X_DISPLAY_MISSING) */
 
 #include <ctype.h>
 #include <stdio.h>
 #include <fcntl.h>
 #include <math.h>
 #include <assert.h>
+
 #include "windef.h"
 #include "wingdi.h"
-#include "winuser.h"
+#include "winnls.h"
 #include "heap.h"
 #include "options.h"
 #include "font.h"
 #include "debugtools.h"
-#include "ldt.h"
-#include "tweak.h"
-
-DEFAULT_DEBUG_CHANNEL(font)
+#include "user.h" /* for TWEAK_WineLook (FIXME) */
+#include "x11font.h"
+#include "server.h"
 
-#ifndef X_DISPLAY_MISSING
+DEFAULT_DEBUG_CHANNEL(font);
 
 #define X_PFONT_MAGIC          (0xFADE0000)
 #define X_FMC_MAGIC            (0x0000CAFE)
@@ -74,7 +72,6 @@ TC_CP_STROKE | TC_CR_ANY |
 
                        /* X11R6 adds TC_SF_X_YINDEP, maybe more... */
 
-static const char*     INIWinePrefix = "/.wine";
 static const char*     INIFontMetrics = "/cachedmetrics.";
 static const char*     INIFontSection = "fonts";
 static const char*     INIAliasSection = "Alias";
@@ -88,6 +85,7 @@ static const char*    INIDefaultSansSerif = "DefaultSansSerif";
 
 
 /* FIXME - are there any more Latin charsets ? */
+/* FIXME - RUSSIAN, ARABIC, GREEK, HEBREW are NOT Latin */
 #define IS_LATIN_CHARSET(ch) \
   ((ch)==ANSI_CHARSET ||\
    (ch)==EE_CHARSET ||\
@@ -98,92 +96,130 @@ static const char* INIDefaultSansSerif = "DefaultSansSerif";
    (ch)==GREEK_CHARSET ||\
    (ch)==HEBREW_CHARSET ||\
    (ch)==TURKISH_CHARSET ||\
-   (ch)==BALTIC_CHARSET)
+   (ch)==ISO10_CHARSET ||\
+   (ch)==BALTIC_CHARSET ||\
+   (ch)==CELTIC_CHARSET)
 
 /* suffix-charset mapping tables - must be less than 254 entries long */
 
 typedef struct __sufch
 {
-  LPSTR                psuffix;
-  BYTE         charset;
+  LPCSTR        psuffix;
+  WORD          charset; /* hibyte != 0 means *internal* charset */
+  WORD          codepage;
+  WORD          cptable;
 } SuffixCharset;
 
-static SuffixCharset sufch_ansi[] = {
-    {  "0", ANSI_CHARSET },
-    { NULL, ANSI_CHARSET }};
-
-static SuffixCharset sufch_iso646[] = {
-    { "irv", ANSI_CHARSET },
-    { NULL, SYMBOL_CHARSET }};
-
-static SuffixCharset sufch_iso8859[] = {
-    {  "1", ANSI_CHARSET },
-    {  "2", EE_CHARSET },
-    {  "3", ISO3_CHARSET }, 
-    {  "4", ISO4_CHARSET }, 
-    {  "5", RUSSIAN_CHARSET },
-    {  "6", ARABIC_CHARSET },
-    {  "7", GREEK_CHARSET },
-    {  "8", HEBREW_CHARSET }, 
-    {  "9", TURKISH_CHARSET },
-    { "10", BALTIC_CHARSET },
-    { "11", THAI_CHARSET },
-    { "12", SYMBOL_CHARSET },
-    { "13", SYMBOL_CHARSET },
-    { "14", SYMBOL_CHARSET },
-    { "15", ANSI_CHARSET },
-    { NULL, SYMBOL_CHARSET }};
-
-static SuffixCharset sufch_microsoft[] = {
-    { "cp1250", EE_CHARSET },
-    { "cp1251", RUSSIAN_CHARSET },
-    { "cp1252", ANSI_CHARSET },
-    { "cp1253", GREEK_CHARSET },
-    { "cp1254", TURKISH_CHARSET },
-    { "cp1255", HEBREW_CHARSET },
-    { "cp1256", ARABIC_CHARSET },
-    { "cp1257", BALTIC_CHARSET },
-    { "fontspecific", SYMBOL_CHARSET },
-    { "symbol", SYMBOL_CHARSET },
-    {   NULL,   SYMBOL_CHARSET }};
-
-static SuffixCharset sufch_tcvn[] = {
-    {  "0", TCVN_CHARSET },
-    { NULL, TCVN_CHARSET }};
-
-static SuffixCharset sufch_tis620[] = {
-    {  "0", THAI_CHARSET },
-    { NULL, THAI_CHARSET }};
-
-static SuffixCharset sufch_viscii[] = {
-    {  "1", VISCII_CHARSET },
-    { NULL, VISCII_CHARSET }};
-
-static SuffixCharset sufch_windows[] = {
-    { "1250", EE_CHARSET },
-    { "1251", RUSSIAN_CHARSET },
-    { "1252", ANSI_CHARSET },
-    { "1253", GREEK_CHARSET },
-    { "1254", TURKISH_CHARSET }, 
-    { "1255", HEBREW_CHARSET }, 
-    { "1256", ARABIC_CHARSET },
-    { "1257", BALTIC_CHARSET },
-    {  NULL,  BALTIC_CHARSET }}; /* CHECK/FIXME is BALTIC really the default ? */
-
-static SuffixCharset sufch_koi8[] = {
-    { "r", RUSSIAN_CHARSET },
-    { NULL, RUSSIAN_CHARSET }};
+static const SuffixCharset sufch_ansi[] = {
+    {  "0", ANSI_CHARSET, 1252, X11DRV_CPTABLE_SBCS },
+    { NULL, ANSI_CHARSET, 1252, X11DRV_CPTABLE_SBCS }};
+
+static const SuffixCharset sufch_iso646[] = {
+    { "irv", ANSI_CHARSET, 1252, X11DRV_CPTABLE_SBCS },
+    { NULL, ANSI_CHARSET, 1252, X11DRV_CPTABLE_SBCS }};
+
+static const SuffixCharset sufch_iso8859[] = {
+    {  "1", ANSI_CHARSET, 28591, X11DRV_CPTABLE_SBCS },
+    {  "2", EE_CHARSET, 28592, X11DRV_CPTABLE_SBCS },
+    {  "3", ISO3_CHARSET, 28593, X11DRV_CPTABLE_SBCS }, 
+    {  "4", ISO4_CHARSET, 28594, X11DRV_CPTABLE_SBCS }, 
+    {  "5", RUSSIAN_CHARSET, 28595, X11DRV_CPTABLE_SBCS },
+    {  "6", ARABIC_CHARSET, 28596, X11DRV_CPTABLE_SBCS },
+    {  "7", GREEK_CHARSET, 28597, X11DRV_CPTABLE_SBCS },
+    {  "8", HEBREW_CHARSET, 28598, X11DRV_CPTABLE_SBCS }, 
+    {  "9", TURKISH_CHARSET, 28599, X11DRV_CPTABLE_SBCS },
+    { "10", ISO10_CHARSET, 28600, X11DRV_CPTABLE_SBCS },
+    { "11", THAI_CHARSET, 874, X11DRV_CPTABLE_SBCS }, /* FIXME */
+    { "12", SYMBOL_CHARSET, CP_SYMBOL, X11DRV_CPTABLE_SBCS },
+    { "13", BALTIC_CHARSET, 28603, X11DRV_CPTABLE_SBCS },
+    { "14", CELTIC_CHARSET, 28604, X11DRV_CPTABLE_SBCS },
+    { "15", ANSI_CHARSET, 28605, X11DRV_CPTABLE_SBCS },
+    { NULL, ANSI_CHARSET, 1252, X11DRV_CPTABLE_SBCS }};
+
+static const SuffixCharset sufch_microsoft[] = {
+    { "cp1250", EE_CHARSET, 1250, X11DRV_CPTABLE_SBCS },
+    { "cp1251", RUSSIAN_CHARSET, 1251, X11DRV_CPTABLE_SBCS },
+    { "cp1252", ANSI_CHARSET, 1252, X11DRV_CPTABLE_SBCS },
+    { "cp1253", GREEK_CHARSET, 1253, X11DRV_CPTABLE_SBCS },
+    { "cp1254", TURKISH_CHARSET, 1254, X11DRV_CPTABLE_SBCS },
+    { "cp1255", HEBREW_CHARSET, 1255, X11DRV_CPTABLE_SBCS },
+    { "cp1256", ARABIC_CHARSET, 1256, X11DRV_CPTABLE_SBCS },
+    { "cp1257", BALTIC_CHARSET, 1257, X11DRV_CPTABLE_SBCS },
+    { "fontspecific", SYMBOL_CHARSET, CP_SYMBOL, X11DRV_CPTABLE_SBCS },
+    { "symbol", SYMBOL_CHARSET, CP_SYMBOL, X11DRV_CPTABLE_SBCS },
+    {   NULL,   ANSI_CHARSET, 1252, X11DRV_CPTABLE_SBCS }};
+
+static const SuffixCharset sufch_tcvn[] = {
+    {  "0", TCVN_CHARSET, 1252, X11DRV_CPTABLE_SBCS }, /* FIXME */
+    { NULL, TCVN_CHARSET, 1252, X11DRV_CPTABLE_SBCS }};
+
+static const SuffixCharset sufch_tis620[] = {
+    {  "0", THAI_CHARSET, 874, X11DRV_CPTABLE_SBCS }, /* FIXME */
+    { NULL, THAI_CHARSET, 874, X11DRV_CPTABLE_SBCS }};
+
+static const SuffixCharset sufch_viscii[] = {
+    {  "1", VISCII_CHARSET, 1252, X11DRV_CPTABLE_SBCS }, /* FIXME */
+    { NULL, VISCII_CHARSET, 1252, X11DRV_CPTABLE_SBCS }};
+
+static const SuffixCharset sufch_windows[] = {
+    { "1250", EE_CHARSET, 1250, X11DRV_CPTABLE_SBCS },
+    { "1251", RUSSIAN_CHARSET, 1251, X11DRV_CPTABLE_SBCS },
+    { "1252", ANSI_CHARSET, 1252, X11DRV_CPTABLE_SBCS },
+    { "1253", GREEK_CHARSET, 1253, X11DRV_CPTABLE_SBCS },
+    { "1254", TURKISH_CHARSET, 1254, X11DRV_CPTABLE_SBCS }, 
+    { "1255", HEBREW_CHARSET, 1255, X11DRV_CPTABLE_SBCS }, 
+    { "1256", ARABIC_CHARSET, 1256, X11DRV_CPTABLE_SBCS },
+    { "1257", BALTIC_CHARSET, 1257, X11DRV_CPTABLE_SBCS },
+    {  NULL,  ANSI_CHARSET, 1252, X11DRV_CPTABLE_SBCS }};
+
+static const SuffixCharset sufch_koi8[] = {
+    { "r", RUSSIAN_CHARSET, 20866, X11DRV_CPTABLE_SBCS },
+    { "ru", RUSSIAN_CHARSET, 20866, X11DRV_CPTABLE_SBCS },
+    { "u", RUSSIAN_CHARSET, 20866, X11DRV_CPTABLE_SBCS },
+    { NULL, RUSSIAN_CHARSET, 20866, X11DRV_CPTABLE_SBCS }};
+
+static const SuffixCharset sufch_jisx0201[] = {
+    { "0", X11FONT_JISX0201_CHARSET, 932, X11DRV_CPTABLE_SBCS },
+    { NULL, X11FONT_JISX0201_CHARSET, 932, X11DRV_CPTABLE_SBCS }};
+
+static const SuffixCharset sufch_jisx0208[] = {
+    { "0", SHIFTJIS_CHARSET, 932, X11DRV_CPTABLE_CP932 },
+    { NULL, SHIFTJIS_CHARSET, 932, X11DRV_CPTABLE_CP932 }};
+
+static const SuffixCharset sufch_jisx0212[] = {
+    { "0", X11FONT_JISX0212_CHARSET, 932, X11DRV_CPTABLE_CP932 },
+    { NULL, X11FONT_JISX0212_CHARSET, 932, X11DRV_CPTABLE_CP932 }};
+
+static const SuffixCharset sufch_ksc5601[] = {
+    { "0", HANGEUL_CHARSET, 949, X11DRV_CPTABLE_CP949 },
+    { NULL, HANGEUL_CHARSET, 949, X11DRV_CPTABLE_CP949 }};
+
+static const SuffixCharset sufch_gb2312[] = {
+    { "0", GB2312_CHARSET, 936, X11DRV_CPTABLE_CP936 },
+    { NULL, GB2312_CHARSET, 936, X11DRV_CPTABLE_CP936 }};
+
+static const SuffixCharset sufch_big5[] = {
+    { "0", CHINESEBIG5_CHARSET, 950, X11DRV_CPTABLE_CP950 },
+    { NULL, CHINESEBIG5_CHARSET, 950, X11DRV_CPTABLE_CP950 }};
+
+static const SuffixCharset sufch_unicode[] = {
+    { "0", DEFAULT_CHARSET, 0, X11DRV_CPTABLE_UNICODE },
+    { NULL, DEFAULT_CHARSET, 0, X11DRV_CPTABLE_UNICODE }};
+
+static const SuffixCharset sufch_iso10646[] = {
+    { "1", DEFAULT_CHARSET, 0, X11DRV_CPTABLE_UNICODE },
+    { NULL, DEFAULT_CHARSET, 0, X11DRV_CPTABLE_UNICODE }};
 
 /* Each of these must be matched explicitly */
-static SuffixCharset sufch_any[] = {
-    { "fontspecific", SYMBOL_CHARSET },
-    { NULL, 0 }};
+static const SuffixCharset sufch_any[] = {
+    { "fontspecific", SYMBOL_CHARSET, CP_SYMBOL, X11DRV_CPTABLE_SBCS },
+    { NULL, 0, 0, X11DRV_CPTABLE_SBCS }};
 
 
 typedef struct __fet
 {
   LPSTR                 prefix;
-  SuffixCharset* sufch;
+  const SuffixCharset* sufch;
   struct __fet*  next;
 } fontEncodingTemplate;
 
@@ -200,15 +236,79 @@ static fontEncodingTemplate __fETTable[] = {
                        { "tis620.2533",  sufch_tis620,       &__fETTable[7] },
                        { "viscii1.1",    sufch_viscii,       &__fETTable[8] },
                        { "windows",      sufch_windows,      &__fETTable[9] },
-                       { "koi8",         sufch_koi8,         &__fETTable[10] },
+                       { "koi8",         sufch_koi8,         &__fETTable[10]},
+                       { "jisx0201.1976",sufch_jisx0201,     &__fETTable[11]},
+                       { "jisc6226.1978",sufch_jisx0208,     &__fETTable[12]},
+                       { "jisx0208.1983",sufch_jisx0208,     &__fETTable[13]},
+                       { "jisx0208.1990",sufch_jisx0208,     &__fETTable[14]},
+                       { "jisx0212.1990",sufch_jisx0212,     &__fETTable[15]},
+                       { "ksc5601.1987", sufch_ksc5601,      &__fETTable[16]},
+                       { "gb2312.1980",  sufch_gb2312,       &__fETTable[17]},
+                       { "big5.et",      sufch_big5,         &__fETTable[18]},
+                       { "unicode",      sufch_unicode,      &__fETTable[19]},
+                       { "iso10646",     sufch_iso10646,     &__fETTable[20]},
+                       { "cp",           sufch_windows,      &__fETTable[21]},
                        /* NULL prefix matches anything so put it last */
                        {   NULL,         sufch_any,          NULL },
 };
 static fontEncodingTemplate* fETTable = __fETTable;
 
+/* a charset database for known facenames */
+struct CharsetBindingInfo
+{
+       const char*     pszFaceName;
+       BYTE            charset;
+};
+static const struct CharsetBindingInfo charsetbindings[] =
+{
+       /* special facenames */
+       { "System", DEFAULT_CHARSET },
+       { "FixedSys", DEFAULT_CHARSET },
+
+       /* known facenames */
+       { "MS Serif", ANSI_CHARSET },
+       { "MS Sans Serif", ANSI_CHARSET },
+       { "Courier", ANSI_CHARSET },
+       { "Symbol", SYMBOL_CHARSET },
+
+       { "Arial", ANSI_CHARSET },
+       { "Arial Greek", GREEK_CHARSET },
+       { "Arial Tur", TURKISH_CHARSET },
+       { "Arial Baltic", BALTIC_CHARSET },
+       { "Arial CE", EASTEUROPE_CHARSET },
+       { "Arial Cyr", RUSSIAN_CHARSET },
+       { "Courier New", ANSI_CHARSET },
+       { "Courier New Greek", GREEK_CHARSET },
+       { "Courier New Tur", TURKISH_CHARSET },
+       { "Courier New Baltic", BALTIC_CHARSET },
+       { "Courier New CE", EASTEUROPE_CHARSET },
+       { "Courier New Cyr", RUSSIAN_CHARSET },
+       { "Times New Roman", ANSI_CHARSET },
+       { "Times New Roman Greek", GREEK_CHARSET },
+       { "Times New Roman Tur", TURKISH_CHARSET },
+       { "Times New Roman Baltic", BALTIC_CHARSET },
+       { "Times New Roman CE", EASTEUROPE_CHARSET },
+       { "Times New Roman Cyr", RUSSIAN_CHARSET },
+
+       { "\x82\x6c\x82\x72 \x83\x53\x83\x56\x83\x62\x83\x4e",
+                       SHIFTJIS_CHARSET }, /* MS gothic */
+       { "\x82\x6c\x82\x72 \x82\x6f\x83\x53\x83\x56\x83\x62\x83\x4e",
+                       SHIFTJIS_CHARSET }, /* MS P gothic */
+       { "\x82\x6c\x82\x72 \x96\xbe\x92\xa9",
+                       SHIFTJIS_CHARSET }, /* MS mincho */
+       { "\x82\x6c\x82\x72 \x82\x6f\x96\xbe\x92\xa9",
+                       SHIFTJIS_CHARSET }, /* MS P mincho */
+       { "GulimChe", HANGEUL_CHARSET },
+       { "MS Song", GB2312_CHARSET },
+       { "MS Hei", GB2312_CHARSET },
+
+       { NULL, 0 }
+};
+
+
 static int             DefResolution = 0;
 
-static CRITICAL_SECTION crtsc_fonts_X11;
+static CRITICAL_SECTION crtsc_fonts_X11 = CRITICAL_SECTION_INIT;
 
 static fontResource*   fontList = NULL;
 static fontObject*      fontCache = NULL;              /* array */
@@ -253,19 +353,17 @@ static UINT16   __lfCheckSum( LPLOGFONT16 plf )
 {
     CHAR        font[LF_FACESIZE];
     UINT16      checksum = 0;
-    UINT16      i;
-
-#define ptr ((UINT16*)plf)
-   for( i = 0; i < 9; i++ ) checksum ^= *ptr++;
-#undef ptr
-   i = 0;
-#define ptr ((CHAR*)plf)
-   do { font[i++] = tolower(*ptr++); } while (( i < LF_FACESIZE) && (*ptr) && (*ptr!=' '));
-   for( ptr = font, i >>= 1; i > 0; i-- ) 
-#undef ptr
-#define ptr ((UINT16*)plf)
-        checksum ^= *ptr++;
-#undef ptr
+    UINT16 *ptr;
+    int i;
+
+    ptr = (UINT16 *)plf;
+    for (i = 0; i < 9; i++) checksum ^= *ptr++;
+    for (i = 0; i < LF_FACESIZE; i++)
+    {
+        font[i] = tolower(plf->lfFaceName[i]);
+        if (!font[i] || font[i] == ' ') break;
+    }
+    for (ptr = (UINT16 *)font, i >>= 1; i > 0; i-- ) checksum ^= *ptr++;
    return checksum;
 }
 
@@ -328,7 +426,7 @@ static LFD* LFD_Parse(LPSTR lpFont)
     if (*lpch)
        WARN("Extra ignored in font '%s'\n", lpFont);
     
-    lfd = HeapAlloc( SystemHeap, 0, sizeof(LFD) );
+    lfd = HeapAlloc( GetProcessHeap(), 0, sizeof(LFD) );
     if (lfd)
     {
        lfd->foundry = lfd_fld[0];
@@ -352,7 +450,7 @@ static LFD* LFD_Parse(LPSTR lpFont)
 
 static void LFD_UnParse(LPSTR dp, UINT buf_size, LFD* lfd)
 {
-    char* lfd_fld[LFD_FIELDS];
+    const char* lfd_fld[LFD_FIELDS];
     int i;
 
     if (!buf_size)
@@ -377,7 +475,7 @@ static void LFD_UnParse(LPSTR dp, UINT buf_size, LFD* lfd)
 
     for (i = 0; i < LFD_FIELDS; i++)
     {
-       char* sp = lfd_fld[i];
+       const char* sp = lfd_fld[i];
        if (!sp || !buf_size)
            break;
        
@@ -396,7 +494,7 @@ static void LFD_UnParse(LPSTR dp, UINT buf_size, LFD* lfd)
 
 static void LFD_GetWeight( fontInfo* fi, LPCSTR lpStr)
 {
-    int j = lstrlenA(lpStr);
+    int j = strlen(lpStr);
     if( j == 1 && *lpStr == '0') 
        fi->fi_flags |= FI_POLYWEIGHT;
     else if( j == 4 )
@@ -432,7 +530,7 @@ static void LFD_GetWeight( fontInfo* fi, LPCSTR lpStr)
 
 static BOOL LFD_GetSlant( fontInfo* fi, LPCSTR lpStr)
 {
-    int l = lstrlenA(lpStr);
+    int l = strlen(lpStr);
     if( l == 1 )
     {
        switch( tolower( *lpStr ) )
@@ -453,7 +551,7 @@ static BOOL LFD_GetSlant( fontInfo* fi, LPCSTR lpStr)
 
 static void LFD_GetStyle( fontInfo* fi, LPCSTR lpstr, int dec_style_check)
 {
-    int j = lstrlenA(lpstr);
+    int j = strlen(lpstr);
     if( j > 3 )        /* find out is there "sans" or "script" */
     {
        j = 0;
@@ -485,7 +583,7 @@ static int LFD_InitFontInfo( fontInfo* fi, const LFD* lfd, LPCSTR fullname )
    int         i, j, dec_style_check, scalability;
    fontEncodingTemplate* boba;
    const char* ridiculous = "font '%s' has ridiculous %s\n";
-   char* lpstr;
+   const char* lpstr;
 
    if (!lfd->charset_registry)
    {
@@ -605,14 +703,11 @@ static int LFD_InitFontInfo( fontInfo* fi, const LFD* lfd, LPCSTR fullname )
 
 /* charset registry, charset encoding - */
    lpstr = lfd->charset_registry;
-   if( strstr(lpstr, "jisx") || 
-       strstr(lpstr, "ksc") || 
+   if( strstr(lpstr, "ksc") || 
        strstr(lpstr, "gb2312") ||
-       strstr(lpstr, "big5") ||
-       strstr(lpstr, "unicode") )
+       strstr(lpstr, "big5") )
    {
-       TRACE(" 2-byte fonts like '%s' are not supported\n", fullname);
-       return FALSE;
+       FIXME("DBCS fonts like '%s' are not working correctly now.\n", fullname);
    }
 
    fi->df.dfCharSet = ANSI_CHARSET;
@@ -627,24 +722,45 @@ static int LFD_InitFontInfo( fontInfo* fi, const LFD* lfd, LPCSTR fullname )
               {
                   if( !strcasecmp(lfd->charset_encoding, boba->sufch[j].psuffix ))
                   {
-                      fi->df.dfCharSet = boba->sufch[j].charset;
+                      fi->df.dfCharSet = (BYTE)(boba->sufch[j].charset & 0xff);
+                      fi->internal_charset = boba->sufch[j].charset;
+                      fi->codepage = boba->sufch[j].codepage;
+                      fi->cptable = boba->sufch[j].cptable;
                       goto done;
                   }
               }
-              if (boba->prefix)
-              {
-                  WARN("font '%s' has unknown character encoding '%s'\n",
-                       fullname, lfd->charset_encoding);
-                  fi->df.dfCharSet = boba->sufch[j].charset;
-                  j = 254;
-                  goto done;
-              }
+
+               fi->df.dfCharSet = (BYTE)(boba->sufch[j].charset & 0xff);
+               fi->internal_charset = boba->sufch[j].charset;
+               fi->codepage = boba->sufch[j].codepage;
+               fi->cptable = boba->sufch[j].cptable;
+               if (boba->prefix)
+               {
+                  FIXME("font '%s' has unknown character encoding '%s' in known registry '%s'\n",
+                       fullname, lfd->charset_encoding, boba->prefix);
+                  j = 254;
+               }
+               else
+               {
+                  FIXME("font '%s' has unknown registry '%s' and character encoding '%s' \n",
+                       fullname, lfd->charset_registry, lfd->charset_encoding);
+                  j = 255;
+               }
+
+               WARN("Defaulting to: df.dfCharSet = %d,  internal_charset = %d, codepage = %d, cptable = %d\n",
+                    fi->df.dfCharSet,fi->internal_charset, fi->codepage, fi->cptable);
+               goto done;
           }
           else if (boba->prefix)
           {
+               WARN("font '%s' has known registry '%s' and no character encoding\n",
+                    fullname, lpstr);
               for( j = 0; boba->sufch[j].psuffix; j++ )
                   ;
-              fi->df.dfCharSet = boba->sufch[j].charset;
+              fi->df.dfCharSet = (BYTE)(boba->sufch[j].charset & 0xff);
+              fi->internal_charset = boba->sufch[j].charset;
+              fi->codepage = boba->sufch[j].codepage;
+              fi->cptable = boba->sufch[j].cptable;
               j = 255;
               goto done;
           }
@@ -657,8 +773,8 @@ done:
    /* i - index into fETTable
     * j - index into suffix array for fETTable[i]
     *     except:
-    *     254 - unknown suffix
-    *     255 - no suffix at all.
+    *     254 - found encoding prefix, unknown suffix
+    *     255 - no encoding match at all.
     */
    fi->fi_encoding = 256 * (UINT16)i + (UINT16)j;
 
@@ -814,7 +930,9 @@ static BOOL LFD_ComposeLFD( const fontObject* fo,
               sprintf(resy_string,  "%d", resy);
           }
           else
-              ; /* FIXME - synth width */
+          {
+              /* FIXME - synth width */
+           }
        }          
        aLFD.resolution_y = resy_string;
    }
@@ -947,7 +1065,8 @@ static INT XFONT_GetAvgCharWidth( LPIFONTINFO16 pFI, const XFontStruct* x_fs,
     if( x_fs->per_char )
     {
        int  width = 0, chars = 0, j;
-       if( IS_LATIN_CHARSET(pFI->dfCharSet))
+       if( IS_LATIN_CHARSET(pFI->dfCharSet) ||
+           pFI->dfCharSet == DEFAULT_CHARSET )
        {
            /* FIXME - should use a weighted average */
            for( j = 0; j < 26; j++ )
@@ -964,7 +1083,8 @@ static INT XFONT_GetAvgCharWidth( LPIFONTINFO16 pFI, const XFontStruct* x_fs,
                    chars++;
                }
        }
-       avg = (width + (chars>>1))/ chars;
+       if (chars) avg = (width + (chars>>1))/ chars;
+       else       avg = 0; /* No characters exist at all */ 
     }
     else /* uniform width */
        avg = x_fs->min_bounds.width;
@@ -1031,66 +1151,6 @@ static void XFONT_SetFontMetric(fontInfo* fi, const fontResource* fr, XFontStruc
     fi->df.dfFace = fr->lfFaceName;
 }
 
-/***********************************************************************
- *              XFONT_GetTextMetrics
- *
- * GetTextMetrics() back end.
- */
-static void XFONT_GetTextMetrics( const fontObject* pfo, const LPTEXTMETRICA pTM )
-{
-    LPIFONTINFO16 pdf = &pfo->fi->df;
-
-    if( ! pfo->lpX11Trans ) {
-      pTM->tmAscent = pfo->fs->ascent;
-      pTM->tmDescent = pfo->fs->descent;
-    } else {
-      pTM->tmAscent = pfo->lpX11Trans->ascent;
-      pTM->tmDescent = pfo->lpX11Trans->descent;
-    }
-
-    pTM->tmAscent *= pfo->rescale;
-    pTM->tmDescent *= pfo->rescale;
-
-    pTM->tmHeight = pTM->tmAscent + pTM->tmDescent;
-
-    pTM->tmAveCharWidth = pfo->foAvgCharWidth * pfo->rescale;
-    pTM->tmMaxCharWidth = pfo->foMaxCharWidth * pfo->rescale;
-
-    pTM->tmInternalLeading = pfo->foInternalLeading * pfo->rescale;
-    pTM->tmExternalLeading = pdf->dfExternalLeading * pfo->rescale;
-
-    pTM->tmStruckOut = (pfo->fo_flags & FO_SYNTH_STRIKEOUT )
-                       ? 1 : pdf->dfStrikeOut;
-    pTM->tmUnderlined = (pfo->fo_flags & FO_SYNTH_UNDERLINE )
-                       ? 1 : pdf->dfUnderline;
-
-    pTM->tmOverhang = 0;
-    if( pfo->fo_flags & FO_SYNTH_ITALIC ) 
-    {
-       pTM->tmOverhang += pTM->tmHeight/3;
-       pTM->tmItalic = 1;
-    } else 
-       pTM->tmItalic = pdf->dfItalic;
-
-    pTM->tmWeight = pdf->dfWeight;
-    if( pfo->fo_flags & FO_SYNTH_BOLD ) 
-    {
-       pTM->tmOverhang++; 
-       pTM->tmWeight += 100;
-    } 
-
-    pTM->tmFirstChar = pdf->dfFirstChar;
-    pTM->tmLastChar = pdf->dfLastChar;
-    pTM->tmDefaultChar = pdf->dfDefaultChar;
-    pTM->tmBreakChar = pdf->dfBreakChar;
-
-    pTM->tmCharSet = pdf->dfCharSet;
-    pTM->tmPitchAndFamily = pdf->dfPitchAndFamily;
-
-    pTM->tmDigitizedAspectX = pdf->dfHorizRes;
-    pTM->tmDigitizedAspectY = pdf->dfVertRes;
-}
-
 /***********************************************************************
  *              XFONT_GetFontMetric
  *
@@ -1270,7 +1330,7 @@ static void XFONT_WindowsNames(void)
            }
 
        lpch = fr->lfFaceName;
-       wsnprintfA( fr->lfFaceName, sizeof(fr->lfFaceName), "%s %s",
+       snprintf( fr->lfFaceName, sizeof(fr->lfFaceName), "%s %s",
                                          /* prepend vendor name */
                                          (pfr==fr) ? "" : fr->resource->foundry,
                                          fr->resource->family);
@@ -1341,7 +1401,7 @@ static void XFONT_LoadDefault(LPCSTR ini, LPCSTR fonttype)
                XFONT_LoadDefaultLFD(lfd, fonttype);
            else
                WARN("Ini section [%s]%s is malformed\n", INIFontSection, ini);
-           HeapFree(SystemHeap, 0, lfd);
+           HeapFree(GetProcessHeap(), 0, lfd);
        }
     }   
 }
@@ -1375,9 +1435,9 @@ static fontAlias* XFONT_CreateAlias( LPCSTR lpTypeFace, LPCSTR lpAlias )
        prev = pfa;
     }
 
-    j = lstrlenA(lpTypeFace) + 1;
-    pfa = HeapAlloc( SystemHeap, 0, sizeof(fontAlias) +
-                              j + lstrlenA(lpAlias) + 1 );
+    j = strlen(lpTypeFace) + 1;
+    pfa = HeapAlloc( GetProcessHeap(), 0, sizeof(fontAlias) +
+                              j + strlen(lpAlias) + 1 );
     if (pfa)
     {
         if (!prev)
@@ -1387,11 +1447,11 @@ static fontAlias* XFONT_CreateAlias( LPCSTR lpTypeFace, LPCSTR lpAlias )
     
        pfa->next = NULL;
        pfa->faTypeFace = (LPSTR)(pfa + 1);
-       lstrcpyA( pfa->faTypeFace, lpTypeFace );
+       strcpy( pfa->faTypeFace, lpTypeFace );
        pfa->faAlias = pfa->faTypeFace + j;
-       lstrcpyA( pfa->faAlias, lpAlias );
+       strcpy( pfa->faAlias, lpAlias );
 
-        TRACE("added alias '%s' for %s\n", lpAlias, lpTypeFace );
+        TRACE("added alias '%s' for '%s'\n", lpAlias, lpTypeFace );
 
        return pfa;
     }
@@ -1444,11 +1504,11 @@ static void XFONT_LoadAlias(const LFD* lfd, LPCSTR lpAlias, BOOL bSubst)
 
                /* Update any references to the substituted font in aliasTable */
                if(!strcmp(frMatch->lfFaceName, pfa->faTypeFace))
-                   pfa->faTypeFace = HEAP_strdupA( SystemHeap, 0, lpAlias );
+                   pfa->faTypeFace = HEAP_strdupA( GetProcessHeap(), 0, lpAlias );
                prev = pfa;
            }
                                                
-           TRACE("\tsubstituted '%s' with %s\n", frMatch->lfFaceName, lpAlias );
+           TRACE("\tsubstituted '%s' with '%s'\n", frMatch->lfFaceName, lpAlias );
                
            lstrcpynA( frMatch->lfFaceName, lpAlias, LF_FACESIZE );
            frMatch->fr_flags |= FR_NAMESET;
@@ -1470,7 +1530,7 @@ static void XFONT_LoadAlias(const LFD* lfd, LPCSTR lpAlias, BOOL bSubst)
  *
  * INIT ONLY 
  *
- * Create font aliases for some standard windows fonts using users
+ * Create font aliases for some standard windows fonts using user's
  * default choice of (sans-)serif fonts
  *
  * Read user-defined aliases from wine.conf. Format is as follows
@@ -1482,7 +1542,7 @@ static void XFONT_LoadAlias(const LFD* lfd, LPCSTR lpAlias, BOOL bSubst)
  *   Alias1 = Times New Roman, -bitstream-courier-, 1
  *   ...
  *
- * Note that from 081797 and on we have built-in alias templates that take
+ * Note that from 970817 and on we have built-in alias templates that take
  * care of the necessary Windows typefaces.
  */
 typedef struct
@@ -1511,7 +1571,7 @@ static void XFONT_LoadAliases(void)
        XFONT_LoadAlias( lfd, "Times New Roman", FALSE);
 
        XFONT_LoadDefaultLFD( lfd, "serif ");
-       HeapFree(SystemHeap, 0, lfd);
+       HeapFree(GetProcessHeap(), 0, lfd);
     }
        
     PROFILE_GetWineIniString( INIFontSection, INIDefaultSansSerif,
@@ -1525,7 +1585,7 @@ static void XFONT_LoadAliases(void)
        XFONT_LoadAlias( lfd, "Arial", FALSE);
 
        XFONT_LoadDefaultLFD( lfd, "sans serif ");
-       HeapFree(SystemHeap, 0, lfd);
+       HeapFree(GetProcessHeap(), 0, lfd);
     }
 
     /* then user specified aliases */
@@ -1533,7 +1593,7 @@ static void XFONT_LoadAliases(void)
     {
         BOOL bHaveAlias, bSubst;
        char subsection[32];
-        wsnprintfA( subsection, sizeof subsection, "%s%i", INIAliasSection, i++ );
+        snprintf( subsection, sizeof subsection, "%s%i", INIAliasSection, i++ );
 
        bHaveAlias = PROFILE_GetWineIniString( INIFontSection, 
                                                subsection, "", buffer, sizeof buffer);
@@ -1549,7 +1609,7 @@ static void XFONT_LoadAliases(void)
            if (lfd)
            {
                XFONT_LoadAlias(lfd, buffer, bSubst);
-               HeapFree(SystemHeap, 0, lfd);
+               HeapFree(GetProcessHeap(), 0, lfd);
            }
        }
        else
@@ -1589,7 +1649,7 @@ static LPCSTR XFONT_UnAlias(char* font)
  *
  * Caller should check if the font resource is in use. If it is it should
  * set FR_REMOVED flag to delay removal until the resource is not in use
- * anymore.
+ * any more.
  */
 void XFONT_RemoveFontResource( fontResource** ppfr )
 {
@@ -1601,10 +1661,10 @@ void XFONT_RemoveFontResource( fontResource** ppfr )
     while( pfr->fi )
     {
        pfi = pfr->fi->next;
-       HeapFree( SystemHeap, 0, pfr->fi );
+       HeapFree( GetProcessHeap(), 0, pfr->fi );
        pfr->fi = pfi;
     }
-    HeapFree( SystemHeap, 0, pfr );
+    HeapFree( GetProcessHeap(), 0, pfr );
 #endif
     *ppfr = pfr->next;
 }
@@ -1647,7 +1707,7 @@ static void XFONT_LoadIgnore(char* lfdname)
     else
        WARN("Malformed font resource\n");
     
-    HeapFree(SystemHeap, 0, lfd);
+    HeapFree(GetProcessHeap(), 0, lfd);
 }
 
 static void XFONT_LoadIgnores(void)
@@ -1663,7 +1723,7 @@ static void XFONT_LoadIgnores(void)
     /* Others from INI file */
     do
     {
-       wsprintfA( subsection, "%s%i", INIIgnoreSection, i++ );
+       sprintf( subsection, "%s%i", INIIgnoreSection, i++ );
 
        if( PROFILE_GetWineIniString( INIFontSection,
                                      subsection, "", buffer, sizeof buffer) )
@@ -1682,26 +1742,22 @@ static void XFONT_LoadIgnores(void)
  *           XFONT_UserMetricsCache
  * 
  * Returns expanded name for the cachedmetrics file.
- * Now it also appends the current value of the $DISPLAY varaible.
+ * Now it also appends the current value of the $DISPLAY variable.
  */
 static char* XFONT_UserMetricsCache( char* buffer, int* buf_size )
 {
-    char* pchDisplay, *home;
+    const char *confdir = get_config_dir();
+    const char *display_name = Options.display;
+    int len = strlen(confdir) + strlen(INIFontMetrics) + strlen(display_name) + 2;
 
-    pchDisplay = getenv( "DISPLAY" );
-    if( !pchDisplay ) pchDisplay = "0";
-
-    if ((home = getenv( "HOME" )) != NULL)
+    if ((len > *buf_size) &&
+        !(buffer = HeapReAlloc( GetProcessHeap(), 0, buffer, *buf_size = len )))
     {
-       int i = strlen( home ) + strlen( INIWinePrefix ) + 
-               strlen( INIFontMetrics ) + strlen( pchDisplay ) + 2;
-       if( i > *buf_size ) 
-           buffer = (char*) HeapReAlloc( SystemHeap, 0, buffer, *buf_size = i );
-       strcpy( buffer, home );
-       strcat( buffer, INIWinePrefix );
-       strcat( buffer, INIFontMetrics );
-       strcat( buffer, pchDisplay );
-    } else buffer[0] = '\0';
+        ERR("out of memory\n");
+        ExitProcess(1);
+    }
+
+    sprintf( buffer, "%s/%s%s", confdir, INIFontMetrics, display_name );
     return buffer;
 }
 
@@ -1759,7 +1815,7 @@ static void XFONT_CheckFIList( fontResource* fr, fontInfo* fi, int action)
            fr->fi_count--;
             if( prev ) prev->next = pfi = pfi->next;
             else fr->fi = pfi = pfi->next;
-           HeapFree( SystemHeap, 0, subset );
+           HeapFree( GetProcessHeap(), 0, subset );
            continue;
         }
     }
@@ -1820,6 +1876,7 @@ static int XFONT_BuildMetrics(char** x_pattern, int res, unsigned x_checksum, in
 {
     int                  i;
     fontInfo*    fi = NULL;
+    fontResource* fr, *pfr;
     int           n_ff = 0;
 
     MESSAGE("Building font metrics. This may take some time...\n");
@@ -1827,21 +1884,20 @@ static int XFONT_BuildMetrics(char** x_pattern, int res, unsigned x_checksum, in
     {
        char*         typeface;
        LFD*          lfd;
-       fontResource* fr, *pfr;
        int           j;
        char          buffer[MAX_LFD_LENGTH];
        char*         lpstr;
        XFontStruct*  x_fs;
        fontInfo*    pfi;
 
-       typeface = HEAP_strdupA(SystemHeap, 0, x_pattern[i]);
+       typeface = HEAP_strdupA(GetProcessHeap(), 0, x_pattern[i]);
        if (!typeface)
            break;
 
        lfd = LFD_Parse(typeface);
        if (!lfd)
        {
-           HeapFree(SystemHeap, 0, typeface);
+           HeapFree(GetProcessHeap(), 0, typeface);
            continue;
        }
 
@@ -1854,7 +1910,7 @@ static int XFONT_BuildMetrics(char** x_pattern, int res, unsigned x_checksum, in
            pfr = fr;
        }  
        
-       if( !fi ) fi = (fontInfo*) HeapAlloc(SystemHeap, 0, sizeof(fontInfo));
+       if( !fi ) fi = (fontInfo*) HeapAlloc(GetProcessHeap(), 0, sizeof(fontInfo));
        
        if( !LFD_InitFontInfo( fi, lfd, x_pattern[i]) )
            goto nextfont;
@@ -1862,17 +1918,17 @@ static int XFONT_BuildMetrics(char** x_pattern, int res, unsigned x_checksum, in
        if( !fr ) /* add new family */
        {
            n_ff++;
-           fr = (fontResource*) HeapAlloc(SystemHeap, 0, sizeof(fontResource)); 
+           fr = (fontResource*) HeapAlloc(GetProcessHeap(), 0, sizeof(fontResource)); 
            if (fr)
            {
                memset(fr, 0, sizeof(fontResource));
              
-               fr->resource = (LFD*) HeapAlloc(SystemHeap, 0, sizeof(LFD)); 
+               fr->resource = (LFD*) HeapAlloc(GetProcessHeap(), 0, sizeof(LFD)); 
                memset(fr->resource, 0, sizeof(LFD));
              
                TRACE("family: -%s-%s-\n", lfd->foundry, lfd->family );
-               fr->resource->foundry = HEAP_strdupA(SystemHeap, 0, lfd->foundry);
-               fr->resource->family = HEAP_strdupA(SystemHeap, 0, lfd->family);
+               fr->resource->foundry = HEAP_strdupA(GetProcessHeap(), 0, lfd->foundry);
+               fr->resource->family = HEAP_strdupA(GetProcessHeap(), 0, lfd->family);
                fr->resource->weight = "";
 
                if( pfr ) pfr->next = fr;
@@ -1934,11 +1990,50 @@ static int XFONT_BuildMetrics(char** x_pattern, int res, unsigned x_checksum, in
            XFONT_CheckFIList( fr, fi, UNMARK_SUBSETS );
        }
     nextfont:
-       HeapFree(SystemHeap, 0, lfd);
-       HeapFree(SystemHeap, 0, typeface);
+       HeapFree(GetProcessHeap(), 0, lfd);
+       HeapFree(GetProcessHeap(), 0, typeface);
     }
-    if( fi ) HeapFree(SystemHeap, 0, fi);
-
+    if( fi ) HeapFree(GetProcessHeap(), 0, fi);
+
+    /* Scan through the font list and remove FontResorce(s) (fr) 
+     * that have no associated Fontinfo(s) (fi). 
+     * This code is necessary because XFONT_ReadCachedMetrics
+     * assumes that there is at least one fi associated with a fr.  
+     * This assumption is invalid for TT font
+     *  -altsys-ms outlook-medium-r-normal--0-0-0-0-p-0-microsoft-symbol.
+     */
+    
+    fr = fontList;
+    
+    while (!fr->fi_count) 
+    {
+       fontList = fr->next;
+    
+       HeapFree(GetProcessHeap(), 0, fr->resource);
+       HeapFree(GetProcessHeap(), 0, fr);
+       
+       fr = fontList;
+       n_ff--;
+    }
+           
+    fr = fontList;
+    
+    while (fr->next)
+    {
+       if (!fr->next->fi_count)
+       {
+           pfr = fr->next;
+           fr->next = fr->next->next;
+                           
+           HeapFree(GetProcessHeap(), 0, pfr->resource);
+           HeapFree(GetProcessHeap(), 0, pfr);
+       
+           n_ff--;
+       }
+       else 
+           fr = fr->next; 
+    }  
+         
     return n_ff;
 }
 
@@ -1969,7 +2064,7 @@ static BOOL XFONT_ReadCachedMetrics( int fd, int res, unsigned x_checksum, int x
            if( length == (i + offset) )
            {
                lseek( fd, offset, SEEK_SET );
-               fontList = (fontResource*)HeapAlloc( SystemHeap, 0, i);
+               fontList = (fontResource*)HeapAlloc( GetProcessHeap(), 0, i);
                if( fontList )
                {
                    fontResource*       pfr = fontList;
@@ -1986,8 +2081,11 @@ static BOOL XFONT_ReadCachedMetrics( int fd, int res, unsigned x_checksum, int x
                        while( TRUE )
                        {
                           if( offset > length ||
+                              pfi->cptable >= (UINT16)X11DRV_CPTABLE_COUNT ||
                              (int)(pfi->next) != j++ ) goto fail;
 
+                          if( pfi->df.dfPixHeight == 0 ) goto fail;
+
                           pfi->df.dfFace = pfr->lfFaceName;
                           if( pfi->fi_flags & FI_SCALABLE )
                           {
@@ -2033,7 +2131,7 @@ static BOOL XFONT_ReadCachedMetrics( int fd, int res, unsigned x_checksum, int x
            }
        }
 fail:
-       if( fontList ) HeapFree( SystemHeap, 0, fontList );
+       if( fontList ) HeapFree( GetProcessHeap(), 0, fontList );
        fontList = NULL;
        close( fd );
     }
@@ -2120,83 +2218,6 @@ static BOOL XFONT_WriteCachedMetrics( int fd, unsigned x_checksum, int x_count,
     return FALSE;
 }
 
-/***********************************************************************
- *           XFONT_CheckIniSection
- *
- * INIT ONLY
- *
- *   Examines wine.conf for old/invalid font entries and recommend changes to
- *   the user.
- *
- *   Revision history
- *        05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
- *             Original implementation.
- */
-static void XFONT_CheckIniCallback(char const *, char const *, void *);
-
-static char const  *fontmsgprologue =
-"Wine warning:\n"
-"   The following entries in the [fonts] section of the wine.conf file are\n"
-"   obsolete or invalid:\n";
-
-static char const  *fontmsgepilogue =
-"   These entries should be eliminated or updated.\n"
-"   See the documentation/fonts file for more information.\n";
-
-static int XFONT_CheckIniSection(void)
-{
-    int  found = 0;
-
-    PROFILE_EnumerateWineIniSection("Fonts", &XFONT_CheckIniCallback,
-                    (void *)&found);
-    if(found)
-       MESSAGE(fontmsgepilogue);
-
-    return 1;
-}
-
-static void  XFONT_CheckIniCallback(
-    char const  *key,
-    char const  *value,
-    void  *found)
-{
-    /* Ignore any keys that start with potential comment characters "'", '#',
-       or ';'. */
-    if(key[0] == '\'' || key[0] == '#' || key[0] == ';' || key[0] == '\0')
-       return;
-
-    /* Make sure this is a valid key */
-    if((strncasecmp(key, INIAliasSection, 5) == 0) ||
-       (strncasecmp(key, INIIgnoreSection, 6) == 0) ||
-       (strcasecmp( key, INIDefault) == 0) ||
-       (strcasecmp( key, INIDefaultFixed) == 0) ||
-       (strcasecmp( key, INIGlobalMetrics) == 0) ||
-       (strcasecmp( key, INIResolution) == 0) ||
-       (strcasecmp( key, INIDefaultSerif) == 0) ||
-       (strcasecmp( key, INIDefaultSansSerif) ==0) )
-    {
-       /* Valid key; make sure the value doesn't contain a wildcard */
-       if(strchr(value, '*')) {
-           if(*(int *)found == 0) {
-               MESSAGE(fontmsgprologue);
-               ++*(int *)found;
-           }
-           MESSAGE("     %s=%s [no wildcards allowed]\n", key, value);
-       }
-    }
-    else {
-       /* Not a valid key */
-       if(*(int *)found == 0) {
-           MESSAGE(fontmsgprologue);
-           ++*(int *)found;
-       }
-       
-       MESSAGE("     %s=%s [obsolete]\n", key, value);
-    }
-
-    return;
-}
-
 /***********************************************************************
  *           XFONT_GetPointResolution()
  *
@@ -2281,12 +2302,33 @@ static UINT XFONT_Match( fontMatch* pfm )
    pfm->flags &= FO_MATCH_MASK;
 
 /* Charset */
-   if( plf->lfCharSet == DEFAULT_CHARSET )
+   /* pfm->internal_charset: given(required) charset */
+   /* pfi->internal_charset: charset of this font */
+   if (pfi->internal_charset == DEFAULT_CHARSET)
+   {
+      /* special case(unicode font) */
+      /* priority: unmatched charset < unicode < matched charset */
+      penalty += 0x50;
+   }
+   else
    {
-       if( (pfi->df.dfCharSet != ANSI_CHARSET) && (pfi->df.dfCharSet != DEFAULT_CHARSET) ) 
+     if( pfm->internal_charset == DEFAULT_CHARSET )
+     {
+       /*
+         if (pfi->internal_charset != ANSI_CHARSET)
+           penalty += 0x200;
+       */
+       if ( pfi->codepage != GetACP() )
            penalty += 0x200;
+     }
+     else if (pfm->internal_charset != pfi->internal_charset)
+     {
+       if ( pfi->internal_charset & 0xff00 )
+         penalty += 0x1000; /* internal charset - should not be used */
+       else
+         penalty += 0x200;
+     }
    }
-   else if (plf->lfCharSet != pfi->df.dfCharSet) penalty += 0x200;
 
 /* Height */
    height = -1;
@@ -2460,6 +2502,24 @@ static void XFONT_MatchDeviceFont( fontResource* start, fontMatch* pfm)
                    return;
            }
        }
+
+       /* get charset if lfFaceName is one of known facenames. */
+       {
+           const struct CharsetBindingInfo* pcharsetbindings;
+
+           pcharsetbindings = &charsetbindings[0];
+           while ( pcharsetbindings->pszFaceName != NULL )
+           {
+               if ( !strcmp( pcharsetbindings->pszFaceName,
+                             fm.plf->lfFaceName ) )
+               {
+                   fm.internal_charset = pcharsetbindings->charset;
+                   break;
+               }
+               pcharsetbindings ++;
+           }
+           TRACE( "%s charset %u\n", fm.plf->lfFaceName, fm.internal_charset );
+       }
     }
 
     /* match all available fonts */
@@ -2576,7 +2636,7 @@ static fontObject* XFONT_GetCacheEntry(void)
 
            /* FIXME: lpXForm, lpPixmap */
            if(fontCache[j].lpX11Trans)
-               HeapFree( SystemHeap, 0, fontCache[j].lpX11Trans );
+               HeapFree( GetProcessHeap(), 0, fontCache[j].lpX11Trans );
 
            TSXFreeFont( display, fontCache[j].fs );
 
@@ -2591,7 +2651,7 @@ static fontObject* XFONT_GetCacheEntry(void)
 
            TRACE("\tgrowing font cache from %i to %i\n", fontCacheSize, prev_i );
 
-           if( (newCache = (fontObject*)HeapReAlloc(SystemHeap, 0,  
+           if( (newCache = (fontObject*)HeapReAlloc(GetProcessHeap(), 0,  
                                                     fontCache, prev_i)) )
            {
                i = fontCacheSize;
@@ -2614,8 +2674,24 @@ static fontObject* XFONT_GetCacheEntry(void)
 static int XFONT_ReleaseCacheEntry(const fontObject* pfo)
 {
     UINT       u = (UINT)(pfo - fontCache);
+    int        i;
+    int        ret;
+
+    if( u < fontCacheSize )
+    {
+       ret = --fontCache[u].count;
+       if ( ret == 0 )
+       {
+           for ( i = 0; i < X11FONT_REFOBJS_MAX; i++ )
+           {
+               if( CHECK_PFONT(pfo->prefobjs[i]) )
+                   XFONT_ReleaseCacheEntry(__PFONT(pfo->prefobjs[i]));
+           }
+       }
+
+       return ret;
+    }
 
-    if( u < fontCacheSize ) return (--fontCache[u].count);
     return -1;
 }
 
@@ -2631,8 +2707,6 @@ BOOL X11DRV_FONT_Init( DeviceCaps* pDevCaps )
   int       i,res, x_count, fd, buf_size;
   char      *buffer;
 
-  XFONT_CheckIniSection();
-
   res = XFONT_GetPointResolution( pDevCaps );
       
   x_pattern = TSXListFonts(display, "*", MAX_FONTS, &x_count );
@@ -2654,7 +2728,7 @@ BOOL X11DRV_FONT_Init( DeviceCaps* pDevCaps )
   }
   x_checksum |= X_PFONT_MAGIC;
   buf_size = 128;
-  buffer = HeapAlloc( SystemHeap, 0, buf_size );
+  buffer = HeapAlloc( GetProcessHeap(), 0, buf_size );
 
   /* deal with systemwide font metrics cache */
 
@@ -2700,19 +2774,16 @@ BOOL X11DRV_FONT_Init( DeviceCaps* pDevCaps )
          TSXFreeFont(display, x_fs);
       }
   }
-  HeapFree(SystemHeap, 0, buffer);
+  HeapFree(GetProcessHeap(), 0, buffer);
 
   XFONT_WindowsNames();
   XFONT_LoadAliases();
   XFONT_LoadDefaults();
   XFONT_LoadIgnores();
 
-  InitializeCriticalSection( &crtsc_fonts_X11 );
-  MakeCriticalSectionGlobal( &crtsc_fonts_X11 );
-
   /* fontList initialization is over, allocate X font cache */
 
-  fontCache = (fontObject*) HeapAlloc(SystemHeap, 0, fontCacheSize * sizeof(fontObject));
+  fontCache = (fontObject*) HeapAlloc(GetProcessHeap(), 0, fontCacheSize * sizeof(fontObject));
   XFONT_GrowFreeList(0, fontCacheSize - 1);
 
   TRACE("done!\n");
@@ -2746,7 +2817,7 @@ static BOOL XFONT_SetX11Trans( fontObject *pfo )
   }
 
   if (lfd->pixel_size[0] != '[') {
-      HeapFree(SystemHeap, 0, lfd);
+      HeapFree(GetProcessHeap(), 0, lfd);
       TSXFree(fontName);
       return FALSE;
   }
@@ -2755,7 +2826,7 @@ static BOOL XFONT_SetX11Trans( fontObject *pfo )
 
   sscanf(lfd->pixel_size, "[%f%f%f%f]", &PX->a, &PX->b, &PX->c, &PX->d);
   TSXFree(fontName);
-  HeapFree(SystemHeap, 0, lfd);
+  HeapFree(GetProcessHeap(), 0, lfd);
 
   TSXGetFontProperty( pfo->fs, RAW_ASCENT, &PX->RAW_ASCENT );
   TSXGetFontProperty( pfo->fs, RAW_DESCENT, &PX->RAW_DESCENT );
@@ -2775,7 +2846,10 @@ static BOOL XFONT_SetX11Trans( fontObject *pfo )
 /***********************************************************************
  *           X Device Font Objects
  */
-static X_PHYSFONT XFONT_RealizeFont( const LPLOGFONT16 plf, LPCSTR* faceMatched)
+static X_PHYSFONT XFONT_RealizeFont( const LPLOGFONT16 plf,
+                                    LPCSTR* faceMatched, BOOL bSubFont,
+                                    WORD internal_charset,
+                                    WORD* pcharsetMatched )
 {
     UINT16     checksum;
     INT         index = 0;
@@ -2792,6 +2866,7 @@ static X_PHYSFONT XFONT_RealizeFont( const LPLOGFONT16 plf, LPCSTR* faceMatched)
        fm.height = 0;
        fm.flags = 0;
        fm.plf = plf;
+       fm.internal_charset = internal_charset;
 
        if( XTextCaps & TC_SF_X_YINDEP ) fm.flags = FO_MATCH_XYINDEP;
 
@@ -2830,9 +2905,9 @@ static X_PHYSFONT XFONT_RealizeFont( const LPLOGFONT16 plf, LPCSTR* faceMatched)
 
                
            if(pfo->lf.lfEscapement != 0) {
-               pfo->lpX11Trans = HeapAlloc(SystemHeap, 0, sizeof(XFONTTRANS));
+               pfo->lpX11Trans = HeapAlloc(GetProcessHeap(), 0, sizeof(XFONTTRANS));
                if(!XFONT_SetX11Trans( pfo )) {
-                   HeapFree(SystemHeap, 0, pfo->lpX11Trans);
+                   HeapFree(GetProcessHeap(), 0, pfo->lpX11Trans);
                    pfo->lpX11Trans = NULL;
                }
            }
@@ -2854,8 +2929,43 @@ static X_PHYSFONT XFONT_RealizeFont( const LPLOGFONT16 plf, LPCSTR* faceMatched)
             */
 
            pfo->lpPixmap = NULL;
+
+           for ( i = 0; i < X11FONT_REFOBJS_MAX; i++ )
+               pfo->prefobjs[i] = (X_PHYSFONT)0xffffffff; /* invalid value */
+
+            /* special treatment for DBCS that needs multiple fonts */
+            /* All member of pfo must be set correctly. */
+           if ( bSubFont == FALSE )
+           {
+               WORD charset_sub;
+               WORD charsetMatchedSub;
+               LOGFONT16 lfSub;
+               LPCSTR faceMatchedSub;
+
+               for ( i = 0; i < X11FONT_REFOBJS_MAX; i++ )
+               {
+                   charset_sub = X11DRV_cptable[pfo->fi->cptable].
+                               penum_subfont_charset( i );
+                   if ( charset_sub == DEFAULT_CHARSET ) break;
+
+                   lfSub = *plf;
+                   lfSub.lfWidth = 0;
+                   lfSub.lfHeight = pfo->fi->df.dfPixHeight;
+                   if ( plf->lfHeight < 0 )
+                       lfSub.lfHeight = - lfSub.lfHeight;
+                   lfSub.lfCharSet = (BYTE)(charset_sub & 0xff);
+                   lfSub.lfFaceName[0] = '\0'; /* FIXME? */
+                   /* this font has sub font */
+                   if ( i == 0 ) pfo->prefobjs[0] = (X_PHYSFONT)0;
+                   pfo->prefobjs[i] =
+                       XFONT_RealizeFont( &lfSub, &faceMatchedSub,
+                                          TRUE, charset_sub,
+                                          &charsetMatchedSub );
+                   /* FIXME: check charsetMatchedSub */
+               }
+           }
        }
-       
+
        if( !pfo ) /* couldn't get a new entry, get one of the cached fonts */
        {
            UINT                current_score, score = (UINT)(-1);
@@ -2886,6 +2996,7 @@ END:
 
     TRACE("physfont %i\n", index);
     *faceMatched = pfo->fi->df.dfFace;
+    *pcharsetMatched = pfo->fi->internal_charset;
 
     return (X_PHYSFONT)(X_PFONT_MAGIC | index);
 }
@@ -2944,35 +3055,31 @@ HFONT X11DRV_FONT_SelectObject( DC* dc, HFONT hfont, FONTOBJ* font )
     /* FIXME - check that the other drivers do this correctly */
     if (lf.lfWidth)
     {
-       int vpt = abs(dc->vportExtX);
-       int wnd = abs(dc->wndExtX);
-       lf.lfWidth = (abs(lf.lfWidth) * vpt + (wnd>>1))/wnd;
+       lf.lfWidth = GDI_ROUND((FLOAT)lf.lfWidth * fabs(dc->xformWorld2Vport.eM11));
        if (lf.lfWidth == 0)
            lf.lfWidth = 1; /* Minimum width */
     }
     if (lf.lfHeight)
     {
-       int vpt = abs(dc->vportExtY);
-       int wnd = abs(dc->wndExtY);
-       if (lf.lfHeight > 0)
-           lf.lfHeight = (lf.lfHeight * vpt + (wnd>>1))/wnd;
-       else
-           lf.lfHeight = (lf.lfHeight * vpt - (wnd>>1))/wnd;
+       lf.lfHeight = GDI_ROUND((FLOAT)lf.lfHeight * fabs(dc->xformWorld2Vport.eM22));
 
        if (lf.lfHeight == 0)
            lf.lfHeight = MIN_FONT_SIZE;
     }
     else
-       lf.lfHeight = -(DEF_POINT_SIZE * dc->w.devCaps->logPixelsY + (72>>1)) / 72;
+       lf.lfHeight = -(DEF_POINT_SIZE * dc->devCaps->logPixelsY + (72>>1)) / 72;
     
     {
        /* Fixup aliases before passing to RealizeFont */
         /* alias = Windows name in the alias table */
        LPCSTR alias = XFONT_UnAlias( lf.lfFaceName );
        LPCSTR faceMatched;
+       WORD charsetMatched;
 
        TRACE("hfont=%04x\n", hfont); /* to connect with the trace from RealizeFont */
-       physDev->font = XFONT_RealizeFont( &lf, &faceMatched );
+       physDev->font = XFONT_RealizeFont( &lf, &faceMatched,
+                                          FALSE, lf.lfCharSet,
+                                          &charsetMatched );
 
        /* set face to the requested facename if it matched 
         * so that GetTextFace can get the correct face name
@@ -2981,10 +3088,19 @@ HFONT X11DRV_FONT_SelectObject( DC* dc, HFONT hfont, FONTOBJ* font )
            strcpy( font->logfont.lfFaceName, alias );
        else
            strcpy( font->logfont.lfFaceName, faceMatched );
+
+       /*
+        * In X, some encodings may have the same lfFaceName.
+        * for example:
+        *   -misc-fixed-*-iso8859-1
+        *   -misc-fixed-*-jisx0208.1990-0
+        * so charset should be saved...
+        */
+       font->logfont.lfCharSet = charsetMatched;
     }
 
-    hPrevFont = dc->w.hFont;
-    dc->w.hFont = hfont;
+    hPrevFont = dc->hFont;
+    dc->hFont = hfont;
 
     LeaveCriticalSection( &crtsc_fonts_X11 );
 
@@ -2996,7 +3112,7 @@ HFONT X11DRV_FONT_SelectObject( DC* dc, HFONT hfont, FONTOBJ* font )
  *
  *           X11DRV_EnumDeviceFonts
  */
-BOOL   X11DRV_EnumDeviceFonts( DC* dc, LPLOGFONT16 plf, 
+BOOL X11DRV_EnumDeviceFonts( HDC hdc, LPLOGFONT16 plf, 
                                        DEVICEFONTENUMPROC proc, LPARAM lp )
 {
     ENUMLOGFONTEX16    lf;
@@ -3039,56 +3155,6 @@ BOOL     X11DRV_EnumDeviceFonts( DC* dc, LPLOGFONT16 plf,
 }
 
 
-/***********************************************************************
- *           X11DRV_GetTextExtentPoint
- */
-BOOL X11DRV_GetTextExtentPoint( DC *dc, LPCWSTR str, INT count,
-                                  LPSIZE size )
-{
-    X11DRV_PDEVICE *physDev = (X11DRV_PDEVICE *)dc->physDev;
-    fontObject* pfo = XFONT_GetFontObject( physDev->font );
-
-    TRACE("%s %d\n", debugstr_wn(str,count), count);
-    if( pfo ) {
-        if( !pfo->lpX11Trans ) {
-           int dir, ascent, descent, i;
-           XCharStruct info;
-           XChar2b *p = HeapAlloc( GetProcessHeap(), 0,
-                                   count * sizeof(XChar2b) );
-           for(i = 0; i < count; i++) {
-               p[i].byte1 = str[i] >> 8;
-               p[i].byte2 = str[i] & 0xff;
-           }
-           TSXTextExtents16( pfo->fs, p, count, &dir, &ascent, &descent, &info );
-           size->cx = abs((info.width + dc->w.breakRem + count * 
-                           dc->w.charExtra) * dc->wndExtX / dc->vportExtX);
-           size->cy = abs((pfo->fs->ascent + pfo->fs->descent) * 
-                          dc->wndExtY / dc->vportExtY);
-           HeapFree( GetProcessHeap(), 0, p );
-       } else {
-           INT i;
-           float x = 0.0, y = 0.0;
-           for(i = 0; i < count; i++) {
-               x += pfo->fs->per_char ? 
-          pfo->fs->per_char[str[i] - pfo->fs->min_char_or_byte2].attributes : 
-          pfo->fs->min_bounds.attributes;
-           }
-           y = pfo->lpX11Trans->RAW_ASCENT + pfo->lpX11Trans->RAW_DESCENT;
-           TRACE("x = %f y = %f\n", x, y);
-           x *= pfo->lpX11Trans->pixelsize / 1000.0;
-           y *= pfo->lpX11Trans->pixelsize / 1000.0; 
-           size->cx = fabs((x + dc->w.breakRem + count * dc->w.charExtra) *
-                            dc->wndExtX / dc->vportExtX);
-           size->cy = fabs(y * dc->wndExtY / dc->vportExtY);
-       }
-       size->cx *= pfo->rescale;
-       size->cy *= pfo->rescale;
-       return TRUE;
-    }
-    return FALSE;
-}
-
-
 /***********************************************************************
  *           X11DRV_GetTextMetrics
  */
@@ -3099,7 +3165,7 @@ BOOL X11DRV_GetTextMetrics(DC *dc, TEXTMETRICA *metrics)
     if( CHECK_PFONT(physDev->font) )
     {
        fontObject* pfo = __PFONT(physDev->font);
-       XFONT_GetTextMetrics( pfo, metrics );
+       X11DRV_cptable[pfo->fi->cptable].pGetTextMetricsA( pfo, metrics );
 
        return TRUE;
     }
@@ -3144,10 +3210,10 @@ BOOL X11DRV_GetCharWidth( DC *dc, UINT firstChar, UINT lastChar,
                    if (CI_NONEXISTCHAR(cs)) cs = def; 
                } else cs = def;
                if(pfo->lpX11Trans)
-                   *buffer++ = MAX(cs->attributes, 0) *
+                   *buffer++ = max(cs->attributes, 0) *
                      pfo->lpX11Trans->pixelsize / 1000.0 * pfo->rescale;
                else
-                   *buffer++ = MAX(cs->width, 0 ) * pfo->rescale;
+                   *buffer++ = max(cs->width, 0 ) * pfo->rescale;
            }
        }
 
@@ -3155,99 +3221,3 @@ BOOL X11DRV_GetCharWidth( DC *dc, UINT firstChar, UINT lastChar,
     }
     return FALSE;
 }
-
-#endif /* !defined(X_DISPLAY_MISSING) */
-
-/***********************************************************************
- *                                                                    *
- *           Font Resource API                                        *
- *                                                                    *
- ***********************************************************************/
-/***********************************************************************
- *           AddFontResource16    (GDI.119)
- *
- *  Can be either .FON, or .FNT, or .TTF, or .FOT font file.
- *
- *  FIXME: Load header and find the best-matching font in the fontList;
- *        fixup dfPoints if all metrics are identical, otherwise create
- *        new fontAlias. When soft font support is ready this will
- *        simply create a new fontResource ('filename' will go into
- *        the pfr->resource field) with FR_SOFTFONT/FR_SOFTRESOURCE 
- *        flag set. 
- */
-INT16 WINAPI AddFontResource16( LPCSTR filename )
-{
-    return AddFontResourceA( filename );
-}
-
-
-/***********************************************************************
- *           AddFontResource32A    (GDI32.2)
- */
-INT WINAPI AddFontResourceA( LPCSTR str )
-{
-    FIXME("(%s): stub\n", debugres_a(str));
-    return 1;
-}
-
-
-/***********************************************************************
- *           AddFontResource32W    (GDI32.4)
- */
-INT WINAPI AddFontResourceW( LPCWSTR str )
-{
-    FIXME("(%s): stub\n", debugres_w(str) );
-    return 1;
-}
-
-/***********************************************************************
- *           RemoveFontResource16    (GDI.136)
- */
-BOOL16 WINAPI RemoveFontResource16( SEGPTR str )
-{
-    FIXME("(%s): stub\n",      debugres_a(PTR_SEG_TO_LIN(str)));
-    return TRUE;
-}
-
-
-/***********************************************************************
- *           RemoveFontResource32A    (GDI32.284)
- */
-BOOL WINAPI RemoveFontResourceA( LPCSTR str )
-{
-/*  This is how it should look like */
-/*
-    fontResource** ppfr;
-    BOOL32 retVal = FALSE;
-
-    EnterCriticalSection( &crtsc_fonts_X11 );
-    for( ppfr = &fontList; *ppfr; ppfr = &(*ppfr)->next )
-        if( !strcasecmp( (*ppfr)->lfFaceName, str ) )
-        {
-            if(((*ppfr)->fr_flags & (FR_SOFTFONT | FR_SOFTRESOURCE)) &&
-                (*ppfr)->hOwnerProcess == GetCurrentProcess() )
-            {
-                if( (*ppfr)->fo_count )
-                    (*ppfr)->fr_flags |= FR_REMOVED;
-                else
-                    XFONT_RemoveFontResource( ppfr );
-            }
-            retVal = TRUE;
-        }
-    LeaveCriticalSection( &crtsc_fonts_X11 );
-    return retVal;
- */
-    FIXME("(%s): stub\n", debugres_a(str));
-    return TRUE;
-}
-
-
-/***********************************************************************
- *           RemoveFontResource32W    (GDI32.286)
- */
-BOOL WINAPI RemoveFontResourceW( LPCWSTR str )
-{
-    FIXME("(%s): stub\n", debugres_w(str) );
-    return TRUE;
-}
-