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(a)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 );
-}