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);