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/fo... ============================================================================== --- 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 );