From c553924dddd89f6b5272f7bb94e7b10477e0b0a9 Mon Sep 17 00:00:00 2001
From: Huw D M Davies <h.davies1@physics.ox.ac.uk>
Date: Sun, 26 Dec 1999 00:47:03 +0000
Subject: [PATCH] Move DCFuncs ExtTextOut and GetTextExtentPoint to Unicode.
 Map a few Unicode chars to the first 0xff in psdrv. Don't expect x11drv to
 display Unicode chars yet.

---
 graphics/metafiledrv/text.c |  16 +++--
 graphics/psdrv/font.c       |  33 ++++++++-
 graphics/psdrv/ps.c         |  13 ++--
 graphics/psdrv/text.c       |  22 +++---
 graphics/ttydrv/font.c      |   4 +-
 graphics/ttydrv/text.c      |  15 ++--
 graphics/win16drv/font.c    |  14 ++--
 graphics/win16drv/text.c    | 137 ++++++++++++++++++------------------
 graphics/x11drv/text.c      |  44 +++++++-----
 graphics/x11drv/xfont.c     |  17 +++--
 include/gdi.h               |   4 +-
 include/metafiledrv.h       |   2 +-
 include/psdrv.h             |   7 +-
 include/ts_xlib.h           |   8 +--
 include/ttydrv.h            |   4 +-
 include/win16drv.h          |   4 +-
 include/x11drv.h            |   4 +-
 objects/font.c              | 113 ++++++++++++++---------------
 objects/text.c              |  22 +++---
 tsx11/X11_calls             |   8 +--
 tsx11/ts_xlib.c             |  32 ++++-----
 21 files changed, 285 insertions(+), 238 deletions(-)

diff --git a/graphics/metafiledrv/text.c b/graphics/metafiledrv/text.c
index 9390336981b..16e6624186c 100644
--- a/graphics/metafiledrv/text.c
+++ b/graphics/metafiledrv/text.c
@@ -34,7 +34,7 @@ static BOOL MFDRV_MetaExtTextOut(DC*dc, short x, short y, UINT16 flags,
         len += sizeof(RECT16);
     if (lpDx)
      len+=count*sizeof(INT16);
-    if (!(mr = HeapAlloc( SystemHeap, HEAP_ZERO_MEMORY, len)))
+    if (!(mr = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, len)))
 	return FALSE;
 
     mr->rdSize = len / 2;
@@ -49,7 +49,7 @@ static BOOL MFDRV_MetaExtTextOut(DC*dc, short x, short y, UINT16 flags,
      memcpy(mr->rdParm + (rect ? 8 : 4) + ((count + 1) >> 1),lpDx,
       count*sizeof(INT16));
     ret = MFDRV_WriteRecord( dc, mr, mr->rdSize * 2);
-    HeapFree( SystemHeap, 0, mr);
+    HeapFree( GetProcessHeap(), 0, mr);
     return ret;
 }
 
@@ -60,23 +60,27 @@ static BOOL MFDRV_MetaExtTextOut(DC*dc, short x, short y, UINT16 flags,
  */
 BOOL
 MFDRV_ExtTextOut( DC *dc, INT x, INT y, UINT flags,
-                  const RECT *lprect, LPCSTR str, UINT count,
+                  const RECT *lprect, LPCWSTR str, UINT count,
                   const INT *lpDx )
 {
     RECT16	rect16;
     LPINT16	lpdx16 = NULL;
     BOOL	ret;
     int		i;
+    LPSTR       ascii;
 
     if(lpDx)
-        lpdx16 = HeapAlloc( SystemHeap, 0, sizeof(INT16)*count );
+        lpdx16 = HeapAlloc( GetProcessHeap(), 0, sizeof(INT16)*count );
     if (lprect)	CONV_RECT32TO16(lprect,&rect16);
     if (lpdx16)
         for (i=count;i--;)
 	    lpdx16[i]=lpDx[i];
-    ret = MFDRV_MetaExtTextOut(dc,x,y,flags,lprect?&rect16:NULL,str,count,
+    ascii = HeapAlloc( GetProcessHeap(), 0, count+1 );
+    lstrcpynWtoA(ascii, str, count+1);
+    ret = MFDRV_MetaExtTextOut(dc,x,y,flags,lprect?&rect16:NULL,ascii,count,
 			       lpdx16);
-    if (lpdx16)	HeapFree( SystemHeap, 0, lpdx16 );
+    HeapFree( GetProcessHeap(), 0, ascii );
+    if (lpdx16)	HeapFree( GetProcessHeap(), 0, lpdx16 );
     return ret;
 }
 
diff --git a/graphics/psdrv/font.c b/graphics/psdrv/font.c
index 12c0936ce18..51a83b5c85f 100644
--- a/graphics/psdrv/font.c
+++ b/graphics/psdrv/font.c
@@ -168,11 +168,37 @@ BOOL PSDRV_GetTextMetrics(DC *dc, TEXTMETRICA *metrics)
     return TRUE;
 }
 
-
+/***********************************************************************
+ *           PSDRV_UnicodeToANSI
+ */
+char PSDRV_UnicodeToANSI(int u)
+{
+    if((u & 0xff) == u)
+        return u;
+    switch(u) {
+    case 0x2013: /* endash */
+        return 0x96;
+    case 0x2014: /* emdash */
+        return 0x97;
+    case 0x2018: /* quoteleft */
+        return 0x91;
+    case 0x2019: /* quoteright */
+        return 0x92;
+    case 0x201c: /* quotedblleft */
+       return 0x93;
+    case 0x201d: /* quotedblright */
+        return 0x94;
+    case 0x2022: /* bullet */
+        return 0x95;
+    default:
+        WARN("Umapped unicode char U%04x\n", u);
+	return 0xff;
+    }
+}
 /***********************************************************************
  *           PSDRV_GetTextExtentPoint
  */
-BOOL PSDRV_GetTextExtentPoint( DC *dc, LPCSTR str, INT count,
+BOOL PSDRV_GetTextExtentPoint( DC *dc, LPCWSTR str, INT count,
                                   LPSIZE size )
 {
     PSDRV_PDEVICE *physDev = (PSDRV_PDEVICE *)dc->physDev;
@@ -183,7 +209,8 @@ BOOL PSDRV_GetTextExtentPoint( DC *dc, LPCSTR str, INT count,
     width = 0.0;
 
     for(i = 0; i < count && str[i]; i++) {
-        width += physDev->font.afm->CharWidths[ *((unsigned char *)str + i) ];
+        char c = PSDRV_UnicodeToANSI(str[i]);
+        width += physDev->font.afm->CharWidths[(int)(unsigned char)c];
 /*	TRACE(psdrv, "Width after %dth char '%c' = %f\n", i, str[i], width);*/
     }
     width *= physDev->font.scale;
diff --git a/graphics/psdrv/ps.c b/graphics/psdrv/ps.c
index 9c0b2c736d9..65500082be6 100644
--- a/graphics/psdrv/ps.c
+++ b/graphics/psdrv/ps.c
@@ -631,7 +631,7 @@ BOOL PSDRV_WriteReencodeFont(DC *dc)
     return TRUE;
 }    
 
-BOOL PSDRV_WriteShow(DC *dc, char *str, INT count)
+BOOL PSDRV_WriteShow(DC *dc, LPCWSTR str, INT count)
 {
     char *buf, *buf1;
     INT buflen = count + 10, i, done;
@@ -639,20 +639,21 @@ BOOL PSDRV_WriteShow(DC *dc, char *str, INT count)
     buf = (char *)HeapAlloc( PSDRV_Heap, 0, buflen );
     
     for(i = done = 0; i < count; i++) {
-        if(!isprint(str[i])) {
+        char c = PSDRV_UnicodeToANSI(str[i]);
+        if(!isprint(c)) {
 	    if(done + 4 >= buflen)
 	        buf = HeapReAlloc( PSDRV_Heap, 0, buf, buflen += 10 );
-	    sprintf(buf + done, "\\%03o", (int)(unsigned char)str[i] );
+	    sprintf(buf + done, "\\%03o", (int)(unsigned char)c);
 	    done += 4;
-	} else if(str[i] == '\\' || str[i] == '(' || str[i] == ')' ) {
+	} else if(c == '\\' || c == '(' || c == ')' ) {
 	    if(done + 2 >= buflen)
 	        buf = HeapReAlloc( PSDRV_Heap, 0, buf, buflen += 10 );
 	    buf[done++] = '\\';
-	    buf[done++] = str[i];
+	    buf[done++] = c;
 	} else {
 	    if(done + 1 >= buflen)
 	        buf = HeapReAlloc( PSDRV_Heap, 0, buf, buflen += 10 );
-	    buf[done++] = str[i];
+	    buf[done++] = c;
 	}
     }
     buf[done] = '\0';
diff --git a/graphics/psdrv/text.c b/graphics/psdrv/text.c
index 6bd6a54ba1a..2175c5770e1 100644
--- a/graphics/psdrv/text.c
+++ b/graphics/psdrv/text.c
@@ -11,14 +11,14 @@
 
 DEFAULT_DEBUG_CHANNEL(psdrv)
 
-static BOOL PSDRV_Text(DC *dc, INT x, INT y, LPCSTR str, UINT count,
+static BOOL PSDRV_Text(DC *dc, INT x, INT y, LPCWSTR str, UINT count,
 		       BOOL bDrawBackground);
 
 /***********************************************************************
  *           PSDRV_ExtTextOut
  */
 BOOL PSDRV_ExtTextOut( DC *dc, INT x, INT y, UINT flags,
-		       const RECT *lprect, LPCSTR str, UINT count,
+		       const RECT *lprect, LPCWSTR str, UINT count,
 		       const INT *lpDx )
 {
     PSDRV_PDEVICE *physDev = (PSDRV_PDEVICE *)dc->physDev;
@@ -27,8 +27,8 @@ BOOL PSDRV_ExtTextOut( DC *dc, INT x, INT y, UINT flags,
     BOOL bOpaque = FALSE;
     RECT rect;
 
-    TRACE("(x=%d, y=%d, flags=0x%08x, str='%.*s', count=%d)\n", x, y,
-	  flags, (int)count, str, count);
+    TRACE("(x=%d, y=%d, flags=0x%08x, str=%s, count=%d)\n", x, y,
+	  flags, debugstr_wn(str, count), count);
 
     /* write font if not already written */
     PSDRV_SetFont(dc);
@@ -74,14 +74,14 @@ BOOL PSDRV_ExtTextOut( DC *dc, INT x, INT y, UINT flags,
 /***********************************************************************
  *           PSDRV_Text
  */
-static BOOL PSDRV_Text(DC *dc, INT x, INT y, LPCSTR str, UINT count,
+static BOOL PSDRV_Text(DC *dc, INT x, INT y, LPCWSTR str, UINT count,
 		       BOOL bDrawBackground)
 {
     PSDRV_PDEVICE *physDev = (PSDRV_PDEVICE *)dc->physDev;
-    char *strbuf;
+    LPWSTR strbuf;
     SIZE sz;
 
-    strbuf = (char *)HeapAlloc( PSDRV_Heap, 0, count + 1);
+    strbuf = HeapAlloc( PSDRV_Heap, 0, (count + 1) * sizeof(WCHAR));
     if(!strbuf) {
         WARN("HeapAlloc failed\n");
         return FALSE;
@@ -95,7 +95,7 @@ static BOOL PSDRV_Text(DC *dc, INT x, INT y, LPCSTR str, UINT count,
     x = XLPTODP(dc, x);
     y = YLPTODP(dc, y);
 
-    GetTextExtentPoint32A(dc->hSelf, str, count, &sz);
+    GetTextExtentPoint32W(dc->hSelf, str, count, &sz);
     sz.cx = XLSTODS(dc, sz.cx);
     sz.cy = YLSTODS(dc, sz.cy);
 
@@ -129,7 +129,7 @@ static BOOL PSDRV_Text(DC *dc, INT x, INT y, LPCSTR str, UINT count,
 	break;
     }
 
-    memcpy(strbuf, str, count);
+    memcpy(strbuf, str, count * sizeof(WCHAR));
     *(strbuf + count) = '\0';
     
     if ((dc->w.backgroundMode != TRANSPARENT) && (bDrawBackground != FALSE))
@@ -145,7 +145,7 @@ static BOOL PSDRV_Text(DC *dc, INT x, INT y, LPCSTR str, UINT count,
     }
 
     PSDRV_WriteMoveTo(dc, x, y);
-    PSDRV_WriteShow(dc, strbuf, strlen(strbuf));
+    PSDRV_WriteShow(dc, strbuf, lstrlenW(strbuf));
 
     /*
      * Underline and strikeout attributes.
@@ -165,7 +165,7 @@ static BOOL PSDRV_Text(DC *dc, INT x, INT y, LPCSTR str, UINT count,
 
         /* Get the width of the text */
 
-        PSDRV_GetTextExtentPoint(dc, strbuf, strlen(strbuf), &size);
+        PSDRV_GetTextExtentPoint(dc, strbuf, lstrlenW(strbuf), &size);
         size.cx = XLSTODS(dc, size.cx);
 
         /* Do the underline */
diff --git a/graphics/ttydrv/font.c b/graphics/ttydrv/font.c
index 937b5c44480..75ab5a02110 100644
--- a/graphics/ttydrv/font.c
+++ b/graphics/ttydrv/font.c
@@ -32,12 +32,12 @@ BOOL TTYDRV_DC_GetCharWidth(DC *dc, UINT firstChar, UINT lastChar,
 /***********************************************************************
  *		TTYDRV_DC_GetTextExtentPoint
  */
-BOOL TTYDRV_DC_GetTextExtentPoint(DC *dc, LPCSTR str, INT count,
+BOOL TTYDRV_DC_GetTextExtentPoint(DC *dc, LPCWSTR str, INT count,
 				  LPSIZE size)
 {
   TTYDRV_PDEVICE *physDev = (TTYDRV_PDEVICE *) dc->physDev;
 
-  TRACE("(%p, %s, %d, %p)\n", dc, debugstr_an(str, count), count, size);
+  TRACE("(%p, %s, %d, %p)\n", dc, debugstr_wn(str, count), count, size);
 
   size->cx = count * physDev->cellWidth;
   size->cy = physDev->cellHeight;
diff --git a/graphics/ttydrv/text.c b/graphics/ttydrv/text.c
index 04ccf4820e6..b9ce6d2ab54 100644
--- a/graphics/ttydrv/text.c
+++ b/graphics/ttydrv/text.c
@@ -18,15 +18,16 @@ DEFAULT_DEBUG_CHANNEL(ttydrv)
  *		TTYDRV_DC_ExtTextOut
  */
 BOOL TTYDRV_DC_ExtTextOut(DC *dc, INT x, INT y, UINT flags,
-			  const RECT *lpRect, LPCSTR str, UINT count,
+			  const RECT *lpRect, LPCWSTR str, UINT count,
 			  const INT *lpDx)
 {
 #ifdef HAVE_LIBCURSES
   TTYDRV_PDEVICE *physDev = (TTYDRV_PDEVICE *) dc->physDev;
   INT row, col;
+  LPSTR ascii;
 
   TRACE("(%p, %d, %d, 0x%08x, %p, %s, %d, %p)\n",
-	dc, x, y, flags, lpRect, debugstr_a(str), count, lpDx);
+	dc, x, y, flags, lpRect, debugstr_wn(str, count), count, lpDx);
 
   if(!physDev->window)
     return FALSE;
@@ -42,19 +43,21 @@ BOOL TTYDRV_DC_ExtTextOut(DC *dc, INT x, INT y, UINT flags,
   
   row = (dc->w.DCOrgY + y) / physDev->cellHeight;
   col = (dc->w.DCOrgX + x) / physDev->cellWidth;
-
-  mvwaddnstr(physDev->window, row, col, str, count);
+  ascii = HeapAlloc( GetProcessHeap(), 0, count+1 );
+  lstrcpynWtoA(ascii, str, count+1);
+  mvwaddnstr(physDev->window, row, col, ascii, count);
+  HeapFree( GetProcessHeap(), 0, ascii );
   wrefresh(physDev->window);
 
   if(dc->w.textAlign & TA_UPDATECP) {
     dc->w.CursPosX += count * physDev->cellWidth;
-    dc->w.CursPosY += count * physDev->cellHeight;
+    dc->w.CursPosY += physDev->cellHeight;
   }
 
   return TRUE;
 #else /* defined(HAVE_LIBCURSES) */
   FIXME("(%p, %d, %d, 0x%08x, %p, %s, %d, %p): stub\n",
-	dc, x, y, flags, lpRect, debugstr_a(str), count, lpDx);
+	dc, x, y, flags, lpRect, debugstr_wn(str,count), count, lpDx);
 
   return TRUE;
 #endif /* defined(HAVE_LIBCURSES) */
diff --git a/graphics/win16drv/font.c b/graphics/win16drv/font.c
index 9a71b40a1bb..ca1a4bf1757 100644
--- a/graphics/win16drv/font.c
+++ b/graphics/win16drv/font.c
@@ -19,15 +19,18 @@ DEFAULT_DEBUG_CHANNEL(win16drv)
 /***********************************************************************
  *           WIN16DRV_GetTextExtentPoint
  */
-BOOL WIN16DRV_GetTextExtentPoint( DC *dc, LPCSTR str, INT count,
-                                    LPSIZE size )
+BOOL WIN16DRV_GetTextExtentPoint( DC *dc, LPCWSTR wstr, INT count,
+				  LPSIZE size )
 {
     WIN16DRV_PDEVICE *physDev = (WIN16DRV_PDEVICE *)dc->physDev;
     DWORD dwRet;
-    
+    char *str;
+
     TRACE("%04x %s %d %p\n",
-		                dc->hSelf, str, count, size);
+	  dc->hSelf, debugstr_wn(wstr, count), count, size);
 
+    str = HeapAlloc( GetProcessHeap(), 0, count+1 );
+    lstrcpynWtoA( str, wstr, count+1 );
     dwRet = PRTDRV_ExtTextOut(physDev->segptrPDEVICE, 0, 0, 
 			      NULL, str, 
 			      -count,  physDev->FontInfo, 
@@ -37,6 +40,7 @@ BOOL WIN16DRV_GetTextExtentPoint( DC *dc, LPCSTR str, INT count,
     size->cy = YDSTOLS(dc,HIWORD(dwRet));
     TRACE("cx=0x%x, cy=0x%x\n",
 		size->cx, size->cy );
+    HeapFree( GetProcessHeap(), 0, str );
     return TRUE;
 }
 
@@ -184,7 +188,7 @@ BOOL	WIN16DRV_EnumDeviceFonts( DC* dc, LPLOGFONT16 plf,
     /* EnumDFontCallback is GDI.158 */
     FARPROC16 pfnCallback = NE_GetEntryPoint( GetModuleHandle16("GDI"), 158 );
 
-    wepfc.proc = proc;
+    wepfc.proc = (int (*)(LPENUMLOGFONT16,LPNEWTEXTMETRIC16,UINT16,LPARAM))proc;
     wepfc.lp = lp;
 
     wRet = PRTDRV_EnumDFonts(physDev->segptrPDEVICE, plf->lfFaceName[0] ?
diff --git a/graphics/win16drv/text.c b/graphics/win16drv/text.c
index ffe688d1fe7..d9374cd5ca8 100644
--- a/graphics/win16drv/text.c
+++ b/graphics/win16drv/text.c
@@ -10,6 +10,7 @@
 #include "dc.h"
 #include "gdi.h"
 #include "debugtools.h"
+#include "winbase.h"
 
 DEFAULT_DEBUG_CHANNEL(win16drv)
 
@@ -17,7 +18,7 @@ DEFAULT_DEBUG_CHANNEL(win16drv)
  *           WIN16DRV_ExtTextOut
  */
 BOOL WIN16DRV_ExtTextOut( DC *dc, INT x, INT y, UINT flags,
-                           const RECT *lprect, LPCSTR str, UINT count,
+                           const RECT *lprect, LPCWSTR wstr, UINT count,
                            const INT *lpDx )
 {
     WIN16DRV_PDEVICE *physDev = (WIN16DRV_PDEVICE *)dc->physDev;
@@ -28,84 +29,82 @@ BOOL WIN16DRV_ExtTextOut( DC *dc, INT x, INT y, UINT flags,
     WORD wOptions = 0;
     WORD wCount = count;
     INT16 width;
+    char *str;
+    DWORD dwRet;
 
     if (count == 0)
-      return FALSE;
+        return FALSE;
 
-    TRACE("%04x %d %d %x %p %*s %p\n",
-	   dc->hSelf, x, y, flags,  lprect, count > 0 ? count : 8, str, lpDx);
+    TRACE("%04x %d %d %x %p %s %p\n",
+	  dc->hSelf, x, y, flags, lprect, debugstr_wn(wstr, count), lpDx);
 
+    str = HeapAlloc( GetProcessHeap(), 0, count+1 );
+    lstrcpynWtoA( str, wstr, count+1 );
 
-    if (dc != NULL)   
-    {
-	DWORD dwRet;
-
-	clipRect.left = 0;
-	clipRect.top = 0;
+    clipRect.left = 0;
+    clipRect.top = 0;
         
-	clipRect.right = dc->w.devCaps->horzRes;
-	clipRect.bottom = dc->w.devCaps->vertRes;
-        if (lprect)
-        {
-            opaqueRect.left = lprect->left;
-            opaqueRect.top = lprect->top;
-            opaqueRect.right = lprect->right;
-            opaqueRect.bottom = lprect->bottom;
-            lpOpaqueRect = &opaqueRect;
-            
-        }
+    clipRect.right = dc->w.devCaps->horzRes;
+    clipRect.bottom = dc->w.devCaps->vertRes;
+    if (lprect) {
+	opaqueRect.left = lprect->left;
+	opaqueRect.top = lprect->top;
+	opaqueRect.right = lprect->right;
+	opaqueRect.bottom = lprect->bottom;
+	lpOpaqueRect = &opaqueRect;
+    }
         
-	TRACE("textalign = %d\n", dc->w.textAlign);
+    TRACE("textalign = %d\n", dc->w.textAlign);
+
+    if (dc->w.textAlign & TA_UPDATECP) {
+        x = dc->w.CursPosX;
+	y = dc->w.CursPosY;
+    }
+
+    x = XLPTODP( dc, x );
+    y = YLPTODP( dc, y );
+
+    dwRet = PRTDRV_ExtTextOut(physDev->segptrPDEVICE, 0, 0, 
+			      NULL, str, -count,  physDev->FontInfo, 
+			      win16drv_SegPtr_DrawMode,
+			      win16drv_SegPtr_TextXForm,
+			      NULL, NULL, 0);
 
+    width = LOWORD(dwRet);
+
+    switch( dc->w.textAlign & (TA_LEFT | TA_RIGHT | TA_CENTER) ) {
+    case TA_LEFT:
+        if (dc->w.textAlign & TA_UPDATECP)
+	    dc->w.CursPosX = XDPTOLP( dc, x + width );
+	break;
+    case TA_RIGHT:
+        x -= width;
 	if (dc->w.textAlign & TA_UPDATECP)
-	{
-	    x = dc->w.CursPosX;
-	    y = dc->w.CursPosY;
-	}
-
-	x = XLPTODP( dc, x );
-	y = YLPTODP( dc, y );
-
-	dwRet = PRTDRV_ExtTextOut(physDev->segptrPDEVICE, 0, 0, 
-		 NULL, str, -count,  physDev->FontInfo, 
-		 win16drv_SegPtr_DrawMode, win16drv_SegPtr_TextXForm,
-		 NULL, NULL, 0);
-
-	width = LOWORD(dwRet);
-
-	switch( dc->w.textAlign & (TA_LEFT | TA_RIGHT | TA_CENTER) )
-	{
-	case TA_LEFT:
- 	    if (dc->w.textAlign & TA_UPDATECP)
-	        dc->w.CursPosX = XDPTOLP( dc, x + width );
-	    break;
-	case TA_RIGHT:
-	     x -= width;
-	     if (dc->w.textAlign & TA_UPDATECP)
-	         dc->w.CursPosX = XDPTOLP( dc, x );
-	     break;
-	case TA_CENTER:
-	    x -= width / 2;
-	    break;
-	}
-
-	switch( dc->w.textAlign & (TA_TOP | TA_BOTTOM | TA_BASELINE) )
-	{
-	case TA_TOP:
-	    break;
-	case TA_BOTTOM:
-	    y -= physDev->FontInfo->dfPixHeight;
-	    break;
-	case TA_BASELINE:
-	    y -= physDev->FontInfo->dfAscent;
-	    break;    
-	}
-
-	dwRet = PRTDRV_ExtTextOut(physDev->segptrPDEVICE, 
-	      x, y, &clipRect, str, wCount,
-	      physDev->FontInfo, win16drv_SegPtr_DrawMode, 
-	      win16drv_SegPtr_TextXForm, NULL, lpOpaqueRect, wOptions);
+	    dc->w.CursPosX = XDPTOLP( dc, x );
+	break;
+    case TA_CENTER:
+        x -= width / 2;
+	break;
+    }
+
+    switch( dc->w.textAlign & (TA_TOP | TA_BOTTOM | TA_BASELINE) ) {
+    case TA_TOP:
+        break;
+    case TA_BOTTOM:
+        y -= physDev->FontInfo->dfPixHeight;
+	break;
+    case TA_BASELINE:
+        y -= physDev->FontInfo->dfAscent;
+	break;    
     }
+
+    dwRet = PRTDRV_ExtTextOut(physDev->segptrPDEVICE, 
+			      x, y, &clipRect, str, wCount,
+			      physDev->FontInfo, win16drv_SegPtr_DrawMode, 
+			      win16drv_SegPtr_TextXForm, NULL, lpOpaqueRect,
+			      wOptions);
+
+    HeapFree( GetProcessHeap(), 0, str );
     return bRet;
 }
 
diff --git a/graphics/x11drv/text.c b/graphics/x11drv/text.c
index 01d2292b911..2445f79f995 100644
--- a/graphics/x11drv/text.c
+++ b/graphics/x11drv/text.c
@@ -30,7 +30,7 @@ DEFAULT_DEBUG_CHANNEL(text)
  */
 BOOL
 X11DRV_ExtTextOut( DC *dc, INT x, INT y, UINT flags,
-                   const RECT *lprect, LPCSTR str, UINT count,
+                   const RECT *lprect, LPCWSTR wstr, UINT count,
                    const INT *lpDx )
 {
     int 	        i;
@@ -41,6 +41,7 @@ X11DRV_ExtTextOut( DC *dc, INT x, INT y, UINT flags,
     char		dfBreakChar, lfUnderline, lfStrikeOut;
     BOOL		rotated = FALSE;
     X11DRV_PDEVICE      *physDev = (X11DRV_PDEVICE *)dc->physDev;
+    XChar2b *str2b;
 
     if (!X11DRV_SetupGCForText( dc )) return TRUE;
 
@@ -55,12 +56,12 @@ X11DRV_ExtTextOut( DC *dc, INT x, INT y, UINT flags,
 
     TRACE("hdc=%04x df=%04x %d,%d %s, %d  flags=%d lpDx=%p\n",
 	  dc->hSelf, (UINT16)(physDev->font), x, y,
-	  debugstr_an (str, count), count, flags, lpDx);
+	  debugstr_wn (wstr, count), count, flags, lpDx);
 
     /* some strings sent here end in a newline for whatever reason.  I have no
        clue what the right treatment should be in general, but ignoring
        terminating newlines seems ok.  MW, April 1998.  */
-    if (count > 0 && str[count - 1] == '\n') count--;
+    if (count > 0 && wstr[count - 1] == '\n') count--;
 
     if (lprect != NULL) TRACE("\trect=(%d,%d - %d,%d)\n",
                                      lprect->left, lprect->top,
@@ -80,7 +81,7 @@ X11DRV_ExtTextOut( DC *dc, INT x, INT y, UINT flags,
             SIZE sz;
             if (flags & ETO_CLIPPED)  /* Can't clip with no rectangle */
 	      return FALSE;
-	    if (!X11DRV_GetTextExtentPoint( dc, str, count, &sz ))
+	    if (!X11DRV_GetTextExtentPoint( dc, wstr, count, &sz ))
 	      return FALSE;
 	    rect.left   = XLPTODP( dc, x );
 	    rect.right  = XLPTODP( dc, x+sz.cx );
@@ -126,7 +127,7 @@ X11DRV_ExtTextOut( DC *dc, INT x, INT y, UINT flags,
     else
     {
         SIZE sz;
-        if (!X11DRV_GetTextExtentPoint( dc, str, count, &sz ))
+        if (!X11DRV_GetTextExtentPoint( dc, wstr, count, &sz ))
 	    return FALSE;
 	width = XLSTODS(dc, sz.cx);
     }
@@ -213,24 +214,29 @@ X11DRV_ExtTextOut( DC *dc, INT x, INT y, UINT flags,
     }
     
     /* Draw the text (count > 0 verified) */
+    str2b = HeapAlloc( GetProcessHeap(), 0, count * sizeof(XChar2b) );
+    for(i = 0; i < count; i++) {
+      str2b[i].byte1 = wstr[i] >> 8;
+      str2b[i].byte2 = wstr[i] & 0xff;
+    }
 
     TSXSetForeground( display, physDev->gc, physDev->textPixel );
     if(!rotated)
     {
       if (!dc->w.charExtra && !dc->w.breakExtra && !lpDx)
       {
-        TSXDrawString( display, physDev->drawable, physDev->gc, 
-                     dc->w.DCOrgX + x, dc->w.DCOrgY + y, str, count );
+        TSXDrawString16( display, physDev->drawable, physDev->gc, 
+			 dc->w.DCOrgX + x, dc->w.DCOrgY + y, str2b, count );
       }
       else  /* Now the fun begins... */
       {
-        XTextItem *items, *pitem;
+        XTextItem16 *items, *pitem;
 	int delta;
 
 	/* allocate max items */
 
         pitem = items = HEAP_xalloc( GetProcessHeap(), 0,
-                                     count * sizeof(XTextItem) );
+                                     count * sizeof(XTextItem16) );
         delta = i = 0;
 	if( lpDx ) /* explicit character widths */
 	{
@@ -240,7 +246,7 @@ X11DRV_ExtTextOut( DC *dc, INT x, INT y, UINT flags,
 	    {
 		/* initialize text item with accumulated delta */
 
-		pitem->chars  = (char *)str + i;
+		pitem->chars  = str2b + i;
 		pitem->delta  = delta;
 		pitem->nchars = 0;
 		pitem->font   = None;
@@ -252,7 +258,7 @@ X11DRV_ExtTextOut( DC *dc, INT x, INT y, UINT flags,
 		do
 		{
 		    delta += (lpDx[i] * dc->vportExtX + extra) / dc->wndExtX
-					    - TSXTextWidth( font, str + i, 1);
+		      - TSXTextWidth16( font, str2b + i, 1);
 		    pitem->nchars++;
 		} while ((++i < count) && !delta);
 		pitem++;
@@ -262,7 +268,7 @@ X11DRV_ExtTextOut( DC *dc, INT x, INT y, UINT flags,
 	{
             while (i < count)
             {
-		pitem->chars  = (char *)str + i;
+		pitem->chars  = str2b + i;
 		pitem->delta  = delta;
 		pitem->nchars = 0;
 		pitem->font   = None;
@@ -271,14 +277,15 @@ X11DRV_ExtTextOut( DC *dc, INT x, INT y, UINT flags,
 		do
                 {
                     delta += dc->w.charExtra;
-                    if (str[i] == (char)dfBreakChar) delta += dc->w.breakExtra;
+                    if (str2b[i].byte2 == (char)dfBreakChar)
+		      delta += dc->w.breakExtra;
 		    pitem->nchars++;
                 } while ((++i < count) && !delta);
 		pitem++;
             } 
         }
 
-        TSXDrawText( display, physDev->drawable, physDev->gc,
+        TSXDrawText16( display, physDev->drawable, physDev->gc,
                    dc->w.DCOrgX + x, dc->w.DCOrgY + y, items, pitem - items );
         HeapFree( GetProcessHeap(), 0, items );
       }
@@ -291,15 +298,15 @@ X11DRV_ExtTextOut( DC *dc, INT x, INT y, UINT flags,
 
       for (i=0; i<count; i++)
       {
-	int char_metric_offset = (unsigned char) str[i] 
+	int char_metric_offset = str2b[i].byte2 + (str2b[i].byte1 << 8) 
 	  - font->min_char_or_byte2;
 	int x_i = IROUND((double) (dc->w.DCOrgX + x) + offset *
 			 pfo->lpX11Trans->a / pfo->lpX11Trans->pixelsize );
 	int y_i = IROUND((double) (dc->w.DCOrgY + y) - offset *
 			 pfo->lpX11Trans->b / pfo->lpX11Trans->pixelsize );
 
-	TSXDrawString( display, physDev->drawable, physDev->gc,
-		       x_i, y_i, &str[i], 1);
+	TSXDrawString16( display, physDev->drawable, physDev->gc,
+		       x_i, y_i, &str2b[i], 1);
 	if (lpDx)
 	  offset += XLSTODS(dc, lpDx[i]);
 	else
@@ -309,11 +316,12 @@ X11DRV_ExtTextOut( DC *dc, INT x, INT y, UINT flags,
 			      font->min_bounds.attributes)
 	                  * pfo->lpX11Trans->pixelsize / 1000.0;
 	  offset += dc->w.charExtra;
-	  if (str[i] == (char)dfBreakChar)
+	  if (str2b[i].byte2 == (char)dfBreakChar)
 	    offset += dc->w.breakExtra;
 	}
       }
     }
+    HeapFree( GetProcessHeap(), 0, str2b );
 
       /* Draw underline and strike-out if needed */
 
diff --git a/graphics/x11drv/xfont.c b/graphics/x11drv/xfont.c
index 831a1bce45f..6eb9e96ee24 100644
--- a/graphics/x11drv/xfont.c
+++ b/graphics/x11drv/xfont.c
@@ -3038,23 +3038,30 @@ BOOL	X11DRV_EnumDeviceFonts( DC* dc, LPLOGFONT16 plf,
 /***********************************************************************
  *           X11DRV_GetTextExtentPoint
  */
-BOOL X11DRV_GetTextExtentPoint( DC *dc, LPCSTR str, INT count,
+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;
+	    int dir, ascent, descent, i;
 	    XCharStruct info;
-
-	    TSXTextExtents( pfo->fs, str, count, &dir, &ascent, &descent, &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++) {
diff --git a/include/gdi.h b/include/gdi.h
index dad68163a78..c2aace30c92 100644
--- a/include/gdi.h
+++ b/include/gdi.h
@@ -198,7 +198,7 @@ typedef struct tagDC_FUNCS
     INT      (*pExtDeviceMode)(LPSTR,HWND,LPDEVMODEA,LPSTR,LPSTR,LPDEVMODEA,
 			       LPSTR,DWORD); 
     BOOL     (*pExtFloodFill)(DC*,INT,INT,COLORREF,UINT);
-    BOOL     (*pExtTextOut)(DC*,INT,INT,UINT,const RECT*,LPCSTR,UINT,
+    BOOL     (*pExtTextOut)(DC*,INT,INT,UINT,const RECT*,LPCWSTR,UINT,
 			    const INT*);
     BOOL     (*pFillPath)(DC*);
     BOOL     (*pFillRgn)(DC*,HRGN,HBRUSH);
@@ -206,7 +206,7 @@ typedef struct tagDC_FUNCS
     BOOL     (*pFrameRgn)(DC*,HRGN,HBRUSH,INT,INT);
     BOOL     (*pGetCharWidth)(DC*,UINT,UINT,LPINT);
     COLORREF (*pGetPixel)(DC*,INT,INT);
-    BOOL     (*pGetTextExtentPoint)(DC*,LPCSTR,INT,LPSIZE);
+    BOOL     (*pGetTextExtentPoint)(DC*,LPCWSTR,INT,LPSIZE);
     BOOL     (*pGetTextMetrics)(DC*,TEXTMETRICA*);
     INT      (*pIntersectClipRect)(DC*,INT,INT,INT,INT);
     BOOL     (*pInvertRgn)(DC*,HRGN);    
diff --git a/include/metafiledrv.h b/include/metafiledrv.h
index 91579096773..1502218ef62 100644
--- a/include/metafiledrv.h
+++ b/include/metafiledrv.h
@@ -54,7 +54,7 @@ extern INT MFDRV_ExcludeClipRect( DC *dc, INT left, INT top, INT right, INT
 extern BOOL MFDRV_ExtFloodFill( DC *dc, INT x, INT y,
 				COLORREF color, UINT fillType );
 extern BOOL MFDRV_ExtTextOut( DC *dc, INT x, INT y,
-			      UINT flags, const RECT *lprect, LPCSTR str,
+			      UINT flags, const RECT *lprect, LPCWSTR str,
 			      UINT count, const INT *lpDx );
 extern BOOL MFDRV_FillPath( DC *dc );
 extern BOOL MFDRV_FillRgn( DC *dc, HRGN hrgn, HBRUSH hbrush );
diff --git a/include/psdrv.h b/include/psdrv.h
index a08b888cb8f..46a46aee3e1 100644
--- a/include/psdrv.h
+++ b/include/psdrv.h
@@ -264,6 +264,7 @@ extern BOOL PSDRV_CmpColor(PSCOLOR *col1, PSCOLOR *col2);
 extern BOOL PSDRV_CopyColor(PSCOLOR *col1, PSCOLOR *col2);
 extern void PSDRV_CreateColor( PSDRV_PDEVICE *physDev, PSCOLOR *pscolor,
 		     COLORREF wincolor );
+extern char PSDRV_UnicodeToANSI(int u);
 
 
 extern INT PSDRV_WriteHeader( DC *dc, LPCSTR title );
@@ -278,7 +279,7 @@ extern BOOL PSDRV_WriteRectangle(DC *dc, INT x, INT y, INT width,
 extern BOOL PSDRV_WriteRRectangle(DC *dc, INT x, INT y, INT width, 
 			INT height);
 extern BOOL PSDRV_WriteSetFont(DC *dc, BOOL UseANSI);
-extern BOOL PSDRV_WriteShow(DC *dc, char *str, INT count);
+extern BOOL PSDRV_WriteShow(DC *dc, LPCWSTR str, INT count);
 extern BOOL PSDRV_WriteReencodeFont(DC *dc);
 extern BOOL PSDRV_WriteSetPen(DC *dc);
 extern BOOL PSDRV_WriteArc(DC *dc, INT x, INT y, INT w, INT h,
@@ -328,11 +329,11 @@ extern BOOL PSDRV_EnumDeviceFonts( DC* dc, LPLOGFONT16 plf,
 extern INT PSDRV_Escape( DC *dc, INT nEscape, INT cbInput, 
 			   SEGPTR lpInData, SEGPTR lpOutData );
 extern BOOL PSDRV_ExtTextOut( DC *dc, INT x, INT y, UINT flags,
-				const RECT *lprect, LPCSTR str, UINT count,
+				const RECT *lprect, LPCWSTR str, UINT count,
 				const INT *lpDx );
 extern BOOL PSDRV_GetCharWidth( DC *dc, UINT firstChar, UINT lastChar,
 				  LPINT buffer );
-extern BOOL PSDRV_GetTextExtentPoint( DC *dc, LPCSTR str, INT count,
+extern BOOL PSDRV_GetTextExtentPoint( DC *dc, LPCWSTR str, INT count,
 					LPSIZE size );
 extern BOOL PSDRV_GetTextMetrics( DC *dc, TEXTMETRICA *metrics );
 extern BOOL PSDRV_LineTo( DC *dc, INT x, INT y );
diff --git a/include/ts_xlib.h b/include/ts_xlib.h
index 05b9465d137..ac414b5ac3e 100644
--- a/include/ts_xlib.h
+++ b/include/ts_xlib.h
@@ -69,8 +69,8 @@ extern int  TSXDrawLines(Display*, Drawable, GC, XPoint*, int, int);
 extern int  TSXDrawPoint(Display*, Drawable, GC, int, int);
 extern int  TSXDrawRectangle(Display*, Drawable, GC, int, int, unsigned int, unsigned int);
 extern int  TSXDrawSegments(Display*, Drawable, GC, XSegment*, int);
-extern int  TSXDrawString(Display*, Drawable, GC, int, int, const  char*, int);
-extern int  TSXDrawText(Display*, Drawable, GC, int, int, XTextItem*, int);
+extern int  TSXDrawString16(Display*, Drawable, GC, int, int, const  XChar2b*, int);
+extern int  TSXDrawText16(Display*, Drawable, GC, int, int, XTextItem16*, int);
 extern int  TSXFillArc(Display*, Drawable, GC, int, int, unsigned int, unsigned int, int, int);
 extern int  TSXFillPolygon(Display*, Drawable, GC, XPoint*, int, int, int);
 extern int  TSXFillRectangle(Display*, Drawable, GC, int, int, unsigned int, unsigned int);
@@ -129,8 +129,8 @@ extern int  TSXSetWindowColormap(Display*, Window, Colormap);
 extern int  TSXStoreColor(Display*, Colormap, XColor*);
 extern int  TSXStoreName(Display*, Window, const  char*);
 extern int  TSXSync(Display*, int);
-extern int  TSXTextExtents(XFontStruct*, const  char*, int, int*, int*, int*, XCharStruct*);
-extern int  TSXTextWidth(XFontStruct*, const  char*, int);
+extern int  TSXTextExtents16(XFontStruct*, const  XChar2b*, int, int*, int*, int*, XCharStruct*);
+extern int  TSXTextWidth16(XFontStruct*, const  XChar2b*, int);
 extern int  TSXUngrabKeyboard(Display*, Time);
 extern int  TSXUngrabPointer(Display*, Time);
 extern int  TSXUngrabServer(Display*);
diff --git a/include/ttydrv.h b/include/ttydrv.h
index 4eef6182c66..cdfa46c3879 100644
--- a/include/ttydrv.h
+++ b/include/ttydrv.h
@@ -75,11 +75,11 @@ extern BOOL TTYDRV_DC_Chord(struct tagDC *dc, INT left, INT top, INT right, INT
 extern BOOL TTYDRV_DC_Ellipse(struct tagDC *dc, INT left, INT top, INT right, INT bottom);
 extern INT TTYDRV_DC_Escape(struct tagDC *dc, INT nEscape, INT cbInput, SEGPTR lpInData, SEGPTR lpOutData);
 extern BOOL TTYDRV_DC_ExtFloodFill(struct tagDC *dc, INT x, INT y, COLORREF color, UINT fillType);
-extern BOOL TTYDRV_DC_ExtTextOut(struct tagDC *dc, INT x, INT y, UINT flags, const RECT *lpRect, LPCSTR str, UINT count, const INT *lpDx);
+extern BOOL TTYDRV_DC_ExtTextOut(struct tagDC *dc, INT x, INT y, UINT flags, const RECT *lpRect, LPCWSTR str, UINT count, const INT *lpDx);
 extern BOOL TTYDRV_DC_GetCharWidth(struct tagDC *dc, UINT firstChar, UINT lastChar, LPINT buffer);
 extern COLORREF TTYDRV_DC_GetPixel(struct tagDC *dc, INT x, INT y);
 
-extern BOOL TTYDRV_DC_GetTextExtentPoint(struct tagDC *dc, LPCSTR str, INT count, LPSIZE size);
+extern BOOL TTYDRV_DC_GetTextExtentPoint(struct tagDC *dc, LPCWSTR str, INT count, LPSIZE size);
 extern BOOL TTYDRV_DC_GetTextMetrics(struct tagDC *dc, TEXTMETRICA *metrics);
 extern BOOL TTYDRV_DC_LineTo(struct tagDC *dc, INT x, INT y);
 extern HANDLE TTYDRV_DC_LoadOEMResource(WORD resid, WORD type);
diff --git a/include/win16drv.h b/include/win16drv.h
index 8cf53d6b72c..0fb32be799c 100644
--- a/include/win16drv.h
+++ b/include/win16drv.h
@@ -208,12 +208,12 @@ extern BOOL WIN16DRV_Init(void);
 extern BOOL WIN16DRV_GetCharWidth( struct tagDC *dc, UINT firstChar, UINT lastChar,
 				   LPINT buffer );
 
-extern BOOL WIN16DRV_GetTextExtentPoint( DC *dc, LPCSTR str, INT count,
+extern BOOL WIN16DRV_GetTextExtentPoint( DC *dc, LPCWSTR str, INT count,
                                            LPSIZE size );
 extern BOOL WIN16DRV_GetTextMetrics( DC *dc, TEXTMETRICA *metrics );
 
 extern BOOL WIN16DRV_ExtTextOut( DC *dc, INT x, INT y, UINT flags,
-                                  const RECT *lprect, LPCSTR str, UINT count,
+                                  const RECT *lprect, LPCWSTR str, UINT count,
                                   const INT *lpDx );
 extern BOOL WIN16DRV_LineTo( DC *dc, INT x, INT y );
 extern BOOL WIN16DRV_MoveToEx(DC *dc,INT x,INT y,LPPOINT pt);
diff --git a/include/x11drv.h b/include/x11drv.h
index a3c9c4012ce..33810ea0b6f 100644
--- a/include/x11drv.h
+++ b/include/x11drv.h
@@ -93,7 +93,7 @@ extern BOOL X11DRV_EnumDeviceFonts( struct tagDC *dc, LPLOGFONT16 plf,
 				      DEVICEFONTENUMPROC dfeproc, LPARAM lp );
 extern BOOL X11DRV_GetCharWidth( struct tagDC *dc, UINT firstChar,
                                    UINT lastChar, LPINT buffer );
-extern BOOL X11DRV_GetTextExtentPoint( struct tagDC *dc, LPCSTR str,
+extern BOOL X11DRV_GetTextExtentPoint( struct tagDC *dc, LPCWSTR str,
                                          INT count, LPSIZE size );
 extern BOOL X11DRV_GetTextMetrics(struct tagDC *dc, TEXTMETRICA *metrics);
 extern BOOL X11DRV_PatBlt( struct tagDC *dc, INT left, INT top,
@@ -139,7 +139,7 @@ extern BOOL X11DRV_ExtFloodFill( struct tagDC *dc, INT x, INT y,
 				   COLORREF color, UINT fillType );
 extern BOOL X11DRV_ExtTextOut( struct tagDC *dc, INT x, INT y,
 				 UINT flags, const RECT *lprect,
-				 LPCSTR str, UINT count, const INT *lpDx );
+				 LPCWSTR str, UINT count, const INT *lpDx );
 extern BOOL X11DRV_CreateBitmap( HBITMAP hbitmap );
 extern BOOL X11DRV_DeleteObject( HGDIOBJ handle );
 extern LONG X11DRV_BitmapBits( HBITMAP hbitmap, void *bits, LONG count,
diff --git a/objects/font.c b/objects/font.c
index c00f607c1e7..e662b7be1f8 100644
--- a/objects/font.c
+++ b/objects/font.c
@@ -852,7 +852,10 @@ BOOL16 WINAPI GetTextExtentPoint16( HDC16 hdc, LPCSTR str, INT16 count,
                                     LPSIZE16 size )
 {
     SIZE size32;
-    BOOL ret = GetTextExtentPoint32A( hdc, str, count, &size32 );
+    BOOL ret;
+    TRACE("%04x, %p (%s), %d, %p\n", hdc, str, debugstr_an(str, count), count,
+	  size);
+    ret = GetTextExtentPoint32A( hdc, str, count, &size32 );
     CONV_SIZE32TO16( &size32, size );
     return (BOOL16)ret;
 }
@@ -864,20 +867,19 @@ BOOL16 WINAPI GetTextExtentPoint16( HDC16 hdc, LPCSTR str, INT16 count,
 BOOL WINAPI GetTextExtentPoint32A( HDC hdc, LPCSTR str, INT count,
                                      LPSIZE size )
 {
-    DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
-    if (!dc)
-    {
-        if (!(dc = (DC *)GDI_GetObjPtr( hdc, METAFILE_DC_MAGIC )))
-            return FALSE;
-    }
+    LPWSTR p;
+    BOOL ret;
 
-    if (!dc->funcs->pGetTextExtentPoint ||
-        !dc->funcs->pGetTextExtentPoint( dc, str, count, size ))
-        return FALSE;
+  /* str may not be 0 terminated so we can't use HEAP_strdupWtoA.
+   * We allocate one more than we need so that lstrcpynWtoA can write a
+   * trailing 0 if it wants.
+   */
 
-    TRACE("(%08x %s %d %p): returning %d,%d\n",
-          hdc, debugstr_an (str, count), count, size, size->cx, size->cy );
-    return TRUE;
+    p = HeapAlloc( GetProcessHeap(), 0, (count+1) * sizeof(WCHAR) );
+    lstrcpynAtoW(p, str, count+1);
+    ret = GetTextExtentPoint32W( hdc, p, count, size );
+    HeapFree( GetProcessHeap(), 0, p );
+    return ret;
 }
 
 
@@ -896,20 +898,14 @@ BOOL WINAPI GetTextExtentPoint32W(
     INT count,   /* [in]  Number of characters in string */
     LPSIZE size) /* [out] Address of structure for string size */
 {
-    LPSTR p;
-    BOOL ret;
-
-  /* str may not be 0 terminated so we can't use HEAP_strdupWtoA.
-   * We allocate one more than we need so that lstrcpynWtoA can write a
-   * trailing 0 if it wants.
-   */
+    DC * dc = DC_GetDCPtr( hdc );
+    if (!dc || !dc->funcs->pGetTextExtentPoint ||
+        !dc->funcs->pGetTextExtentPoint( dc, str, count, size ))
+        return FALSE;
 
-    if(!count) count = lstrlenW(str);
-    p = HeapAlloc( GetProcessHeap(), 0, count+1 );
-    lstrcpynWtoA(p, str, count+1);
-    ret = GetTextExtentPoint32A( hdc, p, count, size );
-    HeapFree( GetProcessHeap(), 0, p );
-    return ret;
+    TRACE("(%08x %s %d %p): returning %d,%d\n",
+          hdc, debugstr_wn (str, count), count, size, size->cx, size->cy );
+    return TRUE;
 }
 
 
@@ -938,19 +934,36 @@ BOOL WINAPI GetTextExtentPointW( HDC hdc, LPCWSTR str, INT count,
  *           GetTextExtentExPointA    (GDI32.228)
  */
 BOOL WINAPI GetTextExtentExPointA( HDC hdc, LPCSTR str, INT count,
-                                       INT maxExt, LPINT lpnFit,
-                                       LPINT alpDx, LPSIZE size )
+				   INT maxExt, LPINT lpnFit,
+				   LPINT alpDx, LPSIZE size )
+{
+    LPWSTR p;
+    BOOL ret;
+
+  /* Docs say str should be 0 terminated here, but we'll use count just in case
+   */ 
+
+    p = HeapAlloc( GetProcessHeap(), 0, (count+1) * sizeof(WCHAR) );
+    lstrcpynAtoW(p, str, count+1);
+    ret = GetTextExtentExPointW( hdc, p, count, maxExt, lpnFit, alpDx, size);
+    HeapFree( GetProcessHeap(), 0, p );
+    return ret;
+}
+
+
+/***********************************************************************
+ *           GetTextExtentExPointW    (GDI32.229)
+ */
+
+BOOL WINAPI GetTextExtentExPointW( HDC hdc, LPCWSTR str, INT count,
+				   INT maxExt, LPINT lpnFit,
+				   LPINT alpDx, LPSIZE size )
 {
     int index, nFit, extent;
     SIZE tSize;
-    DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
+    DC * dc = DC_GetDCPtr( hdc );
 
-    if (!dc)
-    {
-	if (!(dc = (DC *)GDI_GetObjPtr( hdc, METAFILE_DC_MAGIC )))
-	    return FALSE;
-    }
-    if (!dc->funcs->pGetTextExtentPoint) return FALSE;
+    if (!dc || !dc->funcs->pGetTextExtentPoint) return FALSE;
 
     size->cx = size->cy = nFit = extent = 0;
     for(index = 0; index < count; index++)
@@ -967,37 +980,13 @@ BOOL WINAPI GetTextExtentExPointA( HDC hdc, LPCSTR str, INT count,
         else break;
     }
     size->cx = extent;
-   *lpnFit = nFit;
+    *lpnFit = nFit;
 
-    TRACE("(%08x '%.*s' %d) returning %d %d %d\n",
-          hdc,count,str,maxExt,nFit, size->cx,size->cy);
+    TRACE("(%08x %s %d) returning %d %d %d\n",
+          hdc,debugstr_wn(str,count),maxExt,nFit, size->cx,size->cy);
     return TRUE;
 }
 
-
-/***********************************************************************
- *           GetTextExtentExPointW    (GDI32.229)
- */
-
-BOOL WINAPI GetTextExtentExPointW( HDC hdc, LPCWSTR str, INT count,
-                                       INT maxExt, LPINT lpnFit,
-                                       LPINT alpDx, LPSIZE size )
-{
-    LPSTR p;
-    BOOL ret;
-
-  /* Docs say str should be 0 terminated here, but we'll use count just in case
-   */ 
-
-    if(!count) count = lstrlenW(str);
-    p = HeapAlloc( GetProcessHeap(), 0, count+1 );
-    lstrcpynWtoA(p, str, count+1);
-    ret = GetTextExtentExPointA( hdc, p, count, maxExt,
-                                        lpnFit, alpDx, size);
-    HeapFree( GetProcessHeap(), 0, p );
-    return ret;
-}
-
 /***********************************************************************
  *           GetTextMetrics16    (GDI.93)
  */
diff --git a/objects/text.c b/objects/text.c
index 3c4714b2b70..36b0624538d 100644
--- a/objects/text.c
+++ b/objects/text.c
@@ -374,29 +374,33 @@ BOOL16 WINAPI ExtTextOut16( HDC16 hdc, INT16 x, INT16 y, UINT16 flags,
 
 
 /***********************************************************************
- *           ExtTextOut32A    (GDI32.98)
+ *           ExtTextOutA    (GDI32.98)
  */
 BOOL WINAPI ExtTextOutA( HDC hdc, INT x, INT y, UINT flags,
                              const RECT *lprect, LPCSTR str, UINT count,
                              const INT *lpDx )
 {
-    DC * dc = DC_GetDCPtr( hdc );
-    return dc && dc->funcs->pExtTextOut && 
-    	   dc->funcs->pExtTextOut(dc,x,y,flags,lprect,str,count,lpDx);
+    /* str need not be \0 terminated but lstrcpynAtoW adds \0 so we allocate one
+       more byte */
+    LPWSTR p = HeapAlloc( GetProcessHeap(), 0, (count+1) * sizeof(WCHAR) );
+    INT ret;
+    lstrcpynAtoW( p, str, count+1 );
+    ret = ExtTextOutW( hdc, x, y, flags, lprect, p, count, lpDx );
+    HeapFree( GetProcessHeap(), 0, p );
+    return ret;
 }
 
 
 /***********************************************************************
- *           ExtTextOut32W    (GDI32.99)
+ *           ExtTextOutW    (GDI32.99)
  */
 BOOL WINAPI ExtTextOutW( HDC hdc, INT x, INT y, UINT flags,
                              const RECT *lprect, LPCWSTR str, UINT count,
                              const INT *lpDx )
 {
-    LPSTR p = HEAP_strdupWtoA( GetProcessHeap(), 0, str );
-    INT ret = ExtTextOutA( hdc, x, y, flags, lprect, p, count, lpDx );
-    HeapFree( GetProcessHeap(), 0, p );
-    return ret;
+    DC * dc = DC_GetDCPtr( hdc );
+    return dc && dc->funcs->pExtTextOut && 
+        dc->funcs->pExtTextOut(dc,x,y,flags,lprect,str,count,lpDx);
 }
 
 
diff --git a/tsx11/X11_calls b/tsx11/X11_calls
index d2caea7522c..cab20a2179e 100644
--- a/tsx11/X11_calls
+++ b/tsx11/X11_calls
@@ -46,8 +46,8 @@ XDrawLines
 XDrawPoint
 XDrawRectangle
 XDrawSegments
-XDrawString
-XDrawText
+XDrawString16
+XDrawText16
 XEmptyRegion
 XEqualRegion
 XFillArc
@@ -157,8 +157,8 @@ XSubImage
 XSubtractRegion
 XSync
 XSynchronize
-XTextExtents
-XTextWidth
+XTextExtents16
+XTextWidth16
 XUngrabKeyboard
 XUngrabPointer
 XUngrabServer
diff --git a/tsx11/ts_xlib.c b/tsx11/ts_xlib.c
index f6e4ab12410..6912f058736 100644
--- a/tsx11/ts_xlib.c
+++ b/tsx11/ts_xlib.c
@@ -598,25 +598,25 @@ int  TSXDrawSegments(Display* a0, Drawable a1, GC a2, XSegment* a3, int a4)
   return r;
 }
 
-int  TSXDrawString(Display* a0, Drawable a1, GC a2, int a3, int a4, const  char* a5, int a6)
+int  TSXDrawString16(Display* a0, Drawable a1, GC a2, int a3, int a4, const  XChar2b* a5, int a6)
 {
   int  r;
-  TRACE("Call XDrawString\n");
+  TRACE("Call XDrawString16\n");
   EnterCriticalSection( &X11DRV_CritSection );
-  r = XDrawString(a0, a1, a2, a3, a4, a5, a6);
+  r = XDrawString16(a0, a1, a2, a3, a4, a5, a6);
   LeaveCriticalSection( &X11DRV_CritSection );
-  TRACE("Ret XDrawString\n");
+  TRACE("Ret XDrawString16\n");
   return r;
 }
 
-int  TSXDrawText(Display* a0, Drawable a1, GC a2, int a3, int a4, XTextItem* a5, int a6)
+int  TSXDrawText16(Display* a0, Drawable a1, GC a2, int a3, int a4, XTextItem16* a5, int a6)
 {
   int  r;
-  TRACE("Call XDrawText\n");
+  TRACE("Call XDrawText16\n");
   EnterCriticalSection( &X11DRV_CritSection );
-  r = XDrawText(a0, a1, a2, a3, a4, a5, a6);
+  r = XDrawText16(a0, a1, a2, a3, a4, a5, a6);
   LeaveCriticalSection( &X11DRV_CritSection );
-  TRACE("Ret XDrawText\n");
+  TRACE("Ret XDrawText16\n");
   return r;
 }
 
@@ -1258,25 +1258,25 @@ int  TSXSync(Display* a0, int a1)
   return r;
 }
 
-int  TSXTextExtents(XFontStruct* a0, const  char* a1, int a2, int* a3, int* a4, int* a5, XCharStruct* a6)
+int  TSXTextExtents16(XFontStruct* a0, const  XChar2b* a1, int a2, int* a3, int* a4, int* a5, XCharStruct* a6)
 {
   int  r;
-  TRACE("Call XTextExtents\n");
+  TRACE("Call XTextExtents16\n");
   EnterCriticalSection( &X11DRV_CritSection );
-  r = XTextExtents(a0, a1, a2, a3, a4, a5, a6);
+  r = XTextExtents16(a0, a1, a2, a3, a4, a5, a6);
   LeaveCriticalSection( &X11DRV_CritSection );
-  TRACE("Ret XTextExtents\n");
+  TRACE("Ret XTextExtents16\n");
   return r;
 }
 
-int  TSXTextWidth(XFontStruct* a0, const  char* a1, int a2)
+int  TSXTextWidth16(XFontStruct* a0, const  XChar2b* a1, int a2)
 {
   int  r;
-  TRACE("Call XTextWidth\n");
+  TRACE("Call XTextWidth16\n");
   EnterCriticalSection( &X11DRV_CritSection );
-  r = XTextWidth(a0, a1, a2);
+  r = XTextWidth16(a0, a1, a2);
   LeaveCriticalSection( &X11DRV_CritSection );
-  TRACE("Ret XTextWidth\n");
+  TRACE("Ret XTextWidth16\n");
   return r;
 }
 
-- 
GitLab