Better font charset handling

Huw D M Davies h.davies1 at physics.ox.ac.uk
Wed Sep 19 11:22:45 CDT 2001


	Huw D M Davies <hdavies at codeweavers.com>
	Use the font charset to obtain a codepage for A->W conversion in the
	text functions.

-------------- next part --------------
Index: include/font.h
===================================================================
RCS file: /home/wine/wine/include/font.h,v
retrieving revision 1.6
diff -u -r1.6 font.h
--- include/font.h	2001/09/12 20:21:07	1.6
+++ include/font.h	2001/09/19 15:05:18
@@ -71,6 +71,8 @@
 extern void FONT_NewTextMetricEx16ToW(const NEWTEXTMETRICEX16*, LPNEWTEXTMETRICEXW);
 extern void FONT_EnumLogFontEx16ToW(const ENUMLOGFONTEX16*, LPENUMLOGFONTEXW);
 
+extern LPWSTR FONT_mbtowc(HDC, LPCSTR, INT, INT*, UINT*);
+
 extern DWORD WineEngAddRefFont(GdiFont);
 extern GdiFont WineEngCreateFontInstance(HFONT);
 extern DWORD WineEngDecRefFont(GdiFont);
Index: objects/font.c
===================================================================
RCS file: /home/wine/wine/objects/font.c,v
retrieving revision 1.51
diff -u -r1.51 font.c
--- objects/font.c	2001/09/12 20:21:07	1.51
+++ objects/font.c	2001/09/19 15:05:18
@@ -1032,12 +1032,10 @@
                                      LPSIZE size )
 {
     BOOL ret = FALSE;
-    UINT codepage = CP_ACP; /* FIXME: get codepage of font charset */
-    UINT wlen = MultiByteToWideChar(codepage,0,str,count,NULL,0);
-    LPWSTR p = HeapAlloc( GetProcessHeap(), 0, wlen * sizeof(WCHAR) );
+    INT wlen;
+    LPWSTR p = FONT_mbtowc(hdc, str, count, &wlen, NULL);
 
     if (p) {
-        wlen = MultiByteToWideChar(codepage,0,str,count,p,wlen);
 	ret = GetTextExtentPoint32W( hdc, p, wlen, size );
 	HeapFree( GetProcessHeap(), 0, p );
     }
@@ -1109,11 +1107,9 @@
 				   LPINT alpDx, LPSIZE size )
 {
     BOOL ret;
-
-    DWORD len = MultiByteToWideChar( CP_ACP, 0, str, count, NULL, 0 );
-    LPWSTR p = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
-    MultiByteToWideChar( CP_ACP, 0, str, count, p, len );
-    ret = GetTextExtentExPointW( hdc, p, len, maxExt, lpnFit, alpDx, size);
+    INT wlen;
+    LPWSTR p = FONT_mbtowc( hdc, str, count, &wlen, NULL);
+    ret = GetTextExtentExPointW( hdc, p, wlen, maxExt, lpnFit, alpDx, size);
     HeapFree( GetProcessHeap(), 0, p );
     return ret;
 }
Index: objects/text.c
===================================================================
RCS file: /home/wine/wine/objects/text.c,v
retrieving revision 1.36
diff -u -r1.36 text.c
--- objects/text.c	2001/07/25 00:43:36	1.36
+++ objects/text.c	2001/09/19 15:05:18
@@ -18,10 +18,75 @@
 
 DEFAULT_DEBUG_CHANNEL(text);
 
-
 /***********************************************************************
- *           ExtTextOut    (GDI.351)
+ *           FONT_mbtowc
+ *
+ * Returns a '\0' terminated Unicode translation of str using the
+ * charset of the currently selected font in hdc.  If count is -1 then
+ * str is assumed to be '\0' terminated, otherwise it contains the
+ * number of bytes to convert.  If plenW is non-NULL, on return it
+ * will point to the number of WCHARs (excluding the '\0') that have
+ * been written.  If pCP is non-NULL, on return it will point to the
+ * codepage used in the conversion.  The caller should free the
+ * returned LPWSTR from the process heap itself.
  */
+LPWSTR FONT_mbtowc(HDC hdc, LPCSTR str, INT count, INT *plenW, UINT *pCP)
+{
+    LOGFONTW lf;
+    UINT cp = CP_ACP;
+    INT lenW;
+    LPWSTR strW;
+    CHARSETINFO csi;
+
+    GetObjectW(GetCurrentObject(hdc, OBJ_FONT), sizeof(lf), &lf);
+
+    /* Hmm, nicely designed api this one! */
+    if(TranslateCharsetInfo((DWORD*)(UINT)lf.lfCharSet, &csi, TCI_SRCCHARSET))
+        cp = csi.ciACP;
+    else {
+        switch(lf.lfCharSet) {
+	case SYMBOL_CHARSET:
+	    cp = CP_SYMBOL;
+	    break;
+	case OEM_CHARSET:
+	    cp = GetOEMCP();
+	    break;
+
+	case VISCII_CHARSET:
+	case TCVN_CHARSET:
+	case KOI8_CHARSET:
+	case ISO3_CHARSET:
+	case ISO4_CHARSET:
+	case ISO10_CHARSET:
+	case CELTIC_CHARSET:
+	  /* FIXME: These have no place here, but becasue x11drv
+	     enumerates fonts with these (made up) charsets some apps
+	     might use them and then the FIXME below would become
+	     annoying.  Now we could pick the intended codepage for
+	     each of these, but since it's broken anyway we'll just
+	     use CP_ACP and hope it'll go away...
+	  */
+	    cp = CP_ACP;
+	    break;
+
+
+	default:
+	    FIXME("Can't find codepage for charset %d\n", lf.lfCharSet);
+	    break;
+	}
+    }
+
+    lenW = MultiByteToWideChar(cp, 0, str, count, NULL, 0);
+    strW = HeapAlloc(GetProcessHeap(), 0, (lenW + 1) * sizeof(WCHAR));
+    MultiByteToWideChar(cp, 0, str, count, strW, lenW);
+    strW[lenW] = '\0';
+    if(plenW) *plenW = lenW;
+    if(pCP) *pCP = cp;
+    return strW;
+}
+
+/***********************************************************************
+ *           ExtTextOut (GDI.351) */
 BOOL16 WINAPI ExtTextOut16( HDC16 hdc, INT16 x, INT16 y, UINT16 flags,
                             const RECT16 *lprect, LPCSTR str, UINT16 count,
                             const INT16 *lpDx )
@@ -47,48 +112,34 @@
  *           ExtTextOutA    (GDI32.@)
  */
 BOOL WINAPI ExtTextOutA( HDC hdc, INT x, INT y, UINT flags,
-                             const RECT *lprect, LPCSTR str, UINT count,
-                             const INT *lpDx )
+			 const RECT *lprect, LPCSTR str, UINT count,
+			 const INT *lpDx )
 {
-    DC * dc = DC_GetDCUpdate( hdc );
-    LPWSTR p;
-    UINT codepage = CP_ACP; /* FIXME: get codepage of font charset */
-    BOOL ret = FALSE;
+    INT wlen;
+    UINT codepage;
+    LPWSTR p = FONT_mbtowc(hdc, str, count, &wlen, &codepage);
+    BOOL ret;
     LPINT lpDxW = NULL;
 
-    if (!dc) return FALSE;
+    if (lpDx) {
+        unsigned int i = 0, j = 0;
 
-    if (dc->funcs->pExtTextOut)
-    {
-        UINT wlen = MultiByteToWideChar(codepage,0,str,count,NULL,0);
-        if (lpDx)
-        {
-            unsigned int i = 0, j = 0;
-
-            lpDxW = (LPINT)HeapAlloc( GetProcessHeap(), 0, wlen*sizeof(INT));
-            while(i < count)
-            {
-                if(IsDBCSLeadByteEx(codepage, str[i]))
-                {
-                    lpDxW[j++] = lpDx[i] + lpDx[i+1];
-                    i = i + 2;
-                }
-                else
-                {
-                    lpDxW[j++] = lpDx[i];
-                    i = i + 1;
-                }
-            }
-        }
-        if ((p = HeapAlloc( GetProcessHeap(), 0, wlen * sizeof(WCHAR) )))
-        {
-            wlen = MultiByteToWideChar(codepage,0,str,count,p,wlen);
-            ret = dc->funcs->pExtTextOut( dc, x, y, flags, lprect, p, wlen, lpDxW );
-            HeapFree( GetProcessHeap(), 0, p );
-        }
-        if (lpDxW) HeapFree( GetProcessHeap(), 0, lpDxW );
+	lpDxW = (LPINT)HeapAlloc( GetProcessHeap(), 0, wlen*sizeof(INT));
+	while(i < count) {
+	    if(IsDBCSLeadByteEx(codepage, str[i])) {
+	        lpDxW[j++] = lpDx[i] + lpDx[i+1];
+		i = i + 2;
+	    } else {
+	        lpDxW[j++] = lpDx[i];
+		i = i + 1;
+	    }
+	}
     }
-    GDI_ReleaseObj( hdc );
+
+    ret = ExtTextOutW( hdc, x, y, flags, lprect, p, wlen, lpDxW );
+
+    HeapFree( GetProcessHeap(), 0, p );
+    if (lpDxW) HeapFree( GetProcessHeap(), 0, lpDxW );
     return ret;
 }
 
@@ -97,8 +148,8 @@
  *           ExtTextOutW    (GDI32.@)
  */
 BOOL WINAPI ExtTextOutW( HDC hdc, INT x, INT y, UINT flags,
-                             const RECT *lprect, LPCWSTR str, UINT count,
-                             const INT *lpDx )
+			 const RECT *lprect, LPCWSTR str, UINT count,
+			 const INT *lpDx )
 {
     BOOL ret = FALSE;
     DC * dc = DC_GetDCUpdate( hdc );


More information about the wine-patches mailing list