Author: gadamopoulos
Date: Sun Oct 25 10:32:01 2009
New Revision: 43734
URL: 
http://svn.reactos.org/svn/reactos?rev=43734&view=rev
Log:
Sync DrawText funtions with wine 1.1.32
Fixes all user32 text tests
Modified:
    trunk/reactos/dll/win32/user32/windows/font.c
Modified: trunk/reactos/dll/win32/user32/windows/font.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/user32/windows/f…
==============================================================================
--- trunk/reactos/dll/win32/user32/windows/font.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/user32/windows/font.c [iso-8859-1] Sun Oct 25 10:32:01 2009
@@ -31,6 +31,8 @@
 #include <user32.h>
 #include <wine/debug.h>
+
+WINE_DEFAULT_DEBUG_CHANNEL(text);
 /* FUNCTIONS *****************************************************************/
@@ -343,7 +345,7 @@
     unsigned int len_ellipsis;
     unsigned int lo, mid, hi;
-    len_ellipsis = wcslen (ELLIPSISW);
+    len_ellipsis = strlenW (ELLIPSISW);
     if (len_ellipsis > max_len) len_ellipsis = max_len;
     if (*len_str > max_len - len_ellipsis)
         *len_str = max_len - len_ellipsis;
@@ -368,7 +370,7 @@
     /* Now this should take only a couple iterations at most. */
     for ( ; ; )
     {
-        wcsncpy (str + *len_str, ELLIPSISW, len_ellipsis);
+        memcpy(str + *len_str, ELLIPSISW, len_ellipsis*sizeof(WCHAR));
         if (!GetTextExtentExPointW (hdc, str, *len_str + len_ellipsis, width,
                                     NULL, NULL, size)) break;
@@ -383,8 +385,8 @@
     if (modstr)
     {
-        wcsncpy (modstr, str, *len_str);
-        *(str+*len_str) = '\0';
+        memcpy (modstr, str, *len_str * sizeof(WCHAR));
+        modstr[*len_str] = '\0';
     }
 }
@@ -435,12 +437,12 @@
                                 unsigned int *len_str, int width, SIZE *size,
                                 WCHAR *modstr, ellipsis_data *pellip)
 {
-    unsigned int len_ellipsis;
+    int len_ellipsis;
     int len_trailing;
     int len_under;
     WCHAR *lastBkSlash, *lastFwdSlash, *lastSlash;
-    len_ellipsis = wcslen (ELLIPSISW);
+    len_ellipsis = strlenW (ELLIPSISW);
     if (!max_len) return;
     if (len_ellipsis >= max_len) len_ellipsis = max_len - 1;
     if (*len_str + len_ellipsis >= max_len)
@@ -450,15 +452,15 @@
          */
     str[*len_str] = '\0'; /* to simplify things */
-    lastBkSlash  = wcsrchr (str, BACK_SLASH);
-    lastFwdSlash = wcsrchr (str, FORWARD_SLASH);
+    lastBkSlash  = strrchrW (str, BACK_SLASH);
+    lastFwdSlash = strrchrW (str, FORWARD_SLASH);
     lastSlash = lastBkSlash > lastFwdSlash ? lastBkSlash : lastFwdSlash;
     if (!lastSlash) lastSlash = str;
     len_trailing = *len_str - (lastSlash - str);
     /* overlap-safe movement to the right */
     memmove (lastSlash+len_ellipsis, lastSlash, len_trailing * sizeof(WCHAR));
-    wcsncpy (lastSlash, ELLIPSISW, len_ellipsis);
+    memcpy (lastSlash, ELLIPSISW, len_ellipsis*sizeof(WCHAR));
     len_trailing += len_ellipsis;
     /* From this point on lastSlash actually points to the ellipsis in front
      * of the last slash and len_trailing includes the ellipsis
@@ -488,8 +490,8 @@
     if (modstr)
     {
-        wcsncpy (modstr, str, *len_str);
-        *(str+*len_str) = '\0';
+        memcpy(modstr, str, *len_str * sizeof(WCHAR));
+        modstr[*len_str] = '\0';
     }
 }
@@ -999,7 +1001,7 @@
  *   offset     [in] The offset of the underscored character within str
  *   rect       [in] Clipping rectangle (if not NULL)
  */
-/* WINE synced 22-May-2006 */
+/* Synced with wine 1.1.32 */
 static void TEXT_DrawUnderscore (HDC hdc, int x, int y, const WCHAR *str, int offset,
const RECT *rect)
 {
     int prefix_x;
@@ -1044,13 +1046,13 @@
  * the allowance in DrawTextExA.
  */
 #define MAX_BUFFER 1024
-/* WINE synced 22-May-2006 */
-/*
+/*
  * @implemented
- */
-int WINAPI
-DrawTextExW( HDC hdc, LPWSTR str, INT i_count,
-             LPRECT rect, UINT flags, LPDRAWTEXTPARAMS dtp )
+ *
+ * Synced with wine 1.1.32
+ */
+INT WINAPI DrawTextExW( HDC hdc, LPWSTR str, INT i_count,
+                        LPRECT rect, UINT flags, LPDRAWTEXTPARAMS dtp )
 {
     SIZE size;
     const WCHAR *strPtr;
@@ -1067,16 +1069,33 @@
     int tabwidth /* to keep gcc happy */ = 0;
     int prefix_offset;
     ellipsis_data ellip;
-
-#if 0
+    int invert_y=0;
+
     TRACE("%s, %d, [%s] %08x\n", debugstr_wn (str, count), count,
         wine_dbgstr_rect(rect), flags);
    if (dtp) TRACE("Params: iTabLength=%d, iLeftMargin=%d, iRightMargin=%d\n",
           dtp->iTabLength, dtp->iLeftMargin, dtp->iRightMargin);
-#endif
-
-    if (!str || count == 0) return 0;
+
+    if (!str) return 0;
+
+    strPtr = str;
+
+    if (flags & DT_SINGLELINE)
+        flags &= ~DT_WORDBREAK;
+
+    GetTextMetricsW(hdc, &tm);
+    if (flags & DT_EXTERNALLEADING)
+       lh = tm.tmHeight + tm.tmExternalLeading;
+    else
+       lh = tm.tmHeight;
+
+    if (str[0] && count == 0)
+        return lh;
+
+    if (dtp && dtp->cbSize != sizeof(DRAWTEXTPARAMS))
+        return 0;
+
     if (count == -1)
     {
         count = strlenW(str);
@@ -1085,26 +1104,28 @@
             if( flags & DT_CALCRECT)
             {
                 rect->right = rect->left;
-                rect->bottom = rect->top;
+                if( flags & DT_SINGLELINE)
+                    rect->bottom = rect->top + lh;
+                else
+                    rect->bottom = rect->top;
             }
-            return 0;
-        }
-    }
-    strPtr = str;
-
-    if (flags & DT_SINGLELINE)
-        flags &= ~DT_WORDBREAK;
-
-    GetTextMetricsW(hdc, &tm);
-    if (flags & DT_EXTERNALLEADING)
-        lh = tm.tmHeight + tm.tmExternalLeading;
-    else
-        lh = tm.tmHeight;
+            return lh;
+        }
+    }
+
+    if (GetGraphicsMode(hdc) == GM_COMPATIBLE)
+    {
+        SIZE window_ext, viewport_ext;
+        GetWindowExtEx(hdc, &window_ext);
+        GetViewportExtEx(hdc, &viewport_ext);
+        if ((window_ext.cy > 0) != (viewport_ext.cy > 0))
+            invert_y = 1;
+    }
     if (dtp)
     {
-        lmargin = dtp->iLeftMargin * tm.tmAveCharWidth;
-        rmargin = dtp->iRightMargin * tm.tmAveCharWidth;
+        lmargin = dtp->iLeftMargin;
+        rmargin = dtp->iRightMargin;
         if (!(flags & (DT_CENTER | DT_RIGHT)))
             x += lmargin;
         dtp->uiLengthDrawn = 0;     /* This param RECEIVES number of chars processed
*/
@@ -1113,7 +1134,7 @@
     if (flags & DT_EXPANDTABS)
     {
         int tabstop = ((flags & DT_TABSTOP) && dtp) ? dtp->iTabLength : 8;
-        tabwidth = tm.tmAveCharWidth * tabstop;
+       tabwidth = tm.tmAveCharWidth * tabstop;
     }
     if (flags & DT_CALCRECT) flags |= DT_NOCLIP;
@@ -1134,23 +1155,26 @@
     do
     {
-        len = sizeof(line)/sizeof(line[0]);
-        last_line = !(flags & DT_NOCLIP) && y + ((flags & DT_EDITCONTROL)
? 2*lh-1 : lh) > rect->bottom;
-        strPtr = TEXT_NextLineW(hdc, strPtr, &count, line, &len, width, flags,
&size, last_line, &p_retstr, tabwidth, &prefix_offset, &ellip);
-
-    if (flags & DT_CENTER)
-        x = (rect->left + rect->right - size.cx) / 2;
-    else if (flags & DT_RIGHT) x = rect->right - size.cx;
-
-    if (flags & DT_SINGLELINE)
-    {
-        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;
-    }
-
-    if (!(flags & DT_CALCRECT))
-    {
+       len = sizeof(line)/sizeof(line[0]);
+       if (invert_y)
+            last_line = !(flags & DT_NOCLIP) && y - ((flags &
DT_EDITCONTROL) ? 2*lh-1 : lh) < rect->bottom;
+       else
+            last_line = !(flags & DT_NOCLIP) && y + ((flags &
DT_EDITCONTROL) ? 2*lh-1 : lh) > rect->bottom;
+       strPtr = TEXT_NextLineW(hdc, strPtr, &count, line, &len, width, flags,
&size, last_line, &p_retstr, tabwidth, &prefix_offset, &ellip);
+
+       if (flags & DT_CENTER) x = (rect->left + rect->right -
+                                   size.cx) / 2;
+       else if (flags & DT_RIGHT) x = rect->right - size.cx;
+
+       if (flags & DT_SINGLELINE)
+       {
+           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;
+        }
+
+       if (!(flags & DT_CALCRECT))
+       {
             const WCHAR *str = line;
             int xseg = x;
             while (len)
@@ -1168,12 +1192,11 @@
                 else
                     len_seg = len;
-                if (!(flags & DT_PREFIXONLY)&&
-                    !ExtTextOutW( hdc, xseg, y,
+                if (!ExtTextOutW( hdc, xseg, y,
                                  ((flags & DT_NOCLIP) ? 0 : ETO_CLIPPED) |
                                  ((flags & DT_RTLREADING) ? ETO_RTLREADING : 0),
                                  rect, str, len_seg, NULL ))  return 0;
-                if (prefix_offset != -1 && prefix_offset < len_seg &&
!(flags & DT_HIDEPREFIX))
+                if (prefix_offset != -1 && prefix_offset < len_seg)
                 {
                     TEXT_DrawUnderscore (hdc, xseg, y + tm.tmAscent + 1, str,
prefix_offset, (flags & DT_NOCLIP) ? NULL : rect);
                 }
@@ -1205,7 +1228,10 @@
     else if (size.cx > max_width)
         max_width = size.cx;
-    y += lh;
+        if (invert_y)
+           y -= lh;
+        else
+           y += lh;
         if (dtp)
             dtp->uiLengthDrawn += len;
     }
@@ -1213,8 +1239,8 @@
     if (flags & DT_CALCRECT)
     {
-        rect->right = rect->left + max_width;
-        rect->bottom = y;
+       rect->right = rect->left + max_width;
+       rect->bottom = y;
         if (dtp)
             rect->right += lmargin + rmargin;
     }
@@ -1225,6 +1251,10 @@
     }
     return y - rect->top;
 }
+
+DWORD
+WINAPI
+GdiGetCodePage(HDC hdc);
 /***********************************************************************
  *           DrawTextExA    (USER32.@)
@@ -1234,11 +1264,11 @@
  * string we return.
  *
  * @implemented
- */
-/* WINE synced 22-May-2006 */
-int WINAPI
-DrawTextExA( HDC hdc, LPSTR str, INT count,
-             LPRECT rect, UINT flags, LPDRAWTEXTPARAMS dtp )
+ *
+ * Synced with wine 1.1.32
+ */
+INT WINAPI DrawTextExA( HDC hdc, LPSTR str, INT count,
+                        LPRECT rect, UINT flags, LPDRAWTEXTPARAMS dtp )
 {
    WCHAR *wstr;
    WCHAR *p;
@@ -1247,18 +1277,36 @@
    DWORD wcount;
    DWORD wmax;
    DWORD amax;
+   UINT cp;
    if (!count) return 0;
+   if (!str && count > 0) return 0;
    if( !str || ((count == -1) && !(count = strlen(str))))
    {
+        int lh;
+        TEXTMETRICA tm;
+
+        if (dtp && dtp->cbSize != sizeof(DRAWTEXTPARAMS))
+            return 0;
+
+        GetTextMetricsA(hdc, &tm);
+        if (flags & DT_EXTERNALLEADING)
+            lh = tm.tmHeight + tm.tmExternalLeading;
+        else
+            lh = tm.tmHeight;
+
         if( flags & DT_CALCRECT)
         {
             rect->right = rect->left;
-            rect->bottom = rect->top;
-        }
-        return 0;
+            if( flags & DT_SINGLELINE)
+                rect->bottom = rect->top + lh;
+            else
+                rect->bottom = rect->top;
+        }
+        return lh;
    }
-   wcount = MultiByteToWideChar( CP_ACP, 0, str, count, NULL, 0 );
+   cp = GdiGetCodePage( hdc );
+   wcount = MultiByteToWideChar( cp, 0, str, count, NULL, 0 );
    wmax = wcount;
    amax = count;
    if (flags & DT_MODIFYSTRING)
@@ -1269,7 +1317,7 @@
    wstr = HeapAlloc(GetProcessHeap(), 0, wmax * sizeof(WCHAR));
    if (wstr)
    {
-       MultiByteToWideChar( CP_ACP, 0, str, count, wstr, wcount );
+       MultiByteToWideChar( cp, 0, str, count, wstr, wcount );
        if (flags & DT_MODIFYSTRING)
            for (i=4, p=wstr+wcount; i--; p++) *p=0xFFFE;
            /* Initialise the extra characters so that we can see which ones
@@ -1283,7 +1331,7 @@
              * and so we need to measure it ourselves.
              */
             for (i=4, p=wstr+wcount; i-- && *p != 0xFFFE; p++) wcount++;
-            WideCharToMultiByte( CP_ACP, 0, wstr, wcount, str, amax, NULL, NULL );
+            WideCharToMultiByte( cp, 0, wstr, wcount, str, amax, NULL, NULL );
        }
        HeapFree(GetProcessHeap(), 0, wstr);
    }
@@ -1295,15 +1343,15 @@
  *
  * @implemented
  */
-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 )
 {
     DRAWTEXTPARAMS dtp;
     memset (&dtp, 0, sizeof(dtp));
+    dtp.cbSize = sizeof(dtp);
     if (flags & DT_TABSTOP)
     {
-        dtp.iTabLength = (flags >> 8) && 0xff;
+        dtp.iTabLength = (flags >> 8) & 0xff;
         flags &= 0xffff00ff;
     }
     return DrawTextExW(hdc, (LPWSTR)str, count, rect, flags, &dtp);
@@ -1314,15 +1362,15 @@
  *
  * @implemented
  */
-int WINAPI
-DrawTextA( HDC hdc, LPCSTR str, INT count, LPRECT rect, UINT flags )
+INT WINAPI DrawTextA( HDC hdc, LPCSTR str, INT count, LPRECT rect, UINT flags )
 {
     DRAWTEXTPARAMS dtp;
     memset (&dtp, 0, sizeof(dtp));
+    dtp.cbSize = sizeof(dtp);
     if (flags & DT_TABSTOP)
     {
-        dtp.iTabLength = (flags >> 8) && 0xff;
+        dtp.iTabLength = (flags >> 8) & 0xff;
         flags &= 0xffff00ff;
     }
     return DrawTextExA( hdc, (LPSTR)str, count, rect, flags, &dtp );