Author: jimtabor Date: Thu Sep 3 12:59:26 2015 New Revision: 68935
URL: http://svn.reactos.org/svn/reactos?rev=68935&view=rev Log: [RTL] - Fix Underscore drawing for Win32k and related functions.
Added: trunk/reactos/win32ss/user/rtl/text.c - copied, changed from r68599, trunk/reactos/win32ss/user/user32/windows/font.c
Copied: trunk/reactos/win32ss/user/rtl/text.c (from r68599, trunk/reactos/win32ss/user/user32/windows/font.c) URL: http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/user/rtl/text.c?p2=... ============================================================================== --- trunk/reactos/win32ss/user/user32/windows/font.c [iso-8859-1] (original) +++ trunk/reactos/win32ss/user/rtl/text.c [iso-8859-1] Thu Sep 3 12:59:26 2015 @@ -18,8 +18,8 @@ */ /* * PROJECT: ReactOS user32.dll - * FILE: lib/user32/windows/input.c - * PURPOSE: Input + * FILE: win32ss/user/rtl/text.c + * PURPOSE: Draw Text * PROGRAMMER: Casper S. Hornstrup (chorns@users.sourceforge.net) * UPDATE HISTORY: * 09-05-2001 CSH Created @@ -27,14 +27,14 @@
/* INCLUDES ******************************************************************/
+#ifdef _WIN32K_ +#include <win32k.h> +DBG_DEFAULT_CHANNEL(UserMenu); +#else #include <user32.h> - #include <wine/debug.h> - WINE_DEFAULT_DEBUG_CHANNEL(text); - -DWORD WINAPI GdiGetCodePage(HDC hdc); - +#endif
/* FUNCTIONS *****************************************************************/
@@ -47,7 +47,7 @@ #define assert(e) ((e) ? (void)0 : _font_assert(#e, __FILE__, __LINE__))
#else -#include <assert.h> +#include <assert.h>
#endif
@@ -55,40 +55,13 @@ { /* Assertion failed at foo.c line 45: x<y */ DbgPrint("Assertion failed at %s line %d: %s\n", file, line, msg); - ExitProcess(3); +#ifdef _WIN32K_ + ASSERT(FALSE); +#else + ExitProcess(3); for(;;); /* eliminate warning by mingw */ +#endif } - -/* - * @implemented - */ -LONG -WINAPI -TabbedTextOutA( - HDC hDC, - int X, - int Y, - LPCSTR lpString, - int nCount, - int nTabPositions, - CONST INT *lpnTabStopPositions, - int nTabOrigin) -{ - LONG ret; - DWORD len; - LPWSTR strW; - UINT cp = GdiGetCodePage( hDC ); // CP_ACP - - len = MultiByteToWideChar(cp, 0, lpString, nCount, NULL, 0); - if (!len) return 0; - strW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR)); - if (!strW) return 0; - MultiByteToWideChar(cp, 0, lpString, nCount, strW, len); - ret = TabbedTextOutW(hDC, X, Y, strW, len, nTabPositions, lpnTabStopPositions, nTabOrigin); - HeapFree(GetProcessHeap(), 0, strW); - return ret; -} -
/*********************************************************************** * TEXT_TabbedTextOut @@ -98,9 +71,15 @@ * than TA_LEFT|TA_TOP. But we want bug-for-bug compatibility :-) */ /* WINE synced 22-May-2006 */ -static LONG TEXT_TabbedTextOut( HDC hdc, INT x, INT y, LPCWSTR lpstr, - INT count, INT cTabStops, const INT *lpTabPos, INT nTabOrg, - BOOL fDisplayText ) +LONG TEXT_TabbedTextOut( HDC hdc, + INT x, + INT y, + LPCWSTR lpstr, + INT count, + INT cTabStops, + const INT *lpTabPos, + INT nTabOrg, + BOOL fDisplayText ) { INT defWidth; SIZE extent; @@ -117,8 +96,13 @@ } else { +#ifdef _WIN32K_ + TEXTMETRICW tm; + GreGetTextMetricsW( hdc, &tm ); +#else TEXTMETRICA tm; GetTextMetricsA( hdc, &tm ); +#endif defWidth = 8 * tm.tmAveCharWidth; }
@@ -135,7 +119,11 @@ for (j = i; j < count; j++) if (lpstr[j] == '\t') break; /* get the extent of the normal character part */ +#ifdef _WIN32K_ + GreGetTextExtentW( hdc, (LPWSTR)lpstr + i, j - i , &extent, 0 ); +#else GetTextExtentPointW( hdc, lpstr + i, j - i , &extent ); +#endif /* and if there is a <tab>, calculate its position */ if( i) { /* get x coordinate for the drawing of this string */ @@ -179,74 +167,18 @@ r.top = y; r.right = x; r.bottom = y + extent.cy; +#ifdef _WIN32K_ + GreExtTextOutW( hdc, x0, y, GreGetBkMode(hdc) == OPAQUE ? ETO_OPAQUE : 0, + &r, (LPWSTR)lpstr + i, j - i, NULL, 0 ); +#else ExtTextOutW( hdc, x0, y, GetBkMode(hdc) == OPAQUE ? ETO_OPAQUE : 0, &r, lpstr + i, j - i, NULL ); +#endif } count -= j; lpstr += j; } return MAKELONG(x - start, extent.cy); -} - -/* - * @implemented - */ -LONG -WINAPI -TabbedTextOutW( - HDC hDC, - int X, - int Y, - LPCWSTR lpString, - int nCount, - int nTabPositions, - CONST INT *lpnTabStopPositions, - int nTabOrigin) -{ - return TEXT_TabbedTextOut(hDC, X, Y, lpString, nCount, nTabPositions, lpnTabStopPositions, nTabOrigin, TRUE); -} - -/* WINE synced 22-May-2006 */ -/* - * @implemented - */ -DWORD -WINAPI -GetTabbedTextExtentA( - HDC hDC, - LPCSTR lpString, - int nCount, - int nTabPositions, - CONST INT *lpnTabStopPositions) -{ - LONG ret; - UINT cp = GdiGetCodePage( hDC ); // CP_ACP - DWORD len; - LPWSTR strW; - - len = MultiByteToWideChar(cp, 0, lpString, nCount, NULL, 0); - if (!len) return 0; - strW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR)); - if (!strW) return 0; - MultiByteToWideChar(cp, 0, lpString, nCount, strW, len); - ret = GetTabbedTextExtentW(hDC, strW, len, nTabPositions, lpnTabStopPositions); - HeapFree(GetProcessHeap(), 0, strW); - return ret; -} - -/* - * @implemented - */ -DWORD -WINAPI -GetTabbedTextExtentW( - HDC hDC, - LPCWSTR lpString, - int nCount, - int nTabPositions, - CONST INT *lpnTabStopPositions) -{ - return TEXT_TabbedTextOut(hDC, 0, 0, lpString, nCount, nTabPositions, lpnTabStopPositions, 0, FALSE); }
/********************************************************************* @@ -349,21 +281,32 @@ { unsigned int len_ellipsis; unsigned int lo, mid, hi; - +#ifdef _WIN32K_ + len_ellipsis = wcslen (ELLIPSISW); +#else len_ellipsis = strlenW (ELLIPSISW); +#endif if (len_ellipsis > max_len) len_ellipsis = max_len; if (*len_str > max_len - len_ellipsis) *len_str = max_len - len_ellipsis;
/* First do a quick binary search to get an upper bound for *len_str. */ if (*len_str > 0 && +#ifdef _WIN32K_ + GreGetTextExtentExW(hdc, str, *len_str, width, NULL, NULL, size, 0) && +#else GetTextExtentExPointW(hdc, str, *len_str, width, NULL, NULL, size) && +#endif size->cx > width) { for (lo = 0, hi = *len_str; lo < hi; ) { mid = (lo + hi) / 2; +#ifdef _WIN32K_ + if (!GreGetTextExtentExW(hdc, str, mid, width, NULL, NULL, size, 0)) +#else if (!GetTextExtentExPointW(hdc, str, mid, width, NULL, NULL, size)) +#endif break; if (size->cx > width) hi = mid; @@ -376,10 +319,13 @@ for ( ; ; ) { memcpy(str + *len_str, ELLIPSISW, len_ellipsis*sizeof(WCHAR)); - +#ifdef _WIN32K_ + if (!GreGetTextExtentExW (hdc, str, *len_str + len_ellipsis, width, + NULL, NULL, size, 0)) break; +#else if (!GetTextExtentExPointW (hdc, str, *len_str + len_ellipsis, width, NULL, NULL, size)) break; - +#endif if (!*len_str || size->cx <= width) break;
(*len_str)--; @@ -446,8 +392,11 @@ int len_trailing; int len_under; WCHAR *lastBkSlash, *lastFwdSlash, *lastSlash; - +#ifdef _WIN32K_ + len_ellipsis = wcslen (ELLIPSISW); +#else len_ellipsis = strlenW (ELLIPSISW); +#endif if (!max_len) return; if (len_ellipsis >= max_len) len_ellipsis = max_len - 1; if (*len_str + len_ellipsis >= max_len) @@ -456,9 +405,13 @@ * the wrong character */ str[*len_str] = '\0'; /* to simplify things */ - +#ifdef _WIN32K_ + lastBkSlash = wcsrchr (str, BACK_SLASH); + lastFwdSlash = wcsrchr (str, FORWARD_SLASH); +#else lastBkSlash = strrchrW (str, BACK_SLASH); lastFwdSlash = strrchrW (str, FORWARD_SLASH); +#endif lastSlash = lastBkSlash > lastFwdSlash ? lastBkSlash : lastFwdSlash; if (!lastSlash) lastSlash = str; len_trailing = *len_str - (lastSlash - str); @@ -474,9 +427,13 @@ len_under = 0; for ( ; ; ) { +#ifdef _WIN32K_ + if (!GreGetTextExtentExW (hdc, str, *len_str + len_ellipsis, width, + NULL, NULL, size, 0)) break; +#else if (!GetTextExtentExPointW (hdc, str, *len_str + len_ellipsis, width, NULL, NULL, size)) break; - +#endif if (lastSlash == str || size->cx <= width) break;
/* overlap-safe movement to the left */ @@ -670,7 +627,11 @@ } } /* Remeasure the string */ +#ifdef _WIN32K_ + GreGetTextExtentExW (hdc, str, *len_str, 0, NULL, NULL, size, 0); +#else GetTextExtentExPointW (hdc, str, *len_str, 0, NULL, NULL, size); +#endif }
/********************************************************************* @@ -918,7 +879,11 @@
j_in_seg = j - seg_j; max_seg_width = width - plen; +#ifdef _WIN32K_ + GreGetTextExtentExW (hdc, dest + seg_j, j_in_seg, max_seg_width, (PULONG)&num_fit, NULL, &size, 0); +#else GetTextExtentExPointW (hdc, dest + seg_j, j_in_seg, max_seg_width, &num_fit, NULL, &size); +#endif
/* The Microsoft handling of various combinations of formats is weird. * The following may very easily be incorrect if several formats are @@ -1059,10 +1024,17 @@ SIZE size; HPEN hpen; HPEN oldPen; - +#ifdef _WIN32K_ + GreGetTextExtentW (hdc, (LPWSTR)str, offset, &size, 0); +#else GetTextExtentPointW (hdc, str, offset, &size); +#endif prefix_x = x + size.cx; +#ifdef _WIN32K_ + GreGetTextExtentW (hdc, (LPWSTR)str, offset+1, &size, 0); +#else GetTextExtentPointW (hdc, str, offset+1, &size); +#endif prefix_end = x + size.cx - 1; /* The above method may eventually be slightly wrong due to kerning etc. */
@@ -1076,13 +1048,21 @@ if (prefix_x < rect->left ) prefix_x = rect->left; if (prefix_end > rect->right) prefix_end = rect->right; } - +#ifdef _WIN32K_ + hpen = NtGdiCreatePen (PS_SOLID, 1, GreGetTextColor (hdc), NULL); + oldPen = NtGdiSelectPen (hdc, hpen); + GreMoveTo (hdc, prefix_x, y, NULL); + NtGdiLineTo (hdc, prefix_end, y); + NtGdiSelectPen (hdc, oldPen); + GreDeleteObject (hpen); +#else hpen = CreatePen (PS_SOLID, 1, GetTextColor (hdc)); oldPen = SelectObject (hdc, hpen); MoveToEx (hdc, prefix_x, y, NULL); LineTo (hdc, prefix_end, y); SelectObject (hdc, oldPen); DeleteObject (hpen); +#endif }
/*********************************************************************** @@ -1097,12 +1077,16 @@ */ #define MAX_BUFFER 1024 /* - * @implemented + * DrawTextExW * * Synced with Wine Staging 1.7.37 */ -INT WINAPI DrawTextExW( HDC hdc, LPWSTR str, INT i_count, - LPRECT rect, UINT flags, LPDRAWTEXTPARAMS dtp ) +INT WINAPI DrawTextExWorker( HDC hdc, + LPWSTR str, + INT i_count, + LPRECT rect, + UINT flags, + LPDRAWTEXTPARAMS dtp ) { SIZE size; const WCHAR *strPtr; @@ -1120,10 +1104,12 @@ int prefix_offset; ellipsis_data ellip; BOOL invert_y=FALSE; - +#ifdef _WIN32K_ + TRACE("%S, %d, %08x\n", str, count, flags); +#else TRACE("%s, %d, [%s] %08x\n", debugstr_wn (str, count), count, wine_dbgstr_rect(rect), flags); - +#endif if (dtp) TRACE("Params: iTabLength=%d, iLeftMargin=%d, iRightMargin=%d\n", dtp->iTabLength, dtp->iLeftMargin, dtp->iRightMargin);
@@ -1133,8 +1119,11 @@
if (flags & DT_SINGLELINE) flags &= ~DT_WORDBREAK; - +#ifdef _WIN32K_ + GreGetTextMetricsW(hdc, &tm); +#else GetTextMetricsW(hdc, &tm); +#endif if (flags & DT_EXTERNALLEADING) lh = tm.tmHeight + tm.tmExternalLeading; else @@ -1145,7 +1134,16 @@
if (dtp && dtp->cbSize != sizeof(DRAWTEXTPARAMS)) return 0; - +#ifdef _WIN32K_ + if (GreGetGraphicsMode(hdc) == GM_COMPATIBLE) + { + SIZE window_ext, viewport_ext; + GreGetWindowExtEx(hdc, &window_ext); + GreGetViewportExtEx(hdc, &viewport_ext); + if ((window_ext.cy > 0) != (viewport_ext.cy > 0)) + invert_y = TRUE; + } +#else if (GetGraphicsMode(hdc) == GM_COMPATIBLE) { SIZE window_ext, viewport_ext; @@ -1154,10 +1152,14 @@ if ((window_ext.cy > 0) != (viewport_ext.cy > 0)) invert_y = TRUE; } - +#endif if (count == -1) { +#ifdef _WIN32K_ + count = wcslen(str); +#else count = strlenW(str); +#endif if (count == 0) { if( flags & DT_CALCRECT) @@ -1192,7 +1194,11 @@ if (flags & DT_MODIFYSTRING) { size_retstr = (count + 4) * sizeof (WCHAR); +#ifdef _WIN32K_ + retstr = ExAllocatePoolWithTag(PagedPool, size_retstr, USERTAG_RTL); +#else retstr = HeapAlloc(GetProcessHeap(), 0, size_retstr); +#endif if (!retstr) return 0; memcpy (retstr, str, size_retstr); } @@ -1264,21 +1270,40 @@ const WCHAR *p; p = str; while (p < str+len && *p != TAB) p++; len_seg = p - str; - if (len_seg != len && !GetTextExtentPointW(hdc, str, len_seg, &size)) + if (len_seg != len && +#ifdef _WIN32K_ + !GreGetTextExtentW(hdc, (LPWSTR)str, len_seg, &size, 0)) +#else + !GetTextExtentPointW(hdc, str, len_seg, &size)) +#endif { +#ifdef _WIN32K_ + ExFreePoolWithTag(retstr, USERTAG_RTL); +#else HeapFree (GetProcessHeap(), 0, retstr); +#endif return 0; } } else len_seg = len; - +#ifdef _WIN32K_ + if (!GreExtTextOutW( hdc, xseg, y, + ((flags & DT_NOCLIP) ? 0 : ETO_CLIPPED) | + ((flags & DT_RTLREADING) ? ETO_RTLREADING : 0), + rect, (LPWSTR)str, len_seg, NULL, 0 )) +#else if (!ExtTextOutW( hdc, xseg, y, ((flags & DT_NOCLIP) ? 0 : ETO_CLIPPED) | ((flags & DT_RTLREADING) ? ETO_RTLREADING : 0), rect, str, len_seg, NULL )) +#endif { +#ifdef _WIN32K_ + ExFreePoolWithTag(retstr, USERTAG_RTL); +#else HeapFree (GetProcessHeap(), 0, retstr); +#endif return 0; } if (prefix_offset != -1 && prefix_offset < len_seg) @@ -1329,129 +1354,12 @@ if (retstr) { memcpy (str, retstr, size_retstr); +#ifdef _WIN32K_ + ExFreePoolWithTag(retstr, USERTAG_RTL); +#else HeapFree (GetProcessHeap(), 0, retstr); +#endif } return y - rect->top; }
-/*********************************************************************** - * DrawTextExA (USER32.@) - * - * If DT_MODIFYSTRING is specified then there must be room for up to - * 4 extra characters. We take great care about just how much modified - * string we return. - * - * @implemented - * - * Synced with Wine Staging 1.7.37 - */ -INT WINAPI DrawTextExA( HDC hdc, LPSTR str, INT count, - LPRECT rect, UINT flags, LPDRAWTEXTPARAMS dtp ) -{ - WCHAR *wstr; - WCHAR *p; - INT ret = 0; - int i; - 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; - if( flags & DT_SINGLELINE) - rect->bottom = rect->top + lh; - else - rect->bottom = rect->top; - } - return lh; - } - cp = GdiGetCodePage( hdc ); - wcount = MultiByteToWideChar( cp, 0, str, count, NULL, 0 ); - wmax = wcount; - amax = count; - if (flags & DT_MODIFYSTRING) - { - wmax += 4; - amax += 4; - } - wstr = HeapAlloc(GetProcessHeap(), 0, wmax * sizeof(WCHAR)); - if (wstr) - { - 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 - * change. U+FFFE is guaranteed to be not a unicode character and - * so will not be generated by DrawTextEx itself. - */ - ret = DrawTextExW( hdc, wstr, wcount, rect, flags, dtp ); - if (flags & DT_MODIFYSTRING) - { - /* Unfortunately the returned string may contain multiple \0s - * and so we need to measure it ourselves. - */ - for (i=4, p=wstr+wcount; i-- && *p != 0xFFFE; p++) wcount++; - WideCharToMultiByte( cp, 0, wstr, wcount, str, amax, NULL, NULL ); - } - HeapFree(GetProcessHeap(), 0, wstr); - } - return ret; -} - -/*********************************************************************** - * DrawTextW (USER32.@) - * - * @implemented - * Synced with Wine Staging 1.7.37 - */ -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; - flags &= 0xffff00ff; - } - return DrawTextExW(hdc, (LPWSTR)str, count, rect, flags, &dtp); -} - -/*********************************************************************** - * DrawTextA (USER32.@) - * - * @implemented - * Synced with Wine Staging 1.7.37 - */ -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; - flags &= 0xffff00ff; - } - return DrawTextExA( hdc, (LPSTR)str, count, rect, flags, &dtp ); -}