Fully implement DrawTextEx* functions.

diff --git a/dlls/user/text.c b/dlls/user/text.c
index 05962f3..84a1f11 100644
--- a/dlls/user/text.c
+++ b/dlls/user/text.c
@@ -225,8 +225,8 @@
  *           DrawTextExW    (USER32.@)
  */
 #define MAX_STATIC_BUFFER 1024
-INT WINAPI DrawTextExW( HDC hdc, LPCWSTR str, INT i_count, 
-                     LPRECT rect, UINT flags, LPDRAWTEXTPARAMS dtp )
+INT WINAPI DrawTextExW( HDC hdc, LPWSTR str, INT i_count,
+                        LPRECT rect, UINT flags, LPDRAWTEXTPARAMS dtp )
 {
     SIZE size;
     const WCHAR *strPtr;
@@ -235,6 +235,7 @@
     int prefix_x = 0;
     int prefix_end = 0;
     TEXTMETRICW tm;
+    int lmargin = 0, rmargin = 0;
     int x = rect->left, y = rect->top;
     int width = rect->right - rect->left;
     int max_width = 0;
@@ -242,10 +243,8 @@
     TRACE("%s, %d , [(%d,%d),(%d,%d)]\n", debugstr_wn (str, count), count,
 	  rect->left, rect->top, rect->right, rect->bottom);
 
-    if(dtp) {
-        FIXME("Ignores params:%d,%d,%d,%d\n", dtp->cbSize,
-              dtp->iTabLength, dtp->iLeftMargin, dtp->iRightMargin);
-    }
+   if (dtp) TRACE("Params: iTabLength=%d, iLeftMargin=%d, iRightMargin=%d\n",
+          dtp->iTabLength, dtp->iLeftMargin, dtp->iRightMargin);
 
     if (!str) return 0;
     if (count == -1) count = strlenW(str);
@@ -258,8 +257,17 @@
     else
 	lh = tm.tmHeight;
 
+    if (dtp)
+    {
+        lmargin = dtp->iLeftMargin * tm.tmAveCharWidth;
+        rmargin = dtp->iRightMargin * tm.tmAveCharWidth;
+        if (!(flags & (DT_CENTER | DT_RIGHT)))
+            x += lmargin;
+        dtp->uiLengthDrawn = 0;     /* This param RECEIVES number of chars processed */
+    }
+
     if (flags & DT_TABSTOP)
-	tabstop = flags >> 8;
+	tabstop = dtp ? dtp->iTabLength : flags >> 8;
 
     if (flags & DT_EXPANDTABS)
     {
@@ -292,7 +300,7 @@
 
 	if (flags & DT_SINGLELINE)
 	{
-	    if (flags & DT_VCENTER) y = rect->top + 
+	    if (flags & DT_VCENTER) y = rect->top +
 	    	(rect->bottom - rect->top) / 2 - size.cy / 2;
 	    else if (flags & DT_BOTTOM) y = rect->bottom - size.cy;
 
@@ -312,7 +320,7 @@
                     if (flags & DT_WORD_ELLIPSIS)
 	                flags |= DT_WORDBREAK;
 
-		    if (flags & DT_PATH_ELLIPSIS) 
+		    if (flags & DT_PATH_ELLIPSIS)
 	            {
 			WCHAR* lastBkSlash = NULL;
 			WCHAR* lastFwdSlash = NULL;
@@ -320,14 +328,11 @@
                         line[totalLen] = '\0';
 	                lastBkSlash = strrchrW(line, BACK_SLASHW[0]);
 	                lastFwdSlash = strrchrW(line, FORWARD_SLASHW[0]);
-			fnameDelim = lastFwdSlash ? lastFwdSlash : lastBkSlash;
-			if (lastBkSlash && lastFwdSlash) /* which is last? */
-			   if (lastBkSlash > lastFwdSlash)
-				fnameDelim = lastBkSlash;
+                        fnameDelim = lastBkSlash > lastFwdSlash ? lastBkSlash : lastFwdSlash;
 
 	                if (fnameDelim)
 	                    fnameLen = &line[totalLen] - fnameDelim;
-	                else 
+	                else
 	                    fnameDelim = (WCHAR*)str;
 
 	                strcpyW(swapStr, ELLIPSISW);
@@ -343,16 +348,16 @@
 	            }
 
                     len = MAX_STATIC_BUFFER;
-	            TEXT_NextLineW(hdc, swapStr, &count, line, &len, width, flags); 
+	            TEXT_NextLineW(hdc, swapStr, &count, line, &len, width, flags);
 
 	            /* if only the ELLIPSIS will fit, just let it be clipped */
 	            len = max(3, len);
 	            GetTextExtentPointW(hdc, line, len, &size);
 
 	            /* FIXME:
-	             * NextLine uses GetTextExtentPoint for each character, 
+	             * NextLine uses GetTextExtentPoint for each character,
 	             * rather than GetCharABCWidth...  So the whitespace between
-	             * characters is ignored in the width measurement, and the 
+	             * characters is ignored in the width measurement, and the
 	             * reported len is too great.  To compensate, we must get
 	             * the width of the entire line and adjust len accordingly.
 	            */
@@ -365,10 +370,10 @@
 	            if (fnameLen < len-3) /* some of the path will fit */
 	            {
 	                /* put the ELLIPSIS between the path and filename */
-	                strncpyW(swapStr, &line[fnameLen+3], len-3-fnameLen); 
+	                strncpyW(swapStr, &line[fnameLen+3], len-3-fnameLen);
 	                swapStr[len-3-fnameLen] = '\0';
-	                strcatW(swapStr, ELLIPSISW); 
-	                strncpyW(swapStr+strlenW(swapStr), &line[3], fnameLen); 
+	                strcatW(swapStr, ELLIPSISW);
+	                strncpyW(swapStr+strlenW(swapStr), &line[3], fnameLen);
 	            }
 	            else
 	            {
@@ -382,12 +387,15 @@
 	            line[len] = '\0';
 	            strPtr = NULL;
 	        }
+               if (flags & DT_MODIFYSTRING)
+                    strcpyW(str, swapStr);
 	    }
 	}
 	if (!(flags & DT_CALCRECT))
 	{
-	    if (!ExtTextOutW(hdc, x, y, (flags & DT_NOCLIP) ? 0 : ETO_CLIPPED,
-                             rect, line, len, NULL )) return 0;
+           if (!ExtTextOutW( hdc, x, y,
+                    ( (flags & DT_NOCLIP) ? 0 : ETO_CLIPPED )  |  ( (flags & DT_RTLREADING) ? 0 : ETO_RTLREADING ),
+                    rect, line, len, NULL ))  return 0;
             if (prefix_offset != -1)
             {
                 HPEN hpen = CreatePen( PS_SOLID, 1, GetTextColor(hdc) );
@@ -410,20 +418,26 @@
 		    break;
 	    }
 	}
+        if (dtp)
+            dtp->uiLengthDrawn += len;
     }
     while (strPtr);
+
     if (flags & DT_CALCRECT)
     {
 	rect->right = rect->left + max_width;
 	rect->bottom = y;
+        if (dtp)
+            rect->right += lmargin + rmargin;
     }
     return y - rect->top;
 }
 
 /***********************************************************************
- *           DrawTextA    (USER32.@)
+ *           DrawTextExA    (USER32.@)
  */
-INT WINAPI DrawTextA( HDC hdc, LPCSTR str, INT count, LPRECT rect, UINT flags )
+INT WINAPI DrawTextExA( HDC hdc, LPSTR str, INT count,
+                        LPRECT rect, UINT flags, LPDRAWTEXTPARAMS dtp )
 {
    WCHAR *wstr;
    INT ret = 0;
@@ -437,6 +451,8 @@
    {
        MultiByteToWideChar( CP_ACP, 0, str, count, wstr, wcount );
        ret = DrawTextExW( hdc, wstr, wcount, rect, flags, NULL );
+       if (flags & DT_MODIFYSTRING)
+            WideCharToMultiByte( CP_ACP, 0, wstr, -1, str, count, NULL, NULL );
        HeapFree(GetProcessHeap(), 0, wstr);
    }
    return ret;
@@ -445,24 +461,17 @@
 /***********************************************************************
  *           DrawTextW    (USER32.@)
  */
-INT WINAPI DrawTextW( HDC hdc, LPCWSTR str, INT count,
-                          LPRECT rect, UINT flags )
+INT WINAPI DrawTextW( HDC hdc, LPCWSTR str, INT count, LPRECT rect, UINT flags )
 {
-    return DrawTextExW(hdc, str, count, rect, flags, NULL);
+    return DrawTextExW(hdc, (LPWSTR)str, count, rect, flags, NULL);
 }
 
 /***********************************************************************
- *           DrawTextExA    (USER32.@)
+ *           DrawTextA    (USER32.@)
  */
-INT WINAPI DrawTextExA( HDC hdc, LPCSTR str, INT count,
-                     LPRECT rect, UINT flags, LPDRAWTEXTPARAMS dtp )
+INT WINAPI DrawTextA( HDC hdc, LPCSTR str, INT count, LPRECT rect, UINT flags )
 {
-    TRACE("(%d,%s,%d,%p,0x%08x,%p)\n",hdc,debugstr_an(str,count),count,rect,flags,dtp);
-    if(dtp) {
-        FIXME("Ignores params:%d,%d,%d,%d\n",dtp->cbSize,
-                   dtp->iTabLength,dtp->iLeftMargin,dtp->iRightMargin);
-    }
-    return DrawTextA(hdc,str,count,rect,flags);
+    return DrawTextExA( hdc, (LPSTR)str, count, rect, flags, NULL );
 }
 
 /***********************************************************************
diff --git a/include/winuser.h b/include/winuser.h
index 9675580..8caaa63 100644
--- a/include/winuser.h
+++ b/include/winuser.h
@@ -3499,30 +3499,32 @@
 BOOL      WINAPI DrawCaptionTempA(HWND,HDC,const RECT*,HFONT,HICON,LPCSTR,UINT);
 BOOL      WINAPI DrawCaptionTempW(HWND,HDC,const RECT*,HFONT,HICON,LPCWSTR,UINT);
 #define     DrawCaptionTemp WINELIB_NAME_AW(DrawCaptionTemp)
-BOOL      WINAPI DrawEdge(HDC,LPRECT,UINT,UINT);
-BOOL      WINAPI DrawFocusRect(HDC,const RECT*);
-BOOL      WINAPI DrawFrameControl(HDC,LPRECT,UINT,UINT);
-BOOL      WINAPI DrawIcon(HDC,INT,INT,HICON);
-BOOL      WINAPI DrawIconEx(HDC,INT,INT,HICON,INT,INT,
-				UINT,HBRUSH,UINT);
-BOOL      WINAPI DrawMenuBar(HWND);
-BOOL      WINAPI DrawStateA(HDC,HBRUSH,DRAWSTATEPROC,LPARAM,WPARAM,INT,INT,INT,INT,UINT);
-BOOL      WINAPI DrawStateW(HDC,HBRUSH,DRAWSTATEPROC,LPARAM,WPARAM,INT,INT,INT,INT,UINT);
+BOOL        WINAPI DrawEdge(HDC,LPRECT,UINT,UINT);
+BOOL        WINAPI DrawFocusRect(HDC,const RECT*);
+BOOL        WINAPI DrawFrameControl(HDC,LPRECT,UINT,UINT);
+BOOL        WINAPI DrawIcon(HDC,INT,INT,HICON);
+BOOL        WINAPI DrawIconEx(HDC,INT,INT,HICON,INT,INT,UINT,HBRUSH,UINT);
+BOOL        WINAPI DrawMenuBar(HWND);
+BOOL        WINAPI DrawStateA(HDC,HBRUSH,DRAWSTATEPROC,LPARAM,WPARAM,INT,INT,INT,INT,UINT);
+BOOL        WINAPI DrawStateW(HDC,HBRUSH,DRAWSTATEPROC,LPARAM,WPARAM,INT,INT,INT,INT,UINT);
 #define     DrawState WINELIB_NAME_AW(DrawState)
-INT       WINAPI DrawTextA(HDC,LPCSTR,INT,LPRECT,UINT);
-INT       WINAPI DrawTextW(HDC,LPCWSTR,INT,LPRECT,UINT);
+INT         WINAPI DrawTextA(HDC,LPCSTR,INT,LPRECT,UINT);
+INT         WINAPI DrawTextW(HDC,LPCWSTR,INT,LPRECT,UINT);
 #define     DrawText WINELIB_NAME_AW(DrawText)
-BOOL      WINAPI EmptyClipboard(void);
-UINT      WINAPI EnableMenuItem(HMENU,UINT,UINT);
-BOOL      WINAPI EnableScrollBar(HWND,INT,UINT);
-BOOL      WINAPI EnableWindow(HWND,BOOL);
-BOOL      WINAPI EndDeferWindowPos(HDWP);
-BOOL      WINAPI EndDialog(HWND,INT);
-BOOL      WINAPI EndPaint(HWND,const PAINTSTRUCT*);
-BOOL      WINAPI EnumChildWindows(HWND,WNDENUMPROC,LPARAM);
-UINT      WINAPI EnumClipboardFormats(UINT);
-INT       WINAPI EnumPropsA(HWND,PROPENUMPROCA);
-INT       WINAPI EnumPropsW(HWND,PROPENUMPROCW);
+INT         WINAPI DrawTextExA(HDC,LPSTR,INT,LPRECT,UINT,LPDRAWTEXTPARAMS);
+INT         WINAPI DrawTextExW(HDC,LPWSTR,INT,LPRECT,UINT,LPDRAWTEXTPARAMS);
+#define     DrawTextEx WINELIB_NAME_AW(DrawTextEx)
+BOOL        WINAPI EmptyClipboard(void);
+UINT        WINAPI EnableMenuItem(HMENU,UINT,UINT);
+BOOL        WINAPI EnableScrollBar(HWND,INT,UINT);
+BOOL        WINAPI EnableWindow(HWND,BOOL);
+BOOL        WINAPI EndDeferWindowPos(HDWP);
+BOOL        WINAPI EndDialog(HWND,INT);
+BOOL        WINAPI EndPaint(HWND,const PAINTSTRUCT*);
+BOOL        WINAPI EnumChildWindows(HWND,WNDENUMPROC,LPARAM);
+UINT        WINAPI EnumClipboardFormats(UINT);
+INT         WINAPI EnumPropsA(HWND,PROPENUMPROCA);
+INT         WINAPI EnumPropsW(HWND,PROPENUMPROCW);
 #define     EnumProps WINELIB_NAME_AW(EnumProps)
 BOOL      WINAPI EnumWindows(WNDENUMPROC,LPARAM);
 BOOL        WINAPI EnumWindowStationsA(WINSTAENUMPROCA,LPARAM);