DrawText

Travis Michielsen tjmichielsen at yahoo.com
Tue Jul 17 09:35:17 CDT 2001


Hi all,

I have put together a quick patch that SHOULD fully implement the DrawText
functions.  However, I have not had time to thoroughly tested most of the logic
so I thought I would post it here rather than sending it directly to the
patches list.  I welcome any/all comments/suggestions.

 - Travis Michielsen



Index: wine/dlls/user/text.c
===================================================================
RCS file: /home/wine/wine/dlls/user/text.c,v
retrieving revision 1.12
diff -u -r1.12 text.c
--- wine/dlls/user/text.c       2001/07/17 00:51:00     1.12
+++ wine/dlls/user/text.c       2001/07/17 13:55:22
@@ -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,35 @@
                    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.@)
+ *           DrawTextW    (USER32.@)
  */
-INT WINAPI DrawTextA( HDC hdc, LPCSTR 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);
+}
+
+/***********************************************************************
+ *           DrawTextExA    (USER32.@)
+ */
+INT WINAPI DrawTextExA( HDC hdc, LPCSTR str, INT count,
+                     LPRECT rect, UINT flags, LPDRAWTEXTPARAMS dtp )
 {
    WCHAR *wstr;
    INT ret = 0;
@@ -437,32 +460,19 @@
    {
        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;
 }

 /***********************************************************************
- *           DrawTextW    (USER32.@)
- */
-INT WINAPI DrawTextW( HDC hdc, LPCWSTR str, INT count,
-                          LPRECT rect, UINT flags )
-{
-    return DrawTextExW(hdc, 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, str, count, rect, flags, NULL );
 }
 
 /***********************************************************************

__________________________________________________
Do You Yahoo!?
Get personalized email addresses from Yahoo! Mail
http://personal.mail.yahoo.com/




More information about the wine-devel mailing list